Skip to content

odd/gate: canon governance docs for P1.3.2 gate vodka refactor (Phase 1)#120

Merged
klappy merged 1 commit into
mainfrom
gate/canon-governance-docs
Apr 20, 2026
Merged

odd/gate: canon governance docs for P1.3.2 gate vodka refactor (Phase 1)#120
klappy merged 1 commit into
mainfrom
gate/canon-governance-docs

Conversation

@klappy
Copy link
Copy Markdown
Owner

@klappy klappy commented Apr 20, 2026

Summary

Adds two peer governance files under odd/gate/ consumed by oddkit_gate's Phase 2 refactor. Canon-first sequencing per klappy://canon/constraints/core-governance-baseline — these files must merge to main before the klappy/oddkit 0.20.0 PR opens.

  • odd/gate/transitions.md (53 lines) — four transition keys, their from/to endpoints, the prerequisite ids each references, and detection terms (stemmed + BM25-matched against user input at runtime to identify which transition an input signals).
  • odd/gate/prerequisites.md (57 lines) — eight prerequisite ids with description, check vocabulary, and gap message per id. Check vocabularies are stemmed at parse time and set-intersected against stemmed user input.

Split by fit

Transitions need ranking (one transition wins), so BM25. Prereqs evaluate independently (gap-or-not), so stemmed set intersection. Both matchers use the Porter stemmer already shipped in workers/src/bm25.ts. Operator's D5 analysis: BM25 IDF flips negative on small shared-vocabulary corpora (log((N-df+0.5)/(df+0.5)) when df > (N-1)/2), producing score=0 on valid matches. Set intersection sidesteps it; transitions' largely-non-overlapping vocabulary doesn't trigger the pathology. Fit-to-problem > symmetry-of-algorithm.

Structural template

Frontmatter follows canon/meta/frontmatter-schema.md (native YAML types — tier: 2 unquoted, date: 2026-04-20 unquoted, string values quoted only where special characters require). Body structure mirrors odd/challenge/base-prerequisites.md — blockquote, ## Summary — [descriptive subtitle], primary table, ## Notes.

Writing Canon gauntlet

  • Blockquote with compressed argument ✓
  • Summary section with descriptive subtitle (headers tell the story when scanned) ✓
  • Progressive disclosure (blockquote → summary → table → notes) ✓
  • Native YAML frontmatter types ✓
  • klappy:// URI format for internal links ✓
  • AI voice cliché scan clean ✓
  • oddkit_preflight run, referenced constraints surfaced and addressed ✓

Phase 2 preview

Phase 2 (0.20.0 release on klappy/oddkit) consumes both files via fetchGateTransitions and fetchGatePrerequisites helpers, declares governance_source + governance_uris (plural array of 2) in envelope, preserves the vocabulary above as the minimal-tier fallback when canon is unreachable. Full PRD in orchestrator working artifact.

Provenance

  • Handoff: klappy://odd/handoffs/2026-04-21-p1-3-2-gate-canary
  • Prior canary (P1.3.1 ledger): klappy://odd/ledger/2026-04-20-p1-3-1-challenge-canary-landed
  • Structural template: odd/challenge/base-prerequisites.md
  • Contract: klappy://canon/constraints/core-governance-baseline §Canon-Only (odd/gate/ explicitly canon-only, two-tier cascade)

Refs klappy/oddkit P1.3.2 Phase 2.


Note

Low Risk
Adds new governance documentation that will be consumed by oddkit_gate; no runtime code changes in this PR, but incorrect vocab/prereq IDs could later affect gate behavior once integrated.

Overview
Introduces canon-first governance for oddkit_gate by adding two new docs under odd/gate/.

odd/gate/transitions.md defines four mode transition keys with from/to endpoints, prerequisite-id lists, and stemmed BM25 detection vocabularies used to recognize a transition from user input.

odd/gate/prerequisites.md defines eight prerequisite IDs with broad stemmed check vocabularies and user-facing gap messages, intended to be evaluated via per-prereq stemmed set intersection (with a minimal hardcoded fallback described when canon is unreachable).

