ace-assign 0.70.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.
Files changed (181) hide show
  1. checksums.yaml +4 -4
  2. data/.ace-defaults/assign/catalog/steps/auto-merge.step.yml +8 -8
  3. data/.ace-defaults/assign/catalog/steps/create-pr.step.yml +1 -1
  4. data/.ace-defaults/assign/catalog/steps/mark-pr-ready.step.yml +1 -1
  5. data/.ace-defaults/assign/config.yml +0 -13
  6. data/.ace-defaults/assign/presets/fix-bug.yml +1 -1
  7. data/.ace-defaults/assign/presets/work-on-task-ace-development.yml +1 -1
  8. data/.ace-defaults/assign/presets/work-on-task-auto-merge.yml +1 -1
  9. data/.ace-defaults/assign/presets/work-on-task.yml +1 -1
  10. data/CHANGELOG.md +3 -2099
  11. data/README.md +58 -31
  12. data/docs/exit-codes.md +36 -44
  13. data/docs/getting-started.md +9 -4
  14. data/docs/usage.md +129 -522
  15. data/handbook/skills/as-assign-drive/SKILL.md +1 -1
  16. data/handbook/workflow-instructions/assign/drive.wf.md +47 -118
  17. data/handbook/workflow-instructions/assign/prepare.wf.md +1 -1
  18. data/handbook/workflow-instructions/assign/verify-test-suite.wf.md +8 -2
  19. data/lib/ace/assign/cli/commands/assignment_target.rb +2 -15
  20. data/lib/ace/assign/cli/commands/create.rb +1 -8
  21. data/lib/ace/assign/cli/commands/fail.rb +0 -6
  22. data/lib/ace/assign/cli/commands/finish.rb +2 -23
  23. data/lib/ace/assign/cli/commands/fork_session.rb +0 -1
  24. data/lib/ace/assign/cli/commands/select.rb +0 -1
  25. data/lib/ace/assign/cli/commands/start.rb +0 -2
  26. data/lib/ace/assign/cli/commands/status.rb +1 -31
  27. data/lib/ace/assign/cli/commands/step.rb +1 -3
  28. data/lib/ace/assign/cli.rb +1 -85
  29. data/lib/ace/assign/errors.rb +8 -80
  30. data/lib/ace/assign/models/assignment.rb +5 -28
  31. data/lib/ace/assign/molecules/assignment_manager.rb +0 -26
  32. data/lib/ace/assign/molecules/fork_session_launcher.rb +4 -12
  33. data/lib/ace/assign/molecules/lifecycle_exclusion.rb +15 -112
  34. data/lib/ace/assign/molecules/runtime_control_surface_runner.rb +2 -1
  35. data/lib/ace/assign/organisms/assignment_executor.rb +0 -6
  36. data/lib/ace/assign/organisms/task_assignment_creator.rb +3 -8
  37. data/lib/ace/assign/version.rb +1 -1
  38. data/lib/ace/assign.rb +0 -6
  39. metadata +4 -161
  40. data/.ace-defaults/assign/presets/close-delivery.yml +0 -57
  41. data/.ace-defaults/assign/presets/deliver-release.yml +0 -60
  42. data/.ace-defaults/assign/presets/integrate-batch.yml +0 -72
  43. data/.ace-defaults/assign/presets/supervise-delivery.yml +0 -69
  44. data/docs/protected-authority.md +0 -282
  45. data/exe/ace-scope-ready +0 -55
  46. data/lib/ace/assign/atoms/assignment_scope.rb +0 -58
  47. data/lib/ace/assign/atoms/attempt_state_machine.rb +0 -84
  48. data/lib/ace/assign/atoms/delivery_parameters.rb +0 -19
  49. data/lib/ace/assign/atoms/evidence_digest.rb +0 -78
  50. data/lib/ace/assign/atoms/fixed_merge_schemas.rb +0 -398
  51. data/lib/ace/assign/authority/assignment_definition.rb +0 -35
  52. data/lib/ace/assign/authority/assignment_inventory.rb +0 -290
  53. data/lib/ace/assign/authority/campaign_consumer_policy.rb +0 -100
  54. data/lib/ace/assign/authority/campaign_execution.rb +0 -119
  55. data/lib/ace/assign/authority/campaign_round_transfer.rb +0 -82
  56. data/lib/ace/assign/authority/candidate_transfer.rb +0 -327
  57. data/lib/ace/assign/authority/cleanup_result_protection.rb +0 -53
  58. data/lib/ace/assign/authority/client.rb +0 -257
  59. data/lib/ace/assign/authority/deployment.rb +0 -627
  60. data/lib/ace/assign/authority/deployment_history.rb +0 -146
  61. data/lib/ace/assign/authority/endcap.rb +0 -455
  62. data/lib/ace/assign/authority/endcap_attempts.rb +0 -274
  63. data/lib/ace/assign/authority/endcap_campaign_results.rb +0 -232
  64. data/lib/ace/assign/authority/endcap_campaign_rounds.rb +0 -266
  65. data/lib/ace/assign/authority/endcap_contexts.rb +0 -23
  66. data/lib/ace/assign/authority/endcap_inboxes.rb +0 -37
  67. data/lib/ace/assign/authority/endcap_prepared_work.rb +0 -80
  68. data/lib/ace/assign/authority/endcap_publication.rb +0 -207
  69. data/lib/ace/assign/authority/endcap_results.rb +0 -398
  70. data/lib/ace/assign/authority/endcap_review_requests.rb +0 -183
  71. data/lib/ace/assign/authority/endcap_reviews.rb +0 -130
  72. data/lib/ace/assign/authority/endcap_service_settlement.rb +0 -152
  73. data/lib/ace/assign/authority/endcap_services.rb +0 -598
  74. data/lib/ace/assign/authority/evidence_transfer.rb +0 -67
  75. data/lib/ace/assign/authority/execution_scope_observation.rb +0 -903
  76. data/lib/ace/assign/authority/inbox_context_original.rb +0 -113
  77. data/lib/ace/assign/authority/launch_attempt_consumers.rb +0 -51
  78. data/lib/ace/assign/authority/launch_campaign_registration.rb +0 -214
  79. data/lib/ace/assign/authority/launch_control_channel.rb +0 -313
  80. data/lib/ace/assign/authority/launch_control_exclusions.rb +0 -127
  81. data/lib/ace/assign/authority/launch_driver.rb +0 -393
  82. data/lib/ace/assign/authority/launch_input_inhibition.rb +0 -132
  83. data/lib/ace/assign/authority/launch_lifecycle.rb +0 -997
  84. data/lib/ace/assign/authority/launch_prepared_work.rb +0 -122
  85. data/lib/ace/assign/authority/launch_review.rb +0 -91
  86. data/lib/ace/assign/authority/launch_scope_abort.rb +0 -81
  87. data/lib/ace/assign/authority/launch_scope_admission.rb +0 -215
  88. data/lib/ace/assign/authority/launch_scope_close.rb +0 -146
  89. data/lib/ace/assign/authority/launch_scope_parent.rb +0 -44
  90. data/lib/ace/assign/authority/launch_scope_release.rb +0 -859
  91. data/lib/ace/assign/authority/launch_steering.rb +0 -353
  92. data/lib/ace/assign/authority/launch_stop.rb +0 -254
  93. data/lib/ace/assign/authority/maintenance_workspace_retirement.rb +0 -229
  94. data/lib/ace/assign/authority/ordinary_attempt_start.rb +0 -137
  95. data/lib/ace/assign/authority/ordinary_client.rb +0 -70
  96. data/lib/ace/assign/authority/ordinary_completion.rb +0 -94
  97. data/lib/ace/assign/authority/ordinary_effect_settlement.rb +0 -118
  98. data/lib/ace/assign/authority/ordinary_lifecycle.rb +0 -191
  99. data/lib/ace/assign/authority/ordinary_peer.rb +0 -54
  100. data/lib/ace/assign/authority/ordinary_progress.rb +0 -162
  101. data/lib/ace/assign/authority/ordinary_queue.rb +0 -115
  102. data/lib/ace/assign/authority/ordinary_results.rb +0 -196
  103. data/lib/ace/assign/authority/ordinary_server.rb +0 -75
  104. data/lib/ace/assign/authority/original_inbox_selection.rb +0 -41
  105. data/lib/ace/assign/authority/posix_acl.rb +0 -59
  106. data/lib/ace/assign/authority/prepared_input.rb +0 -130
  107. data/lib/ace/assign/authority/prepared_queue.rb +0 -185
  108. data/lib/ace/assign/authority/prepared_task_context.rb +0 -116
  109. data/lib/ace/assign/authority/prepared_work.rb +0 -304
  110. data/lib/ace/assign/authority/prepared_worker.rb +0 -69
  111. data/lib/ace/assign/authority/private_directory.rb +0 -33
  112. data/lib/ace/assign/authority/protected_assignment_context.rb +0 -226
  113. data/lib/ace/assign/authority/readiness_hook.rb +0 -120
  114. data/lib/ace/assign/authority/receipt_transfer.rb +0 -48
  115. data/lib/ace/assign/authority/router.rb +0 -81
  116. data/lib/ace/assign/authority/server.rb +0 -131
  117. data/lib/ace/assign/authority/service_cleanup_dispatch.rb +0 -88
  118. data/lib/ace/assign/authority/service_cleanup_evidence.rb +0 -180
  119. data/lib/ace/assign/authority/service_delivery_evidence.rb +0 -101
  120. data/lib/ace/assign/authority/service_evidence.rb +0 -286
  121. data/lib/ace/assign/authority/service_publication_evidence.rb +0 -110
  122. data/lib/ace/assign/authority/socket_server.rb +0 -255
  123. data/lib/ace/assign/authority/task_context_entry.rb +0 -32
  124. data/lib/ace/assign/authority/transfer_codec.rb +0 -187
  125. data/lib/ace/assign/cli/commands/attempt/base.rb +0 -84
  126. data/lib/ace/assign/cli/commands/attempt/evidence.rb +0 -28
  127. data/lib/ace/assign/cli/commands/attempt/finish.rb +0 -51
  128. data/lib/ace/assign/cli/commands/attempt/reconcile.rb +0 -49
  129. data/lib/ace/assign/cli/commands/attempt/start.rb +0 -45
  130. data/lib/ace/assign/cli/commands/attempt/status.rb +0 -54
  131. data/lib/ace/assign/cli/commands/authority/inbox_context_principal.rb +0 -25
  132. data/lib/ace/assign/cli/commands/authority/inbox_context_selection.rb +0 -28
  133. data/lib/ace/assign/cli/commands/authority/launch.rb +0 -97
  134. data/lib/ace/assign/cli/commands/authority/serve.rb +0 -31
  135. data/lib/ace/assign/cli/commands/authority/status.rb +0 -26
  136. data/lib/ace/assign/cli/commands/authority/task_context.rb +0 -31
  137. data/lib/ace/assign/cli/commands/authority/task_context_principal.rb +0 -25
  138. data/lib/ace/assign/cli/commands/authority/task_context_selection.rb +0 -30
  139. data/lib/ace/assign/cli/commands/authority/terminate.rb +0 -29
  140. data/lib/ace/assign/cli/commands/authority/worker.rb +0 -23
  141. data/lib/ace/assign/cli/commands/campaign_export_result.rb +0 -55
  142. data/lib/ace/assign/cli/commands/campaign_record_round.rb +0 -57
  143. data/lib/ace/assign/cli/commands/delivery.rb +0 -107
  144. data/lib/ace/assign/cli/commands/inbox_bind.rb +0 -34
  145. data/lib/ace/assign/cli/commands/protected_submission.rb +0 -61
  146. data/lib/ace/assign/cli/commands/resume.rb +0 -38
  147. data/lib/ace/assign/cli/commands/submit_candidate.rb +0 -34
  148. data/lib/ace/assign/cli/commands/submit_result.rb +0 -61
  149. data/lib/ace/assign/models/attempt.rb +0 -178
  150. data/lib/ace/assign/models/attempt_binding.rb +0 -116
  151. data/lib/ace/assign/models/evidence_event.rb +0 -86
  152. data/lib/ace/assign/models/execution_receipt.rb +0 -139
  153. data/lib/ace/assign/molecules/attempt_reconciler.rb +0 -127
  154. data/lib/ace/assign/molecules/attempt_store.rb +0 -201
  155. data/lib/ace/assign/molecules/canonical_attempt_state.rb +0 -151
  156. data/lib/ace/assign/molecules/canonical_evidence.rb +0 -153
  157. data/lib/ace/assign/molecules/canonical_read_commands.rb +0 -84
  158. data/lib/ace/assign/molecules/canonical_read_snapshot.rb +0 -313
  159. data/lib/ace/assign/molecules/evidence_calculator.rb +0 -237
  160. data/lib/ace/assign/molecules/evidence_journal.rb +0 -1912
  161. data/lib/ace/assign/molecules/execution_identity_resolver.rb +0 -137
  162. data/lib/ace/assign/molecules/execution_scope_lineage.rb +0 -345
  163. data/lib/ace/assign/molecules/fixed_effect_reference.rb +0 -31
  164. data/lib/ace/assign/molecules/installed_journal_read.rb +0 -143
  165. data/lib/ace/assign/molecules/journal_input_inhibition.rb +0 -78
  166. data/lib/ace/assign/molecules/journal_mutation.rb +0 -273
  167. data/lib/ace/assign/molecules/journal_prompt_mutation.rb +0 -241
  168. data/lib/ace/assign/molecules/ordinary_merge_cli.rb +0 -68
  169. data/lib/ace/assign/molecules/ordinary_merge_contract.rb +0 -410
  170. data/lib/ace/assign/molecules/original_launch_binding.rb +0 -37
  171. data/lib/ace/assign/molecules/proposal_journal.rb +0 -179
  172. data/lib/ace/assign/molecules/protected_control_exclusion.rb +0 -303
  173. data/lib/ace/assign/molecules/protected_workspace_exclusion.rb +0 -330
  174. data/lib/ace/assign/molecules/protected_workspace_provisioner.rb +0 -164
  175. data/lib/ace/assign/molecules/receipt_verifier.rb +0 -314
  176. data/lib/ace/assign/molecules/terminal_scope_receipt.rb +0 -88
  177. data/lib/ace/assign/organisms/attempt_coordinator.rb +0 -1337
  178. data/lib/ace/assign/organisms/delivery_coordinator.rb +0 -342
  179. data/lib/ace/assign/organisms/ordinary_merge_consumer.rb +0 -365
  180. data/lib/ace/assign/organisms/prepared_work_builder.rb +0 -194
  181. data/lib/ace/assign/organisms/protected_delivery_coordinator.rb +0 -100
