ace-lab 0.6.0 → 0.8.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/CHANGELOG.md +22 -0
- data/docs/usage.md +155 -0
- data/lib/ace/lab/cli/commands/assignment.rb +45 -0
- data/lib/ace/lab/cli/commands/service.rb +64 -0
- data/lib/ace/lab/cli.rb +8 -1
- data/lib/ace/lab/molecules/forge_merge_config.rb +127 -0
- data/lib/ace/lab/molecules/forgejo_merge_adapter.rb +150 -0
- data/lib/ace/lab/molecules/grant_resolver.rb +15 -13
- data/lib/ace/lab/molecules/ordinary_admission_resolver.rb +131 -0
- data/lib/ace/lab/molecules/ordinary_listener.rb +262 -0
- data/lib/ace/lab/molecules/ordinary_merge_read.rb +45 -0
- data/lib/ace/lab/molecules/ordinary_native_read.rb +106 -0
- data/lib/ace/lab/molecules/ordinary_owner_admission.rb +139 -0
- data/lib/ace/lab/molecules/ordinary_owner_config.rb +232 -0
- data/lib/ace/lab/molecules/ordinary_receiver_config.rb +94 -0
- data/lib/ace/lab/molecules/ordinary_socket.rb +6 -9
- data/lib/ace/lab/molecules/ordinary_worktree_read.rb +216 -0
- data/lib/ace/lab/molecules/service_executor.rb +9 -39
- data/lib/ace/lab/molecules/service_policy.rb +15 -4
- data/lib/ace/lab/organisms/authority_composition.rb +1 -1
- data/lib/ace/lab/organisms/ordinary_assignment_client.rb +149 -0
- data/lib/ace/lab/organisms/ordinary_authority_composition.rb +123 -0
- data/lib/ace/lab/organisms/ordinary_merge_receiver.rb +688 -0
- data/lib/ace/lab/organisms/ordinary_merge_request.rb +41 -7
- data/lib/ace/lab/version.rb +1 -1
- metadata +48 -6
|
@@ -6,6 +6,7 @@ require "open3"
|
|
|
6
6
|
require_relative "protected_service_request"
|
|
7
7
|
require_relative "../molecules/ordinary_socket"
|
|
8
8
|
require "ace/assign/atoms/fixed_merge_schemas"
|
|
9
|
+
require "ace/assign/molecules/installed_journal_read"
|
|
9
10
|
|
|
10
11
|
module Ace
|
|
11
12
|
module Lab
|
|
@@ -45,8 +46,7 @@ module Ace
|
|
|
45
46
|
def initialize(topology: nil, policy: nil, coordinator: nil, repo_root: nil, ingress: nil)
|
|
46
47
|
@topology = topology || TopologyService.from_config
|
|
47
48
|
@repo_root = repo_root || git_toplevel
|
|
48
|
-
@coordinator = coordinator
|
|
49
|
-
Ace::Assign::Organisms::AttemptCoordinator.new(repo_root: @repo_root)
|
|
49
|
+
@coordinator = coordinator
|
|
50
50
|
@policy = policy || Molecules::ServicePolicy.new(
|
|
51
51
|
Molecules::GrantResolver.trusted_document(Ace::Lab.authorization_path)
|
|
52
52
|
)
|
|
@@ -71,6 +71,11 @@ module Ace
|
|
|
71
71
|
queue_entry: queue_entry, authorization: authorization, request_id: request_id,
|
|
72
72
|
document: document)
|
|
73
73
|
principal = authenticate!(project)
|
|
74
|
+
unless @coordinator
|
|
75
|
+
return with_installed_journal(project) { |producer| producer.request(project: project,
|
|
76
|
+
assignment: assignment, attempt: attempt, queue_entry: queue_entry, operation: operation,
|
|
77
|
+
input: input, authorization: authorization, request_id: request_id, **options) }
|
|
78
|
+
end
|
|
74
79
|
existing = @coordinator.fixed_merge_record(request_id)
|
|
75
80
|
if existing
|
|
76
81
|
return ack_envelope(existing) if exact_replay?(existing, project: project,
|
|
@@ -137,6 +142,11 @@ module Ace
|
|
|
137
142
|
invalid!("invalid input digest", request)
|
|
138
143
|
end
|
|
139
144
|
authenticate!(project)
|
|
145
|
+
unless @coordinator
|
|
146
|
+
return with_installed_journal(project) { |producer| producer.status(project: project,
|
|
147
|
+
assignment: assignment, attempt: attempt, queue_entry: queue_entry, reference: reference,
|
|
148
|
+
request: request, input_digest: input_digest, **options) }
|
|
149
|
+
end
|
|
140
150
|
record = @coordinator.fixed_merge_status(reference: reference, request_id: request,
|
|
141
151
|
project_id: project, assignment_id: assignment, attempt_id: attempt,
|
|
142
152
|
queue_entry: queue_entry, input_digest: input_digest)
|
|
@@ -198,6 +208,23 @@ module Ace
|
|
|
198
208
|
|
|
199
209
|
private
|
|
200
210
|
|
|
211
|
+
def with_installed_journal(project)
|
|
212
|
+
receiver = @policy.ordinary_receiver!(project)
|
|
213
|
+
unless receiver && %w[journal_repository journal_ref].all? { |key| receiver.key?(key) }
|
|
214
|
+
raise Ace::Lab::InvalidConfigurationError, "installed ordinary journal selection is missing"
|
|
215
|
+
end
|
|
216
|
+
repository, ref = receiver.values_at("journal_repository", "journal_ref")
|
|
217
|
+
boundary = Ace::Assign::Molecules::InstalledJournalRead.new(repo_root: repository,
|
|
218
|
+
ref: ref, owner_uid: receiver.fetch("receiver_uid"))
|
|
219
|
+
boundary.with(deadline: Process.clock_gettime(Process::CLOCK_MONOTONIC) + 30) do |view|
|
|
220
|
+
journal = Ace::Assign::Molecules::EvidenceJournal.new(repo_root: repository,
|
|
221
|
+
ref: ref, checkout_root: File.join(repository, ".unused-reader"), read_boundary: view)
|
|
222
|
+
coordinator = Ace::Assign::Organisms::AttemptCoordinator.new(repo_root: @repo_root, journal: journal)
|
|
223
|
+
yield self.class.new(topology: @topology, policy: @policy, repo_root: @repo_root,
|
|
224
|
+
coordinator: coordinator, ingress: @ingress)
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
201
228
|
# The immutable binding digest — spec ruling r4: lowercase hex SHA-256
|
|
202
229
|
# over the canonical JSON (recursively key-sorted, compact, UTF-8) of
|
|
203
230
|
# the full eight-field binding. Computed once here at admission; the
|
|
@@ -242,7 +269,7 @@ module Ace
|
|
|
242
269
|
raise Molecules::OrdinarySocket::OrdinaryUnavailable,
|
|
243
270
|
"ordinary merge admission is not available in the installed configuration"
|
|
244
271
|
end
|
|
245
|
-
receiver.merge("configuration_sha256" =>
|
|
272
|
+
receiver.merge("configuration_sha256" => Molecules::ServicePolicy.configuration_digest(@policy.document))
|
|
246
273
|
end
|
|
247
274
|
|
|
248
275
|
def resolve_selection!(project:, assignment:, attempt:, queue_entry:)
|
|
@@ -261,8 +288,15 @@ module Ace
|
|
|
261
288
|
"head_ref" => document.fetch("head_ref"), "candidate_head" => document.fetch("candidate_head"),
|
|
262
289
|
"base_repository" => document.fetch("base_repository"), "base_ref" => document.fetch("base_ref"),
|
|
263
290
|
"expected_base_head" => document.fetch("expected_base_head")}
|
|
264
|
-
|
|
265
|
-
|
|
291
|
+
if authorization.start_with?("proposal-")
|
|
292
|
+
@coordinator.proposal_authorization(authorization, binding.slice(
|
|
293
|
+
"operation", "project_id", "assignment_id", "attempt_id", "input_digest", "candidate_head").merge(
|
|
294
|
+
"target" => {"resource" => document.fetch("pr_url"), "artifact_digest" => nil},
|
|
295
|
+
"caller_uid" => Process.uid))
|
|
296
|
+
else
|
|
297
|
+
@policy.authorize_ordinary!(authorization, binding)
|
|
298
|
+
end
|
|
299
|
+
rescue SecurityError, Ace::Assign::AttemptErrors::ReceiptRejected => e
|
|
266
300
|
# Spec table (ruling r4): the authorization decision or reference is
|
|
267
301
|
# invalid for this request — missing, expired, revoked, out of scope,
|
|
268
302
|
# bound to another operation/project/PR/head, or not an ordinary
|
|
@@ -306,7 +340,7 @@ module Ace
|
|
|
306
340
|
def normalize_ack(response, request_id:, input_digest:)
|
|
307
341
|
data = response.fetch("data") { {} }
|
|
308
342
|
expected = %w[schema type request_id input_digest reference]
|
|
309
|
-
digest = data["input_digest"]
|
|
343
|
+
digest = data.is_a?(Hash) && data["input_digest"]
|
|
310
344
|
unless data.is_a?(Hash) && (data.keys - expected).empty? &&
|
|
311
345
|
expected.all? { |key| data[key].is_a?(String) && !data[key].empty? } &&
|
|
312
346
|
data.fetch("schema") == Ace::Assign::Atoms::FixedMergeSchemas::ACK_SCHEMA_ID &&
|
|
@@ -322,7 +356,7 @@ module Ace
|
|
|
322
356
|
def normalize_refusal(response, request_id:, input_digest:)
|
|
323
357
|
error = response.fetch("error") { {} }
|
|
324
358
|
expected = %w[schema code message request_id input_digest]
|
|
325
|
-
valid = error.is_a?(Hash) &&
|
|
359
|
+
valid = error.is_a?(Hash) && error.keys.sort == expected.sort &&
|
|
326
360
|
error.fetch("schema") == Ace::Assign::Atoms::FixedMergeSchemas::REFUSAL_SCHEMA_ID &&
|
|
327
361
|
CODES.include?(error.fetch("code")) &&
|
|
328
362
|
error.fetch("message").is_a?(String) && !error.fetch("message").empty? &&
|
data/lib/ace/lab/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ace-lab
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.8.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-16 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: ace-runtime
|
|
@@ -71,28 +71,56 @@ dependencies:
|
|
|
71
71
|
requirements:
|
|
72
72
|
- - "~>"
|
|
73
73
|
- !ruby/object:Gem::Version
|
|
74
|
-
version: '0.
|
|
74
|
+
version: '0.70'
|
|
75
75
|
type: :runtime
|
|
76
76
|
prerelease: false
|
|
77
77
|
version_requirements: !ruby/object:Gem::Requirement
|
|
78
78
|
requirements:
|
|
79
79
|
- - "~>"
|
|
80
80
|
- !ruby/object:Gem::Version
|
|
81
|
-
version: '0.
|
|
81
|
+
version: '0.70'
|
|
82
|
+
- !ruby/object:Gem::Dependency
|
|
83
|
+
name: ace-herdr
|
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - "~>"
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: '0.6'
|
|
89
|
+
type: :runtime
|
|
90
|
+
prerelease: false
|
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - "~>"
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '0.6'
|
|
82
96
|
- !ruby/object:Gem::Dependency
|
|
83
97
|
name: ace-hitl
|
|
84
98
|
requirement: !ruby/object:Gem::Requirement
|
|
85
99
|
requirements:
|
|
86
100
|
- - "~>"
|
|
87
101
|
- !ruby/object:Gem::Version
|
|
88
|
-
version: '0.
|
|
102
|
+
version: '0.16'
|
|
103
|
+
type: :runtime
|
|
104
|
+
prerelease: false
|
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
106
|
+
requirements:
|
|
107
|
+
- - "~>"
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: '0.16'
|
|
110
|
+
- !ruby/object:Gem::Dependency
|
|
111
|
+
name: ace-git-forgejo
|
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
|
113
|
+
requirements:
|
|
114
|
+
- - "~>"
|
|
115
|
+
- !ruby/object:Gem::Version
|
|
116
|
+
version: '0.7'
|
|
89
117
|
type: :runtime
|
|
90
118
|
prerelease: false
|
|
91
119
|
version_requirements: !ruby/object:Gem::Requirement
|
|
92
120
|
requirements:
|
|
93
121
|
- - "~>"
|
|
94
122
|
- !ruby/object:Gem::Version
|
|
95
|
-
version: '0.
|
|
123
|
+
version: '0.7'
|
|
96
124
|
- !ruby/object:Gem::Dependency
|
|
97
125
|
name: ace-support-test-helpers
|
|
98
126
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -205,6 +233,7 @@ files:
|
|
|
205
233
|
- lib/ace/lab/authorization_path.rb
|
|
206
234
|
- lib/ace/lab/cli.rb
|
|
207
235
|
- lib/ace/lab/cli/commands/agents.rb
|
|
236
|
+
- lib/ace/lab/cli/commands/assignment.rb
|
|
208
237
|
- lib/ace/lab/cli/commands/projects.rb
|
|
209
238
|
- lib/ace/lab/cli/commands/resolve.rb
|
|
210
239
|
- lib/ace/lab/cli/commands/route.rb
|
|
@@ -219,10 +248,20 @@ files:
|
|
|
219
248
|
- lib/ace/lab/molecules/caller_authorizer.rb
|
|
220
249
|
- lib/ace/lab/molecules/capability_router.rb
|
|
221
250
|
- lib/ace/lab/molecules/exact_resolver.rb
|
|
251
|
+
- lib/ace/lab/molecules/forge_merge_config.rb
|
|
252
|
+
- lib/ace/lab/molecules/forgejo_merge_adapter.rb
|
|
222
253
|
- lib/ace/lab/molecules/grant_resolver.rb
|
|
223
254
|
- lib/ace/lab/molecules/hitl_authorizer.rb
|
|
224
255
|
- lib/ace/lab/molecules/inventory_query.rb
|
|
256
|
+
- lib/ace/lab/molecules/ordinary_admission_resolver.rb
|
|
257
|
+
- lib/ace/lab/molecules/ordinary_listener.rb
|
|
258
|
+
- lib/ace/lab/molecules/ordinary_merge_read.rb
|
|
259
|
+
- lib/ace/lab/molecules/ordinary_native_read.rb
|
|
260
|
+
- lib/ace/lab/molecules/ordinary_owner_admission.rb
|
|
261
|
+
- lib/ace/lab/molecules/ordinary_owner_config.rb
|
|
262
|
+
- lib/ace/lab/molecules/ordinary_receiver_config.rb
|
|
225
263
|
- lib/ace/lab/molecules/ordinary_socket.rb
|
|
264
|
+
- lib/ace/lab/molecules/ordinary_worktree_read.rb
|
|
226
265
|
- lib/ace/lab/molecules/protected_cleanup_owner_admission.rb
|
|
227
266
|
- lib/ace/lab/molecules/protected_cleanup_owner_client.rb
|
|
228
267
|
- lib/ace/lab/molecules/protected_cleanup_owner_identity.rb
|
|
@@ -233,6 +272,9 @@ files:
|
|
|
233
272
|
- lib/ace/lab/molecules/service_policy.rb
|
|
234
273
|
- lib/ace/lab/molecules/topology_loader.rb
|
|
235
274
|
- lib/ace/lab/organisms/authority_composition.rb
|
|
275
|
+
- lib/ace/lab/organisms/ordinary_assignment_client.rb
|
|
276
|
+
- lib/ace/lab/organisms/ordinary_authority_composition.rb
|
|
277
|
+
- lib/ace/lab/organisms/ordinary_merge_receiver.rb
|
|
236
278
|
- lib/ace/lab/organisms/ordinary_merge_request.rb
|
|
237
279
|
- lib/ace/lab/organisms/protected_cleanup_owner.rb
|
|
238
280
|
- lib/ace/lab/organisms/protected_service_client.rb
|