ace-overseer 0.28.0 → 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 (37) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -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 +258 -40
  7. data/handbook/workflow-instructions/overseer/lab-start.wf.md +60 -24
  8. data/handbook/workflow-instructions/overseer/queue.wf.md +33 -13
  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/report_interpretation.rb +28 -14
  12. data/lib/ace/overseer/atoms/start_contract.rb +20 -0
  13. data/lib/ace/overseer/cli/commands/handoff.rb +4 -0
  14. data/lib/ace/overseer/cli/commands/process_reports.rb +4 -2
  15. data/lib/ace/overseer/cli/commands/start.rb +37 -5
  16. data/lib/ace/overseer/cli/commands/work_on.rb +6 -2
  17. data/lib/ace/overseer/cli.rb +2 -0
  18. data/lib/ace/overseer/molecules/coworker_launcher.rb +189 -0
  19. data/lib/ace/overseer/molecules/event_observation.rb +54 -19
  20. data/lib/ace/overseer/molecules/eyes_evidence.rb +103 -0
  21. data/lib/ace/overseer/molecules/eyes_readiness.rb +21 -0
  22. data/lib/ace/overseer/molecules/eyes_session_evidence.rb +132 -0
  23. data/lib/ace/overseer/molecules/hitl_inbox.rb +14 -5
  24. data/lib/ace/overseer/molecules/local_sources.rb +83 -19
  25. data/lib/ace/overseer/molecules/project_bundle.rb +50 -6
  26. data/lib/ace/overseer/molecules/project_observations.rb +82 -0
  27. data/lib/ace/overseer/molecules/project_sessions.rb +99 -0
  28. data/lib/ace/overseer/molecules/remote_sources.rb +46 -16
  29. data/lib/ace/overseer/molecules/report_completion_check.rb +52 -0
  30. data/lib/ace/overseer/molecules/session_environment.rb +126 -0
  31. data/lib/ace/overseer/organisms/handoff_orchestrator.rb +26 -15
  32. data/lib/ace/overseer/organisms/report_processor.rb +56 -11
  33. data/lib/ace/overseer/organisms/start_orchestrator.rb +107 -52
  34. data/lib/ace/overseer/organisms/work_on_orchestrator.rb +43 -1
  35. data/lib/ace/overseer/version.rb +1 -1
  36. data/lib/ace/overseer.rb +3 -1
  37. metadata +65 -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
 
@@ -21,24 +21,38 @@ the right project. You never take over a project's tasks, worktrees, or
21
21
  private `_overseer` state — those belong to each project's overseer.
22
22
 
23
23
  You own the OUTCOME of routine startup, never its execution. Configuration,
24
- Bundler installation, dependency repairs and binstub generation are WORKER
25
- work. Create a commission and dispatch a separate lab worker even when the
24
+ Bundler installation, dependency repairs, binstub generation and technical
25
+ diagnosis are WORKER work. Read owner state and public CLI contracts to route
26
+ the commission; source-code investigation, troubleshooting and reproduction
27
+ commands belong to the worker. Capture the observed symptom and desired
28
+ outcome. An unknown root cause is not a reason to postpone task creation and
29
+ dispatch. Create a commission and dispatch a separate lab worker even when the
26
30
  project overseer cannot start yet. Do not edit project configuration, install
27
31
  packages or run repair commands yourself. Missing workers are a concrete
28
32
  capability gap, not a reason to become the worker.
29
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
+
30
39
  ## First turn after start
31
40
 
32
- `ace-overseer start` is the bootstrap entry point. It launches your Pi
33
- process directly in the current terminal and directory, with this Lab role
34
- and context. It performs no Herdr agent, owner or layout preflight. A missing `.ace/overseer/config.yml` is first-run setup, not a request
35
- for the Captain to write YAML. The packaged bootstrap profile is
36
- `pi`, `zai/glm-5.3-flash`, thinking `high`; explicit profiles take precedence
37
- 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.
38
52
 
39
53
  The Captain's latest instruction outranks this guide and stored tasks or plans.
40
- On this first turn, establish your own configuration and the commissioned
41
- project overseers 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
42
56
  `_overseer` tasks as context; do not dispatch old auth, publication or full
43
57
  acceptance work while the current instruction is bootstrap and project start.
44
58
  Report scope conflicts to the host operator instead of negotiating away a new
@@ -47,31 +61,53 @@ Captain order.
47
61
  1. Read the lab topology, current private tasks and real assignment/session
48
62
  state. Resume this commissioned bootstrap before unrelated backlog. Resolve
49
63
  actual project paths; ask only about ambiguous scope or missing authority.
50
- 2. Read `wfi://overseer/bootstrap-delegation` through `ace-bundle` and follow
51
- 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.
52
67
  3. Arm observation with the `ace_eyes` tool, action `start`, using the lab's
53
68
  eyes configuration path. Check enabled=true, breaker=null, errors=0 and
54
- a successful observation before dispatch. A missing tool/configuration is
55
- a readiness gap. Writing `/eyes` in prose does not arm observation.
56
- 4. Use `ace-overseer start --reconcile` to inspect/start commissioned project
57
- sessions. Bare `ace-overseer start` launches a foreground harness; never
58
- call it recursively from your own session. Delegate preparation or repair
59
- of blocked projects to a lab worker through the bootstrap procedure.
60
- 5. After dispatch, record the real assignment and agent identity and END YOUR
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
86
+ a startup dry run only if needed to establish an otherwise unknown status.
87
+ Do not investigate its implementation or reproduce the failure yourself.
88
+ Once the symptom is known, create/reconcile the task and dispatch its
89
+ worker. Run `ace-overseer start --reconcile` for that commission only after
90
+ accepted worker completion and independent verification. Bare
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
61
94
  TURN. Do not sleep-poll, run repeated status commands, or wait synchronously
62
95
  for the worker. A semantic change wakes you; unchanged state stays silent.
63
96
 
64
97
  ## Delegation and escalation
65
98
 
66
99
  - Route goals to a project by working through THAT project's overseer (its
67
- 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
68
101
  coworkers directly for product work. Lab bootstrap workers are the explicit
69
102
  exception: they prepare a commissioned project whose overseer cannot start.
70
103
  - Cross-project blockers (shared forge access, missing host capability, a
71
104
  project repeatedly failing) escalate to the Captain through `ace-hitl`
72
105
  with the per-project evidence.
73
- - One project's failure never blocks the healthy ones: keep their work
74
- 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.
75
111
 
76
112
  ## Boundaries
77
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
@@ -80,6 +80,7 @@ task:
80
80
  ```bash
81
81
  ace-task create "Manage: <scope>" --in _overseer --tags queue
82
82
  ace-task create "Prepare <scope>" --child-of <manager-ref>
83
+ ace-task update <prep-ref> --set role=planner
83
84
  ace-task create "Implement <scope>" --child-of <manager-ref>
84
85
  ace-task create "Review <scope>" --child-of <manager-ref>
85
86
  ace-task create "Integrate <scope>" --child-of <manager-ref>
@@ -94,7 +95,11 @@ Rules:
94
95
  - Add worktree/assignment references only after they really exist (the
95
96
  planner prepares them); never fabricate references ahead of preparation.
96
97
  Record them on the step that owns them, e.g.
97
- `ace-task update <step-ref> --set worktree=.ace-wt/<task>/`.
98
+ `ace-task update <step-ref> --set assignment=<actual-id> --set role=<allocated-role> --set worktree=<actual-path>`.
99
+ Read back the fields; notes alone do not bind reports. `role=planner` denotes
100
+ only the allocation that prepares assignments, never bootstrap-worker or
101
+ confirmation of a running project. Resolve note folders from `ace-task show`;
102
+ never guess their title-derived paths.
98
103
 
99
104
  - Cross-task ordering goes through the integration step: a step of task B
100
105
  that requires A's merge depends on A's *integrate* subtask, not on A's
@@ -142,11 +147,10 @@ Worker finishes → reviewer starts → integrator starts, in the same worktree:
142
147
  when every earlier leg reached assignment state `completed` and no
143
148
  executor holds the worktree. A busy, in-flight, failed, or unreadable
144
149
  predecessor refuses with reasons; unknown state is never a free resource.
145
- On success it opens the next executor's window in the same worktree and
146
- prints `ace-coworker start --config .ace-local/coworker/prepare/<role>.yml`
147
- -- the next role starts from the existing start config, nothing is
148
- re-prepared. `--dry-run` checks without effects. Use it before every
149
- 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.
150
154
 
151
155
  - Two different tasks may run in parallel in two different worktrees; one
152
156
  worktree never has two active executors.
@@ -162,8 +166,9 @@ When a report arrives (ace-hitl event or message):
162
166
  1. Match its message ID plus task/assignment/step references to the current
163
167
  order. A report that fits no open allocation is kept for clarification,
164
168
  not counted as success.
165
- 2. Record the outcome and the processed report ID in the managing task /
166
- step (task-folder notes), then update statuses:
169
+ 2. Persist the exact accepted event ID and result on the owning step:
170
+ `ace-task update <step-ref> --set processed_report=<event-id> --set report_result=<result>`.
171
+ Add evidence notes in the folder returned by `ace-task show`, then update statuses:
167
172
  `ace-task update <step-ref> --set status=done` (or keep open / escalate).
168
173
  3. For success: end the current allocation, then continue with the next
169
174
  unblocked step per rule 3. For a repeated report: check the recorded
@@ -172,16 +177,31 @@ When a report arrives (ace-hitl event or message):
172
177
  4. After an interruption between recording a result and the next allocation,
173
178
  resume by re-reading the task tree and the real worktree/assignment state.
174
179
 
175
- `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
176
187
  each incoming event (assignment recorded on a step, or the managing task's
177
- project_task with exactly one non-terminal step), records the outcome and
188
+ project_task with exactly one explicitly allocated `role=planner` non-terminal
189
+ step having no assignment). Task and any supplied role must agree; an event
190
+ without an ID is refused. Unassigned readiness never closes worker, verifier,
191
+ integration or confirm-start allocations. Before recording assigned success, the processor reads the actual coworker role
192
+ allocation and ace-assign state: exact task/assignment/role, a completed nonempty
193
+ plan, and every step done are required in dry-run and apply. Unavailable owner
194
+ state refuses acceptance. It records the outcome and
178
195
  the processed report ID on the step through the ordinary ace-task update
179
196
  surface, and continues with the next unblocked step through the existing
180
197
  gates — `ace-overseer handoff` for the next role when the family records a
181
198
  worktree, otherwise the `work-on` dependency gate. A repeated delivery is
182
199
  answered from the recorded `processed_report` and re-runs nothing; an error
183
200
  report or question never advances a step; a report matching no open
184
- allocation stays for clarification. `--dry-run` interprets without effects.
201
+ allocation stays for clarification. A `role=confirm-start` continuation remains
202
+ a coordinator operation; no generic worker is dispatched and no managing task
203
+ closes until first-turn and observation evidence is accepted. `--dry-run`
204
+ interprets without effects.
185
205
 
186
206
  ### 6) Close
187
207
 
@@ -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
@@ -15,7 +15,7 @@ module Ace
15
15
  # assignment that matches no step is :unmatched), or — only for
16
16
  # reports without an assignment (planner readiness) — by the
17
17
  # managing task's project_task plus exactly one non-terminal
18
- # step whose own assignment is blank (the preparation role). An
18
+ # step explicitly allocated to role planner with no assignment. An
19
19
  # event that fits no open allocation is :unmatched, kept
20
20
  # for clarification, never success (an ambiguous cross-manager
21
21
  # match is also :unmatched).
@@ -45,6 +45,8 @@ module Ace
45
45
  # recorded_result:}
46
46
  # {status: :unmatched, reason:}
47
47
  def self.evaluate(event:, managers:)
48
+ return {status: :unmatched, reason: "event has no report identity"} if event["id"].to_s.strip.empty?
49
+
48
50
  matched = match(event, managers)
49
51
  return {status: :unmatched, reason: unmatched_reason(event)} unless matched
50
52
 
@@ -142,16 +144,11 @@ module Ace
142
144
  # because a stale report for a different assignment must never
143
145
  # complete whichever step happens to remain.
144
146
  #
145
- # Without an assignment (a planner readiness report carries task
146
- # + result only) the report binds to the PREPARATION role alone:
147
- # the managing task's project_task must match the reported task
148
- # AND leave exactly one non-terminal step whose own assignment is
149
- # blank (the preparation step). A sole remaining step that is
150
- # bound to a role assignment belongs to that role, not to the
151
- # report — absence of an assignment is never evidence that
152
- # whichever role remains just finished. A match that is ambiguous
153
- # across managers (or across steps) fits no open allocation and
154
- # returns nil.
147
+ # Unassigned readiness can complete only an explicitly allocated
148
+ # planner step. A missing assignment says nothing about the role:
149
+ # confirm-start and bootstrap execution also have unassigned windows.
150
+ # Task identity and any supplied role must agree with the allocation.
151
+ # Ambiguous allocations never advance.
155
152
  #
156
153
  # @return [Hash{manager:, step:, terminal:}, nil]
157
154
  def self.match(event, managers)
@@ -161,8 +158,10 @@ module Ace
161
158
  assignment = event["assignment"].to_s
162
159
  if assignment != ""
163
160
  matches = managers.flat_map do |manager|
161
+ next [] unless task_agrees?(event, manager)
162
+
164
163
  steps_of(manager).filter_map do |step|
165
- {manager: manager, step: step} if step.metadata["assignment"].to_s == assignment
164
+ {manager: manager, step: step} if step.metadata["assignment"].to_s == assignment && role_agrees?(event, step)
166
165
  end
167
166
  end
168
167
  # No step records this assignment: unmatched, never a
@@ -182,7 +181,9 @@ module Ace
182
181
  next unless manager.metadata["project_task"].to_s == task && task != ""
183
182
 
184
183
  active = steps_of(manager).reject { |step| terminal?(step) }
185
- preparation = active.reject { |step| step.metadata["assignment"].to_s != "" }
184
+ preparation = active.select do |step|
185
+ step.metadata["assignment"].to_s.empty? && step.metadata["role"] == "planner" && role_agrees?(event, step)
186
+ end
186
187
  {manager: manager, step: preparation.first} if preparation.size == 1
187
188
  end
188
189
  return nil if matches.size > 1
@@ -201,7 +202,9 @@ module Ace
201
202
  def self.recorded_match(event, managers)
202
203
  matches = managers.flat_map do |manager|
203
204
  steps_of(manager).filter_map do |step|
204
- {manager: manager, step: step} if step.metadata[PROCESSED_REPORT_KEY] == event["id"]
205
+ {manager: manager, step: step} if step.metadata[PROCESSED_REPORT_KEY] == event["id"] &&
206
+ task_agrees?(event, manager) && role_agrees?(event, step) &&
207
+ (event["assignment"].to_s.empty? || step.metadata["assignment"].to_s == event["assignment"].to_s)
205
208
  end
206
209
  end
207
210
  return nil if matches.size != 1
@@ -210,6 +213,17 @@ module Ace
210
213
  terminal: terminal?(matches.first[:step])}
211
214
  end
212
215
 
216
+ def self.task_agrees?(event, manager)
217
+ expected = manager.metadata["project_task"].to_s
218
+ actual = event["task"].to_s
219
+ expected.empty? || expected == actual
220
+ end
221
+
222
+ def self.role_agrees?(event, step)
223
+ role = event["role"].to_s
224
+ role.empty? || step.metadata["role"].to_s == role
225
+ end
226
+
213
227
  # @return [String] why the event fit no open allocation
214
228
  def self.unmatched_reason(event)
215
229
  refs = []
@@ -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