Spec a maturity assessment app: content contract, tested scoring, results in the URL

Spec a browser-only maturity assessment whose content is checked data and whose scoring is pinned by simulated respondents, so every result is reproducible from a link.

Prompt advanced Tested Opus 5.5 · Nov 2026May be dated

The prompt

Run it in a chat, then hand the spec to the person or coding agent who builds the app. The spec holds one sample question. Have the builder, or a follow-up prompt run one dimension at a time, write the full content module to the section 1 standard; the section 2 contract rejects stubs. Review every anchor yourself.

Fill in the blanks6 placeholders · empty ones stay as {{…}}

Example

Input:

  • assessment_topic: a product team's web accessibility practice
  • audience: product teams of 5 to 50 people; each member answers for their own team
  • dimensions: Ownership & policy · Design · Engineering · Testing & tooling · Content & media · Skills & training
  • levels: 1 Unaware · 2 Reactive · 3 Defined · 4 Embedded · 5 Leading
  • foundation_dimensions: Ownership & policy, Testing & tooling
  • pillars: Foundations: Ownership & policy, Testing & tooling · Practice: Design, Engineering, Content & media, Skills & training

Output (trimmed to the sample question with three of its anchors, three of the nine red-flag rules and four of the 52 scoring scenarios):

Field Value
question How often is the product tested with a screen reader, and by whom?
2 Reactive Someone tests with a screen reader only after a complaint, audit finding or customer request, and only on the screen it names; no record of the test is kept.
3 Defined A written script names the screen reader and browser pairs and the key journeys to cover; a named tester runs it before each release that changes UI and logs defects in the tracker.
4 Embedded As level 3, and every ticket that changes UI records a screen reader check by its engineer or tester before merge, using the scripted pairs.

…

# id: name Rule Severity Dimensions
1 no-owner: Nobody accountable answer(ownership.q1) ≤ 2 high Ownership & policy
2 shipping-blind: Shipping blind score(testing) < 1.8 high Testing & tooling
4 regulated-exposure: Legal duty, weak foundations regulated AND (score(ownership) < 2.6 OR score(testing) < 2.6) high Ownership & policy, Testing & tooling

…

  • Notation. all=k sets all 30 answers to k. dim=[a,b,c,d,e] sets that dimension's q1–q5. qid=k sets one answer. ? = Don't know (0). Later settings override earlier ones.
  • Defaults. Full mode, ambition defined (3), regulated off.
  • Numbers. All expected numbers are raw engine outputs, unrounded, compared with absolute tolerance 1e-6. Repeating decimals are written to 6 places. Levels, ranks, counts, ids and orders compare exactly.
ID Name Answers Expected result
F2a shipping-blind fires all=3; testing=[2,2,1,1,1] Testing 1.4. shipping-blind H, names testing.
F2b shipping-blind near miss all=3; testing=[2,2,2,2,1] Testing 1.8, L2. shipping-blind absent.
D1 Don't know caps severity all=3; testing=[1,1,1,1,?] Testing 1.0 from 4 answers, dkShare 0.2. shipping-blind fires M (base high, downgraded). Testing not urgent: weight 1.25, priority 2.0. blind-spots absent.
PL1 Urgent outside the top three ambition embedded; ownership=[2,4,4,3,3]; design=[2,2,2,2,2]; engineering=[2,2,2,2,2]; testing=[4,4,4,4,4]; content=[2,2,3,2,1]; skills=[4,4,4,4,4] Scores 3.2, 2.0, 2.0, 4.0, 2.0, 4.0. Flags exactly: no-owner H. Ranking: design 1.4, engineering 1.4, content 1.4, ownership 0.27 (rank 4, urgent). d30 = ownership.a3.1, .a3.2, .a3.3, design.a2.1, design.a2.2, engineering.a2.1. …

Each anchor adds something an observer could check, from testing only after a complaint, finding or request, to a written script and a named tester, to a check recorded on every UI ticket. The rows check by hand: in D1 the Don't know demotes shipping-blind to medium, so testing keeps only the foundation weight (gap 2.6 − 1.0 = 1.6, × 1.25 = 2.0), and in PL1 ownership ranks fourth at 0.2 × 1.35 = 0.27 yet, as an urgent dimension, takes the first three 30-day slots.

Why it works

  • Content as data behind a contract. Assessment content is large and gets edited by people who never read the engine. The build check catches what a review misses (a stub anchor, a second quick question, an action pointing at another dimension's KPI, a duplicate id) and names the id, so structurally broken content cannot ship.
  • One observable anchor per level, plus "Don't know". Respondents match what actually happens instead of rating themselves, which damps optimism and makes answers more comparable between people. Counting "Don't know" rather than guessing turns low visibility into a finding (Blind spots), and a null score stops an unknown dimension reading as a weak one.
  • Exact numbers in a pure engine, tested on simulated respondents. With bands, weights and caps written as numbers, every result is reproducible, so known profiles can pin it down: all-lowest, all-top, each flag and its near miss. The foundation weight pushes weak foundations up the plan, the ceiling shows when one holds the rest back, urgent red-flag fixes jump the queue, and the two-levels-a-year and horizon caps keep the plan believable.
  • Answers, not scores, in the URL fragment. Nothing about a respondent is stored on a server, yet the link reproduces the report anywhere. Because it carries answers, a corrected rule re-scores old links, and the version number stops a link made for an older question set from being scored against the new one.

Variations

  • Cognitive test instead of a self-assessment. Replace anchors with items that have one keyed answer, generated from a seeded PRNG so the form is identical for every taker. An answer-key validator fails the build when an item has other than one keyed option, a key index out of range, duplicate options, a key that differs from the answer recomputed from the item's rule, or a guessing parameter other than 1 / number of options, or when the keyed position never varies. Difficulty that falls within a section is a warning, not a failure.
  • Scoring a cognitive test. Score each section with a three-parameter IRT model and estimate ability by EAP over a grid with a normal prior: unlike maximum likelihood, it gives a finite estimate for a perfect or a zero score, plus a standard error for a confidence range. Item parameters are set by hand until calibrated on real takers; say so in the report. Combine k standardised (z) domain scores as their sum divided by √(k + k(k−1)r), where r is their average intercorrelation, then rescale to mean 100, SD 15. The scoring check prints the expected raw score across a range of abilities, so you can see whether the items spread people out, and simulates candidates at known abilities; their mean recovered score must land near the truth.
  • Group mode. Paste many result links into one view and aggregate only finished responses. Average each question across respondents, show the spread per dimension, and flag a gap between groups (for example leaders and everyone else) when it passes a threshold you state. Treat that flag as high severity, so it raises those dimensions' priority. Give each respondent a random id in the link so identical anonymous answers still count as two people.
  • Facilitated use. Give each dimension a discovery brief in the content (interview questions, evidence to ask for and common pitfalls, each with a minimum count you set) and count them in the contract, so a facilitator can run the assessment as an interview.