Skip to content

tooling: objectui consumes @objectstack/* by commit — .objectstack-sha, a bump script, and dev and CI built from that commit's source, cached by the pin (ruling B on objectui#12955, step 1) #12957

Closed

Description

@objectstack-fleet

Filing gate: execution of a ruling. This is ruling B on objectui#12955 (comment 6248859734), from the maintainer's 「12955 同意」 and 「12955 B」. The maintainer then ordered: 「你负责派发处理相关的issue,包括 objectstack 和 objectui 并测试确认。」

  • Filed by: domain:ui seat 1 (session_0188TsgPV8kQXfuRuKmkj2ks), which dispatches this card on that order. ⛔ Not a claim.
  • Tier H: the change touches .github/workflows/**, so the PR stays a draft until a GOVERNED_APPROVERS member approves it.

Why

objectui takes @objectstack/* from npm next.N, and npm releases are human acts (the 2026-08-07 ruling). So a front-end half waits for a release after its back-end half has merged. objectui#12932, #12929 and #12484 wait on next.4 today, although their back-end commits 586705d85d, 1e001c7df and e15897c0f1 merged into objectstack main this morning.

The reverse direction already works by commit: objectstack's .objectui-sha, scripts/bump-objectui.sh and scripts/build-console.sh, and cloud's .objectstack-sha. This card makes objectui → objectstack the same.

Done when

  1. The pin. .objectstack-sha, at the repository root, holds one full sha of a commit on objectstack main.
    • scripts/bump-objectstack.sh moves it, mirroring objectstack's scripts/bump-objectui.sh. It refuses a commit it cannot read, before writing anything, so the file stays byte-identical. It warns when the commit is not on origin/main.
  2. The pinned build. One documented command builds, at the pin, the six packages objectui resolves:
    • @objectstack/spec, core, client, formula, sdui-parser and lint. objectui's manifests name spec, client, formula and lint; client needs core, and lint needs sdui-parser and formula.
    • The output goes into a cache keyed by the pin. The workspace's @objectstack/* then resolve to that build, and no @objectstack/* resolves from npm.
    • A clean checkout reaches a green pnpm install --frozen-lockfile, type check and test run by the documented setup.
  3. An external tree can stand in. The mechanism lets a caller substitute an existing objectstack checkout for the pinned build, without changing pnpm-lock.yaml, so that a frozen install stays valid.
  4. CI. Every job that installs restores the pinned build from a cache keyed by .objectstack-sha. A run whose pin is unchanged does not rebuild.
  5. The lockfile and pin gates read the new resolution truly. check:lockfile-integrity, check:lockfile-dedupe, check:installed-pin-claims, and any other gate that reads where @objectstack/* resolves, are each adapted or retired, with the reason stated.
    • ⛔ No new gate (the 「新增门禁默认否」 rule).
  6. The first pin is an objectstack main commit that contains 586705d85d, 1e001c7df and e15897c0f1. Prove it with git merge-base --is-ancestor for each.
    • The type check then reads the spec keys those commits add: emptyState on the bound record blocks, and the backfill option of publishPackageDrafts.
  7. AGENTS.md names the pin, the bump and the local setup in its dependency and lockfile rules and in its local dev runbook. pnpm setup builds the pinned packages.

Out of scope (other cards)

Prior rulings and precedents


Generated by Claude Code

Activity

  1. added
    domain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repo
    area:devpathThe road — create, dev, verify, publish/install, connect an agent, iterate
    on Oct 18, 2026
  2. objectstack-fleet commented on Oct 18, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 5 · on the maintainer's order in this seat's session, verbatim 「你负责派发处理相关的issue,包括 objectstack 和 objectui 并测试确认。」, executing ruling B (6248859734) on objectui#12955 · domain:devx card dispatched by domain:ui seat 1 on that order
    Session: session_0188TsgPV8kQXfuRuKmkj2ks
    Account: sunhaolin (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-12957-objectstack-sha-pin
    Worktree: objectui-issue-12957
    Domain: domain:devx (on the maintainer's order to domain:ui seat 1)
    Seat: domain:ui#1
    File surface:

    Stop on breach; explain in the report.
    Container & model: M, mode:subagent, model: opus (default tier: a design-bearing tooling card that touches two governed surfaces)
    Clause-②: no
    Clause-② reason: no export, prop, key or schema of a published package moves; this changes how the workspace resolves its build-time dependencies.
    Responsibility: n/a — not a defect card
    Thread-read: 6248859734
    Serial constraints cleared: read at objectui main b5153f44. The only open PR touching these paths is Dependabot #11845 (pnpm-lock.yaml); whichever lands second regenerates the lockfile with pnpm. Governed: AGENTS.md and .github/workflows/** (check-governed-queue-guard --test), so the PR stays a draft until os-zhuang or hotlong approves it.


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 18, 2026

    @objectstack-fleet
    ContributorAuthor

    Done-when item 6 amended · domain:ui seat 1 · session_0188TsgPV8kQXfuRuKmkj2ks · 2026-10-18T13:40Z

    Measured on PR #12963 at 1fa4f1de: 4 Test shards are red. The causes are spec main's contract drift since next.3, not the mechanism:

    • a new emptyState key in record-highlights-layout-9187 and registry-inputs-spec-parity;
    • new list-view.* inputs;
    • spec-object-refinements-7715 at 6 → 7 checks;
    • record:json no longer a spec PageComponentType (block-config);
    • ObjectTree.schemaTyped-8655.

    Following that drift is a contract follow-up of the kind objectui#12873 did for next.3, and it needs its own review. So this card keeps to the mechanism.

    New item 6: the first pin is 2c9bf9430a1198bfaa5c0de9ff4a811838c6869c, the commit @objectstack/spec@18.0.0-next.3 was released from. The pinned build then reproduces what objectui resolves from npm today, so green CI proves the mechanism by itself. The dev proves that equivalence.

    After this card: moving the pin to a commit that carries 586705d85d, 1e001c7df and e15897c0f1, together with the contract follow-ups above, becomes a separate pin-bump card. The seat files it once this lands. objectui#12932, #12929 and #12484 unblock through that card.

    The dev has been sent this change.


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 18, 2026

    @objectstack-fleet
    ContributorAuthor

    Pointer: a second consumer, cloud · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-18T14:05Z

    Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015). ⛔ Not a claim, ⛔ no label change. A reply is owed only on an objection.


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 18, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 12957,
    "status": "done",
    "branch": "claude/issue-12957-objectstack-sha-pin",
    "pr": "#12963",
    "session": "session_0188TsgPV8kQXfuRuKmkj2ks",
    "premise_still_valid": true,
    "summary": "objectui now resolves every @objectstack/* package from a build of the objectstack commit in .objectstack-sha: seven root overrides point at file:node_modules/.cache/objectstack/NAME, which scripts/objectstack-pin.mjs fills (fetch the pin, filtered install, build, pnpm pack, verify entry points, stamp); pnpm run setup = that build + frozen install, OBJECTSTACK_ROOT=TREE packs an already built tree instead, scripts/bump-objectstack.sh moves the pin (refuses an unresolvable or unreadable commit before writing, warns with three answers when off origin/main), and every installing CI job restores the build keyed by the pin and the script and saves it on a miss. SEAT-DIRECTED SCOPE CHANGE (item 6): the first pin is 2c9bf9430a1198bfaa5c0de9ff4a811838c6869c, the @objectstack/spec 18.0.0-next.3 release commit, moved there with bump-objectstack.sh; it is a strict ancestor of 586705d85d, 1e001c7df and e15897c0f1 (git merge-base --is-ancestor PIN C exits 0 for each), so those three belong to the separate pin-bump card, and no parity, refinement or block-config pin was edited. Premise corrections: the closure is seven packages, not six (core depends on types); pnpm setup is pnpm's built-in (it wrote PNPM_HOME into the shell rc and never ran the script), so every doc says pnpm run setup. Two defects found and fixed in the mechanism on the way: the objectstack install inherited objectui's npm_config_* (engine-strict) through pnpm run, now scrubbed; and objectstack's spec build anchors its schema ratchets on origin/main, so the pinned build failed in 13 of 25 CI jobs once main added two schemas; the pinned checkout now drops its remote after the fetch, making the build a function of the pin (CI green at 4bd617b).",
    "equivalence_next3": "Pinned build vs npm 18.0.0-next.3 tarballs (npm pack of all seven, diff -rq against node_modules/.cache/objectstack): every package.json version is 18.0.0-next.3. types, formula, sdui-parser: identical (0 diff lines). core, client, lint: only package.json differs, by dependency key order (same keys, same 18.0.0-next.3 versions). spec (2094 files): all JS and json-schema identical; the npm tarball carries two release-time files the build does not, spec-changes.json and protocol-upgrade-guide.md, which objectui never reads (git grep exit 1, control term exit 0). After the hermetic build, 10 declaration files (api, automation, contracts, marketplace, system; .d.ts and .d.mts) and 2 hashed DTS chunk pairs differ; the sampled chunk (automation-api.zod) differs only in union member order with an identical byte length 523364, i.e. DTS emit nondeterminism, not content.",
    "measurements": {
    "local_cold_build": "objectstack-pin.mjs build under the verify lock: 202 s at 2ee5861 (fetch 17.0, install 4.4, build 160.7, pack 13.9); 174 s at the next.3 pin via pnpm run objectstack:build. Cache 201 to 203 MB; about 0.9 GB scratch deleted after packing. OBJECTSTACK_ROOT pack of an already built tree: 22.0 s.",
    "worktree_setup": "Fresh worktree at the pin (185772b), cold pnpm run setup: 175.7 s, +295 MB (cache 201 MB). Second fresh worktree right after: 167.5 s, +295 MB. Shared-cache simulation (copy the first worktree's cache into a third, then the same command): 6.5 s, +286 MB as a copy; about 85 MB if hardlinked (estimate, NOT MEASURED). Estimated saving per additional worktree about 160 s. No shared or machine-level cache was built, per the order.",
    "ci_cold_warm": "At 4bd617b: 23 jobs built cold in 71 to 125 s, median 111 s (at 1fa4f1d, n=25: 109 to 151 s, median 138 s). Two jobs hit a cache this PR had saved: Build Docs restore 3 s / build 0 s, Test shard 15/16 restore 2 s / build 0 s. Save step 0 to 2 s; install after the build 4 to 8 s.",
    "main_cache_save": "NOT MEASURED: main has no .objectstack-sha until this merges, so no main run has saved an objectstack-pin cache; the save step runs on any miss, so the first main push run after the merge saves it under main's scope, which PR runs can restore. The Actions cache API answers 403 through this proxy, so cache entries could not be listed; eviction risk is the repo's 10 GB limit beside about 2 GB of turbo caches."
    },
    "tests": "At 4bd617b (final HEAD): pnpm exec vitest run --maxWorkers=3 scripts/ then pnpm type-check:scripts under the verify lock: Test Files 188 passed, 2 skipped (190); Tests 5652 passed, 2 skipped; VERDICT command-exit 0. pnpm type-check --concurrency=2: Tasks 81 successful, 81 total; VERDICT command-exit 0. objectstack-pin.test.ts 23 passed, bump-objectstack.test.ts 7 passed (inside the suite). At 185772b (next.3 pin; later commits touch only scripts/objectstack-pin.mjs and its test): vitest over packages/core, packages/types, packages/react plus block-config.test.ts, ObjectTree.schemaTyped-8655.test.ts, registry-inputs-spec-parity.test.ts: 711 files passed, 16337 tests passed, 27 skipped, exit 0. Drift files: 15 failed / 340 passed at 2ee5861, 350 passed at the next.3 pin. Local packages/app-shell full suite NOT MEASURED (own runs stopped at 19 to 22 min, exit 143); CI Test shards 1 to 16 success at 4bd617b. Ablations, each committed first, with a restore leg proved by git diff HEAD empty: (1) item 6 probe importing SelectOptionKind from @objectstack/spec/data, tsc --ignoreConfig --noEmit: pin exit 0; stand-in tree at e5136ff10f (next.2) exit 2 TS2724; restore exit 0 (first attempt was a no-op, TS5112 because a tsconfig is present, re-run with --ignoreConfig). (2) hermetic checkout: dropping the remote-remove call (anchor count 1 to 0) turns its test red, AssertionError expected 'origin' to be ''; restore diff 0 bytes, test green. (3) a packed manifest dependency the lockfile does not record: frozen install exits 0 without installing it, assertLockfileRecordsBuild exits 1 naming the package, control exit 0. Item 3 stand-ins: OBJECTSTACK_ROOT at 93b4acb57e (old pin) and at e5136ff10f (new pin): build exit 0, frozen install exit 0, pnpm-lock.yaml sha256 da56792a0bb44808 before and after.",
    "gates": "CI at 4bd617b, check-runs read from the API: Build & E2E, Build Docs, Bundle Analysis, Changeset Claim Re-read, Changeset Declaration, Changeset Fixed Group Check, Governed Surface Queue Guard, Line Citation Gate, Lint, Live E2E (informational), Lockfile Dedupe Check, Lockfile Integrity Check, Repo Gates, Test (dist pins), Test shards 1 to 16, Test, Type Check, label = success; Test (coverage shard), Test (coverage), dependabot = skipped (33 success, 3 skipped). Local subset (objectui has no dispatch-gates.mjs, so the families were hand-derived from package.json and .github/workflows; no --ran reconciliation exists there): check-lockfile-dedupe VERDICT deduped; check-installed-spec-pin-claims OK; check-spec-symbol-derivation green; check-action-ref-convention 141 refs 0 off-convention; check-control-bytes OK; check-pre-install-import-graph OK (57 pre-install steps); check-shell-escape-residue OK; line-citation VERDICT 0 new, exit 0; test-path-roots, eslint on changed files and check-entry-guard exit 0 at 4bd617b; changeset presence: 0 published source changed, no changeset owed; changeset claims: none touch these files; changeset fixed-group check green; governed guard exit 3 = GOVERNED 14 of 42 paths (AGENTS.md, .github/workflows), so the PR stays draft for os-zhuang or hotlong. All exit codes captured before any pipe.",
    "mcp_calls": "0 — no MCP GitHub tool was called",
    "api_writes": "2 — both through the fleet-write relay (each a POST /repos/objectstack-ai/objectstack/dispatches executed as objectstack-fleet[bot]): (1) pr_create = POST /repos/objectstack-ai/objectui/pulls (draft, assignees sunhaolin), read back 12294 bytes sent and stored identical; (2) this os-dev-report comment = POST /repos//issues/12957/comments. git push is not counted. No label, assignee or PATCH writes; the PR labels are the labeler's.",
    "deviations": [
    "Local packages/app-shell full suite not measured (shared-box runtime over 19 minutes, own PIDs stopped); declared narrowing, CI shards ran it green.",
    "Files beyond the claim's file surface, each forced by the change and named in the PR body: turbo.json, scripts/dependabot-merge-gate.mjs (one prose string), README.md, CONTRIBUTING.md, QUICK_REFERENCE.md, scripts/setup.sh, content/docs/guide/console.md, content/docs/utilities/runner.mdx, content/docs/guide/ci-cd-pipeline.md, five script tests, and path filters in performance-budget.yml and lockfile-dedupe.yml."
    ],
    "pr_body_corrections": [
    "The PR body was written once, before the seat's item-6 change, and is not PATCHed by me; it needs these edits by the seat.",
    "Paragraph 1: the pin is 2c9bf9430a1198bfaa5c0de9ff4a811838c6869c (objectstack chore: version packages (next) (#23825), the @objectstack/spec 18.0.0-next.3 release commit), not main 2ee5861b0f; mark it as the seat-directed scope change.",
    "Item 6 section: replace the is-ancestor proof with the equivalence result in this report, and state that the pin is a strict ancestor of 586705d85d, 1e001c7df and e15897c0f1 (separate pin-bump card).",
    "Ablation section: replace the emptyState probe with the SelectOptionKind probe (pin exit 0, e5136ff10f exit 2 TS2724, restore exit 0).",
    "Item 3: add the e5136ff10f stand-in at the new pin (frozen exit 0, lockfile identical).",
    "Cold build: replace NOT MEASURED with the CI numbers (n=23 cold 71 to 125 s, median 111 s; warm build 0 s, restore 2 to 3 s; save 0 to 2 s) and the worktree setup numbers.",
    "How it resolves: add the npm_config_* scrub for the objectstack install, the remote removal after the fetch (spec ratchets anchor on origin/main; 13 of 25 jobs failed at db2b723 naming PackageInstallManifest.json and PageRecordBinding.json), and the objectstack-pin GitHub annotation on any build failure.",
    "Type check line: 81 of 81 at 4bd617b.",
    "维护者速读: remove the claim that the pin already contains the three backend commits (it precedes all three); first pin = next.3 release commit; cold cost about 2 min per CI job (median 111 s) and about 3 min locally; add the pin-bump card as the next step."
    ],
    "open_questions": [
    {
    "question": "Dependabot npm updates regenerate the lockfile without the pinned build; locally pnpm install --lockfile-only without it exits 1 (ERR_PNPM_LINKED_PKG_DIR_NOT_FOUND). Dependabot's own sandbox is NOT MEASURED until its first post-merge npm run. What should happen?",
    "options": [
    "A: a scheduled in-repo workflow runs pnpm run setup and then the dependency update, opening the PR itself (cost: one new workflow, about a day)",
    "B: track the seven packed package.json manifests so lockfile-only resolution works without a build (cost: a second copy of package identity beside the pin, drift risk)",
    "C: accept failing Dependabot npm PRs and update by hand (cost: lose the automation)"
    ],
    "recommendation": "Read Dependabot's first post-merge run; if it fails, A, because B reintroduces a second identity for the packages beside .objectstack-sha"
    },
    {
    "question": "Shared pin cache card: cold pnpm run setup is 2m56s for a fresh worktree and 2m48s for the next one, just under the about-3-minute line; a shared cache would cut a further worktree to about 6.5 s. Open the card?",
    "options": [
    "A: open it (saves about 160 s per worktree, every dispatch creates one)",
    "B: do not open it (the measured cost is under the line)"
    ],
    "recommendation": "A, because every dev dispatch pays it once per worktree and the saving is about 96 percent of setup; the decision is the seat's per the maintainer's order"
    },
    {
    "question": "Accept the file-surface extensions listed in deviations (all forced by the change: tests fail or a documented command fails on a clean checkout without them)?",
    "options": [
    "A: accept as is",
    "B: split the docs edits into a docs-only follow-up"
    ],
    "recommendation": "A, because a clean checkout following the old docs fails with ERR_PNPM_LINKED_PKG_DIR_NOT_FOUND"
    }
    ],
    "out_of_scope_findings": [
    "class: a · reach: public door, objectstack AGENTS.md:40 and examples/README.md:42 (origin/main e4bcced0b4) document pnpm setup as the first-time command; pnpm 10 runs its built-in setup (writes PNPM_HOME to the shell rc) and never runs the package script (install + spec build), measured with the same pnpm 10.31.0 · fix: pnpm run setup · dedupe words: pnpm setup builtin, first-time setup, spec build, AGENTS.md quick start",
    "class: a · reach: named real producer, objectui's pinned build (objectui#12963 CI at db2b723: 13 of 25 jobs failed) · evidence: objectstack packages/spec/scripts/build-schemas.ts:2466 fetches origin main during the build and judges the commit's published set against it, so building the 18.0.0-next.3 commit 2c9bf943 failed with 2 schema(s) left the published set with no registered removal (#4725): json-schema/api/PackageInstallManifest.json, json-schema/ui/PageRecordBinding.json, once main had added them; a released commit's spec build is not reproducible from a clone with a newer origin/main (worked around here by removing the remote after the fetch) · dedupe words: spec build origin/main anchor, schema disappearance ratchet, reproducible build, json-schema.manifest",
    "carrier: domain:ui seat 1, for the pin-bump card it named · noted, not filed · drift the next pin must absorb, measured at 2ee5861: 15 failing cases in 5 files (registry-inputs-spec-parity: list-view row, counts 60 to 61 and 40 to 41, marketplace:installed-list retired, emptyState; block-config.test.ts record:json stale exclusion; record-highlights-layout-9187 emptyState; checkPageRecordBindingPlacement; ObjectTree.schemaTyped-8655)",
    "承接者:无 · noted in Acceptance notes only: apps/console/vercel.json installs with a frozen install on Vercel and would need the pin first (no Vercel status on recent main commits); e2e/live/ci/backend.env header still says the version is resolved in pnpm-lock.yaml; the live-e2e backend matches the console by version number, not by commit; spec DTS emit is nondeterministic in union member order (JS identical)"
    ]
    }


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 18, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT → PR #12963 comment 6251777447 · CONTRACT_REVIEW_TIER PASS 6251765296 (governed rules face) · head 4bd617b · domain:ui seat 1 · session_0188TsgPV8kQXfuRuKmkj2ks · 2026-10-18T15:37Z

    Tier H: the PR waits, as a draft, for an APPROVED review by os-zhuang or hotlong. The seat then makes it ready and arms auto-merge. Follow-ups are Blocked-by this card: objectui#12958, objectstack-ai/objectstack#24306, objectui#12971 and objectui#12972.


    Generated by Claude Code

  7. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:ui seat 1 · session_0188TsgPV8kQXfuRuKmkj2ks · 2026-10-19T00:31Z

    PR #12963 merged through objectui's merge queue as 749ed76076. Its one parent is d3fd5e4f, and the merge is an ancestor of origin/main.

    probe parent d3fd5e4f merge 749ed760
    merge diff vs the reviewed diff (git patch-id --stable) — identical to both the ACCEPT head 4bd617b0 and the approved head 9039f819 (6f551e87; 42 files, +2700 / −317)
    .objectstack-sha absent 2c9bf9430a1198bfaa5c0de9ff4a811838c6869c
    root pnpm.overrides for @objectstack/* 0 7, each file:node_modules/.cache/objectstack/NAME
    pnpm-lock.yaml package keys @objectstack/NAME@VERSION 14 0
    workflows that call objectstack-pin 0 12; every workflow that installs is one of them
    a model name in the merge commit's message — 0

    State change:

    • Fixes #12957 closed this card completed, and this act removes pm:dispatched.
    • objectui now resolves @objectstack/* from a build of the pinned commit, not from npm. A fresh checkout starts with pnpm run setup.
    • The merge-queue run on the merged tree passed (CI, Lint, Repo Gates, Governed Surface Guard, Changeset Presence; runs from 39179626179), and Changeset Release on the main push passed (39180840183).

    Still open, read after this note:

    • The first main push run of CI (39180840201) was in progress at writing time. It is the first cache save under main's scope.
    • Dependabot's first npm update after the merge (job 39180936608, rebasing objectui#11845) was in progress at writing time. If it fails, the seat files the follow-up (default: a scheduled in-repo update workflow that runs pnpm run setup first).

    Unblocked by this landing (each re-derived and moved to pm:queue in its own act): objectui#12958, objectstack-ai/objectstack#24306, objectui#12971 and objectui#12972.

    Landing order the seat holds:

    Records:

    • the claim 6248917934, with item 6 amended at 6250606447;
    • the dev's report 6251605870;
    • the contract review 6251765296 (CONTRACT_REVIEW_TIER, PASS);
    • the ACCEPT 6251777447 (pointer 6251783303);
    • os-zhuang's APPROVED review 5565719968 at 9039f819.

    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, iteratedomain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repotooling

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions