Skip to content

[finding] The os-dev brief's dependency-closure recipe uses a pnpm selector that reads PEER edges — so any optional-peer declaration can make it select a cyclic superset and fail #13402

Description

@os-elon

Filed by the domain:services PM seat (session session_012WkdHQwHr2KQmaX7P1BHzi), measured by the #12943 dev in PR #13401. Unassigned, ungraded, no pm:queue — grading is triage's field. Filed rather than fixed because the recipe lives in governed agent text, and because the cause is general rather than specific to the card that hit it.

What was measured

PR #12943 declares optional-driver loads as optional peerDependencies + peerDependenciesMeta (the maintainer's 2026-08-29 option-甲 ruling). Declaring @objectstack/driver-turso as an optional peer of @objectstack/service-datasource closes a workspace dependency cycle:

service-datasource -> driver-turso -> @objectstack/verify -> runtime -> service-datasource

The cycle is invisible to the real build path, and that is the interesting half. Measured both sides:

  • turbo does NOT read peerDependencies. pnpm build and CI are unaffected — the 20-task graph for service-datasource#build contains no driver-turso. ⇒ Nothing shipped is broken.
  • pnpm --filter 'PKG^...' DOES read peer edges. It now selects a cyclic superset with no topological order, and the build comes out wrong: @objectstack/verify was observed building before runtime's DTS finished.

⇒ The failure lands squarely on the dependency-closure build recipe the os-dev dispatch brief prescribes, which is stated in terms of that pnpm selector.

Why this is a card and not a line in PR #13401

⛔ Not specific to that card. The recipe is expressed with a selector that reads peer edges, so every future optional-peer declaration can re-break it the same way — and optional peers are now the ruled shape for guarded optional-driver loads, so more of them are expected. Fixing it inside the PR that happened to hit it would leave the next author to rediscover it.

The recipe also lives in agent-facing standing text — a governed surface this seat does not edit.

The options, as the measuring dev framed them

Do what Cost
A Accept it; build through turbo (what PR #13401 does) and let the brief's recipe carry a caveat. 0 now. ⚠️ Leaves a recipe that is wrong in a growing number of cases.
B Amend the brief's dependency-closure recipe repo-wide from the pnpm --filter 'PKG^...' selector to turbo. One documentation fix, in governed text.
C Revert the runtime half of the declaration to break the cycle. ⛔ Contradicts the 2026-08-29 ruling, which names runtime explicitly. Listed only for completeness.

Recommendation: B. A is sufficient for PR #13401's review and is what it already does, but the cause is general. ⛔ Not C — the ruling is not re-litigable, and the cycle is invisible to the real build path anyway.

⚠️ Confidence gaps

  1. I did not reproduce either measurement. The turbo-graph reading (20 tasks, no driver-turso) and the verify-before-runtime-DTS ordering are the dev's, taken during PR fix(datasource,runtime): declare the guarded optional-driver loads as optional peers #13401. ⇒ Re-run both before writing a rule on them, in particular the claim that turbo reads no peer edges — that is what makes A survivable at all.
  2. I did not enumerate how many places state the recipe. "Repo-wide" is B's own word; whoever takes it should count the sites first, since a partial fix here is worse than none (an author following the un-amended copy hits the same wall with more confidence).
  3. No severity judged. Nothing shipped is broken; this is an agent-ergonomics defect whose cost is a confusing local build failure at an unpredictable future moment.

Refs: #12943 / PR #13401 (where this was measured) · the 2026-08-29 maintainer ruling on #12943 (option 甲)

Generated by Claude Code

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions