Landing blocker for #61 and #63: the deployment checkout is 12 commits behind and `merge --ff-only` refuses while tracked paths are dirty. Discard is not available here (workspace policy: no `checkout`/`stash` on shared state), so the dirt is committed. - `agent/APPEND_SYSTEM.md`: the point-of-use / one-work-log / PR-link doctrine, already byte-identical to `origin/main` (`cmp` against the trunk blob: no difference). No new prose — the commit exists so the trunk merge can proceed. - `agent/config.yml` and `agent/managed-skills/**`: the machine-live tier the heartbeat owns (AGENTS.md § Live-sync tiers). `ALLOW_SECRETS=1` was used, deliberately and after auditing the staged diff by hand: the only credential-shaped strings in it are two copies of `AKIA0000000000000EXAMPLE` — the inert all-zero AWS example id — and they appear inside the two skill pages that teach that exact placeholder shape. This checkout is still running the pre-#61 hook; the merged gate (value-scoped placeholder filter, `71601f7`) exempts this value, so the refusal dies with this landing. No `--no-verify` was used: the gate ran and its verdict is recorded here. Refs #61
29 lines
2.0 KiB
Markdown
29 lines
2.0 KiB
Markdown
---
|
|
name: bash-cwd-drift-multi-worktree
|
|
description: "Diagnose \"files keep reverting / phantom edits\" in multi-worktree sessions: the persistent bash shell's cwd silently reverted to another checkout, so probes and git commands ran against different files."
|
|
---
|
|
|
|
# Multi-worktree bash cwd drift
|
|
|
|
## Symptom (all of these at once, in one session)
|
|
- A file "keeps reverting" to an older version between edits (esp. test files).
|
|
- `grep -n` line numbers disagree with the tool/test output (e.g. bats reports `line 637`, grep says the match is at 519).
|
|
- `wc -l`/`md5sum` stable when sampled back-to-back, but state "flaps" across the session.
|
|
- `git status` clean in one call, surprising in the next.
|
|
- Probes against `src/` show code that doesn't exist in the branch you think you're on.
|
|
|
|
## Root cause
|
|
The persistent bash shell resets to the session's ORIGINAL cwd when a call omits `cwd` (e.g. after a shell respawn at a turn boundary). With several git worktrees of the same repo checked out, consecutive calls silently alternate between two full copies of the tree — half the reads land in the old branch's files. Nothing is rewriting anything; two files are being inspected.
|
|
|
|
## Decision
|
|
- In multi-worktree work, pass an **explicit `cwd` on EVERY bash call**. Never rely on persistence.
|
|
- Use **absolute paths** for `read`/`edit`/`write` (already required) — file tools don't drift; only bash does.
|
|
|
|
## Check
|
|
When state seems to flap: `pwd` in the same call as the probe. If two calls to the same relative path report different content, `git worktree list` and census each checkout separately — you have two files, not a gremlin.
|
|
|
|
## Repair pattern (if corruption got committed via the wrong tree)
|
|
1. `git log --oneline --all -- <file>`; per candidate commit print `wc -l` + counts of a few marker strings to classify clean vs corrupted blobs.
|
|
2. Restore the good blob with `git show <commit>:<path> > <path>` (no checkout — safe under worktree policies).
|
|
3. Re-apply the intended additions as surgical edits; verify with targeted tests before the full suite.
|