ace-coworker 0.8.0 → 0.9.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 (35) hide show
  1. checksums.yaml +4 -4
  2. data/.ace-defaults/coworker/sequences/reviewer.yml +5 -0
  3. data/.ace-defaults/coworker/sequences/worker.yml +8 -3
  4. data/CHANGELOG.md +6 -0
  5. data/README.md +18 -0
  6. data/docs/usage.md +8 -2
  7. data/handbook/workflow-instructions/coworker/bootstrap-verifier.wf.md +26 -2
  8. data/handbook/workflow-instructions/coworker/bootstrap-worker.wf.md +37 -1
  9. data/handbook/workflow-instructions/coworker/integrator.wf.md +26 -8
  10. data/handbook/workflow-instructions/coworker/reviewer.wf.md +62 -14
  11. data/handbook/workflow-instructions/coworker/worker.wf.md +37 -3
  12. data/lib/ace/coworker/atoms/brief_formatter.rb +5 -3
  13. data/lib/ace/coworker/atoms/config_schema.rb +7 -4
  14. data/lib/ace/coworker/atoms/integration_gate.rb +8 -4
  15. data/lib/ace/coworker/atoms/resume_planner.rb +9 -7
  16. data/lib/ace/coworker/atoms/role_preset_schema.rb +5 -3
  17. data/lib/ace/coworker/cli/commands/gate.rb +3 -3
  18. data/lib/ace/coworker/cli/commands/prepare.rb +6 -2
  19. data/lib/ace/coworker/cli/commands/status.rb +0 -4
  20. data/lib/ace/coworker/models/brief.rb +2 -0
  21. data/lib/ace/coworker/models/config.rb +5 -4
  22. data/lib/ace/coworker/models/outcome.rb +4 -0
  23. data/lib/ace/coworker/molecules/config_loader.rb +8 -0
  24. data/lib/ace/coworker/molecules/execution_binding.rb +39 -0
  25. data/lib/ace/coworker/molecules/hitl_reporter.rb +37 -0
  26. data/lib/ace/coworker/molecules/worktree_executor_probe.rb +15 -44
  27. data/lib/ace/coworker/molecules/worktree_provision_probe.rb +3 -3
  28. data/lib/ace/coworker/organisms/commission_orchestrator.rb +16 -13
  29. data/lib/ace/coworker/organisms/prepare_orchestrator.rb +18 -4
  30. data/lib/ace/coworker/organisms/report_orchestrator.rb +12 -6
  31. data/lib/ace/coworker/organisms/resume_orchestrator.rb +9 -2
  32. data/lib/ace/coworker/organisms/start_config_writer.rb +10 -1
  33. data/lib/ace/coworker/organisms/status_orchestrator.rb +2 -3
  34. data/lib/ace/coworker/version.rb +1 -1
  35. metadata +29 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b33e4050f914bca417193b67ba22d076a9a7866a89d1d3465fe6fb344f7bca7d
4
- data.tar.gz: 1cba8a3b7b85957083d95da14d5cf2fb44988ebc2b7efdc8537b24eda096612b
3
+ metadata.gz: 2c6668db21df711cc2665adeec0c98ba62f6c97c23ac39443ef56d215aa238f1
4
+ data.tar.gz: 04db562bdca8c30274c76200be45cde3d84c1f3dfff0de32dfbf7ca87cc7e717
5
5
  SHA512:
6
- metadata.gz: 9c4cb31c35e64be7767cf08f12fc9609c788d9d174c7dec0e72077e16721a17670028f57ed0641d422402d70af8f8f2c32bb3304e5b455cf1b8fb20aef340965
7
- data.tar.gz: 8f66afb6f9f8c9d8ceb877ff369b920860a509705356a9b6eca0f1a42aada2b2879dba2e4c028a23956dc528515f7fc48768e56a7b50e5b9d181df211f4027ff
6
+ metadata.gz: 217666331556adc073a8a3bc08f4ea305adb0d5106a86bc1b4deed68cf42f41e15c22f45b1a521301f65c4329958b3e4e8891e39648933372ed3f829910414a9
7
+ data.tar.gz: f67a4eae9eb31296d6283ce395f122c04b825a0df4f810cd153a596288965de5fcf89071b6920026963288297ef0fa5194ffc88787b55dc80b77104d10af344a
@@ -18,3 +18,8 @@ steps:
18
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
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
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."
21
+ - name: publish-approval
22
+ instructions:
23
+ - "For a forge issue, publish formal approval on the original PR after the full review accepts its current HEAD and the required tests pass at that HEAD."
24
+ - "Finish this step with the verified provider receipt and test evidence. For a local-only task record the local review and tests and that no provider publication applies."
25
+ - "Report success only after this step is done. Missing publication evidence keeps a forge-linked assignment incomplete."
@@ -7,7 +7,7 @@ role: worker
7
7
  description: "Worker process for task {{task}}"
8
8
  outcome: >-
