ace-assign 0.71.0 → 0.73.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (195) 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 -2119
  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/organisms/assignment_executor.rb +0 -6
  35. data/lib/ace/assign/organisms/task_assignment_creator.rb +3 -8
  36. data/lib/ace/assign/version.rb +1 -1
  37. data/lib/ace/assign.rb +0 -6
  38. metadata +4 -176
  39. data/.ace-defaults/assign/presets/close-delivery.yml +0 -57
  40. data/.ace-defaults/assign/presets/deliver-release.yml +0 -60
  41. data/.ace-defaults/assign/presets/integrate-batch.yml +0 -72
  42. data/.ace-defaults/assign/presets/supervise-delivery.yml +0 -69
  43. data/docs/protected-authority.md +0 -282
  44. data/exe/ace-scope-ready +0 -55
  45. data/lib/ace/assign/atoms/assignment_scope.rb +0 -58
  46. data/lib/ace/assign/atoms/attempt_state_machine.rb +0 -84
  47. data/lib/ace/assign/atoms/candidate_limits.rb +0 -20
  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/atoms/git_blob_batch.rb +0 -59
  52. data/lib/ace/assign/authority/assignment_definition.rb +0 -35
  53. data/lib/ace/assign/authority/assignment_inventory.rb +0 -290
  54. data/lib/ace/assign/authority/campaign_consumer_policy.rb +0 -100
  55. data/lib/ace/assign/authority/campaign_execution.rb +0 -119
  56. data/lib/ace/assign/authority/campaign_round_transfer.rb +0 -82
  57. data/lib/ace/assign/authority/candidate_blob_batch.rb +0 -55
  58. data/lib/ace/assign/authority/candidate_head_comparison.rb +0 -139
  59. data/lib/ace/assign/authority/candidate_transfer.rb +0 -357
  60. data/lib/ace/assign/authority/cleanup_result_protection.rb +0 -53
  61. data/lib/ace/assign/authority/client.rb +0 -257
  62. data/lib/ace/assign/authority/command_execution.rb +0 -180
  63. data/lib/ace/assign/authority/deployment.rb +0 -627
  64. data/lib/ace/assign/authority/deployment_history.rb +0 -146
  65. data/lib/ace/assign/authority/endcap.rb +0 -457
  66. data/lib/ace/assign/authority/endcap_attempts.rb +0 -274
  67. data/lib/ace/assign/authority/endcap_campaign_results.rb +0 -232
  68. data/lib/ace/assign/authority/endcap_campaign_rounds.rb +0 -266
  69. data/lib/ace/assign/authority/endcap_contexts.rb +0 -23
  70. data/lib/ace/assign/authority/endcap_inboxes.rb +0 -37
  71. data/lib/ace/assign/authority/endcap_prepared_work.rb +0 -80
  72. data/lib/ace/assign/authority/endcap_publication.rb +0 -41
  73. data/lib/ace/assign/authority/endcap_results.rb +0 -398
  74. data/lib/ace/assign/authority/endcap_review_requests.rb +0 -183
  75. data/lib/ace/assign/authority/endcap_reviews.rb +0 -130
  76. data/lib/ace/assign/authority/endcap_service_context.rb +0 -38
  77. data/lib/ace/assign/authority/endcap_service_settlement.rb +0 -152
  78. data/lib/ace/assign/authority/evidence_transfer.rb +0 -67
  79. data/lib/ace/assign/authority/execution_scope_observation.rb +0 -903
  80. data/lib/ace/assign/authority/fixed_publication_lifecycle.rb +0 -176
  81. data/lib/ace/assign/authority/fixed_service_lifecycle.rb +0 -594
  82. data/lib/ace/assign/authority/inbox_context_original.rb +0 -113
  83. data/lib/ace/assign/authority/launch_attempt_consumers.rb +0 -51
  84. data/lib/ace/assign/authority/launch_campaign_registration.rb +0 -214
  85. data/lib/ace/assign/authority/launch_control_channel.rb +0 -313
  86. data/lib/ace/assign/authority/launch_control_exclusions.rb +0 -127
  87. data/lib/ace/assign/authority/launch_driver.rb +0 -393
  88. data/lib/ace/assign/authority/launch_input_inhibition.rb +0 -132
  89. data/lib/ace/assign/authority/launch_lifecycle.rb +0 -997
  90. data/lib/ace/assign/authority/launch_prepared_work.rb +0 -122
  91. data/lib/ace/assign/authority/launch_review.rb +0 -91
  92. data/lib/ace/assign/authority/launch_scope_abort.rb +0 -81
  93. data/lib/ace/assign/authority/launch_scope_admission.rb +0 -215
  94. data/lib/ace/assign/authority/launch_scope_close.rb +0 -146
  95. data/lib/ace/assign/authority/launch_scope_parent.rb +0 -44
  96. data/lib/ace/assign/authority/launch_scope_release.rb +0 -859
  97. data/lib/ace/assign/authority/launch_steering.rb +0 -353
  98. data/lib/ace/assign/authority/launch_stop.rb +0 -254
  99. data/lib/ace/assign/authority/maintenance_workspace_retirement.rb +0 -229
  100. data/lib/ace/assign/authority/ordinary_attempt_start.rb +0 -137
  101. data/lib/ace/assign/authority/ordinary_client.rb +0 -70
  102. data/lib/ace/assign/authority/ordinary_completion.rb +0 -104
  103. data/lib/ace/assign/authority/ordinary_effect_settlement.rb +0 -118
  104. data/lib/ace/assign/authority/ordinary_lifecycle.rb +0 -227
  105. data/lib/ace/assign/authority/ordinary_merge_evidence.rb +0 -81
  106. data/lib/ace/assign/authority/ordinary_peer.rb +0 -54
  107. data/lib/ace/assign/authority/ordinary_progress.rb +0 -162
  108. data/lib/ace/assign/authority/ordinary_queue.rb +0 -115
  109. data/lib/ace/assign/authority/ordinary_release_artifacts.rb +0 -143
  110. data/lib/ace/assign/authority/ordinary_results.rb +0 -206
  111. data/lib/ace/assign/authority/ordinary_review_evidence.rb +0 -180
  112. data/lib/ace/assign/authority/ordinary_reviews.rb +0 -214
  113. data/lib/ace/assign/authority/ordinary_server.rb +0 -75
  114. data/lib/ace/assign/authority/ordinary_supervisor.rb +0 -99
  115. data/lib/ace/assign/authority/original_inbox_selection.rb +0 -41
  116. data/lib/ace/assign/authority/posix_acl.rb +0 -59
  117. data/lib/ace/assign/authority/prepared_input.rb +0 -130
  118. data/lib/ace/assign/authority/prepared_queue.rb +0 -185
  119. data/lib/ace/assign/authority/prepared_task_context.rb +0 -116
  120. data/lib/ace/assign/authority/prepared_work.rb +0 -309
  121. data/lib/ace/assign/authority/prepared_worker.rb +0 -69
  122. data/lib/ace/assign/authority/private_directory.rb +0 -33
  123. data/lib/ace/assign/authority/protected_assignment_context.rb +0 -226
  124. data/lib/ace/assign/authority/readiness_hook.rb +0 -120
  125. data/lib/ace/assign/authority/receipt_transfer.rb +0 -48
  126. data/lib/ace/assign/authority/release_artifact_manifest.rb +0 -91
  127. data/lib/ace/assign/authority/retained_input.rb +0 -53
  128. data/lib/ace/assign/authority/router.rb +0 -81
  129. data/lib/ace/assign/authority/server.rb +0 -131
  130. data/lib/ace/assign/authority/service_cleanup_dispatch.rb +0 -88
  131. data/lib/ace/assign/authority/service_cleanup_evidence.rb +0 -180
  132. data/lib/ace/assign/authority/service_delivery_evidence.rb +0 -101
  133. data/lib/ace/assign/authority/service_evidence.rb +0 -286
  134. data/lib/ace/assign/authority/service_publication_evidence.rb +0 -110
  135. data/lib/ace/assign/authority/socket_server.rb +0 -255
  136. data/lib/ace/assign/authority/task_context_entry.rb +0 -32
  137. data/lib/ace/assign/authority/transfer_codec.rb +0 -189
  138. data/lib/ace/assign/cli/commands/attempt/base.rb +0 -84
  139. data/lib/ace/assign/cli/commands/attempt/evidence.rb +0 -28
  140. data/lib/ace/assign/cli/commands/attempt/finish.rb +0 -51
  141. data/lib/ace/assign/cli/commands/attempt/reconcile.rb +0 -49
  142. data/lib/ace/assign/cli/commands/attempt/start.rb +0 -45
  143. data/lib/ace/assign/cli/commands/attempt/status.rb +0 -54
  144. data/lib/ace/assign/cli/commands/authority/inbox_context_principal.rb +0 -25
  145. data/lib/ace/assign/cli/commands/authority/inbox_context_selection.rb +0 -28
  146. data/lib/ace/assign/cli/commands/authority/launch.rb +0 -97
  147. data/lib/ace/assign/cli/commands/authority/serve.rb +0 -31
  148. data/lib/ace/assign/cli/commands/authority/status.rb +0 -26
  149. data/lib/ace/assign/cli/commands/authority/task_context.rb +0 -31
  150. data/lib/ace/assign/cli/commands/authority/task_context_principal.rb +0 -25
  151. data/lib/ace/assign/cli/commands/authority/task_context_selection.rb +0 -30
  152. data/lib/ace/assign/cli/commands/authority/terminate.rb +0 -29
  153. data/lib/ace/assign/cli/commands/authority/worker.rb +0 -23
  154. data/lib/ace/assign/cli/commands/campaign_export_result.rb +0 -55
  155. data/lib/ace/assign/cli/commands/campaign_record_round.rb +0 -57
  156. data/lib/ace/assign/cli/commands/delivery.rb +0 -107
  157. data/lib/ace/assign/cli/commands/inbox_bind.rb +0 -34
  158. data/lib/ace/assign/cli/commands/protected_submission.rb +0 -61
  159. data/lib/ace/assign/cli/commands/resume.rb +0 -38
  160. data/lib/ace/assign/cli/commands/submit_candidate.rb +0 -34
  161. data/lib/ace/assign/cli/commands/submit_result.rb +0 -61
  162. data/lib/ace/assign/models/attempt.rb +0 -178
  163. data/lib/ace/assign/models/attempt_binding.rb +0 -116
  164. data/lib/ace/assign/models/evidence_event.rb +0 -86
  165. data/lib/ace/assign/models/execution_receipt.rb +0 -139
  166. data/lib/ace/assign/molecules/attempt_reconciler.rb +0 -127
  167. data/lib/ace/assign/molecules/attempt_store.rb +0 -201
  168. data/lib/ace/assign/molecules/canonical_attempt_state.rb +0 -151
  169. data/lib/ace/assign/molecules/canonical_evidence.rb +0 -170
  170. data/lib/ace/assign/molecules/canonical_read_commands.rb +0 -84
  171. data/lib/ace/assign/molecules/canonical_read_snapshot.rb +0 -313
  172. data/lib/ace/assign/molecules/evidence_calculator.rb +0 -237
  173. data/lib/ace/assign/molecules/evidence_journal.rb +0 -1899
  174. data/lib/ace/assign/molecules/execution_identity_resolver.rb +0 -137
  175. data/lib/ace/assign/molecules/execution_scope_lineage.rb +0 -345
  176. data/lib/ace/assign/molecules/fixed_effect_reference.rb +0 -31
  177. data/lib/ace/assign/molecules/installed_journal_read.rb +0 -143
  178. data/lib/ace/assign/molecules/journal_input_inhibition.rb +0 -78
  179. data/lib/ace/assign/molecules/journal_mutation.rb +0 -274
  180. data/lib/ace/assign/molecules/journal_prompt_mutation.rb +0 -241
  181. data/lib/ace/assign/molecules/ordinary_merge_cli.rb +0 -68
  182. data/lib/ace/assign/molecules/ordinary_merge_contract.rb +0 -410
  183. data/lib/ace/assign/molecules/original_launch_binding.rb +0 -37
  184. data/lib/ace/assign/molecules/proposal_journal.rb +0 -179
  185. data/lib/ace/assign/molecules/protected_control_exclusion.rb +0 -303
  186. data/lib/ace/assign/molecules/protected_workspace_exclusion.rb +0 -330
  187. data/lib/ace/assign/molecules/protected_workspace_provisioner.rb +0 -164
  188. data/lib/ace/assign/molecules/receipt_verifier.rb +0 -320
  189. data/lib/ace/assign/molecules/terminal_scope_receipt.rb +0 -88
  190. data/lib/ace/assign/organisms/attempt_coordinator.rb +0 -1374
  191. data/lib/ace/assign/organisms/delivery_coordinator.rb +0 -342
  192. data/lib/ace/assign/organisms/ordinary_driver.rb +0 -310
  193. data/lib/ace/assign/organisms/ordinary_merge_consumer.rb +0 -365
  194. data/lib/ace/assign/organisms/prepared_work_builder.rb +0 -194
  195. data/lib/ace/assign/organisms/protected_delivery_coordinator.rb +0 -100
