SummaryP1.1 Is Shipped and Live; P1.2 Is the Next Arc
Shipped to production this session (2026-04-19):
klappy/klappy.dev#112— DOLCHEO canon umbrella + per-type encoding governance. Merged atd030871. Addscanon/definitions/dolcheo-vocabulary.md(228 lines, tier 2 canon, the umbrella contract),odd/encoding-types/encode.md(53 lines, letter E governance),odd/encoding-types/open.md(60 lines, letter O facet=open governance), plus a See Also cross-ref onodd/encoding-types/observation.md.klappy/klappy.dev#109— Agent-team-pilot session ledger, merged at526c2051after an editorial fix renaming the session-open### Open items (forward-pointing)header to### Session-open queue (planned)to distinguish the planned-queue-at-open from the forward-pointing-at-close snapshot. Bugbot's duplicate-section finding resolved.klappy/klappy.dev#110—canon/principles/agent-self-report-under-stress.md(tier 2). Merged at62581600.klappy/klappy.dev#111— The handoff doc that bootstrapped the 2026-04-19 session. Merged atf5c8999b.klappy/klappy.dev#113— DOLCHEO cleanup: flippeddocs/oddkit/proactive/dolche-vocabulary.mdtostatus: supersededwithsuperseded_by:pointer, added banner. Acknowledged the intentional O/O-open collision inodd/encoding-types/how-to-write-encoding-types.md. Merge status: check at session start.
Prod MCP state: https://oddkit.klappy.dev/mcp at oddkit v0.16.0, serving from https://raw.githubusercontent.com/klappy/klappy.dev/main. Search index size 514+ (depending on whether #113 merged before this handoff was written). All DOLCHEO artifacts verified live via oddkit_get and oddkit_search.
Not started in this session and deferred to you: P1.2 (below) — no edits on klappy/oddkit in this session. The repo is untouched since the prior session's prod promotion at fae2df6 / v0.16.0.
P1.2 scopeone PR on klappy/oddkit
Two concerns, one PR, because they are the same work: the tool can't do batch mode with a hardcoded vocabulary, and the canary refactor is what makes the vocabulary canon-resolved.
Feature half — batch-mode input
- Accept paragraph-split
inputwith optional per-paragraph prefixes[D],[O],[L],[C],[H],[E]. Six unique letters (DOLCHEO uses seven types but the letter registry is six, per the umbrella's "Both Os remain O" section). An[O-open]subtype hint is accepted and resolves to letterOwith facetopen— seeodd/encoding-types/open.mdfor the facet schema. - Return a per-artifact array instead of a single collapsed blob. Each artifact gets its own quality score, persist_required flag, gap messages, and the canon envelope (governance_source, server_time, etc).
- Single-artifact input without any prefix must still work — existing heuristic-based classification stays as the fallback path. Backward behavior preserved.
- Tool response envelope on batch input:
{ action: "encode", result: { artifacts: [...] }, ... }withartifactsas the new array. For single-artifact / no-prefix input,resultstays flat as today, or wrap inartifacts: [single]for uniformity — implementer's call, but document whichever shape lands.
Refactor half — prompt-over-code canary for encode
Same pattern as telemetry_policy in klappy/oddkit PRs #108 and #109 (the completed reference). Read the vocabulary from canon at runtime via KnowledgeBaseFetcher with three-tier resolution.
Tier 1 (preferred): live canon — fetch klappy://canon/definitions/dolcheo-vocabulary from DEFAULT_KNOWLEDGE_BASE_URL (which points at klappy.dev main), parse the Seven Letters section and the tool-level implications.
Tier 2 (fallback): bundled baseline — a minimal DOLCHEO vocabulary shipped with the worker, used when live canon is unreachable. Just the six letter → name mapping plus the Open facet rule. Enough to keep encode working without external I/O.
Tier 3 (fail-loud): if both live and bundled sources return nothing parseable, return an actionable error envelope — not a silent default. Consistent with the core-governance-baseline contract (canon/constraints/core-governance-baseline.md).
Response envelope must declare governance_source: "knowledge_base" | "bundled" | "minimal" so callers can see which tier resolved. Same field the telemetry_policy canary writes.
Zod schema on the tool args accepts an optional knowledge_base_url override (for strict-mode testing where you want to force Tier 1 to fail and observe Tier 2/3 behavior). Same override shape as the telemetry canary.
Smoke test extension
Extend workers/test/canon-tool-envelope.smoke.mjs with new encode assertions:
- Envelope shape on batch input: top-level
result.artifactsis an array; each element carriestype,quality_level,persist_required, and the canon envelope fields. governance_sourcepresent and valid on every encode response.- Batch-mode per-artifact output: three-paragraph input with
[D]/[O]/[L]prefixes returns exactly three artifacts with matching types. - Single-artifact backward behavior: unprefixed single-paragraph input still returns a usable response (whatever shape is chosen — document it).
knowledge_base_urloverride that points at a nonexistent file falls through to Tier 2 (bundled) —governance_source: "bundled". A second override that disables bundled (implementation choice how) falls through to Tier 3 — actionable error envelope.
The smoke test currently runs ODDKIT_URL=<preview> node workers/test/canon-tool-envelope.smoke.mjs and must exit 0 with all assertions green.
Tool description update
After the code lands, update the oddkit_encode tool description (in workers/src/tools/encode.ts or wherever the MCP tool definition lives) to reference DOLCHEO (seven artifact types, six letters, [O-open] subtype hint for the forward-pointing O) and mention batch-mode prefix syntax. The handoff that spawned P1.1 explicitly deferred this description update pending the refactor; ship it with the same PR.
Path 3 workfloworchestrator applies, Sonnet validates
Managed-agent execution on klappy/oddkit is blocked by a safety-layer false-positive. Operator has decided not to report this upstream. Do not dispatch Opus 4.7 execution agents to klappy/oddkit. Sonnet 4.6 read-only validation is fine.
Working rhythm:
- Clone klappy/oddkit into
/home/claude/work/oddkit, cut branchencode/batch-mode-and-canary-refactoroff main. - Apply edits locally. Encode implementation is in
workers/src/— find the file by grepping for existing encode code (the prior renaming fromcanonUrltoknowledgeBaseUrltouchedworkers/src/zip-baseline-fetcher.tsand neighbors; encode lives nearby). - Commit. Githooks run on commit and enforce version sync between
package.jsonandworkers/package.json. Don't skip. - Push to branch. Cloudflare auto-deploys every pushed branch to
https://<branch-slug>-oddkit.klappy.workers.dev/mcp(slashes → hyphens). Do not runwrangler deploymanually. - Smoke the preview:
ODDKIT_URL=<preview-url> node workers/test/canon-tool-envelope.smoke.mjs. Must exit 0. - Open PR via
urllib.request+json.dumps. Never inline shell heredoc JSON. - Dispatch Sonnet 4.6 validator as a new agent object — not a session on an existing agent.
model: claude-sonnet-4-6. Beta header:managed-agents-2026-04-01. Environment id:env_016RffZyqSdHeb5s3Z6UABw8. MCP: oddkit bound, read-only role. Acceptance criteria: PR URL, HEAD SHA, list of DOLCHEO canon URIs the tool must fetch, smoke test passing locally and on the preview URL. Template lives inodd/ledger/2026-04-19-agent-team-pilot.mdandcanon/principles/agent-self-report-under-stress.md(for how to read agent self-reports skeptically). - Accept VERIFIED or iterate. Do not trust the agent's terminal self-report as sole evidence — per
canon/principles/agent-self-report-under-stress, pull the event log and corroborate tool calls against external state. - Squash-merge on VERIFIED. Run main-preview smoke:
ODDKIT_URL=https://main-oddkit.klappy.workers.dev/mcp node workers/test/canon-tool-envelope.smoke.mjs. - Open main → prod PR (the operator prefers PRs over direct
promote.shpushes). Merge when green. Final smoke athttps://oddkit.klappy.dev/mcp.
Six gates, each mechanical, each producing evidence. Expected total orchestrator time: 90–150 min including agent validation overhead.
Standing rules for the fresh session
These carry from the prior handoff (klappy://odd/handoffs/2026-04-20-fresh-session-continuation) and apply unchanged:
- Call
oddkit_timefirst in every turn, passing the priorserver_timeasreference. No inferred timestamps. - Declare epistemic mode out loud. P1.2 opens in planning until preflight + plan are confirmed; then execution; then validation via Sonnet 4.6 agent (context-break required).
- Search canon before asking. Specifically for this arc:
klappy://canon/definitions/dolcheo-vocabulary,klappy://canon/constraints/core-governance-baseline(three-tier fallback contract), and the per-type encoding docs underodd/encoding-types/are the primary reads. - Track DOLCHEO continuously in
/home/claude/work/ledger/<date>-p1-2-encode-canary.md. Save encode output to file — encode does NOT persist on its own. - During execution, produce artifacts, not questions. Reversion requires one sentence naming the specific unknown.
- Never force-push without
git fetchand remote diff first. The prior session's run-1 finding stands: a prior agent may have silently pushed work. - GitHub API: Python
urllib.requestwithjson.dumps. Never bash heredoc. $HOME=/rootin the managed-agent cloud container, not/home/useras the skill doc says.
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://canon/definitions/dolcheo-vocabulary— the vocabulary your refactor will read at runtime.klappy://canon/constraints/core-governance-baseline— the three-tier resolution contract.klappy://canon/principles/agent-self-report-under-stress— read before dispatching the Sonnet validation agent.klappy://odd/ledger/2026-04-19-agent-team-pilot— the path-3 pattern in action, with the agent-team template for the Sonnet validator.klappy://canon/meta/frontmatter-schema— if you touch any docs, native YAML types only.klappy://canon/constraints/ai-voice-cliches— if you touch any writing, avoid negation parallelism and em-dash overuse.
The klappy/oddkit reference PRs for the canary pattern:
klappy/oddkit#108and#109— thetelemetry_policycanary, merged. Reference shape: whatgovernance_sourcelooks like in a real envelope, how the Zod override is wired, how the smoke test asserts three-tier behavior.klappy/oddkit#110and#111— thecanonUrl→knowledgeBaseUrlinternal rename that set up the current naming.
Known foot-guns carried forward from 2026-04-19
- Do not dispatch Opus 4.7 execution agents to klappy/oddkit. The safety-layer false-positive halts them. Orchestrator-applies only. Sonnet read-only validation is fine.
- Do not trust an agent's terminal self-report. Pull the event log. Corroborate
git commit/git push/ PR creation / file-write claims against the external systems they affected. See the self-report-under-stress principle. - Do not mix shell
python3 <<PYEOF > file.txtwith in-scriptopen(file).write(...). Shell>truncates on exit and overwrites the file with stdout content. Write from Python only, send diagnostics tosys.stderr. - Do not run
wrangler deploymanually on klappy/oddkit. Githooks + CF auto-deploy handle the pipeline. - Do not force-push without fetching remote first. A prior agent may have pushed completed work silently.
- Do not treat Cursor Bugbot's
in_progressstatus as a merge blocker on klappy.dev. It's informational, not a required check.mergeable_state: cleanis the authoritative gate signal on that repo. (This session confirmed it on PRs #109, #110, #111, and almost certainly #113 too.)
Open items going into the fresh session
- [O-open P1] Start P1.2. Preflight, plan, execute, validate via Sonnet 4.6, promote. The arc described in this doc.
- [O-open P2] If P1.2 converges cleanly and bandwidth remains, pick up the next canary in the governance-anti-pattern audit (
docs/oddkit/audit/governance-anti-pattern-sweep-2026-04-17.md). Priority order per the 2026-04-20-fresh-session-continuation handoff:oddkit_challenge, thenoddkit_gate, thenoddkit_preflight, thenoddkit_validate, thenoddkit_orient. Each follows the same canary template. - [O-open P3] Version bump on klappy/oddkit from 0.16.0 to 0.17.0 with a populated
CHANGELOG.md[Unreleased]section. Deferred from the prior handoff's Priority 2 list. Natural to do in the same PR-window as P1.2 or as a separate atomic bump PR after. - [O-open P4] If the
superseded_byfield andstatus: supersededvalue introduced in PR #113 become the standard pattern, updatecanon/meta/frontmatter-schemato include them in the canon-audience table. Low urgency; the cleanup PR's field semantics are self-describing.
How this handoff will be validated
The next session should be able to open this doc, read Summary + Operating Notes + Reference Material, and start productive P1.2 work without rereading any transcripts. If the next session feels the need to reconstruct context from a prior session's messages, this handoff failed — file a learning under canon/principles/ and revise.