Reviewed by Cursor Bugbot for commit 68ec21b. Bugbot is set up for automated code reviews on this repo. Configure here.

Adds two peer governance files under odd/gate/ that will be consumed by
oddkit_gate's Phase 2 refactor:

- odd/gate/transitions.md defines the four transition keys, their from/to
  endpoints, the prerequisite ids each references, and the detection terms
  (stemmed and BM25-matched against user input at runtime to identify which
  transition an input signals).

- odd/gate/prerequisites.md defines the eight prerequisite ids —
  description, check vocabulary, and gap message per id. Check vocabularies
  are stemmed at parse time and set-intersected against stemmed user input
  (each prereq evaluates independently; no ranking, no BM25 IDF pathology
  on the small 8-prereq corpus).

Split by fit: transitions need ranking (one winner), so BM25. Prereqs
evaluate independently (gap-or-not), so set intersection. Both matchers
use the Porter stemmer already shipped in workers/src/bm25.ts.

Phase 1 of P1.3.2 per klappy://odd/handoffs/2026-04-21-p1-3-2-gate-canary.
Phase 2 (klappy/oddkit refactor consuming these files, 0.20.0 release)
lands after this PR merges — canon-first is absolute.

Refs: klappy://canon/constraints/core-governance-baseline,
      klappy://canon/principles/vodka-architecture,
      klappy://odd/challenge/base-prerequisites (structural template)
@klappy klappy merged commit 86a7194 into main Apr 20, 2026
1 check passed
klappy pushed a commit that referenced this pull request Apr 20, 2026
Phase 1 of P1.3.2 landed at 86a7194 — two canon files under odd/gate/
merged via PR #120. This handoff carries forward the Phase 2 scope
(klappy/oddkit 0.20.0 refactor consuming the new canon) and supersedes
the original two-phase handoff at the session boundary.

Captures:
- PRD v4 decisions D1-D9 in compact form (next session re-derives
  specifics from code + canon + this handoff)
- The split-by-fit matcher design (BM25 transitions, set intersection
  prereqs) with the IDF-negative rationale for the split
- Helper contracts, envelope before/after, smoke test deltas
- Validator dispatch protocol (5 corroborations)
- Candidate canon principle 'cache fetches and parses, not microsecond
  derivations' — not yet written, pending third recurrence

Refs #120 (Phase 1 merged), P1.3.2 Phase 2 on
klappy/oddkit.
klappy added a commit that referenced this pull request Apr 20, 2026
Forward handoff carrying Phase 2 scope after Phase 1 canon landed in #120. Supersedes klappy://odd/handoffs/2026-04-21-p1-3-2-gate-canary.
klappy pushed a commit to klappy/oddkit that referenced this pull request Apr 20, 2026
…0.0)

P1.3.2 Phase 2. Consumes the two canon files landed in klappy/klappy.dev#120.

runGateAction refactored:

- fetchGateTransitions → {transitions, source} parses odd/gate/transitions.md,
  returns TransitionDef[] with detectionText fed to BM25 at gate time.
- fetchGatePrerequisites → {prerequisites, source} parses
  odd/gate/prerequisites.md, precomputes stemmedTokens: Set<string> per prereq
  at parse time (cache parse products, not microsecond derivations).
