Skip to content

packaging: @objectstack/cli (8 deps), @objectstack/hono (1) and @objectstack/plugin-dev (12) publish @objectstack/* dependencies as caret ranges, so an app pinned exactly still installs a newer 18.x of them #25639

Closed

Description

@objectstack-fleet

Filing gate: ① a product defect, with a named location and a live reproduction.
Business reason: the docs tell an operator to pin exact @objectstack/* versions, because under ruling A (#25105) a patch can break a non-protocol surface. The 18.1.0 scaffolds now write exact pins (#25539). Even so, an app pinned exactly picks up a newer core, runtime, objectql and drivers through the CLI's own ranges the moment one publishes. That is the silent upgrade the pins exist to prevent. It also mixes two 18.x versions in one tree.
Reader: the packaging lane, in packages/cli/package.json, packages/adapters/hono/package.json and packages/plugins/plugin-dev/package.json. Next PR touching the lockstep packaging, or a PR of its own before 18.1.1.
Dedupe (open AND closed):

  • "cli package.json workspace:^ caret range @objectstack/core runtime exact pin resolves newer version mixed tree" → 0 hits.
  • "workspace caret dependency published package lockstep exact version internal dependencies" → 1 hit, lint.yml's "Build the ledgered packages' dependencies" step duplicates the closure refresh once #8330 lands #8331, a lint-step card, which is a different subject.
    reach: public install, measured once. A create-objectstack@18.0.0 app pinned to exactly 18.0.0 and run through pnpm install on 2026-10-24 holds 17 @objectstack/* packages at 18.1.0.
    type: Bug

What happens

These dependencies are written workspace:^. pnpm publishes that as ^<version>:

  • packages/cli/package.json, dependencies: @objectstack/core, driver-memory, driver-mongodb, driver-sql, driver-sqlite-wasm, objectql, observability and runtime. These are published as ^18.1.0 in @objectstack/cli@18.1.0 and as ^18.0.0 in 18.0.0. Its other 47 @objectstack/* dependencies are workspace:* and publish exact.
  • packages/adapters/hono/package.json, dependencies: @objectstack/runtime.
  • packages/plugins/plugin-dev/package.json, dependencies: 12 packages, including objectql, runtime, rest, plugin-auth and plugin-security.
  • Peer-dependency carets (runtime → driver-turso; service-datasource → three drivers) are not part of this card.

Every @objectstack/* package versions in lockstep (the changesets fixed group, 73 packages), so a range buys nothing. All it does is let one tree mix two releases.

Reproduction

  1. Run npx create-objectstack@18.0.0 app --template blank --skip-skills. It writes ^18.0.0 and installs 18.1.0, which is expected for a caret range.
  2. Replace every "^18.0.0" in package.json with "18.0.0", then rm -rf node_modules pnpm-lock.yaml && pnpm install.
    • Expected: every @objectstack/* package at 18.0.0.
    • Actual: 60 at 18.0.0 and 17 at 18.1.0. pnpm why @objectstack/spec@18.1.0 traces them all to @objectstack/cli 18.0.0, through core, driver-*, objectql, observability and their dependencies.
  3. Control: add overrides: for the eight CLI ranges to pnpm-workspace.yaml. With that, all are at 18.0.0, and no package is at 18.1.0.

Fix direction

Write these as workspace:*, like the CLI's other 47. Then pin the published shape with a check that no dependencies entry naming a fixed-group package publishes as a range. Until that ships, the 18.1 release page (#25616) gives the override as the workaround.

Activity

  1. added
    area:devpathThe road — create, dev, verify, publish/install, connect an agent, iterate
    bugSomething isn't working
    priority:p1High: required for production / M2
    and removed on Oct 24, 2026
  2. objectstack-fleet commented on Oct 24, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade — bug · priority:p1 · domain:devx · area:devpath · pm:queue · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-24T12:54Z

    ⛔ Not a claim, ⛔ not a dispatch. finding comes off.


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 24, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop · 2026-10-24T13:25Z
    Session: session_01ToEn6kUxajmjnSeRsFmTGn (card thread, dispatched by seat session session_01LKHDniRQSWjRJyDtacwpEd)
    Account: os-elon-musk
    Branch: claude/project-thread-48m1mn (the harness-pinned branch for the card thread; it names no issue, so this claim is the identity record)
    Worktree: objectstack-issue-25639
    Domain: domain:devx
    Seat: domain:devx#1 (seat post #6023)
    File surface: packages/cli/package.json, packages/adapters/hono/package.json, packages/plugins/plugin-dev/package.json, pnpm-lock.yaml (pnpm-regenerated), one .changeset/*.md (stop on breach; explain in the report)
    Container & model: M, mode:thread, model: default tier, effort: xhigh
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a — filed from the 18.1.0 install measurement.
    Thread-read: none
    Serial constraints cleared: #25631 (branch claude/project-thread-q33ihw) regenerates pnpm-lock.yaml and may touch the same manifests; merge origin/main before each push.

    Dispatched under the maintainer's 「同意」 to the director's ruling batch 1, item 5A (devx dispatches p1–p3). Dispatch order: /mnt/project-files/pm-devx-seat/dispatch-25639.md.

  4. objectstack-fleet commented on Oct 24, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 25639,
      "status": "done",
      "branch": "claude/project-thread-48m1mn",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/25662",
      "session": "session_01ToEn6kUxajmjnSeRsFmTGn",
      "premise_still_valid": true,
      "summary": "Premise re-measured on origin/main 49653f9 and on npm: 21 `dependencies` entries were `workspace:^` (cli 8, hono 1, plugin-dev 12), all 21 in the changesets fixed group, and the published 18.1.0 manifests carry them as ^18.1.0. They are now `workspace:*`; pnpm-lock.yaml moves exactly the 21 importer specifier lines; one patch changeset for the three packages carries `Clause-②: no` and `Metadata-protocol: none`. Peer carets are untouched and no check is added, per triage. With the seat's approval, one comment in packages/cli/src/commands/generate.ts that named the old `workspace:^` specifier now says `workspace:*`.",
      "tests": "Published shape measured with `pnpm --filter PKG pack` at b18406b and the packed package/package.json read: cli 50 internal deps, 0 non-exact (peer driver-turso stays ^18.1.0); hono 3, 0 non-exact; plugin-dev 15, 0 non-exact. Control: `npm view @objectstack/cli@18.1.0 dependencies` lists the eight at ^18.1.0, hono@18.1.0 has runtime ^18.1.0, plugin-dev@18.1.0 has 12 caret entries. Source sweep over every tracked package.json: no published package's dependencies/optionalDependencies names a fixed-group package with anything but workspace:* (remaining non-exact entries: peers, private examples/app-todo, scaffold templates). Unit suites of cli/hono/plugin-dev declared to CI: manifest-only diff, the installed workspace links are the same local packages for workspace:^ and workspace:*. No ablation: no tested behaviour changed.",
      "gates": "dispatch-gates --commands derived 80 families at b18406b; all 80 run, exit codes captured before any pipe: 72 exit 0 (incl. check-changeset-fixed, check-changeset-no-major --base origin/main, check-adr-0087-registration --base origin/main, check-empty-changeset --base origin/main, check:workspace-manifest-cycles, check-undeclared-dep-imports, check:published-files, check:override-consistency, check:manifest-repository-directory, check:nul-bytes, check:doc-authoring, check:issue-citations); 8 exit 3 NOT MEASURED: check:dts-closure, check:dual-build-cjs-loads, check:i18n, check:i18n-coverage, check:i18n-walk-parity, check:lean-entry-closure, check:sourcemap-no-sources-content (no full workspace build in this worktree) and check-plugin-teardown-shape --self-test (shallow clone). `dispatch-gates --ran`: 80 derived famil(ies) accounted for, 72 run, 8 NOT-MEASURED. Head ee5f527 merges origin/main (4 files under .claude/ and scripts/pm/, none on this surface); derived set byte-identical there. PR check-runs: in_progress at report time; CI runs the 8.",
      "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
      "mcp_calls": "6 — reads only: mcp__github__issue_read x5 (card get x2, card comments x2, #25631 get), mcp__github__pull_request_read x1 (get_files on #25631, answered 404). No MCP write.",
      "api_writes": "2 — fleet-write relay stroke fw-20261024T134615Z-ffe945 (run 40099571624): pr_create = POST /repos/objectstack-ai/objectstack/pulls (draft) + POST /repos/objectstack-ai/objectstack/issues/25662/assignees; read-back 5858 bytes sent, 5858 stored, assignee os-elon-musk. Plus this comment via post-stamped.",
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: #25510 (template exact deps) · the scaffold templates' ^18.0.0 ranges · noted, not filed",
        "carrier: maintainer, per triage · whether to add a check that refuses a range on a fixed-group dependency · noted, not filed",
        "examples/app-todo/package.json writes three workspace:^ dependencies; private, never published · Acceptance notes only",
        "packages/adapters/hono/package.json lists @objectstack/runtime in both dependencies and devDependencies; both now workspace:* · Acceptance notes only",
        "the card's 'other 47' CLI count measures 41 @objectstack/* workspace:* deps (49 total, 8 caret) at the base; the first commit message repeats 47 · Acceptance notes only"
      ]
    }

    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratebugSomething isn't workingdomain:devxpriority:p1High: required for production / M2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions