ace-overseer 0.28.1 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -0
  3. data/README.md +2 -2
  4. data/docs/getting-started.md +1 -1
  5. data/docs/usage.md +47 -25
  6. data/handbook/workflow-instructions/overseer/bootstrap-delegation.wf.md +224 -37
  7. data/handbook/workflow-instructions/overseer/lab-start.wf.md +49 -21
  8. data/handbook/workflow-instructions/overseer/queue.wf.md +13 -8
  9. data/handbook/workflow-instructions/overseer/start.wf.md +198 -21
  10. data/lib/ace/overseer/atoms/observation_sources.rb +17 -0
  11. data/lib/ace/overseer/atoms/start_contract.rb +20 -0
  12. data/lib/ace/overseer/cli/commands/handoff.rb +4 -0
  13. data/lib/ace/overseer/cli/commands/process_reports.rb +4 -2
  14. data/lib/ace/overseer/cli/commands/start.rb +37 -5
  15. data/lib/ace/overseer/cli/commands/work_on.rb +6 -2
  16. data/lib/ace/overseer/cli.rb +2 -0
  17. data/lib/ace/overseer/molecules/coworker_launcher.rb +189 -0
  18. data/lib/ace/overseer/molecules/event_observation.rb +54 -19
  19. data/lib/ace/overseer/molecules/eyes_evidence.rb +103 -0
  20. data/lib/ace/overseer/molecules/eyes_readiness.rb +21 -0
  21. data/lib/ace/overseer/molecules/eyes_session_evidence.rb +132 -0
  22. data/lib/ace/overseer/molecules/hitl_inbox.rb +13 -5
  23. data/lib/ace/overseer/molecules/local_sources.rb +83 -19
  24. data/lib/ace/overseer/molecules/project_bundle.rb +1 -1
  25. data/lib/ace/overseer/molecules/project_observations.rb +82 -0
  26. data/lib/ace/overseer/molecules/project_sessions.rb +99 -0
  27. data/lib/ace/overseer/molecules/remote_sources.rb +46 -16
  28. data/lib/ace/overseer/molecules/session_environment.rb +126 -0
  29. data/lib/ace/overseer/organisms/handoff_orchestrator.rb +26 -15
  30. data/lib/ace/overseer/organisms/report_processor.rb +42 -10
  31. data/lib/ace/overseer/organisms/start_orchestrator.rb +105 -55
  32. data/lib/ace/overseer/organisms/work_on_orchestrator.rb +43 -1
  33. data/lib/ace/overseer/version.rb +1 -1
  34. data/lib/ace/overseer.rb +2 -1
  35. metadata +64 -2
@@ -6,8 +6,8 @@ doc-type: workflow
6
6
  title: Lab Overseer Start Guide
7
7
  purpose: Define the lab overseer's coordination role across projects — readiness aggregation, cross-project escalation, delegation to project overseers — without taking over any project's tasks or private state.
8
8
  ace-docs:
9
- last-updated: '2026-10-30'
10
- last-checked: '2026-10-30'
9
+ last-updated: '2026-11-04'
10
+ last-checked: '2026-11-04'
11
11
  ---
12
12
  # Lab Overseer Start Guide
13
13
 
@@ -31,18 +31,28 @@ project overseer cannot start yet. Do not edit project configuration, install
31
31
  packages or run repair commands yourself. Missing workers are a concrete
32
32
  capability gap, not a reason to become the worker.
33
33
 
34
+ Do not run `ace-lab verify`, `ace-lab install`, `ace-lab prepare`, or search
35
+ package source to diagnose bootstrap readiness. Commission those checks and
36
+ any repairs to the bootstrap worker. An unknown readiness result is enough
37
+ reason to delegate, not a reason to investigate before creating the task.
38
+
34
39
  ## First turn after start
35
40
 
36
- `ace-overseer start` is the bootstrap entry point. It launches your Pi
37
- process directly in the current terminal and directory, with this Lab role
38
- and context. It performs no Herdr agent, owner or layout preflight. A missing `.ace/overseer/config.yml` is first-run setup, not a request
39
- for the Captain to write YAML. The packaged bootstrap profile is
40
- `pi`, `zai/glm-5.3-flash`, thinking `high`; explicit profiles take precedence
41
- and an invalid explicit configuration never silently falls back.
41
+ On a configured lab host, `ace-overseer start` selects the lab or project from
42
+ its canonical directory and starts an ordinary Pi process with an explicit environment through native Herdr.
43
+ The protected host deployment selects the installed runtime and standing role;
44
+ project files do not select a different runtime. A start acknowledgement means
45
+ admission or prompt submission, not completed readiness. Readiness requires the
46
+ first turn and active eyes. Repeating start preserves an existing owner and
47
+ does not repeat an uncertain first prompt.
48
+
49
+ A missing project configuration is work to commission to a worker, not a request
50
+ for the Captain to write YAML. Missing protected runtime or host authority is a
51
+ concrete host blocker; never replace it with a project bundle or source checkout.
42
52
 
43
53
  The Captain's latest instruction outranks this guide and stored tasks or plans.
44
- On this first turn, commission any missing configuration and project
45
- preparation through workers before resuming unrelated stored backlog. Read old
54
+ After first-turn observation is ready, prioritize missing configuration and
55
+ project preparation through workers before unrelated stored backlog. Read old
46
56
  `_overseer` tasks as context; do not dispatch old auth, publication or full
47
57
  acceptance work while the current instruction is bootstrap and project start.
48
58
  Report scope conflicts to the host operator instead of negotiating away a new
@@ -51,35 +61,53 @@ Captain order.
51
61
  1. Read the lab topology, current private tasks and real assignment/session
52
62
  state. Resume this commissioned bootstrap before unrelated backlog. Resolve
53
63
  actual project paths; ask only about ambiguous scope or missing authority.
54
- 2. Read `wfi://overseer/bootstrap-delegation` through `ace-bundle` and follow
55
- its complete task → worker → observation → verification → start procedure.
64
+ 2. Read `wfi://overseer/bootstrap-delegation` through `ace-bundle` to understand
65
+ the task → worker → observation → verification → start procedure. Do not
66
+ dispatch during this initialization turn.
56
67
  3. Arm observation with the `ace_eyes` tool, action `start`, using the lab's
57
68
  eyes configuration path. Check enabled=true, breaker=null, errors=0 and
58
- a successful observation before dispatch. A missing tool/configuration is
59
- a readiness gap. Writing `/eyes` in prose does not arm observation.
60
- 4. For a preparation commission, read existing readiness/session state; use
69
+ a successful observation with every required source healthy before dispatch.
70
+ A missing tool/configuration or degraded source is a blocking readiness gap.
71
+ Record the returned error through the existing task/HITL owner and end this
72
+ turn; if that owner is unavailable, report its failure and end the turn.
73
+ Do not inspect host files or probe transport to find the cause yourself.
74
+ Writing `/eyes` in prose does not arm observation.
75
+ 4. Once observation is healthy, END THIS TURN. Do not dispatch or process
76
+ pending reports yet. Leave initial revisions pending so eyes can wake you
77
+ after the completed first turn proves readiness. This avoids requiring a
78
+ completed first turn from inside that same turn.
79
+
80
+ ## On an eyes wake or a new commission
81
+
82
+ Verify that every required observation source is healthy; otherwise record the
83
+ blocker and end the turn. Reconcile existing work before dispatching new work.
84
+
85
+ 1. For a preparation commission, read existing readiness/session state; use
61
86
  a startup dry run only if needed to establish an otherwise unknown status.
62
87
  Do not investigate its implementation or reproduce the failure yourself.
63
88
  Once the symptom is known, create/reconcile the task and dispatch its
64
89
  worker. Run `ace-overseer start --reconcile` for that commission only after
65
90
  accepted worker completion and independent verification. Bare
66
- `ace-overseer start` launches a foreground harness; never call it
67
- recursively from your own session.
68
- 5. After dispatch, record the real assignment and agent identity and END YOUR
91
+ `ace-overseer start` targets the calling scope; do not recursively start
92
+ your own coordinator. Use the returned project session identity.
93
+ 2. After dispatch, record the real assignment and agent identity and END YOUR
69
94
  TURN. Do not sleep-poll, run repeated status commands, or wait synchronously
70
95
  for the worker. A semantic change wakes you; unchanged state stays silent.
71
96
 
72
97
  ## Delegation and escalation
73
98
 
74
99
  - Route goals to a project by working through THAT project's overseer (its
75
- session is labeled `overseer-<project-root>`); you do not dispatch its
100
+ session identity is returned by start and native Herdr); you do not dispatch its
76
101
  coworkers directly for product work. Lab bootstrap workers are the explicit
77
102
  exception: they prepare a commissioned project whose overseer cannot start.
78
103
  - Cross-project blockers (shared forge access, missing host capability, a
79
104
  project repeatedly failing) escalate to the Captain through `ace-hitl`
80
105
  with the per-project evidence.
81
- - One project's failure never blocks the healthy ones: keep their work
82
- flowing and report the failure separately.
106
+ - A project failure observed through healthy sources does not block healthy
107
+ projects: keep their work flowing and report that project failure separately.
108
+ Failure of a required observation source is different: apply the observation
109
+ health gate, record the blocker and end the turn before processing reports
110
+ or dispatching more work.
83
111
 
84
112
  ## Boundaries
85
113
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: overseer-queue
3
- description: Run the private overseer queue in .ace-tasks/_overseer with ace-task --in _overseer - record work as managing tasks with lifecycle subtasks, gate starts on integrated results, keep one active executor per worktree, and process ace-hitl reports
3
+ description: Run the private overseer queue in .ace-tasks/_overseer with ace-task list --in _overseer - record work as managing tasks with lifecycle subtasks, gate starts on integrated results, keep one active executor per worktree, and process ace-hitl reports
4
4
  allowed-tools: Bash, Read
5
5
  doc-type: workflow
6
6
  title: Overseer Queue Workflow
@@ -15,7 +15,7 @@ ace-docs:
15
15
  ## Goal
16
16
 
17
17
  Coordinate delegated work exclusively through the overseer's private task tree
18
- in `.ace-tasks/_overseer/` (gitignored, managed via `ace-task --in _overseer`),
18
+ in `.ace-tasks/_overseer/` (gitignored, managed via `ace-task list --in _overseer`),
19
19
  existing subtasks/dependencies, and `ace-hitl` reports tied to a concrete step.
20
20
  The tree decides order, dependencies, and assignments. There is no second queue
21
21
  engine: no daemon, no journal, no state cache, no lease registry, and no
@@ -147,11 +147,10 @@ Worker finishes → reviewer starts → integrator starts, in the same worktree:
147
147
  when every earlier leg reached assignment state `completed` and no
148
148
  executor holds the worktree. A busy, in-flight, failed, or unreadable
149
149
  predecessor refuses with reasons; unknown state is never a free resource.
150
- On success it opens the next executor's window in the same worktree and
151
- prints `ace-coworker start --config .ace-local/coworker/prepare/<role>.yml`
152
- -- the next role starts from the existing start config, nothing is
153
- re-prepared. `--dry-run` checks without effects. Use it before every
154
- dispatch into a worktree that already served a previous role.
150
+ With `--runtime herdr`, success starts the actual next executor from the
151
+ existing start config and records its native identity. The accepted report
152
+ retires the preceding process before this handoff. `--dry-run` checks without
153
+ effects; a printed brief or dry-run result is not proof of a running agent.
155
154
 
156
155
  - Two different tasks may run in parallel in two different worktrees; one
157
156
  worktree never has two active executors.
@@ -178,7 +177,13 @@ When a report arrives (ace-hitl event or message):
178
177
  4. After an interruption between recording a result and the next allocation,
179
178
  resume by re-reading the task tree and the real worktree/assignment state.
180
179
 
181
- `ace-overseer process-reports` executes rules 1-3 mechanically: it matches
180
+ `ace-overseer process-reports --owner <configured-recipient>` uses the same
181
+ recipient as your eyes observer (default `overseer`). Set `--scope current|all`
182
+ to match an explicit observation scope; without it, HITL uses all linked
183
+ worktrees in the canonical checkout and current scope inside a task worktree.
184
+ Never process another
185
+ coordinator's reports; use the address configured for this commission. It
186
+ executes rules 1-3 mechanically: it matches
182
187
  each incoming event (assignment recorded on a step, or the managing task's
183
188
  project_task with exactly one explicitly allocated `role=planner` non-terminal
184
189
  step having no assignment). Task and any supplied role must agree; an event
@@ -6,8 +6,8 @@ doc-type: workflow
6
6
  title: Project Overseer Start Guide
7
7
  purpose: Define the started project overseer's role boundaries, observation and delegation loop, HITL escalation, and completion semantics; the overseer coordinates and never substitutes for a missing coworker.
8
8
  ace-docs:
9
- last-updated: '2026-10-30'
10
- last-checked: '2026-10-30'
9
+ last-updated: '2026-11-06'
10
+ last-checked: '2026-11-06'
11
11
  ---
12
12
  # Project Overseer Start Guide
13
13
 
@@ -21,14 +21,30 @@ a missing coworker — you report the gap and escalate.
21
21
 
22
22
  ## First turn after start
23
23
 
24
- 1. Read your private task list: `ace-task --in _overseer list` (your
25
- coordination tasks live there; you own them).
26
- 2. Read project truth from the state owners — never a second cache:
27
- `ace-task list`, `ace-overseer status`, `ace-git-worktree list`,
28
- `git status --short`, and pending escalations with `ace-hitl list`.
29
- 3. Continue EXISTING commissioned work before choosing anything new.
30
- 4. When the lists are empty and no report awaits processing: record that state
31
- and remain idle. Silence is a correct state; do not invent work.
24
+ Execute these steps in order; the same order applies after a restart.
25
+
26
+ 1. Call `ace_eyes` with action `start` and `configPath` pointing to
27
+ `<project>/.ace-local/overseer/eyes.json`. Check the returned state:
28
+ enabled=true, breaker=null, errors=0, and every required source healthy.
29
+ 2. If observation is missing, invalid or degraded, record the exact error
30
+ through the existing task/HITL owner and END THIS TURN. Do not process
31
+ pending reports, acknowledge their revisions or dispatch work in this
32
+ branch. If the owner is also unavailable, report that failure and end.
33
+ 3. Once observation is healthy, end this first turn. Leave pending revisions
34
+ untouched so eyes can deliver them when the session is idle. Readiness
35
+ can then be verified independently of backlog processing.
36
+
37
+ ## On an eyes wake or a new commission
38
+
39
+ Verify that required sources are healthy before processing work. Read the
40
+ affected state from its owner, including private coordination tasks with
41
+ `ace-task list --in _overseer` when relevant. Reconcile existing commissioned
42
+ work and pending reports before selecting new work. Acknowledge each revision
43
+ only after its task or assignment owner accepted it. Use the issue and task
44
+ dependencies to select ready work. Advance independent ready tasks in
45
+ separate worktrees while other tasks await reports, tests or approvals. Keep
46
+ one active executor per worktree. Record a concrete prerequisite or conflict
47
+ when it blocks a task. End the turn with eyes armed.
32
48
 