9
9
  Verified implementation of task {{task}} on the task branch: every
10
- modified package passes its required tests (bin/ace-test <pkg> all) and
10
+ modified package passes its required tests with the selected runtime and
11
11
  the work is committed.
12
12
  steps:
13
13
  - name: work-on-task
@@ -17,5 +17,10 @@ steps:
17
17
  - "Acceptance: the required tests of every modified package pass; failed required tests block success (ace-assign fail), never a forced done."
18
18
  - name: verify-test
19
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."
20
+ - "Run the required checks from the worker workflow on the committed candidate with the selected runtime. Record the executed commands, results and exact HEAD in the task results file."
21
+ - "Acceptance: every required check has run and passed."
22
+ - name: publish-pr
23
+ instructions:
24
+ - "For a forge issue, publish the tested branch and create or reconcile its non-draft PR against the commissioned base."
25
+ - "Finish this step with the forge-verified PR identity, source branch, base and tested HEAD. For local-only work record the tested commit and that no PR applies."
26
+ - "Missing or uncertain PR publication keeps a forge-linked assignment incomplete."
data/CHANGELOG.md CHANGED
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.9.0] - 2026-11-10
11
+
12
+ ### Added
13
+
14
+ - Preserve actual executor bindings when preparing or commissioning again; prevent identity replacement. Delegate project setup to workers, retain exact-HEAD review/integration gates, and keep reports tied to the selected commission.
15
+
10
16
  ## [0.8.0] - 2026-10-31
11
17
 
12
18
  ### Added
data/README.md CHANGED
@@ -97,3 +97,21 @@ ADR-022 config cascade, dry-cli commands).
97
97
  ## License
98
98
 
99
99
  MIT — see [LICENSE](../LICENSE).
100
+
101
+ ### Local observation reporting
102
+
103
+ A role preset or serialized coworker start config can select
104
+ `reporting: {channel: hitl, delivery: observe}`. The default delivery mode is
105
+ `adapter`. Observation mode creates the canonical HITL report, verifies its
106
+ exact task, assignment, outcome and configured recipient through the HITL
107
+ owner API, and returns `published for observation; acceptance pending`.
108
+ It does not invoke a transport adapter or claim that the overseer accepted the
109
+ work. The coordinator must have observation armed and accept the report through
110
+ its existing task/assignment workflow.
111
+
112
+ Resume checks the current publication, including archived reports, before
113
+ considering reporting complete. Missing or mismatched publications are not
114
+ success; changing to adapter delivery still requires transport. `--no-send`
115
+ continues to defer reporting and does not mark observation publication complete.
116
+ An observation source error is a failure, never permission to silently skip
117
+ reporting. The executor brief displays the configured delivery mode.
data/docs/usage.md CHANGED
@@ -285,8 +285,14 @@ worktree`).
285
285
  ace-coworker status [--config PATH] [--assignment ID] [--format table|json] [-q] [-d]
286
286
  ```
287
287
 
288
- Readiness query — always exit `0`. Absent config renders
289
- `not ready: .ace-local/coworker/config.yml not found`. Otherwise renders the
288
+ Executor readiness query — a rendered state exits `0`, including not-ready.
289
+ Absent config renders `not ready: .ace-local/coworker/config.yml not found`.
290
+ A missing or mismatched assignment, or a failed assignment status probe,
291
+ also renders `not ready: …` and JSON `ready: false`; successful YAML parsing alone is not readiness.
292
+ This describes one commissioned executor, not project bootstrap readiness.
293
+ Use its returned start configuration from its execution worktree; do not copy
294
+ that config to another checkout to make a project-level status appear ready.
295
+ A resolved assignment renders the
290
296
  resolved role/task/assignment/overseer, the assignment progress, and the
291
297
  completion verdict with remaining-work reasons (empty plan, failed steps,
292
298
  pending/active steps).
@@ -15,6 +15,8 @@ Use its pinned assignment ID for every ace-assign operation. Read the executable
15
15
  lab task and its explicit canonical target path, allowed configuration paths,
16
16
  operations, runtime selection and acceptance criteria. Missing or ambiguous
17
17
  scope is an error report, never a guessed directory or permission.
18
+ The prepared commission and assignment define this leg. Execute them directly;
19
+ do not start a separate `ace-task plan` turn for the commissioned work.
18
20
 
19
21
  The assignment and evidence belong to the prepared lab task worktree. This
20
22
  operational role may act on the explicitly commissioned canonical target
@@ -33,9 +35,18 @@ coordinator, not permission to borrow an account or change ownership.
33
35
  ## Assignment and report
34
36
 
35
37
  Drive the pinned ace-assign step through start/finish/fail. Store evidence in
