Skip to content

fix: reconcile uncommitted production hotfix to main#174

Merged
chitcommit merged 6 commits intomainfrom
fix/reconcile-prod-hotfix
May 1, 2026
Merged

fix: reconcile uncommitted production hotfix to main#174
chitcommit merged 6 commits intomainfrom
fix/reconcile-prod-hotfix

Conversation

@chitcommit
Copy link
Copy Markdown
Contributor

Summary

Reconciles the worker version 3d46be98 (deployed 2026-05-01T10:45:21Z) with main. That deploy carried 8 modified files that were never committed — discovered while investigating why connect.chitty.cc was 1101 across all paths immediately after PR #168 squash-merged.

The OAuth-route bypass in src/index.js is the load-bearing change that brought the worker back. Other commits cluster around two independent features (experience migration, dispute type validation) plus one secrets-path priority fix and small test/docs hygiene.

Commits (in dependency order, last-to-first)

  1. fix(routing)src/index.js: bypass oauthProvider.fetch for non-OAuth paths via isOAuthProviderRoute() allowlist; everything else goes straight to app.fetch. Adds formatCaughtError() to handle non-Error throws across all top-level catch blocks. This is what restored prod after the post-fix: MCP portal zero-trust fixes #168 outage.
  2. feat(experience)context-intelligence.js + tool-dispatcher.js + tool-registry.js: records-only POST /api/v1/intelligence/context/experience/migrate + matching MCP tool. Strict manifest validation (refuses without ChittyID-issued supersession), ledger entries on both source and target. Composing saga lives upstream at Ch1tty.
  3. feat(disputes)chittydisputes.js: factor type validation into VALID_DISPUTE_TYPES + normalizeDisputeType() helper with explicit LEGACY_DISPUTE_TYPE_MAP (billing→FINANCIAL, service→VENDOR, etc). Also fixes a latent ReferenceError in /create (prior conflict resolution dropped const rawType = ... while leaving the existence check that referenced it).
  4. fix(secrets)cloudflare-secrets-client.js: reorder PATH_TO_ENV so services/chittydispute/service_token resolves before the legacy services/chittydispute/token entry.
  5. test(jwt)jwt-helper.test.js: generate test RSA keypair at module load via node:crypto instead of committing a static PKCS#8 PEM. Removes a recurring secret-scanner false-positive.
  6. docs(readme)README.md: link to the canonical MCP Host Standard in the ch1tty repo.

Why this PR exists

fix/mcp-portal-zerotrust was the branch behind PR #168, which squash-merged into main on 2026-04-30T22:16:36Z. Work continued on the same local branch after merge, was deployed directly via wrangler deploy --env production to fix the post-merge 1101 outage, but never made it back to git. This PR restores commit-traceability per ChittyOS canon.

Test plan

  • node --check passes on every modified .js file
  • No mocks / fake data added (commit 5 removes a static fixture; replacement uses real keypair)
  • git log reviewed — every change is purposeful, no whitespace churn
  • /create ReferenceError reproduced by reading and confirmed fixed by the patch
  • Reviewer please confirm: is the experience_migrate endpoint behavior (commit 2) what was intended for the saga handoff to ChittyChronicle/ChittyTrust? It returns nextSteps strings as guidance — verify the caller (Ch1tty experience_reassign) actually reads them.

Production state at time of opening

  • Currently deployed: 3d46be98-344c-4711-9e44-f5418ca84881 (the hotfix, healthy, drained queue)
  • Bytes-for-bytes match between this PR and the deployed bundle is NOT verified — Cloudflare doesn't expose deployed bundle hashes. Source is verified equivalent to the working tree on the host that ran wrangler deploy, modulo the rawType fix in commit 3.

🤖 Generated with Claude Code

chitcommit and others added 6 commits May 1, 2026 12:49
…ror logging

Reconciles a production hotfix that was deployed (worker version
3d46be98, 2026-05-01T10:45:21Z) without a corresponding commit on main.
This change is what restored connect.chitty.cc after the post-merge
1101 outage.

The OAuthProvider library was being invoked for every non-agent
request, including plain Hono routes (/api/health,
/integrations/github/webhook, /intelligence/*). On non-OAuth paths it
was resolving to a non-Response value, causing the runtime to throw
"Incorrect type for Promise: the Promise did not resolve to 'Response'"
and Cloudflare to surface 1101 across the entire worker.

Adds isOAuthProviderRoute(url) — a narrow allowlist of OAuth-specific
paths (/authorize, /token, /register, /.well-known/oauth-*). Only those
routes go through oauthProvider.fetch; everything else is dispatched
straight to app.fetch (the Hono router).

Also adds formatCaughtError() to consistently extract message+stack from
Error vs. non-Error throws across all top-level catch blocks, replacing
the ad-hoc \`err.message\` / \`err.stack\` pattern (which throws on
non-Error rejects).

Also wraps the host==="mcp.chitty.cc" /mcp branch in try/catch with the
same error-normalization pattern, matching the existing /chatgpt/mcp
handler.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds POST /api/v1/intelligence/context/experience/migrate as the
records-only half of the identity-supersession saga. ChittyConnect
moves D1 records between two existing contexts when given a ChittyID-
issued supersession manifest; it does not mint identities, recalculate
trust, or write to event-storage. Those steps are owned upstream by
ChittyID/ChittyChronicle/ChittyTrust and composed by Ch1tty's
experience_reassign saga.

- src/api/routes/context-intelligence.js: route handler, manifest
  validation (from_chitty_id, to_chitty_id, mint_audit_id, signature,
  issued_at, reason all required), ledger entries on both source and
  target, structured 200 response with nextSteps for the caller saga.
- src/mcp/tool-dispatcher.js: dispatcher case forwarding to the new
  endpoint with Bearer auth header.
- src/mcp/tool-registry.js: experience_migrate MCP tool definition with
  full input schema for the manifest.

Aligns with the offline twin at
~/.claude/chittycontext/scripts/experience-reassign.py which is
explicit about not pretending to be authoritative.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces the inline validTypes array + ad-hoc toUpperCase() approach
with VALID_DISPUTE_TYPES + LEGACY_DISPUTE_TYPE_MAP module constants and
a normalizeDisputeType() helper. The helper handles trim, case-fold,
and legacy lowercase aliases ("billing" -> "FINANCIAL", "service" ->
"VENDOR", etc) in one place instead of scattering the rules across
each route.

Also fixes a latent ReferenceError in /create: a prior conflict-resolved
merge dropped the rawType binding while leaving \`if (!rawType || !title)\`
in place. Reintroduces \`const rawType = dispute_type || type;\` ahead of
the existence check; the canonical-type check still runs against the
normalized value.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PATH_TO_ENV is consulted in declaration order. With "services/chittydispute/token"
declared before "services/chittydispute/service_token", a token resolved by
the canonical service_token path was getting eclipsed by a stale plain-token
entry. Swapping the order so service_token resolves first matches how the
1Password/secrets store is actually populated for ChittyDispute.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ture

Removes the hardcoded 2048-bit PKCS#8 PEM (~30 lines of base64) in favor
of node:crypto generateKeyPairSync at module load. Keeps tests
deterministic per-run (the keypair is generated once and reused across
the describe block) while keeping no static private keys in version
control — even ones explicitly labeled "test fixture only" tend to
trigger secret scanners and create false positives in audits.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ChittyConnect owns the dumb-aggregate MCP semantics for mcp.chitty.cc
plus the service catalog feeding the public Chitty discovery document,
but the canonical external host matrix, alias rules, and Cloudflare-
managed OAuth pattern live in the ch1tty repo. Adds a pointer so
consumers know where the source-of-truth document is.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 1, 2026 12:50
@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 1, 2026

Warning

Rate limit exceeded

@chitcommit has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 33 minutes and 59 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8c3fbe84-6bda-45a5-b686-bfb30549c9cf

📥 Commits

Reviewing files that changed from the base of the PR and between d08db33 and 617a7ee.

📒 Files selected for processing (8)
  • README.md
  • src/api/routes/chittydisputes.js
  • src/api/routes/context-intelligence.js
  • src/index.js
  • src/mcp/tool-dispatcher.js
  • src/mcp/tool-registry.js
  • src/services/cloudflare-secrets-client.js
  • tests/services/jwt-helper.test.js
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/reconcile-prod-hotfix

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 0/1 reviews remaining, refill in 33 minutes and 59 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

@cloudflare-workers-and-pages
Copy link
Copy Markdown
Contributor

Deploying with  Cloudflare Workers  Cloudflare Workers

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

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
chittyconnect 617a7ee May 01 2026, 12:50 PM

@chitcommit chitcommit merged commit 1828c1a into main May 1, 2026
16 of 18 checks passed
@chitcommit chitcommit deleted the fix/reconcile-prod-hotfix branch May 1, 2026 12:50
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Reconciles an uncommitted production hotfix back into main for the Cloudflare Worker (ChittyConnect), restoring traceability for routing/OAuth behavior and bundling a few additional feature/fix changes that were present in the deployed worker.

Changes:

  • Adjust worker request routing to bypass oauthProvider.fetch() for non-OAuth endpoints and add safer top-level error formatting for non-Error throws.
  • Add “experience migration” API endpoint + MCP tool wiring, and enhance disputes type normalization/validation.
  • Clean up secrets path mapping priority and replace a committed RSA PEM test fixture with runtime key generation; update README MCP host standard link.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/index.js Changes fetch routing between OAuth provider, MCP agent handler, and Hono app; improves catch/log formatting.
src/api/routes/context-intelligence.js Adds POST /context/experience/migrate records-only migration endpoint and ledger logging.
src/mcp/tool-registry.js Registers new experience_migrate MCP tool schema.
src/mcp/tool-dispatcher.js Dispatches experience_migrate tool calls to the new API endpoint.
src/api/routes/chittydisputes.js Normalizes dispute types via canonical allowlist + legacy mapping; fixes create/list behavior.
src/services/cloudflare-secrets-client.js Updates secret path → env mapping for disputes service tokens.
tests/services/jwt-helper.test.js Generates RSA keypair at runtime to avoid committed PEM fixture/secret scanning noise.
README.md Adds MCP Host Standard section and link to canonical doc.
Comments suppressed due to low confidence (1)

src/index.js:2076

  • In this catch block you compute errorInfo but the response body still uses err.message. This can return undefined for non-Error throws and makes the new formatCaughtError() ineffective for the client response. Use errorInfo.message in the JSON response for consistency with the updated logging.
        `[Agents] routeAgentRequest threw for ${request.method} ${url.pathname}: ${errorInfo.message}
${errorInfo.stack}`,
      );
      return new Response(
        JSON.stringify({ error: "agent_routing_failed", error_description: err.message }),
        { status: 500, headers: { "Content-Type": "application/json" } },

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1926 to +1957
// Order: target receives first (acquires the experience), then source closes.
const tgtEntry = await resolver.logToLedger(
tgt.id,
to_chitty_id,
"experience_migrate",
"experience_received",
{
type: "experience_received",
fromChittyId: from_chitty_id,
mintAuditId: mint_audit_id,
reason,
metricsTransferred: transferred,
receivedAt: timestamp,
},
);

const srcEntry = await resolver.logToLedger(
src.id,
from_chitty_id,
"experience_migrate",
"experience_migrated",
{
type: "experience_migrated",
toChittyId: to_chitty_id,
mintAuditId: mint_audit_id,
reason,
metricsTransferred: transferred,
linkedTargetEntryId: tgtEntry.entryId,
linkedTargetHash: tgtEntry.hash,
migratedAt: timestamp,
},
);
Comment thread README.md

ChittyConnect currently owns the dumb aggregate MCP semantics for `mcp.chitty.cc` and the service catalog that feeds the public Chitty discovery document.

For the canonical external host matrix, alias rules, and Cloudflare-managed OAuth pattern, see [../ch1tty/docs/MCP_HOST_STANDARD.md](../ch1tty/docs/MCP_HOST_STANDARD.md).
Comment thread src/index.js
Comment on lines 2082 to +2087
try {
response = await oauthProvider.fetch(request, env, ctx);
if (isOAuthProviderRoute(url)) {
response = await oauthProvider.fetch(request, env, ctx);
} else {
response = await app.fetch(request, env, ctx);
}
"services/chittychronicle/token": "CHITTY_CHRONICLE_TOKEN",
"services/chittydispute/service_token": "DISPUTES_API_TOKEN",
"services/chittydispute/token": "DISPUTES_API_TOKEN",
"services/chittydispute/service_token": "DISPUTES_API_TOKEN",
Comment on lines +1818 to +1886
if (!manifest || typeof manifest !== "object") {
return apiResponse(
c,
{
success: false,
error: {
code: "MISSING_MANIFEST",
message:
"ChittyID-issued supersession manifest is required. " +
"Records-only migration cannot run without identity authority.",
},
},
400,
);
}

const {
from_chitty_id,
to_chitty_id,
mint_audit_id,
signature,
issued_at,
reason,
} = manifest;

const missing = [
["from_chitty_id", from_chitty_id],
["to_chitty_id", to_chitty_id],
["mint_audit_id", mint_audit_id],
["signature", signature],
["issued_at", issued_at],
["reason", reason],
]
.filter(([, v]) => !v || (typeof v === "string" && !v.trim()))
.map(([k]) => k);

if (missing.length > 0) {
return apiResponse(
c,
{
success: false,
error: {
code: "MANIFEST_INCOMPLETE",
message: `manifest missing required fields: ${missing.join(", ")}`,
},
},
400,
);
}

if (from_chitty_id === to_chitty_id) {
return apiResponse(
c,
{
success: false,
error: {
code: "SAME_ENTITY",
message: "manifest from/to are identical",
},
},
400,
);
}

// TODO: verify Ed25519 signature against ChittyID public key + replay-check
// mint_audit_id against ChittyID audit endpoint. For now, this is a TRUST
// boundary that requires the manifest's existence; full crypto verification
// is the follow-up before production deploy.

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