Claude Code First, specification version 0.1.0. The plain-language guide
Version 0.1.0. Grade R2/S2.
F200 A commit tool that stages everything commits whatever else the working tree holds, and an ignore rule closes only the pattern it names
| Field | Value |
|---|---|
| Status | active |
| Topic | Commits and concurrent sessions |
| Grade | R2/S2 |
| Cases | Shio, freewilly |
| Contrary | none |
| Harness facts | none |
Claim
The owner's commit tool stages the whole tree, so scratch files and unrelated edits in the working tree (run logs, bytecode, a settings file changed mid-session) were committed under another task's message, and the ignore rules added in answer closed each pattern only after it had leaked once.
Mechanism
An agent session leaves artefacts beside its work: a teed test log, a progress file, a __pycache__ directory from a hook, a settings file the session rewrote. A commit step that runs a stage-all command owns everything the tree holds at that moment, so any of these rides into the next commit, whose message, written for the task, does not mention it. An ignore rule names one pattern after it has leaked; a file under a new name is not covered until it leaks in turn.
Observations
- Shio. The pinned instruction file describes the tool: it "generates a Conventional-Commits message from the staged diff via the OpenAI API" [shio@821f18d74:agents.md#L241-L242]
after staging the tree. A teed run log was committed with a feature, "which is how sh545.log landed in b04ee918" [shio@821f18d74:.gitignore#L62], in [shio@b04ee9187] on 2026-08-06; 56 seconds later a commit ignored root logs, "a teed run log at the root stops being committed with the fix it measured" [shio@9553233a2]. The ignore file gives the cause: the tool "stages everything, so a" [shio@821f18d74:.gitignore#L60-L61] log named anything else is committed. On 2026-08-17 the SH778 fix [shio@d726a4b8b] carried provoke.log.progress, which the /*.log rule did not match; the next commit, nine seconds later, removed it: "a scratch artifact from the flake provocation is not a repository file" [shio@44e6ef232], whose body says "so it landed in the SH778 commit" [shio@44e6ef232]. Bytecode had leaked the same way earlier: "one .pyc reached a commit that way (SH46's)" [shio@821f18d74:.gitignore#L117].
- freewilly. On 2026-08-14 the DD112 commit [freewilly@d01fcb3] removed 15 entries from
.claude/settings.json that the task did not call for. The restoring commit states "The harness rewrote .claude/settings.json mid-session" [freewilly@ac7e7ec] (harness observation O1). The test written in answer records the route: "the second time the deletion rode into a commit about" [freewilly@c1c2eaf:tests/FreeWilly.Preflight.Tests/PackagingTests.cs#L278] something else, "because run-commit.cmd stages everything by design." [freewilly@c1c2eaf:tests/FreeWilly.Preflight.Tests/PackagingTests.cs#L279] The ledger entry for DD117 names a second stray of another kind: "A commit owns whatever the tree was holding, so a trimmed setting and a test's bytecode shipped inside other changes" [freewilly@c1c2eaf:docs/CHANGELOG.md#L201]. That task, DD117, was retired because "the fix touches a commit tool every repository shares" [freewilly@c1c2eaf:docs/CHANGELOG.md#L201], and the tree was protected by ignore rules instead, one of them for test output, since "so one diagnostic run otherwise lands in a commit about something else." [freewilly@c1c2eaf:.gitignore#L48]
- winwright, roadkeep, polyweave. The same tool is prescribed in each, and the pinned
sources warn about it without recording a stray file: winwright's skill says the tool stages everything, so "a stray scratch file rides along" [winwright@861b82e:.claude/skills/roadmap-docs/SKILL.md#L48]; roadkeep's says "It stages everything." [roadkeep@91754240:.claude/skills/roadkeep-dev/SKILL.md#L69]; polyweave's rule is "staged by path, never pushed" [polyweave@6d1c136:CLAUDE.md#L62-L63]. These are prose (S1) and add no incident.
Independence
The common cause is one tool, the owner's run-commit.cmd, which all five projects use. Under rule 3 of ../grading.md its behaviour is one origin, however many projects show it. The strays themselves differ by project (Shio's teed logs, freewilly's settings rewrite and test output), so counted as failures under rule 1 they would be two origins; this finding takes the lower count, because the claim is about what the tool does. The ignore rules are local remedies: Shio's and freewilly's name different patterns and were each written after a local leak, so neither is a copy of the other. The warnings in winwright, roadkeep and polyweave are copies of the same instruction and count for nothing.
Counter-evidence
None found at the pins. The pins cannot show strays that were caught before a commit, and freewilly's restoring commit says the first of its two trims was "caught before a commit" [freewilly@ac7e7ec], so the recorded leaks are a lower bound. Whether any project still leaks after its ignore rules is not recorded.
Grade
R2: one origin, the tool, seen on separate occasions and across an attempted fix: Shio's log leak on 2026-08-06, the /*.log rule the same minute, and a second log-like file leaking past that rule on 2026-08-17; freewilly's settings trim on 2026-08-14 and a test's bytecode, undated in the ledger. S2: each leak is recorded by a commit, a ledger entry or a comment beside the ignore rule. The removed entry count (15) describes the freewilly incident but does not measure the finding, and no count of leaked files was made at the pins, so the grade is not S3.