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
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 288508c14f62358d53a0fe59f3a772ea024fa370201285151439e5ab93de88ff
|
|
4
|
+
data.tar.gz: 84e997a0876ad657f0caf39502c65e4d553110306f8b9fd63d83e6c7e5623fc8
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: f73a2ccd21437dc1f44525ada59476246c7668abc4f9bfa26ca8356b8505447fd7bfc498a28baa8ad1ced52109f10b3871e53641e85cab4c249f1d0c8ed633b4
|
|
7
|
+
data.tar.gz: 4756deff6b2f919b3dfd307e17354605e4e5e5e4449a1a562f014d03045e26f083280efcb69598d49375c114775875a7f3d74e11c233721beabab78cac8a6642
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
# Integrator role preset (shipped gem defaults, overridable per project via
|
|
3
|
+
# .ace/coworker/roles/integrator.yml).
|
|
4
|
+
name: integrator
|
|
5
|
+
description: Merge gate for ready candidates; checks integrated dependencies, candidate-review head match, executed tests, and a fresh independent review verdict before merge, and withholds blocked merges
|
|
6
|
+
instructions: wfi://coworker/integrator
|
|
7
|
+
start_prompt: >-
|
|
8
|
+
Work as the {{role}} on task {{task}}: drive assignment {{assignment}} —
|
|
9
|
+
integrate the verified candidate after checking dependencies, current
|
|
10
|
+
changes, executed tests, and the independent review verdict, reporting the
|
|
11
|
+
actual outcome to the overseer at {{overseer}}.
|
|
12
|
+
reporting:
|
|
13
|
+
channel: hitl
|
|
14
|
+
errors:
|
|
15
|
+
on_failure: report
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
# Reviewer role preset (shipped gem defaults, overridable per project via
|
|
3
|
+
# .ace/coworker/roles/reviewer.yml).
|
|
4
|
+
name: reviewer
|
|
5
|
+
description: Independent exact-candidate reviewer; fixes confirmed defects itself within its own assignment, checks the fix diff, and returns to full review rounds; escalates instead of marking unresolved High/Critical as success
|
|
6
|
+
instructions: wfi://coworker/reviewer
|
|
7
|
+
start_prompt: >-
|
|
8
|
+
Work as the {{role}} on task {{task}}: drive assignment {{assignment}} —
|
|
9
|
+
review the delivered change independently, fix confirmed defects yourself
|
|
10
|
+
inside this assignment, check each fix diff, and run full review rounds,
|
|
11
|
+
reporting to the overseer at {{overseer}}.
|
|
12
|
+
reporting:
|
|
13
|
+
channel: hitl
|
|
14
|
+
errors:
|
|
15
|
+
on_failure: report
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
# Spec role preset (shipped gem defaults, overridable per project via
|
|
3
|
+
# .ace/coworker/roles/spec.yml).
|
|
4
|
+
name: spec
|
|
5
|
+
description: Creates or refines a complete behavior-first specification; significant unresolved gaps are reported, never guessed
|
|
6
|
+
instructions: wfi://coworker/spec
|
|
7
|
+
start_prompt: >-
|
|
8
|
+
Work as the {{role}} on task {{task}}: deliver or refine the complete
|
|
9
|
+
specification through assignment {{assignment}}, reporting to the overseer
|
|
10
|
+
at {{overseer}}.
|
|
11
|
+
reporting:
|
|
12
|
+
channel: hitl
|
|
13
|
+
errors:
|
|
14
|
+
on_failure: report
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
# Worker role preset (shipped gem defaults, overridable per project via
|
|
3
|
+
# .ace/coworker/roles/worker.yml).
|
|
4
|
+
name: worker
|
|
5
|
+
description: Implements the commissioned change and verifies it; failed required tests block success
|
|
6
|
+
instructions: wfi://coworker/worker
|
|
7
|
+
start_prompt: >-
|
|
8
|
+
Work as the {{role}} on task {{task}}: drive assignment {{assignment}} to a
|
|
9
|
+
verified change, reporting to the overseer at {{overseer}}.
|
|
10
|
+
reporting:
|
|
11
|
+
channel: hitl
|
|
12
|
+
errors:
|
|
13
|
+
on_failure: report
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
# Integrator role assignment process (shipped gem defaults, overridable
|
|
3
|
+
# per project via .ace/coworker/sequences/integrator.yml). Composed by the
|
|
4
|
+
# planner (ace-coworker prepare) into one ace-assign assignment for the
|
|
5
|
+
# integrator leg of the role sequence. The merge decision goes through
|
|
6
|
+
# the deterministic gate (ace-coworker gate /
|
|
7
|
+
# Ace::Coworker::Atoms::IntegrationGate).
|
|
8
|
+
role: integrator
|
|
9
|
+
description: "Integrator process for task {{task}}"
|
|
10
|
+
outcome: >-
|
|
11
|
+
The verified candidate for task {{task}} is merged, or the merge is
|
|
12
|
+
withheld with an explicit blocked gate verdict escalated to the
|
|
13
|
+
overseer.
|
|
14
|
+
steps:
|
|
15
|
+
- name: integrate-candidate
|
|
16
|
+
workflow: wfi://coworker/integrator
|
|
17
|
+
instructions:
|
|
18
|
+
- "Work as the integrator on task {{task}}: integrate the verified candidate after the reviewer assignment finished successfully."
|
|
19
|
+
- "Check `ace-coworker gate` with the candidate head, the reviewed head, the independent review verdict, the executed tests, and the integrated dependencies; an unknown fact is verified, never guessed."
|
|
20
|
+
- "Acceptance: a ready verdict merges the candidate (a merge that changes the candidate renews the checks and the review); a blocked verdict withholds the merge and escalates to the overseer via ace-hitl - withholding is a legitimate outcome, not a failure."
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
# Reviewer role assignment process (shipped gem defaults, overridable per
|
|
3
|
+
# project via .ace/coworker/sequences/reviewer.yml). Composed by the
|
|
4
|
+
# planner (ace-coworker prepare) into one ace-assign assignment for the
|
|
5
|
+
# reviewer leg of the role sequence. The reviewer is independent of the
|
|
6
|
+
# worker and follows the same 3/2/10 round rule enforced by
|
|
7
|
+
# ace-coworker rounds record (Ace::Coworker::Atoms::RoundRule).
|
|
8
|
+
role: reviewer
|
|
9
|
+
description: "Independent reviewer process for task {{task}}"
|
|
10
|
+
outcome: >-
|
|
11
|
+
Independent review of the delivered change for task {{task}} accepted
|
|
12
|
+
under the 3/2/10 round rule, with all confirmed defects fixed and
|
|
13
|
+
fix diffs checked inside this assignment.
|
|
14
|
+
steps:
|
|
15
|
+
- name: review-rounds
|
|
16
|
+
workflow: wfi://coworker/reviewer
|
|
17
|
+
instructions:
|
|
18
|
+
- "Work as the reviewer on task {{task}}: review the delivered change independently of the worker; fix confirmed defects yourself inside this assignment and check each fix diff with a delta round."
|
|
19
|
+
- "Record every full round with `ace-coworker rounds record --type full` and every fix-diff check with `--type delta`; the RoundRule verdict decides the outcome, aborted or incomplete rounds are never clean."
|
|
20
|
+
- "Acceptance (3/2/10): at least 3 completed full rounds, the last 2 consecutive rounds clean (no confirmed High/Critical), and no unresolved earlier High/Critical; a rule-satisfying round 10 ends in success, no acceptance after 10 full rounds escalates to the overseer via ace-hitl."
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
# Spec role assignment process (shipped gem defaults, overridable per
|
|
3
|
+
# project via .ace/coworker/sequences/spec.yml). Composed by the planner
|
|
4
|
+
# (ace-coworker prepare) into one ace-assign assignment for the spec leg
|
|
5
|
+
# of the role sequence.
|
|
6
|
+
role: spec
|
|
7
|
+
description: "Spec process for task {{task}}"
|
|
8
|
+
outcome: >-
|
|
9
|
+
Resolved requirements for task {{task}}: no material requirement gap is
|
|
10
|
+
left unresolved or guessed.
|
|
11
|
+
steps:
|
|
12
|
+
- name: clarify-requirements
|
|
13
|
+
workflow: wfi://coworker/spec
|
|
14
|
+
instructions:
|
|
15
|
+
- "Work as the spec role on task {{task}}: collect and resolve the requirement gaps that block implementation."
|
|
16
|
+
- "Acceptance: every material gap is either resolved from the task material or raised as an ace-hitl question to the overseer; guessing is never success."
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
# Worker role assignment process (shipped gem defaults, overridable per
|
|
3
|
+
# project via .ace/coworker/sequences/worker.yml). Composed by the planner
|
|
4
|
+
# (ace-coworker prepare) into one ace-assign assignment for the worker leg
|
|
5
|
+
# of the role sequence.
|
|
6
|
+
role: worker
|
|
7
|
+
description: "Worker process for task {{task}}"
|
|
8
|
+
outcome: >-
|
|
9
|
+
Verified implementation of task {{task}} on the task branch: every
|
|
10
|
+
modified package passes its required tests (bin/ace-test <pkg> all) and
|
|
11
|
+
the work is committed.
|
|
12
|
+
steps:
|
|
13
|
+
- name: work-on-task
|
|
14
|
+
workflow: wfi://coworker/worker
|
|
15
|
+
instructions:
|
|
16
|
+
- "Work as the worker on task {{task}}: implement the commissioned change following the worker role instructions."
|
|
17
|
+
- "Acceptance: the required tests of every modified package pass; failed required tests block success (ace-assign fail), never a forced done."
|
|
18
|
+
- name: verify-test
|
|
19
|
+
instructions:
|
|
20
|
+
- "Run bin/ace-test <package> all for every modified package and record the real test counts in the task results file."
|
|
21
|
+
- "Acceptance: 0 failures across all modified packages."
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
# WFI Sources Protocol Configuration for ace-coworker gem
|
|
3
|
+
# This enables workflow discovery from the installed ace-coworker gem
|
|
4
|
+
|
|
5
|
+
name: ace-coworker
|
|
6
|
+
type: gem
|
|
7
|
+
description: Coworker role workflow instructions from ace-coworker gem
|
|
8
|
+
priority: 10
|
|
9
|
+
|
|
10
|
+
# Configuration for workflow discovery within the gem
|
|
11
|
+
config:
|
|
12
|
+
# Relative path within the gem (default: handbook/workflow-instructions)
|
|
13
|
+
relative_path: handbook/workflow-instructions
|
|
14
|
+
|
|
15
|
+
# Pattern for finding workflow files (default: *.wf.md)
|
|
16
|
+
pattern: "*.wf.md"
|
|
17
|
+
|
|
18
|
+
# Enable discovery
|
|
19
|
+
enabled: true
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
## [0.6.0] - 2026-10-20
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- Trust-posture parity with `ace-lab verify`: the instruction resolver
|
|
16
|
+
never executes the repository-controlled `bin/ace-nav` binstub under
|
|
17
|
+
a privileged (root) run — only the PATH-installed resolver is used.
|
|
18
|
+
|
|
19
|
+
- `ace-coworker prepare` no longer reports readiness for a protocol
|
|
20
|
+
instruction URI (`wfi://`, `prompt://`, `tmpl://`) that the ace-nav
|
|
21
|
+
resolver rejects in the prepared worktree. Protocol sources now resolve
|
|
22
|
+
through the SAME `InstructionResolver`/ace-nav path that `start` uses,
|
|
23
|
+
BEFORE readiness is claimed; a resolver that runs and fails is a
|
|
24
|
+
`role_instructions` gap (never ready), while a missing ace-nav CLI
|
|
25
|
+
(`InstructionResolver::NavUnavailableError`, ENOENT) stays a
|
|
26
|
+
non-blocking unknown consistent with lab verify's posture toward an
|
|
27
|
+
absent checker.
|
|
28
|
+
|
|
29
|
+
### Added
|
|
30
|
+
|
|
31
|
+
- Readiness / gap reporting to the overseer in `ace-coworker prepare`
|
|
32
|
+
(8xg.t.sbz.3.3 / L4.4): every SUCCESSFUL preparation ends with a
|
|
33
|
+
READINESS report through ace-hitl (`--type report --result success`,
|
|
34
|
+
title `Preparation ready - <task>/<worktree-dir>`; a report expects
|
|
35
|
+
no reply) carrying the complete set to run the first step — worktree
|
|
36
|
+
(path/branch/disposition), every sequence leg, every start config,
|
|
37
|
+
and the exact first command (`ace-coworker start --config
|
|
38
|
+
.ace-local/coworker/prepare/<first-role>.yml` in the worktree) — so
|
|
39
|
+
the overseer never composes ace-assign details itself. Gaps never
|
|
40
|
+
pass as ready: role errors (unknown role, missing process
|
|
41
|
+
definition) become a `role_sequence` conflict and a missing overseer
|
|
42
|
+
address becomes a `missing_overseer` conflict — both exit 1, write
|
|
43
|
+
no start configs, and escalate to the overseer as a decision
|
|
44
|
+
question (the existing conflict path; question = a decision is
|
|
45
|
+
needed) with the concrete reasons: what is prepared, what is
|
|
46
|
+
missing, and the decision needed. The previous hard error `cannot
|
|
47
|
+
prepare start configs: no overseer address` is replaced by the
|
|
48
|
+
structured `missing_overseer` gap. The prepare result JSON/table
|
|
49
|
+
gained a `report` field (`{"kind": "readiness", "event": <id>,
|
|
50
|
+
"delivered": …}`, or the create/delivery failure under `error`); a
|
|
51
|
+
report delivery failure never undoes the preparation — the event id
|
|
52
|
+
stays available for an `ace-hitl send` retry. `--dry-run` reports
|
|
53
|
+
nothing (zero effects includes ace-hitl events). No new state owner:
|
|
54
|
+
events live with ace-hitl, helper state is none (ADR-034).
|
|
55
|
+
- Per-role executor start configs in `ace-coworker prepare`
|
|
56
|
+
(8xg.t.sbz.3.2 / L4.3): after composing the role-sequence assignments,
|
|
57
|
+
the planner also writes ONE start config per sequence leg into the
|
|
58
|
+
prepared worktree at `.ace-local/coworker/prepare/<role>.yml` — role,
|
|
59
|
+
instruction source, start prompt, task, assignment reference, overseer
|
|
60
|
+
address, and reporting/error rules — so `ace-coworker start --config
|
|
61
|
+
.ace-local/coworker/prepare/<role>.yml` (run inside the worktree)
|
|
62
|
+
begins a leg with zero ad-hoc setup. Ownership split stays one writer
|
|
63
|
+
per file: `prepare` owns `prepare/<role>.yml`, expanded through the
|
|
64
|
+
SAME commission primitive that writes the default `config.yml`, so the
|
|
65
|
+
round-trip guarantee ("what commission writes, start accepts") holds by
|
|
66
|
+
construction; `commission` remains the single writer of the default
|
|
67
|
+
config target. The leg configs require an overseer address (`--to`, or
|
|
68
|
+
the coworker config's `overseer` read leniently): a missing address
|
|
69
|
+
ends the preparation as a `missing_overseer` gap (see the L4.4 entry
|
|
70
|
+
above) instead of writing an incomplete config. Writing leg
|
|
71
|
+
configs never touches an active driver: the existing
|
|
72
|
+
active-executor/mismatched-worktree conflicts run first, and the
|
|
73
|
+
default `config.yml` is never written by prepare. Writes are
|
|
74
|
+
idempotent: identical leg configs are reported as `reused` without a
|
|
75
|
+
write, changed content as `updated`; `--dry-run` reports them as
|
|
76
|
+
`planned` with zero writes. New organism
|
|
77
|
+
`Ace::Coworker::Organisms::StartConfigWriter`; the prepare result
|
|
78
|
+
JSON/table gained a `start_configs` list (role, assignment, path,
|
|
79
|
+
disposition `created`/`reused`/`updated`/`planned`).
|
|
80
|
+
- Role-sequence assignment composition in `ace-coworker prepare`
|
|
81
|
+
(8xg.t.sbz.3.1 / L4.2): after finding or preparing the task worktree,
|
|
82
|
+
the planner composes the assignments for the WHOLE known role sequence in
|
|
83
|
+
one go — one `ace-assign` assignment per role in dependency order, stored
|
|
84
|
+
by ace-assign in the worktree's `.ace-local/assign/` (no second queue;
|
|
85
|
+
ADR-034) — so after start the roles hand off sequentially without the
|
|
86
|
+
overseer re-commissioning preparation per step. Each assignment records
|
|
87
|
+
the task id, its sequence position (`sequence N/M`), the expected outcome
|
|
88
|
+
of the leg, and — for every leg after the first — an explicit entry
|
|
89
|
+
condition naming the predecessor assignment and role. Per-role processes
|
|
90
|
+
come from new shipped sequence definitions overridable per project
|
|
91
|
+
(`.ace-defaults/coworker/sequences/<role>.yml`, project override
|
|
92
|
+
`.ace/coworker/sequences/<role>.yml`): worker (implementation plus
|
|
93
|
+
per-package `bin/ace-test` verification), spec (material requirement gaps
|
|
94
|
+
become `ace-hitl` questions, never guesses), reviewer (embeds the 3/2/10
|
|
95
|
+
round rule via `ace-coworker rounds record`: min 3 completed full rounds,
|
|
96
|
+
last 2 consecutive clean, no unresolved earlier High/Critical, max 10
|
|
97
|
+
then escalation), and integrator (runs the `ace-coworker gate` checks
|
|
98
|
+
before any merge; withholding is a legitimate outcome). A role without a
|
|
99
|
+
preset or without its own process definition is reported with exit 1 and
|
|
100
|
+
nothing is composed (all-or-nothing) — another role's process is never
|
|
101
|
+
substituted. Composition is idempotent: re-preparation reuses
|
|
102
|
+
already-composed assignments (matched by `<task>-<role>` name plus
|
|
103
|
+
recorded task_id) without writes; `--dry-run` composes nothing. New
|
|
104
|
+
molecule `Ace::Coworker::Molecules::RoleSequenceComposer`; the prepare
|
|
105
|
+
result JSON/table gained an ordered `assignments` list (role, position,
|
|
106
|
+
assignment id, disposition `created`/`existing`, step count, expected
|
|
107
|
+
outcome).
|
|
108
|
+
|
|
109
|
+
- Integrator role (8xg.t.sbz.4.3 / L5.2): the fourth coworker role preset
|
|
110
|
+
`integrator` (shipped in `.ace-defaults/coworker/roles/integrator.yml`,
|
|
111
|
+
workflow `wfi://coworker/integrator`). It performs the project-defined
|
|
112
|
+
integration: before merging it checks (a) dependencies are integrated
|
|
113
|
+
predecessors (an open PR or "work done" message never substitutes), (b)
|
|
114
|
+
the candidate head still matches the reviewed head (no drift), (c) tests
|
|
115
|
+
were executed and passed (real evidence; CI stays advisory), and (d) a
|
|
116
|
+
fresh independent review verdict accepts the EXACT candidate head. A
|
|
117
|
+
stale review after a candidate change, an unsatisfied dependency, or
|
|
118
|
+
missing test evidence WITHHOLDS the merge and escalates to the overseer
|
|
119
|
+
via `ace-hitl`; an uncertain operation outcome (merge/push) is verified
|
|
120
|
+
against the real state, never retried blind. A merge that changes the
|
|
121
|
+
candidate (conflict resolution) renews the checks and the review before
|
|
122
|
+
the result counts as integrated. The role drives git/ace-git; no merge
|
|
123
|
+
is performed in code. No new persisted artifact kind: integration
|
|
124
|
+
decisions persist in the assignment's existing report state.
|
|
125
|
+
- `ace-coworker gate`: deterministic pre-merge gate surface for the
|
|
126
|
+
integrator role over the new pure atom
|
|
127
|
+
`Ace::Coworker::Atoms::IntegrationGate`. `ace-coworker gate
|
|
128
|
+
--candidate-head <sha> --review-head <sha> --review-verdict
|
|
129
|
+
accept|continue|escalate --tests executed,passed
|
|
130
|
+
--dep <leaf>=integrated|missing [...]` evaluates the four checks and
|
|
131
|
+
prints `ready` or `blocked` with per-check reasons (dependencies,
|
|
132
|
+
candidate drift, stale/missing review evidence, executed+passing tests).
|
|
133
|
+
Unknown facts (omitted heads, missing sections) block with an explicit
|
|
134
|
+
verify-instead-of-guess reason rather than being assumed. `blocked` is a
|
|
135
|
+
legitimate gate outcome (exit 0); only malformed input fails - an invalid
|
|
136
|
+
`--dep` pair (missing `=`), a duplicate `--dep` name, or an unknown
|
|
137
|
+
`--tests` token (expected: executed, passed). Heads are recorded and
|
|
138
|
+
compared as full lowercase SHAs (case drift is tolerated, length mismatch
|
|
139
|
+
is not). Stateless: readiness only, no writes, no merges.
|
|
140
|
+
|
|
141
|
+
- `ace-coworker rounds record --assignment <id> --type full|delta --status
|
|
142
|
+
completed|aborted [--confirmed id:sev,...] [--resolved id,...]`: CLI
|
|
143
|
+
surface for the 3/2/10 enforcement (8xg.t.sbz.4.2) used by the reviewer
|
|
144
|
+
workflow. Appends one finished round to the coworker-owned history at
|
|
145
|
+
`.ace-local/coworker/review-rounds/<assignment>.json`
|
|
146
|
+
(`Molecules::ReviewRoundStore#record!`, validated at the boundary by
|
|
147
|
+
`Atoms::RoundRecordSchema`) and prints the resulting verdict with its
|
|
148
|
+
counters. A corrupt or non-array history file fails with `corrupt round
|
|
149
|
+
history at <path>` instead of silently resetting the round counters, and
|
|
150
|
+
the 10-round cap is terminal: a rule-satisfying state at round 11+
|
|
151
|
+
escalates instead of accepting.
|
|
152
|
+
- Review-round convergence enforcement (8xg.t.sbz.4.2 / L5.2): the 3/2/10
|
|
153
|
+
rule is now working code. `Ace::Coworker::Atoms::RoundRule` is a pure
|
|
154
|
+
evaluator over round records (type full|delta, status
|
|
155
|
+
completed|aborted, confirmed severities, resolved references) returning
|
|
156
|
+
an explicit verdict `:continue | :accept | :escalate` plus derived
|
|
157
|
+
counters (full rounds, completed full rounds, consecutive clean,
|
|
158
|
+
unresolved High/Critical). Minimum 3 full rounds with the last 2
|
|
159
|
+
consecutive clean and no unresolved earlier High/Critical accepts
|
|
160
|
+
(so clean/clean/clean and error/clean/clean both finish at round 3);
|
|
161
|
+
no acceptance after 10 full rounds escalates as an outcome, never an
|
|
162
|
+
exception. Delta/fix-diff rounds never advance the counters;
|
|
163
|
+
interrupted/aborted rounds are not clean and a confirmed High/Critical
|
|
164
|
+
resets the streak. `Molecules::ReviewRoundStore` persists the round
|
|
165
|
+
history per assignment in
|
|
166
|
+
`.ace-local/coworker/review-rounds/<assignment>.json` (the
|
|
167
|
+
coworker-owned location, following `ReportStateStore`), so a restart
|
|
168
|
+
reloads the counters and findings history instead of resetting them.
|
|
169
|
+
- Reviewer role (8xg.t.sbz.4.1 / L5.2): shipped preset
|
|
170
|
+
`.ace-defaults/coworker/roles/reviewer.yml` and the self-contained
|
|
171
|
+
`wfi://coworker/reviewer` workflow. The reviewer is independent of the
|
|
172
|
+
worker, fixes confirmed defects itself inside its own single assignment
|
|
173
|
+
(steps added via `ace-assign add`), checks each fix diff, and returns to
|
|
174
|
+
full review rounds under the 3/2/10 convergence rule (deterministic
|
|
175
|
+
enforcement landed as 8xg.t.sbz.4.2, see above). No effective fix or a
|
|
176
|
+
needed product decision is escalated via an `ace-hitl` decision question;
|
|
177
|
+
unresolved High/Critical is never marked as success.
|
|
178
|
+
- `ace-review` declared as a runtime dependency: the reviewer role's primary
|
|
179
|
+
function drives the `ace-review`/`ace-review-feedback` CLIs, matching the
|
|
180
|
+
gemspec's stated policy of declaring runtime CLI requirements.
|
|
181
|
+
|
|
182
|
+
### Fixed
|
|
183
|
+
|
|
184
|
+
- `prepare --dry-run` is now zero-write on EXISTING worktrees too
|
|
185
|
+
(PR #393 audit): `PrepareOrchestrator` passes `dry_run` through to
|
|
186
|
+
`RoleSequenceComposer`, which resolves the whole sequence read-only —
|
|
187
|
+
already-composed legs are reported as `existing`, missing legs as
|
|
188
|
+
`planned` with no assignment id — and `StartConfigWriter` plans such
|
|
189
|
+
legs without commissioning them (a real run still requires a composed
|
|
190
|
+
assignment per leg). Previously a dry-run reuse/extension of an
|
|
191
|
+
existing worktree created real ace-assign assignments (e.g. a real
|
|
192
|
+
reviewer `assignment.yaml` after extending `--roles worker` to
|
|
193
|
+
`--roles worker,reviewer --dry-run`), mutating execution state during
|
|
194
|
+
a preview.
|
|
195
|
+
- `prepare` never reports readiness when a leg's instruction source does
|
|
196
|
+
not resolve (never-ready-on-missing-context, 8xg.t.sbz.3.2/.3.3):
|
|
197
|
+
before any start config is written or readiness reported, the
|
|
198
|
+
instruction source of EVERY leg is resolved through the existing
|
|
199
|
+
loader in the prepared worktree (file-path sources in-process; protocol
|
|
200
|
+
URIs stay delegated to ace-nav at start time). A missing source (e.g.
|
|
201
|
+
`instructions: roles/nonexistent.md`) is a new `role_instructions`
|
|
202
|
+
conflict — exit 1, no leg config written, escalated to the overseer as
|
|
203
|
+
a decision question — instead of a success whose emitted first-leg
|
|
204
|
+
start command fails immediately with "instruction file not found".
|
|
205
|
+
- `RoundRule` (3/2/10 review convergence): a completed delta round that
|
|
206
|
+
CONFIRMS a High/Critical finding now invalidates the prior clean
|
|
207
|
+
streak — even when the same delta (or a separate fix delta) resolves
|
|
208
|
+
the finding — so renewed clean full-round evidence is required before
|
|
209
|
+
`accept`. Previously three clean full rounds followed by a
|
|
210
|
+
High-confirmed delta (even resolved) still yielded `accept` with a
|
|
211
|
+
stale `consecutive_clean: 3`. Full-round counting (3/2/10 cap) is
|
|
212
|
+
unchanged; deltas without a confirmed High/Critical stay transparent.
|
|
213
|
+
- `RoleSequenceComposer` raises the actionable
|
|
214
|
+
`invalid assignment process` `Ace::Coworker::Error` for malformed
|
|
215
|
+
sequence step entries (e.g. a project override
|
|
216
|
+
`.ace/coworker/sequences/worker.yml` with `steps: [42]` or
|
|
217
|
+
`steps: [null]`) instead of a raw `TypeError`/`NoMethodError`, so
|
|
218
|
+
malformed user process data flows through the intended `role_sequence`
|
|
219
|
+
gap/HITL escalation in `prepare` instead of crashing it.
|
|
220
|
+
- `WorktreeExecutorProbe` cascade (8xi1p4z2): an unparseable nearest
|
|
221
|
+
cascade layer (e.g. unresolved merge-conflict markers in the
|
|
222
|
+
worktree's own `coworker/config.yml`) is now skipped per-layer,
|
|
223
|
+
exactly like a non-mapping layer, instead of discarding the whole
|
|
224
|
+
merge and silently reverting the probe to the default config
|
|
225
|
+
location — a commissioned executor at a cascade-overridden
|
|
226
|
+
`config_path` stays detected. The user-tier (`~/.ace`) override is
|
|
227
|
+
covered by a stubbed-HOME test (8xi1p4z8).
|
|
228
|
+
- `WorktreeExecutorProbe` cascade (8xi16mz3): a non-mapping cascade
|
|
229
|
+
layer (e.g. a `coworker/config.yml` containing a YAML list) is now
|
|
230
|
+
skipped instead of wiping the already-merged farther tiers, so valid
|
|
231
|
+
configuration (including a `config_path` override) from other tiers
|
|
232
|
+
survives. The probe's deliberate read-only asymmetry — following the
|
|
233
|
+
cascade-resolved `config_path` without the orchestrator's
|
|
234
|
+
project-root containment, since it only reads what the worktree's
|
|
235
|
+
loader process would read anyway — is now documented in the code
|
|
236
|
+
(8xi16mz4).
|
|
237
|
+
- Render start-prompt placeholders in a single pass derived from `PromptTemplate::PLACEHOLDERS`, so substituted values shaped like a later placeholder are never re-expanded.
|
|
238
|
+
- Raise a specific `invalid role preset` error for malformed YAML preset files (all `Psych::Exception` load failures), instead of a raw backtrace.
|
|
239
|
+
- Correct the spec role workflow's escalation command to the required `ace-hitl create "<title>" --type question ... --question "..."` form.
|
|
240
|
+
- `prepare` reads the target worktree's coworker config through the coworker
|
|
241
|
+
config cascade anchored at that worktree (project `.ace` tiers plus the
|
|
242
|
+
user tier), so a commission written under a configured `config_path`
|
|
243
|
+
(e.g. `.ace-local/coworker/worker.yml`) is detected as an active
|
|
244
|
+
executor instead of being missed because of the hard-coded default
|
|
245
|
+
location.
|
|
246
|
+
- `commission` canonicalizes the task identity before the assignment match
|
|
247
|
+
and the config write: a short task ref of the recorded task (e.g. `ccc`
|
|
248
|
+
for `8xh.t.ccc`) is accepted and the config stores the resolved full id,
|
|
249
|
+
while an assignment genuinely belonging to another task stays rejected.
|
|
250
|
+
- Reviewer workflow instruction (`wfi://coworker/reviewer`): newly named
|
|
251
|
+
fix steps are added via `ace-assign add --yaml <file> --assignment <id>`
|
|
252
|
+
(top-level `steps:` array with `name`/`instructions`, example included);
|
|
253
|
+
`--step` is documented as selecting an existing preset-catalog step
|
|
254
|
+
definition only — it cannot mint a new step name.
|
|
255
|
+
|
data/README.md
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# ace-coworker
|
|
2
|
+
|
|
3
|
+
Prepared executor for the file-based ACE lab: `ace-coworker` reads the run
|
|
4
|
+
configuration under `.ace-local/coworker/`, validates it against the real task
|
|
5
|
+
and assignment in the current worktree, and renders the executor brief that
|
|
6
|
+
pins the assignment to drive. It is a composition tool in the spirit of
|
|
7
|
+
`ace-overseer`: it owns **only** `.ace-local/coworker/` and composes the
|
|
8
|
+
existing owners (`ace-task` ref resolution, `ace-assign` lifecycle via its CLI,
|
|
9
|
+
`ace-hitl` reporting via its CLI) without copying their state or adding a
|
|
10
|
+
second queue, journal, or daemon (ADR-034).
|
|
11
|
+
|
|
12
|
+
This is the new L3 file-based coworker; the historical `ace-coworker` gem was
|
|
13
|
+
renamed to `ace-assign` at v0.6.0 and there is no compatibility with old
|
|
14
|
+
`.cache/ace-coworker` paths (ADR-024).
|
|
15
|
+
|
|
16
|
+
## Commands
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
ace-coworker start [--config PATH] [--format table|json]
|
|
20
|
+
ace-coworker status [--config PATH] [--assignment ID] [--format table|json]
|
|
21
|
+
ace-coworker report [--result success|error] [--message TEXT] [--no-send] [--dry-run]
|
|
22
|
+
ace-coworker resume [--dry-run] # Resume interrupted work in this worktree
|
|
23
|
+
ace-coworker prepare --task REF --roles worker,reviewer [--to ADDR] [--dry-run]
|
|
24
|
+
ace-coworker roles # List role presets (gem + project)
|
|
25
|
+
ace-coworker commission --role worker --task REF --assignment ID --overseer ADDR
|
|
26
|
+
ace-coworker gate --candidate-head SHA --review-head SHA --review-verdict accept
|
|
27
|
+
--tests executed,passed --dep LEAF=integrated
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
- `prepare` — the planner side: accept a preparation commission (task +
|
|
31
|
+
expected role sequence) and find or prepare exactly one proper worktree for
|
|
32
|
+
the task, THEN compose the assignments for the whole role sequence in one
|
|
33
|
+
go (L4.2): one `ace-assign` assignment per role in dependency order, stored
|
|
34
|
+
in the worktree's `.ace-local/assign/` with explicit entry conditions, the
|
|
35
|
+
expected outcome of each leg, and the role's process definition (shipped
|
|
36
|
+
`.ace-defaults/coworker/sequences/<role>.yml`, project override
|
|
37
|
+
`.ace/coworker/sequences/<role>.yml` — the reviewer leg embeds the 3/2/10
|
|
38
|
+
round rule, the integrator leg the `ace-coworker gate` checks). Re-preparing
|
|
39
|
+
reuses the worktree and the already-composed assignments without writes; an
|
|
40
|
+
active executor or a mismatched worktree escalates a decision question to
|
|
41
|
+
the overseer via `ace-hitl` instead of overwriting work; a role without its
|
|
42
|
+
own process is reported and nothing is composed — another role's process is
|
|
43
|
+
never substituted.
|
|
44
|
+
|
|
45
|
+
- `roles` / `commission` — role presets and the role-instantiation primitive
|
|
46
|
+
consumed by the planner (L4.2/L4.3 seam). Shipped presets: `worker`
|
|
47
|
+
(implement and verify; failed required tests block success), `spec`
|
|
48
|
+
(complete behavior-first specification; significant unresolved gaps are
|
|
49
|
+
reported via `ace-hitl`, never guessed), and `reviewer` (independent
|
|
50
|
+
review that fixes confirmed defects itself inside its own assignment,
|
|
51
|
+
checks each fix diff, and returns to full review rounds under the 3/2/10
|
|
52
|
+
convergence rule — escalating instead of marking unresolved High/Critical
|
|
53
|
+
as success), and `integrator` (result-dependent integration: merges only
|
|
54
|
+
candidates whose dependencies are integrated, whose head matches the
|
|
55
|
+
reviewed head, whose tests were executed and passed, and whose fresh
|
|
56
|
+
independent review verdict accepts the exact candidate; withheld merges
|
|
57
|
+
are blocked and escalated, never merged past the gate), backed by the
|
|
58
|
+
self-contained workflows `wfi://coworker/worker` / `wfi://coworker/spec` /
|
|
59
|
+
`wfi://coworker/reviewer` / `wfi://coworker/integrator`. `roles` lists
|
|
60
|
+
the catalog (gem defaults + project overrides in `.ace/coworker/roles/`);
|
|
61
|
+
`commission` expands a preset plus the commission identity into
|
|
62
|
+
`.ace-local/coworker/config.yml` — start-grade identity checks, atomic
|
|
63
|
+
write, overwrite refused without `--force`, `--dry-run` renders without
|
|
64
|
+
writing. Sequencing and active-driver guards stay with the planner.
|
|
65
|
+
|
|
66
|
+
- `gate` — the integrator role's deterministic pre-merge check
|
|
67
|
+
(`Ace::Coworker::Atoms::IntegrationGate`): evaluates candidate head vs
|
|
68
|
+
reviewed head (stale review), executed+passing tests, review verdict, and
|
|
69
|
+
per-dependency integration states, and prints `ready` or `blocked` with
|
|
70
|
+
per-check reasons. Pure and stateless — it decides readiness only; the
|
|
71
|
+
integrator role drives git/ace-git. `blocked` is a legitimate gate outcome
|
|
72
|
+
(exit 0); only invalid input fails.
|
|
73
|
+
|
|
74
|
+
- `start` — validate the prepared config (role, instructions, start prompt,
|
|
75
|
+
task, assignment, overseer, error rules), verify the task resolves in this
|
|
76
|
+
worktree and the assignment exists and matches the task, resolve the
|
|
77
|
+
instruction source, and print the executor brief. Writes nothing. Missing or
|
|
78
|
+
mismatched input fails with a specific `not ready:` / `invalid config:` /
|
|
79
|
+
mismatch error — it never guesses another commission and never creates a
|
|
80
|
+
substitute assignment or worktree.
|
|
81
|
+
- `status` — readiness query. Renders `not ready: .ace-local/coworker/config.yml
|
|
82
|
+
not found` (exit 0) when unprepared, otherwise the resolved identity,
|
|
83
|
+
assignment progress from `ace-assign status --format json`, and the
|
|
84
|
+
completion verdict (`complete` only when the assignment state is completed,
|
|
85
|
+
the plan is non-empty, and every step is done).
|
|
86
|
+
|
|
87
|
+
The config format consumed by the planner (L4) is documented in
|
|
88
|
+
[docs/usage.md](docs/usage.md).
|
|
89
|
+
|
|
90
|
+
## Development
|
|
91
|
+
|
|
92
|
+
Tests: `bin/ace-test ace-coworker all` from the repository root. See
|
|
93
|
+
[CONTRIBUTING](../docs/ace-gems.g.md) for gem conventions (ATOM architecture,
|
|
94
|
+
ADR-022 config cascade, dry-cli commands).
|
|
95
|
+
|
|
96
|
+
## License
|
|
97
|
+
|
|
98
|
+
MIT — see [LICENSE](../LICENSE).
|
data/Rakefile
ADDED