- Transition detection uses BM25 (ranking problem — one transition wins;
  rowOrder breaks score ties deterministically). Index built inline per
  request, not cached (microsecond derivation on gate's tiny vocabulary).
- Prereq evaluation uses stemmed set intersection (independent gap-or-not;
  avoids BM25 IDF-negative pathology on small 8-prereq shared-vocab corpus
  where log((N-df+0.5)/(df+0.5)) flips negative for df > (N-1)/2).
- Algorithm uniform across tiers. MINIMAL_TRANSITIONS + MINIMAL_PREREQUISITES
  hold fallback vocabulary matching pre-0.20.0 regex alternations. Stemming
  works in both tiers.

Envelope additions: governance_source ('knowledge_base' | 'minimal'),
governance_uris plural array of 2 (alphabetical by path-tail: prerequisites
then transitions), debug.knowledge_base_url echo on override.

Strictly additive: every input that matched pre-0.20.0 word-boundary regex
still matches; stemmed variations now match too (shipping→completion,
started building→execution, stepped back→exploration, etc.).

cleanup_storage extended with two cache resets. Tool description updated.
Smoke test adds ~30 assertions (envelope shape, governance_uris, override
echo, literal+stemmed pairs per transition, BM25 priority resolution,
stemmed prereq set-intersection, uniform stemming across tiers).

Refs klappy/klappy.dev#120 (Phase 1 canon),
klappy://odd/handoffs/2026-04-20-p1-3-2-phase-2-gate-code-refactor.
klappy pushed a commit to klappy/oddkit that referenced this pull request Apr 20, 2026
…0.0)

P1.3.2 Phase 2. Consumes the two canon files landed in klappy/klappy.dev#120.

runGateAction refactored:

- fetchGateTransitions → {transitions, source} parses odd/gate/transitions.md,
  returns TransitionDef[] with detectionText fed to BM25 at gate time.
- fetchGatePrerequisites → {prerequisites, source} parses
  odd/gate/prerequisites.md, precomputes stemmedTokens: Set<string> per prereq
  at parse time (cache parse products, not microsecond derivations).
