Problem Statement
The stageSourceTargets goroutine in the launcher is one-shot: it polls for plan/.bundle_complete, stages all source_code targets once, then exits. If the operator asks Soundwave to revise the engagement plan — changing the target path, adding a new source target, or removing one — complete_engagement_planning will write a fresh .bundle_complete marker with updated contents. The goroutine is already gone and will never observe the new marker.
The result is that /workspace/src inside the sandbox reflects the original plan, not the replanned one. The analyst continues with the wrong source tree, and there is no warning to the operator. This is a silent correctness failure for any engagement that goes through a planning revision.
Proposed Solution
Replace the one-shot goroutine with a persistent watcher that survives the initial staging run and continues to observe the plan directory for marker refreshes.
Concretely:
- After a successful staging run, instead of returning, the goroutine re-enters its polling loop watching for a new
.bundle_complete whose completed_at timestamp is newer than the one it last processed
- When a newer marker is detected (and the mtime consistency check passes), re-read
roe.json, diff the source targets against the previously staged set, and re-run copyDirTree for any targets that changed
- Write
staging-status.json back to in_progress during the re-stage, then back to staged on completion
- Print an operator-visible note in the CLI:
"Replan detected — re-staging source targets..."
The goroutine should exit only when the engagement workspace is torn down (context cancellation / launcher shutdown).
Alternative (simpler): Re-launch the goroutine from runStart each time a new engagement_ready event is observed on the stream. This avoids persistent state in the goroutine at the cost of always re-copying the full tree (no diffing).
Alternatives Considered
- Do nothing / document the limitation: Operators who replan must restart the launcher to pick up new source targets. Acceptable short-term but a footgun for iterative engagements.
- Full re-copy on every replan: Simpler implementation than diffing; acceptable for most source trees since staging is a local copy and typically fast relative to planning time.
- Operator warning only: Detect a stale
/workspace/src (by comparing manifest against current roe.json) at objective dispatch time and warn the analyst. Does not fix the root cause but prevents silent wrong-tree analysis.
Area
Docker / Infrastructure
Additional Context
Identified as a pre-existing architectural gap during the Codex adversarial review of PR #203. The one-shot design was intentional in the original implementation to keep the goroutine simple, but the introduction of plan/.bundle_complete in PR #203 makes it straightforward to detect replans by watching for a marker whose completed_at is newer than the last-processed timestamp.
The staging-status.json manifest written by PR #203 already records which source paths were staged and when, providing the baseline needed for a diff-based re-stage.
Related: #202, PR #203, #204
Problem Statement
The
stageSourceTargetsgoroutine in the launcher is one-shot: it polls forplan/.bundle_complete, stages allsource_codetargets once, then exits. If the operator asks Soundwave to revise the engagement plan — changing the target path, adding a new source target, or removing one —complete_engagement_planningwill write a fresh.bundle_completemarker with updated contents. The goroutine is already gone and will never observe the new marker.The result is that
/workspace/srcinside the sandbox reflects the original plan, not the replanned one. The analyst continues with the wrong source tree, and there is no warning to the operator. This is a silent correctness failure for any engagement that goes through a planning revision.Proposed Solution
Replace the one-shot goroutine with a persistent watcher that survives the initial staging run and continues to observe the plan directory for marker refreshes.
Concretely:
.bundle_completewhosecompleted_attimestamp is newer than the one it last processedroe.json, diff the source targets against the previously staged set, and re-runcopyDirTreefor any targets that changedstaging-status.jsonback toin_progressduring the re-stage, then back tostagedon completion"Replan detected — re-staging source targets..."The goroutine should exit only when the engagement workspace is torn down (context cancellation / launcher shutdown).
Alternative (simpler): Re-launch the goroutine from
runStarteach time a newengagement_readyevent is observed on the stream. This avoids persistent state in the goroutine at the cost of always re-copying the full tree (no diffing).Alternatives Considered
/workspace/src(by comparing manifest against currentroe.json) at objective dispatch time and warn the analyst. Does not fix the root cause but prevents silent wrong-tree analysis.Area
Docker / Infrastructure
Additional Context
Identified as a pre-existing architectural gap during the Codex adversarial review of PR #203. The one-shot design was intentional in the original implementation to keep the goroutine simple, but the introduction of
plan/.bundle_completein PR #203 makes it straightforward to detect replans by watching for a marker whosecompleted_atis newer than the last-processed timestamp.The
staging-status.jsonmanifest written by PR #203 already records which source paths were staged and when, providing the baseline needed for a diff-based re-stage.Related: #202, PR #203, #204