Skip to content

fix(devx): prune stale objectui worktree registrations before build-console.sh adds one (#14177) - #14417

Merged
baozhoutao merged 1 commit into
mainfrom
claude/issue-14177-build-console-worktree-prune
Sep 2, 2026
Merged

fix(devx): prune stale objectui worktree registrations before build-console.sh adds one (#14177)#14417
baozhoutao merged 1 commit into
mainfrom
claude/issue-14177-build-console-worktree-prune

Conversation

@claude

@claude claude Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Fixes #14177

What

scripts/build-console.sh resolution mode 2 (sibling ../objectui checkout)
creates a git worktree under this repo's .cache/, registered in the
shared objectui/.git. The documented cleanup (rm -rf on the framework
worktree, or the script's own worktree remove --force || rm -rf fallback at
:85) deletes that directory without ever telling objectui, so the
registration survives as prunable. The next worktree add at the same path
then dies with fatal: ... is a missing but already registered worktree,
exit 128 — which reads like a lock or git fault, not a leftover of a previous
run's cleanup.

Fix

Run git -C "$SOURCE_ROOT" worktree prune immediately before the
worktree add at (former) :89, inside the if [[ ! -d "$BUILD_ROOT" ]]
branch — the only path in the script that reaches worktree add in
resolution mode 2, whether the directory is missing because a previous run
never created it or because the force-remove-or-rm -rf fallback above just
stranded it. prune only drops registrations whose directory is already
gone, so it is safe by construction.

Option 2 (an exit trap removing the script's own worktree) is
deliberately not taken: the script reuses BUILD_ROOT across runs when
the pinned SHA already matches (:82-87) — that's what backs the
console-dist CI cache keyed in .github/workflows/ci.yml:1827. A trap that
removed the worktree on every exit would defeat that reuse unconditionally,
which is a bigger behavior change than "one line" for a plain win. Route 1
alone repairs the state regardless of which run stranded it, matching the
ruling's rationale.

Fixture proof (before / after)

Real sibling objectui checkout not required to prove this — the defect and
fix are pure git worktree mechanics. Reproduced with a throwaway fixture
repo (not the real objectui):

$ git init -q source && cd source && git commit -q -m init   # SHA=97b070f...

=== BEFORE (no prune) — reproduce the strand ===
$ git -C source worktree add --detach build-root <SHA>
Preparing worktree (detached HEAD 97b070f)
HEAD is now at 97b070f init

$ rm -rf build-root   # simulate documented cleanup / the script's own rm -rf fallback

$ git -C source worktree list
.../source      97b070f [master]
.../build-root  97b070f (detached HEAD) prunable      # <- registration survives

$ git -C source worktree add --detach build-root <SHA>   # second add, no prune
Preparing worktree (detached HEAD 97b070f)
fatal: '.../build-root' is a missing but already registered worktree;
use 'add -f' to override, or 'prune' or 'remove' to clear
EXIT_WITHOUT_PRUNE=128

=== AFTER (with prune, matching the fixed script's sequence) ===
$ git -C source worktree list
.../source      97b070f [master]
.../build-root  97b070f (detached HEAD) prunable

$ git -C source worktree prune

$ git -C source worktree list
.../source  97b070f [master]                          # <- stale registration gone

$ git -C source worktree add --detach build-root <SHA>
Preparing worktree (detached HEAD 97b070f)
HEAD is now at 97b070f init
EXIT_WITH_PRUNE=0

Exit 128 without the fix, exit 0 with it, on the exact worktree add
invocation the script uses.

Syntax / lint

  • bash -n scripts/build-console.sh — OK.
  • shellcheck — not installed in this environment (no system binary, pnpm exec shellcheck reports Command "shellcheck" not found); not run.

Gates

node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands at head 98b80532 (merge-base 79b6a22a5 of origin/main) names
14 families for scripts/build-console.sh — all RAN, all PASS:

Gate Result
node scripts/check-ci-filter-parity.mjs PASS
node scripts/check-cross-package-test-inputs.mjs PASS
node scripts/check-shard-attestation.mjs PASS
node scripts/check-test-completeness.mjs NOT MEASURED (exit 3 — needs a saved turbo run test log; no PREREQUISITE NOT MET)
pnpm check:agent-test-spelling PASS
pnpm check:bash32-floor PASS
pnpm check:cli-command-ids PASS
pnpm check:console-injection PASS (no local console dist; check no-ops by its own design)
pnpm check:console-sha PASS (same)
pnpm check:cross-package-test-inputs PASS
pnpm check:entry-guard PASS
pnpm check:parse-guard PASS
pnpm check:pnpm-filter-targets PASS
pnpm check:watch-hint-literal PASS

Always-run for scripts/** dispatches (per dispatch order):

Gate Result
pnpm check:ratchet-remedy-authority PASS
pnpm check:declared-population-live PASS

check:pm-dispatch-gates (~11.5 min): not in the derived 14-family list for
this file surface — not run.

Changeset

Scripts-only change, no package surface (scripts/build-console.sh is not
inside any published package's files). Following the precedent for the
same class of change (#14178 / PR #14391, and 0079e2585): no
.changeset/*.md added, skip-changeset label applied.


Generated by Claude Code

…onsole.sh adds one (#14177)

Resolution mode 2 (sibling `../objectui` checkout) creates a git worktree
under this repo's `.cache/`, registered in the SHARED objectui/.git. The
documented cleanup (`rm -rf` on the framework worktree, or the script's own
`worktree remove --force || rm -rf` fallback) deletes that directory without
ever telling objectui, so the registration survives as `prunable`. The next
`worktree add` at the same path then dies with exit 128 "already registered
worktree" -- which reads like a lock or git fault, not a leftover.

Run `git -C SOURCE_ROOT worktree prune` immediately before the `worktree add`
that would trip over a stranded registration. Safe by construction: prune
only drops registrations whose directory is already gone.

Option 2 (an exit trap removing the script's own worktree) is skipped: the
script deliberately reuses BUILD_ROOT across runs when the pin already
matches (for the CI console-dist cache), and a trap firing on every exit
would remove it unconditionally and defeat that reuse.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

build-console.sh strands a git worktree registration in the shared objectui checkout, and the next build dies on already registered

2 participants