You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: enhance crew integration checks and recovery mechanisms
- Improved handling of interrupted checks in CrewMergeJournal, including detailed execution states and outputs.
- Added functionality to reconcile check executions and validate applied checkouts post-crash.
- Introduced a new prompt mechanism for handling stale bridges in crew lanes, allowing for retries and recovery.
- Updated UI components to reflect the state of integration checks and custody halts more clearly.
- Added tests for new functionalities, including check process liveness and custody scope validation.
Copy file name to clipboardExpand all lines: docs/behavioral-merge-review.md
+3-1Lines changed: 3 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -35,7 +35,9 @@ The sidebar reports the result as a **candidate decision**, not as whether CrewC
35
35
36
36
The main process atomically persists a merge journal under CrewCode's user-data directory before combination begins and at every phase transition. Each record contains the session, base branch/SHA, lane label, branch, worktree path, owned files and SHA, current phase, discovered check commands, outputs, status, and timestamps.
37
37
38
-
After restart, an in-flight operation is shown as `interrupted` instead of implying that its process survived. Any running check is likewise marked interrupted. A candidate that had already passed is reconciled against Git; moved base/lane/ref inputs make it stale. If CrewCode stopped while applying but the base now equals the retained integration SHA, reconciliation records the operation as applied. The base is never inferred to be updated merely because a subprocess had started.
38
+
After restart, an in-flight operation is shown as `interrupted` instead of implying that it completed. Every check process receives a random custody token plus a persisted local PID or remote PID file. Restart reconciliation probes the PID and verifies the token through the process environment where the operating system exposes it, reporting `running`, `exited`, or `unknown` rather than treating a reused PID as evidence. A still-running or unresolved interrupted check blocks another verification run. Platforms that do not expose enough process identity evidence remain `unknown` and require manual resolution; CrewCode does not guess that the process exited.
39
+
40
+
A candidate that had already passed is reconciled against Git; moved base/lane/ref inputs make it stale. If CrewCode stopped while applying and the base ref now equals the retained integration SHA, that SHA alone is not sufficient evidence of success. Reconciliation also requires `HEAD` to be attached to the expected base branch at the exact integration commit, a clean index and worktree (including untracked files), and no remaining `MERGE_HEAD`. Only then is the operation recorded as applied; otherwise it remains interrupted with the failed checkout/index invariant shown in the sidebar. The base is never inferred to be updated merely because a subprocess had started.
39
41
40
42
Crew session ownership is also persisted locally. Each lane has an explicit **enabled / paused** switch and an editable **next action** checkpoint, automatically seeded from its latest assignment. Pausing stops the lane runtime but retains its worktree, transcript, and checkpoint; resuming does not auto-submit work. Process-local bridge and terminal IDs are cleared on recovery, lanes that previously said `running` recover as `ready`, and persisted pause/checkpoint state remains visible. The UI never claims an agent process survived without evidence.
Copy file name to clipboardExpand all lines: docs/current-state.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -24,7 +24,7 @@ Supervisor reporting is incremental, not batched: `useCrewSupervisor` feeds each
24
24
25
25
Task distribution (`session.distribution`, default `split`) is a live header toggle separate from `mode`. `split` = each worker gets a distinct sub-task: the supervisor's per-turn run-selection snapshot carries `distributionDirective()`, and `validateDirectivePolicy()` hard-blocks `"to":"all"`, targets that resolve to multiple workers, unavailable/skipped targets, and exact duplicate task text before dispatch. No-supervisor shared mode renders one composer per worker in `CrewTimeline`, and split timeline rounds show each lane's own prompt inside that lane card rather than collapsing to one shared prompt. `broadcast` = same message to all (`handleBroadcast`) and the supervisor may use `"to":"all"`. `set_distribution` is legal at any phase, so it can flip mid-run.
26
26
27
-
Crew control stops are scoped intentionally: `stop all` in `CrewSurface` aborts every runtime, the supervisor composer stop button calls `abortSupervisor()` only, and lane composer stop buttons call `restartLane()` for that lane only. The per-lane enabled/paused switch is durable: pausing releases that runtime while retaining the worktree, transcript, and editable `nextAction`; every assignment seeds the checkpoint, restart recovery preserves it, and supervisor status snapshots include paused lanes without making them delegation targets. The supervisor sidebar width is local UI state in `CrewSurface` and is resized with the shared `Splitter`; the supervisor thread also has a scroll-to-bottom affordance. Shared timeline lane groups (`crew-lane-group`) are locally collapsible with chevrons so dense multi-agent rounds remain scannable. Every direct lane composer lazily supports `@` file search scoped to that lane's effective worktree/base path and auto-grows from one line to a bounded 220px before scrolling.
27
+
Crew control stops are scoped intentionally: `stop all` in `CrewSurface` aborts every runtime, the supervisor composer stop button calls `abortSupervisor()` only, and lane composer stop buttons call `restartLane()` for that lane only. A lane stop must release bridge runtimes through `useBridgeRegistry.dropBridge()` rather than raw stop IPC so the cached `(tab, agent)` id is removed; lane prompt dispatch also replaces and retries a `bridge not found` runtime once, re-priming the replacement before sending. The per-lane enabled/paused switch is durable: pausing releases that runtime while retaining the worktree, transcript, and editable `nextAction`; every assignment seeds the checkpoint, restart recovery preserves it, and supervisor status snapshots include paused lanes without making them delegation targets. The supervisor sidebar width is local UI state in `CrewSurface` and is resized with the shared `Splitter`; the supervisor thread also has a scroll-to-bottom affordance. Shared timeline lane groups (`crew-lane-group`) are locally collapsible with chevrons so dense multi-agent rounds remain scannable. Every direct lane composer lazily supports `@` file search scoped to that lane's effective worktree/base path and auto-grows from one line to a bounded 220px before scrolling. Combined-check processes carry durable custody tokens and PID evidence; restart reconciliation reports them as running, exited, or unresolved and gates a replacement verification accordingly. A crash during apply is called applied only after validating the attached base checkout, exact HEAD, clean index/worktree, and absence of unfinished merge state.
28
28
29
29
Isolated crew review treats clean Git merges as unverified. Cross-lane Diff shows branch/commit ownership, runtime state, exact file overlap, and narrow cross-file contract heuristics; the crew merge sidebar requires explicit acknowledgment when signals exist. Crew sessions persist locally so restart retains lane/worktree provenance while clearing process-local runtime ids. Compare/Merge Git fetches are keyed to a stable ownership fingerprint rather than the once-per-second runtime/usage updates, preventing loaded review evidence from flashing back to a loading state. A merge audit is written before Git starts and recovers a leftover `running` operation as `interrupted`. After a clean merge, the sidebar discovers and visibly presents allowlisted package `typecheck`/`test` scripts; main runs only those discovered ids with `CI=1`, and persists pass/fail/interrupted evidence for local and SSH workspaces. See `docs/behavioral-merge-review.md`.
Copy file name to clipboardExpand all lines: docs/execution-custody.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,5 +1,7 @@
1
1
# Execution Custody
2
2
3
+
> Scope: interactive halt-and-reauthorize custody is enabled for synthetic crew lane threads only. Ordinary solo chats and the crew supervisor use their normal provider error/retry behavior and do not receive custody-loss banners or gates.
4
+
3
5
> Status: living document. `docs/security-model.md` covers **granting** authority —
4
6
> whether it may cross the next boundary. This document covers **withdrawing** it:
5
7
> what happens when authority that was already granted stops being knowable while
0 commit comments