36
- the executable task's docs. Failed or unavailable required checks block success.
38
+ the executable task's docs. Run each `ace-*` check directly, without a pipe or
39
+ redirection, and record its actual exit status and output in task docs; when
40
+ it prints a file path, read that file. Never use the exit status of `head`, another pipeline command or `echo` as the check's result.
41
+ Failed, unavailable or inconclusive required checks block success.
37
42
  Use `ace-coworker report --config <returned path>` for the truthful assignment
38
43
  outcome. A process exit, prepared config or printed CLI brief is not completion.
44
+ For `reporting.delivery: observe`, publish from the assignment worktree.
45
+ The Lab Overseer's inbox is outside your mount by design. Validate the
46
+ configured recipient address, never try to read, create or write its folder.
47
+ Publication returns an event ID and leaves acceptance to the Lab Overseer.
48
+ If the commission asks for a destination-folder write probe, report the
49
+ conflicting check to the coordinator instead of attempting the write.
39
50
  After interruption, read current state before repeating any external effect;
40
51
  resume the same assignment, never silently create a replacement.
41
52
 
@@ -46,7 +57,20 @@ the actual target files and installed runtime independently. Verify requested
46
57
  configuration, allowed-change boundaries, executable resolution and dependency
47
58
  readiness with the task's explicit checks; compare actual results with the
48
59
  worker's claims. Do not repair the target or accept your own preparation.
49
- Report discrepancies as failure for the coordinator to return to the worker.
60
+ `ace-lab prepare`, `ace-lab install` and `ace-lab verify` are host deployment
61
+ commands in every directory. Do not run them, even in dry-run mode. If the
62
+ assignment requires one, fail the step and report the exact conflicting check
63
+ to the commissioning Overseer for correction. End the turn after reporting.
64
+ Independently check the commissioned eyes configuration and its configured
65
+ HITL recipient using checks available to the verifier role. Check the file
66
+ with the installed ace-wake validator. The project Overseer start scope is
67
+ `project`; the eyes JSON observes its current project with `"scope": "current"`.
68
+ Do not require full
69
+ observation of private overseer tasks, host systemd or host-wide verification:
70
+ the authorized coordinator confirms those sources at final project acceptance.
71
+ Record any incidental restricted-source results without treating expected access
72
+ denial as a configuration defect. A failed check required by the commissioned
73
+ preparation scope remains a failure for the coordinator to return to the worker.
50
74
 
51
75
  Do not start the project overseer: the coordinator owns the final reconcile,
52
76
  first-turn and eyes acceptance. Your success accepts preparation only.
@@ -15,6 +15,8 @@ Use its pinned assignment ID for every ace-assign operation. Read the executable
15
15
  lab task and its explicit canonical target path, allowed configuration paths,
16
16
  operations, runtime selection and acceptance criteria. Missing or ambiguous
17
17
  scope is an error report, never a guessed directory or permission.
18
+ The prepared commission and assignment define this leg. Execute them directly;
19
+ do not start a separate `ace-task plan` turn for the commissioned work.
18
20
 
19
21
  The assignment and evidence belong to the prepared lab task worktree. This
20
22
  operational role may act on the explicitly commissioned canonical target
@@ -33,9 +35,18 @@ coordinator, not permission to borrow an account or change ownership.
33
35
  ## Assignment and report
34
36
 
35
37
  Drive the pinned ace-assign step through start/finish/fail. Store evidence in
36
- the executable task's docs. Failed or unavailable required checks block success.
38
+ the executable task's docs. Run each `ace-*` check directly, without a pipe or
39
+ redirection, and record its actual exit status and output in task docs; when
40
+ it prints a file path, read that file. Never use the exit status of `head`, another pipeline command or `echo` as the check's result.
41
+ Failed, unavailable or inconclusive required checks block success.
37
42
  Use `ace-coworker report --config <returned path>` for the truthful assignment
38
43
  outcome. A process exit, prepared config or printed CLI brief is not completion.
44
+ For `reporting.delivery: observe`, publish from the assignment worktree.
45
+ The Lab Overseer's inbox is outside your mount by design. Validate the
46
+ configured recipient address, never try to read, create or write its folder.
47
+ Publication returns an event ID and leaves acceptance to the Lab Overseer.
48
+ If the commission asks for a destination-folder write probe, report the
49
+ conflicting check to the coordinator instead of attempting the write.
39
50
  After interruption, read current state before repeating any external effect;
40
51
  resume the same assignment, never silently create a replacement.
41
52
 
@@ -47,7 +58,32 @@ or rewrite existing project dependency declarations. A product/tool defect
47
58
  requires a separate code-change commission. Use the existing configuration
48
59
  and installation tools; do not invent a second configuration owner.
49
60
 
61
+ `ace-lab prepare`, `ace-lab install` and `ace-lab verify` are host deployment
62
+ commands in every directory. Do not run them, even in dry-run mode. Validate
63
+ the commissioned project files and the effective installed runtime directly.
64
+ If the assignment requires a host deployment command, fail the step and
65
+ report the exact conflicting check to the commissioning Overseer for
66
+ correction. End the turn after reporting.
67
+
50
68
  Verify the requested configuration and installed dependency readiness. Record
