ace-coworker 0.6.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.
- checksums.yaml +7 -0
- data/.ace-defaults/coworker/config.yml +6 -0
- data/.ace-defaults/coworker/roles/integrator.yml +15 -0
- data/.ace-defaults/coworker/roles/reviewer.yml +15 -0
- data/.ace-defaults/coworker/roles/spec.yml +14 -0
- data/.ace-defaults/coworker/roles/worker.yml +13 -0
- data/.ace-defaults/coworker/sequences/integrator.yml +20 -0
- data/.ace-defaults/coworker/sequences/reviewer.yml +20 -0
- data/.ace-defaults/coworker/sequences/spec.yml +16 -0
- data/.ace-defaults/coworker/sequences/worker.yml +21 -0
- data/.ace-defaults/nav/protocols/wfi-sources/ace-coworker.yml +19 -0
- data/CHANGELOG.md +255 -0
- data/README.md +98 -0
- data/Rakefile +13 -0
- data/docs/usage.md +564 -0
- data/exe/ace-coworker +16 -0
- data/handbook/workflow-instructions/coworker/integrator.wf.md +162 -0
- data/handbook/workflow-instructions/coworker/reviewer.wf.md +211 -0
- data/handbook/workflow-instructions/coworker/spec.wf.md +100 -0
- data/handbook/workflow-instructions/coworker/worker.wf.md +103 -0
- data/lib/ace/coworker/atoms/active_executor_rule.rb +71 -0
- data/lib/ace/coworker/atoms/brief_formatter.rb +33 -0
- data/lib/ace/coworker/atoms/config_schema.rb +121 -0
- data/lib/ace/coworker/atoms/integration_gate.rb +92 -0
- data/lib/ace/coworker/atoms/outcome_planner.rb +79 -0
- data/lib/ace/coworker/atoms/prepare_decision.rb +75 -0
- data/lib/ace/coworker/atoms/prompt_template.rb +28 -0
- data/lib/ace/coworker/atoms/report_record_formatter.rb +60 -0
- data/lib/ace/coworker/atoms/resume_brief_formatter.rb +84 -0
- data/lib/ace/coworker/atoms/resume_planner.rb +78 -0
- data/lib/ace/coworker/atoms/role_preset_schema.rb +91 -0
- data/lib/ace/coworker/atoms/round_record_schema.rb +62 -0
- data/lib/ace/coworker/atoms/round_rule.rb +105 -0
- data/lib/ace/coworker/cli/commands/commission.rb +100 -0
- data/lib/ace/coworker/cli/commands/gate.rb +91 -0
- data/lib/ace/coworker/cli/commands/prepare.rb +138 -0
- data/lib/ace/coworker/cli/commands/report.rb +79 -0
- data/lib/ace/coworker/cli/commands/resume.rb +57 -0
- data/lib/ace/coworker/cli/commands/roles.rb +60 -0
- data/lib/ace/coworker/cli/commands/rounds.rb +99 -0
- data/lib/ace/coworker/cli/commands/start.rb +39 -0
- data/lib/ace/coworker/cli/commands/status.rb +95 -0
- data/lib/ace/coworker/cli.rb +83 -0
- data/lib/ace/coworker/errors.rb +10 -0
- data/lib/ace/coworker/models/assignment_snapshot.rb +65 -0
- data/lib/ace/coworker/models/brief.rb +38 -0
- data/lib/ace/coworker/models/config.rb +54 -0
- data/lib/ace/coworker/models/outcome.rb +39 -0
- data/lib/ace/coworker/models/preparation.rb +67 -0
- data/lib/ace/coworker/models/resume_plan.rb +47 -0
- data/lib/ace/coworker/molecules/assignment_metadata.rb +57 -0
- data/lib/ace/coworker/molecules/assignment_probe.rb +57 -0
- data/lib/ace/coworker/molecules/config_loader.rb +119 -0
- data/lib/ace/coworker/molecules/git_state_probe.rb +63 -0
- data/lib/ace/coworker/molecules/hitl_reporter.rb +145 -0
- data/lib/ace/coworker/molecules/instruction_resolver.rb +82 -0
- data/lib/ace/coworker/molecules/project_root.rb +26 -0
- data/lib/ace/coworker/molecules/report_state_store.rb +53 -0
- data/lib/ace/coworker/molecules/review_round_store.rb +115 -0
- data/lib/ace/coworker/molecules/role_preset_loader.rb +95 -0
- data/lib/ace/coworker/molecules/role_sequence_composer.rb +245 -0
- data/lib/ace/coworker/molecules/step_evidence_reader.rb +60 -0
- data/lib/ace/coworker/molecules/step_report_reader.rb +39 -0
- data/lib/ace/coworker/molecules/task_probe.rb +40 -0
- data/lib/ace/coworker/molecules/task_record_writer.rb +44 -0
- data/lib/ace/coworker/molecules/worktree_executor_probe.rb +139 -0
- data/lib/ace/coworker/molecules/worktree_provision_probe.rb +137 -0
- data/lib/ace/coworker/organisms/commission_orchestrator.rb +148 -0
- data/lib/ace/coworker/organisms/prepare_orchestrator.rb +374 -0
- data/lib/ace/coworker/organisms/report_orchestrator.rb +192 -0
- data/lib/ace/coworker/organisms/resume_orchestrator.rb +91 -0
- data/lib/ace/coworker/organisms/start_config_writer.rb +127 -0
- data/lib/ace/coworker/organisms/start_orchestrator.rb +45 -0
- data/lib/ace/coworker/organisms/status_orchestrator.rb +62 -0
- data/lib/ace/coworker/version.rb +7 -0
- data/lib/ace/coworker.rb +86 -0
- metadata +319 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: coworker-integrator
|
|
3
|
+
allowed-tools: Bash, Read
|
|
4
|
+
description: Integrator role for the file-based lab. Performs the project-defined integration; before merging it checks that dependencies are integrated predecessors, the candidate head still matches the reviewed head (no drift), tests were executed and passed, and a fresh independent review verdict accepts the exact candidate head. A stale review, unsatisfied dependency, or missing test evidence WITHHOLDS the merge; an uncertain operation outcome is verified against the real state, never retried blind. Blocked integrations escalate to the overseer via ace-hitl.
|
|
5
|
+
doc-type: workflow
|
|
6
|
+
purpose: integrator role workflow instruction
|
|
7
|
+
ace-docs:
|
|
8
|
+
last-updated: '2026-10-19'
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Integrator - Result-Dependent Integration with a Pre-Merge Gate
|
|
12
|
+
|
|
13
|
+
## Goal
|
|
14
|
+
|
|
15
|
+
Integrate ready, verified candidates in the order of their real dependencies.
|
|
16
|
+
Before any merge, CHECK four facts and merge only when all four hold:
|
|
17
|
+
(a) dependencies are satisfied (predecessors integrated - an open PR or a
|
|
18
|
+
"work done" message is not integration), (b) current changes match what was
|
|
19
|
+
reviewed (candidate head == reviewed head, no drift), (c) tests were executed
|
|
20
|
+
and passed (real evidence), and (d) a fresh independent review verdict accepts
|
|
21
|
+
the exact candidate head. Otherwise WITHHOLD the merge and report/escalate.
|
|
22
|
+
|
|
23
|
+
## Role Identity
|
|
24
|
+
|
|
25
|
+
- The integrator takes the worktree over only after the reviewer's assignment
|
|
26
|
+
completed; one active executor per worktree.
|
|
27
|
+
- Integration sequencing, which candidates merge in which order, and the
|
|
28
|
+
dependency map come from the commissioned assignment and the task's
|
|
29
|
+
`dependencies` fields (leaf-level, per the lab's execution-order contract) -
|
|
30
|
+
never from self-selected extra work.
|
|
31
|
+
- This role never performs the review and never re-litigates it: it verifies
|
|
32
|
+
that a fresh accepting review covers the exact candidate head.
|
|
33
|
+
|
|
34
|
+
## Start State
|
|
35
|
+
|
|
36
|
+
- The run config `.ace-local/coworker/config.yml` names this role
|
|
37
|
+
(`role: integrator`), this workflow (`instructions:
|
|
38
|
+
wfi://coworker/integrator`), the task ref, the pinned assignment id, and
|
|
39
|
+
the overseer address.
|
|
40
|
+
- Run `ace-coworker start` and follow the rendered brief; drive the pinned
|
|
41
|
+
`--assignment <id>` in every ace-assign call.
|
|
42
|
+
- Missing or mismatched input (task does not resolve here, assignment id
|
|
43
|
+
mismatch) fails explicitly - never guess or adopt another commission.
|
|
44
|
+
- After an interruption, `ace-coworker resume` renders the preserved state;
|
|
45
|
+
for steps with external effects (merge/push) verify the actual state before
|
|
46
|
+
repeating them.
|
|
47
|
+
|
|
48
|
+
## Project Context Loading
|
|
49
|
+
|
|
50
|
+
- Read and follow: `ace-bundle wfi://bundle`
|
|
51
|
+
|
|
52
|
+
## Process
|
|
53
|
+
|
|
54
|
+
1. **Drive the assignment.**
|
|
55
|
+
- `ace-assign start` / `finish` / `fail` with the pinned assignment.
|
|
56
|
+
- Scope stays bounded by the commissioned goal; never change the parent
|
|
57
|
+
goal, task dependencies, or the overseer tree.
|
|
58
|
+
|
|
59
|
+
2. **Collect the gate facts (read-only, from their owners).**
|
|
60
|
+
- **Candidate head**: current head of the candidate branch in this
|
|
61
|
+
worktree (`git rev-parse HEAD` after `git status`); heads are recorded
|
|
62
|
+
and compared as full lowercase SHAs (normalize case before comparing,
|
|
63
|
+
never truncate to a short form); the
|
|
64
|
+
worktree state is the truth, not a remembered sha.
|
|
65
|
+
- **Review evidence**: the reviewer's durable report
|
|
66
|
+
(`<task>/coworker/<assignment>.md`) names the exact reviewed candidate
|
|
67
|
+
head, the executed checks, per-round dispositions, and the final
|
|
68
|
+
verdict; the round history lives in
|
|
69
|
+
`.ace-local/coworker/review-rounds/<assignment>.json`
|
|
70
|
+
(`ace-coworker rounds` verdict `accept`). The reviewed head is the head
|
|
71
|
+
that verdict covers.
|
|
72
|
+
- **Test evidence**: executed `bin/ace-test <package> all` results named
|
|
73
|
+
in the worker/reviewer reports (counts, failures) - only real executed
|
|
74
|
+
runs count; CI status is ADVISORY and never a merge blocker.
|
|
75
|
+
- **Dependency states**: for each leaf the candidate depends on, whether
|
|
76
|
+
its result was RECEIVED AND INTEGRATED (merged predecessor), not merely
|
|
77
|
+
finished or reviewed.
|
|
78
|
+
- Any fact you cannot establish is UNCERTAIN: resolve it by checking the
|
|
79
|
+
real state (files, reports, git) before proceeding - never by assuming,
|
|
80
|
+
and never by re-running a merge hoping for a different outcome.
|
|
81
|
+
|
|
82
|
+
3. **Evaluate the gate (deterministic).**
|
|
83
|
+
- `ace-coworker gate --candidate-head <sha> --review-head <sha>
|
|
84
|
+
--review-verdict accept|continue|escalate --tests executed,passed
|
|
85
|
+
--dep <leaf>=integrated --dep <leaf>=missing`
|
|
86
|
+
(repeat `--dep` per dependency; omit `--candidate-head`/`--review-head`
|
|
87
|
+
when genuinely unknown so the gate blocks on the missing evidence).
|
|
88
|
+
- The gate (`Ace::Coworker::Atoms::IntegrationGate`) is pure: it returns
|
|
89
|
+
`ready` or `blocked` with per-check reasons (dependencies, candidate
|
|
90
|
+
drift, review freshness/verdict, executed+passing tests). `blocked` is a
|
|
91
|
+
legitimate outcome with exit 0; only invalid input fails the command.
|
|
92
|
+
- A candidate change after the review (candidate head != reviewed head)
|
|
93
|
+
invalidates the review: the gate reports a stale review even when the
|
|
94
|
+
verdict says accept.
|
|
95
|
+
|
|
96
|
+
4. **Merge only a ready candidate.**
|
|
97
|
+
- Verdict `ready`: perform the project-defined integration with the
|
|
98
|
+
existing tools (`git` / `ace-git`, scoped to the commissioned paths;
|
|
99
|
+
never force-push; fetch first and resolve conflicts explicitly).
|
|
100
|
+
- If the merge itself changed the candidate or conflicts were resolved,
|
|
101
|
+
the result is a NEW candidate: re-run the affected checks
|
|
102
|
+
(`bin/ace-test <package> all`) and RENEW the review for the changed
|
|
103
|
+
result (reviewer role) before treating it as integrated - never mix
|
|
104
|
+
acceptance of the old candidate with new code (step 4 of the lab's execution-order contract). Then re-evaluate the gate.
|
|
105
|
+
- After merging, verify the actual outcome (branch state, merged head)
|
|
106
|
+
before reporting - an uncertain operation outcome is CHECKED, not
|
|
107
|
+
retried blind: a repeated merge/push is never the verification.
|
|
108
|
+
|
|
109
|
+
5. **Withhold blocked merges.**
|
|
110
|
+
- Verdict `blocked`: do NOT merge. Record the withholding reason in the
|
|
111
|
+
step report and report the blocked outcome (step 6). Fixable locally
|
|
112
|
+
(e.g. renewed review needed after your own conflict resolution): do it
|
|
113
|
+
inside this assignment, then re-evaluate the gate.
|
|
114
|
+
- A blocked integration that needs the overseer (unsatisfied dependency,
|
|
115
|
+
sequencing decision, reviewer unavailable):
|
|
116
|
+
`ace-hitl create "<title>" --kind decision --question "<options,
|
|
117
|
+
impact, what is blocked>" --to <overseer>`, then `ace-hitl send <id>`;
|
|
118
|
+
keep the step failed/open (`ace-assign fail` with the cause) and report
|
|
119
|
+
an error outcome. NEVER merge to "unblock" past a failed gate.
|
|
120
|
+
|
|
121
|
+
6. **Record and report the actual outcome.**
|
|
122
|
+
- `ace-coworker report` writes the durable record
|
|
123
|
+
(`<task>/coworker/<assignment>.md`) and delivers the HITL report.
|
|
124
|
+
- The report states the OUTCOME THE NEXT ROLE NEEDS: for an integrated
|
|
125
|
+
candidate - the merged result (target, merged head or PR reference),
|
|
126
|
+
which dependency leaves it unblocks, the gate evidence (verdict,
|
|
127
|
+
candidate/reviewed head, test counts, review verdict), and any renewal
|
|
128
|
+
performed; for a withheld merge - the blocking reasons per check and
|
|
129
|
+
what must change (integrated dependency, fresh review of the new head,
|
|
130
|
+
executed tests). A "work done" message never substitutes for this.
|
|
131
|
+
|
|
132
|
+
## Completion Rule
|
|
133
|
+
|
|
134
|
+
The assignment is complete when every commissioned candidate reached a
|
|
135
|
+
truthful terminal state - integrated (gate `ready`, merge verified, outcome
|
|
136
|
+
reported with the unblocked dependents) or withheld with the blocking reasons
|
|
137
|
+
recorded, reported, and escalated where the overseer must decide. Anything
|
|
138
|
+
less is an error outcome with the cause named.
|
|
139
|
+
|
|
140
|
+
## Reporting
|
|
141
|
+
|
|
142
|
+
- Outcome and progress are reported through `ace-coworker report` (channel
|
|
143
|
+
`hitl` by default; recipient = the config `overseer` address).
|
|
144
|
+
- Escalations travel as `ace-hitl` decision questions; errors follow
|
|
145
|
+
`errors.on_failure: report` (recorded and reported).
|
|
146
|
+
|
|
147
|
+
## Boundaries
|
|
148
|
+
|
|
149
|
+
- No merge past a blocked gate, no force-pushes, no speculative merges of
|
|
150
|
+
unintegrated dependencies.
|
|
151
|
+
- No re-review of the worker's change by this role: renewals go to the
|
|
152
|
+
reviewer role; the integrator only verifies freshness and coverage.
|
|
153
|
+
- The gate atom decides readiness only; this role drives git/ace-git - the
|
|
154
|
+
tool never auto-merges.
|
|
155
|
+
- No new state owners, journals, or queues (ADR-034): `.ace-local/coworker/`
|
|
156
|
+
belongs to ace-coworker, `.ace-local/assign/` to ace-assign,
|
|
157
|
+
`.ace-local/review/` to ace-review, `.ace-local/hitl/` to ace-hitl.
|
|
158
|
+
Integration decisions persist in the assignment's existing report state
|
|
159
|
+
(ReportStateStore / `<task>/coworker/<assignment>.md` record); no new
|
|
160
|
+
artifact kind is introduced.
|
|
161
|
+
- Inside the ACE repository itself, invoke every tool as `bin/ace-*` (the
|
|
162
|
+
binstubs pin the checkout's bundle).
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: coworker-reviewer
|
|
3
|
+
allowed-tools: Bash, Read
|
|
4
|
+
description: Reviewer role for the file-based lab. Independent of the worker; reviews the exact delivered candidate, fixes confirmed defects itself inside its own single assignment (no per-fix overseer round-trip), checks each fix diff, and returns to full review rounds under the 3/2/10 convergence rule. An unresolved High/Critical finding is never marked as success - no effective fix or a needed product decision is escalated to the overseer via ace-hitl.
|
|
5
|
+
doc-type: workflow
|
|
6
|
+
purpose: reviewer role workflow instruction
|
|
7
|
+
ace-docs:
|
|
8
|
+
last-updated: '2026-10-19'
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Reviewer - Independent Review with Fixes Inside the Assignment
|
|
12
|
+
|
|
13
|
+
## Goal
|
|
14
|
+
|
|
15
|
+
Review the delivered change independently of the worker and converge it to a
|
|
16
|
+
verified state: run review rounds, fix confirmed defects **yourself, inside
|
|
17
|
+
this single assignment** (no per-fix overseer round-trip), check the diff of
|
|
18
|
+
each fix, and return to full review rounds. An unresolved High/Critical
|
|
19
|
+
finding is never marked as success; a missing effective fix or a needed
|
|
20
|
+
product decision is escalated to the overseer instead.
|
|
21
|
+
|
|
22
|
+
## Role Identity and Independence
|
|
23
|
+
|
|
24
|
+
- The reviewer is not the worker: it takes the worktree over only after the
|
|
25
|
+
worker's assignment is completed. One active executor per worktree.
|
|
26
|
+
- If the worker is still active in this worktree, do not start alongside it -
|
|
27
|
+
report a blocker (`ace-coworker report --result error` naming the conflict).
|
|
28
|
+
- Independence is about judgment, not isolation: the reviewer reads the
|
|
29
|
+
worker's commits as evidence, then forms its own verdict on the exact
|
|
30
|
+
candidate head. It never relies on the worker's self-assessment as review
|
|
31
|
+
evidence.
|
|
32
|
+
|
|
33
|
+
## Start State
|
|
34
|
+
|
|
35
|
+
- The run config `.ace-local/coworker/config.yml` names this role
|
|
36
|
+
(`role: reviewer`), this workflow (`instructions: wfi://coworker/reviewer`),
|
|
37
|
+
the task ref, the pinned assignment id, and the overseer address.
|
|
38
|
+
- Run `ace-coworker start` and follow the rendered brief; the assignment is
|
|
39
|
+
driven with the pinned `--assignment <id>` in every ace-assign call.
|
|
40
|
+
- Missing or mismatched input (task does not resolve here, assignment id
|
|
41
|
+
mismatch) fails explicitly - never guess or adopt another commission.
|
|
42
|
+
- After an interruption, `ace-coworker resume` renders the preserved state and
|
|
43
|
+
the resume path (same task, same assignment, same worktree).
|
|
44
|
+
|
|
45
|
+
## Project Context Loading
|
|
46
|
+
|
|
47
|
+
- Read and follow: `ace-bundle wfi://bundle`
|
|
48
|
+
|
|
49
|
+
## Process
|
|
50
|
+
|
|
51
|
+
1. **Drive and develop the assignment.**
|
|
52
|
+
- Use `ace-assign start` / `finish` / `fail` with the pinned assignment.
|
|
53
|
+
- You may develop the assignment: add fix and verification steps with
|
|
54
|
+
`ace-assign add --step <name> --after <n>` for a step name that EXISTS
|
|
55
|
+
in the assignment's preset catalog (`--step` selects an existing
|
|
56
|
+
preset step definition; it never creates a new name), or with
|
|
57
|
+
`ace-assign add --yaml <file> --after <n> --assignment <id>` for a
|
|
58
|
+
newly named step (file with a top-level `steps:` array of
|
|
59
|
+
`name`/`instructions` mappings — see step 4). Added steps stay in the
|
|
60
|
+
SAME plan, visible via `ace-assign status` - that is how a fix remains
|
|
61
|
+
inside this one assignment. Scope stays bounded by the role rules and
|
|
62
|
+
the commissioned goal; never change the parent goal, task
|
|
63
|
+
dependencies, or the overseer tree.
|
|
64
|
+
|
|
65
|
+
2. **Run a review round (forge-neutral).**
|
|
66
|
+
- Subject: local candidate
|
|
67
|
+
`ace-review --preset code-valid --subject diff:<merge-base>..<head>`, or
|
|
68
|
+
a typed PR reference `--pr IDENTIFIER` (number, `owner/repo#number`, or
|
|
69
|
+
URL; GitHub `/pull/`, Forgejo `/pulls/`). Use the assignment's retained
|
|
70
|
+
forge selection `--server NAME` or `--default-server` (mutually
|
|
71
|
+
exclusive) - never infer a forge from a hostname or the caller's
|
|
72
|
+
identity.
|
|
73
|
+
- `--dry-run` first: check the selected/omitted files and the budgets
|
|
74
|
+
(30k context / 30k instructions / 128k total input). Change scope if too
|
|
75
|
+
large; never silently truncate or claim omitted code was reviewed.
|
|
76
|
+
- Then `--auto-execute` and record the session path (under
|
|
77
|
+
`.ace-local/review/`).
|
|
78
|
+
- Severity is verified by you, not accepted from the model: every finding
|
|
79
|
+
is checked against the actual code before it counts.
|
|
80
|
+
|
|
81
|
+
3. **Verify findings.**
|
|
82
|
+
- `ace-review-feedback list --session <path>`, then
|
|
83
|
+
`ace-review-feedback verify <id> --valid|--invalid --research "<what you
|
|
84
|
+
checked>"`.
|
|
85
|
+
- Distinguish defects (fixable in code) from product decisions (need the
|
|
86
|
+
overseer) and optional improvements (defer with rationale). A single
|
|
87
|
+
valid finding matters.
|
|
88
|
+
|
|
89
|
+
4. **Fix confirmed defects inside this assignment.**
|
|
90
|
+
No overseer round-trip per fix:
|
|
91
|
+
- Confirmed High/Critical must be fixed. Verified P2: fix within the task
|
|
92
|
+
or defer with rationale (`ace-review-feedback skip <id> --reason
|
|
93
|
+
"<rationale>"`, or verify then skip per the feedback workflow) so the
|
|
94
|
+
finding has a terminal disposition instead of lingering pending; a
|
|
95
|
+
deferred P2 never blocks the round.
|
|
96
|
+
- (a) add a newly named fix step via `ace-assign add --yaml <file>
|
|
97
|
+
--assignment <id> --after <n>`, where `<file>` is a YAML document
|
|
98
|
+
with a top-level `steps:` array and the feedback id named in the
|
|
99
|
+
step instructions, e.g. `.ace-local/fix-<feedback-id>.yaml`:
|
|
100
|
+
```yaml
|
|
101
|
+
steps:
|
|
102
|
+
- name: fix-feedback-<id>
|
|
103
|
+
instructions: |
|
|
104
|
+
Fix the confirmed review finding <feedback-id> in the delivered
|
|
105
|
+
change. Apply the minimal correct fix, run the affected checks
|
|
106
|
+
(bin/ace-test <package>), and record what changed.
|
|
107
|
+
```
|
|
108
|
+
(`--step <name>` only selects a step definition that already exists
|
|
109
|
+
in the preset catalog - it cannot mint a new fix-step name);
|
|
110
|
+
(b) implement the fix on the task branch in this worktree; (c) run
|
|
111
|
+
the affected checks (`bin/ace-test <package> ...` - a failed required
|
|
112
|
+
test blocks); (d) commit scoped (`ace-git-commit <paths>` after
|
|
113
|
+
checking `git status`); (e) only after the fix is verified:
|
|
114
|
+
`ace-review-feedback resolve <id> --resolution "Fixed in <sha>"`.
|
|
115
|
+
- A finding is never resolved or verified away without evidence of a fix.
|
|
116
|
+
|
|
117
|
+
5. **Check the fix diff.**
|
|
118
|
+
- Review the diff of your own fix, e.g.
|
|
119
|
+
`ace-review --preset code-valid --subject diff:<pre-fix>..<post-fix>`,
|
|
120
|
+
or verify directly by reading the diff and re-running the checks.
|
|
121
|
+
- A fix-diff check never replaces the next full round and never advances
|
|
122
|
+
the convergence counters by itself.
|
|
123
|
+
|
|
124
|
+
6. **Return to full review.**
|
|
125
|
+
- After fixes, run a FULL round over the whole candidate with the same
|
|
126
|
+
retained forge selection. With a `--pr` subject, `--delta` may scope
|
|
127
|
+
later rounds (it carries findings forward); with a local diff subject,
|
|
128
|
+
re-run the full `diff:<merge-base>..<head>` range (`--delta` requires
|
|
129
|
+
`--pr`). A delta round counts toward the 3/2/10 rule only when it
|
|
130
|
+
still reviews every changed part; a fix-diff check never counts. Any
|
|
131
|
+
candidate change renews the evidence: every accepted review binds the
|
|
132
|
+
current candidate SHA; a committed task edit changes the candidate and
|
|
133
|
+
requires renewed evidence.
|
|
134
|
+
- **Convergence rule 3/2/10**: minimum 3 full rounds, the last 2
|
|
135
|
+
consecutive without confirmed High/Critical and with no unresolved
|
|
136
|
+
earlier High/Critical; maximum 10 - if round 10 satisfies the rule,
|
|
137
|
+
finish successfully, otherwise escalate. Interrupted or incomplete
|
|
138
|
+
rounds are not clean rounds and do not count.
|
|
139
|
+
- Keep your own round record in the step reports (round number, session
|
|
140
|
+
path, verdict per finding). The review sessions, feedback items, and
|
|
141
|
+
assignment state ARE the checkpoint - there is no separate journal.
|
|
142
|
+
Deterministic counter enforcement exists (8xg.t.sbz.4.2):
|
|
143
|
+
`Ace::Coworker::Atoms::RoundRule` evaluates the recorded rounds
|
|
144
|
+
(:continue | :accept | :escalate) and `Molecules::ReviewRoundStore`
|
|
145
|
+
persists them in
|
|
146
|
+
`.ace-local/coworker/review-rounds/<assignment>.json` - record each
|
|
147
|
+
finished round with `ace-coworker rounds record --assignment <id>
|
|
148
|
+
--type full|delta --status completed|aborted [--confirmed id:sev,...]
|
|
149
|
+
[--resolved id,...]` and follow the printed verdict
|
|
150
|
+
(:escalate means the ace-hitl decision question above, never a
|
|
151
|
+
crashed run). A restart reloads the same file: the round counter and
|
|
152
|
+
findings history are never reset.
|
|
153
|
+
|
|
154
|
+
7. **Escalate, never fake success.**
|
|
155
|
+
- No effective fix after a genuine attempt, the same blocker recurring, or
|
|
156
|
+
a needed product/architecture decision:
|
|
157
|
+
`ace-hitl create "<title>" --kind decision --question "<options, impact,
|
|
158
|
+
what is blocked>" --to <overseer>`, then `ace-hitl send <id>`.
|
|
159
|
+
- Keep the step failed/open (`ace-assign fail` with the cause); report an
|
|
160
|
+
error outcome: `ace-coworker report --result error --message "<cause>"`.
|
|
161
|
+
- NEVER mark unresolved High/Critical as success. `report` derives the
|
|
162
|
+
outcome from the ace-assign verdict and refuses a forced success on an
|
|
163
|
+
incomplete assignment - the tool floor, not a courtesy.
|
|
164
|
+
|
|
165
|
+
8. **Record and hand off.**
|
|
166
|
+
- `ace-coworker report` writes the durable record
|
|
167
|
+
(`<task>/coworker/<assignment>.md`) and delivers the HITL report.
|
|
168
|
+
- The final report names: the exact candidate head, executed checks,
|
|
169
|
+
per-round dispositions (session paths under `.ace-local/review/`), fix
|
|
170
|
+
commits, and unresolved findings - consumable by the integrator role
|
|
171
|
+
(8xg.t.sbz.4.3) and the round-limit tooling (8xg.t.sbz.4.2). The
|
|
172
|
+
reviewed head is recorded as the full lowercase SHA from
|
|
173
|
+
`git rev-parse HEAD` (never a short form), because the integrator
|
|
174
|
+
compares it for drift against the candidate head on the same
|
|
175
|
+
normalization.
|
|
176
|
+
|
|
177
|
+
9. **Resume.**
|
|
178
|
+
- `ace-coworker resume` after interruption; same task, assignment, and
|
|
179
|
+
worktree. Resume from the recorded review sessions and the current
|
|
180
|
+
head: history is not erased, but evidence must bind the current
|
|
181
|
+
candidate. For steps named like external effects (merge/publish/deploy/
|
|
182
|
+
release/push) verify the actual state before repeating them.
|
|
183
|
+
|
|
184
|
+
## Completion Rule
|
|
185
|
+
|
|
186
|
+
The assignment is complete when the convergence rule is satisfied on the
|
|
187
|
+
exact candidate head (>= 3 full rounds, last 2 consecutive clean, no
|
|
188
|
+
unresolved High/Critical, within 10 rounds), every fix landed inside this
|
|
189
|
+
assignment with its diff checked, and the truthful outcome has been recorded
|
|
190
|
+
and reported. Anything less is an error outcome with the cause named.
|
|
191
|
+
|
|
192
|
+
## Reporting
|
|
193
|
+
|
|
194
|
+
- Outcome and progress are reported through `ace-coworker report` (channel
|
|
195
|
+
`hitl` by default; recipient = the config `overseer` address).
|
|
196
|
+
- Escalations travel as `ace-hitl` decision questions; errors follow
|
|
197
|
+
`errors.on_failure: report` (recorded and reported).
|
|
198
|
+
|
|
199
|
+
## Boundaries
|
|
200
|
+
|
|
201
|
+
- The reviewer never reviews its own worker output: this role runs only
|
|
202
|
+
after the worker's assignment completes, on the worker's delivered change.
|
|
203
|
+
- Fixes stay scoped to confirmed defects in the delivered change; no
|
|
204
|
+
speculative redesign, no scope growth beyond the commissioned goal.
|
|
205
|
+
- No merge, publish, deploy, release, or push beyond the assignment's own
|
|
206
|
+
steps.
|
|
207
|
+
- No new state owners, journals, or queues (ADR-034): `.ace-local/coworker/`
|
|
208
|
+
belongs to ace-coworker, `.ace-local/assign/` to ace-assign,
|
|
209
|
+
`.ace-local/review/` to ace-review, `.ace-local/hitl/` to ace-hitl.
|
|
210
|
+
- Inside the ACE repository itself, invoke every tool as `bin/ace-*` (the
|
|
211
|
+
binstubs pin the checkout's bundle).
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: coworker-spec
|
|
3
|
+
allowed-tools: Bash, Read
|
|
4
|
+
description: Spec role for the file-based lab. Creates or refines a complete behavior-first specification (WHAT, not HOW) inside the pinned assignment. A significant unresolved requirement gap is reported to the overseer via an ace-hitl question, never silently guessed. The deliverable lives in the task's own folder under .ace-tasks/.
|
|
5
|
+
doc-type: workflow
|
|
6
|
+
purpose: spec role workflow instruction
|
|
7
|
+
ace-docs:
|
|
8
|
+
last-updated: '2026-10-18'
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Spec - Deliver or Refine the Complete Specification
|
|
12
|
+
|
|
13
|
+
## Goal
|
|
14
|
+
|
|
15
|
+
Deliver a complete, behavior-first specification for the task: requirements
|
|
16
|
+
the planner and the worker can use without translation. The spec role
|
|
17
|
+
produces specifications, not implementations. A significant unresolved
|
|
18
|
+
requirement gap is never guessed away - it is reported to the overseer and
|
|
19
|
+
recorded, and when it blocks completeness it fails the assignment with the
|
|
20
|
+
gap named.
|
|
21
|
+
|
|
22
|
+
## Start State
|
|
23
|
+
|
|
24
|
+
- The run config `.ace-local/coworker/config.yml` names this role
|
|
25
|
+
(`role: spec`), this workflow (`instructions: wfi://coworker/spec`),
|
|
26
|
+
the task ref, the pinned assignment id, and the overseer address.
|
|
27
|
+
- `ace-coworker start` renders the executor brief and verifies the task and
|
|
28
|
+
the assignment against this worktree.
|
|
29
|
+
|
|
30
|
+
## Project Context Loading
|
|
31
|
+
|
|
32
|
+
- Read and follow: `ace-bundle wfi://bundle`
|
|
33
|
+
|
|
34
|
+
## Process
|
|
35
|
+
|
|
36
|
+
1. **Read the commission.**
|
|
37
|
+
- Run `ace-coworker start`; drive the assignment with the pinned
|
|
38
|
+
`--assignment <id>` in every ace-assign call.
|
|
39
|
+
- Read the task's current spec, its acceptance criteria, the program
|
|
40
|
+
contract, and any inherited materials; inherited materials are context,
|
|
41
|
+
not a mandate to keep their architecture.
|
|
42
|
+
|
|
43
|
+
2. **Draft behavior-first, complete.**
|
|
44
|
+
Write the specification in the task's own language with these sections
|
|
45
|
+
(essentials inlined; this file is self-contained):
|
|
46
|
+
- **Goal** - the single sentence the spec delivers.
|
|
47
|
+
- **Behavior and interface** - WHAT the system must do and through which
|
|
48
|
+
interface (commands, files, contracts), not HOW it is implemented.
|
|
49
|
+
- **Acceptance criteria** - checkable outcomes, each verifiable on its own.
|
|
50
|
+
- **Verification plan** - positive scenarios, error/invalid-input
|
|
51
|
+
scenarios, and where the evidence is recorded.
|
|
52
|
+
- **Dependencies and boundaries** - predecessors, exclusions, and the
|
|
53
|
+
state owners the spec must respect.
|
|
54
|
+
- When the full drafting conventions of the task toolchain help, load
|
|
55
|
+
`ace-bundle wfi://task/draft` - it supplements, never replaces, the
|
|
56
|
+
sections above.
|
|
57
|
+
|
|
58
|
+
3. **Resolve gaps - report, never guess.**
|
|
59
|
+
- A significant unresolved requirement gap (a decision that changes
|
|
60
|
+
behavior, an acceptance criterion that cannot be made checkable, a
|
|
61
|
+
contradiction in inputs) is escalated:
|
|
62
|
+
- create a question for the overseer:
|
|
63
|
+
`ace-hitl create "<gap in one line>" --type question --task <ref> --to <overseer> --question "<options, impact, what is blocked>"`,
|
|
64
|
+
then `ace-hitl send <id>`;
|
|
65
|
+
- record the gap in the task folder next to the spec.
|
|
66
|
+
- Continue only on items that are not blocked by the gap.
|
|
67
|
+
- If the gap blocks completeness of the deliverable, fail the step
|
|
68
|
+
(`ace-assign fail`) naming the gap and finish with an error outcome.
|
|
69
|
+
|
|
70
|
+
4. **Keep ownership.**
|
|
71
|
+
- The deliverable lives in the task's own folder under `.ace-tasks/`
|
|
72
|
+
(ace-task is the owner); write it there so planner and worker can use it
|
|
73
|
+
without translation.
|
|
74
|
+
- The spec role makes no code changes; only spec and docs changes within
|
|
75
|
+
its assignment.
|
|
76
|
+
|
|
77
|
+
5. **Finish and report.**
|
|
78
|
+
- `ace-assign finish` when the specification is complete; then
|
|
79
|
+
`ace-coworker report`. The outcome is derived from the assignment
|
|
80
|
+
verdict - never report a success the assignment does not support.
|
|
81
|
+
|
|
82
|
+
## Completion Rule
|
|
83
|
+
|
|
84
|
+
The assignment is complete when the specification is complete
|
|
85
|
+
(behavior-first, acceptance-checkable, gap state explicit), every unresolved
|
|
86
|
+
significant gap is reported to the overseer and recorded in the task folder,
|
|
87
|
+
and the truthful outcome has been recorded and reported.
|
|
88
|
+
|
|
89
|
+
## Reporting
|
|
90
|
+
|
|
91
|
+
- Outcome and progress are reported through `ace-coworker report` (channel
|
|
92
|
+
`hitl` by default; recipient = the config `overseer` address).
|
|
93
|
+
- Requirement gaps travel as `ace-hitl` questions, not as silent decisions.
|
|
94
|
+
|
|
95
|
+
## Boundaries
|
|
96
|
+
|
|
97
|
+
- Spec produces specifications and docs only; no runtime code changes.
|
|
98
|
+
- No new state owners, journals, or queues (ADR-034).
|
|
99
|
+
- Decisions that exceed the commission go to the overseer via `ace-hitl`;
|
|
100
|
+
an invented requirement is a defect, not a deliverable.
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: coworker-worker
|
|
3
|
+
allowed-tools: Bash, Read
|
|
4
|
+
description: Worker role for the file-based lab. Implements the commissioned change inside the pinned assignment and verifies it. Failed required tests block success - the step is failed via ace-assign, never falsely marked done. Drive the assignment via ace-assign, commit path-scoped, and report truthfully through ace-coworker.
|
|
5
|
+
doc-type: workflow
|
|
6
|
+
purpose: worker role workflow instruction
|
|
7
|
+
ace-docs:
|
|
8
|
+
last-updated: '2026-10-18'
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Worker - Implement and Verify the Commissioned Change
|
|
12
|
+
|
|
13
|
+
## Goal
|
|
14
|
+
|
|
15
|
+
Deliver the commissioned change for the task with verification: implement,
|
|
16
|
+
verify, and report. The worker drives its own pinned assignment to a verified
|
|
17
|
+
change. A change without passing required tests is not a result; a failed
|
|
18
|
+
required test blocks success and is reported as an error outcome, never as a
|
|
19
|
+
false "work done".
|
|
20
|
+
|
|
21
|
+
## Start State
|
|
22
|
+
|
|
23
|
+
- The run config `.ace-local/coworker/config.yml` names this role
|
|
24
|
+
(`role: worker`), this workflow (`instructions: wfi://coworker/worker`),
|
|
25
|
+
the task ref, the pinned assignment id, and the overseer address.
|
|
26
|
+
- `ace-coworker start` renders the executor brief and verifies the task and
|
|
27
|
+
the assignment against this worktree.
|
|
28
|
+
- After an interruption, `ace-coworker resume` renders the preserved state and
|
|
29
|
+
the resume path (same task, same assignment, same worktree).
|
|
30
|
+
|
|
31
|
+
## Project Context Loading
|
|
32
|
+
|
|
33
|
+
- Read and follow: `ace-bundle wfi://bundle`
|
|
34
|
+
|
|
35
|
+
## Process
|
|
36
|
+
|
|
37
|
+
1. **Read the commission.**
|
|
38
|
+
- Run `ace-coworker start` and follow the rendered brief; the assignment is
|
|
39
|
+
driven with the pinned `--assignment <id>` in every ace-assign call.
|
|
40
|
+
- Read the task spec and, when present, the approved plan
|
|
41
|
+
(`ace-task plan <ref>`). The goal and the acceptance criteria come from
|
|
42
|
+
the task; when they conflict with the assignment steps, report the
|
|
43
|
+
conflict instead of silently choosing.
|
|
44
|
+
|
|
45
|
+
2. **Drive the assignment via ace-assign.**
|
|
46
|
+
- Use `ace-assign step` / `start` / `finish` / `fail` (with the pinned
|
|
47
|
+
`--assignment`). The step plan stays solely with ace-assign.
|
|
48
|
+
- You may develop the assignment within the goal and role rules: add or
|
|
49
|
+
refine steps when the verified path requires it. Never change the parent
|
|
50
|
+
goal, the task dependencies, or the overseer tree.
|
|
51
|
+
|
|
52
|
+
3. **Implement.**
|
|
53
|
+
- Work only inside this worktree. Mark checkboxes and step states only when
|
|
54
|
+
the underlying work is verified.
|
|
55
|
+
- Commit path-scoped (`ace-git-commit <paths>`), verifying `git status`
|
|
56
|
+
first so only your paths are committed. Never reset or discard unrelated
|
|
57
|
+
changes.
|
|
58
|
+
- Follow repository conventions (AGENTS.md, ATOM architecture, style).
|
|
59
|
+
|
|
60
|
+
4. **Verify - required tests (completion gate).**
|
|
61
|
+
- For every changed package run `bin/ace-test <changed-package> all`.
|
|
62
|
+
- When the task requires monorepo validation, run `bin/ace-test-suite`.
|
|
63
|
+
- **Failed required tests block success.** On a failing required test:
|
|
64
|
+
- fix and rerun within this assignment; record the failure and the fix;
|
|
65
|
+
- while the failure stands, the step is failed (`ace-assign fail` with
|
|
66
|
+
the recorded error), never marked done, and never reported as success;
|
|
67
|
+
- if the failure is unfixable within the assignment, stop and report an
|
|
68
|
+
error outcome naming the cause.
|
|
69
|
+
|
|
70
|
+
5. **Finish and report.**
|
|
71
|
+
- Run `ace-coworker report`. The outcome is derived from the ace-assign
|
|
72
|
+
verdict: reporting a forced success on an incomplete assignment is
|
|
73
|
+
refused by the tool. Never send a false "work done"; when in doubt, the
|
|
74
|
+
assignment truth wins.
|
|
75
|
+
- After an interruption: `ace-coworker resume`, then continue. For steps
|
|
76
|
+
named like external effects (merge/publish/deploy/release/push) verify
|
|
77
|
+
the actual state with existing tools before repeating them - never
|
|
78
|
+
replay blindly.
|
|
79
|
+
|
|
80
|
+
## Completion Rule
|
|
81
|
+
|
|
82
|
+
The assignment is complete when the change is implemented, every required
|
|
83
|
+
test for every changed package passes (or the task's monorepo gate passes),
|
|
84
|
+
and the truthful outcome has been recorded and reported. A failing required
|
|
85
|
+
test means the work is NOT done, whatever the local state of the steps.
|
|
86
|
+
|
|
87
|
+
## Reporting
|
|
88
|
+
|
|
89
|
+
- Outcome and progress are reported through `ace-coworker report` (channel
|
|
90
|
+
`hitl` by default; recipient = the config `overseer` address).
|
|
91
|
+
- Errors: `errors.on_failure: report` (default) records and reports the
|
|
92
|
+
error outcome; `stop` records locally without sending.
|
|
93
|
+
|
|
94
|
+
## Boundaries
|
|
95
|
+
|
|
96
|
+
- The worker never reviews its own work - an independent reviewer decides
|
|
97
|
+
(the review role is a separate commission).
|
|
98
|
+
- No merge, publish, deploy, release, or push beyond the assignment's own
|
|
99
|
+
steps.
|
|
100
|
+
- No new state owners, journals, or queues (ADR-034); `.ace-local/coworker/`
|
|
101
|
+
belongs to ace-coworker, `.ace-local/assign/` to ace-assign.
|
|
102
|
+
- Unblocking decisions that exceed the commission go to the overseer via
|
|
103
|
+
`ace-hitl`, never silent improvisation.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ace
|
|
4
|
+
module Coworker
|
|
5
|
+
module Atoms
|
|
6
|
+
# Pure rule deciding whether a worktree holds an active executor.
|
|
7
|
+
#
|
|
8
|
+
# The commissioned assignment rules: the worktree's coworker config
|
|
9
|
+
# names an assignment (a commission was handed) and its state is
|
|
10
|
+
# anything other than completed — including unknown/unparseable, the
|
|
11
|
+
# conservative direction never destroys work. A completed commission
|
|
12
|
+
# falls through to the uncommissioned in-flight scan, so a finished
|
|
13
|
+
# commission never masks other running/stalled assignments. Without a
|
|
14
|
+
# commission record, only in-flight states (running/stalled) block, so
|
|
15
|
+
# up-front pending assignments from the role-sequence leaf never
|
|
16
|
+
# self-conflict.
|
|
17
|
+
module ActiveExecutorRule
|
|
18
|
+
UNPARSEABLE = :unparseable
|
|
19
|
+
IN_FLIGHT_STATES = %w[running stalled].freeze
|
|
20
|
+
private_constant :IN_FLIGHT_STATES
|
|
21
|
+
|
|
22
|
+
# @param config [nil, :unparseable, Hash] worktree coworker config
|
|
23
|
+
# (nil = missing file; :unparseable = present but unreadable)
|
|
24
|
+
# @param assignments [Array<Hash>] worktree assignments with "id"
|
|
25
|
+
# and "state" keys
|
|
26
|
+
# @return [Hash] {active: bool, evidence: {"assignment","state","source"} | nil}
|
|
27
|
+
def self.evaluate(config:, assignments:)
|
|
28
|
+
if config == UNPARSEABLE
|
|
29
|
+
return active(assignment: nil, state: "unparseable", source: "config")
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
if config.is_a?(Hash) && !config["assignment"].to_s.empty?
|
|
33
|
+
return commissioned(config["assignment"].to_s, assignments)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
in_flight(assignments)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Private class-method section (kept inline for atom simplicity).
|
|
40
|
+
|
|
41
|
+
def self.commissioned(assignment_id, assignments)
|
|
42
|
+
record = assignments.find { |a| a["id"].to_s == assignment_id }
|
|
43
|
+
state = record ? record["state"].to_s : "unknown"
|
|
44
|
+
# Commission finished; still block on other in-flight work.
|
|
45
|
+
return in_flight(assignments) if state == "completed"
|
|
46
|
+
|
|
47
|
+
active(assignment: assignment_id, state: state, source: "config")
|
|
48
|
+
end
|
|
49
|
+
private_class_method :commissioned
|
|
50
|
+
|
|
51
|
+
def self.in_flight(assignments)
|
|
52
|
+
assignments.each do |record|
|
|
53
|
+
state = record["state"].to_s
|
|
54
|
+
if IN_FLIGHT_STATES.include?(state)
|
|
55
|
+
return active(assignment: record["id"].to_s, state: state, source: "assignment")
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
{active: false, evidence: nil}
|
|
60
|
+
end
|
|
61
|
+
private_class_method :in_flight
|
|
62
|
+
|
|
63
|
+
def self.active(assignment:, state:, source:)
|
|
64
|
+
{active: true,
|
|
65
|
+
evidence: {"assignment" => assignment, "state" => state, "source" => source}.freeze}
|
|
66
|
+
end
|
|
67
|
+
private_class_method :active
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|