sparkvibeai/showcase · real specs from the house committee

three work requests, cross-model reviewed, scored before any code.

These are real specs the SparkVibeAI committee produced — not mockups. Each work request was reviewed by two reviewers on different model families (GPT-5.3-Codex (OpenAI) + Claude Opus 4.8 (Anthropic)), revised until they signed off, and given a deterministic, reviewer-derived score. Below: the request, the score, and the actual build-ready spec.

Why two reviewers, on different models?

We ran the same three requests two ways. A single-pass review left all three short of convergence in the low 70s. Routing each request to cross-model reviewers with directed lenses — a security lens, a contract lens — took two of the three to a converged 93/100, at lower cost. The disagreement between two different models is the signal a single reviewer can't produce.

RequestSingle-pass reviewCross-model directed review
URL shortener with rate limiting72/100 · didn't converge93/100 · converged (2 rounds)
Quotes JSON API74/100 · didn't converge93/100 · converged (5 rounds)
Bakery landing page74/100 · didn't converge77/100
security lens · Opus

URL shortener with rate limiting

score93/100
converged✓ 2 rounds
reviewerscross-model

work request → Build a URL shortener. POST /api/shorten accepts {url}, validates it is a well-formed http(s) URL, rate-limits to 10/min per client IP, and returns {code, shortUrl}. GET /:code 302-redirects to the original, or 404. Do not allow shortening javascript: or data: URLs.

What the security lens caught: the security details a single-pass review waves past — rejecting javascript:/data: schemes, trusting only proxy-attested client IPs (so the rate limit can’t be evaded with a spoofed header), bounding URL length, and separating machine-checkable acceptance from manual QA.

read the build-ready spec the committee produced ▸
# URL Shortener with Rate Limiting

## Overview
Build a web service that provides URL shortening functionality matching the following specification precisely.

## Functional Requirements
- POST /api/shorten must accept a JSON payload with a single field `url`.
- The provided URL must be validated as a well-formed http or https URL.
- Reject any URL that is not http(s), is malformed, or uses javascript: or data: schemes with HTTP 400.
- A request whose body is empty, is not valid JSON, omits the `url` field, or whose `url` is not a string returns HTTP 400. The `url` value is bounded to a maximum length of 2048 characters; longer values return HTTP 400.
- Enforce a rate limit of 10 requests per minute per client IP address as follows: Within any rolling 60-second window, up to 10 requests per client IP are allowed (requests 1-10 succeed); the 11th and subsequent requests in that window return HTTP 429. Timestamps older than 60 seconds are evicted, restoring capacity as the window slides.
- On successful shortening, return HTTP 200 with JSON body: { "code": "<6-char-alphanum>", "shortUrl": "<full-short-url>" }
- The short code must be a unique 6-character string using A-Z, a-z, 0-9. Regenerate on collision if necessary (limit 10 retries).
- GET /:code must check if the code exists. If yes, return HTTP 302 with Location header pointing to the original URL. If not, return HTTP 404.

## Additional Endpoints and Behaviors
- GET / must return HTTP 200 with the plain text body: "URL Shortener API is running. Use POST /api/shorten to create short URLs."
- GET /api/shorten must return HTTP 405.
- For unknown codes on GET /:code, return HTTP 404 with body containing the text "Not found".

## Implementation Guidelines
- Store mappings using an in-memory structure such as a map from code to original URL.
- Seed the storage upon startup with code "demo" mapping to "https://example.com".
- For rate limiting, track the timestamps of the last requests per IP using a sliding window of 60 seconds. Count how many fall within the window, evicting those older than 60 seconds.
- Determine client IP from the platform-provided connection peer address. Only honor a forwarded-for header when the deployment platform terminates it through a trusted proxy; in that case use the proxy-attested client address, never an untrusted client-supplied value. Note that a single client cannot evade the rate limit by varying request headers.
- Construct shortUrl using the request's protocol and host combined with the code, e.g. "https://your-host.com/AbCd12".
- No persistent storage or external services are required.

## Error Responses
- Use HTTP status codes as specified: 400 for bad URLs, malformed bodies, or invalid inputs, 429 for rate limit, 404 for unknown codes, 405 for unsupported methods on endpoints.
- No specific error body format is mandated beyond the 404 case noted above.

