ace-assign 0.71.0 → 0.73.1

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 (197) 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 +5 -2116
  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 -4
  16. data/handbook/workflow-instructions/assign/drive.wf.md +47 -195
  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 +6 -2
  35. data/lib/ace/assign/molecules/skill_assign_source_resolver.rb +9 -0
  36. data/lib/ace/assign/organisms/assignment_executor.rb +0 -6
  37. data/lib/ace/assign/organisms/task_assignment_creator.rb +3 -8
  38. data/lib/ace/assign/version.rb +1 -1
  39. data/lib/ace/assign.rb +0 -6
  40. metadata +22 -176
  41. data/.ace-defaults/assign/presets/close-delivery.yml +0 -57
  42. data/.ace-defaults/assign/presets/deliver-release.yml +0 -60
  43. data/.ace-defaults/assign/presets/integrate-batch.yml +0 -72
  44. data/.ace-defaults/assign/presets/supervise-delivery.yml +0 -69
  45. data/docs/protected-authority.md +0 -282
  46. data/exe/ace-scope-ready +0 -55
  47. data/lib/ace/assign/atoms/assignment_scope.rb +0 -58
  48. data/lib/ace/assign/atoms/attempt_state_machine.rb +0 -84
  49. data/lib/ace/assign/atoms/candidate_limits.rb +0 -20
  50. data/lib/ace/assign/atoms/delivery_parameters.rb +0 -19
  51. data/lib/ace/assign/atoms/evidence_digest.rb +0 -78
  52. data/lib/ace/assign/atoms/fixed_merge_schemas.rb +0 -398
  53. data/lib/ace/assign/atoms/git_blob_batch.rb +0 -59
  54. data/lib/ace/assign/authority/assignment_definition.rb +0 -35
  55. data/lib/ace/assign/authority/assignment_inventory.rb +0 -290
  56. data/lib/ace/assign/authority/campaign_consumer_policy.rb +0 -100
  57. data/lib/ace/assign/authority/campaign_execution.rb +0 -119
  58. data/lib/ace/assign/authority/campaign_round_transfer.rb +0 -82
  59. data/lib/ace/assign/authority/candidate_blob_batch.rb +0 -55
  60. data/lib/ace/assign/authority/candidate_head_comparison.rb +0 -139
  61. data/lib/ace/assign/authority/candidate_transfer.rb +0 -357
  62. data/lib/ace/assign/authority/cleanup_result_protection.rb +0 -53
  63. data/lib/ace/assign/authority/client.rb +0 -257
  64. data/lib/ace/assign/authority/command_execution.rb +0 -180
  65. data/lib/ace/assign/authority/deployment.rb +0 -627
  66. data/lib/ace/assign/authority/deployment_history.rb +0 -146
  67. data/lib/ace/assign/authority/endcap.rb +0 -457
  68. data/lib/ace/assign/authority/endcap_attempts.rb +0 -274
  69. data/lib/ace/assign/authority/endcap_campaign_results.rb +0 -232
  70. data/lib/ace/assign/authority/endcap_campaign_rounds.rb +0 -266
  71. data/lib/ace/assign/authority/endcap_contexts.rb +0 -23
  72. data/lib/ace/assign/authority/endcap_inboxes.rb +0 -37
  73. data/lib/ace/assign/authority/endcap_prepared_work.rb +0 -80
  74. data/lib/ace/assign/authority/endcap_publication.rb +0 -41
  75. data/lib/ace/assign/authority/endcap_results.rb +0 -398
  76. data/lib/ace/assign/authority/endcap_review_requests.rb +0 -183
  77. data/lib/ace/assign/authority/endcap_reviews.rb +0 -130
  78. data/lib/ace/assign/authority/endcap_service_context.rb +0 -38
  79. data/lib/ace/assign/authority/endcap_service_settlement.rb +0 -152
  80. data/lib/ace/assign/authority/evidence_transfer.rb +0 -67
  81. data/lib/ace/assign/authority/execution_scope_observation.rb +0 -903
  82. data/lib/ace/assign/authority/fixed_publication_lifecycle.rb +0 -176
  83. data/lib/ace/assign/authority/fixed_service_lifecycle.rb +0 -594
  84. data/lib/ace/assign/authority/inbox_context_original.rb +0 -113
  85. data/lib/ace/assign/authority/launch_attempt_consumers.rb +0 -51
  86. data/lib/ace/assign/authority/launch_campaign_registration.rb +0 -214
  87. data/lib/ace/assign/authority/launch_control_channel.rb +0 -313
  88. data/lib/ace/assign/authority/launch_control_exclusions.rb +0 -127
  89. data/lib/ace/assign/authority/launch_driver.rb +0 -393
  90. data/lib/ace/assign/authority/launch_input_inhibition.rb +0 -132
  91. data/lib/ace/assign/authority/launch_lifecycle.rb +0 -997
  92. data/lib/ace/assign/authority/launch_prepared_work.rb +0 -122
  93. data/lib/ace/assign/authority/launch_review.rb +0 -91
  94. data/lib/ace/assign/authority/launch_scope_abort.rb +0 -81
  95. data/lib/ace/assign/authority/launch_scope_admission.rb +0 -215
  96. data/lib/ace/assign/authority/launch_scope_close.rb +0 -146
  97. data/lib/ace/assign/authority/launch_scope_parent.rb +0 -44
  98. data/lib/ace/assign/authority/launch_scope_release.rb +0 -859
  99. data/lib/ace/assign/authority/launch_steering.rb +0 -353
  100. data/lib/ace/assign/authority/launch_stop.rb +0 -254
  101. data/lib/ace/assign/authority/maintenance_workspace_retirement.rb +0 -229
  102. data/lib/ace/assign/authority/ordinary_attempt_start.rb +0 -137
  103. data/lib/ace/assign/authority/ordinary_client.rb +0 -70
  104. data/lib/ace/assign/authority/ordinary_completion.rb +0 -104
  105. data/lib/ace/assign/authority/ordinary_effect_settlement.rb +0 -118
  106. data/lib/ace/assign/authority/ordinary_lifecycle.rb +0 -227
  107. data/lib/ace/assign/authority/ordinary_merge_evidence.rb +0 -81
  108. data/lib/ace/assign/authority/ordinary_peer.rb +0 -54
  109. data/lib/ace/assign/authority/ordinary_progress.rb +0 -162
  110. data/lib/ace/assign/authority/ordinary_queue.rb +0 -115
  111. data/lib/ace/assign/authority/ordinary_release_artifacts.rb +0 -143
  112. data/lib/ace/assign/authority/ordinary_results.rb +0 -206
  113. data/lib/ace/assign/authority/ordinary_review_evidence.rb +0 -180
  114. data/lib/ace/assign/authority/ordinary_reviews.rb +0 -214
  115. data/lib/ace/assign/authority/ordinary_server.rb +0 -75
  116. data/lib/ace/assign/authority/ordinary_supervisor.rb +0 -99
  117. data/lib/ace/assign/authority/original_inbox_selection.rb +0 -41
  118. data/lib/ace/assign/authority/posix_acl.rb +0 -59
  119. data/lib/ace/assign/authority/prepared_input.rb +0 -130
  120. data/lib/ace/assign/authority/prepared_queue.rb +0 -185
  121. data/lib/ace/assign/authority/prepared_task_context.rb +0 -116
  122. data/lib/ace/assign/authority/prepared_work.rb +0 -309
  123. data/lib/ace/assign/authority/prepared_worker.rb +0 -69
  124. data/lib/ace/assign/authority/private_directory.rb +0 -33
  125. data/lib/ace/assign/authority/protected_assignment_context.rb +0 -226
  126. data/lib/ace/assign/authority/readiness_hook.rb +0 -120
  127. data/lib/ace/assign/authority/receipt_transfer.rb +0 -48
  128. data/lib/ace/assign/authority/release_artifact_manifest.rb +0 -91
  129. data/lib/ace/assign/authority/retained_input.rb +0 -53
  130. data/lib/ace/assign/authority/router.rb +0 -81
  131. data/lib/ace/assign/authority/server.rb +0 -131
  132. data/lib/ace/assign/authority/service_cleanup_dispatch.rb +0 -88
  133. data/lib/ace/assign/authority/service_cleanup_evidence.rb +0 -180
  134. data/lib/ace/assign/authority/service_delivery_evidence.rb +0 -101
  135. data/lib/ace/assign/authority/service_evidence.rb +0 -286
  136. data/lib/ace/assign/authority/service_publication_evidence.rb +0 -110
  137. data/lib/ace/assign/authority/socket_server.rb +0 -255
  138. data/lib/ace/assign/authority/task_context_entry.rb +0 -32
  139. data/lib/ace/assign/authority/transfer_codec.rb +0 -189
  140. data/lib/ace/assign/cli/commands/attempt/base.rb +0 -84
  141. data/lib/ace/assign/cli/commands/attempt/evidence.rb +0 -28
  142. data/lib/ace/assign/cli/commands/attempt/finish.rb +0 -51
  143. data/lib/ace/assign/cli/commands/attempt/reconcile.rb +0 -49
  144. data/lib/ace/assign/cli/commands/attempt/start.rb +0 -45
  145. data/lib/ace/assign/cli/commands/attempt/status.rb +0 -54
  146. data/lib/ace/assign/cli/commands/authority/inbox_context_principal.rb +0 -25
  147. data/lib/ace/assign/cli/commands/authority/inbox_context_selection.rb +0 -28
  148. data/lib/ace/assign/cli/commands/authority/launch.rb +0 -97
  149. data/lib/ace/assign/cli/commands/authority/serve.rb +0 -31
  150. data/lib/ace/assign/cli/commands/authority/status.rb +0 -26
  151. data/lib/ace/assign/cli/commands/authority/task_context.rb +0 -31
  152. data/lib/ace/assign/cli/commands/authority/task_context_principal.rb +0 -25
  153. data/lib/ace/assign/cli/commands/authority/task_context_selection.rb +0 -30
  154. data/lib/ace/assign/cli/commands/authority/terminate.rb +0 -29
  155. data/lib/ace/assign/cli/commands/authority/worker.rb +0 -23
  156. data/lib/ace/assign/cli/commands/campaign_export_result.rb +0 -55
  157. data/lib/ace/assign/cli/commands/campaign_record_round.rb +0 -57
  158. data/lib/ace/assign/cli/commands/delivery.rb +0 -107
  159. data/lib/ace/assign/cli/commands/inbox_bind.rb +0 -34
  160. data/lib/ace/assign/cli/commands/protected_submission.rb +0 -61
  161. data/lib/ace/assign/cli/commands/resume.rb +0 -38
  162. data/lib/ace/assign/cli/commands/submit_candidate.rb +0 -34
  163. data/lib/ace/assign/cli/commands/submit_result.rb +0 -61
  164. data/lib/ace/assign/models/attempt.rb +0 -178
  165. data/lib/ace/assign/models/attempt_binding.rb +0 -116
  166. data/lib/ace/assign/models/evidence_event.rb +0 -86
  167. data/lib/ace/assign/models/execution_receipt.rb +0 -139
  168. data/lib/ace/assign/molecules/attempt_reconciler.rb +0 -127
  169. data/lib/ace/assign/molecules/attempt_store.rb +0 -201
  170. data/lib/ace/assign/molecules/canonical_attempt_state.rb +0 -151
  171. data/lib/ace/assign/molecules/canonical_evidence.rb +0 -170
  172. data/lib/ace/assign/molecules/canonical_read_commands.rb +0 -84
  173. data/lib/ace/assign/molecules/canonical_read_snapshot.rb +0 -313
  174. data/lib/ace/assign/molecules/evidence_calculator.rb +0 -237
  175. data/lib/ace/assign/molecules/evidence_journal.rb +0 -1899
  176. data/lib/ace/assign/molecules/execution_identity_resolver.rb +0 -137
  177. data/lib/ace/assign/molecules/execution_scope_lineage.rb +0 -345
  178. data/lib/ace/assign/molecules/fixed_effect_reference.rb +0 -31
  179. data/lib/ace/assign/molecules/installed_journal_read.rb +0 -143
  180. data/lib/ace/assign/molecules/journal_input_inhibition.rb +0 -78
  181. data/lib/ace/assign/molecules/journal_mutation.rb +0 -274
  182. data/lib/ace/assign/molecules/journal_prompt_mutation.rb +0 -241
  183. data/lib/ace/assign/molecules/ordinary_merge_cli.rb +0 -68
  184. data/lib/ace/assign/molecules/ordinary_merge_contract.rb +0 -410
  185. data/lib/ace/assign/molecules/original_launch_binding.rb +0 -37
  186. data/lib/ace/assign/molecules/proposal_journal.rb +0 -179
  187. data/lib/ace/assign/molecules/protected_control_exclusion.rb +0 -303
  188. data/lib/ace/assign/molecules/protected_workspace_exclusion.rb +0 -330
  189. data/lib/ace/assign/molecules/protected_workspace_provisioner.rb +0 -164
  190. data/lib/ace/assign/molecules/receipt_verifier.rb +0 -320
  191. data/lib/ace/assign/molecules/terminal_scope_receipt.rb +0 -88
  192. data/lib/ace/assign/organisms/attempt_coordinator.rb +0 -1374
  193. data/lib/ace/assign/organisms/delivery_coordinator.rb +0 -342
  194. data/lib/ace/assign/organisms/ordinary_driver.rb +0 -310
  195. data/lib/ace/assign/organisms/ordinary_merge_consumer.rb +0 -365
  196. data/lib/ace/assign/organisms/prepared_work_builder.rb +0 -194
  197. data/lib/ace/assign/organisms/protected_delivery_coordinator.rb +0 -100
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
- require_relative "base"
3
- module Ace
4
- module Assign
5
- module CLI
6
- module Commands
7
- module Attempt
8
- class Evidence < Ace::Support::Cli::Command
9
- include Attempt::Base
10
- desc "Read coordinator-accepted live execution or historical execution authority"
11
- option :attempt, required: true, desc: "Accepted execution attempt ID"
12
- option :receipt_digest, required: true, desc: "Accepted receipt digest"
13
- option :kind, default: "check", desc: "Evidence purpose: check, review-collection or review-approval"
14
- option :check_name, default: "tests", desc: "Required check name (tests binds operation test)"
15
- option :historical_head, desc: "Exact recorded head for historical authority only (never current-head evidence)"
16
- option :format, default: "json", desc: "JSON evidence projection"
17
-
18
- def call(**options)
19
- raise Ace::Support::Cli::Error, "evidence supports --format json" unless options[:format] == "json"
20
- emit_json(build_coordinator.evidence(attempt_id: options[:attempt], receipt_digest: options[:receipt_digest],
21
- kind: options[:kind], check_name: options[:check_name], historical_head: options[:historical_head]))
22
- end
23
- end
24
- end
25
- end
26
- end
27
- end
28
- end
@@ -1,51 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "json"
4
- require_relative "base"
5
-
6
- module Ace
7
- module Assign
8
- module CLI
9
- module Commands
10
- module Attempt
11
- # Protected completion selects an already submitted canonical result.
12
- # Ordinary local completion accepts its structured receipt file.
13
- class Finish < Ace::Support::Cli::Command
14
- include Ace::Support::Cli::Base
15
- include Attempt::Base
16
-
17
- desc "Finish a protected canonical result or an ordinary local receipt"
18
-
19
- option :attempt, desc: "Attempt ID"
20
- option :mapping, desc: "Exact installed protected mapping ID"
21
- option :assignment, desc: "Exact protected assignment ID"
22
- option :mutation, desc: "Stable original authority mutation ID"
23
- option :expected_generation, desc: "Original authority mutation generation"
24
- option :receipt, desc: "Path to the ordinary local receipt JSON file"
25
- option :result, desc: "Already submitted canonical protected result ID"
26
- option :head, desc: "Exact canonical candidate head"
27
- option :candidate_generation, desc: "Original canonical candidate generation"
28
-
29
- def call(**options)
30
- if (context = protected_context(options))
31
- raise Ace::Support::Cli::Error, "Protected finish forbids --receipt" unless options[:receipt].to_s.empty?
32
- usage = "finish --mapping MAP --assignment ID --attempt ID --result ID --head SHA --candidate-generation N --mutation ID --expected-generation N"
33
- client, params, mutation = protected_attempt_request(context, options, usage)
34
- params.merge!("result_id" => require_option(options, :result, usage), "head" => require_option(options, :head, usage),
35
- "candidate_generation" => integer_option(options, :candidate_generation, usage, positive: true))
36
- emit_json(protected_call(client, "finish", params, mutation))
37
- return
38
- end
39
- attempt_id = require_option(options, :attempt, "finish --attempt ID --receipt FILE")
40
- receipt = require_option(options, :receipt, "finish --attempt ID --receipt FILE")
41
-
42
- result = build_coordinator.finish(attempt_id: attempt_id, receipt_path: receipt)
43
-
44
- emit_json(result.projection)
45
- end
46
- end
47
- end
48
- end
49
- end
50
- end
51
- end
@@ -1,49 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "json"
4
- require_relative "base"
5
-
6
- module Ace
7
- module Assign
8
- module CLI
9
- module Commands
10
- module Attempt
11
- # Classify interruptions and resolve uncertainty against verified,
12
- # boundary-attributed receipts. Never replays external effects.
13
- class Reconcile < Ace::Support::Cli::Command
14
- include Ace::Support::Cli::Base
15
- include Attempt::Base
16
-
17
- desc "Reconcile an interrupted or uncertain attempt"
18
-
19
- option :attempt, desc: "Attempt ID"
20
- option :mapping, desc: "Exact installed protected mapping ID"
21
- option :assignment, desc: "Exact protected assignment ID"
22
- option :mutation, desc: "Stable original authority mutation ID"
23
- option :expected_generation, desc: "Original authority mutation generation"
24
- option :receipt, desc: "Path to the receipt JSON file (required to resolve uncertainty)"
25
-
26
- def call(**options)
27
- if (context = protected_context(options))
28
- raise Ace::Support::Cli::Error, "Protected recovery forbids --receipt" unless options[:receipt].to_s.empty?
29
- usage = "reconcile --mapping MAP --assignment ID --attempt ID --mutation ID --expected-generation N"
30
- client, params, mutation = protected_attempt_request(context, options, usage)
31
- emit_json(protected_call(client, "recover", params, mutation))
32
- return
33
- end
34
- attempt_id = require_option(options, :attempt, "reconcile --attempt ID [--receipt FILE]")
35
- receipt = options[:receipt].to_s.strip
36
-
37
- result = build_coordinator.reconcile(
38
- attempt_id: attempt_id,
39
- receipt_path: receipt.empty? ? nil : receipt
40
- )
41
-
42
- emit_json(result.projection)
43
- end
44
- end
45
- end
46
- end
47
- end
48
- end
49
- end
@@ -1,45 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "json"
4
- require_relative "base"
5
-
6
- module Ace
7
- module Assign
8
- module CLI
9
- module Commands
10
- module Attempt
11
- # Bind an immutable attempt to an assignment step/subtree.
12
- #
13
- # Identity is derived from the execution boundary; a repeated
14
- # identical start returns the active attempt, and a conflicting
15
- # binding fails without launching a second writer.
16
- class Start < Ace::Support::Cli::Command
17
- include Ace::Support::Cli::Base
18
- include Attempt::Base
19
-
20
- desc "Start a scoped attempt for an assignment step"
21
-
22
- option :assignment, desc: "Assignment ID"
23
- option :step, desc: "Step or subtree scope (e.g. 010 or 010.01)"
24
- option :project, desc: "Project ID the attempt executes in"
25
-
26
- def call(**options)
27
- usage = "start --assignment ID --step STEP --project ID"
28
- assignment = require_option(options, :assignment, usage)
29
- step = require_option(options, :step, usage)
30
- project = require_option(options, :project, usage)
31
-
32
- attempt = build_coordinator.start(
33
- assignment_id: assignment,
34
- step: step,
35
- project_id: project
36
- )
37
-
38
- emit_json(attempt.projection)
39
- end
40
- end
41
- end
42
- end
43
- end
44
- end
45
- end
@@ -1,54 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "json"
4
- require_relative "base"
5
-
6
- module Ace
7
- module Assign
8
- module CLI
9
- module Commands
10
- module Attempt
11
- # Show attempt state, binding facts, and evidence references.
12
- # JSON output carries only state, binding, references, and digests
13
- # — never credentials or receipt bytes.
14
- class Status < Ace::Support::Cli::Command
15
- include Ace::Support::Cli::Base
16
- include Attempt::Base
17
-
18
- desc "Show attempt status for an assignment"
19
-
20
- option :assignment, desc: "Assignment ID"
21
- option :format, desc: "Output format (json, text)", default: "json"
22
-
23
- def call(**options)
24
- assignment = require_option(options, :assignment, "status --assignment ID --format json")
25
- projection = build_coordinator.status(assignment)
26
-
27
- if options[:format] == "text"
28
- print_text(assignment, projection)
29
- else
30
- emit_json(projection || {"attempt" => nil})
31
- end
32
- end
33
-
34
- private
35
-
36
- def print_text(assignment, projection)
37
- return puts "No attempts recorded for #{assignment}" if projection.nil?
38
-
39
- puts "Attempt: #{projection['attempt_id']} #{projection['state']} (#{projection['scope']})"
40
- puts "Recovery: #{projection['recovery_mode']}"
41
- puts "Base head: #{projection['base_head']}"
42
- puts "Candidate head: #{projection['candidate_head'] || 'unpinned'}"
43
- puts "Evidence ref: #{projection['evidence_git_ref'] || 'local-only'}"
44
- puts "Journal commit: #{projection['journal_commit'] || 'none'}"
45
- return unless projection["unresolved_effects"].any?
46
-
47
- puts "Unresolved effects: #{projection['unresolved_effects'].join(', ')}"
48
- end
49
- end
50
- end
51
- end
52
- end
53
- end
54
- end
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
- require_relative "../../../authority/prepared_task_context"
3
-
4
- module Ace
5
- module Assign
6
- module CLI
7
- module Commands
8
- module Authority
9
- class InboxContextPrincipal < Ace::Support::Cli::Command
10
- desc "Classify the actual caller through every retained protected owner"
11
-
12
- def call(**options)
13
- raise ArgumentError, "fixed inbox context options differ" unless options.empty?
14
- consumer = Ace::Assign::Authority::PreparedTaskContext.new(context: @protected_assignment_context)
15
- $stdout.write(consumer.inbox_principal())
16
- 0
17
- rescue ArgumentError, Ace::Runtime::Error, Ace::Assign::Error => error
18
- raise Ace::Support::Cli::Error, error.message
19
- end
20
- end
21
- end
22
- end
23
- end
24
- end
25
- end
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
- require_relative "../../../authority/prepared_task_context"
3
-
4
- module Ace
5
- module Assign
6
- module CLI
7
- module Commands
8
- module Authority
9
- class InboxContextSelection < Ace::Support::Cli::Command
10
- desc "Read the fixed installed inbox context selection"
11
- option :project, required: true, desc: "Installed project ID"
12
- option :mapping, required: true, desc: "Installed mapping ID"
13
- option :inbox_context, required: true, desc: "Installed inbox context ID"
14
-
15
- def call(**options)
16
- raise ArgumentError, "fixed inbox context options differ" unless options.keys.sort == %i[inbox_context mapping project]
17
- consumer = Ace::Assign::Authority::PreparedTaskContext.new(context: @protected_assignment_context)
18
- $stdout.write(consumer.inbox_selection(**options))
19
- 0
20
- rescue ArgumentError, Ace::Runtime::Error, Ace::Assign::Error => error
21
- raise Ace::Support::Cli::Error, error.message
22
- end
23
- end
24
- end
25
- end
26
- end
27
- end
28
- end
@@ -1,97 +0,0 @@
1
- # frozen_string_literal: true
2
- require "json"
3
- require_relative "../../../authority/launch_driver"
4
- module Ace
5
- module Assign
6
- module CLI
7
- module Commands
8
- module Authority
9
- class Launch < Ace::Support::Cli::Command
10
- desc "Launch one mapped worker and retain its original foreground control channel"
11
- READY_FIELDS = %w[assignment_id attempt_id generation journal_commit mapping_id original_binding_digest type version].freeze
12
- READY_LIMIT = 16_384
13
- option :mapping, required: true, desc: "Installed launch mapping ID"
14
- option :assignment, desc: "Managed assignment ID"
15
- option :definition, desc: "Retained final prepared assignment definition JSON file"
16
- option :prepared_bundle, desc: "Retained original prepared input Git bundle"
17
- option :step, desc: "Assignment subtree scope"
18
- option :base_head, desc: "Exact base commit SHA"
19
- option :mutation, desc: "Stable invocation ID for safe replay"
20
- option :dry_run, type: :boolean, default: false, desc: "Verify installed boundary without mutation or creation"
21
- def call(**options)
22
- driver = build_driver(options.fetch(:mapping))
23
- result = if options[:dry_run]
24
- driver.preflight
25
- else
26
- %i[assignment definition prepared_bundle step base_head].each do |key|
27
- raise ArgumentError, "Missing --#{key.to_s.tr('_', '-')}" unless options[key].is_a?(String) && !options[key].empty?
28
- end
29
- definition = retained_input(options[:definition], 32_768).force_encoding(Encoding::UTF_8)
30
- raise ArgumentError, "assignment definition is not UTF-8" unless definition.valid_encoding?
31
- bundle = retained_input(options[:prepared_bundle], Ace::Assign::Authority::CandidateTransfer::MAX_BYTES)
32
- args = {prepared_bundle: bundle, assignment_id: options[:assignment], definition_bytes: definition,
33
- scope: options[:step], base_head: options[:base_head]}
34
- args[:mutation_id] = options[:mutation] if options[:mutation]
35
- driver.launch(**args)
36
- end
37
- if !options[:dry_run] && result["phase"] == "issued"
38
- retaining_control = true
39
- announced = false
40
- driver.serve_control!(state: result) do |ready|
41
- raise ArgumentError, "original launch readiness was already announced" if announced
42
- line = readiness_line(ready, result, options)
43
- $stdout.write(line)
44
- $stdout.flush
45
- announced = true
46
- end
47
- raise ArgumentError, "original control ended before authenticated readiness" unless announced
48
- else
49
- puts JSON.generate(result)
50
- end
51
- rescue ArgumentError, SystemCallError, Ace::Runtime::Error, Ace::Assign::Error => error
52
- raise Ace::Support::Cli::Error, error.message
53
- ensure
54
- # Local foreground-loop cancellation is not a stopped/settled proof.
55
- driver.request_control_cancel if retaining_control
56
- end
57
- private
58
- def retained_input(path, limit)
59
- File.open(path, File::RDONLY | File::NOFOLLOW | File::NONBLOCK) do |file|
60
- before = file.stat
61
- unless before.file? && before.size.between?(1, limit)
62
- raise ArgumentError, "retained launch input is not a bounded regular file"
63
- end
64
- bytes = (file.read(limit + 1) || "").b
65
- after = file.stat
66
- identity = ->(stat) { [stat.dev, stat.ino, stat.size, stat.mtime, stat.ctime] }
67
- unless bytes.bytesize == before.size && bytes.bytesize <= limit && identity.call(before) == identity.call(after)
68
- raise ArgumentError, "retained launch input changed while reading"
69
- end
70
- bytes
71
- end
72
- end
73
-
74
- def readiness_line(ready, result, options)
75
- unless ready.is_a?(Hash) && ready.keys.all? { |key| key.is_a?(String) } && ready.keys.sort == READY_FIELDS &&
76
- ready["version"].is_a?(Integer) && ready["version"] == 1 && ready["type"] == "launch_ready" &&
77
- ready.values_at("mapping_id", "assignment_id", "attempt_id") ==
78
- [options.fetch(:mapping), options.fetch(:assignment), result.fetch("attempt_id")] &&
79
- ready["generation"].is_a?(Integer) && ready["generation"].positive? &&
80
- ready["journal_commit"].is_a?(String) && ready["journal_commit"].match?(/\A(?:[0-9a-f]{40}|[0-9a-f]{64})\z/) &&
81
- ready["original_binding_digest"].is_a?(String) && ready["original_binding_digest"].match?(/\A[0-9a-f]{64}\z/)
82
- raise ArgumentError, "original launch readiness is malformed or mismatched"
83
- end
84
- line = JSON.generate(ready) + "\n"
85
- raise ArgumentError, "original launch readiness is oversized" if line.bytesize > READY_LIMIT
86
- line
87
- end
88
-
89
- def build_driver(mapping)
90
- Ace::Assign::Authority::LaunchDriver.new(mapping_id: mapping)
91
- end
92
- end
93
- end
94
- end
95
- end
96
- end
97
- end
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
- require_relative "../../../authority/server"
3
- require_relative "../../../authority/router"
4
- require_relative "../../../authority/launch_lifecycle"
5
- module Ace
6
- module Assign
7
- module CLI
8
- module Commands
9
- module Authority
10
- class Serve < Ace::Support::Cli::Command
11
- desc "Serve the installed protected assignment authority"
12
- option :authority, required: true, desc: "Installed authority ID"
13
- def call(**options)
14
- deployment = Ace::Assign::Authority::Deployment.load
15
- history = Ace::Assign::Authority::DeploymentHistory.load
16
- launch = Ace::Assign::Authority::LaunchLifecycle.new(deployment: deployment, deployment_history: history)
17
- router = Ace::Assign::Authority::Router.new(launch: launch)
18
- server = Ace::Assign::Authority::Server.new(authority_id: options.fetch(:authority), deployment: deployment, lifecycle: router)
19
- signals = %w[INT TERM].to_h { |signal| [signal, Signal.trap(signal) { server.request_stop }] }
20
- server.serve
21
- rescue ArgumentError, Ace::Runtime::Error, Ace::Assign::Error => error
22
- raise Ace::Support::Cli::Error, error.message
23
- ensure
24
- signals&.each { |signal, handler| Signal.trap(signal, handler) }
25
- end
26
- end
27
- end
28
- end
29
- end
30
- end
31
- end
@@ -1,26 +0,0 @@
1
- # frozen_string_literal: true
2
- require "json"
3
- require_relative "../../../authority/client"
4
- module Ace
5
- module Assign
6
- module CLI
7
- module Commands
8
- module Authority
9
- class Status < Ace::Support::Cli::Command
10
- desc "Inspect canonical protected launch ownership"
11
- option :mapping, required: true, desc: "Installed launch mapping ID"
12
- option :assignment, required: true, desc: "Assignment ID"
13
- option :attempt, required: true, desc: "Attempt ID"
14
- def call(**options)
15
- reply = Ace::Assign::Authority::Client.new(mapping_id: options.fetch(:mapping)).call("attempt_status",
16
- {"assignment_id" => options.fetch(:assignment), "attempt_id" => options.fetch(:attempt), "result_candidate_generation" => nil})
17
- puts JSON.generate(reply.data)
18
- rescue ArgumentError, Ace::Runtime::Error, Ace::Assign::Error => error
19
- raise Ace::Support::Cli::Error, error.message
20
- end
21
- end
22
- end
23
- end
24
- end
25
- end
26
- end
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
- require_relative "../../../authority/prepared_task_context"
3
-
4
- module Ace
5
- module Assign
6
- module CLI
7
- module Commands
8
- module Authority
9
- class TaskContext < Ace::Support::Cli::Command
10
- desc "Return the captured original task context through the fixed selected entry"
11
- option :mapping, required: true, desc: "Installed original mapping ID"
12
- option :assignment, required: true, desc: "Original assignment ID@SCOPE"
13
- option :attempt, required: true, desc: "Original protected attempt ID"
14
- option :task, required: true, desc: "Captured canonical task ID"
15
-
16
- def call(**options)
17
- unless options.keys.sort == %i[assignment attempt mapping task]
18
- raise ArgumentError, "fixed task-context accepts only its four selectors"
19
- end
20
- consumer = Ace::Assign::Authority::PreparedTaskContext.new(context: @protected_assignment_context)
21
- $stdout.write(consumer.call(**options))
22
- 0
23
- rescue ArgumentError, Ace::Runtime::Error, Ace::Assign::Error => error
24
- raise Ace::Support::Cli::Error, error.message
25
- end
26
- end
27
- end
28
- end
29
- end
30
- end
31
- end
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
- require_relative "../../../authority/prepared_task_context"
3
-
4
- module Ace
5
- module Assign
6
- module CLI
7
- module Commands
8
- module Authority
9
- class TaskContextPrincipal < Ace::Support::Cli::Command
10
- desc "Classify this actual caller through the installed and retained protected owners"
11
-
12
- def call(**options)
13
- raise ArgumentError, "fixed task-context-principal accepts no options" unless options.empty?
14
- consumer = Ace::Assign::Authority::PreparedTaskContext.new(context: @protected_assignment_context)
15
- $stdout.write(consumer.principal)
16
- 0
17
- rescue ArgumentError, Ace::Runtime::Error, Ace::Assign::Error => error
18
- raise Ace::Support::Cli::Error, error.message
19
- end
20
- end
21
- end
22
- end
23
- end
24
- end
25
- end
@@ -1,30 +0,0 @@
1
- # frozen_string_literal: true
2
- require_relative "../../../authority/prepared_task_context"
3
-
4
- module Ace
5
- module Assign
6
- module CLI
7
- module Commands
8
- module Authority
9
- class TaskContextSelection < Ace::Support::Cli::Command
10
- desc "Return the authenticated original task-context entry without captured text"
11
- option :mapping, required: true, desc: "Installed original mapping ID"
12
- option :assignment, required: true, desc: "Original assignment ID@SCOPE"
13
- option :attempt, required: true, desc: "Original protected attempt ID"
14
-
15
- def call(**options)
16
- unless options.keys.sort == %i[assignment attempt mapping]
17
- raise ArgumentError, "fixed task-context-selection accepts only its three selectors"
18
- end
19
- consumer = Ace::Assign::Authority::PreparedTaskContext.new(context: @protected_assignment_context)
20
- $stdout.write(consumer.selection(**options))
21
- 0
22
- rescue ArgumentError, Ace::Runtime::Error, Ace::Assign::Error => error
23
- raise Ace::Support::Cli::Error, error.message
24
- end
25
- end
26
- end
27
- end
28
- end
29
- end
30
- end
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
- require "json"
3
- require_relative "../../../authority/launch_driver"
4
- module Ace
5
- module Assign
6
- module CLI
7
- module Commands
8
- module Authority
9
- class Terminate < Ace::Support::Cli::Command
10
- desc "Close the original gated native child and request proven abort"
11
- option :mapping, required: true, desc: "Installed launch mapping ID"
12
- option :assignment, required: true, desc: "Assignment ID"
13
- option :attempt, required: true, desc: "Attempt ID"
14
- def call(**options)
15
- client = Ace::Assign::Authority::Client.new(mapping_id: options.fetch(:mapping))
16
- state = client.call("inspect_launch", {"assignment_id" => options.fetch(:assignment), "attempt_id" => options.fetch(:attempt)}).data
17
- binding = state.fetch("process_binding") { raise ArgumentError, "no positively recorded original child; supervisor inspection required" }
18
- result = Ace::Assign::Authority::LaunchDriver.new(mapping_id: options.fetch(:mapping)).terminate(
19
- state: state, binding: binding, evidence: "protected exact-child termination requested")
20
- puts JSON.generate(result)
21
- rescue ArgumentError, Ace::Runtime::Error, Ace::Assign::Error => error
22
- raise Ace::Support::Cli::Error, error.message
23
- end
24
- end
25
- end
26
- end
27
- end
28
- end
29
- end
@@ -1,23 +0,0 @@
1
- # frozen_string_literal: true
2
- require_relative "../../../authority/prepared_worker"
3
-
4
- module Ace
5
- module Assign
6
- module CLI
7
- module Commands
8
- module Authority
9
- class Worker < Ace::Support::Cli::Command
10
- desc "Consume the original authenticated prepared subtree as its fixed worker"
11
-
12
- def call(**options)
13
- raise ArgumentError, "fixed worker accepts no options" unless options.empty?
14
- Ace::Assign::Authority::PreparedWorker.new.run
15
- rescue ArgumentError, Ace::Runtime::Error, Ace::Assign::Error => error
16
- raise Ace::Support::Cli::Error, error.message
17
- end
18
- end
19
- end
20
- end
21
- end
22
- end
23
- end
@@ -1,55 +0,0 @@
1
- # frozen_string_literal: true
2
- require_relative "protected_submission"
3
-
4
- module Ace
5
- module Assign
6
- module CLI
7
- module Commands
8
- class CampaignExportResult < Ace::Support::Cli::Command
9
- include Ace::Support::Cli::Base
10
- include ProtectedSubmission
11
- desc "Download a verified accepted campaign result through its original authority"
12
- option :mapping, desc: "Original installed parent mapping"
13
- option :assignment, desc: "Original parent assignment"
14
- option :attempt, desc: "Original parent attempt"
15
- option :head, desc: "Exact parent candidate head"
16
- option :candidate_generation, desc: "Exact parent candidate counter"
17
- option :output, desc: "Result byte file (created once, exact retries allowed)"
18
-
19
- def call(**options)
20
- usage = "campaign-export-result with original parent selectors and --output FILE"
21
- context = protected_context(options)
22
- raise AttemptErrors::EvidenceUnavailable, "Campaign export requires installed authority" unless context
23
- params = {"assignment_id" => require_option(options, :assignment, usage),
24
- "attempt_id" => require_option(options, :attempt, usage), "head" => require_option(options, :head, usage),
25
- "candidate_generation" => integer_option(options, :candidate_generation, usage, positive: true)}
26
- raise Ace::Support::Cli::Error, "Campaign head must be an exact SHA-1" unless params["head"].match?(/\A[0-9a-f]{40}\z/)
27
- context.verify_attempt_hints!(assignment_id: params.fetch("assignment_id"), attempt_id: params.fetch("attempt_id"))
28
- path = require_option(options, :output, usage)
29
- reply = context.client(options: options).call("campaign_export_result", params, download: true, purpose: :artifacts, timeout: 30)
30
- bytes = reply.parts&.first
31
- unless reply.parts&.size == 1 && bytes.is_a?(String) && bytes.bytesize <= 64 * 1024 &&
32
- reply.data.values_at("head", "candidate_generation", "bytes", "sha256") ==
33
- [params.fetch("head"), params.fetch("candidate_generation"), bytes.bytesize, Digest::SHA256.hexdigest(bytes)]
34
- raise AttemptErrors::EvidenceUnavailable, "Campaign result download differs"
35
- end
36
- begin
37
- File.open(path, File::WRONLY | File::CREAT | File::EXCL | File::NOFOLLOW, 0o600) do |file|
38
- file.write(bytes)
39
- file.flush
40
- file.fsync
41
- end
42
- rescue Errno::EEXIST
43
- raise Ace::Support::Cli::Error, "Existing campaign result file differs" unless input_bytes(path, limit: 64 * 1024) == bytes
44
- end
45
- emit_json(reply.data.except("transfer").merge("path" => path))
46
- rescue SecurityError, Ace::Runtime::RuntimeUnavailableError
47
- protected_transport_unavailable!
48
- rescue SystemCallError, IOError
49
- raise Ace::Support::Cli::Error, "Campaign result file or transport is unavailable"
50
- end
51
- end
52
- end
53
- end
54
- end
55
- end