@@ -9,10 +9,6 @@ require_relative "models/assignment"
9
9
  require_relative "models/step"
10
10
  require_relative "models/queue_state"
11
11
  require_relative "models/assignment_info"
12
- require_relative "models/attempt_binding"
13
- require_relative "models/attempt"
14
- require_relative "models/execution_receipt"
15
- require_relative "models/evidence_event"
16
12
 
17
13
  # Atoms
18
14
  require_relative "atoms/step_numbering"
@@ -26,14 +22,10 @@ require_relative "atoms/catalog_loader"
26
22
  require_relative "atoms/composition_rules"
27
23
  require_relative "atoms/assign_frontmatter_parser"
28
24
  require_relative "atoms/tree_formatter"
29
- require_relative "atoms/attempt_state_machine"
30
- require_relative "atoms/evidence_digest"
31
- require_relative "atoms/assignment_scope"
32
25
 
33
26
  # Molecules
34
27
  require_relative "molecules/lifecycle_exclusion"
35
28
  require_relative "molecules/assignment_manager"
36
- require_relative "molecules/attempt_store"
37
29
  require_relative "molecules/assignment_discoverer"
38
30
  require_relative "molecules/queue_scanner"
39
31
  require_relative "molecules/step_writer"
@@ -42,28 +34,14 @@ require_relative "molecules/skill_assign_source_resolver"
42
34
  require_relative "molecules/fork_session_launcher"
