Uh oh!
There was an error while loading. Please reload this page.
fix(ci,api): green main again — the four breaks that stopped every deploy for five days - #770
Merged
Merged
Conversation
…ploy for five days CI has failed on every commit since 50aecb9 (2026-09-01) and the API Worker has not deployed since 5876486. Production is running 5876486; everything after it, including the prompt-section tracing and the engine-invocation-mode change, is undeployed. Four independent breaks, fixed together because main is red until all four are gone. 1. File-size ratchet (#302). Three files grew without the pin move the guard asks for: routes/coding.ts +5 and CodingTab.tsx +12 (both 1e038c4, #731), agent-think.ts +13 (d570182, #732). Pins raised to 815/1490/1251 with the reason beside each, read off the diffs after the fact — which is the cost of raising a pin late, and is recorded as such on this file's own entry. The ratchet runs 11s in, before install, so CI never reached the test suite. That is why breaks 2-4 were only ever visible in the deploy workflows. 2. `pnpm test` could not collect workers/host/src/admin-api-proxy.test.ts: `Cannot find module './pages.js'`. pages.ts is build output (build.js inlines store/ into it) and is gitignored, so it does not exist in a fresh checkout — and NEITHER ci.yml NOR deploy-api.yml built it before running the suite. Fixing only the ratchet would have moved main's redness here rather than clearing it. Both workflows now build console -> admin -> host pages before `pnpm test`, the same chain and order as deploy-host.yml. In ci.yml this reuses the Build Console step that was already there as the job's LAST step, after the tests that needed it; it is moved rather than duplicated. No docs build is added to deploy-api.yml -- build.js guards a missing docs dir, so Zensical stays out of the API path. 3. Type-only import cycle usage.ts -> prompt-section-estimates.ts -> usage.ts, introduced by d570182. `UsageKind` now lives in usage-shape.ts, the leaf that already exists for exactly this and imports nothing; usage.ts re-exports it, so it stays the module you import a kind from. This is the connector-graph remedy import-graph.test.ts documents (a leaf, not a deferred import) — EXPECTED_DEFERRED is untouched. 4. `classifyEngineMetering` had zero production callers. 1e038c4 replaced its only call site with a direct `expectedEngineInvocationMode` check, re-opening the exact gap guard #556 was written to catch. The invocation-mode refinement was right and is kept — it now lives INSIDE the classifier as a third input, so one function still answers "can this reach the ledger" and the guard is satisfied by wiring rather than by a token call. That detour also had to launder the engine name through `asClient`, which falls back to "claude" for anything outside its four-name list. So aider, opencode, goose, amp, crush and cursor-agent every one read as structured and recorded no absence at all — a day of unmeasured aider work looked exactly like a day of measured Claude Code work on the Usage page. Going through the classifier, which uses normalizePaneCommand + STRUCTURED_ENGINES, fixes that too. Five tests pin both behaviours: codex-launched-raw, the absent-launchCommand default (so no old session reclassifies), and the six engines that were being swallowed. Verified locally: pages.ts moved aside reproduces break 2 exactly, and the added build chain clears it. Full suite 606 files / 10845 tests passing (was 603 passed, 3 failed). Ratchet, biome, docs:drift, qa-config, test-isolation, e2e-projects all green; tsc clean for api, api tests, mcp and console. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… raw 10px A FIFTH break on main, and it was invisible: the design-tokens gate (#367) is step 10 of ci.yml and the file-size ratchet is step 5, so while the ratchet failed 11s in this gate never ran. Fixing the ratchet is what surfaced it. `EnginesModal.tsx:128` shipped `text-[10px]` in 1e038c4 — the same commit behind two of the three pin overruns and the metering regression. #390 puts the floor at 11px, and the gate's own instruction for anything below it is to round UP, so this is `text-2xs`: the nearest step, and the one `BuildsPanel.tsx:30` already uses for exactly this pill-badge idiom. No new --text-* entry is warranted for 0.32px. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Sep 6, 2026
…th (pre-existing bug from 17d8265) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Uh oh!
There was an error while loading. Please reload this page.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Main has been red since 50aecb9 (2026-09-01) and the API Worker has not deployed since 5876486. Production is running
5876486; everything after it — includingd5701824's prompt-section tracing and1e038c43's engine-invocation-mode change — is undeployed.Four independent breaks. Main stays red until all four are gone, so they land together.
1. File-size ratchet (#302) — the one that made CI red
Three files grew without the pin move the guard asks for:
workers/api/src/routes/coding.ts1e038c43(#731)agents/coder/web/src/CodingTab.tsx1e038c43(#731)workers/api/src/agent-think.tsd5701824(#732)Reasons are written beside each pin, read off the diffs after the fact — which is the cost of raising a pin late, and is recorded as such on this file's own entry.
The ratchet runs ~11s in, before install, so CI never reached the test suite. That is why breaks 2–4 were only ever visible in the deploy workflows.
2.
pages.tsnever built beforepnpm testpnpm testcould not collectworkers/host/src/admin-api-proxy.test.ts:Cannot find module './pages.js'.pages.tsis build output (build.jsinlinesstore/into it) and is gitignored, so it does not exist in a fresh checkout — and neitherci.ymlnordeploy-api.ymlbuilt it before running the suite.Fixing only the ratchet would have moved main's redness here rather than clearing it.
Both workflows now build console → admin → host pages before
pnpm test, the same chain and order asdeploy-host.yml. Inci.ymlthis reuses theBuild Consolestep that was already there as the job's last step, after the tests that needed it — moved, not duplicated. No docs build is added todeploy-api.yml:build.jsguards a missing docs dir, so Zensical stays out of the API path.3. Type-only import cycle
lib/usage.ts → lib/prompt-section-estimates.ts → lib/usage.ts, introduced byd5701824. Both edges areimport type, so nothing failed at runtime —import-graph.test.tsis what catches it.UsageKindnow lives inusage-shape.ts, the leaf that already exists for exactly this and imports nothing;usage.tsre-exports it, so it stays the module you import a kind from. This is the connector-graph remedy that test documents (a leaf, not a deferred import) —EXPECTED_DEFERREDis untouched.4.
classifyEngineMeteringhad zero production callers1e038c43replaced its only call site with a directexpectedEngineInvocationModecheck, re-opening the exact gap guard #556 was written to catch.The invocation-mode refinement was right and is kept — it now lives inside the classifier as a third input, so one function still answers "can this reach the ledger" and the guard is satisfied by wiring rather than by a token call.
That detour also carried a second, quieter bug. It had to launder the engine name through
asClient, which falls back to"claude"for anything outside its four-name list. Soaider,opencode,goose,amp,crushandcursor-agentevery one read as structured and recorded no absence at all — a day of unmeasured aider work looked identical to a day of measured Claude Code work on the Usage page. Going through the classifier (normalizePaneCommand+STRUCTURED_ENGINES) fixes that too.Five new tests pin both behaviours: codex-launched-raw, the absent-
launchCommanddefault (so no existing session reclassifies retroactively), and the six engines that were being swallowed.Verification
pages.tsmoved aside reproduces break 2 exactly; the added build chain clears it.docs:drift, qa-config, test-isolation, e2e-projects.tscclean: api, api tests (tsconfig.test.json), mcp, console.Note on delivery
This repo's convention is commit-straight-to-main; this is a PR because it was explicitly requested for review before merge. Deploy API Worker will not run on merge unless
workers/api/**changes — it does here, so merging should both green CI and ship the API backlog from5876486forward.🤖 Generated with Claude Code