33
49
  ## Delegation
34
50
 
@@ -42,26 +58,161 @@ a missing coworker — you report the gap and escalate.
42
58
  - Merge gate: executed tests plus an independent reviewer verdict. CI is
43
59
  advisory.
44
60
 
61
+ A release held in the queue stays open after its prerequisites merge.
62
+ Record readiness in the coordination task. Wait for a separate explicit
63
+ release commission before dispatching release work or closing its issue.
64
+
65
+ ### Bind reports to the commissioning coordinator
66
+
67
+ Before preparing any leg, read `recipient` from your armed eyes configuration
68
+ (`<project>/.ace-local/overseer/eyes.json`) and resolve it through this project's
69
+ HITL configuration. Pass that recipient explicitly on every preparation:
70
+
71
+ ```bash
72
+ ace-coworker prepare --task <task-ref> --roles worker,reviewer,integrator --to <your-observed-recipient> --format json
73
+ ```
74
+
75
+ The roles must match the commissioned task. Read each returned start config
76
+ from its execution worktree and verify that `overseer` resolves to the same
77
+ address that your eyes observes before dispatching. A missing or mismatched
78
+ address blocks dispatch; report it through HITL. Do not inherit a bootstrap
79
+ worker's `lab-overseer` recipient for work commissioned by the project Overseer.
80
+ Lab bootstrap reports belong to the Lab Overseer; project delivery reports
81
+ belong to the project Overseer. Keep that recipient through reviewer and
82
+ integrator handoffs so each result reaches the coordinator that owns the work.
83
+
84
+ ### Launching a coworker
85
+
86
+ Use `ace-overseer work-on --task <project-task> --runtime herdr` for a new
87
+ ordinary delivery sequence. It prepares the worktree and role assignments,
88
+ validates the brief, starts the actual worker and records its native identity.
89
+ For an already prepared sequence (including bootstrap), use
90
+ `ace-overseer handoff --task <project-task> --runtime herdr`. Without
91
+ `--dry-run`, handoff starts the next eligible role; the returned execution
92
+ binding is evidence of a start, not merely an opened window.
93
+
94
+ The environment is prepared from the installed runtime and the selected
95
+ project/role credential source. A role has its own process and worktree;
96
+ OS users, systemd units and an authorization service are not prerequisites.
97
+ `ace-coworker start` still renders a brief; do not mistake its output for a
98
+ running agent or write a second launch script around it.
99
+
100
+ Record returned assignment, worktree, terminal and role on the matching
101
+ private coordination step, then END THE TURN. Eyes observes the result.
102
+ On replay, reconcile the recorded execution. An uncertain launch blocks a new
103
+ start; never invent another name to bypass it. A missing observer, runtime or
104
+ credential source is a concrete blocker to report, not a repair for you to do.
105
+
106
+ After accepting the worker report, `process-reports` retires that executor
107
+ and uses the same handoff operation for independent review, then integration.
108
+ Executed tests and independent review must bind to the current candidate HEAD.
109
+
110
+ For delivery from a forge issue, retain the issue link on the project task
111
+ and include its repository, target branch and forge selection in each
112
+ commission. A generic success event is a pointer to assignment evidence.
113
+ Read the exact worker assignment's step reports and inspect the existing PR
114
+ for its branch through the configured forge before deciding that publication
115
+ is missing. Match repository, head branch, base branch and tested HEAD. A
116
+ missing or mismatched PR keeps review pending. Before dispatching the worker,
117
+ verify the assignment has a final `publish-pr` step. If a project override
118
+ omitted it, add it through `ace-assign`. If the worker already completed the
119
+ assignment without publication, add the missing step and reconcile its
120
+ existing session. The worker finishes the step with the verified PR and
121
+ then reports its new outcome. Repeating the old report cannot signal that
122
+ publication finished.
123
+
124
+ Pass the verified PR and tested HEAD to the reviewer. Before dispatch for
125
+ a forge issue, verify the reviewer's assignment has a final
126
+ `publish-approval` step. Add it through `ace-assign` if a project override
127
+ omitted it. The step finishes only with the formal
128
+ receipt recorded alongside the tests. For a forge issue,
129
+ local review acceptance alone leaves the integration leg pending. Require
130
+ the reviewer's formal approval receipt for that PR, verify it against the
131
+ current forge HEAD and the executed tests, and reconcile missing or stale
132
+ approval with the reviewer. If the reviewer prematurely completed the
133
+ assignment, add the missing step to that assignment and reconcile its
134
+ existing session. Ask it to finish that step with the verified receipt.
135
+ A repeated success report for an unchanged assignment may reuse its event.
136
+ The integrator receives the same PR, the verified
137
+ receipt, the tested HEAD and the allowed merge method. Use a merge commit when
138
+ the forge permits it and the project has no other configured preference.
139
+ Immediately add the returned terminal and agent to the private coordination
140
+ leg as structured task fields, including for one-off commissions:
141
+
142
+ ```bash
143
+ ace-task update <coordination-step> --set assignment=<id> --set worktree=<path> --set terminal=<returned-terminal> --set agent=<returned-agent>
144
+ ```
145
+
146
+ Cancel it when the pinned assignment has an active step or a report.
147
+ When an executor observation lists the recorded terminal in
148
+ `missing_sessions`, the deadline fires, or a blocked transport recovers,
149
+ check Herdr and the pinned assignment. If dispatch did not return a terminal,
150
+ use `herdr agent list` to find the unique assignment-labelled agent with the
151
+ expected worktree and recorded role. Record its full `term_…` ID. Use that
152
+ ID with `herdr agent get` and `herdr agent prompt` for recovery.
153
+ Pane indexes such as `p5` are display identifiers.
154
+ For a permitted recovery, submit `herdr agent prompt <terminal> "<text>"`.
155
+ The guarded route accepts the terminal and text only. Use eyes for the
156
+ resulting change and end the turn after recording the submission.
157
+
158
+ At the startup deadline, reconcile any uncertain dispatch acknowledgement.
159
+ If the exact session is still idle, interactive-ready, has no
160
+ completed turn, and the pinned assignment has no activity or report, record
161
+ one recovery attempt before sending the original commission to that same
162
+ terminal. The commission must still name that exact assignment and role.
163
+ Never submit a second dispatch or prompt a session that has begun work.
164
+ After confirmed recovery delivery, arm one follow-up deadline
165
+ `dispatch-recovery-<id>` with the same assignment revision and a fresh
166
+ 300000-millisecond window. Cancel it on assignment activity or a report.
167
+ If it expires without progress, escalate. Do not rearm it.
168
+ If delivery stays uncertain, the session is missing, or the binding is
169
+ ambiguous, record the blocker and escalate through HITL. Do the same when
170
+ delivery was confirmed but the assignment still has no activity at the
171
+ deadline. Keep the unfinished assignment pending or blocked. Reconcile
172
+ reports through their owners before acknowledging events.
173
+
45
174
  ## Escalation (HITL)