43
35
  require_relative "molecules/runtime_control_surface_runner"
44
36
  require_relative "molecules/preset_inferrer"
45
- require_relative "molecules/evidence_calculator"
46
- require_relative "molecules/evidence_journal"
47
- require_relative "molecules/canonical_evidence"
48
- require_relative "molecules/execution_identity_resolver"
49
- require_relative "molecules/receipt_verifier"
50
- require_relative "molecules/attempt_reconciler"
51
37
 
52
38
  # Organisms
53
39
  require_relative "organisms/assignment_executor"
54
- require_relative "organisms/attempt_coordinator"
55
40
 
56
41
  # Commands
57
- require_relative "cli/commands/delivery"
58
42
  require_relative "cli/commands/assignment_target"
59
43
  require_relative "cli/commands/create"
60
44
  require_relative "cli/commands/status"
61
- require_relative "cli/commands/resume"
62
- require_relative "cli/commands/inbox_bind"
63
- require_relative "cli/commands/submit_candidate"
64
- require_relative "cli/commands/submit_result"
65
- require_relative "cli/commands/campaign_record_round"
66
- require_relative "cli/commands/campaign_export_result"
67
45
  require_relative "cli/commands/step"
68
46
  require_relative "cli/commands/start"
69
47
  require_relative "cli/commands/finish"
@@ -74,22 +52,6 @@ require_relative "cli/commands/list"
74
52
  require_relative "cli/commands/select"
75
53
  require_relative "cli/commands/fork_run"
76
54
  require_relative "cli/commands/fork_session"
77
- require_relative "cli/commands/authority/serve"
78
- require_relative "cli/commands/authority/launch"
79
- require_relative "cli/commands/authority/status"
80
- require_relative "cli/commands/authority/terminate"
81
- require_relative "cli/commands/authority/worker"
82
- require_relative "cli/commands/authority/task_context"
83
- require_relative "cli/commands/authority/task_context_principal"
84
- require_relative "cli/commands/authority/task_context_selection"
85
- require_relative "cli/commands/authority/inbox_context_principal"
86
- require_relative "cli/commands/authority/inbox_context_selection"
87
- require_relative "cli/commands/attempt/base"
88
- require_relative "cli/commands/attempt/start"
89
- require_relative "cli/commands/attempt/status"
90
- require_relative "cli/commands/attempt/finish"
91
- require_relative "cli/commands/attempt/reconcile"
92
- require_relative "cli/commands/attempt/evidence"
93
55
 
94
56
  module Ace