- Transition detection uses BM25 (ranking problem — one transition wins;
  rowOrder breaks score ties deterministically). Index built inline per
  request, not cached (microsecond derivation on gate's tiny vocabulary).
- Prereq evaluation uses stemmed set intersection (independent gap-or-not;
  avoids BM25 IDF-negative pathology on small 8-prereq shared-vocab corpus
  where log((N-df+0.5)/(df+0.5)) flips negative for df > (N-1)/2).
- Algorithm uniform across tiers. MINIMAL_TRANSITIONS + MINIMAL_PREREQUISITES
  hold fallback vocabulary matching pre-0.20.0 regex alternations. Stemming
  works in both tiers.

Envelope additions: governance_source ('knowledge_base' | 'minimal'),
governance_uris plural array of 2 (alphabetical by path-tail: prerequisites
then transitions), debug.knowledge_base_url echo on override.

Strictly additive: every input that matched pre-0.20.0 word-boundary regex
still matches; stemmed variations now match too (shipping→completion,
started building→execution, stepped back→exploration, etc.).

cleanup_storage extended with two cache resets. Tool description updated.
Smoke test adds ~30 assertions (envelope shape, governance_uris, override
echo, literal+stemmed pairs per transition, BM25 priority resolution,
stemmed prereq set-intersection, uniform stemming across tiers).

Refs klappy/klappy.dev#120 (Phase 1 canon),
klappy://odd/handoffs/2026-04-20-p1-3-2-phase-2-gate-code-refactor.
klappy added a commit to klappy/oddkit that referenced this pull request Apr 20, 2026
…0.0) (#118)

P1.3.2 Phase 2. runGateAction refactored to consume klappy://odd/gate/transitions
and klappy://odd/gate/prerequisites at runtime via two new helpers
(fetchGateTransitions, fetchGatePrerequisites). Transition detection via BM25
stemmed matching (ranking problem); prereq evaluation via stemmed set
intersection (independent gap-or-not, avoids BM25 IDF-negative pathology
on small shared-vocabulary corpora). Envelope declares governance_source
+ governance_uris (plural array of 2) + debug.knowledge_base_url echo.

Preview smoke 158/158 × 3 consecutive clean.

Canon-first satisfied: klappy/klappy.dev#120 + #122 merged before this PR.
klappy pushed a commit that referenced this pull request Apr 20, 2026
Ledger at odd/ledger/2026-04-20-p1-3-2-gate-canary-landed.md captures
the 2026-04-20T01:21Z-03:20Z session that shipped oddkit 0.20.0. Mirrors
the P1.3.1 ledger structure (Summary, What Shipped, What the Validator
Actually Checked, Patterns, Cleared, O-opens, Session Mechanics,
Handoff, Provenance).

Two handoffs flipped to status: superseded with superseded_by pointing
at the new ledger:

- odd/handoffs/2026-04-21-p1-3-2-gate-canary — the original two-phase
  handoff, superseded by the full P1.3.2 ship.
- odd/handoffs/2026-04-20-p1-3-2-phase-2-gate-code-refactor — the
  mid-session Phase 2 forward handoff, superseded on arrival when
  Phase 2 shipped in the same session. Left in canon as documentation
  of the 'same-session handoff anti-pattern' called out in the ledger.

Honest accounting in the ledger of the tradeoff between this session's
smoke-heavy attestation (9 runs + live self-call) and P1.3.1's Sonnet 4.6
5-corroboration validator pattern. Neither is strictly superior; they
catch different classes of issue.

Refs klappy/oddkit#118 (merged 260492c), #119 (promotion 1308245),
#120 #121 #122.
klappy added a commit that referenced this pull request Apr 20, 2026
…off-drift + bootstrap hook

Root-cause fix for the P1.3.3 process failure that shipped 0.21.0 with
two Bugbot-detectable bugs and zero independent validation. The fix is
not 'remember to wait for Bugbot next time' (orchestrators don't
persist memory) but mechanical canon that future sessions cannot avoid
encountering.

Three artifacts:

1. NEW canon/constraints/release-validation-gate.md (tier 1, 168 lines)
   Three binding rules for any oddkit ship:
   - Rule 1: no merge with active reviews still in_progress
   - Rule 2: no promotion without independent fresh-context validation
     when the PR touches load-bearing surface (orchestrate.ts, matchers,
     governance reads, response envelope, action behavior)
   - Rule 3: canon outranks any session-scoped recommendation that says
     otherwise. Same-session smoke + live self-call do NOT satisfy R2.
   Names the failure modes explicitly (Stall-as-skip, Findings-as-noise,
   Option-A-justification) so future sessions can't re-litigate them as
   judgment calls. Captures O-open P11: oddkit_gate enforces this at
   completion transitions (mechanical enforcement, not just orchestrator
   obligation).

2. NEW canon/principles/contract-governs-handoff-drift.md (tier 2, 128 lines)
   Graduates a candidate principle on its third deciding-argument
   recurrence: P1.3.1 implicit, P1.3.2 explicit (three load-bearing
   applications), P1.3.3 explicit-via-failure (the principle's absence
   shipped two prod bugs). Names the conflict resolution sequence:
   identify, default-to-canon, surface deviation, propose amendment if
   the session's judgment was right. Names the three pressure points
   where it bites hardest: time pressure, authority pressure (respect
   for prior orchestrator's ledger), scope-justified shortcuts.

3. AMEND canon/bootstrap/model-operating-contract.md (+4 lines, +1 section)
   New 'Before Shipping Code' section in Tool Rhythm. Discoverability
   hook: future sessions read the bootstrap on first turn and now
   encounter explicit references to release-validation-gate and
   contract-governs-handoff-drift before any ship work. The bootstrap
   loads on session start; canon search loads when claimed. Putting the
   pointer in bootstrap means the rule reaches the orchestrator before
   the orchestrator decides whether to search.

Provenance:
- P1.3.3 process failure: orchestrator treated Cursor Bugbot in_progress
  as non-blocking, merged PRs #120 and #121 before Bugbot completed
  review. Bugbot subsequently posted findings (one medium-severity prod
  regression, one low-severity DRY violation). The medium one broke the
  strictly-additive invariant the PR description claimed.
- 0.21.1 fix-forward branch is open at klappy/oddkit#fix/0.21.1-bugbot-stopword-and-dry
  applying both Bugbot fixes. That PR will be the FIRST application of
  this canon (independent validator dispatch is mandatory before its
  promotion merges).
- Full session post-mortem to land in P1.3.3 closeout ledger after the
  0.21.1 sequence completes under the new canon rules.

This canon binds the orchestrator that wrote it. The 0.21.1 promotion
PR cannot ship until a Sonnet 4.6 read-only validator is dispatched
and its findings are folded into the closeout ledger. That is the test
of whether the canon works: it works if it stops the same author from
making the same mistake twice.
klappy added a commit that referenced this pull request Apr 20, 2026
…off-drift + bootstrap hook

Root-cause fix for the P1.3.3 process failure that shipped 0.21.0 with
two Bugbot-detectable bugs and zero independent validation. The fix is
not 'remember to wait for Bugbot next time' (orchestrators don't
persist memory) but mechanical canon that future sessions cannot avoid
encountering.

Three artifacts:

1. NEW canon/constraints/release-validation-gate.md (tier 1, 168 lines)
   Three binding rules for any oddkit ship:
   - Rule 1: no merge with active reviews still in_progress
   - Rule 2: no promotion without independent fresh-context validation
     when the PR touches load-bearing surface (orchestrate.ts, matchers,
     governance reads, response envelope, action behavior)
   - Rule 3: canon outranks any session-scoped recommendation that says
     otherwise. Same-session smoke + live self-call do NOT satisfy R2.
   Names the failure modes explicitly (Stall-as-skip, Findings-as-noise,
   Option-A-justification) so future sessions can't re-litigate them as
   judgment calls. Captures O-open P11: oddkit_gate enforces this at
   completion transitions (mechanical enforcement, not just orchestrator
   obligation).

2. NEW canon/principles/contract-governs-handoff-drift.md (tier 2, 128 lines)
   Graduates a candidate principle on its third deciding-argument
   recurrence: P1.3.1 implicit, P1.3.2 explicit (three load-bearing
   applications), P1.3.3 explicit-via-failure (the principle's absence
   shipped two prod bugs). Names the conflict resolution sequence:
   identify, default-to-canon, surface deviation, propose amendment if
   the session's judgment was right. Names the three pressure points
   where it bites hardest: time pressure, authority pressure (respect
   for prior orchestrator's ledger), scope-justified shortcuts.

3. AMEND canon/bootstrap/model-operating-contract.md (+4 lines, +1 section)
   New 'Before Shipping Code' section in Tool Rhythm. Discoverability
   hook: future sessions read the bootstrap on first turn and now
   encounter explicit references to release-validation-gate and
   contract-governs-handoff-drift before any ship work. The bootstrap
   loads on session start; canon search loads when claimed. Putting the
   pointer in bootstrap means the rule reaches the orchestrator before
   the orchestrator decides whether to search.

Provenance:
- P1.3.3 process failure: orchestrator treated Cursor Bugbot in_progress
  as non-blocking, merged PRs #120 and #121 before Bugbot completed
  review. Bugbot subsequently posted findings (one medium-severity prod
  regression, one low-severity DRY violation). The medium one broke the
  strictly-additive invariant the PR description claimed.
- 0.21.1 fix-forward branch is open at klappy/oddkit#fix/0.21.1-bugbot-stopword-and-dry
  applying both Bugbot fixes. That PR will be the FIRST application of
  this canon (independent validator dispatch is mandatory before its
  promotion merges).
- Full session post-mortem to land in P1.3.3 closeout ledger after the
  0.21.1 sequence completes under the new canon rules.

This canon binds the orchestrator that wrote it. The 0.21.1 promotion
PR cannot ship until a Sonnet 4.6 read-only validator is dispatched
and its findings are folded into the closeout ledger. That is the test
of whether the canon works: it works if it stops the same author from
making the same mistake twice.
klappy added a commit that referenced this pull request Apr 20, 2026
…tstrap hook (P1.3.3 root-cause fix) (#126)

* canon: write release-validation-gate + graduate contract-governs-handoff-drift + bootstrap hook

Root-cause fix for the P1.3.3 process failure that shipped 0.21.0 with
two Bugbot-detectable bugs and zero independent validation. The fix is
not 'remember to wait for Bugbot next time' (orchestrators don't
persist memory) but mechanical canon that future sessions cannot avoid
encountering.

Three artifacts:

1. NEW canon/constraints/release-validation-gate.md (tier 1, 168 lines)
   Three binding rules for any oddkit ship:
   - Rule 1: no merge with active reviews still in_progress
   - Rule 2: no promotion without independent fresh-context validation
     when the PR touches load-bearing surface (orchestrate.ts, matchers,
     governance reads, response envelope, action behavior)
   - Rule 3: canon outranks any session-scoped recommendation that says
     otherwise. Same-session smoke + live self-call do NOT satisfy R2.
   Names the failure modes explicitly (Stall-as-skip, Findings-as-noise,
   Option-A-justification) so future sessions can't re-litigate them as
   judgment calls. Captures O-open P11: oddkit_gate enforces this at
   completion transitions (mechanical enforcement, not just orchestrator
   obligation).

2. NEW canon/principles/contract-governs-handoff-drift.md (tier 2, 128 lines)
   Graduates a candidate principle on its third deciding-argument
   recurrence: P1.3.1 implicit, P1.3.2 explicit (three load-bearing
   applications), P1.3.3 explicit-via-failure (the principle's absence
   shipped two prod bugs). Names the conflict resolution sequence:
   identify, default-to-canon, surface deviation, propose amendment if
   the session's judgment was right. Names the three pressure points
   where it bites hardest: time pressure, authority pressure (respect
   for prior orchestrator's ledger), scope-justified shortcuts.

3. AMEND canon/bootstrap/model-operating-contract.md (+4 lines, +1 section)
   New 'Before Shipping Code' section in Tool Rhythm. Discoverability
   hook: future sessions read the bootstrap on first turn and now
   encounter explicit references to release-validation-gate and
   contract-governs-handoff-drift before any ship work. The bootstrap
   loads on session start; canon search loads when claimed. Putting the
   pointer in bootstrap means the rule reaches the orchestrator before
   the orchestrator decides whether to search.

Provenance:
- P1.3.3 process failure: orchestrator treated Cursor Bugbot in_progress
  as non-blocking, merged PRs #120 and #121 before Bugbot completed
  review. Bugbot subsequently posted findings (one medium-severity prod
  regression, one low-severity DRY violation). The medium one broke the
  strictly-additive invariant the PR description claimed.
- 0.21.1 fix-forward branch is open at klappy/oddkit#fix/0.21.1-bugbot-stopword-and-dry
  applying both Bugbot fixes. That PR will be the FIRST application of
  this canon (independent validator dispatch is mandatory before its
  promotion merges).
- Full session post-mortem to land in P1.3.3 closeout ledger after the
  0.21.1 sequence completes under the new canon rules.

This canon binds the orchestrator that wrote it. The 0.21.1 promotion
PR cannot ship until a Sonnet 4.6 read-only validator is dispatched
and its findings are folded into the closeout ledger. That is the test
of whether the canon works: it works if it stops the same author from
making the same mistake twice.

* canon(bootstrap): reduce release-validation-gate hook to pointer to avoid DRY drift

* canon: collapse bootstrap hook to one-line pointer (Bugbot finding on PR #126)

Bugbot caught a within-canon DRY violation in the bootstrap hook: the
'Before Shipping Code' section restated all three rules from
release-validation-gate.md plus the principle from
contract-governs-handoff-drift.md in a single dense paragraph. Every
other subsection in Tool Rhythm uses one-line description + pointer.
Bugbot's finding is correct per dry-canon-says-it-once.md: 'Two
documents saying the same thing in different words... creates the same
drift risk, just between documents.'

Fix: collapse to two one-line bullets matching the convention. Full
rules live in release-validation-gate.md; the bootstrap is the
discoverability hook, not a duplicate.

Meta-instructive: this is the first application of release-validation-gate's
own discipline. The canon being merged caught me in another canon
violation (DRY) before I could merge it. Working as designed.

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
klappy added a commit that referenced this pull request Apr 20, 2026
…flip predecessor handoff to superseded

Honest closeout for P1.3.3.

Two halves, both load-bearing:

1. Technical work that shipped:
   - D5 stemmed prereq matcher (replace per-prereq regex with stemmed
     set intersection + 4 structural-test side-paths)
   - D9 cache removal (drop cachedChallengeTypeIndex; inline
     buildBM25Index per cache-fetches-and-parses)
   - cache-fetches-and-parses graduated tier-2 canon (klappy.dev#125,
     merged 3726073)
   - All landed in oddkit 0.21.0 (PR #120 merged 33ca5bf,
     PR #121 merged 25ad719)

2. Process failure that demonstrated why release-validation-gate
   needed to exist:
   - Orchestrator merged PRs #120 and #121 with Cursor Bugbot still
     in_progress, treating it as non-blocking
   - Skipped Sonnet 4.6 validator dispatch despite P1.3.2 ledger
     warning that smoke-only should not become the default
   - Bugbot subsequently posted 2 findings: medium-severity prod
     regression breaking the strictly-additive invariant the PR
     description claimed (stop-word filter dropping 'from' from
     source-named vocab), low-severity DRY violation in
     BasePrerequisite (re-listed PrereqMatchVocab fields manually
     instead of intersection)
   - Approximate prod-regression window: 04:11Z to 05:09Z + warmup
     ≈ 1h 39m on 'from'-keyword source-named matches

3. Structural fix:
   - canon/constraints/release-validation-gate.md (tier 1, 168 lines)
     — three binding rules: no merge with active reviews in_progress,
     no promotion without independent fresh-context validation when
     PR touches load-bearing surface, canon outranks any
     session-scoped recommendation
   - canon/principles/contract-governs-handoff-drift.md (tier 2,
     128 lines) — graduated on third deciding-argument recurrence
     (P1.3.1 implicit, P1.3.2 explicit, P1.3.3 explicit-via-failure)
   - canon/bootstrap/model-operating-contract.md (+4 lines) —
     'Before Shipping Code' section as discoverability hook
   - All in klappy.dev#126, merged ee9aee4
   - Captures O-open P11: oddkit_gate enforces release-validation-gate
     mechanically at execution → completion transitions

4. Fix-forward applied the new canon end-to-end:
   - oddkit#122 merged d17bc0c (0.21.1 fix branch, both Bugbot
     findings addressed, +2 regression smoke assertions)
   - Bugbot wait respected on PR #122 (completed/success)
   - Sonnet 4.6 validator dispatched (sesn_011CaERPjHi1CV4TrvKW68jB)
     against fix branch + 0.21.0 prod state + canon PR #126
   - Validator verdict: CONDITIONAL PASS (conditional only on canon
     PR #126 merging first; resolved before promotion)
   - oddkit#123 merged 2c5d652b (promotion to prod)
   - Bugbot wait respected on PR #123 (~225s, completed/success)
   - Prod 0.21.1 verified live; live self-call confirms 'from' fix

Meta-instructive moment: Bugbot caught a within-canon DRY violation
on the bootstrap hook in PR #126 itself. The first application of
release-validation-gate's discipline caught me in another canon
violation (dry-canon-says-it-once) before I could merge it. Working
as designed.

Predecessor handoff (odd/handoffs/2026-04-20-p1-3-3-challenge-revisit.md)
flipped to status: superseded with explicit supersession_note naming
the 'Option A is fine for P1.3.3' line in its Validation Plan section
as the recommendation that produced the incident. Future sessions
reading the superseded handoff will be redirected here.

Carry-forward O-opens updated:
- P11 NEW: oddkit_gate mechanical enforcement of release-validation-gate
- P12 NEW: tokenize() audit pass (any caller using canon vocab/input
  should explicitly pass stop-word set)
- P2/P3/P5/P6/P8/P9/P10 carried from prior sweeps unchanged
klappy added a commit that referenced this pull request Apr 20, 2026
…flip predecessor handoff to superseded (#127)

Honest closeout for P1.3.3.

Two halves, both load-bearing:

1. Technical work that shipped:
   - D5 stemmed prereq matcher (replace per-prereq regex with stemmed
     set intersection + 4 structural-test side-paths)
   - D9 cache removal (drop cachedChallengeTypeIndex; inline
     buildBM25Index per cache-fetches-and-parses)
   - cache-fetches-and-parses graduated tier-2 canon (klappy.dev#125,
     merged 3726073)
   - All landed in oddkit 0.21.0 (PR #120 merged 33ca5bf,
     PR #121 merged 25ad719)

2. Process failure that demonstrated why release-validation-gate
   needed to exist:
   - Orchestrator merged PRs #120 and #121 with Cursor Bugbot still
     in_progress, treating it as non-blocking
   - Skipped Sonnet 4.6 validator dispatch despite P1.3.2 ledger
     warning that smoke-only should not become the default
   - Bugbot subsequently posted 2 findings: medium-severity prod
     regression breaking the strictly-additive invariant the PR
     description claimed (stop-word filter dropping 'from' from
     source-named vocab), low-severity DRY violation in
     BasePrerequisite (re-listed PrereqMatchVocab fields manually
     instead of intersection)
   - Approximate prod-regression window: 04:11Z to 05:09Z + warmup
     ≈ 1h 39m on 'from'-keyword source-named matches

3. Structural fix:
   - canon/constraints/release-validation-gate.md (tier 1, 168 lines)
     — three binding rules: no merge with active reviews in_progress,
     no promotion without independent fresh-context validation when
     PR touches load-bearing surface, canon outranks any
     session-scoped recommendation
   - canon/principles/contract-governs-handoff-drift.md (tier 2,
     128 lines) — graduated on third deciding-argument recurrence
     (P1.3.1 implicit, P1.3.2 explicit, P1.3.3 explicit-via-failure)
   - canon/bootstrap/model-operating-contract.md (+4 lines) —
     'Before Shipping Code' section as discoverability hook
   - All in klappy.dev#126, merged ee9aee4
   - Captures O-open P11: oddkit_gate enforces release-validation-gate
     mechanically at execution → completion transitions

4. Fix-forward applied the new canon end-to-end:
   - oddkit#122 merged d17bc0c (0.21.1 fix branch, both Bugbot
     findings addressed, +2 regression smoke assertions)
   - Bugbot wait respected on PR #122 (completed/success)
   - Sonnet 4.6 validator dispatched (sesn_011CaERPjHi1CV4TrvKW68jB)
     against fix branch + 0.21.0 prod state + canon PR #126
   - Validator verdict: CONDITIONAL PASS (conditional only on canon
     PR #126 merging first; resolved before promotion)
   - oddkit#123 merged 2c5d652b (promotion to prod)
   - Bugbot wait respected on PR #123 (~225s, completed/success)
   - Prod 0.21.1 verified live; live self-call confirms 'from' fix

Meta-instructive moment: Bugbot caught a within-canon DRY violation
on the bootstrap hook in PR #126 itself. The first application of
release-validation-gate's discipline caught me in another canon
violation (dry-canon-says-it-once) before I could merge it. Working
as designed.

Predecessor handoff (odd/handoffs/2026-04-20-p1-3-3-challenge-revisit.md)
flipped to status: superseded with explicit supersession_note naming
the 'Option A is fine for P1.3.3' line in its Validation Plan section
as the recommendation that produced the incident. Future sessions
reading the superseded handoff will be redirected here.

Carry-forward O-opens updated:
- P11 NEW: oddkit_gate mechanical enforcement of release-validation-gate
- P12 NEW: tokenize() audit pass (any caller using canon vocab/input
  should explicitly pass stop-word set)
- P2/P3/P5/P6/P8/P9/P10 carried from prior sweeps unchanged
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant