Conversation
Catalogs the Vodka anti-pattern — canon defines vocabulary, code hardcodes interpretation — across all 11 oddkit tools. PR #100's voice-dump schema bug (1h 39m prod breakage) was one instance of this class. Audit identifies 5 tools carrying the same shape. Findings: SEVERE: orient, gate, validate PARTIAL: encode, preflight CROSS-CUTTING: mode enum declared in 4 places CLEAN: challenge (post-refactor), search, get, catalog, version, time, cleanup_storage, telemetry_public Refactor priority ranked by impact × tractability. validate named as the most surprising: it gates 'done' but never reads canon/constraints/definition-of-done.md — which in fact does not exist in the repo despite three user-facing docs claiming it does. Companion PR on klappy/klappy.dev establishes canon/constraints/core-governance-baseline.md as the contract every sweep refactor will conform to.
…vise priority Canary (telemetry_policy self_report_headers reading from canon) shipped to prod via oddkit#106 + #107 and klappy.dev#102 (canon extension). Live smoke confirms governance_source: 'canon' with 8/8 canon-sourced descriptions. Corrections to the audit: - telemetry_policy was originally classified CLEAN but carried a hardcoded header dictionary next to the canon-fetched policy prose — the same anti-pattern class. Reclassified to LOW severity (drift, not correctness) and selected as the canary. Now ✅ shipped. - Refactor priority revised during planning after the canary was selected. New order: canary (✅ done) → validate+preflight bundled → mode-enum collapse → orient → gate → encode. Lessons-first-smallest sequencing rather than raw severity. Validate+preflight moves up because it's a correctness bug, not drift: validate gates 'done' but never reads canon/constraints/definition-of-done.md (which doesn't exist yet). First step is writing that canon doc.
…moke Addresses three gaps found in live validation of canary PR #106: 1. Response envelope was missing server_time, assistant_text, debug. Every other oddkit tool returns {action, result, server_time, assistant_text, debug}; telemetry_policy returned only {action, result}. This breaks the time-discipline contract — project instructions require every oddkit response to carry server_time so models have a clock reading on every call. 2. canon_url parameter was silently ignored. The Zod schema was {}, so MCP stripped canon_url before the handler saw it, and the handler hardcoded the default baseline. The three-tier resolution contract in canon/constraints/core-governance-baseline assumes every canon-driven tool accepts canon_url for overrides — this is load-bearing for TruthKit / custom-canon consumers. 3. No live-smoke test for the envelope shape. Parser tests in governance-parser.test.mjs exercised parser logic only. The canary shipped with partial contract conformance because no test invoked the MCP tool end-to-end and asserted the envelope shape. Changes: - Add canon_url to the tool's Zod schema; thread through to fetcher.getFile(path, canon_url). - Expand response envelope to match convention: server_time, assistant_text (human-readable summary naming the tier), debug with duration_ms and canon_url echo. - New workers/test/canon-tool-envelope.smoke.mjs — live smoke script that curls the MCP endpoint and verifies envelope shape for oddkit_time (convention baseline), telemetry_policy default (canon tier), and telemetry_policy with canon_url override (minimal fallback). Verified: - npm run typecheck: clean - Smoke script structure matches PR #100's governance-parser test style and exits non-zero on any envelope violation. Lesson for the sweep: every canon-driven refactor must verify both the new governance_source signal AND full envelope conformance. The canary's partial completion was caught by live validation but should have been caught by pre-merge smoke. Follow-up to update the refactor template in docs/oddkit/audit/... separately.
When canon_url is provided, getFile() previously still appended the klappy.dev baseline as a search source. A missing governance file in the override canon would be silently satisfied by the baseline, causing governance_source to report 'canon' instead of 'minimal'. Add an optional skipBaselineFallback flag to ZipBaselineFetcher.getFile and pass it from the telemetry_policy handler when canon_url is set, so a missing file in the override canon correctly falls back to the minimal tier.
User-facing terminology rename. Companion to klappy/klappy.dev#101 (contract update) and klappy/klappy.dev#118 (forward-facing doc sweep). Public API changes: - Every tool's Zod schema parameter: canon_url → knowledge_base_url. Affects oddkit router tool (action-routed) and all per-action tools (orient, search, get, challenge, gate, preflight, validate, encode, catalog, version, cleanup_storage) via the unified args passthrough. - telemetry_policy schema also renamed, with updated description naming strict-mode semantics: 'When set, strict mode is automatic: missing files fall through to the bundled governance tier rather than silently substituting from the default knowledge base.' Response envelope tier strings: - governance_source: "canon" → "knowledge_base" - governance_source: "baseline" → "bundled" - governance_source: "minimal" → "minimal" (unchanged) Smoke test (workers/test/canon-tool-envelope.smoke.mjs): - All parameter references renamed - Tier-string assertions updated - Strict-override test now explicitly verifies the 'knowledge_base_url set → bundled fallback suppressed' contract - Error message assertions check debug.knowledge_base_url echo Intentionally NOT renamed in this commit (internal, deferred): - ZipBaselineFetcher class → would become KnowledgeBaseFetcher - Internal variable canonUrl in orchestrate.ts (111 refs) - Internal variable canonUrl in telemetry.ts - BASELINE_URL environment variable Deferring internal renames keeps this PR focused on the user-visible contract. A dedicated internal-rename PR will clean up the class, variable names, and env var in one coordinated pass so reviewers can see the full internal shift at once rather than spread across the user-facing change. The router passthrough (orchestrate.ts interface) still names its input field canon_url for now — the rename there happens in the internal PR. Users never see that field; they pass knowledge_base_url at the MCP level and it's mapped to the orchestrator's canon_url parameter internally. Typecheck clean. Smoke test will run against Cloudflare preview once this commit deploys.
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
oddkit | 36514bd | Commit Preview URL Branch Preview URL |
Apr 19 2026, 06:37 AM |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Promote main → prod
10 commits behind prod, fully validated on main preview (24/24 smoke green on
https://main-oddkit.klappy.workers.dev). Arc completes the canary refactor and the knowledge_base_url rename.What ships
Canary completion (
#106+#108):telemetry_policyreadscanon/constraints/telemetry-governance.mdfrom knowledge base at runtime, falls back to bundled tier, falls back to minimal tier{action, result, server_time, assistant_text, debug}matches conventionknowledge_base_urlis set, bundled fallback is suppressed so a missing file surfaces asminimalrather than silently substitutingworkers/test/canon-tool-envelope.smoke.mjs— ship-blocker template for all future canon-driven toolsTerminology rename:
canon_url→knowledge_base_url"canon"→"knowledge_base","baseline"→"bundled","minimal"unchangedAudit doc (
#105):docs/oddkit/audit/governance-anti-pattern-sweep-2026-04-17.md— full sweep of all 11 oddkit tools against the vodka anti-pattern (canon defines vocabulary; code hardcodes interpretation)#108mergeVerification
Main preview smoke (just ran):
Tests covered: envelope shape (oddkit_time + telemetry_policy default + override), governance_source tier values, strict-override semantics when pointing at a repo lacking the governance file.
Bugbot review: Two findings on
#108during development, both autofixed by Cursor Agent before merge (silent baseline fallback bug, telemetry.ts renamed-parameter extraction). Both verified green in smoke.Post-merge verification plan
oddkit.klappy.dev/mcpODDKIT_URL=https://oddkit.klappy.dev/mcp node workers/test/canon-tool-envelope.smoke.mjsCompanion canon
klappy/klappy.dev#101(merged) — knowledge_base_url contractklappy/klappy.dev#106(merged) — doc sweepklappy/klappy.dev#105(merged) — validation mode + context break (E0008.3)klappy/klappy.dev#107(open) — DOLCHEO ledger extensionAll prod infrastructure aligned with canon terminology after this promotion.
Note
Medium Risk
Changes the public MCP tool schemas and telemetry parsing by renaming
canon_urltoknowledge_base_url, which can break existing clients if they don’t adopt the new parameter (legacy alias only handled in telemetry extraction). Also modifies governance document loading/fallback behavior fortelemetry_policy, which could affect production responses if the new strict override logic misfires.Overview
Promotes the “knowledge base” terminology and contract across the MCP surface. All tool schemas switch from
canon_urltoknowledge_base_url, and unified/individual tool handlers now forward this field into the existingcanon_urlplumbing.Hardens governance loading for
telemetry_policy. The tool now acceptsknowledge_base_url, returns a full response envelope (action,result,server_time,assistant_text,debug), and enforces strict override semantics by suppressing bundled fallback when an override repo is provided (viaZipBaselineFetcher.getFile(..., { skipBaselineFallback: true })).Telemetry and validation additions. Telemetry argument parsing now prefers
knowledge_base_urlwhile still accepting legacycanon_url, a new live smoke test (workers/test/canon-tool-envelope.smoke.mjs) verifies envelope shape and strict-override fallback, and a new audit doc is added documenting governance anti-patterns across tools.Reviewed by Cursor Bugbot for commit 36514bd. Bugbot is set up for automated code reviews on this repo. Configure here.