51
69
  before/after state and exact checks without secrets. Do not start another
52
70
  project overseer yourself: after independent verification the lab coordinator
53
71
  owns reconcile/start. Leave unrelated work and live services untouched.
72
+ Prepare the commissioned project eyes configuration using its explicit path
73
+ and actual configured HITL recipient. Validate its schema and the runtime paths
74
+ available to your worker role. The Overseer start configuration uses
75
+ `scope: project`. The eyes JSON uses `"scope": "current"` for this project
76
+ and `"recipient"` for its configured recipient. Validate the candidate JSON
77
+ against the installed ace-wake validator before writing it to the target path.
78
+ Full observation includes private overseer tasks:
79
+ the authorized coordinator confirms all sources after independent verification
80
+ and project start. Do not require access to that private tree, host systemd or
81
+ host-wide verification to complete your scoped preparation. Report missing
82
+ capabilities required by your commission; never widen permissions.
83
+
84
+ Checkout preparation does not run project after-create hooks, mise trust or
85
+ bootstrap commands. Read the project's worktree setup configuration and perform
86
+ only the setup required by this commission, under your worker identity and
87
+ selected runtime. Record executed and inapplicable phases with evidence. The
88
+ standalone worktree bootstrap command does not replay after-create hooks; do not
89
+ claim those hooks ran merely because bootstrap succeeded.
@@ -69,9 +69,11 @@ the exact candidate head. Otherwise WITHHOLD the merge and report/escalate.
69
69
  `.ace-local/coworker/review-rounds/<assignment>.json`
70
70
  (`ace-coworker rounds` verdict `accept`). The reviewed head is the head
71
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.
72
+ - **Test evidence**: commands and results from the worker and reviewer
73
+ reports for all checks required by the issue and project. Compare the
74
+ test scope with those requirements before accepting the reports.
75
+ Installed mode uses installed `ace-test`, and ACE development mode
76
+ uses `bin/ace-test`. Only executed checks count. CI status is advisory.
75
77
  - **Dependency states**: for each leaf the candidate depends on, whether
76
78
  its result was RECEIVED AND INTEGRATED (merged predecessor), not merely
77
79
  finished or reviewed.
@@ -98,6 +100,19 @@ the exact candidate head. Otherwise WITHHOLD the merge and report/escalate.
98
100
  verdict says accept.
99
101
 
100
102
  4. **Consume formal approval, then merge only a ready candidate.**
103
+ - For every forge issue run the gate with `--require-approval`. Set
104
+ `--approval-head` and `--approval-by` from the verified approval below,
105
+ and `--author` from `ace-git pr show PR --format json` on the same
106
+ server. Without that evidence, the gate stays blocked.
107
+ Stop before any merge attempt and report the missing handoff through
108
+ the existing assignment and report. The integrator does not publish
109
+ a replacement PR or substitute its own approval.
110
+ - A forge issue is delivered through its commissioned PR. Require the
111
+ worker's PR reference and the reviewer's approval for that same PR and
112
+ exact tested HEAD. Verify that the review covers the current forge
113
+ target/merge-base and the full PR delta. Missing or changed scope goes
114
+ back to the overseer for a renewed review. The local integration route
115
+ below is reserved for local-only commissions.
101
116
  - For PR integration, read the reviewer's receipt from the existing report
102
117
  and verify current provider evidence without minting another approval:
