Libra CodeHub

CedarCopilot/cedar-mail

Branch: staging

ci: typecheck shipping source on every PR

merged#2631CedarCopilot

CedarCopilot wants to merge 2 commits into staging from fix/ci-typecheck

Live on prod, no production signal yetTimeline and evidence
  1. Opened
    Aug 30, 2026, 10:06 PM
  2. Aug 30, 2026, 10:23 PM
  3. Merged
    Aug 30, 2026, 10:40 PM
  4. Live on prod
    Aug 30, 2026, 10:40 PM
  5. Observed 2 hours
    Aug 30, 2026, 10:40 PM
  6. Pipelines steady after this deploy
    Aug 30, 2026, 10:40 PM
  7. Unobserved

    Live on prod, no production signal yet

    Aug 31, 2026, 12:21 AM

Behaviors Libra is checking

Email workflow behavior from responseProcessors/clientExecutionResponseProcessors.ts keeps working in prod.Inconclusivelow confidence

Strict CloudWatch fallback saw 2,394 success-shaped log lines matching email, emails, gmail, mail, inbox, but no tied operation was present, so Libra is not calling this working.

prod, checked Aug 31, 2026, 12:21 AM

Libra has verdicts on 0 of 1 tracked behaviors on prod; 1 is still being checked. Libra checks hourly for 3 days after each deploy.

Nothing in CI runs tsc. #2614 sat green through every check while tsc -b failed on it: the branch reverted a driver contract from three parameters to two and left the caller passing three. That is a compile error, and nothing in the pipeline could see it. Only oxlint, the vitest shards and the AWS builds run today.

Scoped to shipping source, and that needs no config change

types is tsc -b over each package's tsconfig.json, which already excludes tests:

apps/server  exclude: ["node_modules", "src/**/*.test.ts", "src/**/__tests__/**"]
apps/mail    exclude: ["node_modules", "**/*.test.ts", "**/*.test.tsx", "**/__tests__/**", "tests/**"]

So "typecheck, but skip tests" is just turbo run types. I measured all four jobs on staging (bac808d30) before writing the workflow:

JobErrors
@zero/server types0
@zero/mail types1fixed here
@zero/server types:test65all in test files
@zero/mail types:test1716 in test files; the 17th is the same source error, double-counted because tsconfig.test.json includes source too

The shipping half is one error from green. The test half is 82 deep, and it's mostly mock drift: a defaultOrganizationIdorganizationId rename never applied to two files, vi.fn() mocks inferring never, mocks missing fields added to a schema later. Turning it on now would make the job red on arrival and train everyone to ignore it.

Worth knowing before anyone adds it: types:test would not have caught the #2614 regression either. That mock is (...args: unknown[]), so a lost parameter is invisible to it. It's a weaker net than the raw count suggests. I left a comment in the workflow saying so, so the next person doesn't helpfully switch it on.

The one error was a real bug, not type noise

sortOrder/sortOrderPinned landed in 1bea051c2 (2026-08-28, task-reordering phase 1). taskUpdatedProcessor mirrors a streamed task into a loaded conversation's userTasks, and on the insert branch it builds a whole ConversationUserTask with no stored row underneath , so both fields arrived undefined. orderOf (utils/task-order.ts) floors undefined to 0, so the card silently sorted as if pinned to the top of its column.

That it's two days old rather than chronic is the encouraging part: shipping-source typecheck is normally green, so nothing has been rotting behind its absence.

My first fix was wrong, and the new tests caught it. I put the fallbacks in updatedTask , but that object is spread onto stored rows in both branches, so a defaulted sortOrder overwrote the real placement of a task the conversation already held whenever the global slice happened not to know it. That's exactly the "PATCH, don't replace" mistake this file's own comments warn about twice. The fallbacks now live only at the insert site, where a whole row is genuinely being constructed.

Three tests: an inserted task gets a real placement, it carries the placement the client already knew, and an already-mirrored task's placement is left alone (the case that caught the bad first fix).

Job details

Runs both codegen steps before tsc. Both emit into gitignored directories, so a fresh checkout has neither and tsc reports 35 TS2307 "cannot find module" errors that say nothing about the diff. Turbo orders the two packages itself (types dependsOn ^types, and apps/mail's tsconfig references ../server for the emitted AppRouter declaration). Cold run is ~60s; timeout-minutes: 10 matches autofix.

I did not add the Libra verdict reporting the two test jobs carry , this is a static-analysis job like autofix, which doesn't report either. Easy to add if you'd rather it did.

Verification

turbo run types clean from a cold cache · oxlint clean · depcruise clean at 1,587 modules · 2,829 mail tests pass across 299 suites.

I also confirmed the job fails for the right reason: with codegen skip

Show production surfaces and changed-file mapping

Production surfaces

Libra has not measured any production surfaces for this change yet.

Changed files → surfaces

  • .github/workflows/ci.ymlno production surface mapped
  • apps/mail/modules/cedar-os/src/store/agentConnection/responseProcessors/clientExecutionResponseProcessors.tsno production surface mapped
  • apps/mail/tests/modules/userTasks/taskUpdatedProcessor.test.tsno production surface mapped