46
175
 
47
176
  - Decisions outside your granted autonomy go to the Captain:
48
177
  `ace-hitl create` with a precise question, then end your turn armed for the
49
178
  wake. Blocking wait is an emergency path only.
50
- - Answers return through the same case; apply them once and close the case.
179
+ - On an answered-case wake, read the exact case with `ace-hitl show CASE`.
180
+ Check its application record and the effect owner's state. If the effect
181
+ is already recorded for this case, reuse that evidence without repeating
182
+ the operation. Otherwise apply the decision once and record the case ID
183
+ and effect through the task, assignment or forge owner.
184
+ - After verifying the effect, record it with
185
+ `ace-hitl apply CASE --ref OWNER_REF` (for example `task:<task-id>`), then
186
+ run `ace-hitl close CASE` and verify closure. The answer being received
187
+ does not record an effect. A closed case needs no further action on
188
+ redelivery. Acknowledge the answered revision after closure or after
189
+ recording a concrete blocker through the existing owner.
51
190
 
52
191
  ## Standing observation
53
192
 
54
- After start, arm `/eyes` with the project's eyes configuration (interval 15s is
55
- the default reconcile cadence). `ace-overseer observe` — what eyes polls —
56
- projects the six local source classes from their owners: project tasks,
193
+ After start, call the `ace_eyes` tool with action `start` and `configPath`
194
+ pointing to `<project>/.ace-local/overseer/eyes.json` (interval 15s is the default
195
+ reconcile cadence). Verify enabled=true, breaker=null, errors=0 and a successful
196
+ observation with every required source healthy. A degraded source blocks
197
+ report processing and new dispatch: record its returned error through the existing task/HITL owner
198
+ and end the turn. If that owner is also unavailable, report its failure and
199
+ end the turn. Do not investigate implementation or host transport yourself.
200
+ Writing `/eyes` in prose does not arm observation. If the configuration is
201
+ missing or invalid, record or escalate that precise blocker and end the turn;
202
+ do not dispatch work without observation or create/edit the configuration yourself. `ace-overseer observe` — what eyes polls —
203
+ projects local source classes from their owners: project tasks,
57
204
  private `_overseer` tasks, worktrees, coworker availability (existing run
58
- identifiers, never pane names), assignment progress and HITL events. A real
205
+ identifiers, never pane names), assignment progress, configured project
206
+ session states and HITL events. A real
59
207
  revision wakes you once; identical state stays silent; a degraded source is
60
208
  visible data (`source-health` rows and the `sources` map), never an empty
61
- healthy list. After a restart, reconcile pending revisions first — a report
62
- that arrived in your absence surfaces as an unacknowledged revision — then
63
- choose work by the existing plan/dependency order (`ace-overseer
64
- process-reports`, `ace-overseer work-on`). Acknowledge (`/eyes ack KEY
209
+ healthy list. When a `source-health` revision reports recovery, check that all
210
+ required sources are healthy and reconcile work that was held by the fault.
211
+ Acknowledge the health revision after recording any required owner state.
212
+ After a restart, complete the first turn's observation health gate and end
213
+ the turn. A report that arrived in your absence surfaces as an unacknowledged
214
+ revision. On delivery, reconcile it and choose work by the existing plan/dependency order (`ace-overseer
215
+ process-reports` and the delegation procedure above). Acknowledge (`/eyes ack KEY
65
216
  REVISION`) only AFTER the proper task/assignment accepted the work: model
66
217
  settlement alone is not proof of handling.
67
218
 
@@ -70,10 +221,36 @@ settlement alone is not proof of handling.
70
221
  - One overseer per project: you own the session label you were started with.
71
222
  Another start reuses you; you never spawn a second whole-project overseer.
72
223
  - Access is limited to what the project configuration and the delegated task
73
- grant. Credentials and OTP values never enter prompts, reports, or files.
74
- - Remote PR observation (observe.remote.pull_requests) and the HITL reply
224
+ grant. Credentials and OTP values never enter prompts, reports or tracked
225
+ files. Configured credential files must remain private (`0600`).
226
+ When forge access is missing, do not search host credential stores or set up
227
+ a persistent `fj` login yourself. Request the existing session-scoped auth
228
+ handoff for the required role and repository using the procedure below; if
229
+ it is unavailable, create a precise HITL blocker and end the turn. Never ask a human
230
+ to paste a token or replace the lease with a durable shared credential.
231
+ - Remote issue and PR observation (`observe.remote.issues` and
232
+ `observe.remote.pull_requests`) and the HITL reply
75
233
  receiver (`ace-hitl reply CASE --stdin`) are delivered surfaces: watch the
76
234
  configured remote sources through them and report what you actually see.
77
235
  Capabilities genuinely not yet delivered (e.g. the Hermes transport
78
236
  producer on the host) are explicitly not available in this slice; do not
79
237
  simulate them. Missing capability is a reported gap, not a workaround.
238
+
239
+ ## Project-scoped forge access
240
+
241
+ The session starts with the selected project's read or role credential in its
242
+ environment or private provider config. Use that configured forge normally.
243
+ Continuous observation needs a read credential valid for the observer's
244
+ lifetime. An unavailable login is a visible configuration blocker; do not
245
+ read host administrator credentials or invent another login method.
246
+
247
+ When the deployment explicitly configures a temporary credential provider,
248
+ use the existing `ace-lab auth request/status/exec/revoke` procedure. These
249
+ commands run locally; they do not depend on a service. Request only the named
250
+ repository and role. `auth exec` gives its child the credential and reports
251
+ execution and cleanup separately. An unconfirmed revoke remains unresolved.
252
+ Static shared project credentials are not revoked when one worker exits.
253
+
254
+ Pass repository, role, scope and acceptance criteria in the commission,
255
+ never tokens. Workers implement, reviewers independently review, and
256
+ integrators merge; the coordinator never borrows those roles to do their work.
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ace
4
+ module Overseer
5
+ module Atoms
6
+ module ObservationSources
7
+ PROJECT_TASKS = "project_tasks"
8
+ OVERSEER_TASKS = "overseer_tasks"
9
+ WORKTREES = "worktrees"
10
+ COWORKERS = "coworkers"
11
+ HITL = "hitl"
12
+ PROJECT_SESSIONS = "project_sessions"
13
+ REQUIRED = [PROJECT_TASKS, OVERSEER_TASKS, WORKTREES, COWORKERS, HITL].freeze
14
+ end
15
+ end
16
+ end
17
+ end
@@ -7,6 +7,26 @@ module Ace
7
7
  # first-run profile when no start section exists. A malformed explicit
8
8
  # configuration never falls back to another model or harness.
9
9
  class StartContract
10
+ FIRST_TURN_PROMPT = <<~PROMPT.chomp
11
+ Begin your first turn now. Execute the "First turn after start"
12
+ protocol in your standing instructions in its listed order.
13
+ Arm observation with the ace_eyes tool, action start, using configPath
14
+ set to your configured eyes path.
15
+ Report reconciliation and new dispatch both require a successful
16
+ observation with every required source healthy. If observation is
17
+ unavailable or degraded, record its exact error through the existing
18
+ task/HITL owner and END THIS TURN without processing pending reports.
19
+ If that owner is unavailable, report its failure and end the turn.
20
+ When observation is healthy, follow the role's first-turn protocol
21
+ through its stopping point. When that protocol calls for work,
22
+ reconcile existing commissions before choosing new work and
23
+ acknowledge revisions only after their owner accepted them.
24
+ Do not diagnose implementation, inspect host
25
+ credential stores, probe transports or repeat status/help commands.
26
+ Installation, configuration and diagnosis belong to workers.
27
+ End the turn after delegation; remain idle when there is no work.
28
+ PROMPT
29
+
10
30
  SCOPES = %w[project lab].freeze
11
31
  SECTION_KEYS = %w[scope profile instructions].freeze
12
32
  PROFILE_KEYS = %w[harness model thinking].freeze
@@ -50,6 +50,10 @@ module Ace
50
50
  end
51
51
 
52
52
  next_leg = result[:next]
53
+ if result[:execution]
54
+ puts "Executor #{result[:execution]['agent']} started for #{next_leg['assignment']}. End the turn; eyes observes its report."
55
+ return
56
+ end
53
57
  unless next_leg && next_leg["start_config"]
54
58
  raise Ace::Support::Cli::Error,
55
59
  "handoff result is missing the next leg start config - refusing to print a guessed command"
@@ -9,6 +9,8 @@ module Ace
9
9
 
10
10
  desc "Process incoming ace-hitl reports and continue the overseer queue"
11
11
 
12
+ option :scope, type: :string, desc: "HITL scope: current or all (default: owner checkout scope)"
13
+ option :owner, type: :string, default: "overseer", desc: "Configured HITL recipient, matching the eyes observer"
12
14
  option :dry_run, type: :boolean, default: false, desc: "Interpret reports without writes or continuation"
13
15
  option :quiet, aliases: ["-q"], type: :boolean, default: false, desc: "Suppress non-essential output"
14
16
  option :debug, aliases: ["-d"], type: :boolean, default: false, desc: "Show debug output"
@@ -18,10 +20,10 @@ module Ace
18
20
  @processor = processor
19
21
  end
20
22
 
21
- def call(dry_run: false, **options)
23
+ def call(dry_run: false, owner: "overseer", scope: nil, **options)
22
24
  Atoms::RepoGuard.ensure_repo!
23
25
 
24
- processor = @processor || Organisms::ReportProcessor.new
26
+ processor = @processor || Organisms::ReportProcessor.new(owner: owner, scope: scope)
25
27
  result = processor.call(
26
28
  dry_run: dry_run,
27
29
  on_progress: options[:quiet] ? nil : ->(msg) { puts msg }
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "json"
4
+ require "shellwords"
4
5
 
5
6
  module Ace
6
7
  module Overseer
@@ -9,8 +10,8 @@ module Ace
9
10
  # `ace-overseer start [--dry-run] [--format table|json]`
10
11
  # (task 8xs.t.pu0.1): starts or reuses the project overseer
11
12
  # session from the directory's explicit start configuration.
12
- # Exit 0 only for started/reused (dry-run reports the plan with
13
- # exit 0 but creates nothing); a blocked start is a CLI error.
13
+ # Ready starts and dry runs exit 0; blocked or partial starts
14
+ # are CLI errors. A dry run creates no session.
14
15
  class Start < Ace::Support::Cli::Command
15
16
  include Ace::Support::Cli::Base
16
17
 
@@ -27,7 +28,7 @@ module Ace
27
28
  super()
28
29
  @orchestrator = orchestrator
29
30
  @config = config
30
- @launcher = launcher || ->(argv) { Kernel.exec(*argv) }
31
+ @launcher = launcher
31
32
  end
32
33
 
33
34
  def call(dry_run: false, format: "table", scope: nil, reconcile: false, **options)
@@ -45,7 +46,7 @@ module Ace
45
46
  else
46
47
  operation.bootstrap(dry_run: dry_run)
47
48
  end
48
- return @launcher.call(report.fetch("command")) if report["status"] == "foreground"
49
+ return launch_foreground(report) if report["status"] == "foreground"
49
50
 
50
51
  if options[:quiet]
51
52
  # quiet still fails loudly on a blocked start
@@ -55,11 +56,16 @@ module Ace
55
56
  render_table(report)
56
57
  end
57
58
 
59
+ if report["prompt_failed"] == true
60
+ raise Ace::Support::Cli::Error, report["message"] || "first turn or readiness is unconfirmed"
61
+ end
58
62
  case report["status"]
59
63
  when "started", "reused", "ready", "dry_run" then nil
60
64
  else
61
65
  raise Ace::Support::Cli::Error, report["message"] || "start blocked"
62
66
  end
67
+ rescue Interrupt
68
+ raise Ace::Support::Cli::Error.new("start interrupted; inspect existing sessions before retrying", exit_code: 130)
63
69
  rescue Ace::Support::Cli::Error
64
70
  raise
65
71
  rescue => e
@@ -68,6 +74,25 @@ module Ace
68
74
 
69
75
  private
70
76
 
77
+ def launch_foreground(report)
78
+ return @launcher.call(report.fetch("command")) if @launcher
79
+
80
+ role = report["scope"] == "lab" ? "lab-overseer" : "project-overseer"
81
+ directory = nil
82
+ Molecules::SessionEnvironment.new.with_environment(root: report.fetch("root"), role: role) do |path, credentials, _args|
83
+ directory = credentials
84
+ environment = JSON.parse(File.read(path))
85
+ system(environment, *report.fetch("command"), unsetenv_others: true)
86
+ status = $?
87
+ unless status&.success?
88
+ raise Ace::Support::Cli::Error.new("coordinator process exited unsuccessfully",
89
+ exit_code: status&.exitstatus || 1)
90
+ end
91
+ end
92
+ ensure
93
+ Molecules::SessionEnvironment.cleanup(directory) if directory
94
+ end
95
+
71
96
  def orchestrator(scope: nil)
72
97
  @orchestrator || Organisms::StartOrchestrator.new(config: @config || Ace::Overseer.config, scope: scope)
73
98
  end
@@ -83,9 +108,16 @@ module Ace
83
108
  end
84
109
  puts " workspace: #{report["workspace"] || "-"}"
85
110
  puts " pane: #{report["pane"] || "-"}"
86
- puts " agent: #{report["agent"]}"
111
+ puts " agent: #{report["agent"] || "-"}"
112
+ puts " command: #{Shellwords.join(report["command"])}" if report["command"]
87
113
  puts " replaced pane: #{report["replaced_pane"] || "-"}" if report["replaced_pane"]
88
114
  puts " #{report["message"]}" if report["message"]
115
+ Array(report["projects"]).each do |project|
116
+ status = project["status"] || "unknown"
117
+ status += " (first turn unconfirmed)" if project["prompt_failed"]
118
+ puts " project #{project["id"]}: #{status} (#{project["path"] || "-"}, pane: #{project["pane"] || "-"})"
119
+ puts " #{project["message"]}" if project["message"]
120
+ end
89
121
  end
90
122
  end
91
123
  end
@@ -37,7 +37,7 @@ module Ace
37
37
  end
38
38
 
39
39
  progress = options[:quiet] ? nil : ->(msg) { puts msg }
40
- @orchestrator.call(
40
+ result = @orchestrator.call(
41
41
  task_ref: task_refs.first,
42
42
  task_refs: task_refs,
43
43
  cli_preset: preset,
@@ -46,7 +46,11 @@ module Ace
46
46
 
47
47
  return if options[:quiet]
48
48
 
49
- puts "Done. Switch to tmux window and run /ace-assign-drive"
49
+ if result[:execution]
50
+ puts "Executor #{result[:execution]['agent']} started for #{result[:assignment_id]}. End the turn; eyes observes its report."
51
+ else
52
+ puts "Done. Switch to the task window and run /ace-assign-drive"
53
+ end
50
54
  rescue Ace::Support::Cli::Error
51
55
  raise
52
56
  rescue => e
@@ -20,6 +20,7 @@ module Ace
20
20
  PROGRAM_NAME = "ace-overseer"
21
21
 
22
22
  REGISTERED_COMMANDS = [
23
+ ["start", "Start the lab or project overseer"],
23
24
  ["work-on", "Start local task work"],
24
25
  ["handoff", "Hand the task worktree to the next role"],
25
26
  ["process-reports", "Process ace-hitl reports and continue the queue"],
@@ -31,6 +32,7 @@ module Ace
31
32
  ].freeze
32
33
 
33
34
  HELP_EXAMPLES = [
35
+ "ace-overseer start # Start in the current directory",
34
36
  "ace-overseer work-on 148 # Launch task in worktree",
35
37
  "ace-overseer handoff --task 148 # Hand the worktree to the next role",
36
38
  "ace-overseer process-reports # Interpret reports, continue the queue",