Stop os-backlog tests from rewriting the main checkout .cc-os/config from a linked worktree #1759
Labels
No labels
P0
P1
P2
P3
bug
category/code-change
category/cross-repo
category/eval-run
category/investigation
category/no-test-target
category/owner-ruling
category/prose-artifact
category/recurring-chore
category/structure
category/umbrella
crc-refactor
create
delete
enhancement
filed-by/agent
filed-by/user
frozen
lint-rule
needs-info
needs-triage
next
plugin/cc-architect
plugin/os
plugin/os-adr
plugin/os-aidd-lint
plugin/os-backlog
plugin/os-context
plugin/os-doc-hygiene
plugin/os-sdlc
plugin/os-vault
project/cc-os
ready-for-agent
ready-for-human
recurring
review
rule-proposal
update
waiting
wayfinder:grilling
wayfinder:map
wayfinder:map
wayfinder:research
wayfinder:task
wayfinder:task
wontfix
worklist/deviations
worklist/lint-rule
worklist/new-implement-build
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
jared/cc-os#1759
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
os-backlog project configurewrites the.cc-os/configof the primary checkout when the working directory is in a linked git worktree that has no.cc-os/config. The os-backlog tests runproject configure repo:docs/issues. Thus a test run in such a worktree can replace the tracker of the real repository, and then every os-backlog ticket command in the repository fails.Observed
At about 15:21 EST on 2026-11-13 a process rewrote
/home/jared/dev/cc-os/.cc-os/configtotracker=repo:docs/issues.Only os-backlog tests and os-sdlc tests use the value
repo:docs/issues. The directorydocs/issuesdoes not exist.Every os-backlog ticket command in the repository failed until an agent ran
os-backlog project configure forgejo:jared/cc-os(file mtime 15:24:13).Git ignores the file (
.gitignore:26), so git has no history of it.Mechanism, read in the source:
plugins/os-backlog/lib/backlog/config_locator.rb:13-15locate_for_writeusesfind_owning_rootwhen the start directory has no.cc-os/config.plugins/os-backlog/lib/backlog/config_locator.rb:24-30find_owning_rootreturns the primary checkout root when the start directory is in a linked worktree (OsGit::RepoRoot.primary_root,plugins/os-git/lib/os_git/repo_root.rb:13-17and:49-55).plugins/os-backlog/lib/backlog/cli/session.rb:16givesDir.pwdas the start directory.plugins/os-backlog/lib/backlog/config/write_command.rb:14-16writes the file.Candidate writer (strong evidence, not proven):
project configure repo:docs/issuesareplugins/os-backlog/test/cli_config_write_command_test.rb:47andplugins/os-backlog/test/cli_config_write_origin_remote_test.rb:49. They are safe only whilein_dir(plugins/os-backlog/test/support/temporary_chdir.rb) moves the process into a temporary directory first./home/jared/dev/cc-os/.claude/worktrees/os-backlog-test-speedhas no.cc-os/config. Most other worktrees have a symlink to the.cc-osof the main checkout.test/support/temporary_chdir.rbhas mtime 15:18:31.test/cli_config_write_command_test.rb,test/cli_config_write_origin_remote_test.rb,test/support/cli_sandbox.rb,test/support/in_process_cli_run.rb,lib/backlog/cli/session.rb, andlib/backlog/cli/project_commands.rbhave mtime 15:23:52. That work removesin_dirfrom those tests and replacesDir.pwdinSessionwith an injectedcwd.Dir.pwd.project configure repo:docs/issuesthen ran with the working directory in the worktree, and the write went to the main checkout.docs/takedown/1748-20261113-150953in the worktreeticket-1742). It ran only os-sdlc ConceptCycle tests in a scratch repository below~/.cache/cc-os/takedown-runs/. That repository is not a linked worktree.Reproduce
Not run, because it rewrites the real file. Expected to reproduce:
Acceptance criteria
.cc-os/config, when the full os-backlog suite and the os-sdlc tests that userepo:docs/issuesrun from that worktree, then/home/jared/dev/cc-os/.cc-os/configis byte-identical before and after the run.project configure, when its write target is outside its temporary directory, then it fails with an error and writes nothing.project configurein a linked worktree that has no.cc-os/config, when it runs, then it obeys a recorded decision about a write to the primary checkout.Origin
/home/jared/dev/cc-osafter about 15:21 EST on 2026-11-13; the file containedtracker=repo:docs/issues.os-backlog project configure forgejo:jared/cc-os..cc-os/configholds the test valuerepo:docs/issues(file content, observed) ←project configure repo:docs/issuesran with a working directory in a linked worktree without.cc-os/config(inferred from file mtimes in the worktreeos-backlog-test-speed) ←locate_for_writesends the write to the primary checkout (plugins/os-backlog/lib/backlog/config_locator.rb:13-30) ← DESIGN (plugins/os-backlog/lib/backlog/config_locator.rb).plugins/os-backlog/lib/backlog/config_locator.rb(Backlog::ConfigLocator#locate_for_write);plugins/os-backlog/test/cli_config_write_command_test.rbVERDICT: CREATE (ticket-skeptic, 2026-11-13): a test run from a linked worktree can overwrite the git-ignored
.cc-os/configof the real repository; the nearest open ticket #1674 covers a different fault.