## Deployment
The service must be deployed to a publicly accessible HTTPS URL. The base URL of the deployment will serve as the artifact for verification.
Ensure the server handles the described routes and starts successfully.

## Acceptance criteria (summary)
Programmatic (auto-verified via verifierChecks):
- GET / returns HTTP 200 with the plain text body containing "URL Shortener API is running. Use POST /api/shorten to create short URLs."
- GET /api/shorten returns HTTP 405.
- GET /demo returns HTTP 302 with Location header set to https://example.com.
- GET /nonexistent123 returns HTTP 404 with body containing the text "Not found".

Manual / out-of-band QA (not auto-verified):
- POST /api/shorten with a valid http(s) URL returns HTTP 200 with JSON body containing "code" and "shortUrl".
- POST /api/shorten with an empty body, non-JSON body, missing "url" field, non-string "url", URL longer than 2048 characters, or invalid (non-http(s), javascript:, data:, malformed) returns HTTP 400.
- More than 10 POST /api/shorten requests per minute from the same client IP (i.e., the 11th within a rolling 60s window) returns HTTP 429.

## Programmatic verifier checks
These checks are executed against the deployed artifact URL using supported GET-based probes.

- root_status: GET / returns 200
- root_message: GET / body contains "URL Shortener API is running"
- shorten_method: GET /api/shorten returns 405
- redirect_status: GET /demo returns 302
- redirect_location: GET /demo has Location header "https://example.com"
- unknown_code: GET /nonexistent123 returns 404
- unknown_not_found: GET /nonexistent123 body contains "Not found"

## Manual / out-of-band QA acceptance (not auto-verified)
The following behaviors are required per the work request and spec but cannot be auto-verified with current supported verifier types (which are limited to GET requests without body payloads):
- POST /api/shorten accepts {url} where url is well-formed http(s), returns 200 with {code, shortUrl} where code is 6-char alphanum and shortUrl is the full URL.
- POST /api/shorten rejects with 400 for: non-http(s) URLs, javascript: or data: schemes, malformed URLs, empty body, invalid JSON, missing url field, non-string url, or url > 2048 chars.
- Rate limiting: after 10 POSTs in a 60s window from one IP, the next (11th) returns 429. The limit uses IP from connection peer or trusted proxy only.
- GET /:code for unknown returns 404 (already programmatic).
- All other specified behaviors.

Note: Manual QA should exercise these with actual POST requests, including boundary cases for rate limiting (e.g. send 11 requests quickly) and validation edge cases.
contract lens · Codex

Quotes JSON API

score93/100
converged✓ 5 rounds
reviewerscross-model

work request → Build a small JSON API. GET /api/quotes returns a random quote as {id, text, author}. GET /api/quotes/:id returns that quote or 404. GET /api/health returns {status:"ok"}. All responses application/json. Document the response shapes precisely.

What the contract lens caught: contract precision — exact JSON response shapes for every endpoint, a fixed corpus so results are deterministic, the Content-Type rule enforced on every path, and 16 machine-readable verifier checks the build can be graded against.

read the build-ready spec the committee produced ▸
# Quotes JSON API

## Overview

Build a small JSON API that exposes exactly three endpoints using a hardcoded corpus of quotes. The service is read-only with no authentication or external dependencies required. All responses must be valid JSON and set Content-Type: application/json.

## API Endpoints

### GET /api/quotes

Returns a randomly selected quote from the corpus with HTTP 200.

**Response shape (200):**
```json
{
  "id": "1",
  "text": "The only way to do great work is to love what you do.",
  "author": "Steve Jobs"
}
```

### GET /api/quotes/:id

Returns the quote matching the ID if present.

**Response shape (200):**
Same as the shape above.

**Response shape (404):**
```json
{
  "error": "Quote not found"
}
```

### GET /api/health

**Response shape (200):**
```json
{
  "status": "ok"
}
```

## Quote Corpus

Hardcode exactly these four quotes (IDs are strings):
- id: "1", text: "The only way to do great work is to love what you do.", author: "Steve Jobs"
- id: "2", text: "Life is what happens when you're busy making other plans.", author: "John Lennon"
- id: "3", text: "The future belongs to those who believe in the beauty of their dreams.", author: "Eleanor Roosevelt"
- id: "4", text: "It does not matter how slowly you go as long as you do not stop.", author: "Confucius"

