The decisions, and what each one rejected
This is the build's own record. Every decision below carries what was rejected and what the choice would measure, compiled from the ledger in this repository rather than retyped here.
The card is the ledger's ninth field and the only one that ships. Each is held to 40 words, and its rejected line has to quote an alternative that entry recorded, so a summary cannot name a reject the record does not carry.
The concept that was killed at research
The first idea was a pre-publish consequence preview: show a guidance author what a change will do before it ships. Fin already ships Preview, Batch Test, Procedure Simulations and guidance authoring assistance. Pitching it would have meant re-proposing shipped features to the team that shipped them.
It was killed at research rather than at judgement, by reading the help centre before writing the pitch.
Gate 1, and the two concepts it rejected
Three concepts went in and one came out. A, the boundary, was the most senior of the three and had the most ways to look naive: it needs corpus behaviour that nothing Fin publishes can ground. C, the failure ledger, was the strongest autobiographical fit and the weakest standalone prototype, because a record of past work is not a designed artifact. B, the handover, was chosen. C's receipts idea survived it, and this page is that idea. The comparison is recorded at d-010.
Shape Up, and the part that was not adopted
Four artifacts, recorded after the fact rather than claimed in advance. The appetite was flagship, and it bent one way only: deadlines moved and scope did not. A brief became the shaped pitch, then an epic with a hypothesis attached to it. The scope map came to nine tickets in five waves, with the proving slice built end to end first so the hypothesis could be killed early rather than late. The fourth artifact is the circuit-breaker, and it was not adopted.
The circuit-breaker is the rule that unfinished work does not automatically get more time: at the end of the cycle it is dropped rather than extended. This build took the opposite stance on the same question, so there was nothing left for the rule to do.
How this was built, and who decided what
AI agents wrote most of the code, the CSS and the checks. I set the constitution, made every call recorded below, and rejected the alternatives beside them. The gate is one command and it is the test suite, the linter and the type check at once. Where a rule could not be checked in code, the boundary is published in the constitution instead of implied, and each of those is an entry here.
The record
The entries below are in the order the decisions were taken, and none has a reject count of zero, because a decision without one is a preference.
System decisions
d-001 · system · The ledger lives in this repo; _factory is a hand-run mirror
- Decision
- The ledger lives here; _factory holds a hand-run mirror.
- Because
- A hook blocks writes there, so a PR cannot deliver it.
- Rejected
- the source of truth with an in-repo copy
- Would measure
- Whether the mirror is ever run by hand.
d-002 · system · Custom events stay virtual routes
- Decision
- Takeover events ship as fire-once synthetic pageviews, one fixed path each.
- Because
- Cloudflare Web Analytics has no custom events: the route is the payload.
- Rejected
- A sibling Worker plus KV as a beacon endpoint
- Would measure
- Whether any takeover row reaches the dashboard.
d-003 · system · Time-to-first-takeover is coarse buckets, encoded as route literals
- Decision
- Time to first takeover is recorded as four coarse buckets.
- Because
- A virtual route carries no duration, so buckets are the finest grain.
- Rejected
- Exact seconds in the path
- Would measure
- Whether the buckets distribute or pile into one.
d-004 · system · site/ is the only deployable directory
- Decision
- site/ is the deployed root; everything else stays private.
- Because
- Direct upload has no ignore mechanism and the link goes to a panel.
- Rejected
- the repo root, per the ux-factory habit
- Would measure
- Whether a private file is ever reachable on the deployed URL.
d-005 · system · Deploy URL: custom domain, with *.pages.dev pre-authorized
- Decision
- Target the custom domain, with the pages.dev host pre-authorised.
- Because
- No saulera.com subdomain has ever resolved, so the fallback is the likely branch.
- Rejected
- Block the build until DNS for saulera.com is fixed
- Would measure
- Whether the domain resolves inside the timebox.
d-006 · system · The machine layer ships partial, and the carve is named
- Decision
- A5 ships tokens.json and decisions.json; JSON-LD and llms.txt are carved by name.
- Because
- A rule nobody can satisfy trains the next author to ignore the file.
- Rejected
- Drop A5 entirely
- Would measure
- Whether anyone ever asks for a carved file.
d-007 · system · tokens.json is generated FROM the hand-authored contract CSS
- Decision
- The CSS is the source and tokens.json is the generated mirror.
- Because
- Importing the other repo's generator would take a live dependency on its canon.
- Rejected
- Hand-author both files
- Would measure
- Whether the drift check ever catches a real divergence.
d-008 · system · Kettle, the fictional B2B SaaS client pack
- Decision
- The client is Kettle, a fictional company with a one-file pack.
- Because
- The hue moves the whole way to copper rather than nudged off blue.
- Rejected
- Use a real company as the client
- Would measure
- Whether a reviewer reads Kettle as real.
d-009 · system · What the gate measures: fetch positions, CSS case rules, and one published gap
- Decision
- The gate measures fetch positions and case rules, not lookalike bytes.
- Because
- It was green on three violations and red on five correct files.
- Rejected
- banning contract-token rebinding in page CSS
- Would measure
- Whether the published gap ever costs a real contrast miss.
d-011 · system · Standalone site, not a studio mount
- Decision
- A self-contained static site, reusing the proven layers by copy.
- Because
- The exploration was cheap and conclusive, so no spike was needed.
- Rejected
- Studio-mount, the ux-factory #222 shape
- Would measure
- Whether the no-dependency rule survives contact with six pages.
d-013 · system · The eight slots and the three labels are two tables, not one
- Decision
- The eight slots and the three labels become two tables.
- Because
- One table asserts membership by layout before the disclaimer is read.
- Rejected
- rely on the prose disclaimer already above the table
- Would measure
- Whether a surface names a label without its hedge.
d-019 · system · The arrival clock stays synchronous, the flip moves to DOMContentLoaded, and the four buckets are re-set
- Decision
- The clock stays synchronous, the flip defers, the buckets are re-set.
- Because
- The take-over fires on a click, so a deferred clock starts late.
- Rejected
- Recycle the three superseded literals
- Would measure
- Whether the buckets distribute once the take-over ships.
d-022 · system · The runaway CSS comment is caught by what it leaves behind, and the obvious fix was measured green twice
- Decision
- Three detectors hold the runaway-comment class; no one matcher sees both shapes.
- Because
- Both halves were found by mutation and both survived the obvious fix.
- Rejected
- Report close === -1, as the review prescribed
- Would measure
- Whether either carve-out ever costs anything.
d-023 · system · The footer's legal line gets an opaque colour, and the exclusion that hid it gets a rule
- Decision
- The muted inverse foreground becomes opaque, and the tenth contrast pair.
- Because
- The exclusion and the defect were one sentence: it carried text.
- Rejected
- Leave it, since DESIGN.md already publishes the gap
- Would measure
- Whether 55% survives a real dark surface.
d-024 · system · The live region moves to the glass, the gutter becomes a check, and group 6 stops stopping at the file boundary
- Decision
- The live region moves to the glass; the gutter pairing becomes a check.
- Because
- Each was a defect the gate could not see.
- Rejected
- leave gate coverage to the browser checkers
- Would measure
- Whether the gutter check's selector matching earns its boundary.
d-028 · system · both-scenarios is the only row this surface writes, and it writes it from the success path
- Decision
- The recovery page writes one row, fired once from the success path.
- Because
- A literal is forever, because the dashboard cannot say a path changed meaning.
- Rejected
- Add a fifth literal
- Would measure
- Whether that row ever exceeds completed take-overs.
d-031 · system · Two published C2 budgets get producers, and contract gets its own row
- Decision
- The proposal takes 600 words; the contract gets its own row.
- Because
- The published budget had no producer and held no page.
- Rejected
- Raise both budgets to 1,000 and keep one row
- Would measure
- Whether a page buys budget inside an exempt block.
d-032 · system · C1 binds prototype surfaces, and the document pages carry no "Built because" line
- Decision
- C1 binds prototype surfaces, and the list is closed at three.
- Because
- A document about the prototype would open with someone else's sentence.
- Rejected
- Give both document pages a C1 line anyway
- Would measure
- Whether the closed list stays closed.
d-033 · system · C10's em-dash ban gets its first glob-wide producer, and the shipped-features ban is not taken
- Decision
- The em-dash ban gets a glob-wide producer over the rendered file set.
- Because
- The clause is a single byte and had no producer anywhere.
- Rejected
- Leave the em dash to /humanizer and the content checker
- Would measure
- Whether the ban ever reddens correct content.
d-034 · system · The "which value resonates" answer is grounded in the value's name plus the build's own evidence, because Fin's text for it is not reachable
- Decision
- The answer grounds on the value's name plus this build's own evidence.
- Because
- Fin's own text for that value is not reachable.
- Rejected
- the only value whose text is published
- Would measure
- Whether it survives a reader who knows Fin's text.
d-036 · system · .page-bet and the replay's measure move up a layer, because S5 is not optional when it fits
- Decision
- The bet block and the replay measure move up into components.css.
- Because
- Two byte-identical declarations in two files is S5's threshold.
- Rejected
- Delete handover.css now that it declares nothing
- Would measure
- Whether an empty stylesheet reads as discipline or dead weight.
d-039 · system · A claim about this build is checked against this build's ledger, and "deployed" failed that test
- Decision
- The word deployed is removed, because this build's own ledger contradicts it.
- Because
- A false claim inside an argument about checking claims costs the most.
- Rejected
- Keep "deployed" and make C11's status conditional
- Would measure
- Whether the pack still reads as one voice.
d-040 · system · The gate's own false-positive vectors are closed, and three published measurements get producers
- Decision
- Six false-positive vectors are closed, and three published numbers get producers.
- Because
- Each reddens correct content, the direction that teaches deletion.
- Rejected
- Let ANY sentence of C-6's verbatim satisfy the clause
- Would measure
- Whether the rewritten clause ever fires in anger.
d-041 · system · The pack gets a gate group that cannot check whether a sentence is true, and says so in its own verdict line
- Decision
- The pack gets a gate group that publishes its own limits.
- Because
- A shipped false claim proved the pack had no producer.
- Rejected
- Ban straight quotes outright across all four outward files
- Would measure
- Whether the arithmetic clause survives a hand-edited inventory.
d-042 · system · Group 13 stops ending the run, so a schema change can finally redden group 17
- Decision
- Group 13 probes the mount once, then skips and reports.
- Because
- A dereferenced null ended the run and took every later group.
- Rejected
- Wrap group 13 in one try/catch
- Would measure
- Whether a fourth instance of the shape appears.
d-043 · system · The ninth field, and why the page compiles from it rather than from the record
- Decision
- The card is a ninth ledger field and the only one that compiles.
- Because
- The eight recorded fields carry em dashes, route literals and 35,753 words.
- Rejected
- A sibling docs/decisions/cards.md file
- Would measure
- Whether the next ticket writes a card or deletes the clause.
d-044 · system · decisions.json publishes what the page publishes, and nothing more
- Decision
- The JSON publishes exactly what the page publishes, and no more.
- Because
- 34 recorded jd_line values carry an em dash that C10 binds.
- Rejected
- DTCG framing
- Would measure
- Whether any consumer asks for a field the page omits.
d-045 · system · The two #10 candidates are taken rather than deferred a second time
- Decision
- Both deferred checks ship: the orphan check and the rebinding detector.
- Because
- Both preconditions are met and both measure green today.
- Rejected
- Defer both again to a later ticket
- Would measure
- Whether either ever reddens on correct code.
d-046 · system · The decisions page gets a real C2 budget and its compiled cards are exempt
- Decision
- The page takes a 600-word budget and its cards are exempt.
- Because
- A page with no budget is the one page nothing holds.
- Rejected
- Counting the compiled cards against the budget
- Would measure
- Whether the page's prose grows towards 600.
d-047 · system · The two root JSON files get the cache rule their siblings already have
- Decision
- One rule covers both root JSON files, matching their siblings.
- Because
- tokens.json sat uncovered, so the new file closes an old omission.
- Rejected
- A separate rule for each file
- Would measure
- Whether a stale JSON is ever served after a deploy.
d-048 · system · The site wears Fin’s observed tokens, and the Kettle skin retires
- Decision
- The pack binds Fin’s observed tokens; the Kettle skin retires.
- Because
- The audience is Fin, and a re-skin is one file.
- Rejected
- Vendor Fin’s Saans and Serrif faces for full fidelity
- Would measure
- Whether the panel reads the surfaces as Fin’s own language.
d-051 · system · The left accent bars retire, and who-is-speaking stays in words
- Decision
- Every left accent bar leaves the components and the pages.
- Because
- The bars read as template furniture; the words already carry the signal.
- Rejected
- Restyle the bars rather than remove them
- Would measure
- Whether a reviewer misattributes a turn without the bars.
Handover decisions
d-010 · handover · Gate 1: concept B, The Handover
- Decision
- Gate 1 chose concept B, the handover, seen from the receiving human.
- Because
- Fin's escalation data dies at the human end: a gap in shipped product.
- Rejected
- C · The Failure Ledger
- Would measure
- Whether a reviewer recognises the gap in their own product.
d-012 · handover · Scenario grounding: the decision is primary, the reason label rides along hedged
- Decision
- Cards ground on the three-way escalation decision; the reason label rides along hedged.
- Because
- The two claims have different strengths and merging them would overstate one.
- Rejected
- name no reason label at all
- Would measure
- Whether a reviewer questions a card's provenance.
d-014 · handover · The honesty label, and its exact words
- Decision
- The honesty label is one fixed sentence, present on first paint.
- Because
- C10 bans em dashes and the sentence is on no exemption list.
- Rejected
- Keep the em dash as a named C10 carve-out
- Would measure
- Whether the second scenario ships the identical string.
d-015 · handover · Provenance is declared in the data, and the schema enforces it
- Decision
- Every claim-bearing scenario field declares its provenance, and the schema enforces it.
- Because
- A plausible claim with nothing behind it is the RELEX failure.
- Rejected
- Citations optional, cited where useful
- Would measure
- Whether a field ever has to be forced to designed.
d-016 · handover · Scenario 1 is a guideline-triggered escalation
- Decision
- Scenario 1 escalates on a guideline match, with the label hedged.
- Because
- Guideline has the most behind it of the three published labels.
- Rejected
- angry as the reason label
- Would measure
- Whether the hedge reads as rigour or as hesitancy.
d-017 · handover · The gate drives the real DOM binding against a stub document
- Decision
- The gate mounts the real player against a stub document.
- Because
- A renderer rebuilt the whole list on every emit, unseen.
- Rejected
- Add jsdom and mount against a real DOM
- Would measure
- Whether the next extension of the phase machine is caught.
d-018 · handover · A gate count printed as an assertion is a lie the gate tells about itself
- Decision
- The meta-assertion is an equality with one carve-out, not a floor.
- Because
- The verdict line claimed an equality its bound did not hold.
- Rejected
- Keep the loose bound and change the verdict line
- Would measure
- Whether the equality ever fires legitimately.
d-020 · handover · The take-over fires one completion event, from the success path, behind a state machine that is the only guard
- Decision
- Four guarded states, one completion event, fired from the success path.
- Because
- One completion event has to mean exactly one completed take-over.
- Rejected
- One shared fire-once flag inside takeover.mjs
- Would measure
- Whether completions ever exceed starts in the dashboard.
d-021 · handover · The handover contract field set, kept or revised
- Decision
- All five contract fields stand, and confidence stays in a fixed form.
- Because
- Each was put to three tests against the rendered card, not the JSON.
- Rejected
- Merge whatWasSaid into whatNotToRepeat
- Would measure
- Whether whatWasSaid earns its place on scenario 2.
d-025 · handover · Scenario 2 is a wrong answer nobody flagged, and the discovery beat is the stop
- Decision
- Scenario 2 is a confident wrong answer that nothing flagged.
- Because
- A model that raises its hand is the easy half of the argument.
- Rejected
- Have the customer ask for a human
- Would measure
- Whether the missing guideline row reads as a bug.
d-026 · handover · The beat's own copy moves into the data, and citedGuideline becomes conditional
- Decision
- The beat's copy moves into the data and citedGuideline becomes conditional.
- Because
- Nothing escalated on scenario 2, so a required guideline had nothing true.
- Rejected
- Derive the title from the decision branch
- Would measure
- Whether the beat node stays two fields.
d-027 · handover · The override captures the human's words, names one specific change, and publishes what it costs
- Decision
- The override panel names one specific change and publishes what it costs.
- Because
- A correction that stops at the customer teaches nothing.
- Rejected
- A generic "your feedback improves the system" panel
- Would measure
- Whether a reviewer reads correction, change and cost as one loop.
d-029 · handover · The frame says it is designed before the glass does
- Decision
- Every replay page carries a frame note saying the scenario is designed.
- Because
- Read cold, a page showing Fin wrong is a cheap shot.
- Rejected
- Scope the note to recovery.html by name
- Would measure
- Whether the note is read.
d-030 · handover · The contract document specifies the schema's own field set, and a check reads both modules
- Decision
- The document specifies the schema's own field set, checked against both modules.
- Because
- Document and prototype are two renderings of one list.
- Rejected
- Bind the document to the prototype by review
- Would measure
- Whether the group ever fires where another already would.
d-035 · handover · The override panel is measured by driving it, not by scanning the page it ships hidden on
- Decision
- The override band collapses at 700px, measured by driving it to a send.
- Because
- It was the only label and value grid with no collapse.
- Rejected
- Collapse at 520px, matching .dc-field
- Would measure
- Whether driving before measuring survives as the method.
d-037 · handover · The corrected row may only name a turn the reader was shown, and it names it by position
- Decision
- The corrected row may only name a turn the reader was shown.
- Because
- The guard the header claimed was never in the code.
- Rejected
- Number the turns visibly in the transcript
- Would measure
- Whether turn 2 is read as the second turn shown.
d-038 · handover · The panel announces itself by taking focus, because the sentence that would have said so is shared
- Decision
- After a send, focus moves to the override panel's heading.
- Because
- The shared status sentence could not say what this page needed.
- Rejected
- A second live region on the panel
- Would measure
- Whether the focus move is felt as help or as disorientation.
Prototypes decisions
d-049 · prototypes · A seventh page shows the idea as three tap-through flows
- Decision
- Three tap-through flows on a seventh page, notes beside the glass.
- Because
- The replay pages argue at depth; the panel needs tap speed.
- Rejected
- Autoplaying walkthrough videos or GIF captures
- Would measure
- Whether a reviewer taps a full flow before a replay.
Work decisions
d-050 · work · An eighth page shows the five products behind the method
- Decision
- An eighth page: five live products, thumbnail and link each.
- Because
- The concept argues a method; five shipped products show it working.
- Rejected
- A block on the proposal memo instead of a page
- Would measure
- Whether a reviewer opens a case study.