feat(state): Preserve selected project roots - #122
Conversation
72f40d7 to
be8d24f
Compare
Canonicalize so d.root, the runtime dir, and fsnotify event paths agree (e.g. macOS /tmp -> /private/tmp, /var -> /private/var), fixing the union-gated watch tests standalone (PR JordanCoin#122 macOS CI failure class). Co-Authored-By: GPT-5.6 Sol <codex@openai.com>
|
Reviewed. The root-selection work itself is coherent and the concern I raised on #94 doesn't bite here — I checked, But there's one change I'd call a blocker, and it's unrelated to the PR's stated purpose.
|
78679b8 to
1b6be65
Compare
Keep setup and runtime roots consistent across configuration, handoffs, scanning, skills, and watch state, so a sandbox's runtime artifacts (handoff storage, watch state, pid, events) live with its selected project root. Runtime state is owned per project: State records its Root, ReadState rejects state written by a different project when several projects share one runtime dir (callers inside the owning project still see it), and Stop never removes the pid file for an unverified foreign PID. Restores the linked-worktree setup-root skills test; drops config tests that passed unchanged on main. Co-Authored-By: GPT-5.6 Sol <codex@openai.com>
Read stdout only and take the error detail from the process stderr (ExitError.Stderr) instead of the merged output, so an exit-0 git warning (ambiguous refname, CRLF notice, textconv driver) cannot contaminate the parser. A strict numstat count guard rejects non-numstat rows. Co-Authored-By: GPT-5.6 Sol <codex@openai.com>
f28a89b to
ed9e18b
Compare
|
Blocker — fixed as you suggested. Watch PID/state vs Also: restored |
|
The three things I raised are all genuinely fixed, and I verified each rather than taking the diff at face value:
But holding on one thing, because it's a regression this PR introduces rather than a pre-existing gap.
// origin/main
pidFile := filepath.Join(root, ".codemap", "watch.pid")
// this PR
pidFile := filepath.Join(projectpath.RuntimeCodemapDir(root), "watch.pid")Under an explicit Two distinct failures: This isn't only manual-CLI reachable — You solved exactly this class of bug on the read side with Same shape applies to Genuinely close — the read-side design is right, it just needs to extend to the write/kill side. Everything else in the PR is good to go. For context: #125 and #128 are merged (they're independent of this — zero file overlap), so this is the only one outstanding from the ready set. |
Projects sharing a setup root previously collided on watch.pid, state.json, events.log, and handoff files: the second project silently got no daemon and stopping it killed the first project's daemon. Mutable state now lives under a per-project key (projectpath.ProjectRuntimeDir) derived from the canonical project root, so subdirectories share the key and distinct projects never do. The daemon still watches the config directory for configured-file changes. Co-Authored-By: GPT-5.6 Sol <codex@openai.com>
|
Heads-up on the red check — it isn't yours. Don't spend time on it.
Confirmed three ways:
time.Sleep(100 * time.Millisecond) // hope the daemon is watching by now
for i := 0; i < 5; i++ { os.WriteFile(...) }
time.Sleep(300 * time.Millisecond) // hope the debounce flushed by now
...
if writeCount == 0 || writeCount > 2 { ... }
if lastWriteLines != 6 { ... }Fixed sleeps around real fsnotify delivery on a shared CI runner. Either the 100ms start-up window elapses before the watcher is actually registered (writes missed, I've filed it separately so it stops costing contributors time on unrelated PRs. Re-running the job should go green; nothing to change here. Separately — I still owe you a re-review of the |
|
No stress, my next dozen PRs keep waiting for you 😄 Of course we saw that red, and I think we even fixed it in one of the open PRs... but which one is the question, I can't keep dozens of worktrees open, MacBooks have only tiny expensive SSDs, can't even install all those amazing new small models of the last 7 days alone. |
Give the fake ast-grep spawn and deadline-termination generous 5s budgets instead of racing 1s/2s windows, so loaded CI runners don't flake. Co-Authored-By: GPT-5.6 Sol <codex@openai.com>
|
It's a cold-cache flake, we found a stabilization, decoupled the test's timing windows at the cost of ~4.5s/job.
Both are now generous, decoupled budgets (5s each) — the test verifies cancellation semantics (deadline → subprocess terminated), not subprocess timing on loaded runners. |
What does this PR do?
Keeps setup and runtime roots consistent across configuration, handoffs, scanning, skills, and watch state, so runtime state (handoff storage, watch state/pid/events) lives with its selected project root. State is owned per project:
State.Root+ReadStatereject foreign-project state in shared runtime dirs;Stopkeeps the pid file for an unverified PID.Also fixes
git diff --numstatparsing: stdout is numstat only, error text comes from stderr, and a strict count guard rejects non-numstat rows — git warnings can never fabricate changed files.Verification
go test ./config ./handoff ./scanner ./skills ./watchDeveloped with carefully directed, manually reviewed AI assistance.