95
57
  module Assign
@@ -102,21 +64,6 @@ module Ace
102
64
  # Application commands with descriptions (for help output)
103
65
  REGISTERED_COMMANDS = [
104
66
  ["create", "Create assignment from preset or YAML"],
105
- ["authority serve", "Serve the installed protected assignment owner"],
106
- ["authority launch", "Launch one mapped native gated worker"],
107
- ["authority status", "Inspect protected launch ownership"],
108
- ["authority terminate", "Terminate the original native gated child"],
109
- ["authority worker", "Consume original authenticated prepared work"],
110
- ["authority task-context", "Read captured original task context through the fixed entry"],
111
- ["authority task-context-principal", "Classify the actual caller through retained protected owners"],
112
- ["authority task-context-selection", "Read the authenticated original context entry selection"],
113
- ["authority inbox-context-principal", "Classify the actual caller through every retained protected owner"],
114
- ["authority inbox-context-selection", "Read the fixed installed inbox context selection"],
115
- ["delivery", "Execute or reconcile attempt-bound forge delivery"],
116
- ["submit-candidate", "Submit original protected worker candidate bytes"],
117
- ["submit-result", "Submit original protected worker receipt and artifact bytes"],
118
- ["campaign-export-result", "Download the original parent campaign's verified accepted result"],
119
- ["campaign-record-round", "Consume canonical settled children into the original campaign store"],
120
67
  ["status", "Show assignment status"],
121
68
  ["step", "Show step instructions"],
122
69
  ["start", "Start next workable step"],
@@ -127,12 +74,6 @@ module Ace
127
74
  ["list", "List all assignments"],
128
75
  ["select", "Select active assignment"],
129
76
  ["fork-run", "Run subtree in forked process"],
130
- ["attempt start", "Start a scoped attempt for an assignment step"],
131
- ["attempt status", "Show attempt status for an assignment"],
132
- ["attempt evidence", "Read accepted current-head check evidence"],
133
- ["attempt finish", "Finish a protected canonical result or an ordinary local receipt"],
134
- ["attempt reconcile", "Recover an exact protected attempt or reconcile an ordinary attempt"],
135
- ["inbox-bind", "Bind an original protected Inbox registration"],
136
77
  ].freeze
137
78
 
138
79
  HELP_EXAMPLES = [
@@ -142,10 +83,7 @@ module Ace
142
83
  "ace-assign start # Start next workable step",
143
84
  "ace-assign finish --message done.md # Complete active step",
144
85
  "cat report.md | ace-assign finish # Complete step via stdin",
145
- "ace-assign fork-run 010.01 # Run subtree in subprocess",
146
- "ace-assign attempt start --assignment ID --step 010 --project ID",
147
- "ace-assign attempt finish --attempt ID --receipt receipt.json",
148
- "ace-assign resume --assignment ID --dry-run"
86
+ "ace-assign fork-run 010.01 # Run subtree in subprocess"
149
87
  ].freeze
150
88
 
151
89
  # Captured command exit code from last run
@@ -181,18 +119,7 @@ module Ace
181
119
  end
182
120
 
183
121
  # Register commands (wrapped to capture exit codes)
184
- register "authority serve", wrap_command(Commands::Authority::Serve)
185
- register "authority launch", wrap_command(Commands::Authority::Launch)
186
- register "authority status", wrap_command(Commands::Authority::Status)
187
- register "authority terminate", wrap_command(Commands::Authority::Terminate)
188
- register "authority worker", wrap_command(Commands::Authority::Worker)
189
- register "authority task-context", wrap_command(Commands::Authority::TaskContext)
190
- register "authority task-context-principal", wrap_command(Commands::Authority::TaskContextPrincipal)
191
- register "authority task-context-selection", wrap_command(Commands::Authority::TaskContextSelection)
192
- register "authority inbox-context-principal", wrap_command(Commands::Authority::InboxContextPrincipal)
193
- register "authority inbox-context-selection", wrap_command(Commands::Authority::InboxContextSelection)
194
122
  register "create", wrap_command(Commands::Create)
195
- register "delivery", wrap_command(Commands::Delivery)
196
123
  register "status", wrap_command(Commands::Status)
197
124
  register "step", wrap_command(Commands::Step)
198
125
  register "start", wrap_command(Commands::Start)