## Implementation

Implement a server that correctly handles the three GET requests above and returns the exact documented response shapes and status codes. For /api/quotes select uniformly at random from the corpus on each request. For /api/quotes/:id perform an exact string match on the ID from the path; return 404 for any non-matching ID. The deployed artifact must be reachable at an HTTPS URL that directly serves the /api/* paths. No database, authentication, UI, additional endpoints, or external calls are in scope.

## Acceptance criteria

GET /api/health returns 200 with JSON body {"status":"ok"}. GET /api/quotes returns 200 with JSON containing id, text, author. GET /api/quotes/1 returns 200 with the exact Steve Jobs quote. GET /api/quotes/999 returns 404 with JSON {"error":"Quote not found"}. All responses must have Content-Type: application/json. The /api/quotes response must match one of the 4 corpus quotes exactly. Repeated requests to /api/quotes must be able to return varying quotes. GET /api/quotes/2 must return the John Lennon quote with 200.

## Verifier Checks

The machine-readable verifier checks (limited to 16) are:

```json
[
  {"type": "http_status", "name": "health_status", "target": "/api/health", "expectedStatus": 200},
  {"type": "http_header", "name": "health_content_type", "target": "/api/health", "headerName": "content-type", "expectedRegex": "application/json"},
  {"type": "http_json_path", "name": "health_status_value", "target": "/api/health", "jsonPath": "status", "expectedValue": "ok"},
  {"type": "http_status", "name": "random_quotes_status", "target": "/api/quotes", "expectedStatus": 200},
  {"type": "http_header", "name": "quotes_content_type", "target": "/api/quotes", "headerName": "content-type", "expectedRegex": "application/json"},
  {"type": "http_status", "name": "specific_quote_status", "target": "/api/quotes/1", "expectedStatus": 200},
  {"type": "http_header", "name": "specific_quote_content_type", "target": "/api/quotes/1", "headerName": "content-type", "expectedRegex": "application/json"},
  {"type": "http_json_path", "name": "specific_quote_id", "target": "/api/quotes/1", "jsonPath": "id", "expectedValue": "1"},
  {"type": "http_json_path", "name": "specific_quote_text", "target": "/api/quotes/1", "jsonPath": "text", "expectedValue": "The only way to do great work is to love what you do."},
  {"type": "http_json_path", "name": "specific_quote_author", "target": "/api/quotes/1", "jsonPath": "author", "expectedValue": "Steve Jobs"},
  {"type": "http_status", "name": "not_found_status", "target": "/api/quotes/999", "expectedStatus": 404},
  {"type": "http_header", "name": "not_found_content_type", "target": "/api/quotes/999", "headerName": "content-type", "expectedRegex": "application/json"},
  {"type": "http_status", "name": "specific_quote_2_status", "target": "/api/quotes/2", "expectedStatus": 200},
  {"type": "http_json_path", "name": "specific_quote_2_id", "target": "/api/quotes/2", "jsonPath": "id", "expectedValue": "2"},
  {"type": "http_json_path", "name": "specific_quote_2_text", "target": "/api/quotes/2", "jsonPath": "text", "expectedValue": "Life is what happens when you're busy making other plans."},
  {"type": "http_json_path", "name": "specific_quote_2_author", "target": "/api/quotes/2", "jsonPath": "author", "expectedValue": "John Lennon"}
]
```

Note: Content-type checks for /api/quotes/1 and /api/quotes/999 were added (by replacing the random_quotes_has_text and random_quotes_has_author checks) to ensure the universal contract “All responses must have Content-Type: application/json” is fully verifier-enforced. The random endpoint structure is still validated via status and the presence of fields on specific quotes.
feature lens · Codex + Opus

Bakery landing page

score77/100
rounds8 (max)
reviewerscross-model

work request → Build a single-page marketing website for a local bakery: a hero, a menu of at least 6 items with prices, hours/location, and a contact form that POSTs name+email+message to a configurable endpoint and shows a success state. Static HTML/CSS/JS.

What the feature lens caught: that even a “simple” landing page has a security surface — XSS-safe DOM updates (textContent, not innerHTML), HTTPS-only endpoint validation before any fetch, an empty default endpoint to prevent accidental data egress, and no client-side persistence.

read the build-ready spec the committee produced ▸
# Golden Grain Bakery - Static Landing Page

## Overview
Build a complete single-page marketing website as a single self-contained HTML file using only vanilla HTML, CSS, and JavaScript. The site promotes Golden Grain Bakery, a fictional local bakery. It must include a hero section with name and tagline, a menu with exactly 6 items, hours and location details, and a contact form that performs a POST using form data to a configurable endpoint and displays a success state.

The deliverable is one index.html file that can be opened directly in a browser or deployed to any static web host.

## Design and UX Guidelines
- Warm, inviting color palette: cream backgrounds (#FFF8E7), brown accents (#8B5E3C), gold highlights (#C9A227)
- Clean, modern sans-serif typography
- Responsive design that works on mobile, tablet, and desktop using CSS media queries
- Subtle shadows and rounded corners for cards and form
- Smooth scrolling for navigation links
- All content must be visible without external dependencies except for the form POST
- Accessible with proper labels, aria attributes, and sufficient contrast

## Security and Privacy Requirements
- Implement client-side input validation before any submission
- No secrets, API keys, or tokens in the source code
- Configurable endpoint must use HTTPS scheme; validate before fetch
- No cookies, localStorage, sessionStorage, or analytics
- Form data sent only on explicit user-initiated submit
- Use textContent (not innerHTML) for all dynamic updates to prevent XSS
- Disable submit button on submission with a 5-second cooldown and loading indicator
- Privacy-focused: no data persistence on the client
- Default endpoint is empty to prevent unintended data egress; owner must configure a valid HTTPS endpoint for actual submissions

## Detailed Page Sections

### Header / Navigation
- Sticky top navigation bar
- Left: Bakery name as logo/link to top
- Right: Links to #menu, #hours, #contact using anchor tags
- Simple responsive layout on small screens

### Hero Section (id="hero")
- Full viewport height or large padding with warm gradient or solid background
- Centered content:
  - Large heading: Golden Grain Bakery
  - Subtitle: Artisanal breads and pastries baked fresh daily
  - Prominent button: "View Our Menu" that scrolls to the menu section

### Menu Section (id="menu")
- Section heading: "Our Fresh Menu"
- Responsive CSS grid (1 column mobile, 2-3 desktop)
- 6 menu items as cards. Each card contains:
  - Item name in bold
  - Short description
  - Price in bold
- Exact menu items:
  1. Butter Croissant | Flaky, buttery French pastry | $4.25
  2. Chocolate Chip Cookie | Soft and chewy with dark chocolate | $2.75
  3. Sourdough Bread | Tangy, crusty loaf made with natural starter | $5.50
  4. Blueberry Muffin | Moist muffin loaded with blueberries | $3.50
  5. Raspberry Danish | Sweet pastry with raspberry jam | $4.00
  6. Pecan Pie Slice | Classic Southern pie with toasted pecans | $5.25
- Note at bottom: "All items baked fresh daily. Prices subject to change."

### Hours and Location Section (id="hours")
- Heading: "Visit Us"
- Flex or grid layout for two columns on larger screens:
  - Left: Hours
    - Monday - Friday: 7:00 AM - 6:00 PM
    - Saturday: 8:00 AM - 5:00 PM
    - Sunday: Closed
  - Right: Location
    - 123 Main Street
    - Anytown, CA 90210
    - (555) 123-4567
- Add: "Walk-ins welcome!"

### Contact Form Section (id="contact")
- Heading: "Get In Touch"
- Intro text: "Questions about orders, events, or catering? Send us a message!"
- Form with exact fields:
  - Name: text input, required, placeholder "Your full name"
  - Email: email input, required, placeholder "you@example.com"
  - Message: textarea, required, placeholder "How can we help you today?", rows=5
  - Submit button labeled "Send Message"
- After the form: success div with id="success-message" (initially display: none) containing "Thank you! Your message has been received. We will get back to you within 24 hours."
- Include a "Send Another Message" button in success area that resets to show the form

## Form Functionality (JavaScript)
Include a script that:
1. Defines at the top:
```javascript
// === CONFIGURABLE ENDPOINT ===
// Set to your actual form endpoint (must start with https://). 
// Default is empty for local-only demo (no data sent, success shown immediately).
const CONTACT_ENDPOINT = "";
```
2. Selects the form and adds a submit event listener.
3. Prevents default submission.
4. Performs client-side validation:
   - Name: trimmed, 2-100 characters
   - Email: matches standard regex, max 254 characters
   - Message: trimmed, 10-1000 characters
   - Shows clear error messages next to invalid fields; does not submit if invalid
5. If valid: disables submit button, shows "Sending...", creates FormData with 'name', 'email', 'message'.
6. Determines if to perform network POST: only if CONTACT_ENDPOINT is non-empty and starts with 'https://'. Otherwise, logs a console warning and skips the fetch.
7. If performing POST: wraps the fetch in try/catch with an AbortController set to timeout after 8000 ms. On fetch completion, error, or timeout, proceeds to success state.
8. On completion (regardless of network response or skip), hides the form and shows the success message.
9. The "Send Another Message" button clears inputs, hides success, shows form, and re-enables submit.

Validate that CONTACT_ENDPOINT starts with "https://" before fetch; log warning if not or if empty.

## Implementation Notes
- Use semantic HTML5
- All styles in one <style> tag in <head>
- All JavaScript in one <script> tag before </body>
- Proper <title>Golden Grain Bakery</title>
- meta viewport for mobile
- Test that the form can be submitted multiple times via the reset button
- The site must load and function completely from a single file
- When CONTACT_ENDPOINT is not configured, form submission must show success without making any network request

## Out of Scope
- Actual backend or email sending (configurable endpoint handles that)
- Real images (use CSS or text placeholders)
- Shopping cart or e-commerce
- Analytics or tracking
- Multiple pages
- Any server-side code or databases

## Acceptance criteria (summary)
Programmatic: 1. Hero displays 'Golden Grain Bakery' and tagline. 2. Menu shows exactly 6 specified items with descriptions and prices. 3. Hours and location details visible. 4. Contact form has required name, email, message fields. 8. Fully responsive single-file static HTML/CSS/JS.

## Manual / out-of-band QA acceptance (not auto-verified)
5. Form submission performs POST with name+email+message as form data to the configurable CONTACT_ENDPOINT (when set to valid https://); shows success locally without sending data if endpoint not configured.
6. Client-side validation blocks invalid submissions (empty fields, bad email format, length violations) and shows clear error messages next to fields.
7. Successful submission hides the form and displays the success message. The "Send Another Message" button resets the form allowing multiple submissions.

This covers the required behavior for the contact form.

## verifierChecks — the machine-readable programmatic gate (12)
- {"type":"http_status","name":"page_load","target":"/","expectedStatus":200}
- {"type":"http_body_contains","name":"hero_name","target":"/","expectedSubstring":"Golden Grain Bakery","caseSensitive":true}
- {"type":"http_body_contains","name":"menu_first_item","target":"/","expectedSubstring":"Butter Croissant"}
- {"type":"http_body_contains","name":"menu_price_example","target":"/","expectedSubstring":"$4.25"}
- {"type":"http_body_contains","name":"hours_info","target":"/","expectedSubstring":"7:00 AM - 6:00 PM"}
- {"type":"http_body_contains","name":"location_info","target":"/","expectedSubstring":"123 Main Street"}
- {"type":"http_body_contains","name":"contact_heading","target":"/","expectedSubstring":"Get In Touch"}
- {"type":"http_body_contains","name":"success_message","target":"/","expectedSubstring":"Thank you! Your message has been received"}
- {"type":"http_body_contains","name":"email_placeholder","target":"/","expectedSubstring":"you@example.com"}
- {"type":"http_header","name":"content_type","target":"/","headerName":"Content-Type","expectedRegex":"(?i)^text/html(?:;.*)?$"}
- {"type":"http_response_time_ms","name":"load_performance","target":"/","maxMs":1500}
- {"type":"http_body_contains","name":"endpoint_placeholder","target":"/","expectedSubstring":"CONTACT_ENDPOINT = \"\""}

Commission one for your build.

Describe what you want; the house committee writes a build-ready spec, two cross-model reviewers pressure-test it, and you get a scored spec to hand your AI coding agent — connect over MCP or commission one in the browser.

Commission a spec →