Skip to content

handoff: P1.3.4 encode canon-parity refactor (D5 + D9) — closes the sweep#128

Merged
klappy merged 1 commit into
mainfrom
handoff/p1-3-4-encode-canon-parity
Apr 20, 2026
Merged

handoff: P1.3.4 encode canon-parity refactor (D5 + D9) — closes the sweep#128
klappy merged 1 commit into
mainfrom
handoff/p1-3-4-encode-canon-parity

Conversation

@klappy
Copy link
Copy Markdown
Owner

@klappy klappy commented Apr 20, 2026

Forward handoff for the next session: P1.3.4 — migrate oddkit_encode's trigger-word classifier from regex alternation to stemmed set intersection (D5) and remove the module-level cachedEncodingTypes cache (D9). This closes the canon-parity sweep.

Why this is next

Encode is the only tool in the sweep whose matcher still uses literal regex alternation:

new RegExp("\\b(word1|word2|...)\\b", "i")

The trigger vocabulary itself is already governance-driven — runEncodeAction's parse loop reads ## Trigger Words from each odd/encoding-types/*.md at runtime. What's NOT governance-driven and NOT stemmed is the matcher. Input "deciding" does not match canon vocab decided because \b(decided|decision|chose|...) is literal word-boundary alternation. Input "realizing" does not match realized. Same bug class challenge had pre-0.21.0.

Gate (P1.3.2) and challenge (P1.3.3) both closed their vodka anti-pattern remnants. Encode is the last holdout.

What's in the handoff

  • Bootstrap-first instructions. First turn of the next session: oddkit_time, oddkit_get on klappy://canon/bootstrap/model-operating-contract, read the "Before Shipping Code" section, follow the pointers to release-validation-gate and contract-governs-handoff-drift.
  • Current state: prod at 0.21.1, main at d17bc0c, canon at bc6bfb1/ee9aee4. No pending canon-first prereqs.
  • Scope — exactly two items: D5 stemmed matcher for EncodingTypeDef.triggerRegex → stemmedTokens, and D9 removal of cachedEncodingTypes / siblings at L506–508.
  • Load-bearing design callout. The no break comment at orchestrate.ts L1161 is canon-by-convention — parseUnstructuredInput emits one artifact per matching type intentionally ("We must never deploy without tests" is both Decision AND Constraint). The refactor preserves both the first-match path (L1123, batch-untagged) and the multi-match path (L1165, parseUnstructuredInput) with their existing contracts.
  • Stop-word caveat explicit. Pass new Set() to tokenize() on both sides. Canon trigger vocab includes going with, committed to, turns out, next step, blocked by, must not, haven't decided — all contain stop-words. P1.3.3 Bug feat(website): implement public website for PRD v1.0 #1 is the concrete precedent.
  • Stemmer gemination caveat. From P1.3.2. Audit each canon trigger vocab for geminating inflections before shipping.
  • Exact line numbers for every touch point.
  • Smoke expansion — 5 new regression assertions (inflection match, stop-word survival, multi-type preservation, first-match preservation, cache-removal structural check). Target smoke count: 176–177 pass.
  • CHANGELOG sketch for 0.22.0.
  • Validation plan — single path, binding. Deliberately no "Option A vs. Option B" section. The P1.3.3 handoff had one and it produced the P1.3.3 incident. This handoff makes the release-validation-gate path mechanical: wait for Bugbot on both feature + promotion PRs, dispatch Sonnet 4.6 validator (5-corroboration adapted for encode) before promotion, fold findings into closeout ledger, then merge.
  • Attestation mapping table — each constraint tied to the specific gate that satisfies it.
  • Carry-forward O-opens updated from P1.3.3, including P11 (mechanical gate enforcement of release-validation-gate) flagged as the natural post-sweep follow-up.
  • Thin prompt at the bottom for fast next-session context load.

Provenance notes

The handoff is explicit about its own authoring context: it's written immediately after P1.3.3 — the session that demonstrated why release-validation-gate needed to exist. The validation plan is single-path on purpose. If the next session reads anything in this handoff that conflicts with canon, canon wins per contract-governs-handoff-drift.

Writing-canon gate satisfied

  • Blockquote with compressed argument ✓
  • Summary sections (Bootstrap + Current state) ✓
  • Descriptive headers (each section header tells the story when scanned) ✓
  • Frontmatter well-formed, derives_from references real ledgers + canon ✓
  • Cross-references to related canon throughout ✓

What closing the sweep unlocks

Before sweep After sweep (post-0.22.0)
Encode uses regex alternation Stemmed set intersection
Challenge uses regex per check Stemmed set intersection + 4 structural flags (shipped 0.21.1)
Gate uses hardcoded word-boundary regex cascade BM25 for transitions, set intersection for prereqs (shipped 0.20.0)
3 module-level derivation caches 0 module-level derivation caches (fetch layer caches still)
No canon governing the release pipeline release-validation-gate + contract-governs-handoff-drift (shipped ee9aee4)

Next move after the sweep closes: P11 — mechanical enforcement of release-validation-gate in oddkit_gate at execution → completion transitions. That's a capability add, not a parity ship — candidate for an epoch transition (E0008.4 or E0009), not P1.3.5.