103
118
  `ace-git pr approval PR --expected-head SHA --review-id REVIEW_ID
@@ -112,12 +127,15 @@ the exact candidate head. Otherwise WITHHOLD the merge and report/escalate.
112
127
  copy their token or bypass branch protection. This read does not replace
113
128
  the dependency/test/current-head gate or authorize a merge by itself.
114
129
 
115
- - Verdict `ready`: perform the project-defined integration with the
130
+ - With verdict `ready` and the verified provider approval, merge the PR via
131
+ `ace-git pr merge PR --expected-head SHA --method METHOD` with the retained
132
+ server selection and commissioned merge method.
133
+ - For local-only commissions with verdict `ready`, perform integration with the
116
134
  existing tools (`git` / `ace-git`, scoped to the commissioned paths;
117
135
  never force-push; fetch first and resolve conflicts explicitly).
118
136
  - If the merge itself changed the candidate or conflicts were resolved,
119
- the result is a NEW candidate: re-run the affected checks
120
- (`bin/ace-test <package> all`) and RENEW the review for the changed
137
+ the result is a NEW candidate: re-run the affected checks with the
138
+ selected toolchain and RENEW the review for the changed
121
139
  result (reviewer role) before treating it as integrated - never mix
122
140
  acceptance of the old candidate with new code (step 4 of the lab's execution-order contract). Then re-evaluate the gate.
123
141
  - After merging, verify the actual outcome (branch state, merged head)
@@ -176,5 +194,5 @@ less is an error outcome with the cause named.
176
194
  Integration decisions persist in the assignment's existing report state
177
195
  (ReportStateStore / `<task>/coworker/<assignment>.md` record); no new
178
196
  artifact kind is introduced.
179
- - Inside the ACE repository itself, invoke every tool as `bin/ace-*` (the
180
- binstubs pin the checkout's bundle).
197
+ - In ACE development mode, use `bin/ace-*`. With `ACE_TOOLCHAIN=installed`,
198
+ use installed commands and packaged instructions even inside an ACE checkout.
@@ -5,7 +5,7 @@ description: Reviewer role for the file-based lab. Independent of the worker; re
5
5
  doc-type: workflow
6
6
  purpose: reviewer role workflow instruction
7
7
  ace-docs:
8
- last-updated: '2026-10-19'
8
+ last-updated: '2026-11-06'
9
9
  ---
10
10
 
11
11
  # Reviewer - Independent Review with Fixes Inside the Assignment
@@ -42,6 +42,12 @@ product decision is escalated to the overseer instead.
42
42
  - After an interruption, `ace-coworker resume` renders the preserved state and
43
43
  the resume path (same task, same assignment, same worktree).
44
44
 
45
+ For a forge issue, ensure the pinned assignment has a final
46
+ `publish-approval` step before starting review. Add it through `ace-assign add`
47
+ if the commission has not prepared it. Keep that step open while reviewing
48
+ and testing. The round verdict `accept` completes review rounds only. An
49
+ assignment with an open publication step cannot produce a success report.
50
+
45
51
  ## Project Context Loading
46
52
 
47
53
  - Read and follow: `ace-bundle wfi://bundle`
@@ -63,6 +69,12 @@ product decision is escalated to the overseer instead.
63
69
  dependencies, or the overseer tree.
64
70
 
65
71
  2. **Run a review round (forge-neutral).**
72
+ - A task linked to a forge issue requires the worker's published PR and
73
+ exact tested HEAD before review starts. Read both from the accepted
74
+ worker assignment's step reports and reconcile them with the configured
75
+ forge. The issue link makes this a PR review even when the commission
76
+ omits the PR or calls the work local. If the PR or tested HEAD is
77
+ missing, report a blocked handoff to the overseer for worker publication.
66
78
  - Subject: local candidate
67
79
  `ace-review --preset code-valid --subject diff:<merge-base>..<head>`, or