@@ -1,146 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Ace
4
- module Assign
5
- module Authority
6
- class LaunchLifecycle
7
- # Source-owned close core. Its first accepted mutation seals admission
8
- # and caches the retained running reply before any manager stop. A
9
- # subsequent fresh mutation may record positive observation; replay of
10
- # the first mutation always keeps its original reply and performs no I/O.
11
- def close_execution_scope!(params:, peer:, role:)
12
- strict!(params, %w[mapping_id assignment_id attempt_id mutation_id expected_generation])
13
- %w[assignment_id attempt_id mutation_id].each { |key| token!(params.fetch(key)) }
14
- generation!(params.fetch("expected_generation"))
15
- @kernel.live!(peer)
16
- map = @deployment.mapping(params.fetch("mapping_id"))
17
- journal = journal_for(map)
18
- input = params.reject { |key, _| key == "mutation_id" }
19
- digest = Digest::SHA256.hexdigest(JSON.generate(canonical(input)))
20
- stop_after_commit = false
21
- inhibit_after_commit = false
22
- result = with_containment_exclusion(params, map, journal) do
23
- result = @mutex.synchronize do
24
- current = journal.read_events(params.fetch("assignment_id")).select { |event| event["attempt_id"] == params.fetch("attempt_id") }
25
- scope_close_owner!(params, map, current, peer, role)
26
- journal.mutate(assignment_id: params.fetch("assignment_id"), attempt_id: params.fetch("attempt_id"),
27
- mutation_id: params.fetch("mutation_id"), operation: "close_execution_scope", parameters_digest: digest,
28
- expected_generation: params.fetch("expected_generation"), with_replay: true) do |events, _commit, _generation|
29
- lineage = scope_close_owner!(params, map, events, peer, role)
30
- closure = scope_closure_plan!(lineage: lineage, params: params, map: map, events: events, journal: journal, commit: _commit)
31
- stop_after_commit = closure.fetch(:stop_required)
32
- inhibit_after_commit = closure.fetch(:inhibit_required)
33
- closure.fetch(:plan)
34
- end
35
- end
36
- result
37
- end
38
- if !result.fetch(:replayed) && inhibit_after_commit
39
- request_original_input_inhibition!(params, map, journal)
40
- end
41
- if !result.fetch(:replayed) && stop_after_commit
42
- with_containment_exclusion(params, map, journal) do
43
- @mutex.synchronize do
44
- current = journal.read_events(params.fetch("assignment_id")).select { |event| event["attempt_id"] == params.fetch("attempt_id") }
45
- scope_close_owner!(params, map, current, peer, role)
46
- end
47
- scope_observer_for(params.fetch("mapping_id")).stop_sealed_service!
48
- end
49
- end
50
- result
51
- end
52
-
53
- def observe_execution_scope!(params:, peer:, role:)
54
- strict!(params, %w[mapping_id assignment_id attempt_id])
55
- %w[assignment_id attempt_id].each { |key| token!(params.fetch(key)) }
56
- @kernel.live!(peer)
57
- map = @deployment.mapping(params.fetch("mapping_id"))
58
- journal = journal_for(map)
59
- with_containment_exclusion(params, map, journal) do
60
- @mutex.synchronize do
61
- commit = journal.ref_value
62
- events = journal.read_events(params.fetch("assignment_id"), commit: commit).select { |event| event["attempt_id"] == params.fetch("attempt_id") }
63
- lineage = scope_close_owner!(params, map, events, peer, role)
64
- projection = {"attempt_id" => params.fetch("attempt_id"), "scope_generation" => lineage.binding&.fetch("scope_generation"),
65
- "state" => "unverifiable", "proof_id" => nil, "required_action" => "inspect_exact_scope",
66
- "generation" => journal.authority_generation(events), "journal_commit" => commit}
67
- return projection unless lineage.binding
68
- begin
69
- observation = scope_observer_for(params.fetch("mapping_id")).observe(lineage)
70
- if pending_prompt_issuers?(events, journal, commit)
71
- projection.merge("required_action" => "drain_original_prompt_issuer")
72
- elsif lineage.proof_event
73
- scope_observer_for(params.fetch("mapping_id")).verify_closed!(lineage)
74
- projection.merge("state" => "closed_no_writers", "proof_id" => lineage.proof_id, "required_action" => nil)
75
- elsif lineage.sealed? && observation.fetch("populated").zero?
76
- projection.merge("required_action" => "close_scope")
77
- else
78
- projection.merge("state" => "running", "required_action" => "close_scope")
79
- end
80
- rescue Ace::Runtime::RuntimeUnavailableError, AttemptErrors::EvidenceUnavailable
81
- projection
82
- end
83
- end
84
- end
85
- end
86
-
87
- private
88
-
89
- # Shared source-only plan for close and public stop. It does not issue
90
- # manager/native control, mutate canonical state or acquire exclusions.
91
- # Each CAS invocation derives its own post-commit work flags anew.
92
- def scope_closure_plan!(lineage:, params:, map:, events:, journal:, commit:)
93
- stop_required = false
94
- inhibit_required = false
95
- binding = lineage.binding
96
- raise AttemptErrors::EvidenceUnavailable, "original parent binding is missing" unless binding
97
- projection = {"attempt_id" => params.fetch("attempt_id"), "scope_generation" => binding.fetch("scope_generation"),
98
- "state" => "running", "proof_id" => nil, "required_action" => "close_scope"}
99
- plan = if !lineage.sealed?
100
- stop_required = true
101
- inhibit_required = true
102
- payload = {"scope_generation" => binding.fetch("scope_generation"), "scope_binding_event_id" => lineage.binding_event.fetch("digest")}
103
- {events: [{type: "scope_sealed", payload: payload}], blobs: {}, data: projection}
104
- elsif @native_issuers.key?(native_issuer_key(params, map)) || pending_prompt_issuers?(events, journal, commit)
105
- # A live issuer may still start after this inactive snapshot.
106
- inhibit_required = true
107
- {events: [], blobs: {}, data: projection}
108
- elsif lineage.proof_event
109
- scope_observer_for(params.fetch("mapping_id")).verify_closed!(lineage)
110
- {events: [], blobs: {}, data: projection.merge("state" => "closed_no_writers", "proof_id" => lineage.proof_id, "required_action" => nil)}
111
- elsif scope_observer_for(params.fetch("mapping_id")).sealed_service_stop_required?(lineage)
112
- # A fresh canonical close resumes a stop lost after the seal.
113
- # Replaying either mutation performs no manager I/O.
114
- stop_required = true
115
- {events: [], blobs: {}, data: projection}
116
- else
117
- # This call must return a fresh validated observation, never
118
- # a cached population, caller JSON or a manifest boolean.
119
- payload = scope_observer_for(params.fetch("mapping_id")).closed_observation_for_proof!(lineage, events: events)
120
- expected = binding.slice("scope_generation", "boot_id", "slice_invocation_id", "cgroup_identity").merge(
121
- "scope_binding_event_id" => lineage.binding_event.fetch("digest"), "seal_event_id" => lineage.seal_event.fetch("digest"), "populated" => 0)
122
- unless payload == expected
123
- raise AttemptErrors::EvidenceUnavailable, "fresh observation does not name the retained sealed parent"
124
- end
125
- at = Time.now.utc
126
- event = Models::EvidenceEvent.build(type: "scope_closed_no_writers", attempt_id: params.fetch("attempt_id"),
127
- payload: payload, previous_digest: events.last&.fetch("digest"), recorded_at: at)
128
- {events: [{type: "scope_closed_no_writers", payload: payload, recorded_at: at}], blobs: {},
129
- data: projection.merge("state" => "closed_no_writers", "proof_id" => event.fetch("digest"), "required_action" => nil)}
130
- end
131
- {plan: plan, stop_required: stop_required, inhibit_required: inhibit_required}
132
- end
133
-
134
- def scope_close_owner!(params, map, events, peer, role)
135
- state = states(events)[params.fetch("attempt_id")]
136
- unless state && state["mapping_id"] == params.fetch("mapping_id") &&
137
- (role == :supervisor || role == :launcher && @kernel.same?(state.fetch("launcher_identity"), peer))
138
- raise AttemptErrors::UnauthorizedIdentity, "scope closure requires the original launch owner"
139
- end
140
- Molecules::ExecutionScopeLineage.new(events: events, project_id: map.fetch("project_id"),
141
- assignment_id: params.fetch("assignment_id"), attempt_id: params.fetch("attempt_id"), mapping_id: params.fetch("mapping_id"))
142
- end
143
- end
144
- end
145
- end
146
- end
@@ -1,44 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Ace
4
- module Assign
5
- module Authority
6
- class LaunchLifecycle
7
- private
8
-
9
- # Called inside the existing slot/assignment exclusion, after the fresh
10
- # reservation CAS and outside its authority mutex/journal ref lock.
11
- # Mutation replay and restart never call this activation path.
12
- def provision_reserved_parent_held!(reservation, map, journal)
13
- params = reservation.slice("mapping_id", "assignment_id", "attempt_id")
14
- context = params.merge("project_id" => map.fetch("project_id"),
15
- "reservation_generation" => reservation.fetch("reservation_generation"),
16
- "scope_generation" => reservation.fetch("generation") + 1)
17
- observer = scope_observer_for(params.fetch("mapping_id"))
18
- binding = observer.activate_parent!(context)
19
- @mutex.synchronize do
20
- journal.mutate(assignment_id: params.fetch("assignment_id"), attempt_id: params.fetch("attempt_id"),
21
- mutation_id: "scope-parent-#{Digest::SHA256.hexdigest(params.fetch('attempt_id'))[0, 48]}",
22
- operation: "scope_parent_binding", parameters_digest: Digest::SHA256.hexdigest(JSON.generate(canonical(context))),
23
- expected_generation: reservation.fetch("generation"), with_replay: true) do |events, _commit, _generation|
24
- state = states(events)[params.fetch("attempt_id")]
25
- unless state && state["phase"] == "reserved" && state["launch_ticket"] == reservation.fetch("launch_ticket") &&
26
- events.none? { |event| %w[scope_bound scope_native_bound scope_child_bound scope_sealed].include?(event["type"]) ||
27
- event["type"] == "authority_mutation" && event.dig("payload", "operation") == "scope_service_admission" }
28
- raise AttemptErrors::Conflict, "parent activation cannot replace or reopen an existing generation"
29
- end
30
- at = Time.now.utc
31
- event = Models::EvidenceEvent.build(type: "scope_bound", attempt_id: params.fetch("attempt_id"),
32
- payload: binding, previous_digest: events.last&.fetch("digest"), recorded_at: at)
33
- lineage = Molecules::ExecutionScopeLineage.new(events: events + [event], project_id: map.fetch("project_id"),
34
- assignment_id: params.fetch("assignment_id"), attempt_id: params.fetch("attempt_id"), mapping_id: params.fetch("mapping_id"))
35
- observer.observe(lineage)
36
- {events: [{type: "scope_bound", payload: binding, recorded_at: at}], blobs: {}, data: state.merge(
37
- "scope_generation" => binding.fetch("scope_generation"), "scope_binding_event_id" => event.fetch("digest"))}
38
- end
39
- end
40
- end
41
- end
42
- end
43
- end
44
- end