diff --git a/docs/pipeline-setup.md b/docs/pipeline-setup.md index 4d4ac34..de4e05d 100644 --- a/docs/pipeline-setup.md +++ b/docs/pipeline-setup.md @@ -137,6 +137,8 @@ New runs retain a source SHA-256 in `run.json`. Stages refuse missing or changed before launching; existing outputs stay on disk. Legacy manifests without a digest need a new submission instead of blindly reusing cached state. Orchestrated runs reject cuts instead of silently trimming into another run directory. The direct runner retains its explicit shot controls. +Reject-only cut checks skip shot ranking and its model loads; their detector arguments match +the cache key. Cut detection and rejection still run before any stage. `wander step` admits one unresolved attempt per step in a run directory. A filesystem lock serializes admission, then releases before execution so independent steps can proceed. Detached diff --git a/docs/pipeline-validation.md b/docs/pipeline-validation.md index 23d64c1..7a9ca93 100644 --- a/docs/pipeline-validation.md +++ b/docs/pipeline-validation.md @@ -104,6 +104,20 @@ sign-in; inherited unrelated MCP sign-in and duplicate-hook warnings did not pre turn. The broken system CLI was then updated to that version and its exec/resume startup checks passed. Evidence: `.context/evidence/worker-reply-resume/`. +A further bottle delivery check used the real Codex agent to inspect the retained inputs, +launch one detached `package_people` stage, end its turn, and resume when packaging finished. +The stage completed in 78.3 seconds; the agent read its result and requested viewer review. +The live admin showed one successful attempt and distinguished five saved-input stages from +fresh execution. All 240 animated person frames, room, object assets, original audio, and +presentation matched the prior delivery. Camera/source URLs correctly named the new run. +Browser checks loaded both people, enabled the original soundtrack, advanced playback, reached +frame 119 at 9.93 seconds, wrapped to frame zero, and moved beyond the room without an edge +fade. No console errors were observed. The supervisor stopped and the run was paused. +This was the explicitly requested fifth packaging execution after four successful delivery +checks, with no automatic retry, provider commands, paid-ledger change, or quality acceptance. +It joins actual agent control to retained packaging and viewer delivery; fresh reconstruction +and headset behavior remain unverified. Evidence: `.context/evidence/bottle-agent-delivery/`. + Regression tests cover questions arriving before stage/agent launch, blocked watchdog resumes, retained transcript/session evidence, and answers arriving between a turn's final journal read and the supervisor's next pass. Quiet turns do not repeatedly wake on their own status notes. diff --git a/scripts/run_clip.py b/scripts/run_clip.py index 18aea97..dfdb21f 100644 --- a/scripts/run_clip.py +++ b/scripts/run_clip.py @@ -3077,8 +3077,8 @@ def valid_report(value): "--threshold", str(a.cut_threshold), ] - if a.shot is not None or a.all_shots: - cmd.append("--no-score") # the choice is already made; do not pay to rank + if no_score: + cmd.append("--no-score") # chosen shots and reject-only checks do not need ranking say("cut check: looking for cuts before anything is spent") try: p = subprocess.run( diff --git a/scripts/tests/test_run_clip_cut_cache.py b/scripts/tests/test_run_clip_cut_cache.py index 2c639c5..0f79bbe 100644 --- a/scripts/tests/test_run_clip_cut_cache.py +++ b/scripts/tests/test_run_clip_cut_cache.py @@ -61,13 +61,14 @@ def restore(self): run_clip.ROOT = self.old_root self.temp.cleanup() - def args(self, threshold=0.1, shot=None, all_shots=False): + def args(self, threshold=0.1, shot=None, all_shots=False, reject_cuts=False): return SimpleNamespace( clip=str(self.clip), name="same-run", cut_threshold=threshold, shot=shot, all_shots=all_shots, + reject_cuts=reject_cuts, ) def cache_path(self): @@ -133,6 +134,18 @@ def test_score_mode_change_same_threshold_misses(self): self.assertEqual(len(self.calls), 2) self.assertIn("--no-score", self.calls[-1]) + def test_reject_cuts_skips_ranking_and_matches_its_cached_detector_args(self): + with patch.object(run_clip.subprocess, "run", side_effect=self.fake): + run_clip.cut_check(self.args()) + result = run_clip.cut_check(self.args(reject_cuts=True)) + cached = run_clip.cut_check(self.args(reject_cuts=True)) + self.assertEqual(len(self.calls), 2) + self.assertNotIn("--no-score", self.calls[0]) + self.assertIn("--no-score", self.calls[1]) + self.assertIn("--no-score", result["_cacheKey"]["detectorArgs"]) + self.assertFalse(result["continuous"], "skipping ranking must retain cut detection") + self.assertEqual(result, cached) + def test_detector_key_change_misses(self): with patch.object(run_clip.subprocess, "run", side_effect=self.fake): run_clip.cut_check(self.args())