What shipped since the prior handoff
| PR | Repo | Merged SHA | Purpose |
|---|---|---|---|
| #116 | klappy/oddkit | 71ee6ed | feat(challenge): governance_source envelope + peer governance_uris (0.19.0). Squash-merged. |
| #117 | klappy/oddkit | 1b4fce8 | main → 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. No regressions.
Validator record: agent_011CaE62pg6jJ7yYpRj1o9Do / sesn_011CaE63LZhPUX1UAZPbiV7n. Disposition: VERIFIED, 5/5, zero blockers, zero non-blocking advisories. External corroboration pattern (main-bytes grep, live curl ×3 shapes, canon citation, 9-mode curl, 3× independent smoke) is now the default for the sweep.
What is cleared from the prior handoff
- [O-open P1] Challenge envelope retrofit — closed by #116/#117.
What remains open
- [O-open P1] P1.3.2 — gate vodka refactor + envelope. See scope section below. This is the next atomic unit.
- [O-open P2]
getIndexstrict-mode (skipBaselineFallback) — now affects telemetry_policy + encode + challenge. Same limitation, one fix. Pull into a later P1.3.x PR if a tool exercises the code path; otherwise standalone PR. - [O-open P3] Handoff text corrections on klappy.dev. Two deferred: (a) P1.2 handoff "bundled baseline" → "minimal fallback"; (b) P1.3 handoff three
discover*→fetch*names. Low priority. Bundle both into a single tiny canon PR at next session's natural PR window. - [O-open P4] Canon principle on contract-governs-handoff-drift. Now standing — three recurrences documented (P1.2 ledger's two + P1.3.1 ledger's one). Principle draft text in the P1.3.1 ledger's §"Canon Principle Now Standing" section. Draft location:
canon/principles/contract-governs-handoff-drift.md. Bundle into the handoff-text-corrections PR. - [O-open P5]
workers/baseline/bundled-tier build pipeline — separate epoch. Deferred until sweep surfaces concrete need or TruthKit forces the question. - [O-open P6] CHANGELOG render route on klappy.dev +
version_notes_urlon MCPinitialize. Low priority; slot into a tool-envelope PR window.
P1.3.2 scoperetrofit oddkit_gate
The delta (larger than P1.3.1)
Gate has zero canon integration today. runGateAction at workers/src/orchestrate.ts hardcodes:
- Transition detection (
detectTransition(input)— regex-based mode recognition) - Transition-specific prerequisites (
problem_defined,constraints_reviewed,decisions_locked,dod_defined,irreversibility_assessed,constraints_satisfied,dod_met,artifacts_present) - DoD criteria and evidence requirements
All of this is code, not canon. The sweep thesis says: canon defines vocabulary; code must not hardcode interpretation. Gate is currently the most pure vodka-anti-pattern violation of any remaining tool in the sweep.
Unlike P1.3.1, the canon governance docs for gate do not yet exist in the klappy.dev repo (no odd/gate/ directory). This session will need to write canon first, then refactor code — preserving the "canon-first rule is absolute" from the bootstrap contract.
Work to ship — two-phase scope
Phase 1: write canon (klappy.dev PR, lands first).
- Create
odd/gate/transitions.md— the canonical list of mode transitions (e.g.exploration → planning,planning → execution,* → completion) with a markdown table of detection patterns, prerequisite IDs, and governance references. - Create
odd/gate/prerequisites.md— the canonical definitions of each prerequisite ID (problem_defined,constraints_reviewed, etc.), matching the pattern ofodd/challenge/base-prerequisites.md: each row is(id, description, check, gap_message). - Optionally
odd/gate/completion-criteria.md— DoD and artifact-presence checks if they are sufficiently distinct from prerequisites to warrant their own file. - Merge the klappy.dev PR first. Canon must be live before the oddkit PR can reference it.
Phase 2: refactor oddkit_gate (oddkit PR, lands second).
- Add
fetchGateTransitions(fetcher, knowledgeBaseUrl)→{ transitions, source }andfetchGatePrerequisites(fetcher, knowledgeBaseUrl)→{ prerequisites, source }helpers, following the P1.3.1 per-helper domain-noun tuple pattern. - Refactor
runGateActionto read transitions and prerequisites from canon at runtime; keep the current hardcoded logic as the"minimal"fallback (matches encode's soft-fallback pattern, not challenge's hollow-response pattern — gate cannot hollow out without becoming useless, so the minimal tier must preserve today's behavior exactly). - Declare
governance_sourceandgovernance_urisin the response envelope. Per D4 principle from P1.3.1: because gate will read two peer governance files (transitions + prerequisites), usegovernance_uris(plural array). Shape parity with challenge. - Echo
debug.knowledge_base_urlon overrides. - Extend
workers/test/canon-tool-envelope.smoke.mjswith gate assertions matching the P1.3.1 pattern: envelope shape,governance_sourcevalid enum,governance_urislength 2 (or 3 if completion-criteria ships as separate file), override behavior, and at minimum one assertion per defined transition type. - CHANGELOG
[0.20.0]entry with Added / Changed / Fixed / Known-limitations. MINOR bump per sweep precedent (encode 0.18.0, challenge 0.19.0). - Tool description update to reference the two governance docs and the envelope signal.
Known subtleties
- Canon-first is mandatory. Unlike P1.3.1, this session cannot write oddkit code and then "update canon as needed" — the oddkit PR references klappy.dev files that must exist at the SHA the worker pins. Standing rule: klappy.dev PR merged to main before oddkit PR is even opened.
- Back-compat is critical. Unlike encode and challenge (where the envelope changes were additive), gate's hardcoded logic is the only behavior callers have today. The minimal fallback must preserve exact current behavior. If a canon doc is missing or malformed, gate must still return the same transitions and prerequisites it does today — just with
governance_source: "minimal"in the envelope so callers see the degradation. - The
detectTransitionregex may not belong in canon. Detection patterns are low-level parsing; canon governs vocabulary and policy. Candidate split: keepdetectTransitionin code as the parser, have it emit a transition key, and read the transition-specific prerequisite set from canon by key. Mirrors how challenge's parser stays in code but the per-type vocabulary lives in canon. - Two URIs vs three URIs for
governance_uris. If completion-criteria ships as a third file, the array has three entries. If transitions and prerequisites alone cover the contract, the array has two. Either is coherent under D4's peer-array principle; decide during planning based on how the canon docs actually split. - This session may want to split into two sessions. Phase 1 (canon) + Phase 2 (code) is a lot for one session if canon discussion goes deep. Acceptable to land Phase 1 in session A and Phase 2 in session B. The forward handoff from session A would then be "P1.3.2 Phase 2".
Out of scope (deferred)
- Any other tool in the sweep (preflight, validate, orient, search, catalog, cleanup, version) — subsequent P1.3.x PRs.
getIndexstrict-mode — still deferred.workers/baseline/build pipeline — still deferred.- Any edits to existing tools' envelopes — gate only.
Path 3 workflow
Same shape as P1.3.1, with the Phase 1 canon PR inserted first:
Phase 1 (klappy.dev):
- Clone
klappy/klappy.devinto/home/claude/work/klappy.dev, cut branchgate/canon-governance-docsoff main. - Write
odd/gate/transitions.md,odd/gate/prerequisites.md(and possiblyodd/gate/completion-criteria.md). Followcanon/meta/frontmatter-schema— native YAML types only. Useodd/challenge/base-prerequisites.mdas the structural template. - Commit. Push. Open PR via
urllib.request+json.dumps. - Optional lightweight validation: use
oddkit_preflightto confirm Writing Canon gate criteria are met before opening PR. - Squash-merge on self-review (canon docs are lower-risk than code — no need for Sonnet 4.6 validator unless the docs encode contract semantics that need pressure-testing).
Phase 2 (klappy/oddkit):
- Clone
klappy/oddkit, cut branchgate/governance-source-envelopeoff main. - Apply edits locally (canon discovery helpers + envelope retrofit). Run
npm run typecheckinworkers/. Runnode workers/test/governance-parser.test.mjs— must stay at 105/105 (or grow if gate-specific parser tests are added). - Commit (version bump to 0.20.0, githook enforces sync).
- Push. CF auto-deploys to preview. Wait ~25s. Smoke preview with updated script. 3 consecutive clean.
- Open PR via
urllib.request+json.dumps. - Dispatch Sonnet 4.6 read-only validator with required external corroborations (template from P1.3.1):
- Main-branch
orchestrate.tsbytes grep confirming gate has no canon integration pre-refactor - Live curl against preview for envelope shape +
governance_sourcevalue oddkit_getcitation oncore-governance-baseline§Runtime Invariantsoddkit_geton the new canon files (odd/gate/transitions,odd/gate/prerequisites) to confirm they landed in Phase 1- 3× independent smoke
- Main-branch
- Accept VERIFIED. Squash-merge. Main-preview smoke 3× clean. Open main → prod PR. Merge. Prod smoke 3× clean.
Estimate: Phase 1 canon writing 30–60 min, Phase 2 code + validation 90–150 min. Total may warrant split across two sessions.
Standing rules (carried from prior handoffs, unchanged)
- Call
oddkit_timefirst every turn. Pass the priorserver_timeasreference. No inferred timestamps. - Declare epistemic mode out loud. Planning until PRD is written and contract decisions are named; execution after the gate; validation via Sonnet 4.6 (context-break required, same-session self-review is not validation).
- Search canon before asking. Especially before claiming anything about gate's current state or the core-governance-baseline contract.
- Ground framing in code + canon, not in the latest handoff. Per P1.3.1 ledger §"Canon Principle Now Standing" — three recurrences justify this as a named principle. If a handoff's word choice disagrees with a contract's enum or a live code reality, the contract/code wins.
- PRD before code. Write the plan as a file before touching source. Articulation is the deliverable during planning, not prose in the chat window. P1.3.1 shipped with zero advisories specifically because of PRD-first discipline.
- During execution, produce artifacts, not questions. Reversion requires one sentence naming the specific unknown.
- Canon-first is absolute. This session especially: Phase 1 klappy.dev PR must merge before Phase 2 oddkit PR is opened. Do not write oddkit code that references canon files that do not yet exist.
- No force-push without
git fetchfirst. Remote state may have diverged. - GitHub API:
urllib.request+json.dumps, never bash heredoc. The PAT-in-command footgun and JSON-escaping pitfalls are documented; use the proven path. $HOME=/rootin the managed-agent cloud container (not/home/useras the skill doc historically suggested).- Do NOT dispatch Opus 4.7 execution agents to klappy/oddkit. Safety-layer false-positive blocks them. Sonnet 4.6 read-only validation is fine; orchestrator-applies for writes.
- Do NOT run
wrangler deploymanually. Githooks + CF auto-deploy handle the pipeline. - Branch preview slug rule: slashes AND dots → hyphens.
gate/governance-source-envelope→gate-governance-source-envelope. - Prod deploy warmup pattern: first smoke run immediately after prod flip can flake as isolates serve mixed versions. Accept 3 consecutive clean runs as the "prod clean" gate.
Reference materialread this at session start
Priority order for fresh-session reading:
- This doc.
klappy://canon/bootstrap/model-operating-contract— the evolving operating contract.klappy://odd/ledger/2026-04-20-p1-3-1-challenge-canary-landed— P1.3.1 closeout with the D4 pivot rationale, validator corroboration pattern, and the three-recurrence evidence for the contract-governs-handoff-drift principle.klappy://canon/constraints/core-governance-baseline— the governing contract. Re-read §Runtime Invariants and §What-Ships-in-Baseline (gate's canon docs are candidates for Required-in-Baseline if the build pipeline ever ships).klappy://canon/principles/vodka-architecture— the principle this session is applying. Gate is the tool where the anti-pattern has survived longest; this session ends its run.klappy://canon/principles/agent-self-report-under-stress— for the validator dispatch.klappy://canon/meta/frontmatter-schema— native YAML types only, critical for Phase 1 canon writing.klappy://odd/challenge/base-prerequisites— structural template forodd/gate/prerequisites.md.klappy://odd/challenge/stakes-calibration— reference for table-driven canon that tools parse at runtime.
Reference PRs for canary pattern (same-shape):
klappy/oddkit#108/#109— telemetry_policy canary (reference envelope).klappy/oddkit#114— encode canary completion (P1.2).klappy/oddkit#116— challenge canary completion (P1.3.1, most recent precedent).
Thin prompt for the next session
Resume P1.3.2 per klappy://odd/handoffs/2026-04-21-p1-3-2-gate-canary.
Current state: 0.19.0 in prod (oddkit.klappy.dev), challenge envelope now
declares governance_source + governance_uris (plural array of 4 peer canon
URIs), gate remains the purest remaining vodka anti-pattern in the sweep.
P1.3.1 formally closed at klappy://odd/ledger/2026-04-20-p1-3-1-challenge-canary-landed.
Two-phase scope: (1) write canon docs odd/gate/transitions.md and
odd/gate/prerequisites.md on klappy.dev and merge — canon-first absolute.
(2) refactor oddkit runGateAction to read from canon via {data, source}
helpers, add governance_source + governance_uris (plural) to envelope,
ship as 0.20.0. Orchestrator applies on both repos, Sonnet 4.6 validates
oddkit Phase 2.
Read the handoff. Run the gauntlet on gate's current state + the
core-governance-baseline contract + vodka-architecture principle. Write
the PRD as a file before touching source. May split across two sessions
if Phase 1 canon discussion goes deep.
Credentials in project instructions. No Opus 4.7 execution agents to
oddkit.
Provenance
- Prior session ledger:
odd/ledger/2026-04-20-p1-3-1-challenge-canary-landed.md— full retrospective for the P1.3.1 arc. - Prior handoff:
odd/handoffs/2026-04-20-p1-3-challenge-canary.md— superseded by this document. - Merged PRs this cycle:
klappy/oddkit#116(feat),klappy/oddkit#117(promotion). - Target code at current main:
workers/src/orchestrate.tsrunGateAction(currently ~L2097–L2200 post-P1.3.1 edits). Zero canon integration pre-refactor.