ace-assign 0.64.0 → 0.66.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 +11 -0
- data/CHANGELOG.md +19 -0
- data/docs/protected-authority.md +23 -7
- data/docs/usage.md +117 -4
- data/exe/ace-scope-ready +55 -0
- data/handbook/workflow-instructions/assign/drive.wf.md +26 -1
- data/lib/ace/assign/atoms/attempt_state_machine.rb +8 -0
- data/lib/ace/assign/atoms/delivery_parameters.rb +4 -39
- data/lib/ace/assign/authority/assignment_inventory.rb +290 -0
- data/lib/ace/assign/authority/campaign_consumer_policy.rb +100 -0
- data/lib/ace/assign/authority/campaign_execution.rb +119 -0
- data/lib/ace/assign/authority/campaign_round_transfer.rb +82 -0
- data/lib/ace/assign/authority/candidate_transfer.rb +169 -2
- data/lib/ace/assign/authority/cleanup_result_protection.rb +53 -0
- data/lib/ace/assign/authority/client.rb +156 -6
- data/lib/ace/assign/authority/deployment.rb +201 -39
- data/lib/ace/assign/authority/deployment_history.rb +146 -0
- data/lib/ace/assign/authority/endcap.rb +131 -18
- data/lib/ace/assign/authority/endcap_attempts.rb +274 -0
- data/lib/ace/assign/authority/endcap_campaign_results.rb +232 -0
- data/lib/ace/assign/authority/endcap_campaign_rounds.rb +266 -0
- data/lib/ace/assign/authority/endcap_contexts.rb +23 -0
- data/lib/ace/assign/authority/endcap_inboxes.rb +3 -280
- data/lib/ace/assign/authority/endcap_prepared_work.rb +80 -0
- data/lib/ace/assign/authority/endcap_publication.rb +207 -0
- data/lib/ace/assign/authority/endcap_results.rb +36 -18
- data/lib/ace/assign/authority/endcap_review_requests.rb +183 -0
- data/lib/ace/assign/authority/endcap_reviews.rb +130 -0
- data/lib/ace/assign/authority/endcap_service_settlement.rb +152 -0
- data/lib/ace/assign/authority/endcap_services.rb +221 -18
- data/lib/ace/assign/authority/execution_scope_observation.rb +468 -41
- data/lib/ace/assign/authority/inbox_context_original.rb +113 -0
- data/lib/ace/assign/authority/launch_attempt_consumers.rb +51 -0
- data/lib/ace/assign/authority/launch_campaign_registration.rb +214 -0
- data/lib/ace/assign/authority/launch_control_channel.rb +313 -0
- data/lib/ace/assign/authority/launch_control_exclusions.rb +141 -0
- data/lib/ace/assign/authority/launch_driver.rb +298 -19
- data/lib/ace/assign/authority/launch_input_inhibition.rb +132 -0
- data/lib/ace/assign/authority/launch_lifecycle.rb +275 -100
- data/lib/ace/assign/authority/launch_prepared_work.rb +122 -0
- data/lib/ace/assign/authority/launch_review.rb +91 -0
- data/lib/ace/assign/authority/launch_scope_abort.rb +0 -7
- data/lib/ace/assign/authority/launch_scope_admission.rb +136 -5
- data/lib/ace/assign/authority/launch_scope_close.rb +68 -37
- data/lib/ace/assign/authority/launch_scope_release.rb +696 -17
- data/lib/ace/assign/authority/launch_steering.rb +353 -0
- data/lib/ace/assign/authority/launch_stop.rb +254 -0
- data/lib/ace/assign/authority/maintenance_workspace_retirement.rb +229 -0
- data/lib/ace/assign/authority/original_inbox_selection.rb +41 -0
- data/lib/ace/assign/authority/posix_acl.rb +5 -2
- data/lib/ace/assign/authority/prepared_input.rb +130 -0
- data/lib/ace/assign/authority/prepared_queue.rb +185 -0
- data/lib/ace/assign/authority/prepared_task_context.rb +116 -0
- data/lib/ace/assign/authority/prepared_work.rb +304 -0
- data/lib/ace/assign/authority/prepared_worker.rb +69 -0
- data/lib/ace/assign/authority/protected_assignment_context.rb +226 -0
- data/lib/ace/assign/authority/readiness_hook.rb +120 -0
- data/lib/ace/assign/authority/router.rb +24 -2
- data/lib/ace/assign/authority/server.rb +103 -33
- data/lib/ace/assign/authority/service_cleanup_dispatch.rb +88 -0
- data/lib/ace/assign/authority/service_cleanup_evidence.rb +180 -0
- data/lib/ace/assign/authority/service_delivery_evidence.rb +101 -0
- data/lib/ace/assign/authority/service_evidence.rb +243 -12
- data/lib/ace/assign/authority/service_publication_evidence.rb +110 -0
- data/lib/ace/assign/authority/task_context_entry.rb +32 -0
- data/lib/ace/assign/authority/transfer_codec.rb +44 -12
- data/lib/ace/assign/cli/commands/assignment_target.rb +15 -2
- data/lib/ace/assign/cli/commands/attempt/base.rb +49 -0
- data/lib/ace/assign/cli/commands/attempt/finish.rb +20 -4
- data/lib/ace/assign/cli/commands/attempt/reconcile.rb +11 -0
- data/lib/ace/assign/cli/commands/authority/inbox_context_principal.rb +25 -0
- data/lib/ace/assign/cli/commands/authority/inbox_context_selection.rb +28 -0
- data/lib/ace/assign/cli/commands/authority/launch.rb +58 -6
- data/lib/ace/assign/cli/commands/authority/serve.rb +2 -1
- data/lib/ace/assign/cli/commands/authority/status.rb +1 -1
- data/lib/ace/assign/cli/commands/authority/task_context.rb +31 -0
- data/lib/ace/assign/cli/commands/authority/task_context_principal.rb +25 -0
- data/lib/ace/assign/cli/commands/authority/task_context_selection.rb +30 -0
- data/lib/ace/assign/cli/commands/authority/worker.rb +23 -0
- data/lib/ace/assign/cli/commands/campaign_export_result.rb +55 -0
- data/lib/ace/assign/cli/commands/campaign_record_round.rb +57 -0
- data/lib/ace/assign/cli/commands/create.rb +2 -0
- data/lib/ace/assign/cli/commands/delivery.rb +54 -4
- data/lib/ace/assign/cli/commands/fail.rb +6 -0
- data/lib/ace/assign/cli/commands/finish.rb +23 -2
- data/lib/ace/assign/cli/commands/fork_session.rb +6 -2
- data/lib/ace/assign/cli/commands/inbox_bind.rb +34 -0
- data/lib/ace/assign/cli/commands/protected_submission.rb +61 -0
- data/lib/ace/assign/cli/commands/resume.rb +12 -0
- data/lib/ace/assign/cli/commands/select.rb +2 -0
- data/lib/ace/assign/cli/commands/start.rb +2 -0
- data/lib/ace/assign/cli/commands/status.rb +4 -2
- data/lib/ace/assign/cli/commands/step.rb +3 -1
- data/lib/ace/assign/cli/commands/submit_candidate.rb +34 -0
- data/lib/ace/assign/cli/commands/submit_result.rb +61 -0
- data/lib/ace/assign/cli.rb +36 -5
- data/lib/ace/assign/errors.rb +139 -0
- data/lib/ace/assign/models/assignment.rb +26 -4
- data/lib/ace/assign/models/evidence_event.rb +3 -3
- data/lib/ace/assign/molecules/assignment_manager.rb +12 -2
- data/lib/ace/assign/molecules/attempt_reconciler.rb +20 -0
- data/lib/ace/assign/molecules/canonical_attempt_state.rb +151 -0
- data/lib/ace/assign/molecules/canonical_evidence.rb +5 -2
- data/lib/ace/assign/molecules/canonical_read_snapshot.rb +374 -0
- data/lib/ace/assign/molecules/evidence_journal.rb +720 -44
- data/lib/ace/assign/molecules/execution_scope_lineage.rb +27 -9
- data/lib/ace/assign/molecules/fork_session_launcher.rb +16 -6
- data/lib/ace/assign/molecules/journal_input_inhibition.rb +78 -0
- data/lib/ace/assign/molecules/journal_mutation.rb +82 -13
- data/lib/ace/assign/molecules/journal_prompt_mutation.rb +241 -0
- data/lib/ace/assign/molecules/lifecycle_exclusion.rb +178 -26
- data/lib/ace/assign/molecules/original_launch_binding.rb +37 -0
- data/lib/ace/assign/molecules/protected_control_exclusion.rb +303 -0
- data/lib/ace/assign/molecules/protected_workspace_exclusion.rb +330 -0
- data/lib/ace/assign/molecules/protected_workspace_provisioner.rb +164 -0
- data/lib/ace/assign/molecules/queue_scanner.rb +26 -11
- data/lib/ace/assign/molecules/receipt_verifier.rb +21 -15
- data/lib/ace/assign/molecules/step_writer.rb +27 -5
- data/lib/ace/assign/molecules/terminal_scope_receipt.rb +88 -0
- data/lib/ace/assign/organisms/assignment_executor.rb +4 -4
- data/lib/ace/assign/organisms/attempt_coordinator.rb +66 -76
- data/lib/ace/assign/organisms/prepared_work_builder.rb +194 -0
- data/lib/ace/assign/organisms/protected_delivery_coordinator.rb +100 -0
- data/lib/ace/assign/organisms/task_assignment_creator.rb +4 -2
- data/lib/ace/assign/version.rb +1 -1
- data/lib/ace/assign.rb +1 -112
- metadata +88 -9
- data/lib/ace/assign/cli/commands/inbox_reconcile.rb +0 -36
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require_relative "../authority/service_delivery_evidence"
|
|
3
|
+
require "ace/git/atoms/service_pr_evidence"
|
|
4
|
+
|
|
5
|
+
module Ace
|
|
6
|
+
module Assign
|
|
7
|
+
module Organisms
|
|
8
|
+
# Worker consumes only the original authority's canonical completion.
|
|
9
|
+
# No local journal, provider mutation, recovery write or merge retry.
|
|
10
|
+
class ProtectedDeliveryCoordinator
|
|
11
|
+
BASE_FIELDS = %w[request_id assignment_id attempt_id project_id operation service_id target candidate_head
|
|
12
|
+
candidate_generation state dispatch_ticket_id claim_binding claim_generation dispatch_phase policy_digest generation journal_commit].freeze
|
|
13
|
+
COMPLETE_FIELDS = %w[input_digest authorization executor_uid completion_digest receipt delivery_event].freeze
|
|
14
|
+
|
|
15
|
+
def initialize(client:, project_id:)
|
|
16
|
+
@client, @project_id = client, project_id
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def perform(assignment_id:, attempt_id:, operation:, service_request_id:, candidate_head:, candidate_generation:,
|
|
20
|
+
input_digest:, target:, parameters: nil, title: nil, body: nil, tests: nil, review: nil)
|
|
21
|
+
unless %w[create update ready merge status].include?(operation) && [title, body, tests, review].all?(&:nil?) &&
|
|
22
|
+
[assignment_id, attempt_id, service_request_id].all? { |value| value.is_a?(String) && value.match?(Molecules::JournalMutation::ID) } &&
|
|
23
|
+
candidate_head.is_a?(String) && candidate_head.match?(/\A[0-9a-f]{40}\z/) &&
|
|
24
|
+
candidate_generation.is_a?(Integer) && candidate_generation.positive? &&
|
|
25
|
+
input_digest.is_a?(String) && input_digest.match?(/\A[0-9a-f]{64}\z/) &&
|
|
26
|
+
target.is_a?(Hash) && target.keys.sort == %w[artifact_digest resource] && target["resource"].is_a?(String) &&
|
|
27
|
+
(target["artifact_digest"].nil? || target["artifact_digest"].is_a?(String) && target["artifact_digest"].match?(/\A[0-9a-f]{64}\z/))
|
|
28
|
+
raise ArgumentError, "protected delivery requires exact canonical merge selectors; local delivery flags are unavailable"
|
|
29
|
+
end
|
|
30
|
+
binding = {"assignment_id" => assignment_id, "attempt_id" => attempt_id,
|
|
31
|
+
"candidate_generation" => candidate_generation, "head" => candidate_head, "request_id" => service_request_id}
|
|
32
|
+
data = @client.call("service_status", binding).data
|
|
33
|
+
unless data.is_a?(Hash) && (data.keys - BASE_FIELDS - COMPLETE_FIELDS).empty? &&
|
|
34
|
+
Atoms::EvidenceDigest.digest(data.slice("assignment_id", "attempt_id", "request_id", "candidate_generation")) == Atoms::EvidenceDigest.digest(binding.except("head")) &&
|
|
35
|
+
data["project_id"] == @project_id && data["candidate_head"] == candidate_head && Atoms::EvidenceDigest.digest(data["target"]) == Atoms::EvidenceDigest.digest(target) &&
|
|
36
|
+
%w[create update ready merge].include?(data["operation"]) && (operation == "status" || data["operation"] == operation) && data["generation"].is_a?(Integer) && data["generation"].positive? &&
|
|
37
|
+
data["input_digest"] == input_digest &&
|
|
38
|
+
data["journal_commit"].is_a?(String) && data["journal_commit"].match?(/\A(?:[0-9a-f]{40}|[0-9a-f]{64})\z/)
|
|
39
|
+
raise AttemptErrors::ReceiptRejected, "original canonical merge status differs"
|
|
40
|
+
end
|
|
41
|
+
if data["state"] != "succeeded"
|
|
42
|
+
return data if operation == "status"
|
|
43
|
+
raise AttemptErrors::EvidenceUnavailable, "original merge is not canonically succeeded; inspect its status without retry"
|
|
44
|
+
end
|
|
45
|
+
unless data.keys.sort == (BASE_FIELDS + COMPLETE_FIELDS).sort && data["input_digest"] == input_digest &&
|
|
46
|
+
data["executor_uid"].is_a?(Integer) && data["executor_uid"].positive? &&
|
|
47
|
+
data["completion_digest"].is_a?(String) && data["completion_digest"].match?(/\A[0-9a-f]{64}\z/)
|
|
48
|
+
raise AttemptErrors::ReceiptRejected, "original canonical completion selectors differ"
|
|
49
|
+
end
|
|
50
|
+
receipt = data.fetch("receipt")
|
|
51
|
+
unless receipt.is_a?(Hash) && receipt.keys.sort == Molecules::EvidenceJournal::TERMINAL_RECEIPT_FIELDS.sort &&
|
|
52
|
+
receipt["outcome"] == "succeeded" && receipt["operation"] == data["operation"] && receipt["transport"] == "unix" &&
|
|
53
|
+
receipt.slice("request_id", "assignment_id", "attempt_id", "project_id", "input_digest", "target", "candidate_head", "executor_uid") ==
|
|
54
|
+
data.slice("request_id", "assignment_id", "attempt_id", "project_id", "input_digest", "target", "candidate_head", "executor_uid") &&
|
|
55
|
+
receipt["evidence"].is_a?(Array) && receipt["evidence"].one?
|
|
56
|
+
raise AttemptErrors::ReceiptRejected, "original canonical merge receipt differs"
|
|
57
|
+
end
|
|
58
|
+
reference = receipt.fetch("evidence").first
|
|
59
|
+
unless reference.is_a?(Hash) && reference.keys.sort == %w[ref sha256] &&
|
|
60
|
+
reference["ref"].is_a?(String) && reference["ref"].match?(%r{\Aevidence/imports/[a-z0-9-]+\z}) &&
|
|
61
|
+
reference["sha256"].is_a?(String) && reference["sha256"].match?(/\A[0-9a-f]{64}\z/)
|
|
62
|
+
raise AttemptErrors::ReceiptRejected, "original canonical artifact reference differs"
|
|
63
|
+
end
|
|
64
|
+
fetched = @client.call("evidence_fetch", {"assignment_id" => assignment_id, "attempt_id" => attempt_id,
|
|
65
|
+
"kind" => "service", "purpose_id" => service_request_id,
|
|
66
|
+
"artifact_id" => reference.fetch("ref").delete_prefix("evidence/imports/")}, download: true, purpose: :artifacts)
|
|
67
|
+
descriptor = fetched.data.fetch("descriptor")
|
|
68
|
+
original_binding = Authority::ServiceEvidence::FIELDS.to_h { |key| [key, receipt.key?(key) ? receipt.fetch(key) : data.fetch(key)] }
|
|
69
|
+
unless Molecules::CanonicalEvidence.valid_descriptor?(descriptor) &&
|
|
70
|
+
descriptor["binding_digest"] == Atoms::EvidenceDigest.digest(original_binding) &&
|
|
71
|
+
descriptor["sha256"] == reference.fetch("sha256") && descriptor["peer_uid"] == data.fetch("executor_uid") &&
|
|
72
|
+
fetched.parts.is_a?(Array) && fetched.parts.one? && fetched.parts.first.is_a?(String) &&
|
|
73
|
+
Digest::SHA256.hexdigest(fetched.parts.first) == reference.fetch("sha256")
|
|
74
|
+
raise AttemptErrors::ReceiptRejected, "original canonical artifact descriptor differs"
|
|
75
|
+
end
|
|
76
|
+
proof_options = {request_id: service_request_id, input_digest: input_digest, target: target, head: candidate_head}
|
|
77
|
+
proof = if data.fetch("operation") == "merge"
|
|
78
|
+
Ace::Git::Atoms::ServiceMergeEvidence.validate(fetched.parts.first, **proof_options)
|
|
79
|
+
else
|
|
80
|
+
Ace::Git::Atoms::ServicePrEvidence.validate(fetched.parts.first, operation: data.fetch("operation"), **proof_options)
|
|
81
|
+
end
|
|
82
|
+
unless Atoms::EvidenceDigest.digest(proof.fetch(:input)) == input_digest &&
|
|
83
|
+
(!parameters || Atoms::EvidenceDigest.digest(Atoms::DeliveryParameters.validate(parameters)) == Atoms::EvidenceDigest.digest(proof.fetch(:input).fetch("delivery")))
|
|
84
|
+
raise AttemptErrors::ReceiptRejected, "canonical merge artifact accepted input differs"
|
|
85
|
+
end
|
|
86
|
+
event = data.fetch("delivery_event")
|
|
87
|
+
expected = Authority::ServiceDeliveryEvidence.payload(data, receipt, data.fetch("completion_digest"), proof)
|
|
88
|
+
unless event.is_a?(Hash) && event.keys.sort == %w[attempt_id digest payload previous_digest recorded_at type] &&
|
|
89
|
+
event["type"] == "delivery" && event["attempt_id"] == attempt_id && Models::EvidenceEvent.valid?(event) &&
|
|
90
|
+
Atoms::EvidenceDigest.digest(event.fetch("payload")) == Atoms::EvidenceDigest.digest(expected)
|
|
91
|
+
raise AttemptErrors::ReceiptRejected, "canonical delivery result/completion/import join differs"
|
|
92
|
+
end
|
|
93
|
+
data
|
|
94
|
+
rescue KeyError, TypeError, ArgumentError
|
|
95
|
+
raise AttemptErrors::ReceiptRejected, "protected merge evidence is malformed or unavailable"
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
@@ -21,7 +21,7 @@ module Ace
|
|
|
21
21
|
@executor = executor || AssignmentExecutor.new
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
-
def call(task_refs:, preset_name: DEFAULT_PRESET, primary_task_ref: nil, delivery_parameters: nil)
|
|
24
|
+
def call(task_refs:, preset_name: DEFAULT_PRESET, primary_task_ref: nil, delivery_parameters: nil, project_id: nil)
|
|
25
25
|
requested_refs = normalize_requested_refs(task_refs)
|
|
26
26
|
raise Ace::Support::Cli::Error, "--task requires at least one task reference" if requested_refs.empty?
|
|
27
27
|
|
|
@@ -58,7 +58,9 @@ module Ace
|
|
|
58
58
|
steps: steps, delivery: delivery
|
|
59
59
|
)
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
start_options = {task_id: primary_ref}
|
|
62
|
+
start_options[:project_id] = project_id unless project_id.nil?
|
|
63
|
+
result = @executor.start(job_path, **start_options)
|
|
62
64
|
result.merge(
|
|
63
65
|
skipped_terminal: skipped_terminal,
|
|
64
66
|
primary_ref: primary_ref,
|
data/lib/ace/assign/version.rb
CHANGED
data/lib/ace/assign.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative "assign/version"
|
|
4
|
+
require_relative "assign/errors"
|
|
4
5
|
require "ace/support/config"
|
|
5
6
|
require "ace/support/fs"
|
|
6
7
|
require "ace/support/nav"
|
|
@@ -14,118 +15,6 @@ require_relative "assign/organisms/task_assignment_creator"
|
|
|
14
15
|
|
|
15
16
|
module Ace
|
|
16
17
|
module Assign
|
|
17
|
-
# Base error class for all ace-assign exceptions.
|
|
18
|
-
# Inherits from Ace::Support::Cli::Error to support exception-based
|
|
19
|
-
# exit code pattern (per ADR-023).
|
|
20
|
-
#
|
|
21
|
-
# Subclasses should call super with appropriate exit_code.
|
|
22
|
-
class Error < Ace::Support::Cli::Error
|
|
23
|
-
def initialize(message, exit_code: 1)
|
|
24
|
-
super
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
# Assignment-related errors
|
|
29
|
-
module AssignmentErrors
|
|
30
|
-
class NotFound < Error
|
|
31
|
-
def initialize(message = "Assignment not found")
|
|
32
|
-
super(message, exit_code: 2)
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
class NoActive < Error
|
|
37
|
-
def initialize(message = "No active assignment")
|
|
38
|
-
super(message, exit_code: 2)
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
# Config-related errors
|
|
44
|
-
module ConfigErrors
|
|
45
|
-
class NotFound < Error
|
|
46
|
-
def initialize(message = "Configuration not found")
|
|
47
|
-
super(message, exit_code: 3)
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
# Step-related errors
|
|
53
|
-
module StepErrors
|
|
54
|
-
class NotFound < Error
|
|
55
|
-
def initialize(message = "Step not found")
|
|
56
|
-
super(message, exit_code: 4)
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
class InvalidState < Error; end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
# Attempt/evidence-related errors (exit code 5)
|
|
64
|
-
module AttemptErrors
|
|
65
|
-
class InvalidTransition < Error
|
|
66
|
-
def initialize(message = "Illegal attempt state transition")
|
|
67
|
-
super(message, exit_code: 5)
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
class InvalidScope < Error
|
|
72
|
-
def initialize(message = "Invalid attempt scope")
|
|
73
|
-
super(message, exit_code: 5)
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
# Duplicate start with a conflicting binding for an owned subtree
|
|
78
|
-
class Conflict < Error
|
|
79
|
-
def initialize(message = "Conflicting active attempt for scope")
|
|
80
|
-
super(message, exit_code: 5)
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
class NotFound < Error
|
|
85
|
-
def initialize(message = "Attempt not found")
|
|
86
|
-
super(message, exit_code: 5)
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
# Untrusted or unknown execution identity; authority fails closed
|
|
91
|
-
class UnauthorizedIdentity < Error
|
|
92
|
-
def initialize(message = "Unknown or unauthorized execution identity")
|
|
93
|
-
super(message, exit_code: 5)
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
# Receipt failed verification (binding, head, digest, artifacts, review)
|
|
98
|
-
class ReceiptRejected < Error
|
|
99
|
-
def initialize(message = "Receipt rejected")
|
|
100
|
-
super(message, exit_code: 5)
|
|
101
|
-
end
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
# Byte framing failed before any business receipt could be admitted.
|
|
105
|
-
class MalformedTransfer < ReceiptRejected; end
|
|
106
|
-
|
|
107
|
-
# Recovery settled a prior effect, but did not perform this request.
|
|
108
|
-
class CurrentEffectRequired < ReceiptRejected
|
|
109
|
-
def initialize(operation:, recovered_operation:)
|
|
110
|
-
super("Recovered #{recovered_operation}; requested #{operation} still needs execution")
|
|
111
|
-
end
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
# Attempt state forbids the requested effect (terminal, uncertain, blocked)
|
|
115
|
-
class InvalidState < Error
|
|
116
|
-
def initialize(message = "Attempt state forbids the requested operation")
|
|
117
|
-
super(message, exit_code: 5)
|
|
118
|
-
end
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
# Evidence storage is missing or unwritable; external effects are blocked
|
|
122
|
-
class EvidenceUnavailable < Error
|
|
123
|
-
def initialize(message = "Evidence storage unavailable")
|
|
124
|
-
super(message, exit_code: 5)
|
|
125
|
-
end
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
|
|
129
18
|
# Define module namespaces
|
|
130
19
|
module Commands; end
|
|
131
20
|
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ace-assign
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.66.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Michal Czyz
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-10-
|
|
10
|
+
date: 2026-10-08 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: ace-llm-providers-cli
|
|
@@ -43,14 +43,14 @@ dependencies:
|
|
|
43
43
|
requirements:
|
|
44
44
|
- - "~>"
|
|
45
45
|
- !ruby/object:Gem::Version
|
|
46
|
-
version: '0.
|
|
46
|
+
version: '0.30'
|
|
47
47
|
type: :runtime
|
|
48
48
|
prerelease: false
|
|
49
49
|
version_requirements: !ruby/object:Gem::Requirement
|
|
50
50
|
requirements:
|
|
51
51
|
- - "~>"
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
|
-
version: '0.
|
|
53
|
+
version: '0.30'
|
|
54
54
|
- !ruby/object:Gem::Dependency
|
|
55
55
|
name: json
|
|
56
56
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -175,14 +175,14 @@ dependencies:
|
|
|
175
175
|
requirements:
|
|
176
176
|
- - "~>"
|
|
177
177
|
- !ruby/object:Gem::Version
|
|
178
|
-
version: '0.
|
|
178
|
+
version: '0.60'
|
|
179
179
|
type: :runtime
|
|
180
180
|
prerelease: false
|
|
181
181
|
version_requirements: !ruby/object:Gem::Requirement
|
|
182
182
|
requirements:
|
|
183
183
|
- - "~>"
|
|
184
184
|
- !ruby/object:Gem::Version
|
|
185
|
-
version: '0.
|
|
185
|
+
version: '0.60'
|
|
186
186
|
- !ruby/object:Gem::Dependency
|
|
187
187
|
name: ace-task
|
|
188
188
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -197,6 +197,20 @@ dependencies:
|
|
|
197
197
|
- - "~>"
|
|
198
198
|
- !ruby/object:Gem::Version
|
|
199
199
|
version: '0.37'
|
|
200
|
+
- !ruby/object:Gem::Dependency
|
|
201
|
+
name: ace-bundle
|
|
202
|
+
requirement: !ruby/object:Gem::Requirement
|
|
203
|
+
requirements:
|
|
204
|
+
- - "~>"
|
|
205
|
+
- !ruby/object:Gem::Version
|
|
206
|
+
version: '0.44'
|
|
207
|
+
type: :runtime
|
|
208
|
+
prerelease: false
|
|
209
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
210
|
+
requirements:
|
|
211
|
+
- - "~>"
|
|
212
|
+
- !ruby/object:Gem::Version
|
|
213
|
+
version: '0.44'
|
|
200
214
|
- !ruby/object:Gem::Dependency
|
|
201
215
|
name: ace-runtime
|
|
202
216
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -231,14 +245,14 @@ dependencies:
|
|
|
231
245
|
requirements:
|
|
232
246
|
- - "~>"
|
|
233
247
|
- !ruby/object:Gem::Version
|
|
234
|
-
version: '0.
|
|
248
|
+
version: '0.5'
|
|
235
249
|
type: :runtime
|
|
236
250
|
prerelease: false
|
|
237
251
|
version_requirements: !ruby/object:Gem::Requirement
|
|
238
252
|
requirements:
|
|
239
253
|
- - "~>"
|
|
240
254
|
- !ruby/object:Gem::Version
|
|
241
|
-
version: '0.
|
|
255
|
+
version: '0.5'
|
|
242
256
|
- !ruby/object:Gem::Dependency
|
|
243
257
|
name: ace-support-test-helpers
|
|
244
258
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -288,6 +302,7 @@ email:
|
|
|
288
302
|
- mc@cs3b.com
|
|
289
303
|
executables:
|
|
290
304
|
- ace-assign
|
|
305
|
+
- ace-scope-ready
|
|
291
306
|
extensions: []
|
|
292
307
|
extra_rdoc_files: []
|
|
293
308
|
files:
|
|
@@ -299,6 +314,7 @@ files:
|
|
|
299
314
|
- ".ace-defaults/assign/catalog/recipes/implement-with-pr.recipe.yml"
|
|
300
315
|
- ".ace-defaults/assign/catalog/recipes/release-only.recipe.yml"
|
|
301
316
|
- ".ace-defaults/assign/catalog/steps/apply-feedback.step.yml"
|
|
317
|
+
- ".ace-defaults/assign/catalog/steps/auto-merge.step.yml"
|
|
302
318
|
- ".ace-defaults/assign/catalog/steps/commit.step.yml"
|
|
303
319
|
- ".ace-defaults/assign/catalog/steps/create-pr.step.yml"
|
|
304
320
|
- ".ace-defaults/assign/catalog/steps/create-retro.step.yml"
|
|
@@ -354,6 +370,7 @@ files:
|
|
|
354
370
|
- docs/protected-authority.md
|
|
355
371
|
- docs/usage.md
|
|
356
372
|
- exe/ace-assign
|
|
373
|
+
- exe/ace-scope-ready
|
|
357
374
|
- handbook/guides/fork-context.g.md
|
|
358
375
|
- handbook/skills/as-assign-add-task/SKILL.md
|
|
359
376
|
- handbook/skills/as-assign-compose/SKILL.md
|
|
@@ -396,28 +413,67 @@ files:
|
|
|
396
413
|
- lib/ace/assign/atoms/step_numbering.rb
|
|
397
414
|
- lib/ace/assign/atoms/step_sorter.rb
|
|
398
415
|
- lib/ace/assign/atoms/tree_formatter.rb
|
|
416
|
+
- lib/ace/assign/authority/assignment_inventory.rb
|
|
417
|
+
- lib/ace/assign/authority/campaign_consumer_policy.rb
|
|
418
|
+
- lib/ace/assign/authority/campaign_execution.rb
|
|
419
|
+
- lib/ace/assign/authority/campaign_round_transfer.rb
|
|
399
420
|
- lib/ace/assign/authority/candidate_transfer.rb
|
|
421
|
+
- lib/ace/assign/authority/cleanup_result_protection.rb
|
|
400
422
|
- lib/ace/assign/authority/client.rb
|
|
401
423
|
- lib/ace/assign/authority/deployment.rb
|
|
424
|
+
- lib/ace/assign/authority/deployment_history.rb
|
|
402
425
|
- lib/ace/assign/authority/endcap.rb
|
|
426
|
+
- lib/ace/assign/authority/endcap_attempts.rb
|
|
427
|
+
- lib/ace/assign/authority/endcap_campaign_results.rb
|
|
428
|
+
- lib/ace/assign/authority/endcap_campaign_rounds.rb
|
|
429
|
+
- lib/ace/assign/authority/endcap_contexts.rb
|
|
403
430
|
- lib/ace/assign/authority/endcap_inboxes.rb
|
|
431
|
+
- lib/ace/assign/authority/endcap_prepared_work.rb
|
|
432
|
+
- lib/ace/assign/authority/endcap_publication.rb
|
|
404
433
|
- lib/ace/assign/authority/endcap_results.rb
|
|
434
|
+
- lib/ace/assign/authority/endcap_review_requests.rb
|
|
435
|
+
- lib/ace/assign/authority/endcap_reviews.rb
|
|
436
|
+
- lib/ace/assign/authority/endcap_service_settlement.rb
|
|
405
437
|
- lib/ace/assign/authority/endcap_services.rb
|
|
406
438
|
- lib/ace/assign/authority/evidence_transfer.rb
|
|
407
439
|
- lib/ace/assign/authority/execution_scope_observation.rb
|
|
440
|
+
- lib/ace/assign/authority/inbox_context_original.rb
|
|
441
|
+
- lib/ace/assign/authority/launch_attempt_consumers.rb
|
|
442
|
+
- lib/ace/assign/authority/launch_campaign_registration.rb
|
|
443
|
+
- lib/ace/assign/authority/launch_control_channel.rb
|
|
444
|
+
- lib/ace/assign/authority/launch_control_exclusions.rb
|
|
408
445
|
- lib/ace/assign/authority/launch_driver.rb
|
|
446
|
+
- lib/ace/assign/authority/launch_input_inhibition.rb
|
|
409
447
|
- lib/ace/assign/authority/launch_lifecycle.rb
|
|
448
|
+
- lib/ace/assign/authority/launch_prepared_work.rb
|
|
449
|
+
- lib/ace/assign/authority/launch_review.rb
|
|
410
450
|
- lib/ace/assign/authority/launch_scope_abort.rb
|
|
411
451
|
- lib/ace/assign/authority/launch_scope_admission.rb
|
|
412
452
|
- lib/ace/assign/authority/launch_scope_close.rb
|
|
413
453
|
- lib/ace/assign/authority/launch_scope_parent.rb
|
|
414
454
|
- lib/ace/assign/authority/launch_scope_release.rb
|
|
455
|
+
- lib/ace/assign/authority/launch_steering.rb
|
|
456
|
+
- lib/ace/assign/authority/launch_stop.rb
|
|
457
|
+
- lib/ace/assign/authority/maintenance_workspace_retirement.rb
|
|
458
|
+
- lib/ace/assign/authority/original_inbox_selection.rb
|
|
415
459
|
- lib/ace/assign/authority/posix_acl.rb
|
|
460
|
+
- lib/ace/assign/authority/prepared_input.rb
|
|
461
|
+
- lib/ace/assign/authority/prepared_queue.rb
|
|
462
|
+
- lib/ace/assign/authority/prepared_task_context.rb
|
|
463
|
+
- lib/ace/assign/authority/prepared_work.rb
|
|
464
|
+
- lib/ace/assign/authority/prepared_worker.rb
|
|
416
465
|
- lib/ace/assign/authority/private_directory.rb
|
|
466
|
+
- lib/ace/assign/authority/protected_assignment_context.rb
|
|
467
|
+
- lib/ace/assign/authority/readiness_hook.rb
|
|
417
468
|
- lib/ace/assign/authority/receipt_transfer.rb
|
|
418
469
|
- lib/ace/assign/authority/router.rb
|
|
419
470
|
- lib/ace/assign/authority/server.rb
|
|
471
|
+
- lib/ace/assign/authority/service_cleanup_dispatch.rb
|
|
472
|
+
- lib/ace/assign/authority/service_cleanup_evidence.rb
|
|
473
|
+
- lib/ace/assign/authority/service_delivery_evidence.rb
|
|
420
474
|
- lib/ace/assign/authority/service_evidence.rb
|
|
475
|
+
- lib/ace/assign/authority/service_publication_evidence.rb
|
|
476
|
+
- lib/ace/assign/authority/task_context_entry.rb
|
|
421
477
|
- lib/ace/assign/authority/transfer_codec.rb
|
|
422
478
|
- lib/ace/assign/cli.rb
|
|
423
479
|
- lib/ace/assign/cli/commands/add.rb
|
|
@@ -428,24 +484,36 @@ files:
|
|
|
428
484
|
- lib/ace/assign/cli/commands/attempt/reconcile.rb
|
|
429
485
|
- lib/ace/assign/cli/commands/attempt/start.rb
|
|
430
486
|
- lib/ace/assign/cli/commands/attempt/status.rb
|
|
487
|
+
- lib/ace/assign/cli/commands/authority/inbox_context_principal.rb
|
|
488
|
+
- lib/ace/assign/cli/commands/authority/inbox_context_selection.rb
|
|
431
489
|
- lib/ace/assign/cli/commands/authority/launch.rb
|
|
432
490
|
- lib/ace/assign/cli/commands/authority/serve.rb
|
|
433
491
|
- lib/ace/assign/cli/commands/authority/status.rb
|
|
492
|
+
- lib/ace/assign/cli/commands/authority/task_context.rb
|
|
493
|
+
- lib/ace/assign/cli/commands/authority/task_context_principal.rb
|
|
494
|
+
- lib/ace/assign/cli/commands/authority/task_context_selection.rb
|
|
434
495
|
- lib/ace/assign/cli/commands/authority/terminate.rb
|
|
496
|
+
- lib/ace/assign/cli/commands/authority/worker.rb
|
|
497
|
+
- lib/ace/assign/cli/commands/campaign_export_result.rb
|
|
498
|
+
- lib/ace/assign/cli/commands/campaign_record_round.rb
|
|
435
499
|
- lib/ace/assign/cli/commands/create.rb
|
|
436
500
|
- lib/ace/assign/cli/commands/delivery.rb
|
|
437
501
|
- lib/ace/assign/cli/commands/fail.rb
|
|
438
502
|
- lib/ace/assign/cli/commands/finish.rb
|
|
439
503
|
- lib/ace/assign/cli/commands/fork_run.rb
|
|
440
504
|
- lib/ace/assign/cli/commands/fork_session.rb
|
|
441
|
-
- lib/ace/assign/cli/commands/
|
|
505
|
+
- lib/ace/assign/cli/commands/inbox_bind.rb
|
|
442
506
|
- lib/ace/assign/cli/commands/list.rb
|
|
507
|
+
- lib/ace/assign/cli/commands/protected_submission.rb
|
|
443
508
|
- lib/ace/assign/cli/commands/resume.rb
|
|
444
509
|
- lib/ace/assign/cli/commands/retry_cmd.rb
|
|
445
510
|
- lib/ace/assign/cli/commands/select.rb
|
|
446
511
|
- lib/ace/assign/cli/commands/start.rb
|
|
447
512
|
- lib/ace/assign/cli/commands/status.rb
|
|
448
513
|
- lib/ace/assign/cli/commands/step.rb
|
|
514
|
+
- lib/ace/assign/cli/commands/submit_candidate.rb
|
|
515
|
+
- lib/ace/assign/cli/commands/submit_result.rb
|
|
516
|
+
- lib/ace/assign/errors.rb
|
|
449
517
|
- lib/ace/assign/models/assignment.rb
|
|
450
518
|
- lib/ace/assign/models/assignment_info.rb
|
|
451
519
|
- lib/ace/assign/models/attempt.rb
|
|
@@ -458,25 +526,36 @@ files:
|
|
|
458
526
|
- lib/ace/assign/molecules/assignment_manager.rb
|
|
459
527
|
- lib/ace/assign/molecules/attempt_reconciler.rb
|
|
460
528
|
- lib/ace/assign/molecules/attempt_store.rb
|
|
529
|
+
- lib/ace/assign/molecules/canonical_attempt_state.rb
|
|
461
530
|
- lib/ace/assign/molecules/canonical_evidence.rb
|
|
531
|
+
- lib/ace/assign/molecules/canonical_read_snapshot.rb
|
|
462
532
|
- lib/ace/assign/molecules/evidence_calculator.rb
|
|
463
533
|
- lib/ace/assign/molecules/evidence_journal.rb
|
|
464
534
|
- lib/ace/assign/molecules/execution_identity_resolver.rb
|
|
465
535
|
- lib/ace/assign/molecules/execution_scope_lineage.rb
|
|
466
536
|
- lib/ace/assign/molecules/fork_session_launcher.rb
|
|
537
|
+
- lib/ace/assign/molecules/journal_input_inhibition.rb
|
|
467
538
|
- lib/ace/assign/molecules/journal_mutation.rb
|
|
539
|
+
- lib/ace/assign/molecules/journal_prompt_mutation.rb
|
|
468
540
|
- lib/ace/assign/molecules/lifecycle_exclusion.rb
|
|
541
|
+
- lib/ace/assign/molecules/original_launch_binding.rb
|
|
469
542
|
- lib/ace/assign/molecules/preset_inferrer.rb
|
|
470
543
|
- lib/ace/assign/molecules/proposal_journal.rb
|
|
544
|
+
- lib/ace/assign/molecules/protected_control_exclusion.rb
|
|
545
|
+
- lib/ace/assign/molecules/protected_workspace_exclusion.rb
|
|
546
|
+
- lib/ace/assign/molecules/protected_workspace_provisioner.rb
|
|
471
547
|
- lib/ace/assign/molecules/queue_scanner.rb
|
|
472
548
|
- lib/ace/assign/molecules/receipt_verifier.rb
|
|
473
549
|
- lib/ace/assign/molecules/runtime_control_surface_runner.rb
|
|
474
550
|
- lib/ace/assign/molecules/skill_assign_source_resolver.rb
|
|
475
551
|
- lib/ace/assign/molecules/step_renumberer.rb
|
|
476
552
|
- lib/ace/assign/molecules/step_writer.rb
|
|
553
|
+
- lib/ace/assign/molecules/terminal_scope_receipt.rb
|
|
477
554
|
- lib/ace/assign/organisms/assignment_executor.rb
|
|
478
555
|
- lib/ace/assign/organisms/attempt_coordinator.rb
|
|
479
556
|
- lib/ace/assign/organisms/delivery_coordinator.rb
|
|
557
|
+
- lib/ace/assign/organisms/prepared_work_builder.rb
|
|
558
|
+
- lib/ace/assign/organisms/protected_delivery_coordinator.rb
|
|
480
559
|
- lib/ace/assign/organisms/task_assignment_creator.rb
|
|
481
560
|
- lib/ace/assign/version.rb
|
|
482
561
|
homepage: https://github.com/cs3b/ace
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Ace
|
|
4
|
-
module Assign
|
|
5
|
-
module CLI
|
|
6
|
-
module Commands
|
|
7
|
-
class InboxReconcile < Ace::Support::Cli::Command
|
|
8
|
-
include Ace::Support::Cli::Base
|
|
9
|
-
desc "Verify a Herdr inbox proof and record its references in the assignment journal"
|
|
10
|
-
option :attempt, desc: "Exact attempt ID"
|
|
11
|
-
option :event, desc: "Herdr inbox event ID"
|
|
12
|
-
option :receipt, desc: "Existing native receipt JSON file with detached FILE.sig"
|
|
13
|
-
|
|
14
|
-
def initialize(coordinator: nil, inbox: nil)
|
|
15
|
-
super()
|
|
16
|
-
@coordinator = coordinator
|
|
17
|
-
@inbox = inbox
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def call(**options)
|
|
21
|
-
%i[attempt event receipt].each do |key|
|
|
22
|
-
raise Ace::Support::Cli::Error, "--#{key} is required" if options[key].to_s.strip.empty?
|
|
23
|
-
end
|
|
24
|
-
result = (@coordinator || Organisms::AttemptCoordinator.new).reconcile_inbox(
|
|
25
|
-
attempt_id: options[:attempt], event_id: options[:event], receipt_path: options[:receipt],
|
|
26
|
-
inbox: @inbox || Ace::Herdr::Organisms::Inbox.from_config)
|
|
27
|
-
# Keep the public projection bounded; raw native output and the
|
|
28
|
-
# human observation text belong to the existing receipt file.
|
|
29
|
-
puts JSON.generate(result.slice("event_id", "attempt_id", "state", "claim_generation",
|
|
30
|
-
"receipt_key_sha256", "reconciliation_refusal"))
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
end
|