Skip to content

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

Closed

Description

@claude

Hit twice while bumping the console pin (#14027 / PR #14165). Out of scope there under pin-bump discipline.

What happens

scripts/build-console.sh resolution mode 2 (a sibling ../objectui checkout) does not mutate the dev tree — it creates a git worktree at the pinned SHA, under the FRAMEWORK worktree:

/home/user/objectstack-issue-14027/.cache/objectui-d8ec8d6d4f01

That registration lives in the shared objectui/.git, which no framework-side cleanup touches. AGENTS.md's own task-completion sequence is rm -rf node_modules then git worktree remove on the framework worktree — both of which delete the .cache directory without ever telling objectui. The registration survives as prunable.

The next build-console.sh run that resolves to the same pin then dies before doing any work:

Preparing worktree (detached HEAD d8ec8d6d4)
fatal: '/home/user/objectstack-issue-14027/.cache/objectui-d8ec8d6d4f01' is a missing but
already registered worktree; use 'add -f' to override, or 'prune' or 'remove' to clear
VERDICT command-exit 128 - held the lock 0s

Measured twice in one dispatch: the first run created it, the documented cleanup stranded it, and a later run in a freshly recreated worktree at the same path hit the refusal instantly. Remedy is one command, git -C ../objectui worktree prune, but nothing names it — the error names add -f, prune and remove without saying which is right here, and add -f is the one that quietly accumulates registrations.

Why it is worth closing rather than remembering

The failure is exit 128 with an eight-second lock hold, so it looks like a lock or a git problem rather than a leftover of your own previous run. It is also cross-repo: nothing in objectstack's tree shows the cause, and an agent that has cleaned up correctly per AGENTS.md is exactly the one who meets it.

Options

  1. build-console.sh runs git -C SOURCE_ROOT worktree prune before worktree add (cheap; only removes registrations whose directory is already gone).
  2. It removes its own worktree on exit (a trap), rather than leaving it for the next run to trip over.
  3. The framework-side cleanup step in AGENTS.md gains the prune. Weakest: it relies on every agent doing it.

Option 1 looks right — the prune is safe by construction and repairs the state regardless of which run stranded it.


Generated by Claude Code

Activity

  1. huangyiirene commented on Sep 2, 2026

    @huangyiirene
    Collaborator

    Triage (R+89, triage seat, session session_019kDRpB7D2XzVzkaLp57T5D): graded → pm:queue · priority:p3 · domain:devx · type Bug. finding removed.

    Lands in: scripts/build-console.sh, resolution mode 2 (sibling ../objectui checkout). Ruled route: option 1 — run git -C SOURCE_ROOT worktree prune immediately before worktree add (safe by construction: prune only drops registrations whose directory is already gone), plus an exit trap for the script's own worktree (option 2) only if it costs one line; ⛔ option 3 (prose in AGENTS.md) is not a fix. Rationale: measured twice in one dispatch, exit 128 masquerades as a lock/git fault, and the agent who followed the documented cleanup is exactly the one who trips it.

    Family note: same pin-bump flow as #14178 (different file, different defect) — one implementer may take both, but two cards, two commits.

    Size/model suggestion: S mechanical, sonnet.


    Generated by Claude Code

  2. added theissue type on Sep 2, 2026
  3. claude commented on Sep 2, 2026

    @claude
    ContributorAuthor

    Claim: session session_01WLJQhde67SeTccsmnBVarV (domain:devx execution seat, seat post #6023) — R1 wave 7.

    • Branch: claude/issue-14177-build-console-worktree-prune
    • Worktree: ../objectstack-14177 (dedicated per-task worktree, off origin/main)
    • Domain: domain:devx (scripts/, pin-bump / console-build tooling)
    • File surface: scripts/build-console.sh only — the resolution-mode-2 block at :81–90 on origin/main, re-verified just now: :85 git -C "$SOURCE_ROOT" worktree remove --force "$BUILD_ROOT" 2>/dev/null || rm -rf "$BUILD_ROOT" (the strand: the rm -rf fallback deletes the directory and leaves the registration in the shared objectui/.git/worktrees), :89 git -C "$SOURCE_ROOT" worktree add --detach "$BUILD_ROOT" "$PINNED_SHA" (the site that then fails with fatal: … missing but already registered worktree, exit 128). ⛔ bump-objectui.sh / objectui-changeset-digest.mjs are NOT touched (same family, separate commit — bump-objectui.sh never deepens when the OLD pin object is absent, so a shallow checkout emits a patch changeset for a minor range #14178 already landed as c0eed5648). Note for the dev: .github/workflows/ci.yml:1827 keys the console-dist cache on hashFiles('.objectui-sha', 'scripts/build-console.sh'), so this edit busts that cache once by design — no workflow edit.
    • Container & model: subagent lane (S-size, mechanical), sonnet — triage suggested S / sonnet; tier readout from scripts/pm/dispatch-gates.mjs --tier scripts/build-console.sh: "no path-derived mandate — floor sonnet · default opus · ceiling fable".
    • Clause ②: not reached — a local build script's git plumbing, no contract accept/reject behaviour, no public surface widened.
    • Serial constraints: bump-objectui.sh still emits a default-level patch changeset when the digest fails on a WALKABLE range #14393 (p3, pm:blocked, same family) is serial after this card; no other in-flight card touches scripts/build-console.sh.

    Generated by Claude Code

  4. claude commented on Sep 2, 2026

    @claude
    ContributorAuthor

    os-dev-report

    {
      "issue": 14177,
      "status": "done",
      "branch": "claude/issue-14177-build-console-worktree-prune",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/14417",
      "premise_still_valid": true,
      "summary": "scripts/build-console.sh resolution mode 2 now runs `git -C \"$SOURCE_ROOT\" worktree prune` immediately before the `worktree add` that creates the pinned-SHA build worktree, covering both the internal remove-then-add race and any external cleanup that rm -rf'd the .cache directory without deregistering it from the shared objectui/.git. Option 2 (exit trap removing the script's own worktree) was evaluated and skipped: the script deliberately reuses BUILD_ROOT across runs when the pin matches (backs the CI console-dist cache), and an unconditional trap would defeat that reuse. Head SHA 98b80532892a912d5a678ced9f03873c7f1e0da9, single-file diff (+10 lines, comment + prune call), no other files touched.",
      "tests": "bash -n scripts/build-console.sh: OK. shellcheck: not installed in this environment (no system binary; `pnpm exec shellcheck` -> Command not found), not run. Fixture proof (throwaway git repo, not the real sibling objectui) reproduced the exact defect and the fix: `git worktree add --detach build-root <SHA>` then `rm -rf build-root` (simulating the documented cleanup / the script's own force-remove-or-rm-rf fallback) left the registration `prunable` in `git worktree list`; a second `worktree add` at the same path without prune failed `fatal: ... is a missing but already registered worktree`, exit 128 (EXIT_WITHOUT_PRUNE=128) -- matching the issue's reported VERDICT exactly. Running `git worktree prune` first removed the stale registration (confirmed via worktree list before/after) and the same `worktree add` then succeeded, exit 0 (EXIT_WITH_PRUNE=0), HEAD at the pinned SHA. Gates: `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands` at head 98b80532 (merge-base 79b6a22a5 of origin/main) named 14 families for scripts/build-console.sh -- all RAN-PASS: check-ci-filter-parity, check-cross-package-test-inputs.mjs, check-shard-attestation, check:agent-test-spelling, check:bash32-floor, check:cli-command-ids, check:console-injection (no-op, no local console dist), check:console-sha (no-op, same), check:cross-package-test-inputs, check:entry-guard, check:parse-guard, check:pnpm-filter-targets, check:watch-hint-literal. check-test-completeness.mjs: NOT MEASURED, exit 3 PREREQUISITE NOT MET (needs a saved turbo run test log this scripts-only change did not produce). Always-run scripts/** dispatch gates check:ratchet-remedy-authority and check:declared-population-live: both RAN-PASS. check:pm-dispatch-gates (~11.5 min) not named by the derived list for this file surface -- not run. No package surface touched by this diff -- no lock needed for the heavy-verify slot; nothing here built a package.",
      "mcp_calls": "0 -- all GitHub reads/writes done over REST per the dispatch order's channel guidance; PR creation also succeeded over REST (POST /pulls was not refused), so the MCP fallback for PR creation was not needed.",
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Generated by Claude Code


    Generated by Claude Code

  5. claude commented on Sep 2, 2026

    @claude
    ContributorAuthor

    ACCEPT — #14177 landed. PR #14417 (head 98b80532) merged to main as 96b627d13 via the merge queue (auto-merge armed 05:48:58Z, zero rework).

    Close-out probes executed on origin/main (fresh fetch, throwaway worktree — not the shared checkout; 96b627d13 confirmed as an ancestor of origin/main):

    • scripts/build-console.sh:98 git -C "$SOURCE_ROOT" worktree prune — placed immediately before the worktree add --detach at :99, inside the [[ ! -d "$BUILD_ROOT" ]] branch, so a prunable registration left in the shared objectui/.git by an out-of-band rm -rf .cache/objectui-* (or the force-remove fallback) no longer makes the next add die with exit 128 "already registered worktree". The comment block :89–97 records why prune is safe unconditionally here (it only drops registrations whose directory is already gone). Control: worktree add = hits at :94 (comment) and :99 (the call), so the file is read and the prune is the new line.

    pm:dispatched stripped in this same step (tooling / priority:p3 / domain:devx kept — ownership is not state). Hot-file lock on scripts/build-console.sh released; #14393 (serial after this card on the same file) is now dispatchable.

    Seat: session_01WLJQhde67SeTccsmnBVarV (domain:devx, #6023).


    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

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions