ace-assign 0.71.0 → 0.73.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 +4 -4
- data/.ace-defaults/assign/catalog/steps/auto-merge.step.yml +8 -8
- data/.ace-defaults/assign/catalog/steps/create-pr.step.yml +1 -1
- data/.ace-defaults/assign/catalog/steps/mark-pr-ready.step.yml +1 -1
- data/.ace-defaults/assign/config.yml +0 -13
- data/.ace-defaults/assign/presets/fix-bug.yml +1 -1
- data/.ace-defaults/assign/presets/work-on-task-ace-development.yml +1 -1
- data/.ace-defaults/assign/presets/work-on-task-auto-merge.yml +1 -1
- data/.ace-defaults/assign/presets/work-on-task.yml +1 -1
- data/CHANGELOG.md +3 -2119
- data/README.md +58 -31
- data/docs/exit-codes.md +36 -44
- data/docs/getting-started.md +9 -4
- data/docs/usage.md +129 -522
- data/handbook/skills/as-assign-drive/SKILL.md +1 -4
- data/handbook/workflow-instructions/assign/drive.wf.md +47 -195
- data/handbook/workflow-instructions/assign/prepare.wf.md +1 -1
- data/handbook/workflow-instructions/assign/verify-test-suite.wf.md +8 -2
- data/lib/ace/assign/cli/commands/assignment_target.rb +2 -15
- data/lib/ace/assign/cli/commands/create.rb +1 -8
- data/lib/ace/assign/cli/commands/fail.rb +0 -6
- data/lib/ace/assign/cli/commands/finish.rb +2 -23
- data/lib/ace/assign/cli/commands/fork_session.rb +0 -1
- data/lib/ace/assign/cli/commands/select.rb +0 -1
- data/lib/ace/assign/cli/commands/start.rb +0 -2
- data/lib/ace/assign/cli/commands/status.rb +1 -31
- data/lib/ace/assign/cli/commands/step.rb +1 -3
- data/lib/ace/assign/cli.rb +1 -85
- data/lib/ace/assign/errors.rb +8 -80
- data/lib/ace/assign/models/assignment.rb +5 -28
- data/lib/ace/assign/molecules/assignment_manager.rb +0 -26
- data/lib/ace/assign/molecules/fork_session_launcher.rb +4 -12
- data/lib/ace/assign/molecules/lifecycle_exclusion.rb +15 -112
- data/lib/ace/assign/organisms/assignment_executor.rb +0 -6
- data/lib/ace/assign/organisms/task_assignment_creator.rb +3 -8
- data/lib/ace/assign/version.rb +1 -1
- data/lib/ace/assign.rb +0 -6
- metadata +4 -176
- data/.ace-defaults/assign/presets/close-delivery.yml +0 -57
- data/.ace-defaults/assign/presets/deliver-release.yml +0 -60
- data/.ace-defaults/assign/presets/integrate-batch.yml +0 -72
- data/.ace-defaults/assign/presets/supervise-delivery.yml +0 -69
- data/docs/protected-authority.md +0 -282
- data/exe/ace-scope-ready +0 -55
- data/lib/ace/assign/atoms/assignment_scope.rb +0 -58
- data/lib/ace/assign/atoms/attempt_state_machine.rb +0 -84
- data/lib/ace/assign/atoms/candidate_limits.rb +0 -20
- data/lib/ace/assign/atoms/delivery_parameters.rb +0 -19
- data/lib/ace/assign/atoms/evidence_digest.rb +0 -78
- data/lib/ace/assign/atoms/fixed_merge_schemas.rb +0 -398
- data/lib/ace/assign/atoms/git_blob_batch.rb +0 -59
- data/lib/ace/assign/authority/assignment_definition.rb +0 -35
- data/lib/ace/assign/authority/assignment_inventory.rb +0 -290
- data/lib/ace/assign/authority/campaign_consumer_policy.rb +0 -100
- data/lib/ace/assign/authority/campaign_execution.rb +0 -119
- data/lib/ace/assign/authority/campaign_round_transfer.rb +0 -82
- data/lib/ace/assign/authority/candidate_blob_batch.rb +0 -55
- data/lib/ace/assign/authority/candidate_head_comparison.rb +0 -139
- data/lib/ace/assign/authority/candidate_transfer.rb +0 -357
- data/lib/ace/assign/authority/cleanup_result_protection.rb +0 -53
- data/lib/ace/assign/authority/client.rb +0 -257
- data/lib/ace/assign/authority/command_execution.rb +0 -180
- data/lib/ace/assign/authority/deployment.rb +0 -627
- data/lib/ace/assign/authority/deployment_history.rb +0 -146
- data/lib/ace/assign/authority/endcap.rb +0 -457
- data/lib/ace/assign/authority/endcap_attempts.rb +0 -274
- data/lib/ace/assign/authority/endcap_campaign_results.rb +0 -232
- data/lib/ace/assign/authority/endcap_campaign_rounds.rb +0 -266
- data/lib/ace/assign/authority/endcap_contexts.rb +0 -23
- data/lib/ace/assign/authority/endcap_inboxes.rb +0 -37
- data/lib/ace/assign/authority/endcap_prepared_work.rb +0 -80
- data/lib/ace/assign/authority/endcap_publication.rb +0 -41
- data/lib/ace/assign/authority/endcap_results.rb +0 -398
- data/lib/ace/assign/authority/endcap_review_requests.rb +0 -183
- data/lib/ace/assign/authority/endcap_reviews.rb +0 -130
- data/lib/ace/assign/authority/endcap_service_context.rb +0 -38
- data/lib/ace/assign/authority/endcap_service_settlement.rb +0 -152
- data/lib/ace/assign/authority/evidence_transfer.rb +0 -67
- data/lib/ace/assign/authority/execution_scope_observation.rb +0 -903
- data/lib/ace/assign/authority/fixed_publication_lifecycle.rb +0 -176
- data/lib/ace/assign/authority/fixed_service_lifecycle.rb +0 -594
- data/lib/ace/assign/authority/inbox_context_original.rb +0 -113
- data/lib/ace/assign/authority/launch_attempt_consumers.rb +0 -51
- data/lib/ace/assign/authority/launch_campaign_registration.rb +0 -214
- data/lib/ace/assign/authority/launch_control_channel.rb +0 -313
- data/lib/ace/assign/authority/launch_control_exclusions.rb +0 -127
- data/lib/ace/assign/authority/launch_driver.rb +0 -393
- data/lib/ace/assign/authority/launch_input_inhibition.rb +0 -132
- data/lib/ace/assign/authority/launch_lifecycle.rb +0 -997
- data/lib/ace/assign/authority/launch_prepared_work.rb +0 -122
- data/lib/ace/assign/authority/launch_review.rb +0 -91
- data/lib/ace/assign/authority/launch_scope_abort.rb +0 -81
- data/lib/ace/assign/authority/launch_scope_admission.rb +0 -215
- data/lib/ace/assign/authority/launch_scope_close.rb +0 -146
- data/lib/ace/assign/authority/launch_scope_parent.rb +0 -44
- data/lib/ace/assign/authority/launch_scope_release.rb +0 -859
- data/lib/ace/assign/authority/launch_steering.rb +0 -353
- data/lib/ace/assign/authority/launch_stop.rb +0 -254
- data/lib/ace/assign/authority/maintenance_workspace_retirement.rb +0 -229
- data/lib/ace/assign/authority/ordinary_attempt_start.rb +0 -137
- data/lib/ace/assign/authority/ordinary_client.rb +0 -70
- data/lib/ace/assign/authority/ordinary_completion.rb +0 -104
- data/lib/ace/assign/authority/ordinary_effect_settlement.rb +0 -118
- data/lib/ace/assign/authority/ordinary_lifecycle.rb +0 -227
- data/lib/ace/assign/authority/ordinary_merge_evidence.rb +0 -81
- data/lib/ace/assign/authority/ordinary_peer.rb +0 -54
- data/lib/ace/assign/authority/ordinary_progress.rb +0 -162
- data/lib/ace/assign/authority/ordinary_queue.rb +0 -115
- data/lib/ace/assign/authority/ordinary_release_artifacts.rb +0 -143
- data/lib/ace/assign/authority/ordinary_results.rb +0 -206
- data/lib/ace/assign/authority/ordinary_review_evidence.rb +0 -180
- data/lib/ace/assign/authority/ordinary_reviews.rb +0 -214
- data/lib/ace/assign/authority/ordinary_server.rb +0 -75
- data/lib/ace/assign/authority/ordinary_supervisor.rb +0 -99
- data/lib/ace/assign/authority/original_inbox_selection.rb +0 -41
- data/lib/ace/assign/authority/posix_acl.rb +0 -59
- data/lib/ace/assign/authority/prepared_input.rb +0 -130
- data/lib/ace/assign/authority/prepared_queue.rb +0 -185
- data/lib/ace/assign/authority/prepared_task_context.rb +0 -116
- data/lib/ace/assign/authority/prepared_work.rb +0 -309
- data/lib/ace/assign/authority/prepared_worker.rb +0 -69
- data/lib/ace/assign/authority/private_directory.rb +0 -33
- data/lib/ace/assign/authority/protected_assignment_context.rb +0 -226
- data/lib/ace/assign/authority/readiness_hook.rb +0 -120
- data/lib/ace/assign/authority/receipt_transfer.rb +0 -48
- data/lib/ace/assign/authority/release_artifact_manifest.rb +0 -91
- data/lib/ace/assign/authority/retained_input.rb +0 -53
- data/lib/ace/assign/authority/router.rb +0 -81
- data/lib/ace/assign/authority/server.rb +0 -131
- data/lib/ace/assign/authority/service_cleanup_dispatch.rb +0 -88
- data/lib/ace/assign/authority/service_cleanup_evidence.rb +0 -180
- data/lib/ace/assign/authority/service_delivery_evidence.rb +0 -101
- data/lib/ace/assign/authority/service_evidence.rb +0 -286
- data/lib/ace/assign/authority/service_publication_evidence.rb +0 -110
- data/lib/ace/assign/authority/socket_server.rb +0 -255
- data/lib/ace/assign/authority/task_context_entry.rb +0 -32
- data/lib/ace/assign/authority/transfer_codec.rb +0 -189
- data/lib/ace/assign/cli/commands/attempt/base.rb +0 -84
- data/lib/ace/assign/cli/commands/attempt/evidence.rb +0 -28
- data/lib/ace/assign/cli/commands/attempt/finish.rb +0 -51
- data/lib/ace/assign/cli/commands/attempt/reconcile.rb +0 -49
- data/lib/ace/assign/cli/commands/attempt/start.rb +0 -45
- data/lib/ace/assign/cli/commands/attempt/status.rb +0 -54
- data/lib/ace/assign/cli/commands/authority/inbox_context_principal.rb +0 -25
- data/lib/ace/assign/cli/commands/authority/inbox_context_selection.rb +0 -28
- data/lib/ace/assign/cli/commands/authority/launch.rb +0 -97
- data/lib/ace/assign/cli/commands/authority/serve.rb +0 -31
- data/lib/ace/assign/cli/commands/authority/status.rb +0 -26
- data/lib/ace/assign/cli/commands/authority/task_context.rb +0 -31
- data/lib/ace/assign/cli/commands/authority/task_context_principal.rb +0 -25
- data/lib/ace/assign/cli/commands/authority/task_context_selection.rb +0 -30
- data/lib/ace/assign/cli/commands/authority/terminate.rb +0 -29
- data/lib/ace/assign/cli/commands/authority/worker.rb +0 -23
- data/lib/ace/assign/cli/commands/campaign_export_result.rb +0 -55
- data/lib/ace/assign/cli/commands/campaign_record_round.rb +0 -57
- data/lib/ace/assign/cli/commands/delivery.rb +0 -107
- data/lib/ace/assign/cli/commands/inbox_bind.rb +0 -34
- data/lib/ace/assign/cli/commands/protected_submission.rb +0 -61
- data/lib/ace/assign/cli/commands/resume.rb +0 -38
- data/lib/ace/assign/cli/commands/submit_candidate.rb +0 -34
- data/lib/ace/assign/cli/commands/submit_result.rb +0 -61
- data/lib/ace/assign/models/attempt.rb +0 -178
- data/lib/ace/assign/models/attempt_binding.rb +0 -116
- data/lib/ace/assign/models/evidence_event.rb +0 -86
- data/lib/ace/assign/models/execution_receipt.rb +0 -139
- data/lib/ace/assign/molecules/attempt_reconciler.rb +0 -127
- data/lib/ace/assign/molecules/attempt_store.rb +0 -201
- data/lib/ace/assign/molecules/canonical_attempt_state.rb +0 -151
- data/lib/ace/assign/molecules/canonical_evidence.rb +0 -170
- data/lib/ace/assign/molecules/canonical_read_commands.rb +0 -84
- data/lib/ace/assign/molecules/canonical_read_snapshot.rb +0 -313
- data/lib/ace/assign/molecules/evidence_calculator.rb +0 -237
- data/lib/ace/assign/molecules/evidence_journal.rb +0 -1899
- data/lib/ace/assign/molecules/execution_identity_resolver.rb +0 -137
- data/lib/ace/assign/molecules/execution_scope_lineage.rb +0 -345
- data/lib/ace/assign/molecules/fixed_effect_reference.rb +0 -31
- data/lib/ace/assign/molecules/installed_journal_read.rb +0 -143
- data/lib/ace/assign/molecules/journal_input_inhibition.rb +0 -78
- data/lib/ace/assign/molecules/journal_mutation.rb +0 -274
- data/lib/ace/assign/molecules/journal_prompt_mutation.rb +0 -241
- data/lib/ace/assign/molecules/ordinary_merge_cli.rb +0 -68
- data/lib/ace/assign/molecules/ordinary_merge_contract.rb +0 -410
- data/lib/ace/assign/molecules/original_launch_binding.rb +0 -37
- data/lib/ace/assign/molecules/proposal_journal.rb +0 -179
- data/lib/ace/assign/molecules/protected_control_exclusion.rb +0 -303
- data/lib/ace/assign/molecules/protected_workspace_exclusion.rb +0 -330
- data/lib/ace/assign/molecules/protected_workspace_provisioner.rb +0 -164
- data/lib/ace/assign/molecules/receipt_verifier.rb +0 -320
- data/lib/ace/assign/molecules/terminal_scope_receipt.rb +0 -88
- data/lib/ace/assign/organisms/attempt_coordinator.rb +0 -1374
- data/lib/ace/assign/organisms/delivery_coordinator.rb +0 -342
- data/lib/ace/assign/organisms/ordinary_driver.rb +0 -310
- data/lib/ace/assign/organisms/ordinary_merge_consumer.rb +0 -365
- data/lib/ace/assign/organisms/prepared_work_builder.rb +0 -194
- data/lib/ace/assign/organisms/protected_delivery_coordinator.rb +0 -100
|
@@ -6,13 +6,12 @@ description: Drive agent execution through an active assignment
|
|
|
6
6
|
user-invocable: true
|
|
7
7
|
allowed-tools:
|
|
8
8
|
- Bash(ace-assign:*)
|
|
9
|
-
- Bash(ace-lab:*)
|
|
10
9
|
- Bash(ace-bundle:*)
|
|
11
10
|
- Read
|
|
12
11
|
- Write
|
|
13
12
|
- AskUserQuestion
|
|
14
13
|
- Skill
|
|
15
|
-
argument-hint: "[assignment[@scope]
|
|
14
|
+
argument-hint: "[assignment[@scope]]"
|
|
16
15
|
last_modified: 2026-04-23
|
|
17
16
|
source: ace-assign
|
|
18
17
|
skill:
|
|
@@ -24,8 +23,6 @@ skill:
|
|
|
24
23
|
|
|
25
24
|
Load and run `ace-bundle wfi://assign/drive` in the current project, then follow the loaded workflow as the source of truth and execute it end-to-end instead of only summarizing it.
|
|
26
25
|
|
|
27
|
-
When `--ordinary` or `ACE_ASSIGN_ORDINARY_CONTEXT` is present, follow the workflow’s ordinary installed branch before resolving local assignment state. Its canonical `ace-lab assignment drive` operations own status, start, progress, results and recovery; local commands below apply only outside that branch.
|
|
28
|
-
|
|
29
26
|
Hard stop rule:
|
|
30
27
|
|
|
31
28
|
- Do not stop after intermediate progress.
|
|
@@ -3,7 +3,6 @@ name: assign-drive
|
|
|
3
3
|
description: Drive an ace-assign assignment until completion or an explicit blocker.
|
|
4
4
|
allowed-tools:
|
|
5
5
|
- Bash(ace-assign:*)
|
|
6
|
-
- Bash(ace-lab:*)
|
|
7
6
|
- Bash(ace-bundle:*)
|
|
8
7
|
- Read
|
|
9
8
|
- Write
|
|
@@ -13,8 +12,8 @@ doc-type: workflow
|
|
|
13
12
|
title: Drive Assignment Workflow
|
|
14
13
|
purpose: workflow instruction for driving ace-assign assignment execution
|
|
15
14
|
ace-docs:
|
|
16
|
-
last-updated: '2026-
|
|
17
|
-
last-checked: '2026-
|
|
15
|
+
last-updated: '2026-10-19'
|
|
16
|
+
last-checked: '2026-10-19'
|
|
18
17
|
---
|
|
19
18
|
|
|
20
19
|
# Drive Assignment Workflow
|
|
@@ -28,82 +27,6 @@ Drive agent execution through an active assignment by continuously checking stat
|
|
|
28
27
|
- An active assignment exists (created via `ace-assign create` or `/as-assign-create`)
|
|
29
28
|
- Assignment has at least one pending or active step
|
|
30
29
|
|
|
31
|
-
## Ordinary installed execution
|
|
32
|
-
|
|
33
|
-
Select this branch **before resolving any local assignment** when invoked with
|
|
34
|
-
`--ordinary <context.json>` or when `ACE_ASSIGN_ORDINARY_CONTEXT` is set. Require
|
|
35
|
-
`ACE_ASSIGN_ORDINARY_PROJECT` and use the exact retained context path throughout.
|
|
36
|
-
Conflicting explicit and environment paths are an error. In this branch every
|
|
37
|
-
execution read and write uses `ace-lab assignment drive --project <project>
|
|
38
|
-
--context <context.json>` against the installed owner. The local assignment
|
|
39
|
-
commands below, `.current`, `.latest`, `fork-run`, and protected `work-on --project`
|
|
40
|
-
are not fallback routes.
|
|
41
|
-
|
|
42
|
-
1. Run `--operation status`. If `not_started`, run `--operation start` from the
|
|
43
|
-
actual native worker pane. A launch/send acknowledgement is not a start receipt.
|
|
44
|
-
Verify canonical status is `running` with the expected assignment, attempt,
|
|
45
|
-
scope, native binding and producer. Never adopt another pane's execution.
|
|
46
|
-
2. Run `--operation bootstrap --output <new-private-directory>`. Read the returned
|
|
47
|
-
accepted task/context/report paths and retain their exact manifest and file
|
|
48
|
-
digests in the work report. These bytes come from canonical prepared work;
|
|
49
|
-
mutable task files in a checkout cannot replace them. Resolve referenced
|
|
50
|
-
project workflows/guides with the selected installed packages and record each
|
|
51
|
-
effective path and digest. A missing or conflicting required asset is a blocker.
|
|
52
|
-
3. Run `--operation next`. Execute the returned current step, or start the returned
|
|
53
|
-
next step using `--operation step-start --step <number> --generation <observed>`.
|
|
54
|
-
The accepted root's children run in this already admitted worker; do not fork
|
|
55
|
-
another execution because a prepared root originated in a batch preset.
|
|
56
|
-
4. After executing a step, write its bounded UTF-8 report and run
|
|
57
|
-
`--operation step-finish --step <number> --report <path> --generation <observed>`.
|
|
58
|
-
On an unrecoverable step failure, use `--operation fail --message <reason>
|
|
59
|
-
--generation <observed>`. Read `next` again after every acknowledged mutation.
|
|
60
|
-
Do not mark an unexecuted step successful. Nested skills may perform the work,
|
|
61
|
-
but their local Assign bookkeeping must not replace these canonical operations.
|
|
62
|
-
5. When the scope is complete or failed, prepare an execution receipt and exact
|
|
63
|
-
artifact files using the receipt contract in the Lab usage documentation.
|
|
64
|
-
Its producer is the canonical start producer; HEAD is the actual committed
|
|
65
|
-
candidate; checks describe executed checks. Submit with `--operation result
|
|
66
|
-
--generation <observed> --receipt <json> --artifact <file>` in receipt order.
|
|
67
|
-
Submission is not terminal acceptance, merge, publication or installation.
|
|
68
|
-
6. Keep the worker's native process and checkout available until the supervisor
|
|
69
|
-
accepts the result through `--operation adopt` and canonical `status` becomes
|
|
70
|
-
terminal. The filesystem watch emits only a hint. Never infer completion from
|
|
71
|
-
a quiet pane, a hint file, an old message or a send acknowledgement.
|
|
72
|
-
|
|
73
|
-
Each mutation prints its retained original request path. After any lost reply,
|
|
74
|
-
read canonical `status`/`next` first and use `--operation replay --request <path>`
|
|
75
|
-
only for that original input. Preserve assignment, attempt, mutation, candidate
|
|
76
|
-
and pane identities. Never edit an original request's generation or bytes. For a
|
|
77
|
-
result/finish CAS refusal, reread canonical status. An accepted result replays its
|
|
78
|
-
exact original input; an accepted terminal outcome needs no new finish. If no
|
|
79
|
-
result/terminal was accepted and the attempt generation advanced, the original
|
|
80
|
-
CAS can no longer accept: result/finish may retain a separate request at the new
|
|
81
|
-
observed generation. The driver preserves all old inputs and performs these
|
|
82
|
-
checks; unavailable status remains a blocker. Changed content, project or owner
|
|
83
|
-
is not a generation retry, and never authorizes another worker.
|
|
84
|
-
|
|
85
|
-
A supervisor installs the `watch_command` returned by `ace-overseer ordinary`
|
|
86
|
-
exactly once in its native session, runs a harmless turn to persist it, and uses
|
|
87
|
-
exact-session resume thereafter. Do not recreate an intentionally removed watch.
|
|
88
|
-
A watch merely requests canonical inspection; recurring native progress audits
|
|
89
|
-
also find accepted results when a wake or reply is lost. Wrong project/attempt
|
|
90
|
-
hints carry no authority. Existing inbound Inbox settlement remains a separate
|
|
91
|
-
owner configuration: without it, nonempty Inbox references refuse completion.
|
|
92
|
-
|
|
93
|
-
After replacement of the coordinator process, read `--operation supervisor`.
|
|
94
|
-
A new coordinator uses `--operation adopt-supervisor --pane <actual-pane>
|
|
95
|
-
--generation <old-selection-generation> --previous-binding-sha256 <old-digest>`.
|
|
96
|
-
The installed owner authenticates its actual placement and positively verifies
|
|
97
|
-
that the original process generation ended. Live or unobservable old generations
|
|
98
|
-
refuse adoption. Replay the original adoption request after a lost reply. This
|
|
99
|
-
changes only the canonical supervisor selection; existing workers, uncertain
|
|
100
|
-
launches, attempts, pending results and mutation IDs remain intact. Then resume
|
|
101
|
-
canonical inspection and result adoption. Never re-register or relaunch workers
|
|
102
|
-
because the coordinator restarted.
|
|
103
|
-
|
|
104
|
-
**End of ordinary branch.** The remaining sections apply only to local assignment
|
|
105
|
-
execution; do not enter them from an ordinary installed context.
|
|
106
|
-
|
|
107
30
|
## Assignment Context Propagation
|
|
108
31
|
|
|
109
32
|
When working with multiple concurrent assignments, the active assignment is resolved in this order:
|
|
@@ -733,130 +656,54 @@ Follow the instructions directly, performing the described work:
|
|
|
733
656
|
|
|
734
657
|
**Agent Action:** Execute each instruction line as a task.
|
|
735
658
|
|
|
736
|
-
### 4.
|
|
737
|
-
|
|
738
|
-
Every external-facing step (implement, verify, review, merge, publish, deploy, release) runs inside a scoped attempt. The attempt -- not the report and not exit status -- is the delivery record.
|
|
739
|
-
|
|
740
|
-
For an original protected PreparedWorker, use its already admitted assignment,
|
|
741
|
-
attempt and selected scope. Do not run the local `attempt start`/receipt-file
|
|
742
|
-
sequence below, acquire another attempt, or execute an outer preset step. The
|
|
743
|
-
delivery step must already belong to the immutable captured subtree. Submit the
|
|
744
|
-
actual candidate and obtain the installed independent reviewer acceptance through
|
|
745
|
-
the protected commands supplied by the original drive prompt.
|
|
746
|
-
|
|
747
|
-
For an authorized protected merge, retain the exact approved head/candidate
|
|
748
|
-
generation, structured input file, installed receiver, authorization and stable
|
|
749
|
-
request ID. Read current authority generation for the first new request. Invoke
|
|
750
|
-
`ace-lab service request` with those original mapping/assignment/attempt/scope
|
|
751
|
-
selectors. Inspect `ace-lab service status` with the same request, input digest and
|
|
752
|
-
target, then consume succeeded canonical evidence with `ace-assign delivery
|
|
753
|
-
--operation merge --service-request REQUEST` and the same selectors. Include
|
|
754
|
-
`--artifact-digest` on status and consumption when the original target has one.
|
|
755
|
-
Exact retries retain the original generation, mutation/request ID and input bytes;
|
|
756
|
-
uncertainty never permits refreshing or resending an effect. The protected delivery
|
|
757
|
-
consumer verifies the imported receipt and canonical delivery event without another
|
|
758
|
-
provider mutation. Only that succeeded result permits finishing the active queue
|
|
759
|
-
step. Refusal, unavailable evidence or uncertainty leaves it unfinished and reports
|
|
760
|
-
the exact blocker. Credentials and queue completion do not replace authorization
|
|
761
|
-
or canonical evidence. The following local attempt sequence applies only to
|
|
762
|
-
ordinary standalone assignments.
|
|
763
|
-
|
|
764
|
-
**Step 1: Start the attempt before executing the step.** Actor identity is derived from the execution boundary; never pass actor flags.
|
|
765
|
-
|
|
766
|
-
```bash
|
|
767
|
-
ATTEMPT_JSON=$(ace-assign attempt start --assignment "$ASSIGNMENT_ID" --step "$STEP_NUMBER" --project "$PROJECT_ID")
|
|
768
|
-
echo "$ATTEMPT_JSON"
|
|
769
|
-
```
|
|
770
|
-
|
|
771
|
-
- A repeated identical start returns the same attempt; a conflicting start fails (exit 5). Never launch a second writer for an owned subtree.
|
|
772
|
-
- `base_head` is captured exactly once at start. Record the `attempt_id`.
|
|
773
|
-
|
|
774
|
-
**Step 2: Execute the step command(s).** If blocked, capture concrete evidence:
|
|
775
|
-
|
|
776
|
-
- command attempted
|
|
777
|
-
- exact error output
|
|
778
|
-
- why the step cannot proceed
|
|
659
|
+
### 4. Execute the Active Step Directly
|
|
779
660
|
|
|
780
|
-
|
|
661
|
+
Execute the active step's instructions directly, run the checks it requires, and
|
|
662
|
+
record the real results in the step report.
|
|
781
663
|
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
"attempt_id": "<ATTEMPT_ID>",
|
|
792
|
-
"assignment_id": "<ASSIGNMENT_ID>",
|
|
793
|
-
"project_id": "<PROJECT_ID>",
|
|
794
|
-
"scope": "<STEP_NUMBER>",
|
|
795
|
-
"operation": "implement",
|
|
796
|
-
"producer": {"actor": "<boundary-actor>", "role": "worker", "runtime": "<boundary-runtime>"},
|
|
797
|
-
"head": "<exact tested/reviewed HEAD sha>",
|
|
798
|
-
"verdict": "succeeded",
|
|
799
|
-
"artifacts": [{"path": "report.md", "sha256": "<sha256>"}],
|
|
800
|
-
"checks": [{"name": "ace-test", "verdict": "passed"}],
|
|
801
|
-
"review": {"reviewer": {"actor": "<independent-reviewer>", "runtime": "<reviewer-runtime>"}, "verdict": "approved", "head": "<same HEAD sha>"}
|
|
802
|
-
}
|
|
803
|
-
EOF
|
|
804
|
-
|
|
805
|
-
ace-assign attempt finish --attempt "$ATTEMPT_ID" --receipt /tmp/attempt-receipt.json
|
|
806
|
-
```
|
|
807
|
-
|
|
808
|
-
Receipt rules enforced by the coordinator:
|
|
809
|
-
|
|
810
|
-
- `succeeded` verdicts require verifiable artifact digests, passing checks, and trusted coordinator/service authority; worker runtimes may submit attributable results but cannot self-approve.
|
|
811
|
-
- Review approval requires an executed independent reviewer verdict for the exact current head; same author/reviewer and report-only existence are rejected.
|
|
812
|
-
- Receipts carrying credentials, environment dumps, or terminal output are rejected outright.
|
|
813
|
-
- External effects (`merge`, `publish`, `deploy`, `release`) additionally require an accepted independent review receipt for the current head. Taskless assignments cannot record external effects.
|
|
814
|
-
|
|
815
|
-
**Step 4: Handle interruptions by classifying and reconciling -- never by assuming.**
|
|
816
|
-
|
|
817
|
-
```bash
|
|
818
|
-
ace-assign attempt status --assignment "$ASSIGNMENT_ID" --format json
|
|
819
|
-
ace-assign attempt reconcile --attempt "$ATTEMPT_ID"
|
|
820
|
-
ace-assign attempt reconcile --attempt "$ATTEMPT_ID" --receipt /tmp/attempt-receipt.json
|
|
821
|
-
```
|
|
822
|
-
|
|
823
|
-
- A lost receipt after a possible effect is `uncertain`; it resolves only against a verified receipt attributed to the recorded execution boundary.
|
|
824
|
-
- Running attempts stay running only while their recorded process is verifiably live; anything else becomes `stopped` or `uncertain`.
|
|
825
|
-
- Never replay `merge`, `publish`, or `deploy` automatically. Reconciliation records evidence; it never re-executes effects.
|
|
664
|
+
- If the work is blocked, capture the command you ran, the exact error output,
|
|
665
|
+
and why the step cannot proceed, then fail the step with that evidence (see
|
|
666
|
+
[Handle Failures](#7-handle-failures)).
|
|
667
|
+
- Record actual test and review results for the exact candidate head in the
|
|
668
|
+
assignment report (or the project task folder) before advancing. A report or
|
|
669
|
+
exit code alone is not proof by itself; report only what was actually run.
|
|
670
|
+
- Never replay `merge`, `publish`, or `deploy` automatically. An uncertain
|
|
671
|
+
external effect is reconciled against the authoritative remote/owner first;
|
|
672
|
+
reconciliation never re-executes the effect by itself.
|
|
826
673
|
|
|
827
674
|
#### Integration Gate and Typed Outcomes (every integration invocation)
|
|
828
675
|
|
|
829
676
|
These gates apply at EVERY integration entry point — a native integrate
|
|
830
|
-
command
|
|
831
|
-
|
|
677
|
+
command or an assignment integration step — with shared contract validation so
|
|
678
|
+
no entry point bypasses them.
|
|
832
679
|
|
|
833
680
|
- Before any mutation, resolve FRESH repository, PR, candidate exact head,
|
|
834
681
|
target base/head, review/test evidence and the authorized executor; recheck
|
|
835
682
|
target/head immediately before the mutation. A detected race invalidates
|
|
836
683
|
eligibility for that invocation.
|
|
837
|
-
- The low-level
|
|
684
|
+
- The low-level integrator ENFORCES the gates and returns one typed
|
|
838
685
|
outcome: `merged`, `needs-rebase`, `blocked` or `uncertain`. It never
|
|
839
686
|
authors, rebases or reviews its own candidate. Relay alone is not
|
|
840
|
-
execution: the
|
|
687
|
+
execution: the integrating agent monitors the actual result and continuation.
|
|
841
688
|
- If the target (current main) is NOT an ancestor of the candidate head, the
|
|
842
|
-
outcome is `needs-rebase`: never merge and never silently rewrite. The
|
|
843
|
-
|
|
844
|
-
preservation) in the candidate's isolated worktree, obtains
|
|
845
|
-
exact-head checks plus independent review of the NEW head, updates
|
|
846
|
-
verifies remote candidate identity and resubmits. A common old base
|
|
847
|
-
NOT make sibling heads sequentially fast-forwardable.
|
|
848
|
-
- Integration is serial in PREPARATION as well as in effect: the
|
|
849
|
-
|
|
850
|
-
candidate — never a mass rebase of the remaining queue. Each
|
|
851
|
-
its turn: resolve fresh target main; delegate `wfi://git/rebase`
|
|
852
|
-
candidate's isolated worktree IF needed; run the applicable checks;
|
|
853
|
-
an INDEPENDENT EXPLICIT review of the resulting exact head (patch
|
|
854
|
-
may support a short delta review but never substitutes the explicit
|
|
855
|
-
independent head approval); verify the remote PR head/base; issue ONE
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
689
|
+
outcome is `needs-rebase`: never merge and never silently rewrite. The
|
|
690
|
+
integrating agent delegates `wfi://git/rebase` (as-git-rebase, including
|
|
691
|
+
CHANGELOG preservation) in the candidate's isolated worktree, obtains
|
|
692
|
+
refreshed exact-head checks plus independent review of the NEW head, updates
|
|
693
|
+
the PR, verifies remote candidate identity and resubmits. A common old base
|
|
694
|
+
does NOT make sibling heads sequentially fast-forwardable.
|
|
695
|
+
- Integration is serial in PREPARATION as well as in effect: the confirmed
|
|
696
|
+
integration result for one candidate causes preparation of ONLY the next
|
|
697
|
+
selected candidate — never a mass rebase of the remaining queue. Each
|
|
698
|
+
candidate, on its turn: resolve fresh target main; delegate `wfi://git/rebase`
|
|
699
|
+
in that candidate's isolated worktree IF needed; run the applicable checks;
|
|
700
|
+
obtain an INDEPENDENT EXPLICIT review of the resulting exact head (patch
|
|
701
|
+
identity may support a short delta review but never substitutes the explicit
|
|
702
|
+
independent head approval); verify the remote PR head/base; issue ONE scoped
|
|
703
|
+
integrator request; wait/reconcile the actual integration outcome; refresh
|
|
704
|
+
main; select and prepare ONLY the next candidate. Queued later PRs keep their
|
|
705
|
+
existing branches/heads untouched until their turn; prior batch work is never
|
|
706
|
+
rolled back or reset.
|
|
860
707
|
- `uncertain` triggers reconciliation against the original durable reference;
|
|
861
708
|
it never permits blind retry.
|
|
862
709
|
- Never push directly to main; never switch the canonical checkout to a topic
|
|
@@ -908,7 +755,9 @@ For a blocked step:
|
|
|
908
755
|
|
|
909
756
|
### 5. Write Report (Only After Real Execution)
|
|
910
757
|
|
|
911
|
-
After the
|
|
758
|
+
After executing the step (or failing it with concrete evidence), write a brief report summarizing what was accomplished. The report is the local record: state what was actually run and link or paste the actual test/review evidence for the exact head.
|
|
759
|
+
|
|
760
|
+
**Re-read state before every finish.** In forked assignment subtrees, queued child steps can auto-advance between status checks, and a report submitted against a stale view can land on the wrong step number. Immediately before every `ace-assign finish --message` (and every `ace-assign fail`), re-run `ace-assign status --assignment "$ASSIGNMENT_TARGET"` and confirm the step you are reporting on is still the active step. If the active step moved, re-target or re-plan the report instead of submitting it against the old step.
|
|
912
761
|
|
|
913
762
|
```bash
|
|
914
763
|
# Write report content to a temp file
|
|
@@ -919,20 +768,23 @@ Completed the setup step successfully:
|
|
|
919
768
|
|
|
920
769
|
- Installed all dependencies via npm install
|
|
921
770
|
- Configured PostgreSQL database connection
|
|
922
|
-
- Verified installation with health check
|
|
771
|
+
- Verified installation with health check (command + observed output)
|
|
923
772
|
|
|
924
773
|
All setup prerequisites are now satisfied.
|
|
925
774
|
EOF
|
|
926
775
|
|
|
776
|
+
# Re-check active state immediately before submitting the report
|
|
777
|
+
ace-assign status --assignment "$ASSIGNMENT_TARGET"
|
|
778
|
+
|
|
927
779
|
# Submit report to advance the queue
|
|
928
780
|
ace-assign finish --message /tmp/step-report.md --assignment "$ASSIGNMENT_TARGET"
|
|
929
781
|
```
|
|
930
782
|
|
|
931
783
|
Prohibited:
|
|
932
784
|
|
|
933
|
-
- Advancing a step
|
|
934
|
-
- Treating a written report, exit 0, or prose as proof
|
|
935
|
-
- Reporting
|
|
785
|
+
- Advancing a step that was not executed or whose result has no recorded evidence.
|
|
786
|
+
- Treating a written report, exit 0, or prose as proof when the required tests or review were not run.
|
|
787
|
+
- Reporting an uncertain external effect as complete; reconcile the original effect first.
|
|
936
788
|
|
|
937
789
|
### 6. Verify State Transition (Required)
|
|
938
790
|
|
|
@@ -1080,7 +932,7 @@ When executing a step with a `skill:` field:
|
|
|
1080
932
|
| Step fails | Attempt first, then use `fail` with command/error evidence; decide retry/add/ask |
|
|
1081
933
|
| Skill not found | Execute instructions directly without skill |
|
|
1082
934
|
| Unclear instructions | Ask user for clarification |
|
|
1083
|
-
| Provider/tool unavailable | For fork steps: see Provider-Unavailability Recovery. For inline steps:
|
|
935
|
+
| Provider/tool unavailable | For fork steps: see Provider-Unavailability Recovery. For inline steps: retry with an alternate model, then fail with evidence |
|
|
1084
936
|
|
|
1085
937
|
## Assignment State Reference
|
|
1086
938
|
|
|
@@ -334,7 +334,7 @@ steps:
|
|
|
334
334
|
|
|
335
335
|
### 8. Output Result
|
|
336
336
|
|
|
337
|
-
Default output: `<task>/jobs/<timestamp>-job.yml` (e.g., `.ace-task
|
|
337
|
+
Default output: `<task>/jobs/<timestamp>-job.yml` (e.g., `.ace-tasks/<task-folder>/jobs/k5abc123-job.yml`)
|
|
338
338
|
|
|
339
339
|
Custom output: Use `--output path/to/custom.yaml`
|
|
340
340
|
|
|
@@ -3,8 +3,8 @@ doc-type: workflow
|
|
|
3
3
|
title: Assign Verify Test Suite Workflow
|
|
4
4
|
purpose: Narrow deterministic verification contract for ace-assign orchestration
|
|
5
5
|
ace-docs:
|
|
6
|
-
last-updated: 2026-
|
|
7
|
-
last-checked: 2026-
|
|
6
|
+
last-updated: 2026-10-19
|
|
7
|
+
last-checked: 2026-10-19
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# Verify Test Suite Workflow
|
|
@@ -25,6 +25,12 @@ Do not run `ace-test-e2e` or `ace-test-e2e-suite` from this workflow.
|
|
|
25
25
|
4. Run `ace-test <package> all --profile 6` for each modified package.
|
|
26
26
|
5. Run `ace-test-suite --target all`.
|
|
27
27
|
|
|
28
|
+
## Hermetic Environment Rule (Forked Drive Sessions)
|
|
29
|
+
|
|
30
|
+
Package verification frequently runs inside forked assignment drive sessions, where the launcher exports fork-runtime variables (`ACE_ASSIGN_DEFAULT_TARGET`, `ACE_ASSIGN_CURRENT_ASSIGNMENT_ID`, `ACE_ASSIGN_CURRENT_FORK_ROOT`, `ACE_RUNTIME`, `ACE_ASSIGN_LAUNCH_MODE`, `ACE_ASSIGN_FORK_WINDOW`, `ACE_ASSIGN_CALLBACK_PANE`, `PROJECT_ROOT_PATH`) and ambient tmux session variables (`TMUX`, `TMUX_PANE`) may also be present. Do not scrub these by hand and never bypass the runner with raw `bundle exec rake`/`ruby` inside a forked subtree.
|
|
31
|
+
|
|
32
|
+
Always verify through `ace-test` / `ace-test-suite`: the deterministic test runner applies a hermetic environment policy that drops all ambient `ACE_*` and `LAB_*` runtime configuration (including every `ACE_ASSIGN_*` fork-runtime variable) before any test executes, in-process and for spawned subprocesses. Verification results are therefore identical whether the command runs from a clean shell or from inside a forked drive session; any other invocation forfeits that guarantee.
|
|
33
|
+
|
|
28
34
|
## Skip Guidance
|
|
29
35
|
|
|
30
36
|
Skip only when all modified files are documentation, retrospectives, task specs, or similarly non-runnable metadata.
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
require_relative "../../authority/protected_assignment_context"
|
|
3
2
|
|
|
4
3
|
module Ace
|
|
5
4
|
module Assign
|
|
@@ -12,16 +11,11 @@ module Ace
|
|
|
12
11
|
# - <assignment-id>@<step-number>
|
|
13
12
|
module AssignmentTarget
|
|
14
13
|
DEFAULT_TARGET_ENV = "ACE_ASSIGN_DEFAULT_TARGET"
|
|
15
|
-
Target = Struct.new(:assignment_id, :scope,
|
|
14
|
+
Target = Struct.new(:assignment_id, :scope, keyword_init: true)
|
|
16
15
|
View = Struct.new(:assignment, :state, :scoped_state, :active_steps, :next_step, :focus_step, :scope_root, keyword_init: true)
|
|
17
16
|
|
|
18
17
|
private
|
|
19
18
|
|
|
20
|
-
def refuse_protected_graph_mutation!(options)
|
|
21
|
-
context = @protected_assignment_context ||= Ace::Assign::Authority::ProtectedAssignmentContext.load
|
|
22
|
-
context.refuse_graph_mutation!(options: options)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
19
|
def resolve_assignment_target(options)
|
|
26
20
|
assignment_raw = options[:assignment]
|
|
27
21
|
explicit_target = unless assignment_raw.nil? || assignment_raw.to_s.strip.empty?
|
|
@@ -35,13 +29,7 @@ module Ace
|
|
|
35
29
|
"does not match #{DEFAULT_TARGET_ENV}=#{target_identity(env_target)}"
|
|
36
30
|
end
|
|
37
31
|
|
|
38
|
-
|
|
39
|
-
context = @protected_assignment_context ||= Ace::Assign::Authority::ProtectedAssignmentContext.load
|
|
40
|
-
target.prepared_input = context.resolve(options: options, assignment_id: target.assignment_id, scope: target.scope)
|
|
41
|
-
if target.prepared_input && ![Status, Step, Start, Finish, Fail, Resume].any? { |command| is_a?(command) }
|
|
42
|
-
raise AttemptErrors::EvidenceUnavailable, "protected queue command requires a reviewed new prepared version and attempt"
|
|
43
|
-
end
|
|
44
|
-
target
|
|
32
|
+
explicit_target || env_target || Target.new(assignment_id: nil, scope: nil)
|
|
45
33
|
end
|
|
46
34
|
|
|
47
35
|
def parse_assignment_target(raw)
|
|
@@ -75,7 +63,6 @@ module Ace
|
|
|
75
63
|
end
|
|
76
64
|
|
|
77
65
|
def build_executor_for_target(target)
|
|
78
|
-
return Ace::Assign::Authority::PreparedExecutor.new(target.prepared_input) if target.prepared_input
|
|
79
66
|
return Organisms::AssignmentExecutor.new unless target.assignment_id
|
|
80
67
|
|
|
81
68
|
manager = Molecules::AssignmentManager.new
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
require "json"
|
|
3
2
|
|
|
4
3
|
module Ace
|
|
5
4
|
module Assign
|
|
@@ -12,7 +11,6 @@ module Ace
|
|
|
12
11
|
|
|
13
12
|
desc "Create a new workflow assignment"
|
|
14
13
|
|
|
15
|
-
option :delivery_parameters, desc: "JSON file with forge selection and explicit PR provenance (task mode)"
|
|
16
14
|
option :yaml, desc: "Path to job.yaml config file"
|
|
17
15
|
option :task, aliases: ["-t"], type: :array,
|
|
18
16
|
desc: "Task reference(s), repeatable and comma-separated"
|
|
@@ -21,17 +19,14 @@ module Ace
|
|
|
21
19
|
option :debug, aliases: ["-d"], type: :boolean, default: false, desc: "Show debug output"
|
|
22
20
|
|
|
23
21
|
def call(yaml: nil, task: nil, preset: nil, **options)
|
|
24
|
-
refuse_protected_graph_mutation!(options)
|
|
25
22
|
validate_modes!(yaml, task, preset)
|
|
26
|
-
raise Ace::Support::Cli::Error, "--delivery-parameters requires --task" if yaml && options[:delivery_parameters]
|
|
27
23
|
|
|
28
24
|
result = if yaml
|
|
29
25
|
Organisms::AssignmentExecutor.new.start(yaml)
|
|
30
26
|
else
|
|
31
27
|
Organisms::TaskAssignmentCreator.new.call(
|
|
32
28
|
task_refs: task,
|
|
33
|
-
preset_name: preset || Organisms::TaskAssignmentCreator::DEFAULT_PRESET
|
|
34
|
-
delivery_parameters: options[:delivery_parameters] && JSON.parse(File.read(options[:delivery_parameters]))
|
|
29
|
+
preset_name: preset || Organisms::TaskAssignmentCreator::DEFAULT_PRESET
|
|
35
30
|
)
|
|
36
31
|
end
|
|
37
32
|
|
|
@@ -40,8 +35,6 @@ module Ace
|
|
|
40
35
|
print_assignment_header(result[:assignment])
|
|
41
36
|
print_step_instructions(result[:current] || result[:state]&.next_workable)
|
|
42
37
|
end
|
|
43
|
-
rescue JSON::ParserError, Errno::ENOENT
|
|
44
|
-
raise Ace::Support::Cli::Error, "Delivery parameters file unavailable or invalid JSON"
|
|
45
38
|
rescue ArgumentError => e
|
|
46
39
|
raise Ace::Support::Cli::Error, e.message
|
|
47
40
|
end
|
|
@@ -12,8 +12,6 @@ module Ace
|
|
|
12
12
|
desc "Mark current step as failed"
|
|
13
13
|
|
|
14
14
|
option :message, aliases: ["-m"], required: true, desc: "Error message"
|
|
15
|
-
option :mapping, desc: "Installed protected launch mapping ID"
|
|
16
|
-
option :attempt, desc: "Original protected attempt ID"
|
|
17
15
|
option :assignment, desc: "Target specific assignment ID"
|
|
18
16
|
option :quiet, aliases: ["-q"], type: :boolean, default: false, desc: "Suppress non-essential output"
|
|
19
17
|
option :debug, aliases: ["-d"], type: :boolean, default: false, desc: "Show debug output"
|
|
@@ -30,10 +28,6 @@ module Ace
|
|
|
30
28
|
puts "Step #{failed.number} (#{failed.name}) marked as failed"
|
|
31
29
|
puts "Updated: #{File.basename(failed.file_path)}"
|
|
32
30
|
puts "Error: #{message}"
|
|
33
|
-
if target.prepared_input
|
|
34
|
-
puts "Further work requires a reviewed new prepared version and attempt."
|
|
35
|
-
return
|
|
36
|
-
end
|
|
37
31
|
puts
|
|
38
32
|
puts "Options:"
|
|
39
33
|
puts "- ace-assign add \"fix-step\" to add a fix step"
|
|
@@ -13,8 +13,6 @@ module Ace
|
|
|
13
13
|
|
|
14
14
|
argument :step, required: false, desc: "Step number to finish (active assignment only)"
|
|
15
15
|
option :message, aliases: ["-m"], desc: "Report content: string, file path, or pipe stdin"
|
|
16
|
-
option :mapping, desc: "Installed protected launch mapping ID"
|
|
17
|
-
option :attempt, desc: "Original protected attempt ID"
|
|
18
16
|
option :assignment, desc: "Target specific assignment ID"
|
|
19
17
|
option :quiet, aliases: ["-q"], type: :boolean, default: false, desc: "Suppress non-essential output"
|
|
20
18
|
option :debug, aliases: ["-d"], type: :boolean, default: false, desc: "Show debug output"
|
|
@@ -26,7 +24,7 @@ module Ace
|
|
|
26
24
|
|
|
27
25
|
target = resolve_assignment_target(options)
|
|
28
26
|
executor = build_executor_for_target(target)
|
|
29
|
-
report_content = resolve_report_content(options
|
|
27
|
+
report_content = resolve_report_content(options)
|
|
30
28
|
result = executor.finish_step(
|
|
31
29
|
report_content: report_content,
|
|
32
30
|
step_number: step,
|
|
@@ -74,27 +72,8 @@ module Ace
|
|
|
74
72
|
|
|
75
73
|
private
|
|
76
74
|
|
|
77
|
-
def resolve_report_content(options
|
|
75
|
+
def resolve_report_content(options)
|
|
78
76
|
message = options[:message]&.strip
|
|
79
|
-
if protected
|
|
80
|
-
limit = Ace::Assign::Authority::PreparedWork::MAX_TEXT
|
|
81
|
-
if message && !message.empty? && File.exist?(message)
|
|
82
|
-
return File.open(message, File::RDONLY | File::NOFOLLOW | File::NONBLOCK) do |file|
|
|
83
|
-
before = file.stat
|
|
84
|
-
raise Error, "Report input must be a bounded regular file" unless before.file? && before.size.between?(1, limit)
|
|
85
|
-
bytes = file.read(limit + 1)
|
|
86
|
-
after = file.stat
|
|
87
|
-
unless bytes.bytesize == before.size && [before.dev, before.ino, before.size, before.mtime, before.ctime] ==
|
|
88
|
-
[after.dev, after.ino, after.size, after.mtime, after.ctime]
|
|
89
|
-
raise Error, "Report input changed"
|
|
90
|
-
end
|
|
91
|
-
bytes
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
bytes = message && !message.empty? ? message : $stdin.read(limit + 1)
|
|
95
|
-
raise Error, "Report input exceeds captured text bound" unless bytes && bytes.bytesize.between?(1, limit)
|
|
96
|
-
return bytes
|
|
97
|
-
end
|
|
98
77
|
return File.read(message) if message && !message.empty? && File.exist?(message)
|
|
99
78
|
return message if message && !message.empty?
|
|
100
79
|
|
|
@@ -12,8 +12,6 @@ module Ace
|
|
|
12
12
|
desc "Start next workable pending step"
|
|
13
13
|
|
|
14
14
|
argument :step, required: false, desc: "Step number to start (active assignment only)"
|
|
15
|
-
option :mapping, desc: "Installed protected launch mapping ID"
|
|
16
|
-
option :attempt, desc: "Original protected attempt ID"
|
|
17
15
|
option :assignment, desc: "Target specific assignment ID"
|
|
18
16
|
option :quiet, aliases: ["-q"], type: :boolean, default: false, desc: "Suppress non-essential output"
|
|
19
17
|
option :debug, aliases: ["-d"], type: :boolean, default: false, desc: "Show debug output"
|
|
@@ -41,8 +41,6 @@ module Ace
|
|
|
41
41
|
option :format, desc: "Output format (table, json)", default: "table"
|
|
42
42
|
option :quiet, aliases: ["-q"], type: :boolean, default: false, desc: "Suppress non-essential output"
|
|
43
43
|
option :debug, aliases: ["-d"], type: :boolean, default: false, desc: "Show debug output"
|
|
44
|
-
option :mapping, desc: "Installed protected launch mapping ID"
|
|
45
|
-
option :attempt, desc: "Original protected attempt ID"
|
|
46
44
|
option :assignment, desc: "Show status for specific assignment ID"
|
|
47
45
|
option :all, aliases: ["-a"], type: :boolean, default: false, desc: "Include completed assignments in other assignments section"
|
|
48
46
|
|
|
@@ -87,14 +85,9 @@ module Ace
|
|
|
87
85
|
def status_to_h(assignment, state, active_steps, next_step, target:, scope_root:)
|
|
88
86
|
# Extract auto_merge config if present in assignment settings or preset
|
|
89
87
|
auto_merge = false
|
|
90
|
-
preset_name = Ace::Assign::Molecules::PresetInferrer.infer_from_assignment(assignment)
|
|
88
|
+
preset_name = Ace::Assign::Molecules::PresetInferrer.infer_from_assignment(assignment)
|
|
91
89
|
auto_merge = true if preset_name && preset_name.start_with?("work-on-task-auto-merge")
|
|
92
90
|
|
|
93
|
-
evidence = Ace::Assign::Molecules::EvidenceCalculator.calculate(
|
|
94
|
-
auto_merge: auto_merge,
|
|
95
|
-
assignment_id: assignment.id
|
|
96
|
-
)
|
|
97
|
-
|
|
98
91
|
payload = {
|
|
99
92
|
assignment: {
|
|
100
93
|
id: assignment.id,
|
|
@@ -108,9 +101,6 @@ module Ace
|
|
|
108
101
|
|
|
109
102
|
payload[:next_step] = step_to_h(next_step, effective_fork_provider: effective_fork_provider_for(next_step, scoped_fork_metadata_step(state, next_step, target.scope, scope_root))) if active_steps.empty? && next_step
|
|
110
103
|
|
|
111
|
-
# Merge exact head evidence into root payload
|
|
112
|
-
payload.merge!(evidence)
|
|
113
|
-
|
|
114
104
|
payload
|
|
115
105
|
end
|
|
116
106
|
|
|
@@ -137,10 +127,6 @@ module Ace
|
|
|
137
127
|
lines = []
|
|
138
128
|
lines.concat(compact_summary_lines(view.assignment, view.scoped_state, view.active_steps, view.next_step))
|
|
139
129
|
|
|
140
|
-
if !target.prepared_input && (attempt_line = compact_attempt_line(view.assignment.id))
|
|
141
|
-
lines.insert(1, attempt_line)
|
|
142
|
-
end
|
|
143
|
-
|
|
144
130
|
unless target.assignment_id
|
|
145
131
|
other_line = compact_other_assignments_line(view.assignment.id, include_completed: include_completed)
|
|
146
132
|
lines << other_line if other_line
|
|
@@ -149,22 +135,6 @@ module Ace
|
|
|
149
135
|
puts lines.take(10).join("\n")
|
|
150
136
|
end
|
|
151
137
|
|
|
152
|
-
# Active attempt summary projected from the coordinator authority.
|
|
153
|
-
def compact_attempt_line(assignment_id)
|
|
154
|
-
projection = Organisms::AttemptCoordinator.new.status(assignment_id)
|
|
155
|
-
return nil unless projection
|
|
156
|
-
|
|
157
|
-
base = projection["base_head"].to_s[0, 7]
|
|
158
|
-
candidate = projection["candidate_head"].to_s[0, 7]
|
|
159
|
-
line = "Attempt: #{projection['attempt_id']} #{projection['state']}"
|
|
160
|
-
line += " | base:#{base}" unless base.to_s.empty?
|
|
161
|
-
line += " | cand:#{candidate.empty? ? 'none' : candidate}"
|
|
162
|
-
line += " | unresolved: #{projection['unresolved_effects'].join(',')}" if projection["unresolved_effects"].any?
|
|
163
|
-
line
|
|
164
|
-
rescue Ace::Assign::Error, Ace::Support::Cli::Error
|
|
165
|
-
nil
|
|
166
|
-
end
|
|
167
|
-
|
|
168
138
|
def compact_summary_lines(assignment, state, active_steps, next_step)
|
|
169
139
|
lines = [
|
|
170
140
|
compact_assignment_line(assignment, state, active_steps, next_step),
|
|
@@ -12,8 +12,6 @@ module Ace
|
|
|
12
12
|
desc "Show instructions for the active, next, or explicit step"
|
|
13
13
|
|
|
14
14
|
argument :step, required: false, desc: "Exact step number to inspect"
|
|
15
|
-
option :mapping, desc: "Installed protected launch mapping ID"
|
|
16
|
-
option :attempt, desc: "Original protected attempt ID"
|
|
17
15
|
option :assignment, desc: "Target specific assignment ID"
|
|
18
16
|
option :quiet, aliases: ["-q"], type: :boolean, default: false, desc: "Suppress non-essential output"
|
|
19
17
|
option :debug, aliases: ["-d"], type: :boolean, default: false, desc: "Show debug output"
|
|
@@ -26,7 +24,7 @@ module Ace
|
|
|
26
24
|
return if options[:quiet]
|
|
27
25
|
|
|
28
26
|
if inspected
|
|
29
|
-
puts(
|
|
27
|
+
puts(inspected.instructions)
|
|
30
28
|
else
|
|
31
29
|
puts no_work_message(view)
|
|
32
30
|
end
|