Skip to content

promote: main → prod (canary completion + knowledge_base rename)#109

Merged
klappy merged 9 commits into
prodfrom
main
Apr 19, 2026
Merged

promote: main → prod (canary completion + knowledge_base rename)#109
klappy merged 9 commits into
prodfrom
main

Conversation

@klappy
Copy link
Copy Markdown
Owner

@klappy klappy commented Apr 19, 2026

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_policy reads canon/constraints/telemetry-governance.md from knowledge base at runtime, falls back to bundled tier, falls back to minimal tier
  • Full response envelope: {action, result, server_time, assistant_text, debug} matches convention
  • Strict-override: when knowledge_base_url is set, bundled fallback is suppressed so a missing file surfaces as minimal rather than silently substituting
  • Live smoke test in workers/test/canon-tool-envelope.smoke.mjs — ship-blocker template for all future canon-driven tools

Terminology rename:

  • Every tool schema renamed: canon_urlknowledge_base_url
  • Response envelope tier strings: "canon""knowledge_base", "baseline""bundled", "minimal" unchanged
  • Telemetry extraction accepts both new and legacy keys for blob6

Audit 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)
  • Canary row reclassified as completed post-#108 merge

Verification

Main preview smoke (just ran):

24 passed, 0 failed

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 #108 during 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

  1. Merge this PR → prod
  2. Cloudflare deploys to oddkit.klappy.dev/mcp
  3. Re-run ODDKIT_URL=https://oddkit.klappy.dev/mcp node workers/test/canon-tool-envelope.smoke.mjs
  4. Expect 24/24 green (parity with main)
  5. If any assertion fails, revert and investigate

Companion canon

  • klappy/klappy.dev#101 (merged) — knowledge_base_url contract
  • klappy/klappy.dev#106 (merged) — doc sweep
  • klappy/klappy.dev#105 (merged) — validation mode + context break (E0008.3)
  • klappy/klappy.dev#107 (open) — DOLCHEO ledger extension

All prod infrastructure aligned with canon terminology after this promotion.


Note

Medium Risk
Changes the public MCP tool schemas and telemetry parsing by renaming canon_url to knowledge_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 for telemetry_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_url to knowledge_base_url, and unified/individual tool handlers now forward this field into the existing canon_url plumbing.

Hardens governance loading for telemetry_policy. The tool now accepts knowledge_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 (via ZipBaselineFetcher.getFile(..., { skipBaselineFallback: true })).

Telemetry and validation additions. Telemetry argument parsing now prefers knowledge_base_url while still accepting legacy canon_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.

klappy and others added 9 commits April 18, 2026 00:01
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.
@cloudflare-workers-and-pages
Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

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

@klappy klappy merged commit 876d004 into prod Apr 19, 2026
5 checks passed
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.

2 participants