ace-overseer 0.27.0 → 0.28.1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +47 -0
- data/docs/usage.md +53 -13
- data/handbook/workflow-instructions/overseer/bootstrap-delegation.wf.md +119 -0
- data/handbook/workflow-instructions/overseer/lab-start.wf.md +49 -9
- data/handbook/workflow-instructions/overseer/queue.wf.md +20 -5
- data/lib/ace/overseer/atoms/report_interpretation.rb +28 -14
- data/lib/ace/overseer/atoms/start_contract.rb +25 -12
- data/lib/ace/overseer/cli/commands/start.rb +33 -16
- data/lib/ace/overseer/molecules/event_observation.rb +21 -2
- data/lib/ace/overseer/molecules/hitl_inbox.rb +1 -0
- data/lib/ace/overseer/molecules/project_bundle.rb +163 -0
- data/lib/ace/overseer/molecules/report_completion_check.rb +52 -0
- data/lib/ace/overseer/organisms/report_processor.rb +15 -2
- data/lib/ace/overseer/organisms/start_orchestrator.rb +168 -86
- data/lib/ace/overseer/version.rb +1 -1
- data/lib/ace/overseer.rb +1 -0
- metadata +9 -12
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4d96c79ae10f470e6358022f081234f5080eba56cd58353471a33aa6f187e0c5
|
|
4
|
+
data.tar.gz: 5e4eadc41222d3448b57f938ad5c2716b1941ddfe7b800479d69a6a3f72f3cb9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f9fdda6024283fd16b8be35da318b7e4eb6a85574ef623cc1395c4c7af0d77fc1971a541bb2a28abe3a6ce7a6d52f1c04df442c69eaff53e09f7d3974b6b89e3
|
|
7
|
+
data.tar.gz: 4fe70abfe425a0c399763c790125f391bbca8099f5a96e4a24677047148fc4b7e1c578ae976853195a28f1e5306500e259de498a491601e241e1c82e1b514c91
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,53 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.28.1] - 2026-10-31
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- Transfer terminal runtime setup through a private script and require its
|
|
15
|
+
acknowledgement before launch, preventing canonical-input PATH truncation.
|
|
16
|
+
|
|
17
|
+
- Bind unassigned readiness only to explicit planner allocations; reject missing
|
|
18
|
+
report identities and conflicting task/role references. Persist bootstrap
|
|
19
|
+
assignment and receipt identities in task metadata, using resolved task paths.
|
|
20
|
+
Check real completed assignment and role ownership before accepting success;
|
|
21
|
+
leave confirm-start continuation to the coordinator without worker dispatch.
|
|
22
|
+
|
|
23
|
+
- Preserve concrete child startup failures reported before project scope is
|
|
24
|
+
established, while continuing to reject unscoped or wrong-scope success.
|
|
25
|
+
|
|
26
|
+
- Delegate bootstrap diagnosis and reproduction to workers as well as repair;
|
|
27
|
+
a known symptom is enough to commission work. Reconcile project startup only
|
|
28
|
+
after accepted worker completion and independent verification.
|
|
29
|
+
|
|
30
|
+
## [0.28.0] - 2026-10-31
|
|
31
|
+
|
|
32
|
+
### Fixed
|
|
33
|
+
|
|
34
|
+
- Delegate lab bootstrap to workers and independent verification; distinguish
|
|
35
|
+
preparation/printed briefs from running agents and confirmed first turns.
|
|
36
|
+
- Preserve installed operational runtime across project starts.
|
|
37
|
+
- Normalize local observation identities for the eyes wire contract.
|
|
38
|
+
|
|
39
|
+
## [0.28.0.pre.3] - 2026-10-31
|
|
40
|
+
|
|
41
|
+
### Fixed
|
|
42
|
+
|
|
43
|
+
- Child project bundles no longer inherit a forced Lab `ACE_TOOLCHAIN` mode;
|
|
44
|
+
project-selected path/source dependencies and explicit child policies remain
|
|
45
|
+
authoritative. The Lab role may perform routine project startup setup without
|
|
46
|
+
taking over project deliverables.
|
|
47
|
+
- `ace-overseer start` bootstraps missing start settings and becomes the Lab
|
|
48
|
+
coordinator in the current terminal without Herdr preflight. Explicit
|
|
49
|
+
`start --reconcile` manages project children after agent initialization. The coordinator can configure itself using the packaged guide.
|
|
50
|
+
- Lab and project workspaces use `overseer` and topology ids such as `ace`,
|
|
51
|
+
independently of session ownership labels. Project startup executes each
|
|
52
|
+
project's own Gemfile/lock and binstub in a separate process; project panes
|
|
53
|
+
use their own bundle instead of inheriting the Lab's gem runtime.
|
|
54
|
+
|
|
8
55
|
## [0.27.0] - 2026-10-30
|
|
9
56
|
|
|
10
57
|
### Fixed (review rounds 3/3b)
|
data/docs/usage.md
CHANGED
|
@@ -32,14 +32,21 @@ authority execution model. tmux and Herdr are transports, never state owners.
|
|
|
32
32
|
|
|
33
33
|
## `ace-overseer start`
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
Run `ace-overseer start` at a shell in the Lab's existing Herdr `overseer`
|
|
36
|
+
space. The command becomes the Lab's Pi agent directly in that same terminal
|
|
37
|
+
and cwd, without any Herdr environment, agent, owner or layout preflight. The agent receives the packaged Lab guide
|
|
38
|
+
and a first-turn prompt to delegate configuration of commissioned projects
|
|
39
|
+
using installed CLI, skills and normal configuration editing.
|
|
40
|
+
|
|
41
|
+
No local start YAML is required for first run. The packaged bootstrap profile
|
|
42
|
+
is `pi`, `zai/glm-5.3-flash`, thinking `high`, in Lab scope. An explicit start
|
|
43
|
+
section overrides bootstrap and is validated without fallback. For an
|
|
44
|
+
explicit project start use:
|
|
38
45
|
|
|
39
46
|
```yaml
|
|
40
47
|
# .ace/overseer/config.yml (project tier of the cascade)
|
|
41
48
|
start:
|
|
42
|
-
scope: project # project | lab
|
|
49
|
+
scope: project # project | lab
|
|
43
50
|
profile: overseer-default # reference into the profiles map below
|
|
44
51
|
instructions: wfi://overseer/start # handbook source (or absolute file path)
|
|
45
52
|
profiles:
|
|
@@ -53,6 +60,8 @@ profiles:
|
|
|
53
60
|
|--------|---------|
|
|
54
61
|
| `--dry-run` | Show the start plan; no session, no sync, no model call |
|
|
55
62
|
| `--format` | `table` (default) or `json` |
|
|
63
|
+
| `--reconcile` | Explicitly reconcile project children after the agent configures the Lab; never restart the coordinator |
|
|
64
|
+
| `--scope` | Explicit `lab` or `project` role; an unconfigured bare start bootstraps the Lab |
|
|
56
65
|
|
|
57
66
|
Behavior:
|
|
58
67
|
|
|
@@ -86,15 +95,37 @@ Behavior:
|
|
|
86
95
|
- The report carries `status` (`started|reused|blocked|dry_run`), `scope`,
|
|
87
96
|
`root`, `label`, `workspace`, `pane`, `agent`, `profile`, `instructions`
|
|
88
97
|
(`source` + resolved `path`) and a `message`. Exit 0 only for a ready
|
|
89
|
-
start/reuse (dry-run included); a blocked start is a CLI error naming the
|
|
90
|
-
|
|
98
|
+
start/reuse (dry-run included); a blocked start is a CLI error naming the concrete invalid configuration
|
|
99
|
+
or unavailable capability.
|
|
91
100
|
- The started overseer coordinates and delegates (guide:
|
|
92
101
|
`wfi://overseer/start`); it never substitutes for a missing coworker.
|
|
93
102
|
|
|
103
|
+
### Project-local bundles
|
|
104
|
+
|
|
105
|
+
In auto mode each project owns its Gemfile/lock and binstubs. Child starts
|
|
106
|
+
clear parent Bundler/Ruby injection and select the project's bundle.
|
|
107
|
+
|
|
108
|
+
Explicit `ACE_TOOLCHAIN=installed` is preserved instead: the installed
|
|
109
|
+
Toolchain launcher and gem closure start the child without reading its
|
|
110
|
+
Gemfile or executing its binstub. Missing installed dependencies fail visibly;
|
|
111
|
+
there is no fallback to checkout code. Terminal backend selection does not
|
|
112
|
+
change toolchain mode.
|
|
113
|
+
|
|
114
|
+
The lab overseer delegates bundle/configuration preparation to a lab worker;
|
|
115
|
+
it never edits the project's binstub or installs gems itself. Follow
|
|
116
|
+
`wfi://overseer/bootstrap-delegation` for the task, worker, independent
|
|
117
|
+
verification and observed completion cycle. `ace-coworker start` prints a
|
|
118
|
+
brief; a separate Herdr agent launch and first prompt are required.
|
|
119
|
+
|
|
94
120
|
### Lab scope (8xs.t.pu0.a)
|
|
95
121
|
|
|
96
122
|
`scope: lab` in the LAB coordination directory's own `.ace/overseer/config.yml`
|
|
97
|
-
|
|
123
|
+
selects the Lab role. Bare `start` launches the foreground harness;
|
|
124
|
+
`start --reconcile` is the explicit tool the agent uses after configuring its
|
|
125
|
+
projects. Reconciliation manages project children without restarting or probing
|
|
126
|
+
the Lab coordinator. The older full orchestration operation remains available
|
|
127
|
+
explicitly through `start --scope lab`:
|
|
128
|
+
|
|
98
129
|
|
|
99
130
|
- The project list and CANONICAL locations come from the existing ace-lab
|
|
100
131
|
topology (`topology.projects` id/path, read internally — the public
|
|
@@ -105,17 +136,14 @@ starts the whole lab from one external entry point:
|
|
|
105
136
|
per-project (a nested lab start never recurses). An unreadable topology
|
|
106
137
|
(missing or unparseable `.ace/lab/config.yml`) is a blocked start with
|
|
107
138
|
the concrete cause.
|
|
108
|
-
- The lab creates/reuses its own herdr space (`
|
|
109
|
-
so it can never collide with a session/space title derived from a project
|
|
110
|
-
directory name, e.g. a project rooted at a directory named `lab` owns
|
|
111
|
-
`overseer-lab`) and boots or
|
|
139
|
+
- The lab creates/reuses its own herdr space (`overseer`, reserved for the Lab) and boots or
|
|
112
140
|
reuses the lab's OWN overseer session there (label `overseer-<lab-root>`,
|
|
113
141
|
cwd at the lab root, the lab guide as standing instructions, first-turn
|
|
114
142
|
prompt included) — the lab-start instructions always reach a real agent,
|
|
115
143
|
and an empty configured project list still runs the lab overseer (idle).
|
|
116
|
-
- EACH project then starts or is found through the SAME operation as a
|
|
144
|
+
- EACH project then starts or is found through its own bundle and the SAME operation as a
|
|
117
145
|
standalone start (its own cascade, root, and session identity) in its OWN
|
|
118
|
-
herdr space, titled by its
|
|
146
|
+
herdr space, titled by its topology id (for example `ace`) and
|
|
119
147
|
created/reused by title by the lab flow — project sessions are isolated
|
|
120
148
|
from each other and from the lab overseer, never share one space, and
|
|
121
149
|
never re-resolve the caller's ambient workspace (a plain terminal without
|
|
@@ -532,3 +560,15 @@ ace-overseer prune --dry-run
|
|
|
532
560
|
ace-overseer prune --yes
|
|
533
561
|
ace-overseer prune --dry-run
|
|
534
562
|
```
|
|
563
|
+
|
|
564
|
+
### Workspace names and foreground instructions
|
|
565
|
+
|
|
566
|
+
Topology IDs reserve workspace titles for the commissioned lab projects.
|
|
567
|
+
Reconciliation may reuse an existing workspace with that title, but never
|
|
568
|
+
replaces its manual panes; project ownership is the stable overseer tab label
|
|
569
|
+
plus canonical cwd, not the mutable terminal title. Ambiguous ownership blocks.
|
|
570
|
+
|
|
571
|
+
Foreground bootstrap pins the two built-in start guides to their packaged
|
|
572
|
+
files. An explicit custom instruction source remains configurable; missing
|
|
573
|
+
files block before launching Pi. Project development dependencies do not select
|
|
574
|
+
the operational runtime when installed mode is chosen.
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: overseer-bootstrap-delegation
|
|
3
|
+
description: Delegate project startup to lab workers and accept their observed results
|
|
4
|
+
allowed-tools: Bash, Read
|
|
5
|
+
doc-type: workflow
|
|
6
|
+
title: Delegated Project Bootstrap
|
|
7
|
+
purpose: Complete one lab-owned startup commission without the overseer doing the repair.
|
|
8
|
+
---
|
|
9
|
+
# Delegated project bootstrap
|
|
10
|
+
|
|
11
|
+
## Commission and ownership
|
|
12
|
+
|
|
13
|
+
The overseer reads owner state and public CLI contracts to establish scope,
|
|
14
|
+
existing execution and the observed symptom. Technical diagnosis, source-code
|
|
15
|
+
investigation, troubleshooting and reproduction commands belong to the worker.
|
|
16
|
+
Record the known failure and desired outcome in the commission; discovering
|
|
17
|
+
the root cause is part of the assigned work, never a prerequisite for dispatch.
|
|
18
|
+
Use existing readiness state, or a startup dry run only when that state is
|
|
19
|
+
otherwise unknown. Do not turn that check into a technical investigation.
|
|
20
|
+
Once the symptom is known, proceed to task creation/reconciliation, observation
|
|
21
|
+
and worker dispatch, then end the turn.
|
|
22
|
+
|
|
23
|
+
Read existing tasks and assignments first. Reuse the open commission for the
|
|
24
|
+
same project and goal; unknown execution state never means free capacity.
|
|
25
|
+
Create one lab coordination task in `_overseer`, with three direct children:
|
|
26
|
+
prepare, independently verify, confirm start. The latter two depend on their
|
|
27
|
+
predecessor. Only the lab overseer updates this private tree.
|
|
28
|
+
|
|
29
|
+
Create a separate executable lab task through `ace-task` for the bootstrap
|
|
30
|
+
work, linking it as the manager's `project_task`. Keep its specification in
|
|
31
|
+
its task folder. Include the canonical target repository path, required
|
|
32
|
+
configuration, observed failure, desired outcome, allowed changes, runtime
|
|
33
|
+
mode, acceptance checks and report recipient. Assign diagnosis and reproduction
|
|
34
|
+
as well as preparation to the worker. This is lab infrastructure work, not a project product task.
|
|
35
|
+
Workers must not edit the private coordination tree. Resolve each task folder
|
|
36
|
+
from `ace-task show <ref>` before writing commission, dispatch or receipt notes;
|
|
37
|
+
never construct a folder from a guessed or expanded title slug.
|
|
38
|
+
|
|
39
|
+
Explicit `ACE_TOOLCHAIN=installed` remains installed in every subprocess,
|
|
40
|
+
worker and resumed session. The project checkout is domain data. Never modify
|
|
41
|
+
tracked binstubs to bypass this selection. In auto mode retain the project's
|
|
42
|
+
own dependency model. If package code is defective, commission its repair;
|
|
43
|
+
do not patch installed gems. Preserve unrelated changes.
|
|
44
|
+
|
|
45
|
+
## Arm eyes before dispatch
|
|
46
|
+
|
|
47
|
+
Use the lab's existing eyes JSON configuration. The `ace_eyes` tool accepts
|
|
48
|
+
`{"action":"start","configPath":"<absolute eyes JSON path>"}`.
|
|
49
|
+
Inspect the returned state: enabled=true, breaker=null, errors=0 and at least
|
|
50
|
+
one observation. Read pending revisions from their original owners, reconcile
|
|
51
|
+
existing commissions, and ack each exact key/revision only after acceptance.
|
|
52
|
+
A missing extension, invalid configuration or degraded source blocks dispatch;
|
|
53
|
+
report that capability gap. Do not claim that mentioning `/eyes` armed it.
|
|
54
|
+
|
|
55
|
+
## Prepare and actually launch a worker
|
|
56
|
+
|
|
57
|
+
Use `ace-coworker prepare --task <executable-task> --roles bootstrap-worker,bootstrap-verifier
|
|
58
|
+
--to <configured-overseer-address> --format json`. Read its returned worktree,
|
|
59
|
+
assignment IDs and start-config paths; record these on the matching private
|
|
60
|
+
steps before launch through the task API, not only in prose:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
ace-task update <prepare-step> --set assignment=<worker-assignment> --set role=bootstrap-worker --set worktree=<returned-worktree>
|
|
64
|
+
ace-task update <verify-step> --set assignment=<verifier-assignment> --set role=bootstrap-verifier --set worktree=<returned-worktree>
|
|
65
|
+
ace-task update <confirm-step> --set role=confirm-start
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Read back the steps with `ace-task show` and verify exact returned identities.
|
|
69
|
+
A preparation readiness report is not worker completion. It does not complete
|
|
70
|
+
any of these three steps; never label bootstrap execution as `role=planner`.
|
|
71
|
+
Only a separate, explicitly commissioned planner preparation allocation may
|
|
72
|
+
accept an unassigned readiness report.
|
|
73
|
+
The task must be present in the execution worktree before any agent starts.
|
|
74
|
+
|
|
75
|
+
`ace-coworker start --config <returned-path>` validates and prints a brief;
|
|
76
|
+
it does NOT launch an agent. Use the configured Herdr provider/profile to
|
|
77
|
+
start a separate worker agent in the returned worktree, load the returned
|
|
78
|
+
role instructions, and send its first prompt. The prompt commissions only
|
|
79
|
+
that task and pinned assignment, requires the worker to read its start brief,
|
|
80
|
+
drive that assignment, and finish with `ace-coworker report`. These operational roles explicitly allow the commissioned canonical target
|
|
81
|
+
outside the lab task worktree; ordinary product worker/reviewer roles do not.
|
|
82
|
+
Use CLI help for
|
|
83
|
+
Herdr's current arguments. Record the returned pane/agent identity and verify
|
|
84
|
+
first-turn delivery. Never replace a missing executor with your own work.
|
|
85
|
+
|
|
86
|
+
End the overseer's turn immediately after dispatch. The eyes timer observes
|
|
87
|
+
assignment and HITL revisions without invoking the model on unchanged state.
|
|
88
|
+
|
|
89
|
+
## Receive, verify, start
|
|
90
|
+
|
|
91
|
+
On wake, read the original report and current assignment. Require matching
|
|
92
|
+
report ID, task, assignment and role; a preparation report, process exit or
|
|
93
|
+
unmatched message is not success. Use `ace-overseer process-reports --dry-run`
|
|
94
|
+
to inspect the matching and continuation before applying it. Only accept
|
|
95
|
+
worker success with a completed non-empty assignment and the promised evidence.
|
|
96
|
+
Record the actual accepted HITL event ID and result in step metadata through
|
|
97
|
+
`ace-task update <step> --set processed_report=<event-id> --set report_result=<result>`
|
|
98
|
+
(or let `process-reports` perform that same write after its dry run is checked).
|
|
99
|
+
Mark done only after acceptance; errors keep the step open. Receipt notes in
|
|
100
|
+
the path returned by `ace-task show` supplement these fields, never replace them.
|
|
101
|
+
Read back the recorded identity before acknowledging the eyes revision.
|
|
102
|
+
Never put a preparation readiness ID on a worker, verifier or confirm-start step.
|
|
103
|
+
|
|
104
|
+
Use the existing role handoff gate to prepare the independent reviewer after
|
|
105
|
+
worker completion. As with the worker, a printed start command is not a live
|
|
106
|
+
agent: launch the reviewer separately with its own returned role/config and
|
|
107
|
+
confirm first-turn delivery. Do not launch a second executor while an earlier
|
|
108
|
+
one is active or its state is unknown. On repeated delivery, reconcile existing
|
|
109
|
+
assignments and agents instead of dispatching again.
|
|
110
|
+
|
|
111
|
+
Only after accepted worker completion and independent verification does the
|
|
112
|
+
overseer perform this commission's project-start coordination operation `ace-overseer start --reconcile`. Confirm the target's session, first
|
|
113
|
+
turn and active eyes from actual session evidence. A ready process alone is
|
|
114
|
+
not initialized observation. Close the confirmation step and managing task
|
|
115
|
+
only with these proofs; the worker report alone cannot close the family.
|
|
116
|
+
|
|
117
|
+
On error, keep the step open and route repair to the worker. Missing authority
|
|
118
|
+
or an actual Captain decision becomes a precise HITL question; end the turn
|
|
119
|
+
armed for its answer. Never self-repair or use sleep-poll while waiting.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: overseer-lab-start
|
|
3
3
|
description: Standing instructions for a started LAB overseer session (aggregate project readiness, escalate across projects, delegate to project overseers)
|
|
4
|
-
allowed-tools: Bash, Read
|
|
4
|
+
allowed-tools: Bash, Read, Write, Edit
|
|
5
5
|
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.
|
|
@@ -20,21 +20,61 @@ aggregating their status and escalations, and routing the Captain's goals to
|
|
|
20
20
|
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
|
+
You own the OUTCOME of routine startup, never its execution. Configuration,
|
|
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
|
|
30
|
+
project overseer cannot start yet. Do not edit project configuration, install
|
|
31
|
+
packages or run repair commands yourself. Missing workers are a concrete
|
|
32
|
+
capability gap, not a reason to become the worker.
|
|
33
|
+
|
|
23
34
|
## First turn after start
|
|
24
35
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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.
|
|
42
|
+
|
|
43
|
+
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
|
|
46
|
+
`_overseer` tasks as context; do not dispatch old auth, publication or full
|
|
47
|
+
acceptance work while the current instruction is bootstrap and project start.
|
|
48
|
+
Report scope conflicts to the host operator instead of negotiating away a new
|
|
49
|
+
Captain order.
|
|
50
|
+
|
|
51
|
+
1. Read the lab topology, current private tasks and real assignment/session
|
|
52
|
+
state. Resume this commissioned bootstrap before unrelated backlog. Resolve
|
|
53
|
+
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.
|
|
56
|
+
3. Arm observation with the `ace_eyes` tool, action `start`, using the lab's
|
|
57
|
+
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
|
|
61
|
+
a startup dry run only if needed to establish an otherwise unknown status.
|
|
62
|
+
Do not investigate its implementation or reproduce the failure yourself.
|
|
63
|
+
Once the symptom is known, create/reconcile the task and dispatch its
|
|
64
|
+
worker. Run `ace-overseer start --reconcile` for that commission only after
|
|
65
|
+
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
|
|
69
|
+
TURN. Do not sleep-poll, run repeated status commands, or wait synchronously
|
|
70
|
+
for the worker. A semantic change wakes you; unchanged state stays silent.
|
|
32
71
|
|
|
33
72
|
## Delegation and escalation
|
|
34
73
|
|
|
35
74
|
- Route goals to a project by working through THAT project's overseer (its
|
|
36
75
|
session is labeled `overseer-<project-root>`); you do not dispatch its
|
|
37
|
-
coworkers directly.
|
|
76
|
+
coworkers directly for product work. Lab bootstrap workers are the explicit
|
|
77
|
+
exception: they prepare a commissioned project whose overseer cannot start.
|
|
38
78
|
- Cross-project blockers (shared forge access, missing host capability, a
|
|
39
79
|
project repeatedly failing) escalate to the Captain through `ace-hitl`
|
|
40
80
|
with the per-project evidence.
|
|
@@ -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
|
|
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
|
|
@@ -162,8 +167,9 @@ When a report arrives (ace-hitl event or message):
|
|
|
162
167
|
1. Match its message ID plus task/assignment/step references to the current
|
|
163
168
|
order. A report that fits no open allocation is kept for clarification,
|
|
164
169
|
not counted as success.
|
|
165
|
-
2.
|
|
166
|
-
step
|
|
170
|
+
2. Persist the exact accepted event ID and result on the owning step:
|
|
171
|
+
`ace-task update <step-ref> --set processed_report=<event-id> --set report_result=<result>`.
|
|
172
|
+
Add evidence notes in the folder returned by `ace-task show`, then update statuses:
|
|
167
173
|
`ace-task update <step-ref> --set status=done` (or keep open / escalate).
|
|
168
174
|
3. For success: end the current allocation, then continue with the next
|
|
169
175
|
unblocked step per rule 3. For a repeated report: check the recorded
|
|
@@ -174,14 +180,23 @@ When a report arrives (ace-hitl event or message):
|
|
|
174
180
|
|
|
175
181
|
`ace-overseer process-reports` executes rules 1-3 mechanically: it matches
|
|
176
182
|
each incoming event (assignment recorded on a step, or the managing task's
|
|
177
|
-
project_task with exactly one non-terminal
|
|
183
|
+
project_task with exactly one explicitly allocated `role=planner` non-terminal
|
|
184
|
+
step having no assignment). Task and any supplied role must agree; an event
|
|
185
|
+
without an ID is refused. Unassigned readiness never closes worker, verifier,
|
|
186
|
+
integration or confirm-start allocations. Before recording assigned success, the processor reads the actual coworker role
|
|
187
|
+
allocation and ace-assign state: exact task/assignment/role, a completed nonempty
|
|
188
|
+
plan, and every step done are required in dry-run and apply. Unavailable owner
|
|
189
|
+
state refuses acceptance. It records the outcome and
|
|
178
190
|
the processed report ID on the step through the ordinary ace-task update
|
|
179
191
|
surface, and continues with the next unblocked step through the existing
|
|
180
192
|
gates — `ace-overseer handoff` for the next role when the family records a
|
|
181
193
|
worktree, otherwise the `work-on` dependency gate. A repeated delivery is
|
|
182
194
|
answered from the recorded `processed_report` and re-runs nothing; an error
|
|
183
195
|
report or question never advances a step; a report matching no open
|
|
184
|
-
allocation stays for clarification.
|
|
196
|
+
allocation stays for clarification. A `role=confirm-start` continuation remains
|
|
197
|
+
a coordinator operation; no generic worker is dispatched and no managing task
|
|
198
|
+
closes until first-turn and observation evidence is accepted. `--dry-run`
|
|
199
|
+
interprets without effects.
|
|
185
200
|
|
|
186
201
|
### 6) Close
|
|
187
202
|
|
|
@@ -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
|
|
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
|
-
#
|
|
146
|
-
#
|
|
147
|
-
#
|
|
148
|
-
#
|
|
149
|
-
#
|
|
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.
|
|
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 = []
|
|
@@ -3,14 +3,9 @@
|
|
|
3
3
|
module Ace
|
|
4
4
|
module Overseer
|
|
5
5
|
module Atoms
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
# `profile` reference into the same document's `profiles` map and
|
|
10
|
-
# an `instructions` source (wfi:// or an absolute file path).
|
|
11
|
-
# Nothing is guessed: a missing or ambiguous section is an error
|
|
12
|
-
# BEFORE any session is created, and no interim default model is
|
|
13
|
-
# applied anywhere. Pure — no IO, value-free messages.
|
|
6
|
+
# Validate explicit start configuration, or select the packaged
|
|
7
|
+
# first-run profile when no start section exists. A malformed explicit
|
|
8
|
+
# configuration never falls back to another model or harness.
|
|
14
9
|
class StartContract
|
|
15
10
|
SCOPES = %w[project lab].freeze
|
|
16
11
|
SECTION_KEYS = %w[scope profile instructions].freeze
|
|
@@ -23,7 +18,25 @@ module Ace
|
|
|
23
18
|
# thinking:}, instructions:}
|
|
24
19
|
# @raise [Ace::Overseer::Error] missing/ambiguous/invalid start
|
|
25
20
|
# configuration
|
|
21
|
+
BOOTSTRAP_PROFILE = {"harness" => "pi", "model" => "zai/glm-5.3-flash",
|
|
22
|
+
"thinking" => "high"}.freeze
|
|
23
|
+
|
|
24
|
+
# A missing start configuration is first-run setup, not a reason to
|
|
25
|
+
# prevent the coordinator that owns setup from starting. Explicit
|
|
26
|
+
# configurations are still validated without fallback.
|
|
27
|
+
def self.bootstrap(config, scope: "lab")
|
|
28
|
+
return config if config.key?("start")
|
|
29
|
+
|
|
30
|
+
profiles = config.fetch("profiles", {})
|
|
31
|
+
raise Ace::Overseer::Error, "profiles must be a mapping" unless profiles.is_a?(Hash)
|
|
32
|
+
|
|
33
|
+
config.merge("start" => {"scope" => scope, "profile" => "overseer-default",
|
|
34
|
+
"instructions" => "wfi://overseer/#{(scope == "lab") ? "lab-start" : "start"}"},
|
|
35
|
+
"profiles" => {"overseer-default" => BOOTSTRAP_PROFILE}.merge(profiles))
|
|
36
|
+
end
|
|
37
|
+
|
|
26
38
|
def self.normalize(config)
|
|
39
|
+
config = bootstrap(config)
|
|
27
40
|
start = config["start"]
|
|
28
41
|
unless start.is_a?(Hash)
|
|
29
42
|
raise Ace::Overseer::Error,
|
|
@@ -36,13 +49,13 @@ module Ace
|
|
|
36
49
|
unless unknown.empty?
|
|
37
50
|
raise Ace::Overseer::Error,
|
|
38
51
|
"start section has unknown key '#{unknown.sort.first}' " \
|
|
39
|
-
"(allowed: #{SECTION_KEYS.join(
|
|
52
|
+
"(allowed: #{SECTION_KEYS.join(", ")})"
|
|
40
53
|
end
|
|
41
54
|
|
|
42
55
|
scope = required(start, "scope")
|
|
43
56
|
unless SCOPES.include?(scope)
|
|
44
57
|
raise Ace::Overseer::Error,
|
|
45
|
-
"start scope must be one of: #{SCOPES.join(
|
|
58
|
+
"start scope must be one of: #{SCOPES.join(", ")} (got '#{scope}')"
|
|
46
59
|
end
|
|
47
60
|
|
|
48
61
|
profile_name = required(start, "profile")
|
|
@@ -50,7 +63,7 @@ module Ace
|
|
|
50
63
|
|
|
51
64
|
instructions = required(start, "instructions")
|
|
52
65
|
unless INSTRUCTION_PROTOCOLS.any? { |prefix| instructions.start_with?(prefix) } ||
|
|
53
|
-
|
|
66
|
+
instructions.start_with?("/")
|
|
54
67
|
raise Ace::Overseer::Error,
|
|
55
68
|
"start instructions must be a wfi:// (or prompt://, tmpl://) " \
|
|
56
69
|
"source or an absolute file path"
|
|
@@ -81,7 +94,7 @@ module Ace
|
|
|
81
94
|
unless unknown.empty?
|
|
82
95
|
raise Ace::Overseer::Error,
|
|
83
96
|
"profile '#{profile_name}' has unknown key '#{unknown.sort.first}' " \
|
|
84
|
-
"(allowed: #{PROFILE_KEYS.join(
|
|
97
|
+
"(allowed: #{PROFILE_KEYS.join(", ")})"
|
|
85
98
|
end
|
|
86
99
|
|
|
87
100
|
harness = required_value(raw, "harness", "profile '#{profile_name}'")
|