Skip to content

refactor: eliminate local ChittyID generation, enforce service-only minting with circuit breaker#9

Open
Copilot wants to merge 4 commits into
feat/delegate-minting-to-chittymintfrom
copilot/sub-pr-6
Open

refactor: eliminate local ChittyID generation, enforce service-only minting with circuit breaker#9
Copilot wants to merge 4 commits into
feat/delegate-minting-to-chittymintfrom
copilot/sub-pr-6

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Jan 25, 2026

The worker was generating fallback ChittyIDs locally using hardcoded ERROR_CODES and ENTITY_TYPES, violating the CHARTER requirement that all IDs must originate from centralized services. Additionally, the fallback re-mint path lacked circuit breaker protection, risking unbounded failures.

Changes

  • Replaced local fallback ID generation with service delegation

    • Removed generateFallbackErrorId() and associated constants (ERROR_CODES, ENTITY_TYPES)
    • Added requestFallbackIdFromService() that calls fallback.id.chitty.cc/api/fallback
    • Returns structured error object when fallback service is unavailable
  • Added circuit breaker and timeout protection

    • Created fetchWithTimeout() using AbortController for configurable timeouts (default 30s)
    • Created fetchWithCircuitBreaker() combining circuit state checks with timeout handling
    • Applied to both primary minting and fallback re-mint paths in /api/validate
    • Integrated PipelineCircuitBreaker for automatic failure tracking and recovery
  • Code quality improvements

    • Extracted getCircuitBreaker() helper to eliminate initialization duplication
    • Added JSDoc documentation for all utility functions

Example

Before (local generation):

function generateFallbackErrorId(errorCode, entityType, originalRequest) {
  const sequential = ERROR_CODES[errorCode] || ERROR_CODES.INTERNAL_ERROR;
  const type = ENTITY_TYPES[entityType?.toLowerCase()] || 'T';
  // ... local ID construction
  return `${version}-${region}-${jurisdiction}-${sequential}-${type}-${yearMonth}-${trustLevel}-${checksum}`;
}

After (service delegation):

async function requestFallbackIdFromService(errorCode, entityType, originalRequest, env) {
  const circuitBreaker = getCircuitBreaker(env);
  const response = await fetchWithCircuitBreaker(
    circuitBreaker,
    'fallback-id-service',
    'request-fallback-id',
    `${FALLBACK_ID_SERVICE}/api/fallback`,
    { method: 'POST', body: JSON.stringify({ errorCode, entityType, context }) },
    REQUEST_TIMEOUT
  );
  return result.chittyId;
}

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Co-authored-by: chitcommit <208086304+chitcommit@users.noreply.github.com>
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Jan 25, 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
chittyid 079f934 Commit Preview URL

Branch Preview URL
Jan 25 2026, 07:14 AM

Copilot AI and others added 2 commits January 25, 2026 07:12
Co-authored-by: chitcommit <208086304+chitcommit@users.noreply.github.com>
Co-authored-by: chitcommit <208086304+chitcommit@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Jan 25, 2026

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • sparrow.cloudflare.com
    • Triggering command: /usr/local/bin/node /usr/local/bin/node --no-warnings --experimental-vm-modules /home/REDACTED/work/chittyid/chittyid/node_modules/wrangler/wrangler-dist/cli.js deploy --dry-run (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI changed the title [WIP] Refactor ChittyID minting to use ChittyMint service refactor: eliminate local ChittyID generation, enforce service-only minting with circuit breaker Jan 25, 2026
Copilot AI requested a review from chitcommit January 25, 2026 07:16
@chitcommit chitcommit marked this pull request as ready for review April 24, 2026 14:45
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 079f934c8c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread worker.js
Comment on lines +91 to +95
const response = await fetchWithTimeout(url, options, timeout);

// Record success
await circuitBreaker.recordSuccess(serviceName, operation);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Treat non-2xx upstream responses as circuit failures

Update fetchWithCircuitBreaker so HTTP error responses are not counted as successes. Right now recordSuccess runs immediately after fetchWithTimeout, but fetch resolves for statuses like 429/500; callers (for example requestFallbackIdFromService) only check response.ok afterward. In a real outage that returns non-2xx, failure counts never increase, the circuit never opens, and the worker keeps sending traffic to a known-unhealthy service.

Useful? React with 👍 / 👎.

Comment thread worker.js
Comment on lines +158 to +159
const result = await response.json();
return result.chittyId;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Validate fallback service payload before returning chittyId

requestFallbackIdFromService returns result.chittyId without validating it. If the fallback service responds 200 with a malformed body (for example missing chittyId), downstream code in generateFallbackResponse assumes a string and calls split('-'), which can throw and bubble into the generic top-level security error path instead of returning a controlled service-unavailable fallback response.

Useful? React with 👍 / 👎.

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

This PR refactors fallback ChittyID behavior to remove local ID construction and instead delegate fallback minting to a centralized fallback service, while introducing timeout + circuit breaker wrappers to reduce cascading failures when upstream services are unhealthy.

Changes:

  • Removed local fallback ID generation (hardcoded error/entity mappings) and added requestFallbackIdFromService() to obtain fallback IDs from fallback.id.chitty.cc.
  • Added fetchWithTimeout() and fetchWithCircuitBreaker() utilities, plus a getCircuitBreaker() helper for reuse.
  • Applied circuit breaker + timeout to the fallback re-mint path in /api/validate; lockfile updated to include a nested optional peer zod for @anthropic-ai/sdk.

Reviewed changes

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

File Description
worker.js Replaces local fallback ID minting with a service call; adds timeout/circuit breaker helpers and uses them on the re-mint path.
package-lock.json Adds a nested optional peer dependency (zod@4.3.6) under @langchain/anthropic’s dependency tree.

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

Comment thread worker.js
Comment on lines +90 to +96
try {
const response = await fetchWithTimeout(url, options, timeout);

// Record success
await circuitBreaker.recordSuccess(serviceName, operation);

return response;
Comment thread worker.js
}

const result = await response.json();
return result.chittyId;
Comment thread worker.js
Comment on lines +298 to +301
// Parse the fallback ID components
const parts = fallbackId.split('-');
const [version, region, jurisdiction, sequential, type, yearMonth, trustLevel, checksum] = parts;

Comment thread worker.js
INTERNAL_ERROR: '0099' // Unknown internal error
};
// Fallback ID service URL
const FALLBACK_ID_SERVICE = process.env.FALLBACK_ID_SERVICE || 'https://fallback.id.chitty.cc';
Comment thread worker.js
Comment on lines +71 to +89
/**
* Fetch with circuit breaker and timeout
* @param {PipelineCircuitBreaker} circuitBreaker - The circuit breaker instance to use
* @param {string} serviceName - Name of the service being called
* @param {string} operation - Name of the operation being performed
* @param {string} url - URL to fetch
* @param {Object} options - Fetch options
* @param {number} [timeout=REQUEST_TIMEOUT] - Request timeout in milliseconds
* @returns {Promise<Response>} The fetch response
* @throws {Error} If circuit breaker is open or request fails
*/
async function fetchWithCircuitBreaker(circuitBreaker, serviceName, operation, url, options, timeout = REQUEST_TIMEOUT) {
// Check circuit state
const circuitCheck = await circuitBreaker.checkCircuit(serviceName, operation);

if (!circuitCheck.allowed) {
throw new Error(`Circuit breaker is open for ${serviceName}:${operation}. Time until retry: ${circuitCheck.timeUntilRetry}ms`);
}

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.

3 participants