68
80
  a typed PR reference `--pr IDENTIFIER` (number, `owner/repo#number`, or
@@ -70,6 +82,32 @@ product decision is escalated to the overseer instead.
70
82
  forge selection `--server NAME` or `--default-server` (mutually
71
83
  exclusive) - never infer a forge from a hostname or the caller's
72
84
  identity.
85
+ - Use the session's configured project-scoped credentials for forge reads,
86
+ fetches and approval. When the deployment uses temporary grants, obtain
87
+ a grant through its configured adapter and use `ace-lab auth exec` for
88
+ the individual forge operation (one argument per repeated `--cmd`).
89
+ Keep review, model calls and tests in the ordinary installed session;
90
+ they do not need a forge grant. A static project token needs no lease
91
+ service and must not be revoked after each operation.
92
+ - Run the task's required checks from the assignment worktree on the
93
+ candidate you will approve. Confirm the scope against the issue and
94
+ project requirements, and record the executed commands and results.
95
+ Use installed `ace-test` when `ACE_TOOLCHAIN=installed`. Check the
96
+ test commands and their prerequisites before installing development dependencies.
97
+ A checkout binstub or Gemfile alone does not require `bundle install`.
98
+ If a required installed test tool is missing, report the readiness failure.
99
+ In ACE development mode use the checkout's `bin/ace-test`.
100
+ - For a commissioned PR, review the **full forge PR delta**. Prefer its
101
+ typed PR reference. If using a local diff range, first resolve the actual
102
+ target branch and candidate HEAD from the configured forge, fetch those
103
+ exact refs through your granted access, and compute their merge-base.
104
+ Record the full base and head SHAs and compare the selected files with the
105
+ forge PR diff. Local `main` may contain unpublished coordination/task
106
+ commits and is not evidence of the forge base. Include those commits when
107
+ they are part of the PR; a worker-only slice is not a full review round.
108
+ Missing base/head evidence or omitted PR changes blocks acceptance. After
109
+ candidate/base changes, re-establish the complete range for subsequent
110
+ full rounds; a fix-only check does not replace it.
73
111
  - `--dry-run` first: check the selected/omitted files and the budgets
74
112
  (30k context / 30k instructions / 128k total input). Change scope if too
75
113
  large; never silently truncate or claim omitted code was reviewed.
@@ -103,12 +141,12 @@ product decision is escalated to the overseer instead.
103
141
  instructions: |
104
142
  Fix the confirmed review finding <feedback-id> in the delivered
105
143
  change. Apply the minimal correct fix, run the affected checks
106
- (bin/ace-test <package>), and record what changed.
144
+ with the selected toolchain, and record what changed.
107
145
  ```
108
146
  (`--step <name>` only selects a step definition that already exists
109
147
  in the preset catalog - it cannot mint a new fix-step name);
110
148
  (b) implement the fix on the task branch in this worktree; (c) run
111
- the affected checks (`bin/ace-test <package> ...` - a failed required
149
+ the affected checks with the selected toolchain (a failed required
112
150
  test blocks); (d) commit scoped (`ace-git-commit <paths>` after
113
151
  checking `git status`); (e) only after the fix is verified:
114
152
  `ace-review-feedback resolve <id> --resolution "Fixed in <sha>"`.
@@ -122,15 +160,19 @@ product decision is escalated to the overseer instead.
122
160
  the convergence counters by itself.
123
161
 
124
162
  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.
163
+ - For a forge PR, publish scoped fix commits to the existing PR source
164
+ branch before the next full round. Use the reviewer session's own
165
+ project-scoped credentials. Read the current PR source repository, branch and
166
+ HEAD from the forge. Proceed only if that HEAD is the last known PR
167
+ revision and the update is a fast-forward. Push the exact candidate
168
+ to that branch without force and re-read the PR to verify its HEAD.
169
+ An unexpected remote change or denied push blocks this handoff.
170
+ - Run a FULL round over the whole current candidate with the retained
171
+ forge selection and the verified forge base and HEAD. Re-read the forge
172
+ through the configured project access and recompute the
173
+ merge-base if either changes. A fix-only diff or scoped delta is
174
+ separate from a full round. A committed task edit also changes the
175
+ candidate and requires renewed review and test evidence.
134
176
  - **Convergence rule 3/2/10**: minimum 3 full rounds, the last 2
135
177
  consecutive without confirmed High/Critical and with no unresolved
136
178
  earlier High/Critical; maximum 10 - if round 10 satisfies the rule,
@@ -171,6 +213,11 @@ product decision is escalated to the overseer instead.
171
213
  `--default-server` selection). Keep the report and returned receipt in the
172
214
  existing task/review/assignment artifacts. Use one stable REVIEW_ID for
173
215
  this repository/PR publication; changed report/head needs a new publication.
216
+ - Finish the `publish-approval` step with the verified receipt and
217
+ executed test evidence in its assignment step report. Then run
218
+ `ace-coworker report`. The approval receipt and its forge-verified
219
+ reviewer identity are the handoff. The worker's PR description does
220
+ not have to be editable by the reviewer.
174
221
  - A comment, local acceptance or `pr ready` is not formal approval. Confirm
175
222
  the receipt's exact repo/PR/head/reviewer/evidence digest and effective
176
223
  approval. Missing permission, unsupported capability or unknown outcome
@@ -227,8 +274,9 @@ and reported. Anything less is an error outcome with the cause named.
227
274
  - No new state owners, journals, or queues (ADR-034): `.ace-local/coworker/`
228
275
  belongs to ace-coworker, `.ace-local/assign/` to ace-assign,
229
276
  `.ace-local/review/` to ace-review, `.ace-local/hitl/` to ace-hitl.
230
- - Inside the ACE repository itself, invoke every tool as `bin/ace-*` (the
231
- binstubs pin the checkout's bundle).
277
+ - With `ACE_TOOLCHAIN=installed`, use installed executables and packaged
278
+ instructions; the checkout is reviewed project data, never your runtime.
279
+ In development mode inside the ACE repository, use `bin/ace-*`.
232
280
 
233
281
 
234
282
  Deployment must provide a dedicated automation reviewer identity and one writer
@@ -50,6 +50,15 @@ false "work done".
50
50
  goal, the task dependencies, or the overseer tree.
51
51
 
52
52
  3. **Implement.**
53
+ - Checkout preparation delegates project setup to you. Inspect the project's
54
+ worktree configuration for after-create hooks, toolchain trust and bootstrap;
55
+ perform the setup needed by this assignment under your worker identity.
56
+ Preserve installed ACE as the operational runtime while preparing project
57
+ development dependencies separately. Check the commissioned test command
58
+ and its prerequisites before installing development dependencies. A checkout
59
+ Gemfile or binstub alone does not require `bundle install` in installed mode.
60
+ Record executed or inapplicable phases;
61
+ the standalone bootstrap command does not replay after-create hooks.
53
62
  - Work only inside this worktree. Mark checkboxes and step states only when
54
63
  the underlying work is verified.
55
64
  - Commit path-scoped (`ace-git-commit <paths>`), verifying `git status`
@@ -58,8 +67,15 @@ false "work done".
58
67
  - Follow repository conventions (AGENTS.md, ATOM architecture, style).
59
68
 
60
69
  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`.
70
+ - Run the task's required checks from the assignment worktree. If the
71
+ task and project leave the test scope unspecified, run
72
+ `ace-test <changed-package> all` for every changed package. Use
73
+ installed `ace-test` when `ACE_TOOLCHAIN=installed`. When the task
74
+ requires monorepo validation, run installed `ace-test-suite`.
75
+ Record the required commands and their results for the reviewer.
76
+ If a required installed test tool is missing, report the readiness failure.
77
+ - In ACE development mode use the checkout's `bin/ace-test` and
78
+ `bin/ace-test-suite` for the same checks.
63
79
  - **Failed required tests block success.** On a failing required test:
64
80
  - fix and rerun within this assignment; record the failure and the fix;
65
81
  - while the failure stands, the step is failed (`ace-assign fail` with
@@ -68,6 +84,23 @@ false "work done".
68
84
  error outcome naming the cause.
69
85
 
70
86
  5. **Finish and report.**
87
+ - Keep the final `publish-pr` step open while implementing and testing.
88
+ If a forge-linked assignment lacks that step, add it through
89
+ `ace-assign add` before completing the test step.
90
+ - For a task linked to a forge issue, publish the tested candidate on a
91
+ source branch and create or reconcile its pull request against the
92
+ commissioned target branch. Use the worker's scoped access and the
93
+ configured forge. Use `ace-git pr create --head BRANCH --base TARGET
94
+ --expected-head SHA --title TITLE --body-file BODY --no-draft` with the retained
95
+ server selection. Link the originating issue in the PR body. The full
96
+ pushed HEAD must match the tested HEAD. Record the PR reference, target
97
+ branch and exact HEAD in the worker report. If publication is unavailable
98
+ or uncertain, report the impediment and reconcile before retrying.
99
+ If the existing PR is a draft, use `ace-git pr ready PR --expected-head
100
+ SHA` and re-read it. Finish `publish-pr` only after verifying the
101
+ open, non-draft PR at
102
+ the exact tested HEAD. Record the evidence in that step's report.
103
+ For local-only work record the tested commit and that no PR applies.
71
104
  - Run `ace-coworker report`. The outcome is derived from the ace-assign
72
105
  verdict: reporting a forced success on an incomplete assignment is
73
106
  refused by the tool. Never send a false "work done"; when in doubt, the
@@ -80,7 +113,8 @@ false "work done".
80
113
  ## Completion Rule
81
114
 
82
115
  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),
116
+ test declared by the task passes. When the task does not specify checks,
117
+ run each changed package's required suite (or its monorepo gate),
84
118
  and the truthful outcome has been recorded and reported. A failing required
85
119
  test means the work is NOT done, whatever the local state of the steps.
86
120
 
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "shellwords"
4
+
3
5
  module Ace
4
6
  module Coworker
5
7
  module Atoms
@@ -19,11 +21,11 @@ module Ace
19
21
  lines << " instructions src: #{h['instructions_source']}"
20
22
  lines << " start prompt: #{h['start_prompt']}"
21
23
  lines << " task: #{h['task']} (#{h['task_path']})"
22
- lines << " assignment: drive with --assignment #{h['assignment']}"
24
+ lines << " assignment: drive with --assignment #{Shellwords.escape(h.fetch('assignment'))}"
23
25
  lines << " assignment state: #{h['assignment_state']} (#{h['assignment_progress']})"
24
- lines << " overseer: #{h['overseer']} (channel: #{h['reporting_channel']})"
26
+ lines << " overseer: #{h['overseer']} (channel: #{h['reporting_channel']}, delivery: #{h['reporting_delivery']})"
25
27
  lines << " on failure: #{h['on_failure']}"
26
- lines << " report with: ace-coworker report --assignment #{h['assignment']}"
28
+ lines << " report with: ace-coworker report --config #{Shellwords.escape(h.fetch('config_path'))} --assignment #{Shellwords.escape(h.fetch('assignment'))}"
27
29
  lines << " project root: #{h['project_root']}"
28
30
  lines.join("\n")
29
31
  end
@@ -11,6 +11,7 @@ module Ace
11
11
  REQUIRED_FIELDS = %w[role instructions task assignment overseer].freeze
12
12
  PROTOCOL_PREFIXES = %w[wfi:// prompt:// tmpl://].freeze
13
13
  CHANNELS = %w[hitl].freeze
14
+ DELIVERIES = %w[adapter observe].freeze
14
15
  ON_FAILURE = %w[report stop].freeze
15
16
 
16
17
  # @param raw [Hash, nil] parsed config hash
@@ -53,7 +54,8 @@ module Ace
53
54
  "assignment" => str(raw["assignment"]),
54
55
  "overseer" => str(raw["overseer"]),
55
56
  "case" => str(raw["case"]),
56
- "reporting" => {"channel" => nested_str(raw, "reporting", "channel").empty? ? "hitl" : nested_str(raw, "reporting", "channel")},
57
+ "reporting" => {"channel" => nested_str(raw, "reporting", "channel").empty? ? "hitl" : nested_str(raw, "reporting", "channel"),
58
+ "delivery" => nested_str(raw, "reporting", "delivery").empty? ? "adapter" : nested_str(raw, "reporting", "delivery")},
57
59
  "errors" => {"on_failure" => nested_str(raw, "errors", "on_failure").empty? ? "report" : nested_str(raw, "errors", "on_failure")}
58
60
  }.compact
59
61
  end
@@ -83,9 +85,10 @@ module Ace
83
85
 
84
86
  def self.reporting_errors(raw)
85
87
  channel = nested_str(raw, "reporting", "channel")
86
- return [] if channel.empty?
87
-
88
- CHANNELS.include?(channel) ? [] : ["reporting.channel '#{channel}' is not one of: #{CHANNELS.join(', ')}"]
88
+ errors = channel.empty? || CHANNELS.include?(channel) ? [] : ["reporting.channel '#{channel}' is not one of: #{CHANNELS.join(', ')}"]
89
+ delivery = nested_str(raw, "reporting", "delivery")
90
+ errors << "reporting.delivery must be adapter or observe" unless delivery.empty? || DELIVERIES.include?(delivery)
91
+ errors
89
92
  end
90
93
  private_class_method :reporting_errors
91
94
 
@@ -29,9 +29,8 @@ module Ace
29
29
  # "review" => {"head" => String reviewed head, "verdict" => String}
30
30
  # "tests" => {"executed" => bool, "passed" => bool,
31
31
  # "head" => String head the test run covered}
32
- # "approval" => {"head" => String, "by" => String account} (a
33
- # nil/empty approval skips the formal-approval check; lanes
34
- # that require it must supply it)
32
+ # "require_approval" => bool (requires approval and author evidence)
33
+ # "approval" => {"head" => String, "by" => String account}
35
34
  # "author" => String candidate author account (optional)
36
35
  # "dependencies" => {name => bool (integrated predecessor)}
37
36
  # @return [Hash] {verdict: :ready | :blocked, reasons: [String],
@@ -94,7 +93,8 @@ module Ace
94
93
  end
95
94
 
96
95
  approval = hash(input["approval"])
97
- unless approval.empty?
96
+ require_approval = input["require_approval"] == true
97
+ if require_approval || !approval.empty?
98
98
  approval_head = str(approval["head"])
99
99
  approved_by = str(approval["by"])
100
100
  if approval_head.empty?
@@ -107,6 +107,10 @@ module Ace
107
107
  failed << :approval
108
108
  end
109
109
  author = str(input["author"])
110
+ if require_approval && author.empty?
111
+ reasons << "PR author unknown: record the author account to verify independent approval"
112
+ failed << :approval
113
+ end
110
114
  if approved_by.empty?
111
115
  reasons << "formal approval is anonymous: no approving account is recorded — " \
112
116
  "the author≠approver guarantee is vacuous; record the approving lane account"
@@ -17,9 +17,9 @@ module Ace
17
17
  # @param step_report_path [String, nil] report file of the in-flight step
18
18
  # @return [Models::ResumePlan]
19
19
  def self.plan(snapshot:, report_state: nil, git_state: {},
20
- step_cause: nil, step_report_path: nil)
20
+ step_cause: nil, step_report_path: nil, reporting_delivery: "adapter", publication_verified: false)
21
21
  if snapshot.completion_verdict == :complete