@@ -204,17 +131,6 @@ register "authority inbox-context-selection", wrap_command(Commands::Authority::
204
131
  register "select", wrap_command(Commands::Select)
205
132
  register "fork-run", wrap_command(Commands::ForkRun)
206
133
  register "fork-session", wrap_command(Commands::ForkSession)
207
- register "attempt start", wrap_command(Commands::Attempt::Start)
208
- register "attempt status", wrap_command(Commands::Attempt::Status)
209
- register "attempt evidence", wrap_command(Commands::Attempt::Evidence)
210
- register "attempt finish", wrap_command(Commands::Attempt::Finish)
211
- register "attempt reconcile", wrap_command(Commands::Attempt::Reconcile)
212
- register "resume", wrap_command(Commands::Resume)
213
- register "inbox-bind", wrap_command(Commands::InboxBind)
214
- register "submit-candidate", wrap_command(Commands::SubmitCandidate)
215
- register "submit-result", wrap_command(Commands::SubmitResult)
216
- register "campaign-export-result", wrap_command(Commands::CampaignExportResult)
217
- register "campaign-record-round", wrap_command(Commands::CampaignRecordRound)
218
134
 
219
135
  # Register version command
220
136
  version_cmd = Ace::Support::Cli::VersionCommand.build(
@@ -50,94 +50,22 @@ module Ace
50
50
  class InvalidState < Error; end
51
51
  end
52
52
 
53
- # Attempt/evidence-related errors (exit code 5)
54
- module AttemptErrors
55
- class InvalidTransition < Error
56
- def initialize(message = "Illegal attempt state transition")
57
- super(message, exit_code: 5)
58
- end
59
- end
60
-
61
- class InvalidScope < Error
62
- def initialize(message = "Invalid attempt scope")
63
- super(message, exit_code: 5)
64
- end
65
- end
66
-
67
- # Duplicate start with a conflicting binding for an owned subtree
53
+ # Local prune/start exclusion errors (exit code 5).
54
+ module LifecycleErrors
55
+ # The identity was pruned or its exclusion artifacts are unsafe, so a
56
+ # writer must not be started against it.
68
57
  class Conflict < Error
69
- def initialize(message = "Conflicting active attempt for scope")
70
- super(message, exit_code: 5)
71
- end
72
- end
73
-
74
- # An exact authorization reference is not currently valid for a new
75
- # effect: consumed by another live request, expired, or out of scope.
76
- class AuthorizationConflict < Conflict; end
77
-
78
- class NotFound < Error
79
- def initialize(message = "Attempt not found")
80
- super(message, exit_code: 5)
81
- end
82
- end
83
-
84
- # Untrusted or unknown execution identity; authority fails closed
85
- class UnauthorizedIdentity < Error
86
- def initialize(message = "Unknown or unauthorized execution identity")
87
- super(message, exit_code: 5)
88
- end
89
- end
90
-
91
- # Receipt failed verification (binding, head, digest, artifacts, review)
92
- class ReceiptRejected < Error
93
- def initialize(message = "Receipt rejected")
94
- super(message, exit_code: 5)
95
- end
96
- end
97
-
98
- # Byte framing failed before any business receipt could be admitted.
99
- class MalformedTransfer < ReceiptRejected; end
100
-
101
- # Recovery settled a prior effect, but did not perform this request.
102
- class CurrentEffectRequired < ReceiptRejected
103
- def initialize(operation:, recovered_operation:)
104
- super("Recovered #{recovered_operation}; requested #{operation} still needs execution")
105
- end
106
- end
107
-
108
- # Attempt state forbids the requested effect (terminal, uncertain, blocked)
109
- class InvalidState < Error
110
- def initialize(message = "Attempt state forbids the requested operation")
58
+ def initialize(message = "Conflicting lifecycle identity")
111
59
  super(message, exit_code: 5)
112
60
  end
113
61
  end
114
62
 
115
- # Evidence storage is missing or unwritable; external effects are blocked
116
- class EvidenceUnavailable < Error
117
- def initialize(message = "Evidence storage unavailable")
63
+ # Maintenance exclusion is busy or its admission deadline expired.
64
+ class MaintenanceBusy < Error
65
+ def initialize(message = "Maintenance exclusion is busy")
118
66
  super(message, exit_code: 5)
119
67
  end
120
68
  end
121
-
122
- # Complete maintenance exclusions are busy or their admission deadline expired.
123
- class MaintenanceBusy < EvidenceUnavailable
124
- end
125
-
126
- # One canonical inventory row cannot fit the fixed protocol frame.
127
- class BoundedResultUnavailable < EvidenceUnavailable
128
- end
129
-
130
- # Exhaustively authenticated service inventory remains unsettled.
131
- class ServiceSettlementPending < EvidenceUnavailable
132
- end
133
-
134
- # Exhaustively authenticated current Inbox claims remain queued.
135
- class InboxSettlementPending < EvidenceUnavailable
136
- end
137
-
138
- # Positively admitted original Inbox work remains pending, not corrupt.
139
- class InboxContextPending < EvidenceUnavailable
140
- end
141
69
  end
142
70
  end
143
71
  end
@@ -20,7 +20,7 @@ module Ace
20
20
  # but tests would need to be updated to provide all required fields.
21
21
  class Assignment
22
22
  attr_reader :id, :name, :description, :created_at, :updated_at, :source_config, :cache_dir, :parent,
23
- :task_id, :project_id, :campaign_execution, :review_campaign
23
+ :task_id, :project_id
24
24
 
25
25
  # @param id [String] Unique assignment ID (6-char compact timestamp)
26
26
  # @param name [String] Human-readable assignment name
@@ -33,7 +33,7 @@ module Ace
33
33
  # @param task_id [String, nil] Source task ID attached to this assignment (nil = taskless)
34
34
  # @param project_id [String, nil] Project ID this assignment executes in
35
35
  def initialize(id:, name:, created_at:, source_config:, description: nil, updated_at: nil, cache_dir: nil,
36
- parent: nil, task_id: nil, project_id: nil, campaign_execution: nil, review_campaign: nil)
36
+ parent: nil, task_id: nil, project_id: nil)
37
37
  @id = id.freeze
38
38
  @name = name.freeze
39
39
  @description = description&.freeze
@@ -44,29 +44,10 @@ module Ace
44
44
  @parent = parent&.freeze
45
45
  @task_id = task_id&.freeze
46
46
  @project_id = project_id&.freeze
47
- if !campaign_execution.nil? && !review_campaign.nil?
48
- raise ArgumentError, "assignment cannot own both parent campaign and child execution"
49
- end
50
- @campaign_execution = immutable_campaign_execution(campaign_execution) unless campaign_execution.nil?
51
- @review_campaign = immutable_campaign_execution(review_campaign) unless review_campaign.nil?
52
- end
53
-
54
- # Keep registered definition bytes stable without retaining caller-owned
55
- # mutable objects. Authority validates the closed linkage and provenance.
56
- private def immutable_campaign_execution(value)
57
- case value
58
- when Hash
59
- value.to_h { |key, item| [immutable_campaign_execution(key), immutable_campaign_execution(item)] }.freeze
60
- when Array then value.map { |item| immutable_campaign_execution(item) }.freeze
61
- when String then value.dup.freeze
62
- when Integer, NilClass, TrueClass, FalseClass then value
63
- else raise ArgumentError, "invalid campaign execution value"
64
- end
65
47
  end
66
48
 
67
49
  # @return [Boolean] True when a source task is attached; taskless
68
- # assignments persist attempts locally only and never claim
69
- # Git-backed recovery
50
+ # assignments keep their plan state locally only.
70
51
  def managed?
71
52
  !task_id.nil? && !task_id.to_s.strip.empty?
72
53
  end
@@ -83,9 +64,7 @@ module Ace
83
64
  "source_config" => source_config,
84
65
  "parent" => parent,
85
66
  "task_id" => task_id,
86
- "project_id" => project_id,
87
- "campaign_execution" => campaign_execution,
88
- "review_campaign" => review_campaign
67
+ "project_id" => project_id
89
68
  }.compact
90
69
  end
91
70
 
@@ -104,9 +83,7 @@ module Ace
104
83
  cache_dir: cache_dir,
