What happened
In a repository the user set up by hand (git init, then a commit), the interactive shell refuses to run on its own session log.
The shell opens a session log at .copperhead/runs/repl-<ts>.log before the first turn (repl.ts:325). A hand-made repository has no .gitignore entry for .copperhead/runs/, so git status now reports ?? .copperhead/. The dirty-tree gate (git.ts, gitPreflight) counts that as uncommitted work and refuses the run.
The result is a dead end on a repository that was clean a second earlier: copperhead tells you to commit or stash work that is not yours, over a file copperhead itself just wrote. The three suggested fixes all miss, because none of them is the actual problem:
git add -A && git commit commits copperhead's transcripts into project history
git stash stashes them, and the next launch recreates them
--allow-dirty works, but it silently disables the protection for the user's real work too
Expected: copperhead's own audit trail is not the user's uncommitted work, so it should not count toward the dirty-tree gate. restore() already carries .copperhead/runs/ across a rollback rather than resetting it, so excluding it costs nothing.
Affects do, sync, and the interactive shell. create is unaffected: it runs with allowDirty: true and bootstraps .gitignore itself.
Steps to reproduce
1. mkdir board && cd board
2. printf '# Brief\n\nA simple LED blinker board.\n' > brief.md
3. git init && git add -A && git commit -m "initial commit"
4. copperhead # or: copperhead do "add a resistor"
5. type any request at the prompt
Step 4 creates .copperhead/. Step 5 refuses.
Output
$ git status --porcelain # after step 3
$ # clean
$ copperhead
# ... shell opens, writes .copperhead/runs/repl-<ts>.log
$ git status --porcelain # copperhead's own file, nothing of the user's
?? .copperhead/
# at the prompt:
working tree is dirty; copperhead refuses to run on uncommitted changes by default
why it failed: a rollback hard-resets to the pre-run snapshot, which would silently destroy your uncommitted work
to fix:
1. git add -A && git commit — to keep your changes (recommended)
2. git stash — to set them aside for now
3. or rerun with --allow-dirty to let copperhead preserve them via "git stash create"
Related: the ignore entry is never topped up
GIT_ADD_EXCLUDES in git.ts currently holds only .history/, so no copperhead commit adds .copperhead/runs/ to a repository that lacks it. AC-4.3 requires that entry. In a hand-made repository, a run that reaches commitAll (git add -A) therefore sweeps the transcripts into project history.
Which command
other or not command-specific (do, sync, and the interactive shell)
Model backend
Not applicable: the gate fires before the provider is constructed.
copperhead version
0.9.0
Node, KiCad, and OS
node v24.18.0, kicad-cli 10.0.4, Linux 6.6.6 (Pop!_OS)
What happened
In a repository the user set up by hand (
git init, then a commit), the interactive shell refuses to run on its own session log.The shell opens a session log at
.copperhead/runs/repl-<ts>.logbefore the first turn (repl.ts:325). A hand-made repository has no.gitignoreentry for.copperhead/runs/, sogit statusnow reports?? .copperhead/. The dirty-tree gate (git.ts,gitPreflight) counts that as uncommitted work and refuses the run.The result is a dead end on a repository that was clean a second earlier: copperhead tells you to commit or stash work that is not yours, over a file copperhead itself just wrote. The three suggested fixes all miss, because none of them is the actual problem:
git add -A && git commitcommits copperhead's transcripts into project historygit stashstashes them, and the next launch recreates them--allow-dirtyworks, but it silently disables the protection for the user's real work tooExpected: copperhead's own audit trail is not the user's uncommitted work, so it should not count toward the dirty-tree gate.
restore()already carries.copperhead/runs/across a rollback rather than resetting it, so excluding it costs nothing.Affects
do,sync, and the interactive shell.createis unaffected: it runs withallowDirty: trueand bootstraps.gitignoreitself.Steps to reproduce
Step 4 creates
.copperhead/. Step 5 refuses.Output
Related: the ignore entry is never topped up
GIT_ADD_EXCLUDESin git.ts currently holds only.history/, so no copperhead commit adds.copperhead/runs/to a repository that lacks it. AC-4.3 requires that entry. In a hand-made repository, a run that reachescommitAll(git add -A) therefore sweeps the transcripts into project history.Which command
other or not command-specific (
do,sync, and the interactive shell)Model backend
Not applicable: the gate fires before the provider is constructed.
copperhead version
0.9.0
Node, KiCad, and OS
node v24.18.0, kicad-cli 10.0.4, Linux 6.6.6 (Pop!_OS)