22
- return complete_plan(report_state, git_state)
22
+ return complete_plan(snapshot, report_state, git_state, reporting_delivery, publication_verified)
23
23
  end
24
24
 
25
25
  continue_plan(snapshot, report_state, git_state,
@@ -29,15 +29,17 @@ module Ace
29
29
  # Only a DELIVERED SUCCESS report matches a completed assignment:
30
30
  # a delivered error report describes an outcome the assignment has
31
31
  # since left behind, so resume must still report the success.
32
- def self.complete_plan(report_state, git_state)
33
- delivered = report_state.is_a?(Hash) &&
34
- report_state["result"] == "success" &&
35
- report_state["delivery"].to_s.start_with?("delivered")
32
+ def self.complete_plan(snapshot, report_state, git_state, reporting_delivery, publication_verified)
33
+ current = OutcomePlanner.plan(snapshot).matches_report?(report_state)
34
+ delivered = current &&
35
+ (reporting_delivery == "observe" ?
36
+ publication_verified && report_state["delivery"].to_s.start_with?("published for observation") :
37
+ report_state["delivery"].to_s.start_with?("delivered"))
36
38
  if delivered
37
39
  Models::ResumePlan.new(disposition: :complete, git: git_state)
38
40
  else
39
41
  Models::ResumePlan.new(disposition: :report, git: git_state,
40
- redeliver_event_id: report_state.is_a?(Hash) ? report_state["event_id"] : nil)
42
+ redeliver_event_id: current ? report_state["event_id"] : nil)
41
43
  end
42
44
  end
43
45