105
84
  parent: data["parent"],
106
85
  task_id: data["task_id"],
107
- project_id: data["project_id"],
108
- campaign_execution: data["campaign_execution"],
109
- review_campaign: data["review_campaign"]
86
+ project_id: data["project_id"]
110
87
  )
111
88
  end
112
89
 
@@ -195,32 +195,6 @@ module Ace
195
195
  updated
196
196
  end
197
197
 
198
- # The attempt store sharing this manager's cache base. The store is
199
- # the single authority for attempt records and subtree ownership;
200
- # assignment metadata never carries attempt history.
201
- #
202
- # @return [Molecules::AttemptStore] Attempt store
203
- def attempt_store
204
- @attempt_store ||= Molecules::AttemptStore.new(cache_base: @cache_base)
205
- end
206
-
207
- # Assignment-scoped lookup of the active attempt for a scope.
208
- #
209
- # @param assignment_id [String] Assignment ID
210
- # @param scope [String] Step/subtree scope
211
- # @return [Models::Attempt, nil] Active attempt or nil
212
- def active_attempt(assignment_id, scope)
213
- attempt_store.active(assignment_id, scope)
214
- end
215
-
216
- # All attempts recorded for an assignment.
217
- #
218
- # @param assignment_id [String] Assignment ID
219
- # @return [Array<Models::Attempt>] Persisted attempts
220
- def attempts(assignment_id)
221
- attempt_store.list(assignment_id)
222
- end
223
-
224
198
  # List all assignments
225
199
  #
226
200
  # @return [Array<Models::Assignment>] All assignments
@@ -85,22 +85,14 @@ module Ace
85
85
  end
86
86
 
87
87
  def launch_provider_session(assignment_id:, fork_root:, provider:, cli_args: nil, timeout: nil, cache_dir: nil,
88
- last_message_file: nil, session_meta_file: nil, prepared_input: nil)
88
+ last_message_file: nil, session_meta_file: nil)
89
89
  ensure_not_same_scoped_refork!(assignment_id: assignment_id, fork_root: fork_root)
90
90
  resolved_provider = provider || config.dig("execution", "provider") || DEFAULT_PROVIDER
91
91
  resolved_timeout = timeout || config.dig("execution", "timeout") || DEFAULT_TIMEOUT
92
92
  scoped_assignment = "#{assignment_id}@#{fork_root}"
93
- if prepared_input && prepared_input.descriptor.values_at("assignment_id", "scope") != [assignment_id, fork_root]
94
- raise Error, "Prepared provider scope differs"
95
- end
96
- prompt = prepared_input ? prepared_input.drive_prompt : "/as-assign-drive #{scoped_assignment}"
93
+ prompt = "/as-assign-drive #{scoped_assignment}"
97
94
  last_msg_file = last_message_file || build_last_message_file(cache_dir, fork_root)
98
95
  scope_env = self.class.fork_scope_env(assignment_id: assignment_id, fork_root: fork_root)
99
- if prepared_input
100
- scope_env = scope_env.merge("ACE_ASSIGN_LAUNCH_MAPPING" => prepared_input.descriptor.fetch("mapping_id"),
101
- "ACE_ASSIGN_ASSIGNMENT_ID" => assignment_id, "ACE_ASSIGN_ATTEMPT_ID" => prepared_input.descriptor.fetch("attempt_id"),
102
- "ACE_ASSIGN_TASK_CONTEXT_ENTRY" => JSON.generate(prepared_input.descriptor.fetch("task_context_entry").fetch("manifest")))
103
- end
104
96
 
105
97
  result = query_interface.query(
106
98
  resolved_provider,
@@ -111,7 +103,7 @@ module Ace
111
103
  fallback: false,
112
104
  last_message_file: last_msg_file,
113
105
  subprocess_env: scope_env,
114
- working_dir: prepared_input&.working_directory
106
+ working_dir: nil
115
107
  )
116
108
 
117
109
  if last_msg_file && result[:text] && !result[:text].strip.empty?
@@ -120,7 +112,7 @@ module Ace
120
112
  end
121
113
 
122
114
  write_session_metadata(last_msg_file, result, prompt: prompt, session_meta_file: session_meta_file,
123
- discover_session: prepared_input.nil?)
115
+ discover_session: true)
124
116
 
125
117
  result
126
118
  rescue Ace::LLM::Error => e
@@ -6,7 +6,6 @@ require "json"
6
6
  require "open3"
7
7
  require "time"
8
8
  require "securerandom"
9
- require_relative "../atoms/evidence_digest"
10
9
 
11
10
  module Ace
12
11
  module Assign
@@ -17,108 +16,15 @@ module Ace
17
16
  # common dir — so they survive removal of the assignment cache, the
18
17
  # worktree, or a recreated lock pathname. Prune holds the exclusive
19
18
  # side from its final evidence reads through completion of removal;
20
- # every supported start path (attempt registration, fork/driver
21
- # session launch, worktree provisioning) holds the shared side while
22
- # registering a writer.
19
+ # every supported start path (fork/driver session launch, worktree
20
+ # provisioning) holds the shared side while registering a writer.
23
21
  #
24
22
  # A `removed` marker recorded by prune makes post-deletion starts fail
25
23
  # closed instead of recreating the deleted identity: acquiring the
26
- # shared side raises {AttemptErrors::Conflict} when the marker is
24
+ # shared side raises {LifecycleErrors::Conflict} when the marker is
27
25
  # present. Legitimate fresh provisioning (a new worktree for a task)
28
26
  # clears the marker explicitly via `reset_removed`.
29
27
  class LifecycleExclusion
