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 bends in one direction only: the clock gives and the scope does 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. It was not adapted or modified for this build. It was not adopted.

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.

2026-08-12 · 3 rejected alternatives recorded

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.

2026-08-11 · 4 rejected alternatives recorded

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.

2026-08-11 · 2 rejected alternatives recorded

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.

2026-08-11 · 2 rejected alternatives recorded

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.

2026-08-11 · 1 rejected alternative recorded

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.

2026-08-11 · 3 rejected alternatives recorded

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.

2026-08-11 · 3 rejected alternatives recorded

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.

2026-08-11 · 4 rejected alternatives recorded

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.

2026-08-11 · 4 rejected alternatives recorded

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.

2026-08-11 · 3 rejected alternatives recorded

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.

2026-08-13 · 3 rejected alternatives recorded

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.

2026-08-14 · 4 rejected alternatives recorded

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.

2026-08-14 · 4 rejected alternatives recorded

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.

2026-08-14 · 4 rejected alternatives recorded

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.

2026-08-14 · 4 rejected alternatives recorded

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.

2026-08-15 · 3 rejected alternatives recorded

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.

2026-08-15 · 4 rejected alternatives recorded

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.

2026-08-15 · 2 rejected alternatives recorded

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.

2026-08-15 · 4 rejected alternatives recorded

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.

2026-08-15 · 4 rejected alternatives recorded

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.

2026-08-15 · 3 rejected alternatives recorded

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.

2026-08-15 · 4 rejected alternatives recorded

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.

2026-08-15 · 6 rejected alternatives recorded

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.

2026-08-15 · 4 rejected alternatives recorded

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.

2026-08-16 · 4 rejected alternatives recorded

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.

2026-08-16 · 4 rejected alternatives recorded

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.

2026-08-16 · 3 rejected alternatives recorded

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.

2026-08-16 · 4 rejected alternatives recorded

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.

2026-08-16 · 3 rejected alternatives recorded

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.

2026-08-16 · 3 rejected alternatives recorded

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.

2026-08-19 · 3 rejected alternatives recorded

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.

2026-08-11 · 3 rejected alternatives recorded

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.

2026-08-12 · 2 rejected alternatives recorded

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.

2026-08-14 · 3 rejected alternatives recorded

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.

2026-08-14 · 3 rejected alternatives recorded

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.

2026-08-14 · 3 rejected alternatives recorded

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.

2026-08-14 · 3 rejected alternatives recorded

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.

2026-08-14 · 3 rejected alternatives recorded

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.

2026-08-14 · 4 rejected alternatives recorded

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.

2026-08-14 · 3 rejected alternatives recorded

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.

2026-08-15 · 3 rejected alternatives recorded

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.

2026-08-15 · 3 rejected alternatives recorded

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.

2026-08-15 · 3 rejected alternatives recorded

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.

2026-08-15 · 3 rejected alternatives recorded

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.

2026-08-15 · 4 rejected alternatives recorded

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.

2026-08-15 · 3 rejected alternatives recorded

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.

2026-08-15 · 3 rejected alternatives recorded

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.

2026-08-15 · 3 rejected alternatives recorded

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.

2026-08-19 · 3 rejected alternatives recorded