ace-herdr 0.5.0 → 0.6.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 +12 -0
- data/lib/ace/herdr/models/delivery_record.rb +9 -0
- data/lib/ace/herdr/molecules/bounded_observation.rb +51 -0
- data/lib/ace/herdr/organisms/inbox.rb +33 -0
- data/lib/ace/herdr/organisms/inbox_context_owner.rb +1 -6
- data/lib/ace/herdr/version.rb +1 -1
- metadata +7 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5e3b1b413921a28b8ebd2437c424f885d11ec65bcf886fdb173101b8ce5ca8de
|
|
4
|
+
data.tar.gz: a4ebad7d9470e1f7f1e74e6b7a66d3ced20605f13bb323c67f5abc51993978ee
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b53397db1e608164a19390d073ae7420b602ec1a8152b975f11d6dd3443dda4da4ff5208644aecf7f2bb7bfc269034c6813eac283683eed4ea916b1b01c52795
|
|
7
|
+
data.tar.gz: e716fc0fe8329fffda5b2c18c81395432b3257b4fee3118207f21e016f69185454f4ea2661fda6f8ba3aa42eebaf0aaca773fed7e20d7899ff08e6c139f2cb18
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.6.0] - 2026-10-16
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Expose bounded native observations and hold ordinary Inbox delivery settlement through canonical Assign acceptance. Preserve exact targets and unresolved outcomes without repeat sends or alternate execution records.
|
|
15
|
+
|
|
16
|
+
## [0.5.1] - 2026-10-10
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- Require the published producer and consumer patch versions containing the protected context and managed-attempt APIs; exclude incompatible prior dependency graphs.
|
|
21
|
+
|
|
10
22
|
## [0.5.0] - 2026-10-08
|
|
11
23
|
|
|
12
24
|
### Changed
|
|
@@ -79,6 +79,15 @@ module Ace
|
|
|
79
79
|
state == "delivered"
|
|
80
80
|
end
|
|
81
81
|
|
|
82
|
+
# Exact native submission receipt, not a business completion verdict.
|
|
83
|
+
def inbox_delivered?
|
|
84
|
+
return false unless delivered? && inbox.is_a?(Hash)
|
|
85
|
+
receipt = inbox["receipt"]
|
|
86
|
+
inbox["claim_generation"].is_a?(Integer) && inbox["claim_generation"].positive? &&
|
|
87
|
+
receipt.is_a?(Hash) && receipt.values_at("event_id", "attempt_id", "claim_generation", "payload_sha256", "binding") ==
|
|
88
|
+
[event_id, inbox["attempt_id"], inbox["claim_generation"], answer_digest, inbox["binding"]]
|
|
89
|
+
end
|
|
90
|
+
|
|
82
91
|
# A "submitting" history entry without a matching outcome means the
|
|
83
92
|
# previous run crashed between prompt submission and persistence;
|
|
84
93
|
# resending could duplicate the answer, so the outcome is ambiguous.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "herdr_executor"
|
|
4
|
+
|
|
5
|
+
module Ace
|
|
6
|
+
module Herdr
|
|
7
|
+
module Molecules
|
|
8
|
+
# Read-only native attribution under one absolute deadline, including all
|
|
9
|
+
# ancestry probes. Never renew the budget for another process in the chain.
|
|
10
|
+
class BoundedObservation < HerdrExecutor
|
|
11
|
+
def initialize(deadline:, binary: DEFAULT_BINARY, process: BoundedProcess)
|
|
12
|
+
super(binary: binary, process: process)
|
|
13
|
+
@deadline = deadline
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def pane_get(pane) = observe!([@binary, "pane", "get", pane])
|
|
17
|
+
def pane_process_info(pane) = observe!([@binary, "pane", "process-info", "--pane", pane])
|
|
18
|
+
|
|
19
|
+
# ProcessIdentity's existing executor seam. Do not let PATH select ps.
|
|
20
|
+
def capture2(command, *args, stdin_data: "")
|
|
21
|
+
raise ArgumentError, "observation only permits ps" unless command == "ps" && stdin_data.empty?
|
|
22
|
+
result = bounded(["/bin/ps", *args])
|
|
23
|
+
[result.stdout, result.status]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def observe!(argv)
|
|
29
|
+
result = bounded(argv)
|
|
30
|
+
execution = ExecutionResult.new(stdout: result.stdout.strip, stderr: result.stderr.strip,
|
|
31
|
+
success: result.status.success?, exit_code: result.status.exitstatus || -1)
|
|
32
|
+
raise classify(execution, argv) unless execution.success?
|
|
33
|
+
execution
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def bounded(argv)
|
|
37
|
+
remaining = @deadline - Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
38
|
+
raise AgentNotReadyError, "native observation deadline elapsed" unless remaining.positive?
|
|
39
|
+
result = @process.call(argv, stdin_data: "", timeout_s: remaining,
|
|
40
|
+
output_limit: WAKE_OUTPUT_LIMIT, cleanup_group: true)
|
|
41
|
+
raise AgentNotReadyError, "native observation output exceeded limit" if result.oversized
|
|
42
|
+
result
|
|
43
|
+
rescue Timeout::Error, BoundedProcess::PostLaunchError
|
|
44
|
+
raise AgentNotReadyError, "native observation did not complete within its bound"
|
|
45
|
+
rescue SystemCallError
|
|
46
|
+
raise ExecutorUnavailableError, "native observation executable unavailable"
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -172,6 +172,39 @@ module Ace
|
|
|
172
172
|
|
|
173
173
|
def context_root = @deliveries_dir.dup.freeze
|
|
174
174
|
|
|
175
|
+
# The installed consumer supplies canonical references and native
|
|
176
|
+
# owner, while this owner holds every existing record lock through the
|
|
177
|
+
# consumer's acceptance CAS. No delivery/retry/wake is performed here.
|
|
178
|
+
def with_delivery_settlement(deadline: nil)
|
|
179
|
+
self.class.with_retained_records(deliveries_dir: @deliveries_dir, deadline: deadline) do |records|
|
|
180
|
+
verify = lambda do |references:, attempt_id:, owner:|
|
|
181
|
+
unless references.is_a?(Array) && references.all? { |reference|
|
|
182
|
+
reference.is_a?(Hash) && reference.keys.sort == %w[attempt_id event_id payload_sha256] &&
|
|
183
|
+
reference["attempt_id"] == attempt_id }
|
|
184
|
+
raise ValidationError, "canonical Inbox references differ"
|
|
185
|
+
end
|
|
186
|
+
selected = records.select { |record| record.inbox.fetch("attempt_id") == attempt_id }
|
|
187
|
+
ids = references.map { |reference| reference.fetch("event_id") }
|
|
188
|
+
unless ids.uniq == ids && selected.map(&:event_id).sort == ids.sort
|
|
189
|
+
raise ValidationError, "canonical Inbox reference inventory differs"
|
|
190
|
+
end
|
|
191
|
+
next [] if selected.empty?
|
|
192
|
+
target = target_from_owner(owner)
|
|
193
|
+
selected.map do |record|
|
|
194
|
+
reference = references.find { |item| item.fetch("event_id") == record.event_id }
|
|
195
|
+
binding = record.inbox.fetch("binding", {})
|
|
196
|
+
unless !record.inbox["original_context"] && record.inbox_delivered? && record.answer_digest == reference.fetch("payload_sha256") &&
|
|
197
|
+
record.inbox["origin_target"] == target && binding.slice(*target.keys) == target &&
|
|
198
|
+
binding["payload_sha256"] == record.answer_digest && %w[none sent].include?(record.inbox.dig("wake", "status"))
|
|
199
|
+
raise ValidationError, "original Inbox delivery or wake remains unsettled"
|
|
200
|
+
end
|
|
201
|
+
reference.merge("claim_generation" => record.inbox.fetch("claim_generation"))
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
yield verify
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
175
208
|
|
|
176
209
|
def enqueue(event:, attempt:, ref:, payload:, managed_envelope: nil, expected_target: nil, original_context: nil, original_binding_digest: nil)
|
|
177
210
|
validate_id!(event, "event")
|
|
@@ -378,12 +378,7 @@ module Ace
|
|
|
378
378
|
end
|
|
379
379
|
|
|
380
380
|
def completed_record?(record)
|
|
381
|
-
|
|
382
|
-
inbox = record.inbox
|
|
383
|
-
receipt = inbox["receipt"]
|
|
384
|
-
inbox["claim_generation"].is_a?(Integer) && inbox["claim_generation"].positive? &&
|
|
385
|
-
receipt.is_a?(Hash) && receipt.values_at("event_id", "attempt_id", "claim_generation", "payload_sha256", "binding") ==
|
|
386
|
-
[record.event_id, inbox["attempt_id"], inbox["claim_generation"], record.answer_digest, inbox["binding"]]
|
|
381
|
+
record.inbox_delivered?
|
|
387
382
|
end
|
|
388
383
|
|
|
389
384
|
def expected!(state, expected)
|
data/lib/ace/herdr/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ace-herdr
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.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: websocket-driver
|
|
@@ -49,28 +49,28 @@ dependencies:
|
|
|
49
49
|
requirements:
|
|
50
50
|
- - "~>"
|
|
51
51
|
- !ruby/object:Gem::Version
|
|
52
|
-
version:
|
|
52
|
+
version: 0.2.1
|
|
53
53
|
type: :runtime
|
|
54
54
|
prerelease: false
|
|
55
55
|
version_requirements: !ruby/object:Gem::Requirement
|
|
56
56
|
requirements:
|
|
57
57
|
- - "~>"
|
|
58
58
|
- !ruby/object:Gem::Version
|
|
59
|
-
version:
|
|
59
|
+
version: 0.2.1
|
|
60
60
|
- !ruby/object:Gem::Dependency
|
|
61
61
|
name: ace-runtime
|
|
62
62
|
requirement: !ruby/object:Gem::Requirement
|
|
63
63
|
requirements:
|
|
64
64
|
- - "~>"
|
|
65
65
|
- !ruby/object:Gem::Version
|
|
66
|
-
version: '0.
|
|
66
|
+
version: '0.3'
|
|
67
67
|
type: :runtime
|
|
68
68
|
prerelease: false
|
|
69
69
|
version_requirements: !ruby/object:Gem::Requirement
|
|
70
70
|
requirements:
|
|
71
71
|
- - "~>"
|
|
72
72
|
- !ruby/object:Gem::Version
|
|
73
|
-
version: '0.
|
|
73
|
+
version: '0.3'
|
|
74
74
|
- !ruby/object:Gem::Dependency
|
|
75
75
|
name: ace-support-cli
|
|
76
76
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -237,6 +237,7 @@ files:
|
|
|
237
237
|
- lib/ace/herdr/errors.rb
|
|
238
238
|
- lib/ace/herdr/models/delivery_record.rb
|
|
239
239
|
- lib/ace/herdr/models/dispatch_outcome.rb
|
|
240
|
+
- lib/ace/herdr/molecules/bounded_observation.rb
|
|
240
241
|
- lib/ace/herdr/molecules/bounded_process.rb
|
|
241
242
|
- lib/ace/herdr/molecules/delivery_record_store.rb
|
|
242
243
|
- lib/ace/herdr/molecules/guarded_native_origin.rb
|