30
- autoload :ControlExclusion, File.expand_path("protected_control_exclusion", __dir__)
31
-
32
- def self.control_exclusion(authority:, project_id:, descriptor_sha256:, root_identity: nil, **boundaries)
33
- ControlExclusion.new(authority: authority, project_id: project_id,
34
- descriptor_sha256: descriptor_sha256, root_identity: root_identity, **boundaries)
35
- end
36
-
37
- autoload :WorkspaceNativeReader, File.expand_path("protected_workspace_exclusion", __dir__)
38
- autoload :WorkspaceReader, File.expand_path("protected_workspace_exclusion", __dir__)
39
-
40
- autoload :WorkspaceWriter, File.expand_path("protected_workspace_exclusion", __dir__)
41
-
42
- autoload :WorkspaceFenceReader, File.expand_path("protected_workspace_exclusion", __dir__)
43
-
44
- def self.workspace_fence_reader(projection:, protection: nil, files: File)
45
- WorkspaceFenceReader.new(projection: projection, protection: protection, files: files)
46
- end
47
-
48
- def self.workspace_writer(projection:, protection: nil, files: File)
49
- WorkspaceWriter.new(projection: projection, protection: protection, files: files)
50
- end
51
-
52
- autoload :WorkspaceProvisioner, File.expand_path("protected_workspace_provisioner", __dir__)
53
-
54
- def self.provision_workspace!(mapping_id:, project_id:, authority:, cwd_resource:, **boundaries)
55
- WorkspaceProvisioner.new(mapping_id: mapping_id, project_id: project_id,
56
- authority: authority, cwd_resource: cwd_resource, **boundaries).provision!
57
- end
58
-
59
- def self.workspace_reader(projection:, protection: nil, files: File)
60
- WorkspaceReader.new(projection: projection, protection: protection, files: files)
61
- end
62
-
63
- def self.workspace_selection(mapping_id:, project_id:, authority:, cwd_resource:)
64
- fields = %w[device filesystem_type gid host_path inode mount_id uid view_path]
65
- unless authority.is_a?(Hash) && cwd_resource.is_a?(Hash) && cwd_resource.keys.sort == fields &&
66
- %w[device gid inode uid].all? { |field| cwd_resource[field].is_a?(Integer) && cwd_resource[field] >= 0 } &&
67
- cwd_resource["mount_id"].is_a?(Integer) && cwd_resource["mount_id"].positive? &&
68
- %w[host_path view_path].all? { |field| cwd_resource[field].is_a?(String) &&
69
- cwd_resource[field].valid_encoding? && cwd_resource[field].bytesize.between?(1, 4096) &&
70
- !cwd_resource[field].include?("\0") && cwd_resource[field].start_with?("/") &&
71
- File.expand_path(cwd_resource[field]) == cwd_resource[field] } &&
72
- %w[ext4 xfs btrfs tmpfs].include?(cwd_resource["filesystem_type"]) &&
73
- [mapping_id, project_id].all? { |value| value.is_a?(String) && value.match?(/\A[A-Za-z0-9][A-Za-z0-9._-]{0,127}\z/) } &&
74
- %w[uid gid].all? { |field| authority[field].is_a?(Integer) && authority[field].positive? } &&
75
- authority["state_root"].is_a?(String) && authority["state_root"].valid_encoding? &&
76
- authority["state_root"].bytesize.between?(1, 4096) && !authority["state_root"].include?("\0") &&
77
- authority["state_root"].start_with?("/") &&
78
- File.expand_path(authority["state_root"]) == authority["state_root"]
79
- raise AttemptErrors::EvidenceUnavailable, "Original lifecycle workspace selection is malformed"
80
- end
81
- digest = Atoms::EvidenceDigest.digest(cwd_resource)
82
- selection = {"key" => "workspace:#{mapping_id}:#{digest}",
83
- "host_path" => File.join(authority.fetch("state_root"), "lifecycle-exclusion", project_id,
84
- "workspaces", mapping_id, digest), "view_path" => "/run/ace/lifecycle-exclusion/#{mapping_id}"}
85
- unless selection.fetch("host_path").bytesize <= 4096
86
- raise AttemptErrors::EvidenceUnavailable, "Original lifecycle workspace path is oversized"
87
- end
88
- selection.each_value(&:freeze)
89
- selection.freeze
90
- end
91
-
92
- def self.workspace_initial_marker(key:)
93
- unless key.is_a?(String) && key.match?(/\Aworkspace:[A-Za-z0-9][A-Za-z0-9._-]{0,127}:[0-9a-f]{64}\z/)
94
- raise AttemptErrors::EvidenceUnavailable, "Original lifecycle workspace key is malformed"
95
- end
96
- Atoms::EvidenceDigest.canonical_json({"key" => key, "removed" => false, "removed_at" => nil}).freeze
97
- end
98
-
99
- def self.workspace_marker!(bytes:, key:)
100
- unless bytes.is_a?(String) && bytes.bytesize.between?(1, 8192)
101
- raise AttemptErrors::EvidenceUnavailable, "Lifecycle marker bytes differ"
102
- end
103
- bytes = bytes.dup.force_encoding(Encoding::UTF_8)
104
- unless bytes.valid_encoding?
105
- raise AttemptErrors::EvidenceUnavailable, "Lifecycle marker is not bounded UTF8"
106
- end
107
- state = JSON.parse(bytes, create_additions: false, max_nesting: 4, allow_duplicate_key: false)
108
- unless state.is_a?(Hash) && state.keys.sort == %w[key removed removed_at] && state.fetch("key") == key &&
109
- (state.values_at("removed", "removed_at") == [false, nil] || state["removed"] == true &&
110
- state["removed_at"].is_a?(String) && Time.iso8601(state["removed_at"]).utc.iso8601 == state["removed_at"])
111
- raise AttemptErrors::EvidenceUnavailable, "Lifecycle marker schema differs"
112
- end
113
- state.each_value { |value| value.freeze }
114
- state.freeze
115
- rescue JSON::ParserError, ArgumentError, KeyError
116
- raise AttemptErrors::EvidenceUnavailable, "Lifecycle marker schema differs"
117
- end
118
-
119
- # @param repo_root [String, nil] Repository used to resolve the
120
- # shared Git common dir (default: project root)
121
- # @param root [String, nil] Explicit exclusion root (tests)
122
28
  def initialize(repo_root: nil, root: nil)
123
29
  @root = root || self.class.default_root(repo_root)
124
30
  end
@@ -132,7 +38,7 @@ module Ace
132
38
  "git", "-C", repo_root, "rev-parse", "--path-format=absolute", "--git-common-dir"
133
39
  )
134
40
  unless status.success? && !common_dir.to_s.strip.empty? && File.absolute_path(common_dir.strip) == common_dir.strip
135
- raise AttemptErrors::Conflict, "Repository lifecycle root is unavailable"
41
+ raise LifecycleErrors::Conflict, "Repository lifecycle root is unavailable"
136
42
  end
137
43
  File.join(common_dir.strip, "ace", "lifecycle-exclusion")
138
44
  end
@@ -141,9 +47,6 @@ module Ace
141
47
  "assignment:#{assignment_id}"
142
48
  end
143
49
 
144
- def slot_key(slot_id)
145
- "execution-slot:#{slot_id}"
146
- end
147
50
 
148
51
  # Task identity is the canonical worktree identity: work-on derives
149
52
  # the worktree path from the task ref, and prune candidates carry
@@ -174,7 +77,7 @@ module Ace
174
77
  begin
175
78
  mode = File::LOCK_EX | (deadline ? File::LOCK_NB : 0)
176
79
  unless lock.flock(mode)
177
- raise AttemptErrors::MaintenanceBusy, "maintenance exclusion is busy"
80
+ raise LifecycleErrors::MaintenanceBusy, "maintenance exclusion is busy"
178
81
  end
179
82
  maintenance_deadline!(deadline) unless deadline.nil?
180
83
  yield
@@ -198,7 +101,7 @@ module Ace
198
101
  begin
199
102
  if removed?(key)
200
103
  unless reset_removed
201
- raise AttemptErrors::Conflict, removed_message(key)
104
+ raise LifecycleErrors::Conflict, removed_message(key)
202
105
  end
203
106
 
204
107
  clear_removed!(key)
@@ -236,7 +139,7 @@ module Ace
236
139
  ordered.each do |key|
237
140
  if removed?(key)
238
141
  unless reset_removed
239
- raise AttemptErrors::Conflict, removed_message(key)
142
+ raise LifecycleErrors::Conflict, removed_message(key)
240
143
  end
241
144
 
242
145
  clear_removed!(key)
@@ -267,25 +170,25 @@ module Ace
267
170
  opened = true
268
171
  before = file.stat
269
172
  unless before.file? && before.nlink == 1 && before.size.between?(1, 8192) && (before.mode & 0022).zero?
270
- raise AttemptErrors::Conflict, "Lifecycle marker is unsafe"
173
+ raise LifecycleErrors::Conflict, "Lifecycle marker is unsafe"
271
174
  end
272
175
  content = file.read(8193).force_encoding(Encoding::UTF_8)
273
176
  unless content.valid_encoding? && content.bytesize == before.size && same_file?(before, file.stat) && same_file?(before, File.lstat(path))
274
- raise AttemptErrors::Conflict, "Lifecycle marker changed"
177
+ raise LifecycleErrors::Conflict, "Lifecycle marker changed"
275
178
  end
276
179
  state = JSON.parse(content, create_additions: false, max_nesting: 4, allow_duplicate_key: false)
277
180
  unless state.is_a?(Hash) && state.keys.sort == %w[key removed removed_at] &&
278
181
  state["key"] == key && state["removed"] == true && state["removed_at"].is_a?(String)
279
- raise AttemptErrors::Conflict, "Lifecycle marker is malformed"
182
+ raise LifecycleErrors::Conflict, "Lifecycle marker is malformed"
280
183
  end
281
184
  Time.iso8601(state.fetch("removed_at"))
282
185
  true
283
186
  end
284
187
  rescue Errno::ENOENT
285
- raise AttemptErrors::Conflict, "Lifecycle marker disappeared during read" if opened
188
+ raise LifecycleErrors::Conflict, "Lifecycle marker disappeared during read" if opened
286
189
  false
287
190
  rescue JSON::ParserError, ArgumentError, TypeError, SystemCallError, IOError
288
- raise AttemptErrors::Conflict, "Lifecycle marker is unavailable or malformed"
191
+ raise LifecycleErrors::Conflict, "Lifecycle marker is unavailable or malformed"
289
192
  end
290
193
 
291
194
  def clear_removed!(key)
@@ -305,12 +208,12 @@ module Ace
305
208
  file = File.open(lock_path(key), flags, 0600)
306
209
  unless file.stat.file? && file.stat.nlink == 1 && (file.stat.mode & 0022).zero? &&
307
210
  same_file?(file.stat, File.lstat(lock_path(key)))
308
- raise AttemptErrors::MaintenanceBusy, "maintenance exclusion is not a regular file"
211
+ raise LifecycleErrors::MaintenanceBusy, "maintenance exclusion is not a regular file"
309
212
  end
310
213
  retained = true
311
214
  file
312
215
  rescue SystemCallError
313
- raise AttemptErrors::Conflict, "Lifecycle lock is unavailable"
216
+ raise LifecycleErrors::Conflict, "Lifecycle lock is unavailable"
314
217
  ensure
315
218
  file&.close unless retained
316
219
  end
@@ -320,7 +223,7 @@ module Ace
320
223
  raise ArgumentError, "maintenance deadline must be finite"
321
224
  end
322
225
  if Process.clock_gettime(Process::CLOCK_MONOTONIC) >= deadline
323
- raise AttemptErrors::MaintenanceBusy, "maintenance admission deadline expired"
226
+ raise LifecycleErrors::MaintenanceBusy, "maintenance admission deadline expired"
324
227
  end
325
228
  end
326
229
 
@@ -12,9 +12,10 @@ module Ace
12
12
  # operation delegates to the resolved Ace::Runtime adapter; assign
13
13
  # never calls a runtime-native API directly (k86.3 interface rule).
14
14
  class RuntimeControlSurfaceRunner
15
- def initialize(runtime: nil, env: ENV)
15
+ def initialize(runtime: nil, env: ENV, adapter: nil)
16
16
  @runtime_name = runtime
17
17
  @env = env
18
+ @runtime = adapter
18
19
  end
19
20
 
20
21
  attr_reader :runtime_name, :env
@@ -68,12 +68,6 @@ module Ace
68
68
 
69
69
  assignment_config = config["assignment"] || {}
70
70
  steps_config = config["steps"] || []
71
- if config.key?("delivery")
72
- Atoms::DeliveryParameters.validate(config["delivery"])
73
- unless Array(steps_config).any? { |step| %w[create-pr update-pr-desc mark-pr-ready].include?(step["name"]) }
74
- raise ArgumentError, "Explicit delivery inputs require remote steps"
75
- end
76
- end
77
71
 
78
72
  raise Error, "No steps defined in config" if steps_config.empty?
79
73