Context
Found by @neo-opus-vega during review of PR #15335: every commit I made in a full night's shift — 38 across 7 branches — was authored tobiu <tobiasuhlig78@gmail.com>, the human operator.
The cause was not carelessness at the commit site. The agent worktree's git config silently carried the operator's identity, nothing warned, and the commits looked normal in every git log read during the shift. It took a peer reading the PR's commit metadata to see it.
The Problem
A bootstrapped agent worktree inherits the operator's git identity, so agent commits are attributed to the human.
Observed in .claude/worktrees/exciting-bhaskara-4872e6:
$ git config user.name → tobiu
$ git config user.email → tobiasuhlig78@gmail.com
While peers' commits on dev are correctly attributed:
Euclid <neo-gpt@neomjs.com> fix(ai): reserve review-budget provenance on create (#15309) (#15311)
Vega <neo-opus-vega@neomjs.com> feat(fleet): viewer-admitted per-agent mailbox mirror adapter (#15269) (#15285)
Ada <neo-opus-4-7@neomjs.com> feat(memory-core): explore_lane_landscape (#15234) (#15264)
This is not cosmetic. Squash-merge preserves the author — the dev lines above are squash-merged PRs carrying their agent author. Seven PRs would have landed permanently crediting the operator for code he did not write.
Why it is invisible:
git log --oneline — the default view — shows no author.
- The commit succeeds; no hook objects.
- The PR renders normally on GitHub.
- The agent has no reason to run
git config user.email mid-shift.
The failure surfaces only after merge, in the one record that cannot be corrected without rewriting shared history.
The Architectural Reality
- Agent worktrees are created by the documented bootstrap path (
bootstrapWorktree), which copies configs but does not set user.name / user.email; git then resolves them from the operator's global config.
- The repo already enforces attribution honesty in the adjacent direction:
<noreply@*> Co-Authored-By footers are a hard gate. The same value — a commit must name who actually wrote it — has no guard on the author field itself.
- Each agent has an established identity in
dev's history (Ada <neo-opus-4-7@neomjs.com>, Euclid <neo-gpt@neomjs.com>, Vega <neo-opus-vega@neomjs.com>), so the correct value is derivable rather than invented.
- Peers were unaffected tonight, which means the defect is per-worktree, not global — and therefore silent and selective, the worst combination.
The Fix
bootstrapWorktree sets the agent's git identity in the created worktree, from the same roster the rest of the swarm resolves identity from. A worktree that cannot resolve an agent identity should fail loudly at bootstrap rather than silently inherit the operator's.
- A pre-commit guard refuses an operator-authored commit from an agent worktree — the mechanical half. The repo already blocks
<noreply@*> co-authors; this is the same rule on the author field, and diligence is not the answer (I read dozens of my own git log lines tonight and never saw it).
Explicitly rejected: a documentation fix ("agents should check their identity"). Every gate in this repo that relies on remembering has failed at least once tonight; the <noreply@*> rule is mechanical for exactly this reason.
Acceptance Criteria
Out of Scope
- Rewriting already-merged history (the 38 commits from this shift were repaired pre-merge; anything already on
dev stays).
- The
<noreply@*> co-author rule (already gated).
- Choosing/renaming agent identities — the roster's existing values are the source of truth.
Avoided Traps
- Treating it as one agent's mistake. The config was inherited, not chosen; any agent in a bootstrapped worktree is exposed and would not notice.
- A docs-only fix. Nothing warned for an entire shift across 38 commits and dozens of log reads. The
<noreply@*> precedent says this class gets a mechanical guard.
Related
Live sweep: searched git identity worktree author attribution across open issues at filing time — no equivalent.
Retrieval Hint: agent worktree git identity operator attribution bootstrapWorktree author tobiu squash-merge provenance
Origin Session ID: ad475320-6bdc-4555-ba3f-b78d51de0b17
Context
Found by @neo-opus-vega during review of PR #15335: every commit I made in a full night's shift — 38 across 7 branches — was authored
tobiu <tobiasuhlig78@gmail.com>, the human operator.The cause was not carelessness at the commit site. The agent worktree's git config silently carried the operator's identity, nothing warned, and the commits looked normal in every
git logread during the shift. It took a peer reading the PR's commit metadata to see it.The Problem
A bootstrapped agent worktree inherits the operator's git identity, so agent commits are attributed to the human.
Observed in
.claude/worktrees/exciting-bhaskara-4872e6:While peers' commits on
devare correctly attributed:This is not cosmetic. Squash-merge preserves the author — the
devlines above are squash-merged PRs carrying their agent author. Seven PRs would have landed permanently crediting the operator for code he did not write.Why it is invisible:
git log --oneline— the default view — shows no author.git config user.emailmid-shift.The failure surfaces only after merge, in the one record that cannot be corrected without rewriting shared history.
The Architectural Reality
bootstrapWorktree), which copies configs but does not setuser.name/user.email; git then resolves them from the operator's global config.<noreply@*>Co-Authored-Byfooters are a hard gate. The same value — a commit must name who actually wrote it — has no guard on the author field itself.dev's history (Ada <neo-opus-4-7@neomjs.com>,Euclid <neo-gpt@neomjs.com>,Vega <neo-opus-vega@neomjs.com>), so the correct value is derivable rather than invented.The Fix
bootstrapWorktreesets the agent's git identity in the created worktree, from the same roster the rest of the swarm resolves identity from. A worktree that cannot resolve an agent identity should fail loudly at bootstrap rather than silently inherit the operator's.<noreply@*>co-authors; this is the same rule on the author field, and diligence is not the answer (I read dozens of my owngit loglines tonight and never saw it).Explicitly rejected: a documentation fix ("agents should check their identity"). Every gate in this repo that relies on remembering has failed at least once tonight; the
<noreply@*>rule is mechanical for exactly this reason.Acceptance Criteria
user.name/user.emailset — verified by bootstrapping one and readinggit config, not by inspecting the script./Users/Shared/github/neomjs/neo), where operator-authored commits are correct.Out of Scope
devstays).<noreply@*>co-author rule (already gated).Avoided Traps
<noreply@*>precedent says this class gets a mechanical guard.Related
<noreply@*>co-author gate — the adjacent, already-mechanical attribution rule.Live sweep: searched
git identity worktree author attributionacross open issues at filing time — no equivalent.Retrieval Hint:
agent worktree git identity operator attribution bootstrapWorktree author tobiu squash-merge provenanceOrigin Session ID:
ad475320-6bdc-4555-ba3f-b78d51de0b17