Skip to content

Promote PR #102: challenge mode enum schema fix to prod#103

Merged
klappy merged 3 commits intoprodfrom
main
Apr 17, 2026
Merged

Promote PR #102: challenge mode enum schema fix to prod#103
klappy merged 3 commits intoprodfrom
main

Conversation

@klappy
Copy link
Copy Markdown
Owner

@klappy klappy commented Apr 17, 2026

Promote PR #102 (challenge mode enum schema fix) to production

Promotes the single commit from PR #102 (now in main) to prod. Unblocks the voice-dump suppression invariant — the load-bearing feature of PR #100 that has been unreachable from the public API since the original promotion (PR #101) merged at 15:28:44Z today.

What ships

  • workers/src/index.ts — Zod mode enum expanded from [exploration, planning, execution] to all 9 modes defined in odd/challenge/stakes-calibration.md:
    • Epistemic: exploration, planning, execution
    • Writing-lifecycle: voice-dump, drafting, peer-review-ready, canon-tier-2, canon-tier-1, published-essay
  • Two sites: unified oddkit tool (line 170) and dedicated oddkit_challenge tool (line 235)
  • Description text updated to explain both mode families and call out voice-dump suppression

Verification plan after this lands

  1. Manual MCP call: oddkit_challenge with mode: "voice-dump" and a strong-claim input. Expect status: "SUPPRESSED" with governance field still populated (so the model sees what would have fired)
  2. Manual MCP call: oddkit_challenge with mode: "drafting" and same input. Expect CHALLENGED with reduced challenge tier per calibration
  3. Existing supported modes (exploration/planning/execution) regression check

Known remaining production issues (not blocked by this PR)

  • Cache poisoning on transient upstream failure. When GitHub returns 403 on the SHA endpoint during a cold call, discoverChallengeTypes can cache an empty result that persists until cleanup_storage clears it. Tracked separately — needs either "don't cache empty" or "track error state in cache" fix
  • Test infrastructure debt. Parser-fidelity test depends on live network fetch from raw.githubusercontent.com; introduces flakiness in CI
  • Three follow-up refactors share the pre-refactor anti-pattern — encode parity, gate, orient. Tracked in PR Promote PR #100: governance-driven challenge with BM25 + stemming to prod #101 description

Refs


Note

Low Risk
Schema-only expansion (no behavioral logic changes) and backwards-compatible for existing clients using the original three modes; main risk is minor client-side validation mismatches if consumers hardcode the old enum.

Overview
Expands the public tool schemas to accept the full set of writing-lifecycle modes (e.g. voice-dump, drafting, peer-review-ready, canon-tier-*, published-essay) in addition to exploration/planning/execution.

This updates both the shared JS tool registry (oddkit orchestrator and oddkit_challenge) and the Cloudflare worker’s Zod schemas (unified oddkit tool and oddkit_challenge), with descriptions clarifying the two mode families and that voice-dump suppresses challenge output.

Reviewed by Cursor Bugbot for commit daa9a96. Bugbot is set up for automated code reviews on this repo. Configure here.

klappy added 2 commits April 17, 2026 15:22
Production preview test caught a real show-stopper: the MCP tool's mode
parameter Zod schema accepted only exploration/planning/execution but
the calibration governance article (odd/challenge/stakes-calibration)
defines 9 modes. The 6 writing-lifecycle modes (voice-dump, drafting,
peer-review-ready, canon-tier-2, canon-tier-1, published-essay) were
unreachable from the public API — schema validation rejected them
before runtime ever saw them.

Net effect of the bug: the voice-dump suppression invariant — the
load-bearing feature of PR #100, named in evidence as load-bearing —
could not be exercised through the public MCP tool. Internal tests
worked because they bypassed the schema. The CI 'Test CF Preview' job
failed on cold-start timeout (red herring); the real failure was
discovered by manual curl against the preview.

Two sites in workers/src/index.ts:
- Line 170: unified oddkit tool
- Line 235: dedicated oddkit_challenge tool

Both expanded to the full 9-mode enum. Description text updated to
explain the two mode families and call out voice-dump suppression.

Longer-term direction (not this commit): drop the enum entirely and
let canon be the validator. The runtime already validates against the
calibration table at fetchStakesCalibration time — having the schema
also enforce vocabulary is the same Vodka anti-pattern shape that
PR #100 fixed for stop words. Tracked as a follow-up.

