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.
Files changed (77) hide show
  1. checksums.yaml +7 -0
  2. data/.ace-defaults/coworker/config.yml +6 -0
  3. data/.ace-defaults/coworker/roles/integrator.yml +15 -0
  4. data/.ace-defaults/coworker/roles/reviewer.yml +15 -0
  5. data/.ace-defaults/coworker/roles/spec.yml +14 -0
  6. data/.ace-defaults/coworker/roles/worker.yml +13 -0
  7. data/.ace-defaults/coworker/sequences/integrator.yml +20 -0
  8. data/.ace-defaults/coworker/sequences/reviewer.yml +20 -0
  9. data/.ace-defaults/coworker/sequences/spec.yml +16 -0
  10. data/.ace-defaults/coworker/sequences/worker.yml +21 -0
  11. data/.ace-defaults/nav/protocols/wfi-sources/ace-coworker.yml +19 -0
  12. data/CHANGELOG.md +255 -0
  13. data/README.md +98 -0
  14. data/Rakefile +13 -0
  15. data/docs/usage.md +564 -0
  16. data/exe/ace-coworker +16 -0
  17. data/handbook/workflow-instructions/coworker/integrator.wf.md +162 -0
  18. data/handbook/workflow-instructions/coworker/reviewer.wf.md +211 -0
  19. data/handbook/workflow-instructions/coworker/spec.wf.md +100 -0
  20. data/handbook/workflow-instructions/coworker/worker.wf.md +103 -0
  21. data/lib/ace/coworker/atoms/active_executor_rule.rb +71 -0
  22. data/lib/ace/coworker/atoms/brief_formatter.rb +33 -0
  23. data/lib/ace/coworker/atoms/config_schema.rb +121 -0
  24. data/lib/ace/coworker/atoms/integration_gate.rb +92 -0
  25. data/lib/ace/coworker/atoms/outcome_planner.rb +79 -0
  26. data/lib/ace/coworker/atoms/prepare_decision.rb +75 -0
  27. data/lib/ace/coworker/atoms/prompt_template.rb +28 -0
  28. data/lib/ace/coworker/atoms/report_record_formatter.rb +60 -0
  29. data/lib/ace/coworker/atoms/resume_brief_formatter.rb +84 -0
  30. data/lib/ace/coworker/atoms/resume_planner.rb +78 -0
  31. data/lib/ace/coworker/atoms/role_preset_schema.rb +91 -0
  32. data/lib/ace/coworker/atoms/round_record_schema.rb +62 -0
  33. data/lib/ace/coworker/atoms/round_rule.rb +105 -0
  34. data/lib/ace/coworker/cli/commands/commission.rb +100 -0
  35. data/lib/ace/coworker/cli/commands/gate.rb +91 -0
  36. data/lib/ace/coworker/cli/commands/prepare.rb +138 -0
  37. data/lib/ace/coworker/cli/commands/report.rb +79 -0
  38. data/lib/ace/coworker/cli/commands/resume.rb +57 -0
  39. data/lib/ace/coworker/cli/commands/roles.rb +60 -0
  40. data/lib/ace/coworker/cli/commands/rounds.rb +99 -0
  41. data/lib/ace/coworker/cli/commands/start.rb +39 -0
  42. data/lib/ace/coworker/cli/commands/status.rb +95 -0
  43. data/lib/ace/coworker/cli.rb +83 -0
  44. data/lib/ace/coworker/errors.rb +10 -0
  45. data/lib/ace/coworker/models/assignment_snapshot.rb +65 -0
  46. data/lib/ace/coworker/models/brief.rb +38 -0
  47. data/lib/ace/coworker/models/config.rb +54 -0
  48. data/lib/ace/coworker/models/outcome.rb +39 -0
  49. data/lib/ace/coworker/models/preparation.rb +67 -0
  50. data/lib/ace/coworker/models/resume_plan.rb +47 -0
  51. data/lib/ace/coworker/molecules/assignment_metadata.rb +57 -0
  52. data/lib/ace/coworker/molecules/assignment_probe.rb +57 -0
  53. data/lib/ace/coworker/molecules/config_loader.rb +119 -0
  54. data/lib/ace/coworker/molecules/git_state_probe.rb +63 -0
  55. data/lib/ace/coworker/molecules/hitl_reporter.rb +145 -0
  56. data/lib/ace/coworker/molecules/instruction_resolver.rb +82 -0
  57. data/lib/ace/coworker/molecules/project_root.rb +26 -0
  58. data/lib/ace/coworker/molecules/report_state_store.rb +53 -0
  59. data/lib/ace/coworker/molecules/review_round_store.rb +115 -0
  60. data/lib/ace/coworker/molecules/role_preset_loader.rb +95 -0
  61. data/lib/ace/coworker/molecules/role_sequence_composer.rb +245 -0
  62. data/lib/ace/coworker/molecules/step_evidence_reader.rb +60 -0
  63. data/lib/ace/coworker/molecules/step_report_reader.rb +39 -0
  64. data/lib/ace/coworker/molecules/task_probe.rb +40 -0
  65. data/lib/ace/coworker/molecules/task_record_writer.rb +44 -0
  66. data/lib/ace/coworker/molecules/worktree_executor_probe.rb +139 -0
  67. data/lib/ace/coworker/molecules/worktree_provision_probe.rb +137 -0
  68. data/lib/ace/coworker/organisms/commission_orchestrator.rb +148 -0
  69. data/lib/ace/coworker/organisms/prepare_orchestrator.rb +374 -0
  70. data/lib/ace/coworker/organisms/report_orchestrator.rb +192 -0
  71. data/lib/ace/coworker/organisms/resume_orchestrator.rb +91 -0
  72. data/lib/ace/coworker/organisms/start_config_writer.rb +127 -0
  73. data/lib/ace/coworker/organisms/start_orchestrator.rb +45 -0
  74. data/lib/ace/coworker/organisms/status_orchestrator.rb +62 -0
  75. data/lib/ace/coworker/version.rb +7 -0
  76. data/lib/ace/coworker.rb +86 -0
  77. 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