Skip to content

fix(release): the console injection assertion has a real witness on a .objectstack-sha pin, instead of passing vacuously #24510

Closed

Description

@objectstack-fleet

Filed by the epic seat (epic:#15194, session_01Y5583bs2RDd53MH6kM1ca3) from the F1 rerun, os-dev-report 6263864885 on #15194, open question 1, answer B. ⛔ Not an 18.0 gate: the seat accepted A for the 18.0 cut, in its ACCEPT on #15194.

Problem. From console pin 4016370af3c9 on, objectui consumes @objectstack/* by commit through .objectstack-sha (objectstack-ai/objectui#12957). On that branch, scripts/build-console.sh packs THIS tree into objectui's install, so assert-console-spec-injection.mjs is called with --vendored equal to --injected.

  • It prints "no observable skew, so nothing for this check to assert".
  • The stamp records skew false with null witnesses.
  • release.yml's check:console-injection --require-stamp then passes on "Nothing assertable".
  • The import/jobs bundle canary is present in a non-injected bundle too, so it no longer discriminates either.

Today the bundle is correct. The rerun proved it by hand, against the spec at objectui's own .objectstack-sha 2c9bf9430a11: 16 of 16 injected-only descriptions present, 0 of 2 published-only. But a regression in the pack-or-inject step would now pass both release checks silently.

Wanted. On a .objectstack-sha pin, the assertion takes its witness from the spec at objectui's .objectstack-sha, or from another real reference that differs from this tree, so that the stamp carries a non-null witness. A bundle that does not carry this tree's spec fails both release paths again.

Refs: os-dev-reports 6262553400 and 6263864885 on #15194; 6111383302 on #15204; scripts/build-console.sh (the .objectstack-sha branch, about line 341); scripts/assert-console-spec-injection.mjs; scripts/check-console-injection.mjs.

Activity

  1. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 4 · on the maintainer's 「这个需要处理。」 in this session's chat (the card had no pm:queue yet; the maintainer's order is the queueing)
    Session: session_01FM29ZqLTrnPNXxijioZwMp
    Account: os-warren (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-24510-console-injection-real-witness
    Worktree: objectstack-issue-24510
    Domain: domain:devx
    Seat: domain:devx#1
    File surface: scripts/assert-console-spec-injection.mjs, scripts/console-spec-probes.mjs, scripts/check-console-injection.mjs with their tests, and the .objectstack-sha branch of scripts/build-console.sh (about :341–:520) (stop on breach; explain in the report). .github/workflows/release.yml only if its check:console-injection --require-stamp call must change, which makes the PR Tier H.
    Container & model: M (a release-path assertion that needs a second real reference spec), mode:subagent, model: TIER_DEFAULT (dispatch-gates --tier: "no path-derived mandate")
    Clause-②: no
    Responsibility: scripts/build-console.sh's .objectstack-sha branch hands assert-console-spec-injection.mjs the same spec as --vendored and --injected | none: this assertion and its stamp replay are the only check that a released console bundle carries this tree's @objectstack/spec | every release built on a .objectstack-sha console pin (the pin has been objectui 4016370af3 since #24476): a regression in the pack-or-inject step would ship silently
    Thread-read: none
    Serial constraints cleared: none — no open PR touches scripts/build-console.sh, scripts/assert-console-spec-injection.mjs, scripts/check-console-injection.mjs, scripts/console-spec-probes.mjs, .objectui-sha or .github/workflows/release.yml (read at 2026-10-19T10:49Z). Today's changes on those paths, 2be3d7a5e (#24440) and 3b086e76f (#24476), have landed.


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    Posted 2026-10-19T12:45Z · issue #24510 · os-dev subagent of the domain:devx seat 1 PM (session_01FM29ZqLTrnPNXxijioZwMp) · draft PR #24532

    {
     "issue": 24510,
     "status": "done",
     "branch": "claude/issue-24510-console-injection-real-witness",
     "pr": "https://github.com/objectstack-ai/objectstack/pull/24532",
     "session": "session_01FM29ZqLTrnPNXxijioZwMp — mode:subagent, so this is the parent PM seat's id, the one in the claim and the commit trailers",
     "premise_still_valid": true,
     "summary": "On a .objectstack-sha console pin, scripts/build-console.sh now builds objectui's own @objectstack/* at its .objectstack-sha first, by objectui's own recipe (scripts/objectstack-pin.mjs build with OBJECTSTACK_ROOT and OS_SKIP_DTS unset). It keeps that cache, the pin stamp included, at node_modules/.cache/objectstack-pin-reference, outside the cache the OBJECTSTACK_ROOT stand-in replaces, and passes its spec as --vendored. A rerun reuses it while its stamp names the pin. assert-console-spec-injection.mjs now refuses, as cannot-judge (exit 2), any other reference on such a pin: the stand-in, the install's copy, or a build of another commit. The stamp records vendoredFrom and vendoredPin, and the verdict text names the pinned reference. check-console-injection.mjs names it in the replay too, and gains self-test battery 15. The existing branch test packages/spec/scripts/build-console-objectstack-root.test.ts was updated, because it pins this exact branch. On a real build at .objectui-sha 4016370af3c9 (objectui .objectstack-sha 2c9bf9430a11), the stamp went from skew false with null witnesses to skew true with a real witness and detector. A bundle carrying the pin's own spec now fails both release paths: build exit 1, replay exit 1. The old code passed both: exit 0 and 0. release.yml is untouched.",
     "files_changed": [
      "scripts/build-console.sh",
      "scripts/assert-console-spec-injection.mjs",
      "scripts/check-console-injection.mjs",
      "packages/spec/scripts/build-console-objectstack-root.test.ts"
     ],
     "line_budget": "227 changed lines (204 added, 23 removed) against a budget of about 200. The three planned scripts are 191. The other 36 are the existing branch test, which pins the .objectstack-sha branch and failed 2 of 5 until it was updated. Over budget by 27, reported as a deviation.",
     "stamp_before": "BASE a5a781bc7, real bash scripts/build-console.sh under os-verify-lock (VERDICT command-exit 0, held 862s), .objectui-sha 4016370af3c9: skew false, freshWitness null, staleDetector null. The assertion printed 'Injected and vendored @objectstack/spec declare the same descriptions — no observable skew'. check-console-injection --require-stamp exit 0: 'Nothing assertable in this stamp; the dist was not contradicted.'",
     "stamp_after": "Branch 91dc1bab6, same real build (VERDICT command-exit 0, held 672s): skew true; freshWitness 'Error code the write was refused or failed with, as the single-record write door answers it'; staleDetector 'Binds the element to one same-origin API endpoint instead of an object'; vendoredPin 2c9bf9430a1198bfaa5c0de9ff4a811838c6869c; vendoredFrom .cache/objectui-4016370af3c9/node_modules/.cache/objectstack-pin-reference/spec. 16 of 16 injected-only descriptions present, all 2 pin-only absent. check-console-injection --require-stamp exit 0: 'the dist carries this tree's copy'. The reference build's own step times: fetch 14.8s, install 5.0s, build 7 packages 144.7s, pack 16.5s, about 181s in all. A rerun reused it (0 'Building objectui's own' lines, against 1 on the first run).",
     "red_green": "Hypothesis 5. RED through the real build path: a scratch build-console.sh run at 91dc1bab6 with OBJECTUI_DEPS_BUILD_CMD putting objectui's own pin build back into its install after the stand-in, and OBJECTUI_BUILD_CMD dropping OBJECTSTACK_SPEC_DIST and OBJECTSTACK_CLIENT_DIST, so pack and inject are both broken. VERDICT command-exit 1 at the assertion: 'Built console still carries the ... objectui's own build of objectstack 2c9bf9430a11 ... Binds the element to one same-origin API endpoint instead of an object'. The import/jobs canary passed on that bundle. Then, at the final head 14d4124e8, on the saved bundles (assertion blob 26acfe988c3b, BASE blob 4fd59042a9eb): new assertion against the pin reference: real bundle 0, pin bundle 1. BASE assertion with BASE's wiring (the stand-in spec): real bundle 0, pin bundle 0 (the vacuity). New assertion given the stand-in: 2 (refused). Replay of the new stamp: pin bundle 1, real bundle 0. Replay of the BASE stamp on the pin bundle: 0 (the vacuity). Two earlier sabotage attempts were not measurements and are not counted. Aiming OBJECTSTACK_SPEC_DIST at the bare reference failed in vite's dependency check. Aiming it at a resolvable copy while the install stayed this tree failed in rolldown with MISSING_EXPORT virtualFieldAggregateRemedy, because this tree's @objectstack/lint needs it. Neither produced a bundle.",
     "tests": "All at HEAD 14d4124e8 unless named. node scripts/check-console-injection.mjs --self-test: exit 0, '84 assertions over real fixture trees'. Ablation in a scratch tree (the worktree was never mutated): BASE's assert script swapped in, its blob verified equal to the BASE blob, self-test exit 1 with 10 failures, among them 'the stand-in (this tree, packed) as the reference is refused as cannot-judge: expected 2, got 0'; restored, blob equal to HEAD, exit 0. pnpm --filter @objectstack/spec exec vitest run --project repo --maxWorkers=2 scripts/build-console-objectstack-root.test.ts: 6 of 6 pass. The same command at 24e7c5cab, before the test update, failed 2 of 5. Ablation through scripts/ablation-replace.mjs: the guard 'if [[ \"$REFERENCE_SHA\" != \"$OBJECTSTACK_PIN_SHA\" ]]; then' was replaced by 'if false; then' (anchor 1 to 0, blob 158773d617c3 to 1abd02a02cf3), 3 of 6 failed; restore proven (blob equal to HEAD, git diff HEAD empty); re-run 6 of 6. pnpm --filter @objectstack/spec typecheck: VERDICT command-exit 0. tsc --noEmit -p tsconfig.scripts.json --listFiles: exit 0, and the edited test is in the program (1 hit). Every heavy step ran through scripts/pm/os-verify-lock.sh with OS_VERIFY_LOCK_SLOT=issue-24510.",
     "gates": "Local union at 14d4124e8: node scripts/pm/dispatch-gates.mjs --commands derived 86 families, all run with exit codes captured before any pipe. 84 exited 0 on the first pass. 2 exited 3, PREREQUISITE NOT MET: check-plugin-teardown-shape --self-test (a shallow clone), exit 0 after git fetch --unshallow origin main; and check:dual-build-cjs-loads (dists missing), exit 0 after turbo run build --filter=!@objectstack/docs --concurrency=2 (76 of 76, 75 cached, VERDICT 0). dispatch-gates --ran: exit 0, '86 derived, 86 run, 0 NOT-MEASURED, 0 UNRUN'. check:console-injection exit 0 and check:console-sha exit 0 on the real dist. check:pm-dispatch-gates: EXIT=0, 1913 cases, fast tier. CI at report time, PR head 14d4124e8, 42 check-runs: completed success are Auto Label, Check PR Size, Check Changeset, filter, Check Documentation Links, Dogfood Regression Gate, the card-claims-this-branch check, both no-other-open-PR checks, and the Part-of check. Still in_progress: Test Core 1-6/6, Build Core, every Lint and Type Check lane, Governed Surface Queue Guard, Spec property liveness, Flag docs affected. Console Pin Gate is skipped on PRs (full battery only), so CI first runs the new build-console.sh path on main's push after the merge; the local real builds above are this PR's evidence for that path. NOT MEASURED: check-platform-checklist --changed-from (no exported symbol was renamed or removed).",
     "deviations": [
      "Line budget: 227 changed lines against about 200. The extra 36 are the existing branch test, which this diff could not leave red.",
      "build-console.sh ran in its mode 2, a git worktree of the shared /home/user/objectui at the pin under .cache/, because ../objectui exists beside the worktree. That registered and later removed a worktree in /home/user/objectui/.git (git worktree remove, without --force, exit 0). objectui's checkout and HEAD were not touched.",
      "Ran git fetch --unshallow origin main in the shared objectstack clone, as the teardown-shape gate's refusal prescribes. The shallow file is gone for every worktree of this clone.",
      "Stopped my own superseded gate-union run (it was at 24e7c5cab, before the test commit) with kill -TERM on its recorded process group 6818, and confirmed the group was empty. No other process was touched.",
      "The second union runner's pid was looked up once with pgrep -f right after I started it, and confirmed by ps (pid 22124, the runner script). It was only waited on, never killed.",
      "Commit trailers use AGENTS.md's model-free pair (Claude-Session plus Co-authored-by: Claude), not the harness reminder's model-named Co-Authored-By line. The pre-push hook would refuse the latter.",
      "Declared local narrowing: the spec package's local vitest project (no file it reads changed) and the rest of test:repo are CI's. Only the edited repo-project test file ran locally.",
      "The relay's read-back line named the assignee (os-warren) but printed no label line. The label was confirmed by a REST read of the pull: labels [skip-changeset], draft true, assignee os-warren, author objectstack-fleet[bot].",
      "The PR body was posted once at create and read back equal to what was sent (13607 bytes), with no PATCH. Its 'Tests and gates' section carries the union result."
     ],
     "mcp_calls": "0 — no MCP GitHub call of any kind",
     "api_writes": "2 REST writes through the fleet relay, plus git pushes. (1) One pr_create stroke, relay run 39254161875, conclusion success: POST /repos/objectstack-ai/objectstack/pulls (draft), POST /repos/objectstack-ai/objectstack/issues/24532/assignees, POST /repos/objectstack-ai/objectstack/issues/24532/labels. (2) This os-dev-report comment, POST /repos/objectstack-ai/objectstack/issues/24510/comments, through scripts/pm/post-stamped.mjs. The 5 git pushes of the branch (the empty probe plus 4 commits) are not REST. Reads: gh api GETs (session token) of the card, its comments, the three cited reports, and the pull and its check-runs.",
     "open_questions": [],
     "out_of_scope_findings": [
      "carrier: none (承接者:无) · noted, not filed: the import/jobs client canary in build-console.sh does not discriminate on a .objectstack-sha pin. It passed on the pin-native red bundle too (measured here, and in 6263864885). The two trees' client differs only in a type and comments, so a client witness would have nothing to tell apart today. The reference cache this PR keeps also holds the pin's own @objectstack/client, which is where a derived client witness would come from. No filing class applies: an observation with zero pull.",
      "carrier: none · noted, not filed: the replay's pass line still reads 'not the published one' on a pinned stamp. That is wording polish.",
      "carrier: none · noted, not filed: every console build that misses its dist cache on a .objectstack-sha pin now pays the reference build, about 181s on this shared box. Both workflows hash scripts/build-console.sh into their dist key, so every old vacuous-stamp entry stops being restored, and the first run of each workflow after the merge rebuilds cold. This is a cost note, not a defect."
     ]
    }

    Generated by Claude Code

  3. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:devx seat 1 · session_01FM29ZqLTrnPNXxijioZwMp · 2026-10-19T13:53Z

    reading result
    merge queue (gh-readonly-queue/main/pr-24532-* heads) none left: the entry has drained
    PR object PR #24532 merged at 2026-10-19T13:53:23Z (not governed; landed by this seat on its ACCEPT 6268156004)
    origin/main at ba4afcc239, by content scripts/build-console.sh:400 keeps the pin reference at node_modules/.cache/objectstack-pin-reference, and :411 passes its spec as --vendored; scripts/assert-console-spec-injection.mjs:151 reads the pinned reference and names it by objectui's own build of the pin

    State change: PR #24532 closed this card through Fixes #24510 (completed); pm:dispatched comes off in this act.

    Carried onward (owed by this seat): Console Pin Gate is the first CI run of the new .objectstack-sha path, because it is skipped on PRs. The reading is main's push CI run 39264027017 on ba4afcc239. Its verdict, and the stamp's skew and witnesses where the log shows them, are recorded here when it completes.


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    Stay-behind reading: Console Pin Gate on main, green · domain:devx seat 1 · session_01FM29ZqLTrnPNXxijioZwMp · 2026-10-19T14:47Z

    reading result
    run ci.yml push run 39264027017 on ba4afcc239 (PR #24532's merge), conclusion success
    job Console Pin Gate (118099006889), success. Every step succeeded: build at the pinned objectui, assert a real dist, stamp matches the pin, restored dist bundles this tree's spec, save
    dist cache CACHE_HIT empty, so the console was built by scripts/build-console.sh (not restored); the new key Linux-console-dist-5374…02ea was saved
    build-time assertion ✓ Console bundle carries THIS tree's @objectstack/spec, and only it (vendored: @objectstack/spec of objectui's own build of objectstack 2c9bf9430a11). 16 of 16 injected-only descriptions present, all 2 pin-only descriptions absent
    replay (check:console-injection --require-stamp) ✓ @objectstack/spec: the dist carries this tree's copy, and not the published one., naming the same witness and detector, after --self-test's 84 assertions

    The new .objectstack-sha path ran on CI for the first time, with a real reference and real witnesses, not the vacuous "no observable skew" pass. The card stays closed completed, and nothing is carried. The one-shot trig_01MHya4mEcMs6wnEhZtWLrwQ has fired.


    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

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions