klappy.dev

The StylebookLedger

Session Ledger

P1.3.1 Challenge governance_source Canary Landed (0.19.0)

SummaryWhat Shipped and What the Session Proved

P1.3.1 delivered the challenge canary completion described in the prior session's handoff: envelope contract compliance (governance_source), four peer canon URIs (governance_uris), and debug.knowledge_base_url echo. Two PRs on klappy/oddkit — #116 (squash-merged at 71ee6ed), #117 (main→prod merge at 1b4fce8). Prod at 0.19.0 (https://oddkit.klappy.dev/health confirmed). Smoke 126/126 × 5 consecutive on prod after 40s CF warmup; main-preview required two isolate-warmup flakes before settling (the pattern the P1.2 handoff named).

Three patterns deserve naming — each one a test of whether the P1.2 ledger's hard-won lessons actually propagate.

Code-first discipline caught two handoff errors on first pass. The P1.3 handoff described four discovery helpers all named discover* (recency-as-authority: pattern-matching encode's discoverEncodingTypes onto challenge). Direct grep of workers/src/orchestrate.ts@290dde5 showed only one was discover*; the other three are fetch*. The PRD called this out in §3.1 and committed to preserving the names (minimizing diff, zero behavioral impact). Second catch: the handoff framed the bundled tier as contract aspiration but didn't explicitly note that workers/baseline/ does not exist in the repo at all. ls workers/baseline/ returned "NO BASELINE DIR". The two-tier cascade (knowledge_base | minimal) isn't a classification-specific call for challenge — it's the current reality for every knowledge-base-driven tool. The PRD named this in §3.2 and the risk register called out that the validator would need to see this explicitly, which is exactly what it did when corroborating against core-governance-baseline.

Operator pivot on D4 was load-bearing. The PRD's first draft proposed governance_uri: "klappy://odd/challenge/stakes-calibration" — single string, parity with encode's shape. The operator flagged this: challenge reads four peer governance files (base-prerequisites, challenge-types/, normative-vocabulary, stakes-calibration) and stakes-calibration doesn't govern or represent the other three. A single anchor pointing at it would mislead callers about where the vocabulary and prerequisite contracts live. Alternative: governance_uris: [array of four], alphabetical. Shape divergence from encode is accepted because the underlying governance reality diverges. The PRD §7 envelope-after diagram was updated, D6 CHANGELOG language specifically named the divergence for consumers reading both tools, and the smoke test asserts governance_uri (singular) is NOT emitted on challenge. This decision was the most consequential of the session; every other decision fell in line.

Validator external-corroboration pattern worked end-to-end. Per canon/principles/agent-self-report-under-stress, terminal self-reports are not authoritative. The validator task explicitly required five external corroborations: main-branch bytes grep (pre-refactor state), live curl ×3 shapes (default, override, voice-dump SUPPRESSED), oddkit_get citation on core-governance-baseline, all 9 modes curl, and 3× independent smoke runs. Sonnet 4.6 pulled each piece independently — including cloning the repo itself to run the smoke test from its own session, not trusting the orchestrator's preview-smoke output. Disposition VERIFIED 5/5 with zero advisories. Zero advisories is unusual and worth marking — the PRD-first discipline (writing the plan as a file before touching code) appears to front-load the kind of review findings that would otherwise surface at validation time.


What Shipped

PRRepoMerged SHAPurpose
#116klappy/oddkit71ee6edfeat(challenge): governance_source envelope + peer governance_uris (0.19.0). Squash-merged.
#117klappy/oddkit1b4fce8main → prod promotion for 0.19.0. Merge commit.

Production state: https://oddkit.klappy.dev/health returns {"version":"0.19.0"}. Smoke 126/126 × 5 consecutive on prod.

Validator record: agent_011CaE62pg6jJ7yYpRj1o9Do / sesn_011CaE63LZhPUX1UAZPbiV7n. Disposition: VERIFIED, 5/5, zero blockers, zero non-blocking advisories.

Feature delta (files changed): 6 files, +222 / -19 lines in the feat commit.

  • workers/src/orchestrate.ts — four helpers retrofitted to {<domainNoun>, source} tuples (discoverChallengeTypes→{types, source}, fetchBasePrerequisites→{prerequisites, source}, fetchNormativeVocabulary→{vocabulary, source}, fetchStakesCalibration→{calibration, source}); runChallengeAction aggregates strictly and adds envelope fields on both SUPPRESSED and CHALLENGED paths; cleanup_storage extended to reset the three new cachedXSource fields
  • workers/src/index.ts — oddkit_challenge tool description updated to name the four governance surfaces and the two-tier envelope signal
  • workers/test/canon-tool-envelope.smoke.mjs — 47 new assertions: envelope shape on both paths, governance_uris array of exactly 4 with expected alphabetical ordering, governance_uri singular asserted absent, knowledge_base_url override behavior, 9-mode parse integrity loop (voice-dump asserts SUPPRESSED; others assert CHALLENGED)
  • CHANGELOG.md — [0.19.0] entry with Added / Changed / Fixed / Known-limitations; divergence-from-encode called out explicitly in the governance_uris Added bullet
  • package.json + workers/package.json — synced to 0.19.0 (pre-commit hook enforced)

What the Validator Actually Checked

The five corroborations are worth enumerating because the pattern should be the default for subsequent canaries in the sweep.

  1. Main-branch bytes grep. Validator cloned klappy/oddkit, checked out main, grepped workers/src/orchestrate.ts for governance_source references inside runChallengeAction. Confirmed zero hits — pre-refactor state matches the PR's "before" claim. The one match at line 2262 of main is inside runEncodeAction (P1.2), which the validator correctly disambiguated.
  2. Live preview curl, three shapes. Default KB planning mode → governance_source: "knowledge_base", governance_uris length 4, governance_uri undefined. Override to torvalds/linux → debug.knowledge_base_url echoed, governance_source within enum. Voice-dump mode → status: "SUPPRESSED" with governance fields still present on the early-return envelope (the PRD §10 risk register flagged this branch specifically; validator confirmed it landed).
  3. Canon citation on core-governance-baseline. Validator used oddkit_get to fetch §Runtime Invariants and confirmed the three-tier enum is documented, plus fetched the §What-Ships-in-Baseline section to confirm odd/challenge/stakes-calibration.md is listed as required-in-baseline. Two-tier cascade today is coherent with the contract given workers/baseline/ is not shipped.
  4. Nine-mode curl. Validator iterated all nine modes from odd/challenge/stakes-calibration against the preview URL. Each returned a full envelope with valid governance_source and governance_uris length 4. voice-dump returned SUPPRESSED; the other eight returned CHALLENGED. PR #100 regression guard is live.
  5. Independent smoke runs. Validator cloned its own copy of the branch and ran the smoke test three consecutive times against the preview URL — not trusting the orchestrator's own smoke output. 126/126 each run.

The disposition block: VERIFIED / 5/5 / [] blockers / [] advisories.


Patterns Observed, Worth Carrying Forward

"PRD as a file before touching source" is a review-cost reducer. P1.2 landed with 3 non-blocking advisories. P1.3.1 landed with zero. The difference this session was the PRD: 296 lines including 8 explicit decisions (D1–D8) each with alternatives named, a risk register covering the SUPPRESSED early-return gotcha before the first line of code was written, and a §8 validator dispatch protocol naming five corroborations that the validator then faithfully executed. The hypothesis: review findings tend to come from (a) decisions the author didn't realize were decisions, and (b) edge cases the author didn't think about. Writing the PRD surfaces both before code, turning would-be review findings into planning-time clarifications.

Operator pivot on a design decision is more productive than operator approval of all decisions. D4 was the only pivot of eight decisions. The PRD's first-draft case for single-string was internally coherent — but the operator caught that it was optimizing for the wrong thing (envelope parity over accurate representation of governance reality). The change took one message, one PRD edit, and zero downstream rework. If the operator had approved D4 as drafted, the validator corroboration on the governance_uri field would have surfaced the same question at validation time, which is 10× more expensive to fix. The session confirms: review pivots during planning are the cheapest kind. "7 of 8 approved, D4 reconsider" is a high-value approval shape.

Isolate-warmup pattern is real across tiers. The P1.2 handoff established "3 consecutive clean as prod-ready gate" because CF isolates can serve mixed versions immediately after deploy. This session reproduced the pattern precisely on main-preview: two flakes, then three clean, then two more clean for confidence. Prod took 40s of warmup wait and then five clean in a row. The operational rule generalizes: trust the third-consecutive-clean, not the first.

Handoff errors are structural, not exceptional. The P1.2 ledger named recency-as-authority (three recurrences) and proposed a candidate canon principle on contract-governs-handoff-drift, pending one more recurrence before canonization. This session is that recurrence. The P1.3 handoff's claim of four discover* helpers was recency-as-authority in the forward-pointing doc itself — the author pattern-matched from the encode helper (discoverEncodingTypes) onto the challenge helpers without verifying against code. The fix worked: code-first discipline caught it in the PRD's §3.1 before any edits. Third instance confirmed; the canon principle now has standing.


What Is Cleared from the Prior Handoff

  • [O-open P1] P1.3.1 challenge governance_source retrofit — closed by #116/#117.

What Remains Open (Carry-Forward O-opens)

  • [O-open P1] P1.3.2 — next tool in sweep. Candidates: gate, preflight, validate, orient, search, catalog, cleanup, version. Priority to be decided in the next session's handoff. Audit doc at docs/oddkit/audit/governance-anti-pattern-sweep-2026-04-17.md has the ranking.
  • [O-open P2] getIndex strict-mode (skipBaselineFallback). Inherited from encode 0.18.0; now affects challenge 0.19.0 as well. Same limitation, one fix — natural to pull into a later P1.3.x PR when a tool exercises the code path non-trivially, or as a standalone PR if the sweep doesn't naturally touch it.
  • [O-open P3] Handoff text corrections on klappy.dev. Two corrections deferred from this session: (a) P1.2 handoff klappy://odd/handoffs/2026-04-20-p1-2-encode-canary rename "bundled baseline" → "minimal fallback" to align with the contract's enum; (b) P1.3 handoff klappy://odd/handoffs/2026-04-20-p1-3-challenge-canary rename the three discover* → fetch* for fetchBasePrerequisites / fetchNormativeVocabulary / fetchStakesCalibration. Low priority, archival; bundle both into a single tiny canon PR.
  • [O-open P4] Canon principle on contract-governs-handoff-drift. P1.2 ledger called for one more recurrence before writing the principle. This session is recurrence #3 (P1.3 handoff's discover* naming error). The principle has standing. Draft location: canon/principles/contract-governs-handoff-drift.md. Core claim: "when a handoff's word choice disagrees with a governing contract's enum or a live code reality, the contract/code wins — the handoff is a bridging artifact, not a source of truth." Draft in a small canon PR when the next session opens a klappy.dev PR for any reason.
  • [O-open P5] workers/baseline/ bundled-tier build pipeline. The contract §Build-Time-Invariants describes the regeneration process (fetch canon at pinned SHA, extract required-baseline files, schema-check against canon, fail build on divergence). Nothing in the repo implements this today. Separate epoch's work — not a single-session unit. First step would be writing the MANIFEST.json and the regeneration script; second step would be the schema check; third step would be a oddkit_baseline_check probe. Deferred until the sweep surfaces concrete need or TruthKit's TruthKit-specific baseline needs force the question.
  • [O-open P6] CHANGELOG render route on klappy.dev + version_notes_url on MCP initialize. Low priority, unchanged from prior handoffs. Slot into a tool-envelope PR window.

What This Session Added to the Carry List

None beyond the above — the session stayed in scope. No new scope-creep O-opens.


Canon Principle Now Standing: contract-governs-handoff-drift

Three recurrences justify the principle. Named explicitly:

When a handoff's word choice or described state disagrees with a governing contract's enum or the target code's live reality, the contract and code win. The handoff is a bridging artifact — useful for session continuity, but not authoritative over the governing documents or the repo state. The fix is always the same: before acting on a handoff's framing, grep the target code and re-fetch the governing contract. Recency is not authority.

Three recurrences this principle addresses:

  1. P1.2 session: handoff described three-tier cascade; contract's enum for encoding-types is two-tier (knowledge_base | minimal). Word collision, not design conflict.
  2. P1.2 session: handoff's scope framing treated "bundled DOLCHEO minimum" as a tier name; contract calls that case "minimal". Same pattern at scope-framing level.
  3. P1.3.1 session (this one): handoff described four discover* helpers; code has one discover* and three fetch*. Pattern-matched from encode without verifying.

The principle should be drafted in the next klappy.dev PR (natural to bundle with the handoff text corrections in O-open P3). The candidate doc already has three attestation cases in the ledger — a stronger grounding than most canon principles get at draft time.


Session MechanicsWhat Worked and What Didn't

What worked:

  • PRD as a file before code. 296 lines of planning produced an execution path the validator could corroborate exactly, zero advisories.
  • Time discipline via oddkit_time first each turn with server_time reference. The session's elapsed-time claims in final reporting (3h 25m total wall clock) are observed, not inferred.
  • Two explicit gates (exploration→planning, planning→execution) named the mode transitions out loud, even though the session started mid-plan. Cheap tool call; binds the scope lock that follows.
  • Strict aggregation rule (any helper minimal → aggregate minimal) matched encode's single-helper precedent trivially and has no edge cases.
  • Per-helper domain-noun tuples ({types, source}, {prerequisites, source}, etc.) read more cleanly at the call site than a generic {data, source} would have. Operator's style nit on D3 was right.

What didn't work as well:

  • Initial PRD draft on D4 optimized for parity over accuracy. Single-string governance_uri would have been merged if the operator hadn't pushed back. The review caught it cheaply; the PRD-first discipline is not a substitute for operator design review on non-obvious tradeoffs.
  • Smoke output pipeline filtering hid the pass/fail tallies on the first prod-smoke attempt. The fix was trivial (tail -1 instead of a grep filter), but the lesson is that observability tooling around verification steps should itself be verified before trusting its output.
  • Two main-preview isolate flakes before three clean. Not a defect — the P1.2 handoff predicted this — but a reminder that the 3-consecutive-clean gate is doing real work, not ritual.

Handoff

Next session's atomic unit: P1.3.2 — apply the canary pattern to the next tool in the sweep. Forward handoff at klappy://odd/handoffs/2026-04-21-p1-3-2-next-tool-canary. This ledger is status: active; a future closeout session will flip it to status: superseded with a pointer to that successor.


Provenance

  • Source handoff: odd/handoffs/2026-04-20-p1-3-challenge-canary.md — the instructions this session executed against.
  • Predecessor ledger: odd/ledger/2026-04-19-p1-2-encode-dolcheo-landed.md — the P1.2 retrospective whose code-first and recency-as-authority observations this session tested.
  • Merged PRs: klappy/oddkit#116 (feat), klappy/oddkit#117 (promotion).
  • Validator session: sesn_011CaE63LZhPUX1UAZPbiV7n under agent agent_011CaE62pg6jJ7yYpRj1o9Do. Model: claude-sonnet-4-5. Event log ephemeral to the validator's container; the VERIFIED 5/5 disposition is summarized above and in the final disposition block retrieved from the session's terminal agent.message event.
  • PRD: /home/claude/work/prd-p1-3-1-challenge-canary.md — local planning artifact in the orchestrator's working directory, not committed to any repo. Referenced in PR #116 commit message and inline orchestrate.ts comments.

Markdown · RSS · built from klappy/klappy.dev@b750d7d