Refs

  • Predecessor ledger: klappy://odd/ledger/2026-04-20-p1-3-3-challenge-canon-parity-landed
  • Release validation gate (binding): klappy://canon/constraints/release-validation-gate
  • Contract governs handoff drift (binding): klappy://canon/principles/contract-governs-handoff-drift
  • Cache fetches and parses: klappy://canon/principles/cache-fetches-and-parses
  • Vodka architecture: klappy://canon/principles/vodka-architecture
  • Managed agents skill (Rule 2 dispatch): /mnt/skills/user/managed-agents/SKILL.md

Note

Low Risk
Adds a new handoff markdown document only; no production code or configuration changes are included.

Overview
Adds a new odd/handoffs/2026-04-20-p1-3-4-encode-canon-parity.md handoff describing the next session’s planned oddkit_encode canon-parity refactor: switch the trigger-word matcher from regex alternation to stemmed token set intersection (while preserving first-match vs multi-match semantics) and remove the in-process cachedEncodingTypes cache per cache-fetches-and-parses.

Includes an updated, single-path validation plan aligned to release-validation-gate, plus concrete smoke-test assertions and a 0.22.0 changelog sketch to guide the implementation and release.

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

…gex matcher in the sweep)

Writes the forward handoff for the next session to pick up P1.3.4 —
the LAST regex-matcher ship in the canon-parity sweep. Same D5 +
D9 pattern that P1.3.2 applied to gate and P1.3.3 applied to
challenge, now for encode's triggerRegex classifier and the
cachedEncodingTypes module-level cache.

Key substantive points:

- Confirms the premise: encode's vocabulary is already
  governance-driven (reads ## Trigger Words from odd/encoding-types/*.md
  at runtime), but the matcher is literal regex alternation with no
  stemming. Input 'deciding' does not match canon vocab 'decided'.
  Same bug class challenge had pre-0.21.0.

- Calls out the load-bearing multi-type design at orchestrate.ts L1161:
  'no break' comment is canon-by-convention and the refactor must
  preserve both semantics (batch-untagged first-match and
  parseUnstructuredInput multi-match). Handoff explicitly names it so
  the next session does not accidentally collapse it into single-match.

- Carries forward the P1.3.3 Bug #1 stop-word lesson: pass new Set() as
  second arg to tokenize() on both sides. Canon trigger vocab includes
  stop-word phrases ('going with', 'committed to', 'turns out', 'must
  not', etc.) — filtering them would recreate the strictly-additive
  invariant break.

- Validation plan is SINGLE-PATH and binding per release-validation-gate.
  No Option A vs Option B. The P1.3.3 handoff's optionality section
  produced the P1.3.3 incident; this handoff does not repeat that mistake.
  'Before merging the main → prod promotion PR' explicitly requires
  Sonnet 4.6 validator dispatch with the 5-corroboration pattern adapted
  for encode.

- Attestation mapping table ties each constraint (release-validation-gate
  Rules 1/2/3, cache-fetches-and-parses, vodka-architecture,
  contract-governs-handoff-drift) to the specific gate that satisfies it.

- Carry-forward O-opens updated: P11 (mechanical gate enforcement of
  release-validation-gate) flagged as the natural follow-up after the
  sweep closes — a capability add, not a parity ship, so candidate for
  epoch transition rather than P1.3.5.

- Thin prompt at the bottom for fast next-session context load.

Target: 45-75 min to prod, ~40-line code delta, ship as oddkit 0.22.0.
Closes the canon-parity sweep.
@klappy
Copy link
Copy Markdown
Owner Author

klappy commented Apr 20, 2026

Release Validation Gate — Disposition

Rule 1 (active reviews): Cursor Bugbot completed/success on c0903817, no findings. All checks completed. Rule 1 satisfied.

Rule 2 (independent validator for load-bearing surface): This PR is doc-only — adds odd/handoffs/2026-04-20-p1-3-4-encode-canon-parity.md, zero workers/src/ changes, zero canon changes. Per klappy://canon/constraints/release-validation-gate the Rule 2 trigger is "any change to load-bearing surface" and the not-triggered list explicitly includes "Documentation-only PRs." Rule 2 not triggered; no validator dispatch required.

Rule 3 (canon outranks session artifacts): This PR's content is itself a session artifact. Its validation plan section is written in single-path form specifically because the P1.3.3 handoff's optionality produced the P1.3.3 incident. If the next session reads anything in this handoff that contradicts canon, canon wins per contract-governs-handoff-drift. The handoff's Provenance section names this explicitly.

Merging.

@klappy klappy merged commit 2b07680 into main Apr 20, 2026
1 check passed
klappy pushed a commit that referenced this pull request Apr 20, 2026
…elease-validation-gate

Closeout ledger for the oddkit 0.22.0 ship cycle (PRs #124, #125, #127, #128, #129).
First post-canon application of release-validation-gate (tier 1, landed earlier today
in P1.3.3). Documents the retroactive-closure pattern used to heal PR #127's
validation gap without reverting, and names the four criteria that make retroactive
closure legitimate.

Key contents:
- Summary of what shipped (two envelope-conformance fixes into 0.22.0)
- D3 names the retroactive-closure pattern and its four legitimacy criteria
- Timeline of all agent/validator sessions with evidence trail
- L2 distinguishes feature-branch validators from promotion-PR validators under
  canon's strict reading
- L3 captures the Managed-Agent-bypass workaround for orchestrator-IP rate limits
- H2 carries forward P11 (oddkit_gate mechanical enforcement of release-validation-gate)

Writing canon gate satisfied: blockquote with compressed argument, Summary section,
descriptive headers.

Encoded via oddkit_encode (governance_source: knowledge_base) — 18 DOLCHE artifacts
folded into D/O/L/C/H sections.
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