Verification:
- npm run typecheck: clean
- workers/test/governance-parser.test.mjs: 97/97 against main
- Manual preview curl with mode=voice-dump pending after this deploys

Lesson: testing the running preview is not optional. PR #100 had
typecheck pass, parser test 97/97, smoke 6/6, AND production preview
deploy succeed — and still shipped a feature the schema blocked from
being called. Three layers of verification missed it because none of
them exercised the public API contract.
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Apr 17, 2026

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 daa9a96 Commit Preview URL

Branch Preview URL
Apr 17 2026, 05:00 PM

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Mode enum not updated in local tool registry
    • Expanded the mode enum in both the orchestrator tool and oddkit_challenge schemas in src/core/tool-registry.js to include the six writing-lifecycle modes, matching the workers schema.
Preview (aa6208da31)
diff --git a/src/core/tool-registry.js b/src/core/tool-registry.js
--- a/src/core/tool-registry.js
+++ b/src/core/tool-registry.js
@@ -46,8 +46,12 @@
       },
       mode: {
         type: "string",
-        enum: ["exploration", "planning", "execution"],
-        description: "Optional epistemic mode hint.",
+        enum: [
+          "exploration", "planning", "execution",
+          "voice-dump", "drafting", "peer-review-ready",
+          "canon-tier-2", "canon-tier-1", "published-essay",
+        ],
+        description: "Optional mode hint. Epistemic modes (exploration/planning/execution) or writing-lifecycle modes (voice-dump/drafting/peer-review-ready/canon-tier-2/canon-tier-1/published-essay). Sourced from odd/challenge/stakes-calibration.",
       },
       canon_url: {
         type: "string",
@@ -107,7 +111,7 @@
       type: "object",
       properties: {
         input: { type: "string", description: "A claim, assumption, or proposal to challenge." },
-        mode: { type: "string", enum: ["exploration", "planning", "execution"], description: "Optional epistemic mode for proportional challenge." },
+        mode: { type: "string", enum: ["exploration", "planning", "execution", "voice-dump", "drafting", "peer-review-ready", "canon-tier-2", "canon-tier-1", "published-essay"], description: "Mode for proportional challenge. Epistemic (exploration/planning/execution) or writing-lifecycle (voice-dump/drafting/peer-review-ready/canon-tier-2/canon-tier-1/published-essay). voice-dump suppresses all challenge output." },
         canon_url: { type: "string", description: "Optional: GitHub repo URL for canon override." },
       },
       required: ["input"],

You can send follow-ups to the cloud agent here.

Reviewed by Cursor Bugbot for commit aa6208d. Configure here.

Comment thread workers/src/index.ts
klappy added a commit that referenced this pull request Apr 17, 2026
Parallels PR #102 which fixed the same enum in workers/src/index.ts.
The local tool registry at src/core/tool-registry.js drives the local
MCP server (src/mcp/server.js) and CLI (src/cli.js) and had the same
3-mode enum, creating a contract divergence between the deployment
surfaces for the same logical API.

Two sites in src/core/tool-registry.js:
- Line 47-55 (unified oddkit tool)
- Line 113-121 (dedicated oddkit_challenge tool)

Both expanded to the full 9-mode enum with description text matching
PR #102's style. Mode families explained, voice-dump suppression called
out in the dedicated tool description.

Sweep verified: grep across src/ and workers/ for the 3-mode string
returns only the first line of each 9-mode block now — zero stale
enums.

Caught by bugbot on PR #103 (the promotion PR for #102). Flagged
appropriately as Low severity (the CF Worker surface is the primary
production path; the local surface is used for dev/CLI). Fixing in a
separate PR so #103 can promote cleanly without rebase.

Verification:
- npm run typecheck: clean
- tests/smoke.sh: 6/6 pass

Longer-term (same as #102 flagged): drop enum entirely and let canon
be the validator. Hardcoding mode vocabulary in schema is the same
Vodka anti-pattern shape challenge stop words used to be.
)

Parallels PR #102 which fixed the same enum in workers/src/index.ts. The local tool registry at src/core/tool-registry.js drives the local MCP server and CLI and had the same 3-mode enum, creating contract divergence between surfaces.

Both sites expanded to 9-mode enum with description text matching PR #102 style.
@klappy klappy merged commit 06e1a70 into prod Apr 17, 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.

1 participant