klappy.dev

The StylebookHandoffs

Handoff

P1.3.2 oddkit_gate Vodka Refactor + governance_source Envelope

What shipped since the prior handoff

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. 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] getIndex strict-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_url on MCP initialize. 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).

  1. 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.
  2. Create odd/gate/prerequisites.md — the canonical definitions of each prerequisite ID (problem_defined, constraints_reviewed, etc.), matching the pattern of odd/challenge/base-prerequisites.md: each row is (id, description, check, gap_message).
  3. Optionally odd/gate/completion-criteria.md — DoD and artifact-presence checks if they are sufficiently distinct from prerequisites to warrant their own file.
  4. 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).

  1. Add fetchGateTransitions(fetcher, knowledgeBaseUrl) → { transitions, source } and fetchGatePrerequisites(fetcher, knowledgeBaseUrl) → { prerequisites, source } helpers, following the P1.3.1 per-helper domain-noun tuple pattern.
  2. Refactor runGateAction to 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).
  3. Declare governance_source and governance_uris in the response envelope. Per D4 principle from P1.3.1: because gate will read two peer governance files (transitions + prerequisites), use governance_uris (plural array). Shape parity with challenge.
  4. Echo debug.knowledge_base_url on overrides.
  5. Extend workers/test/canon-tool-envelope.smoke.mjs with gate assertions matching the P1.3.1 pattern: envelope shape, governance_source valid enum, governance_uris length 2 (or 3 if completion-criteria ships as separate file), override behavior, and at minimum one assertion per defined transition type.
  6. CHANGELOG [0.20.0] entry with Added / Changed / Fixed / Known-limitations. MINOR bump per sweep precedent (encode 0.18.0, challenge 0.19.0).
  7. 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 detectTransition regex may not belong in canon. Detection patterns are low-level parsing; canon governs vocabulary and policy. Candidate split: keep detectTransition in 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.
  • getIndex strict-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):

  1. Clone klappy/klappy.dev into /home/claude/work/klappy.dev, cut branch gate/canon-governance-docs off main.
  2. Write odd/gate/transitions.md, odd/gate/prerequisites.md (and possibly odd/gate/completion-criteria.md). Follow canon/meta/frontmatter-schema — native YAML types only. Use odd/challenge/base-prerequisites.md as the structural template.
  3. Commit. Push. Open PR via urllib.request + json.dumps.
  4. Optional lightweight validation: use oddkit_preflight to confirm Writing Canon gate criteria are met before opening PR.
  5. 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):

  1. Clone klappy/oddkit, cut branch gate/governance-source-envelope off main.
  2. Apply edits locally (canon discovery helpers + envelope retrofit). Run npm run typecheck in workers/. Run node workers/test/governance-parser.test.mjs — must stay at 105/105 (or grow if gate-specific parser tests are added).
  3. Commit (version bump to 0.20.0, githook enforces sync).
  4. Push. CF auto-deploys to preview. Wait ~25s. Smoke preview with updated script. 3 consecutive clean.
  5. Open PR via urllib.request + json.dumps.
  6. Dispatch Sonnet 4.6 read-only validator with required external corroborations (template from P1.3.1):
    • Main-branch orchestrate.ts bytes grep confirming gate has no canon integration pre-refactor
    • Live curl against preview for envelope shape + governance_source value
    • oddkit_get citation on core-governance-baseline §Runtime Invariants
    • oddkit_get on the new canon files (odd/gate/transitions, odd/gate/prerequisites) to confirm they landed in Phase 1
    • 3× independent smoke
  7. 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_time first every turn. Pass the prior server_time as reference. 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 fetch first. 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=/root in the managed-agent cloud container (not /home/user as 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 deploy manually. 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:

  1. This doc.
  2. klappy://canon/bootstrap/model-operating-contract — the evolving operating contract.
  3. 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.
  4. 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).
  5. 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.
  6. klappy://canon/principles/agent-self-report-under-stress — for the validator dispatch.
  7. klappy://canon/meta/frontmatter-schema — native YAML types only, critical for Phase 1 canon writing.
  8. klappy://odd/challenge/base-prerequisites — structural template for odd/gate/prerequisites.md.
  9. 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.ts runGateAction (currently ~L2097–L2200 post-P1.3.1 edits). Zero canon integration pre-refactor.

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