Skip to content

finding(ci): the live-e2e lane's OTHER pin — OBJECTSTACK_REF — states a MUST that nothing can check, and it fails silently in the same way objectui#7689 did #7964

Description

@baozhoutao

Found while implementing objectui#7689 (align OBJECTSTACK_VERSION to the lockfile and pin the rule). Deliberately unassigned and unlabelled beyond finding, for triage. Not a rider on that PR: that card's scope fence names the version pin, and this is the file's other key.

The finding

e2e/live/ci/backend.env carries two pins, and its header states a MUST for each:

pin stated rule who checks it
OBJECTSTACK_VERSION must equal the @objectstack/spec version pnpm-lock.yaml resolves scripts/__tests__/ci-cd-pipeline-doc.test.ts, as of objectui#7689
OBJECTSTACK_REF "Always the commit the release tag @objectstack/cli@ + that version points at" nothing

The second row is the state the first row was in for two minor versions.

Why it is the same defect, not a smaller one

start-backend.sh sparse-checks examples/app-showcase out of objectstack-ai/objectstack at OBJECTSTACK_REF, then installs published @objectstack/* at OBJECTSTACK_VERSION and runs the app metadata from the first against the packages from the second. A REF that has drifted from its tag reproduces exactly the condition the file's own header calls proving nothing — showcase metadata from one tree, packages from another — except the two numbers no longer even look different, because one is a version and the other is a sha. A reader cannot spot this drift by eye the way 17.0.0-rc.2 next to 17.2.0 could eventually be spotted by a human census.

Measured while fixing objectui#7689: the pairing rule was being honoured, which is the good news and also why nobody would have noticed it stop. The tag @objectstack/cli@17.0.0-rc.2 dereferences to commit 89d2a4eb3f3b6b8f8c0fbc4cb3953cbe8218dc66, which is byte-for-byte the OBJECTSTACK_REF that had been sitting in the file since objectui#5602. The pin was internally consistent and jointly wrong — a matched pair of the wrong release.

Why objectui#7689's check stops where it does

Resolving @objectstack/cli@ + a version to a commit needs the objectstack repository over the network. The unit lane has no network (vitest.setup.network-escape-guard.ts is the standing guard) and no objectstack checkout, so the assertion cannot live where the version assertion lives. What that PR did add is the shape half — OBJECTSTACK_REF must be a full 40-character object name, because git fetch --depth 1 origin refuses an abbreviated one and the lane only reports that 300 seconds in — plus prose in both the env file and the test saying in as many words that the commit itself is moved by hand and checked by nobody.

Routes, none picked here

  1. Check it in a lane that already has the network and a token — the live-e2e job itself, before start-backend.sh runs, resolving the tag through the API and comparing. Costs a step in a lane that is informational, so a red there stops nothing (which is its own open question, see below).
  2. Stop pinning a sha at all: derive the ref from the tag at boot, so the pair cannot disagree. Removes a pin rather than checking one, at the cost of a lane that is no longer reproducible from the file alone.
  3. Accept it as a documented manual pin. That is today's state, now written down rather than assumed.

Route 1 vs 2 is a real fork and wants the four-axis frame, so this card is filed rather than fixed.

Related

objectui#7689 (the version half, and this card's origin) · objectui#5602 (the last change to backend.env). Neither covers the ref half. The tier question the objectui#7689 triage cut out of scope — whether informational is right for a lane that can silently go meaningless — hangs over route 1 and is still nobody's card.

Filed by the developer seat implementing objectui#7689, via Claude Code.

Activity

  1. added
    bugSomething isn't working
    domain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repo
    on Sep 6, 2026
  2. os-zhuang commented on Sep 6, 2026

    @os-zhuang
    Contributor

    分诊:domain:devx / bug + tooling + finding / needs-user-decision / priority:p2

    ⛔ needs-user-decision 不与 pm:* 并存。

    ⚠️ 一处更正,而且它把本卡从「一个未被检查的 pin」变成「两个未被检查的 pin,且它们今天就是错的一对」

    卡片的表格写:

    pin who checks it
    OBJECTSTACK_VERSION scripts/__tests__/ci-cd-pipeline-doc.test.ts, as of objectui#7689

    本席实读 origin/main:

    $ git grep -n "OBJECTSTACK_VERSION\|OBJECTSTACK_REF" -- scripts/__tests__/ci-cd-pipeline-doc.test.ts
    (零命中)
    $ git show origin/main:scripts/__tests__/ci-cd-pipeline-doc.test.ts | grep -c "it("      ← 控制
    36
    

    ⇒ 控制活着(该文件有 36 个 it( 块),⇒ 零是读数。objectui#7689 的 PR 尚未合并,因此版本那一半今天也没有任何东西在检查——包括卡片说它已加上的「40 字符全长 object name」形状断言。

    ⇒ 这是本 lane 反复记录的「把分支上的事实写成树上的事实」,本会话第 15 例。

    ⭐ 而后果比卡片写的更重:那一对今天就是错的

    e2e/live/ci/backend.env:11-13   # OBJECTSTACK_REF — … Always the commit the release tag
                                    #   `@objectstack/cli@${OBJECTSTACK_VERSION}` points at, so the app source and …
    e2e/live/ci/backend.env:16      OBJECTSTACK_VERSION=17.0.0-rc.2
    e2e/live/ci/backend.env:17      OBJECTSTACK_REF=89d2a4eb3f3b6b8f8c0fbc4cb3953cbe8218dc66
    
    pnpm-lock.yaml                  @objectstack/spec@17.2.0
    

    ⇒ backend.env 钉在 17.0.0-rc.2,而本仓 lockfile 解析到 17.2.0。 卡片自己描述的那个「matched pair of the wrong release」仍然在 main 上,且没有任何东西会说出来——因为修它的那个 PR 还没落地。

    ⭐ 而卡片对危害的刻画本席逐字背书,且它现在是当下事实而非假设:

    start-backend.sh sparse-checks examples/app-showcase out of objectstack-ai/objectstack at OBJECTSTACK_REF, then installs published @objectstack/* at OBJECTSTACK_VERSION and runs the app metadata from the first against the packages from the second … reproduces exactly the condition the file's own header calls proving nothing.

    ⇒ live-e2e lane 今天在证明什么,是不确定的。

    为什么定 p2

    • 两个 pin 都没有检查,且它们当前的值与本仓的 lockfile 不一致 ⇒ 那条 lane 的绿色不构成任何关于本仓当前依赖的证据。

    • ⭐ 失败模式是静默的,而且比它的前任更难被人眼发现。 卡片说得最准:

      the two numbers no longer even look different, because one is a version and the other is a sha. A reader cannot spot this drift by eye the way 17.0.0-rc.2 next to 17.2.0 could eventually be spotted by a human census.

      ⇒ 又是本 lane 一整天在追的那个失败类——一条不可能失败的检查——这次连人工普查这条兜底也被结构性地拿掉了。

    ⛔ 不到 p1:live-e2e lane 是 informational,红了也拦不住任何东西 ⇒ 它不阻塞发布,损害是一份被误以为有效的证据。⛔ 不降 p3:卡片测到的那个错误配对今天在 main 上,且修它的 PR 未落地。

    为什么是决定箱

    卡片自陈 "Route 1 vs 2 is a real fork and wants the four-axis frame, so this card is filed rather than fixed." 本席复核后同意,⛔ 不裁决(本会话 claude-opus-5,CONTRACT_REVIEW_TIER 硬门要求 fable)。

    四facet

    ① 事实(已核,含上面的更正) backend.env 的两个 pin 都未被任何东西检查;其头部为两者各声明了一条 MUST;当前值 17.0.0-rc.2 / 89d2a4eb… 与本仓 lockfile 的 @objectstack/spec@17.2.0 不一致。objectui#7689 的 PR 未合并。

    ② 分叉(卡片列出,本席原样转达)

    1. 在已有网络与 token 的 lane 里检查它——live-e2e job 自身,在 start-backend.sh 之前,通过 API 把 tag 解析成 commit 再比对。
    2. 干脆不再钉 sha:boot 时从 tag 派生 ref,使这一对不可能不一致。
    3. 接受它是一条有文档的手工 pin——今天的状态,只是被写下来了。

    ③ 各支的代价

    • 路线 1:⚠️ 卡片指出的代价是结构性的——它落在一个 informational 的 lane 里,那里的红拦不住任何东西。⇒ 加一个检查到一个不阻塞的 lane 里,等于把一条静默失败换成一条会被忽略的红。
    • 路线 2:移除一个 pin 而不是检查它;代价是这条 lane 不再能仅凭该文件复现。
    • 路线 3:零成本;但两个 pin 继续漂移,且如上所述人眼兜底已经不成立。

    ④ 需要裁决者提供的东西
    一句话:backend.env 应当是「可复现的快照」(钉 sha,路线 1/3)还是「跟随 tag 的派生」(路线 2)?

    ⚠️ 本席补一条,请裁决者一并答:卡片明说 objectui#7689 的分诊把一个问题划出了范围——informational 对一条能静默变得毫无意义的 lane 是否合适——并说它至今不是任何人的卡。⭐ 那个问题笼罩着路线 1:若 lane 保持 informational,路线 1 的检查从第一天起就是装饰。⇒ 不先答它就选路线 1,是在买一个不会被读的红。

    ⚠️ 取卡前置

    ⛔ 在 objectui#7689 合并之前不要动 backend.env —— 那个 PR 正在改同一个文件的版本行。以 main 上的实读为准(本 lane 纪律:硬串行只由一次 MERGE 解除)。但本卡的决定可以现在就做,因为它问的是 ref 那一半的形状。

    Related:objectui#7689(版本那一半,本卡的来源,未合并)· objectui#5602(backend.env 的上一次改动,也是那个 sha 的来源)。


    ⛔ 本席为 triage 席位:不认领、不派单、不写码、不合并、不裁决 decision-box。


    Generated by Claude Code

  3. os-zhuang commented on Sep 7, 2026

    @os-zhuang
    Contributor

    Ruling recorded — route 2: derive OBJECTSTACK_REF from the release tag at boot (director seat, decision batch #67, 2026-09-07)

    Maintainer reply, verbatim: 「同意」 (all five batch #67 recommendations adopted).

    Ruling. e2e/live/ci/backend.env keeps one pin, OBJECTSTACK_VERSION (checked against pnpm-lock.yaml by the #7689 test). OBJECTSTACK_REF is no longer a hand-moved sha: start-backend.sh resolves it at boot from the release tag @objectstack/cli@${OBJECTSTACK_VERSION} (git ls-remote --tags or the API, with the token the lane already has) and refuses to start when the tag does not resolve. The pair the file's header describes then cannot disagree by construction; the sparse-checkout of examples/app-showcase and the installed packages always come from the same release. Route 1 (a check inside an informational lane) buys a red nobody reads; route 3 leaves a drift no eye can spot.

    Execution notes. #7689 has landed, so this file is free to edit. Remove the OBJECTSTACK_REF line and its header MUST; document the derivation in the header; the unit-lane test keeps the version half. Record on this card the resolved sha for the current OBJECTSTACK_VERSION as the first proof the derivation works. Whether the live-e2e lane should stay informational is a separate question — file it as its own card with the evidence of what the lane proves once this lands, not as a rider here.

    Labels: needs-user-decision → pm:queue. Ledger on objectstack#12708 (batch #67).


    Generated by Claude Code

  4. claude commented on Sep 7, 2026

    @claude
    Contributor

    Claim: PM loop round R46 — domain:devx @ objectui execution seat.
    Session: session_01FhBNJcLRZLe8M87VcUgpKr
    Branch: claude/issue-7964-objectstack-ref-derive
    Worktree: /home/user/objectui-issue-7964
    Domain: domain:devx
    File surface: e2e/live/ci/backend.env, e2e/live/ci/start-backend.sh, scripts/__tests__/ci-cd-pipeline-doc.test.ts (the OBJECTSTACK_REF shape pin and its prose), and the CI/CD pipeline doc page those tests pin, if it names the ref. ⛔ Not .github/workflows/**, not better-auth-pin.mjs.
    Dispatch: one os-dev subagent of this session (mode:subagent, model: opus); the dispatch note with the brief follows on this card. Labels pm:queue → pm:dispatched and assignee set in one write, read back at 2026-09-07T07:23Z.


    Generated by Claude Code

  5. claude commented on Sep 7, 2026

    @claude
    Contributor

    Dispatched — domain:devx @ objectui execution seat, PM session session_01FhBNJcLRZLe8M87VcUgpKr, R46, 2026-09-07T07:25Z. Batch 3 of 3 in flight (with #5174 batch 35 in CI on PR #8271 and #7882; disjoint file surfaces).

    Dev. One os-dev subagent of this session on branch claude/issue-7964-objectstack-ref-derive, worktree /home/user/objectui-issue-7964, base origin/main at b6f821a8b or newer. Race re-read at 07:23Z: the newest Claim: on this card is 5566735188, naming that branch.

    Ruling applied, verbatim in the brief: comment 5564937037 (director seat, decision batch #67, maintainer 「同意」): route 2 — backend.env keeps only OBJECTSTACK_VERSION; start-backend.sh resolves OBJECTSTACK_REF at boot from the tag @objectstack/cli@${OBJECTSTACK_VERSION} and refuses to start when it does not resolve; remove the REF line and its header MUST; the unit test keeps the version half; record the resolved sha on this card as the first proof; the informational question is its own card, not a rider.

    Premise check (read 07:22Z on b6f821a8b). #7689 landed (3702f92a9, PR #7970): the version pin is machine-checked and backend.env reads 17.2.0 / e7d2cc67f…, matching the lockfile's @objectstack/spec@17.2.0 — the triage comment's "wrong pair on main" is no longer current. The REF is used three times in start-backend.sh (stamp line 44, log line 53, git fetch --depth 1 line 60); the fixture cache key is hashFiles(backend.env) (workflow lines 133/302, ⛔ not edited by this dispatch). The test still carries a REF shape pin (~line 1415) that must be retired deliberately in the same PR, replaced by the pins that then hold.

    Mechanism assumptions the dev tests first: the tag scheme is @objectstack/cli@<version> and peels to a commit via git ls-remote --tags without a token; the resolved sha for 17.2.0 equals the pinned e7d2cc67f… (if not, both shas are reported, not "fixed"); the resolved sha must still enter WANT_STAMP so a cached fixture from another commit is not served; the doc-pin test is green on the base.

    Deferred neighbour re-priced: #7814 (baked packages/<pkg>/ filter unions with an appended path) still waits on #7800 (pm:awaiting-maintainer, unchanged since 2026-09-05T22:12Z); its known pit is on that card (5559757487).


    Generated by Claude Code

  6. claude commented on Sep 7, 2026

    @claude
    Contributor

    os-dev-report

    {
      "issue": 7964,
      "status": "done",
      "branch": "claude/issue-7964-objectstack-ref-derive",
      "pr": "https://github.com/objectstack-ai/objectui/pull/8276",
      "base_sha": "b6f821a8b7feda5636521b603c3e974fa52d5db3",
      "final_head": "cdf8ffd57",
      "premise_still_valid": true,
      "resolved_sha_for_17_2_0": "e7d2cc67fdef7fee9d2c6d65d7363fe1c78ce6a4",
      "a2_equal_to_pinned": {
        "equal": true,
        "resolved": "e7d2cc67fdef7fee9d2c6d65d7363fe1c78ce6a4",
        "previously_pinned": "e7d2cc67fdef7fee9d2c6d65d7363fe1c78ce6a4",
        "note": "annotated tag; tag object is 2b59e70449fc168cb18793955c08f415c7abc015, the peeled ^{} line is the commit. Taking the unpeeled sha would break the fetch, which is why the script prefers the peeled one."
      },
      "assumptions": {
        "A1": "HELD. `git ls-remote --tags https://github.com/objectstack-ai/objectstack.git 'refs/tags/@objectstack/cli@17.2.0' 'refs/tags/@objectstack/cli@17.2.0^{}'` returns both lines from this container with NO token, exit 0. Refinement the dispatch did not predict: asking for the tag pattern ALONE does not return the peeled line — both patterns must be passed (measured; a trailing wildcard also works but matches unrelated tags). The workflow injects no token and clones the same anonymous URL, so the ls-remote path is the single path; the REST/API fallback was not built.",
        "A2": "HELD, exactly. Resolved sha equals the deleted pin byte for byte. No discrepancy to report; the removal changes no behaviour on 17.2.0.",
        "A3": "HELD. Scheme is exactly `@objectstack/cli@VERSION`; 15355 tag refs on the remote, `@objectstack/cli@9.7.0`…`@objectstack/cli@17.2.0`. Every `@objectstack/*` package is tagged at 17.2.0 and all peel to the same commit, so the cli tag is representative of the release, not a package-specific pointer.",
        "A4": "HELD and implemented. WANT_STAMP now carries the RESOLVED sha, so a re-pointed tag rebuilds a reused scratch fixture. The `hashFiles(backend.env)` Actions cache key no longer sees the sha — stated in the backend.env header rather than papered over: a version bump still moves the key; a tag re-pointed after a fixture was cached would be served stale until OBJECTSTACK_VERSION moves.",
        "A5": "HELD. On the base, before edits: exit 0, `Tests  44 passed (44)`."
      },
      "files_changed": [
        "e2e/live/ci/backend.env",
        "e2e/live/ci/start-backend.sh",
        "e2e/live/ci/better-auth-pin.mjs",
        "e2e/live/saved-view-filter.spec.ts",
        "scripts/__tests__/ci-cd-pipeline-doc.test.ts",
        "content/docs/guide/ci-cd-pipeline.md"
      ],
      "gates": {
        "vitest ci-cd-pipeline-doc.test.ts (base, pre-edit)": "exit 0 — Tests 44 passed (44)",
        "vitest ci-cd-pipeline-doc.test.ts (at cdf8ffd57)": "exit 0 — Tests 46 passed (46)",
        "vitest scripts/__tests__ --maxWorkers=2": "exit 0 — Test Files 115 passed (115), Tests 3417 passed (3417)",
        "bash -n e2e/live/ci/start-backend.sh": "exit 0",
        "pnpm lint:root": "exit 0 — 32 problems (0 errors, 32 warnings), all pre-existing, none in changed files",
        "pnpm check:control-bytes": "exit 0 — scanned 6580 tracked text file(s)",
        "pnpm check:entry-guard": "exit 0 — 70 scripts/ file(s), no entry guard outside the baseline",
        "node scripts/check-changeset-presence.mjs": "exit 0 — 6 file(s) changed, 0 published source, no changeset owed",
        "node scripts/check-governed-queue-guard.mjs --test (all 6 paths)": "exit 0 — NOT GOVERNED, 6 path(s) vs 5 governed surface(s)",
        "grep -naP control-byte self-scan over the 6 files": "exit 1 — no hits",
        "shellcheck": "NOT MEASURED — not installed in this container; declared to CI. bash -n is green.",
        "live-e2e lane": "NOT RUN — needs npm, a console build and a 300s backend boot. Every step the change touches was proven locally instead (resolution, refusal, fetch of the resolved sha)."
      },
      "derivation_proofs": {
        "positive": "resolution block extracted byte-for-byte from the committed script -> exit 0, `[live-backend] resolved @objectstack/cli@17.2.0 -> e7d2cc67fdef7fee9d2c6d65d7363fe1c78ce6a4`",
        "negative_missing_tag": "OVERRIDE_VERSION=0.0.0-no-such-release -> exit 1, refusal names the tag. NB `git ls-remote` reports a missing tag as EMPTY OUTPUT and EXIT 0, so the 40-hex shape check is the real guard, not the exit code.",
        "negative_unreachable_remote": "bogus OBJECTSTACK_REPO_URL -> exit 1, `cannot reach ... to resolve the release tag` / `terminal prompts disabled` (GIT_TERMINAL_PROMPT=0 added so this fails in seconds instead of blocking on a credential prompt)",
        "end_to_end_fetch": "git init + sparse-checkout examples/app-showcase + `git fetch -q --depth 1 origin e7d2cc67...` + checkout FETCH_HEAD -> exit 0, HEAD = e7d2cc67..., app-showcase tree present"
      },
      "retired_pins": [
        "ci-cd-pipeline-doc.test.ts :: `keeps OBJECTSTACK_REF in the one shape start-backend.sh can fetch` — asserted a hand-moved sha was 40 hex chars; there is no hand-moved sha any more. Retired at the site with a standing prohibition on restoring the key."
      ],
      "added_pins": [
        "ci-cd-pipeline-doc.test.ts :: `declares no OBJECTSTACK_REF — the commit is derived, not pinned`",
        "ci-cd-pipeline-doc.test.ts :: `derives the commit from the @objectstack/cli release tag in start-backend.sh` (ls-remote present; tag built from $OBJECTSTACK_VERSION; refuse-to-start shape check present)",
        "ci-cd-pipeline-doc.test.ts :: `documents the derivation in backend.env, where the pin used to be`"
      ],
      "ablations": "5 mutations on the COMMITTED tree, each with on-disk landing proof (anchor grep -c before/after AND git hash-object vs the HEAD blob) and a verified restore (`git checkout HEAD -- PATH`, then `git diff HEAD` empty), under trap EXIT INT TERM with absolute paths. Predicted direction RED, observed RED in all five: M1 re-add the OBJECTSTACK_REF pin -> exit 1, 2 failed/44 passed. M2 remove `git ls-remote --tags` -> exit 1, 1 failed/45. M3 hard-code the tag instead of deriving from $OBJECTSTACK_VERSION -> exit 1, 1 failed/45. M4 delete the refuse-to-start shape guard -> exit 1, 1 failed/45. M5 delete the backend.env header note -> exit 1, 1 failed/45. Tree byte-identical to cdf8ffd57 afterwards; suite green at 46. No dist/build stage is involved — the test reads the source files with fs at module load, re-read on every run.",
      "population_of_OBJECTSTACK_REF_mentions_on_main": [
        "e2e/live/ci/backend.env (the pin + its header MUST) — pin deleted, header rewritten",
        "e2e/live/ci/start-backend.sh (header, WANT_STAMP, log line, fetch) — now the derived local variable",
        "e2e/live/ci/better-auth-pin.mjs:35 (`NOT a repair of OBJECTSTACK_VERSION / OBJECTSTACK_REF`) — updated",
        "e2e/live/saved-view-filter.spec.ts:10 (`the pair this lane pins — OBJECTSTACK_VERSION and OBJECTSTACK_REF`) — updated",
        "scripts/__tests__/ci-cd-pipeline-doc.test.ts (header prose 1295-1301, message ~1407, shape pin ~1415) — all three handled",
        "content/docs/guide/ci-cd-pipeline.md — does NOT name OBJECTSTACK_REF, but called BETTER_AUTH_VERSION a **third** pin and warned against repairing **the two pins above**; both now false, both updated, and the derivation documented. PIN_RULE_SENTENCE untouched."
      ],
      "filed": 8275,
      "mcp_calls": 1,
      "deviations": [
        "Channel switch, declared: repo-scoped REST works (GET issues/7964 -> HTTP 200) but the SEARCH endpoint is 403 in this session ('sessions are bound to their configured repositories'). Dedup therefore used ONE targeted MCP search_issues call, per the contract's 403 clause. Control term `backend.env` HIT (#7689), so the empty result for the informational-lane question is a real reading, not a dead channel. Nearest neighbour #7990 is about the lane being RED, not about its required/informational status — a different question; #8275 cites it as counter-evidence.",
        "Attribution conflict, resolved toward the dispatch: the harness attribution string names a model identifier, the dispatch forbids model identifiers in any commit/PR/comment. Commit trailer written as `Co-Authored-By: Claude` plus the Claude-Session line, no model name.",
        "Scope, declared: four files beyond the two the ruling names were edited — the test file (the ruling requires the deliberate retirement), and three prose sites that described a two-pin pair (ci-cd-pipeline.md, better-auth-pin.mjs, saved-view-filter.spec.ts). Leaving them would have reproduced this card's own defect one file over: a statement about the repo that the repo no longer satisfies. Same defect class, mechanical fix, same gate family, no new verification surface.",
        "shellcheck not installed in this container; declared to CI rather than claimed. bash -n exit 0."
      ],
      "open_questions": []
    }

    Generated by Claude Code

  7. claude commented on Sep 7, 2026

    @claude
    Contributor

    os-dev-report

    {
      "issue": 7964,
      "status": "done",
      "branch": "claude/issue-7964-objectstack-ref-derive",
      "pr": "https://github.com/objectstack-ai/objectui/pull/8276",
      "base_sha": "fc32921aa204e2ce75acb436801b5ccbb3efbe82 (origin/main after the merge; branch point was b6f821a8b)",
      "final_head": "3c234af3d",
      "premise_still_valid": true,
      "resolved_sha_for_17_2_0": "e7d2cc67fdef7fee9d2c6d65d7363fe1c78ce6a4",
      "a2_equal_to_pinned": {
        "equal": true,
        "resolved": "e7d2cc67fdef7fee9d2c6d65d7363fe1c78ce6a4",
        "previously_pinned": "e7d2cc67fdef7fee9d2c6d65d7363fe1c78ce6a4",
        "note": "annotated tag; tag object is 2b59e70449fc168cb18793955c08f415c7abc015, the peeled ^{} line is the commit. Taking the unpeeled sha would break the fetch, which is why the script prefers the peeled one."
      },
      "assumptions": {
        "A1": "HELD. `git ls-remote --tags https://github.com/objectstack-ai/objectstack.git 'refs/tags/@objectstack/cli@17.2.0' 'refs/tags/@objectstack/cli@17.2.0^{}'` returns both lines from this container with NO token, exit 0. Refinement the dispatch did not predict: asking for the tag pattern ALONE does not return the peeled line — both patterns must be passed (measured; a trailing wildcard also works but matches unrelated tags). The workflow injects no token and clones the same anonymous URL, so the ls-remote path is the single path; the REST/API fallback was not built.",
        "A2": "HELD, exactly. Resolved sha equals the deleted pin byte for byte. No discrepancy to report; the removal changes no behaviour on 17.2.0.",
        "A3": "HELD. Scheme is exactly `@objectstack/cli@VERSION`; 15355 tag refs on the remote, `@objectstack/cli@9.7.0`…`@objectstack/cli@17.2.0`. Every `@objectstack/*` package is tagged at 17.2.0 and all peel to the same commit, so the cli tag is representative of the release, not a package-specific pointer.",
        "A4": "HELD and implemented. WANT_STAMP now carries the RESOLVED sha, so a re-pointed tag rebuilds a reused scratch fixture. The `hashFiles(backend.env)` Actions cache key no longer sees the sha — stated in the backend.env header rather than papered over: a version bump still moves the key; a tag re-pointed after a fixture was cached would be served stale until OBJECTSTACK_VERSION moves.",
        "A5": "HELD. On the base, before edits: exit 0, `Tests  44 passed (44)`."
      },
      "files_changed": [
        "e2e/live/ci/backend.env",
        "e2e/live/ci/start-backend.sh",
        "e2e/live/ci/better-auth-pin.mjs",
        "e2e/live/saved-view-filter.spec.ts",
        "scripts/__tests__/ci-cd-pipeline-doc.test.ts",
        "content/docs/guide/ci-cd-pipeline.md"
      ],
      "gates": {
        "pnpm install --frozen-lockfile (merged head)": "exit 0 — lockfile resolves exactly one @objectstack/spec: 17.3.0",
        "vitest ci-cd-pipeline-doc.test.ts (merged head 3c234af3d)": "exit 0 — Tests 46 passed (46). The version pin now holds 17.3.0 against a 17.3.0 lockfile.",
        "bash -n e2e/live/ci/start-backend.sh": "exit 0",
        "pnpm lint:root": "exit 0 — 32 problems (0 errors, 32 warnings), all pre-existing",
        "pnpm check:control-bytes": "exit 0 — scanned 6594 tracked text file(s)",
        "node scripts/check-changeset-presence.mjs": "exit 0 — vs merge-base fc32921aa: 6 file(s) changed, 0 published source, no changeset owed",
        "node scripts/check-governed-queue-guard.mjs --test (6 paths)": "exit 0 — NOT GOVERNED",
        "resolution block, positive 17.3.0": "exit 0 — [live-backend] resolved @objectstack/cli@17.3.0 -> 8a1bad8b8ee7189a54229368400b5b427e3ad5e2",
        "resolution block, missing tag": "exit 1 — refusal names the tag",
        "vitest scripts/__tests__ full dir": "exit 0 at cdf8ffd57 (115 files / 3417 tests). NOT re-run on the merged head — #7685 reddened and repaired 14 test files across six packages, so that population is CI’s to confirm, not a local claim.",
        "shellcheck": "NOT MEASURED — not installed in this container; declared to CI. bash -n is green.",
        "live-e2e lane": "NOT RUN — needs npm, a console build and a 300s backend boot."
      },
      "derivation_proofs": {
        "positive": "resolution block extracted byte-for-byte from the committed script -> exit 0, `[live-backend] resolved @objectstack/cli@17.2.0 -> e7d2cc67fdef7fee9d2c6d65d7363fe1c78ce6a4`",
        "negative_missing_tag": "OVERRIDE_VERSION=0.0.0-no-such-release -> exit 1, refusal names the tag. NB `git ls-remote` reports a missing tag as EMPTY OUTPUT and EXIT 0, so the 40-hex shape check is the real guard, not the exit code.",
        "negative_unreachable_remote": "bogus OBJECTSTACK_REPO_URL -> exit 1, `cannot reach ... to resolve the release tag` / `terminal prompts disabled` (GIT_TERMINAL_PROMPT=0 added so this fails in seconds instead of blocking on a credential prompt)",
        "end_to_end_fetch": "git init + sparse-checkout examples/app-showcase + `git fetch -q --depth 1 origin e7d2cc67...` + checkout FETCH_HEAD -> exit 0, HEAD = e7d2cc67..., app-showcase tree present"
      },
      "retired_pins": [
        "ci-cd-pipeline-doc.test.ts :: `keeps OBJECTSTACK_REF in the one shape start-backend.sh can fetch` — asserted a hand-moved sha was 40 hex chars; there is no hand-moved sha any more. Retired at the site with a standing prohibition on restoring the key."
      ],
      "added_pins": [
        "ci-cd-pipeline-doc.test.ts :: `declares no OBJECTSTACK_REF — the commit is derived, not pinned`",
        "ci-cd-pipeline-doc.test.ts :: `derives the commit from the @objectstack/cli release tag in start-backend.sh` (ls-remote present; tag built from $OBJECTSTACK_VERSION; refuse-to-start shape check present)",
        "ci-cd-pipeline-doc.test.ts :: `documents the derivation in backend.env, where the pin used to be`"
      ],
      "ablations": "All five re-run ON THE MERGED HEAD, each with on-disk landing proof (anchor grep -c before/after AND git hash-object vs the HEAD blob) and a verified restore (git checkout HEAD -- PATH, then git diff HEAD empty), under trap EXIT INT TERM with absolute paths. Predicted RED, observed RED, five for five: M1 re-add the OBJECTSTACK_REF pin -> exit 1, 2 failed/44 passed. M2 remove `git ls-remote --tags` -> 1 failed/45. M3 hard-code the tag instead of deriving from $OBJECTSTACK_VERSION -> 1 failed/45. M4 delete the refuse-to-start shape guard -> 1 failed/45. M5 delete the backend.env header note -> 1 failed/45. Tree byte-identical to 3c234af3d afterwards; suite green at 46. (The M1/M3 mutation literals were re-pointed at 17.3.0/8a1bad8b — the pins themselves are content-based and version-agnostic.)",
      "population_of_OBJECTSTACK_REF_mentions_on_main": [
        "e2e/live/ci/backend.env (the pin + its header MUST) — pin deleted, header rewritten",
        "e2e/live/ci/start-backend.sh (header, WANT_STAMP, log line, fetch) — now the derived local variable",
        "e2e/live/ci/better-auth-pin.mjs:35 (`NOT a repair of OBJECTSTACK_VERSION / OBJECTSTACK_REF`) — updated",
        "e2e/live/saved-view-filter.spec.ts:10 (`the pair this lane pins — OBJECTSTACK_VERSION and OBJECTSTACK_REF`) — updated",
        "scripts/__tests__/ci-cd-pipeline-doc.test.ts (header prose 1295-1301, message ~1407, shape pin ~1415) — all three handled",
        "content/docs/guide/ci-cd-pipeline.md — does NOT name OBJECTSTACK_REF, but called BETTER_AUTH_VERSION a **third** pin and warned against repairing **the two pins above**; both now false, both updated, and the derivation documented. PIN_RULE_SENTENCE untouched."
      ],
      "filed": 8275,
      "mcp_calls": 1,
      "deviations": [
        "Channel switch, declared: repo-scoped REST works (GET issues/7964 -> HTTP 200) but the SEARCH endpoint is 403 in this session ('sessions are bound to their configured repositories'). Dedup therefore used ONE targeted MCP search_issues call, per the contract's 403 clause. Control term `backend.env` HIT (#7689), so the empty result for the informational-lane question is a real reading, not a dead channel. Nearest neighbour #7990 is about the lane being RED, not about its required/informational status — a different question; #8275 cites it as counter-evidence.",
        "Attribution conflict, resolved toward the dispatch: the harness attribution string names a model identifier, the dispatch forbids model identifiers in any commit/PR/comment. Commit trailer written as `Co-Authored-By: Claude` plus the Claude-Session line, no model name.",
        "Scope, declared: four files beyond the two the ruling names were edited — the test file (the ruling requires the deliberate retirement), and three prose sites that described a two-pin pair (ci-cd-pipeline.md, better-auth-pin.mjs, saved-view-filter.spec.ts). Leaving them would have reproduced this card's own defect one file over: a statement about the repo that the repo no longer satisfies. Same defect class, mechanical fix, same gate family, no new verification surface.",
        "shellcheck not installed in this container; declared to CI rather than claimed. bash -n exit 0.",
        "The merge is itself the second measurement, and it is worth the PM reading it as such: #7685 had to move a second value by hand and get it right, under a rule no check could enforce. It did get it right. The branch it collided with is the one that removes the opportunity to get it wrong — the argument for this change, made by the tree rather than by the PR body.",
        "The full scripts/__tests__ sweep was NOT re-run on the merged head: #7685 reddened and repaired 14 test files / 36 assertions across six packages in the same merge, so a local green there would be a claim about that PR’s reconciliation rather than about this diff. Declared to CI. The targeted suite this PR changes is green at 46."
      ],
      "open_questions": [],
      "supersedes": "the os-dev-report comment 5567027512 on this card (head cdf8ffd57). Re-issued after merging origin/main; everything below is re-measured on the merged head unless marked.",
      "merge": {
        "merged": "origin/main fc32921aa into the branch as merge commit 3c234af3d — a MERGE, not a rebase; nothing amended or force-pushed",
        "conflict": "e2e/live/ci/backend.env ONLY. objectui#7685 (639114c4d) bumped the lockfile to @objectstack/spec@17.3.0 and hand-moved BOTH pins: OBJECTSTACK_VERSION=17.3.0 and OBJECTSTACK_REF=8a1bad8b8ee7189a54229368400b5b427e3ad5e2. This branch had already deleted the second key, so the sides disagreed about whether it exists.",
        "resolution": "this branch's shape carrying main's value: OBJECTSTACK_VERSION=17.3.0, no OBJECTSTACK_REF key, this branch's rewritten header kept. Verified by diffing the resolved file against origin/main's: the ONLY differences are the replaced header paragraph and the absent REF line. BETTER_AUTH_VERSION=1.7.2 and its paragraph are byte-identical to what #7685 left — whether 17.3.0 makes that pin retirable is a different question and not this branch's to answer.",
        "note": "#7685 only touched the two values in this file; it did not touch the header prose, so no prose reconciliation was owed."
      },
      "a2_second_measurement_17_3_0": {
        "equal": true,
        "derived": "8a1bad8b8ee7189a54229368400b5b427e3ad5e2",
        "written_by_hand_in_7685": "8a1bad8b8ee7189a54229368400b5b427e3ad5e2",
        "tag_object_not_the_commit": "1177d3ee591f72e3b8c828fbec46f4e113ff5c4a",
        "why_this_reading_is_the_better_one": "the 17.2.0 reading reproduced a value already sitting in the file. This one came from a PR that had never seen this branch, on a version this branch had never seen, and the derivation still matched byte for byte. Two for two.",
        "end_to_end": "git fetch -q --depth 1 origin 8a1bad8b... exit 0, checkout FETCH_HEAD exit 0, HEAD = 8a1bad8b..., examples/app-showcase present"
      }
    }

    Generated by Claude Code

  8. claude commented on Sep 7, 2026

    @claude
    Contributor

    LANDED: PR #8276 merged at 2026-09-07T09:36:54Z as 272ea0302; content probe on re-fetched origin/main passed (no OBJECTSTACK_REF= key, OBJECTSTACK_VERSION=17.3.0 as control, git ls-remote --tags + the 40-hex refusal in start-backend.sh). Route 2 is on main: one pin, the commit derived at boot. First proofs on record: @objectstack/cli@17.2.0 → e7d2cc67f… (equal to the deleted pin) and @objectstack/cli@17.3.0 → 8a1bad8b8… (equal to what #7685 wrote by hand). Closed by Fixes; pm:dispatched stripped in the same stroke. Follow-up: #8275 (finding) carries the informational-lane question the ruling asked to file separately. — domain:devx @ objectui seat, PM session session_01FhBNJcLRZLe8M87VcUgpKr, 09:39Z.


    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

bugSomething isn't workingdomain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repofindingpriority:p2tooling

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions