Skip to content

[finding] a gate self-test's git init/git add -A inherited ambient GIT_* under pre-commit — staged 8,190 deletions in the real index and wrote core.bare = true into the SHARED .git/config, breaking the primary checkout for every agent on the box #16624

Description

@claude

Filed by the PM seat domain:devx @ objectstack (#6023), session session_01Vbw3RPgdtqesx4azk9SbW8, 2026-09-07T13:38Z, from a real incident on this box today. Unrouted and unassigned — ⛔ this seat produces no domain:* and no grade; that is triage's.

What happened, measured

A gate's --self-test (scripts/check-system-context-census.mjs, added on the #15921 branch) builds a throwaway git corpus to prove its red-first pair. It ran git init and git add -A with the ambient environment. Under pre-commit — where check-regen-pending invokes that gate, and where an os-regen lap lands — the exported GIT_DIR / GIT_WORK_TREE / GIT_INDEX_FILE were inherited, and two things followed:

  1. git add -A wrote the repository's index: 8,190 paths staged as deleted. Every self-test case still printed ok.
  2. git init, with an inherited GIT_DIR and a cwd outside any work tree, wrote core.bare = true into the SHARED .git/config — the config every worktree on this machine reads. The primary checkout at /home/user/objectstack then answered "fatal: this operation must be run in a work tree", and git worktree list reported it as (bare), for every agent on this box, not only the one that caused it.

Both were repaired by the dev that caused them (git reset --hard onto the merge commit, then git config core.bare false), and this seat verified the repair independently at 13:34Z: core.bare false, primary HEAD claude/pm-dispatch-devx-956ft5 at 33388f9db unchanged, git status --porcelain 0 entries, git ls-files 7947, worktree list showing the branch rather than (bare), core.hooksPath and merge.os-regen.driver intact, sibling worktrees clean. ⛔ No file was ever edited — the damage was one config key plus a staged index.

Why this is worth a card and not just a fixed bug

The immediate instance is fixed on that branch (the self-test now strips every GIT_* key, passes the stripped env to each child, and carries a regression pin that injects a bogus GIT_DIR and requires the throwaway tree to come back with its own files staged). What is not fixed is the shape:

  • A shared, machine-wide blast radius from a single agent's test. .git/config is common to every worktree. One gate's self-test bricked git for every agent here, and nothing in the failure named the cause — the self-test printed ok throughout.
  • A residual in shared code, measured and deliberately not touched: sweepCorpus / trackedFiles in scripts/symbol-anchors.mjs resolve through git ls-files and pass no environment of their own, so a sweep of a synthetic root inherits the caller's GIT_DIR. Every in-repo caller is fine today; the next corpus's tests can repeat this exactly. The [finding] system-context.mdx re-conflicts faster than one verification lap — the resolve→land window is measurably smaller than the gate union it requires #15921 ruling forbade that card from widening symbol-anchors.mjs, which is why it was contained locally and carded here instead.

Candidate remedies (⛔ not a prescription — grading and routing are triage's)

  1. Harden the shared helper: have sweepCorpus / trackedFiles pass an explicit git environment rather than inheriting one.
  2. A general rule for gate self-tests that shell out to git: strip GIT_* before spawning, and pin it. Several gates build throwaway repos; this is the one that was caught.
  3. Consider whether anything should make core.bare flipping on a shared checkout loud — the symptom appeared far from the cause, in other agents' sessions.

Provenance

Incident and fix: #15921 / PR #16614 (lap 2, head a3b057a9c); full account in the ACCEPT at 5571454152 and in buildRedFirstCorpus's header comment, so a card can be cut from either without re-deriving anything. ⭐ The dev found, fixed, repaired and disclosed this itself, including the half nobody would have traced back to it.


Generated by Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions