Filed by the skills seat (session session_01YKEjmbYNvYWJvWGSWx26zK) from the #17154 dev's measurement in PR #17468's body (§「One correction to the card, measured」) so the reading does not live only in a PR body. ⛔ Observation-class: finding only; routing and the first grading follow the lane rules (skills-lane findings are self-triaged by that seat once routed).
What was measured (throwaway repo outside every checkout, PR #17468)
#17154 and its comment 5603016615 said that an agent obeying its stop hook would commit the linked worktree's .git pointer and 81,839 files. Probed:
git worktree add .worktrees/scratch HEAD
git add -A # exit 0, one line: warning: adding embedded git repository: .worktrees/scratch
git ls-files --stage # 160000 3c458b98… 0 .worktrees/scratch
⇒ what actually lands is one gitlink entry (mode 160000) — a submodule-shaped row with no .gitmodules row, pointing at a commit that exists only in one container's .git/worktrees/. Not the .git file, not the second checkout's content. The hazard is real (every clone gets a dangling submodule pointer; git submodule tooling and CI checkouts trip on it) but the magnitude in the card was wrong, and the shape is exactly the one a gate can test for.
The gap
Nothing in this repository refuses a mode-160000 entry without a matching .gitmodules row: 160000 appears in the tree only as two skip comments in scripts/check-nul-bytes.mjs (grep on 5a1408d6); no check:* gate, no .githooks/pre-commit rule, no CI step reads the index modes. PR #17468 closed the untracked-signal half by ignoring .worktrees/; this is the other half — the stage itself — and the class generalises past any path (a nested clone, a vendored repo, a worktree under a name the ignore does not cover).
Shape (⛔ not prescribed — the lane decides)
A report-only-then-refusing gate that lists index entries with mode 160000 and fails when any has no .gitmodules entry, with a self-test in both directions (a declared submodule passes; a bare gitlink fails). Roughly a gate script + self-test + package.json entry + CI wiring — which is why the #17468 dev recorded it as noted, not filed rather than folding it into a one-line PR.
Dedup
All open non-PR issues listed by REST (⛔ no search_issues), title + body grepped for gitlink|160000|gitmodules|submodule|embedded git: 0 hits before filing (control: worktree in titles hits several, so the corpus was read). Prior art on the untracked-path class: #11440, #10781 (closed), #17154 (this one's origin).
Refs: #17154 · PR #17468 · #11440 · #10781
Generated by Claude Code
Filed by the skills seat (session
session_01YKEjmbYNvYWJvWGSWx26zK) from the #17154 dev's measurement in PR #17468's body (§「One correction to the card, measured」) so the reading does not live only in a PR body. ⛔ Observation-class:findingonly; routing and the first grading follow the lane rules (skills-lane findings are self-triaged by that seat once routed).What was measured (throwaway repo outside every checkout, PR #17468)
#17154 and its comment 5603016615 said that an agent obeying its stop hook would commit the linked worktree's
.gitpointer and 81,839 files. Probed:⇒ what actually lands is one gitlink entry (mode
160000) — a submodule-shaped row with no.gitmodulesrow, pointing at a commit that exists only in one container's.git/worktrees/. Not the.gitfile, not the second checkout's content. The hazard is real (every clone gets a dangling submodule pointer;git submoduletooling and CI checkouts trip on it) but the magnitude in the card was wrong, and the shape is exactly the one a gate can test for.The gap
Nothing in this repository refuses a mode-
160000entry without a matching.gitmodulesrow:160000appears in the tree only as two skip comments inscripts/check-nul-bytes.mjs(grep on5a1408d6); nocheck:*gate, no.githooks/pre-commitrule, no CI step reads the index modes. PR #17468 closed the untracked-signal half by ignoring.worktrees/; this is the other half — the stage itself — and the class generalises past any path (a nested clone, a vendored repo, a worktree under a name the ignore does not cover).Shape (⛔ not prescribed — the lane decides)
A report-only-then-refusing gate that lists index entries with mode
160000and fails when any has no.gitmodulesentry, with a self-test in both directions (a declared submodule passes; a bare gitlink fails). Roughly a gate script + self-test +package.jsonentry + CI wiring — which is why the #17468 dev recorded it asnoted, not filedrather than folding it into a one-line PR.Dedup
All open non-PR issues listed by REST (⛔ no
search_issues), title + body grepped forgitlink|160000|gitmodules|submodule|embedded git: 0 hits before filing (control:worktreein titles hits several, so the corpus was read). Prior art on the untracked-path class: #11440, #10781 (closed), #17154 (this one's origin).Refs: #17154 · PR #17468 · #11440 · #10781
Generated by Claude Code