Packet — fix-claude-config-cache
Execution plan
The change is a small surgical refactor. Do it in three edits, then add three test cases.
Edit 1 — Swap the import (src/domains/integrations/claude.ts:33)
- import { loadConfig } from '../../config.js';
+ import { config } from '../../config.js';
Edit 2 — Replace the fallback in createCompletion (lines 344–353)
Replace:
// Resolve model: options → env → config default
let defaultModel = 'claude-sonnet-4-5';
try {
const cfg = loadConfig(process.env);
defaultModel = cfg.COLIBRI_ANTHROPIC_MODEL;
} catch {
// config may fail in test environments with minimal env — use hardcoded default
}
const model = options.model ?? defaultModel;
With:
const model = options.model ?? config.COLIBRI_ANTHROPIC_MODEL;
Edit 3 — Replace the fallback in createCompletionWithTools (lines 385–393)
Replace:
let defaultModel = 'claude-sonnet-4-5';
try {
const cfg = loadConfig(process.env);
defaultModel = cfg.COLIBRI_ANTHROPIC_MODEL;
} catch {
// test env fallback
}
const model = options.model ?? defaultModel;
With:
const model = options.model ?? config.COLIBRI_ANTHROPIC_MODEL;
Edit 4 — Add new test block
Inside src/__tests__/domains/integrations/claude.test.ts, append a new
describe('default-model resolution from config') block before the final
describe('edge cases') block. The block contains three tests:
createCompletion uses config.COLIBRI_ANTHROPIC_MODEL when options.model is omittedcreateCompletion: injected options.model overrides the config defaultcreateCompletionWithTools uses config.COLIBRI_ANTHROPIC_MODEL when options.model is omitted
Each test imports config from '../../../config.js' and asserts the
request body’s model matches the expected value.
Verification plan
After implementation:
cd .worktrees/claude/fix-claude-config-cache
npm run build
npm run lint
npm test
Expected:
- Build: clean compile.
- Lint: clean.
- Tests: existing 30+ claude.test.ts tests pass + 3 new tests pass. Full suite count goes up by exactly 3.
If any test fails, investigate the failure — do not patch around it. The
config singleton is loaded at module-import time using the test environment
(NODE_ENV=test is set by jest), and the schema default for
COLIBRI_ANTHROPIC_MODEL will resolve to 'claude-sonnet-4-5' unless the
test env overrides it.
Step ordering for commits
| # | Step | Commit prefix |
|---|---|---|
| 1 | Audit (already committed) | audit(fix-claude-config-cache): inventory surface |
| 2 | Contract (already committed) | contract(fix-claude-config-cache): behavioral contract |
| 3 | Packet (this file) | packet(fix-claude-config-cache): execution plan |
| 4 | Implementation (single commit covering both source + tests) | feat(fix-claude-config-cache): swap loadConfig try/catch for config singleton |
| 5 | Verification doc | verify(fix-claude-config-cache): test evidence |
Each step lands as a separate commit. The 5-step gate rule applies.
Risks and mitigations during implementation
| Risk | Mitigation |
|---|---|
Edit 2 + Edit 3 are textually different (different comment lines, different surrounding whitespace) — must use distinct Edit calls or careful replace_all=false |
Use two separate Edit invocations with enough surrounding context to make each old_string unique. |
Stripping the unused loadConfig import would break TypeScript compile if any other line references it — but a replace of the import line removes both occurrences cleanly |
The imports are the only loadConfig references in claude.ts. Once the two try/catch blocks are gone, loadConfig is no longer referenced. |
New tests need to import config — but the test file already imports loadConfig at line 738+ via dynamic await import('../../../config.js') inside test bodies |
Add a static import { config } from '../../../config.js'; near the top alongside the other claude.js imports. |
Out-of-scope (per dispatch packet constraints)
- Retry logic (lines 245–315) — untouched.
- Token accounting (
parseResultlines 194–229) — untouched. - Response parsing — untouched.
AnthropicConfigError,AnthropicApiError— untouched.- Tool-use handling logic — untouched.
Configtype /src/config.tsschema — untouched.- Public function signatures — preserved exactly.