refactor: eliminate local ChittyID generation, enforce service-only minting with circuit breaker#9
Conversation
Co-authored-by: chitcommit <208086304+chitcommit@users.noreply.github.com>
Deploying with
|
| 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 |
Co-authored-by: chitcommit <208086304+chitcommit@users.noreply.github.com>
Co-authored-by: chitcommit <208086304+chitcommit@users.noreply.github.com>
|
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:
If you need me to access, download, or install something from one of these locations, you can either:
|
There was a problem hiding this comment.
💡 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".
| const response = await fetchWithTimeout(url, options, timeout); | ||
|
|
||
| // Record success | ||
| await circuitBreaker.recordSuccess(serviceName, operation); | ||
|
|
There was a problem hiding this comment.
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 👍 / 👎.
| const result = await response.json(); | ||
| return result.chittyId; |
There was a problem hiding this comment.
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 👍 / 👎.
There was a problem hiding this comment.
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 fromfallback.id.chitty.cc. - Added
fetchWithTimeout()andfetchWithCircuitBreaker()utilities, plus agetCircuitBreaker()helper for reuse. - Applied circuit breaker + timeout to the fallback re-mint path in
/api/validate; lockfile updated to include a nested optional peerzodfor@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.
| try { | ||
| const response = await fetchWithTimeout(url, options, timeout); | ||
|
|
||
| // Record success | ||
| await circuitBreaker.recordSuccess(serviceName, operation); | ||
|
|
||
| return response; |
| } | ||
|
|
||
| const result = await response.json(); | ||
| return result.chittyId; |
| // Parse the fallback ID components | ||
| const parts = fallbackId.split('-'); | ||
| const [version, region, jurisdiction, sequential, type, yearMonth, trustLevel, checksum] = parts; | ||
|
|
| INTERNAL_ERROR: '0099' // Unknown internal error | ||
| }; | ||
| // Fallback ID service URL | ||
| const FALLBACK_ID_SERVICE = process.env.FALLBACK_ID_SERVICE || 'https://fallback.id.chitty.cc'; |
| /** | ||
| * 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`); | ||
| } | ||
|
|
The worker was generating fallback ChittyIDs locally using hardcoded
ERROR_CODESandENTITY_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
generateFallbackErrorId()and associated constants (ERROR_CODES,ENTITY_TYPES)requestFallbackIdFromService()that callsfallback.id.chitty.cc/api/fallbackAdded circuit breaker and timeout protection
fetchWithTimeout()using AbortController for configurable timeouts (default 30s)fetchWithCircuitBreaker()combining circuit state checks with timeout handling/api/validatePipelineCircuitBreakerfor automatic failure tracking and recoveryCode quality improvements
getCircuitBreaker()helper to eliminate initialization duplicationExample
Before (local generation):
After (service delegation):
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.