kb://learnings/2026-05-21-workspace-path-deps-unblockstable2026-05-21

Workspace path deps red-CI unblock — real bugs surfaced

learningciworkspacepath-depsdebugging

Five streaming-product repos had been red on CI for days because of unresolved path = "../sibling" deps in single-repo checkouts. When the co-checkout pattern landed and CI started actually running, three real bugs surfaced underneath the red. The «red CI» wasn't one problem — it was four.

What was on top: the unresolved path

CI for live, voice, rt, social-api, world couldn't even start the build because the sibling repo wasn't on disk. Every job died at manifest-parse time. Looked like one infra problem.

Fix: co-checkout via actions/checkout of the sibling under ../<sibling> with a fine-grained PAT (kb://architecture/co-checkout-for-private-workspace-deps).

What was underneath: three real bugs

Once builds actually ran, lint and compile surfaced:

1. openalice-live@openalicelabs/ui woff2 asset path mismatch

The UI library shipped assets/fonts/*.woff2 referenced from CSS as /fonts/... (Next.js public-path convention) but the consumer was a Next 14 app expecting ./_next/static/... paths. Pre-co-checkout CI hadn't loaded a single page; the path mismatch was invisible. After the fix: broken font loads everywhere.

2. openalice-world — TypeScript module resolution drift

world imported @openalicelabs/agent-protocol types, but the path dep + TS moduleResolution: "node16" in the consumer disagreed with the sibling's "bundler" mode. Local dev was fine because both packages were resolved by the same workspace tooling; isolated CI surfaced the disagreement.

3. openalice-voice-client — missing @types/node ambient

A process.env reference in voice-client compiled locally because the workspace root had @types/node. In an isolated checkout, the sibling repo did not declare its own @types/node and the type-check failed.

The lesson

Long-red CI hides multiple problems behind a single visible failure. The first fix is necessary but not sufficient — once CI starts running, budget time for the second and third bugs to surface. Don't declare victory at "green on the first re-run"; wait for two clean runs in a row across all five repos.

Operational follow-ups

  • Each consumer repo now declares its own @types/node (or equivalent ambient types) — workspace-root inheritance is not a guarantee in CI.
  • TS moduleResolution is unified across the workspace via a shared base tsconfig.json referenced from every package.
  • Path-dep readiness checks: when a new path dep is added, the consumer's CI must be run in isolation once to surface ambient-context drift before the dep is merged.