Two independent bugs make this repo hostile to git worktree checkouts. Both were hit during real work on PR #31 and cost time to diagnose and work around.
1. script/install-precommit writes to a path that does not exist in a worktree
The script writes .git/hooks/pre-commit directly. In a linked worktree, .git is a file containing a gitdir: pointer, not a directory — so there is no .git/hooks/ to write into:
make hooks therefore fails outright in any worktree.
The fix is one line: resolve the hooks directory with git rev-parse --git-common-dir instead of assuming the literal path. That returns the shared .git of the main checkout from inside a worktree, and the plain .git directory otherwise, so it is correct in both cases.
Note backend/Makefile's hooks target has the same flaw — it uses $(git rev-parse --show-toplevel)/.git/hooks/pre-commit, which is wrong for the same reason. That target is slated for removal in #16; if #16 lands first this half is moot, so check before duplicating work.
2. Dockerfile.backend's COPY .git /repo/.git breaks in a worktree
The Docker build copies .git so backend/Makefile's git describe can resolve a version. From a worktree, .git is the pointer file, so the copy produces something unusable and git describe fails inside the build. make docker cannot be run from a worktree at all.
This half is already addressed by #17, which replaces the .git copy with ARG VERSION per the mandated Go Dockerfile pattern. It is recorded here only so the two symptoms are documented together — do not fix it twice. If #17 lands first, close this half as resolved.
Why this matters beyond convenience
Worktrees are the standard isolation mechanism for concurrent work in this repo. Every implementer and reviewer is expected to work in one. Both of these bugs are hit on essentially every backend change, and the workarounds are non-obvious:
The PR #31 implementer had to clone the worktree to a scratch directory just to run the Docker gate.
Anyone running make setup in a worktree gets a hard failure on a target that is supposed to be routine.
That is a tax on every future change, and it invites a worse outcome: an agent that cannot run make docker from its worktree may skip the Docker gate rather than work around it, and a gate that is inconvenient enough to skip is not a gate.
Definition of done
script/install-precommit resolves the hooks directory via git rev-parse --git-common-dir (or equivalent) rather than the literal .git/hooks path.
make hooks succeeds from a linked worktree and from a normal clone. Verify both explicitly and report both results.
The installed hook is functional in both cases — not merely created. Make a trivial commit in each and confirm the hook actually runs.
make docker succeeds from a linked worktree. If #17 has already landed, verify this still holds rather than re-implementing; if it has not, coordinate — say in the PR which issue you are relying on.
If backend/Makefile's hooks target still exists at implementation time, it gets the same fix or is removed per #16.
make check passes at the root and in backend/.
TODO.md updated in the same commit.
Commit title ends with (closes #N).
Implementation requirements
script/ files stay POSIX sh: #!/bin/sh, set -eu, no bashisms.
script/install-precommit is close to a model script shared across repos — if the fix is generally correct (it is), note in the PR that it is worth upstreaming to sneak/prompts rather than diverging here. See #28, which tracks script drift from the models.
Do not silently swallow errors. If the hooks directory genuinely cannot be resolved, fail loudly.
make targets and script/ entrypoints only.
No attribution trailers in the commit message.
## Problem
Two independent bugs make this repo hostile to `git worktree` checkouts. Both were hit during real work on PR #31 and cost time to diagnose and work around.
### 1. `script/install-precommit` writes to a path that does not exist in a worktree
The script writes `.git/hooks/pre-commit` directly. In a linked worktree, `.git` is a **file** containing a `gitdir:` pointer, not a directory — so there is no `.git/hooks/` to write into:
```
cannot create .git/hooks/pre-commit: Directory nonexistent
```
`make hooks` therefore fails outright in any worktree.
The fix is one line: resolve the hooks directory with `git rev-parse --git-common-dir` instead of assuming the literal path. That returns the shared `.git` of the main checkout from inside a worktree, and the plain `.git` directory otherwise, so it is correct in both cases.
Note `backend/Makefile`'s `hooks` target has the same flaw — it uses `$(git rev-parse --show-toplevel)/.git/hooks/pre-commit`, which is wrong for the same reason. That target is slated for removal in #16; if #16 lands first this half is moot, so check before duplicating work.
### 2. `Dockerfile.backend`'s `COPY .git /repo/.git` breaks in a worktree
The Docker build copies `.git` so `backend/Makefile`'s `git describe` can resolve a version. From a worktree, `.git` is the pointer **file**, so the copy produces something unusable and `git describe` fails inside the build. `make docker` cannot be run from a worktree at all.
**This half is already addressed by #17**, which replaces the `.git` copy with `ARG VERSION` per the mandated Go Dockerfile pattern. It is recorded here only so the two symptoms are documented together — do not fix it twice. If #17 lands first, close this half as resolved.
## Why this matters beyond convenience
Worktrees are the standard isolation mechanism for concurrent work in this repo. Every implementer and reviewer is expected to work in one. Both of these bugs are hit on essentially every backend change, and the workarounds are non-obvious:
- The PR #31 implementer had to clone the worktree to a scratch directory just to run the Docker gate.
- Anyone running `make setup` in a worktree gets a hard failure on a target that is supposed to be routine.
That is a tax on every future change, and it invites a worse outcome: an agent that cannot run `make docker` from its worktree may skip the Docker gate rather than work around it, and a gate that is inconvenient enough to skip is not a gate.
## Definition of done
- [ ] `script/install-precommit` resolves the hooks directory via `git rev-parse --git-common-dir` (or equivalent) rather than the literal `.git/hooks` path.
- [ ] `make hooks` succeeds from a linked worktree **and** from a normal clone. Verify both explicitly and report both results.
- [ ] The installed hook is functional in both cases — not merely created. Make a trivial commit in each and confirm the hook actually runs.
- [ ] `make docker` succeeds from a linked worktree. If #17 has already landed, verify this still holds rather than re-implementing; if it has not, coordinate — say in the PR which issue you are relying on.
- [ ] If `backend/Makefile`'s `hooks` target still exists at implementation time, it gets the same fix or is removed per #16.
- [ ] `make check` passes at the root and in `backend/`.
- [ ] `TODO.md` updated in the same commit.
- [ ] Commit title ends with ` (closes #N)`.
## Implementation requirements
- `script/` files stay POSIX sh: `#!/bin/sh`, `set -eu`, no bashisms.
- `script/install-precommit` is close to a model script shared across repos — if the fix is generally correct (it is), note in the PR that it is worth upstreaming to `sneak/prompts` rather than diverging here. See #28, which tracks script drift from the models.
- Do not silently swallow errors. If the hooks directory genuinely cannot be resolved, fail loudly.
- `make` targets and `script/` entrypoints only.
- No attribution trailers in the commit message.
clawbot
added this to the 1.0.0 milestone 2026-08-09 04:11:48 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Problem
Two independent bugs make this repo hostile to
git worktreecheckouts. Both were hit during real work on PR #31 and cost time to diagnose and work around.1.
script/install-precommitwrites to a path that does not exist in a worktreeThe script writes
.git/hooks/pre-commitdirectly. In a linked worktree,.gitis a file containing agitdir:pointer, not a directory — so there is no.git/hooks/to write into:make hookstherefore fails outright in any worktree.The fix is one line: resolve the hooks directory with
git rev-parse --git-common-dirinstead of assuming the literal path. That returns the shared.gitof the main checkout from inside a worktree, and the plain.gitdirectory otherwise, so it is correct in both cases.Note
backend/Makefile'shookstarget has the same flaw — it uses$(git rev-parse --show-toplevel)/.git/hooks/pre-commit, which is wrong for the same reason. That target is slated for removal in #16; if #16 lands first this half is moot, so check before duplicating work.2.
Dockerfile.backend'sCOPY .git /repo/.gitbreaks in a worktreeThe Docker build copies
.gitsobackend/Makefile'sgit describecan resolve a version. From a worktree,.gitis the pointer file, so the copy produces something unusable andgit describefails inside the build.make dockercannot be run from a worktree at all.This half is already addressed by #17, which replaces the
.gitcopy withARG VERSIONper the mandated Go Dockerfile pattern. It is recorded here only so the two symptoms are documented together — do not fix it twice. If #17 lands first, close this half as resolved.Why this matters beyond convenience
Worktrees are the standard isolation mechanism for concurrent work in this repo. Every implementer and reviewer is expected to work in one. Both of these bugs are hit on essentially every backend change, and the workarounds are non-obvious:
make setupin a worktree gets a hard failure on a target that is supposed to be routine.That is a tax on every future change, and it invites a worse outcome: an agent that cannot run
make dockerfrom its worktree may skip the Docker gate rather than work around it, and a gate that is inconvenient enough to skip is not a gate.Definition of done
script/install-precommitresolves the hooks directory viagit rev-parse --git-common-dir(or equivalent) rather than the literal.git/hookspath.make hookssucceeds from a linked worktree and from a normal clone. Verify both explicitly and report both results.make dockersucceeds from a linked worktree. If #17 has already landed, verify this still holds rather than re-implementing; if it has not, coordinate — say in the PR which issue you are relying on.backend/Makefile'shookstarget still exists at implementation time, it gets the same fix or is removed per #16.make checkpasses at the root and inbackend/.TODO.mdupdated in the same commit.(closes #N).Implementation requirements
script/files stay POSIX sh:#!/bin/sh,set -eu, no bashisms.script/install-precommitis close to a model script shared across repos — if the fix is generally correct (it is), note in the PR that it is worth upstreaming tosneak/promptsrather than diverging here. See #28, which tracks script drift from the models.maketargets andscript/entrypoints only.