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,176 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Ace
4
- module Assign
5
- module Authority
6
- module FixedPublicationLifecycle
7
- def publication_executor_identity?(project:, uid:)
8
- service_project!(project).fetch("service_executor_uids").include?(uid)
9
- end
10
-
11
- def with_publication_hitl!(binding:, project:, peer:)
12
- params = binding.slice("mapping_id", "assignment_id", "attempt_id", "request_id", "claim_binding", "input_digest", "candidate_generation", "head")
13
- map = service_mapping!(params.fetch("mapping_id"))
14
- raise AttemptErrors::UnauthorizedIdentity, "publication project differs" unless map.fetch("project_id") == project
15
- with_service_scope(params: params, map: map) do |journal, _registration|
16
- service_journal!(journal)
17
- record = publication_record!(journal, params, map, peer, :executor)
18
- unless record["dispatch_phase"] == "otp_pending" && record["publication_challenge_digest"] == binding.fetch("challenge_digest")
19
- raise AttemptErrors::Conflict, "publication HITL challenge is no longer pending"
20
- end
21
- ServiceEvidence.new(journal: journal).publication_challenge!(record)
22
- selection = settlement_immutable({"executor_process_binding" => record.fetch("executor_process_binding"),
23
- "challenge_ref" => record.fetch("publication_challenge_ref").fetch("ref")})
24
- yield selection
25
- end
26
- end
27
-
28
- def authorize_publication_update!(journal:, existing:, replacement:, pending:)
29
- operation = pending.fetch(:operation)
30
- allowed = ServicePublicationEvidence::PUBLICATION_FIELDS + ["dispatch_phase"]
31
- unless existing.except(*allowed) == replacement.except(*allowed) && existing["state"] == "uncertain"
32
- raise AttemptErrors::InvalidState, "publication transition changed original binding"
33
- end
34
- owner = ServiceEvidence.new(journal: journal)
35
- if operation == "publication_challenge"
36
- unless %w[dispatch_started issuing].include?(existing["dispatch_phase"]) && replacement["dispatch_phase"] == "otp_pending" &&
37
- replacement["publication_issuing_event_digest"] == existing["publication_issuing_event_digest"]
38
- raise AttemptErrors::InvalidState, "publication need has no source-owned rejected push"
39
- end
40
- need = owner.publication_challenge!(replacement, pending: pending)
41
- unless need["previous_challenge_digest"] == existing["publication_challenge_digest"]
42
- raise AttemptErrors::InvalidState, "publication need predecessor differs"
43
- end
44
- elsif operation == "publication_continue"
45
- unless existing["dispatch_phase"] == "otp_pending" && replacement["dispatch_phase"] == "issuing" &&
46
- (allowed - %w[dispatch_phase publication_issuing_event_digest]).all? { |key| existing[key] == replacement[key] }
47
- raise AttemptErrors::InvalidState, "publication continuation is not a unique pending challenge"
48
- end
49
- owner.publication_challenge!(replacement, pending: pending)
50
- events = pending.fetch(:current_events) + pending.fetch(:pending_events)
51
- event = events.find { |row| row["digest"] == replacement["publication_issuing_event_digest"] }
52
- unless event && event["type"] == "service_publication_issuing" &&
53
- %w[request_id input_digest claim_binding publication_challenge_digest].all? { |key| event.dig("payload", key) == replacement[key] }
54
- raise AttemptErrors::EvidenceUnavailable, "publication issuing event is unavailable"
55
- end
56
- else
57
- raise AttemptErrors::InvalidState, "publication transition has no fixed source owner"
58
- end
59
- true
60
- end
61
-
62
- def publication_record!(journal, params, map, peer, role, events: nil)
63
- record = journal.service_request(params.fetch("request_id"))
64
- unless record && record["operation"] == "publish" && record["state"] == "uncertain" &&
65
- %w[dispatch_started otp_pending issuing].include?(record["dispatch_phase"]) &&
66
- %w[claim_binding input_digest candidate_generation].all? { |key| record[key] == params[key] } &&
67
- record["candidate_head"] == params["head"] && record["mapping_id"] == params["mapping_id"]
68
- raise AttemptErrors::Conflict, "publication original tuple or phase differs"
69
- end
70
- service_executor!(peer, role, record)
71
- service_ticket!(record, params, map, peer)
72
- events ||= attempt_events(journal, params)
73
- current = exact_candidate!(candidate(events), params)
74
- origin = service_origin!(events, params)
75
- service_worker!(record.fetch("worker_process_binding"), :worker, map, origin)
76
- service_review!(journal, events, params, map, current)
77
- service_scope_open!(events: events, params: params, map: map)
78
- service_policy!.authorize!(record)
79
- ServiceEvidence.new(journal: journal).context(record)
80
- record
81
- end
82
-
83
- def authorize_publication_transfer!(request, params, map, peer, role)
84
- with_service_scope(params: params, map: map) do |journal, _registration|
85
- service_journal!(journal)
86
- publication_record!(journal, params, map, peer, role)
87
- end
88
- true
89
- end
90
-
91
- def dispatch_publication(request, params, map, peer, role, transfer)
92
- authorize_publication_transfer!(request, params, map, peer, role)
93
- challenge = request.fetch("operation") == "publication_challenge"
94
- bytes = nil
95
- if challenge
96
- unless transfer && transfer.count == 1
97
- raise ArgumentError, "publication need requires one bounded artifact"
98
- end
99
- bytes = transfer.bytes.dup.freeze
100
- unless Digest::SHA256.hexdigest(bytes) == params.fetch("receipt_sha256")
101
- raise AttemptErrors::ReceiptRejected, "publication need transfer digest differs"
102
- end
103
- elsif transfer
104
- raise ArgumentError, "publication continuation forbids upload"
105
- end
106
- with_service_scope(params: params, map: map) do |journal, _registration|
107
- publication_record!(journal, params, map, peer, role)
108
- result = journal.mutate(assignment_id: params.fetch("assignment_id"), attempt_id: params.fetch("attempt_id"),
109
- mutation_id: request.fetch("mutation_id"), operation: request.fetch("operation"),
110
- parameters_digest: Atoms::EvidenceDigest.digest(params), expected_generation: params.fetch("expected_generation"),
111
- with_replay: true) do |events, _commit, generation|
112
- record = publication_record!(journal, params, map, peer, role, events: events)
113
- if challenge
114
- publication_challenge_plan(journal, events, record, params, bytes, generation)
115
- else
116
- publication_continue_plan(journal, events, record, params, generation)
117
- end
118
- end
119
- if !challenge && result.fetch(:replayed)
120
- result = result.merge(data: result.fetch(:data).merge("invocation" => "already_issued"))
121
- end
122
- result
123
- end
124
- end
125
-
126
- def publication_challenge_plan(journal, events, record, params, bytes, generation)
127
- owner = ServiceEvidence.new(journal: journal)
128
- digest = Digest::SHA256.hexdigest(bytes)
129
- if record["dispatch_phase"] == "otp_pending"
130
- owner.publication_challenge!(record)
131
- raise AttemptErrors::Conflict, "publication pending challenge differs" unless record["publication_challenge_digest"] == digest
132
- return {data: service_projection(record).merge("challenge" => "retained")}
133
- end
134
- unless %w[dispatch_started issuing].include?(record["dispatch_phase"])
135
- raise AttemptErrors::InvalidState, "publication has no rejected push"
136
- end
137
- previous = record["publication_challenge_digest"]
138
- owner.publication_challenge!(record) if previous
139
- owner.publication_need!(bytes, record, previous: previous)
140
- payload = record.slice("request_id", "input_digest", "claim_binding").merge(
141
- "challenge_digest" => digest, "previous_challenge_digest" => previous, "generation" => generation + 1)
142
- time = Time.now.utc
143
- event = Models::EvidenceEvent.build(type: "service_publication_challenge", attempt_id: record.fetch("attempt_id"),
144
- payload: payload, previous_digest: events.last&.fetch("digest"), recorded_at: time)
145
- plan = Molecules::CanonicalEvidence.new(journal: journal).import_plan(**owner.context(record),
146
- artifacts: [bytes], admitted_after_event_digest: event.fetch("digest"))
147
- replacement = record.merge("dispatch_phase" => "otp_pending", "publication_challenge_digest" => digest,
148
- "publication_challenge_ref" => plan.fetch(:references).fetch(0),
149
- "publication_challenge_event_digest" => event.fetch("digest"), "publication_challenge_generation" => generation + 1)
150
- plan.merge(events: [{type: "service_publication_challenge", payload: payload, recorded_at: time}] + plan.fetch(:events),
151
- data: service_projection(replacement).merge("challenge" => "created"), service_updates: [{request_id: record.fetch("request_id"),
152
- expected: record, replacement: replacement, event_type: "service_transition"}])
153
- end
154
-
155
- def publication_continue_plan(journal, events, record, params, generation)
156
- ServiceEvidence.new(journal: journal).publication_challenge!(record)
157
- unless record["publication_challenge_digest"] == params.fetch("challenge_digest")
158
- raise AttemptErrors::Conflict, "publication continuation challenge differs"
159
- end
160
- if record["dispatch_phase"] == "issuing"
161
- return {data: service_projection(record).merge("invocation" => "already_issued")}
162
- end
163
- raise AttemptErrors::InvalidState, "publication is not pending" unless record["dispatch_phase"] == "otp_pending"
164
- payload = record.slice("request_id", "input_digest", "claim_binding", "publication_challenge_digest").merge("generation" => generation + 1)
165
- time = Time.now.utc
166
- event = Models::EvidenceEvent.build(type: "service_publication_issuing", attempt_id: record.fetch("attempt_id"),
167
- payload: payload, previous_digest: events.last&.fetch("digest"), recorded_at: time)
168
- replacement = record.merge("dispatch_phase" => "issuing", "publication_issuing_event_digest" => event.fetch("digest"))
169
- {events: [{type: "service_publication_issuing", payload: payload, recorded_at: time}],
170
- data: service_projection(replacement).merge("invocation" => "permitted"), service_updates: [{request_id: record.fetch("request_id"),
171
- expected: record, replacement: replacement, event_type: "service_transition"}]}
172
- end
173
- end
174
- end
175
- end
176
- end