ace-hitl 0.23.2 → 0.24.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 +6 -0
- data/README.md +12 -0
- data/lib/ace/hitl/cli/commands/observe.rb +24 -0
- data/lib/ace/hitl/cli.rb +3 -0
- data/lib/ace/hitl/molecules/event_observation.rb +62 -0
- data/lib/ace/hitl/organisms/hitl_manager.rb +3 -1
- data/lib/ace/hitl/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 066770bf07c22e97f6d1571d8d7697a9681df2872102b9454e26dc934d494162
|
|
4
|
+
data.tar.gz: 398b6537945687a92f34a0284d9e687f7b41cfea777352c9b7046a07ef45cd9a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cb37ecff31019de3e8007964a8631e9f8e33c7dd5ba4be5505b84a4172c030e7eadf4580e8e70b962b8d26942a4b1a6221ed9a7641adb8726e4dce408b11c734
|
|
7
|
+
data.tar.gz: a7ecb1759adaa8e6ae5dae068eb556bc0f094cd905a11b12f30f1f1bd6012ea61f68487eeeddf48298ee92de212b7b5c57c893e371a2234b20b9ca18f1475035
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.24.0] - 2026-10-23
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Add read-only semantic event observations with configured-owner filtering; exclude delivery metadata and unrelated recipients.
|
|
15
|
+
|
|
10
16
|
## [0.23.2] - 2026-10-20
|
|
11
17
|
|
|
12
18
|
### Fixed
|
data/README.md
CHANGED
|
@@ -78,3 +78,15 @@ bin/ace-test ace-hitl all
|
|
|
78
78
|
`ace-hitl` owns HITL event semantics and the markdown contract.
|
|
79
79
|
`ace-support-items` remains generic support infrastructure and does not absorb
|
|
80
80
|
HITL-specific behaviour.
|
|
81
|
+
|
|
82
|
+
### Read semantic event revisions
|
|
83
|
+
|
|
84
|
+
`ace-hitl observe --scope current --limit 500` prints one JSON object with schema
|
|
85
|
+
`ace.hitl.observation/v1` and a bounded `events` list. `--scope all` includes linked
|
|
86
|
+
worktrees of this repository. Each row contains a hashed canonical file identity,
|
|
87
|
+
event ID, semantic revision hash, type/status and task/assignment references.
|
|
88
|
+
It emits no private message or answer text. It reads active (non-special-folder) canonical events and
|
|
89
|
+
does not import transports, acknowledge, archive, resume or mutate events.
|
|
90
|
+
Delivery/poll timestamps and filesystem mtime are excluded from revisions;
|
|
91
|
+
content, answers and report/status changes are included. Exceeding the configured
|
|
92
|
+
limit refuses the entire projection rather than silently truncating it.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require "ace/support/cli"
|
|
3
|
+
require_relative "../../molecules/event_observation"
|
|
4
|
+
module Ace
|
|
5
|
+
module Hitl
|
|
6
|
+
module CLI
|
|
7
|
+
module Commands
|
|
8
|
+
class Observe < Ace::Support::Cli::Command
|
|
9
|
+
desc "Read bounded semantic event revisions without private message text"
|
|
10
|
+
option :scope, type: :string, default: "current", desc: "current or all linked worktrees"
|
|
11
|
+
option :owner, type: :string, desc: "Configured recipient owning incoming events"
|
|
12
|
+
option :limit, type: :integer, default: 500, desc: "Maximum event count (1..2000)"
|
|
13
|
+
def call(**options)
|
|
14
|
+
scope = options[:scope] || "current"
|
|
15
|
+
raise Ace::Support::Cli::Error, "invalid scope" unless %w[current all].include?(scope)
|
|
16
|
+
puts JSON.generate(Molecules::EventObservation.new.call(scope: scope, limit: options[:limit] || 500, owner: options[:owner]))
|
|
17
|
+
rescue ArgumentError => e
|
|
18
|
+
raise Ace::Support::Cli::Error, e.message
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
data/lib/ace/hitl/cli.rb
CHANGED
|
@@ -8,6 +8,7 @@ require_relative "cli/commands/operator_question"
|
|
|
8
8
|
require_relative "cli/commands/read"
|
|
9
9
|
require_relative "cli/commands/show"
|
|
10
10
|
require_relative "cli/commands/list"
|
|
11
|
+
require_relative "cli/commands/observe"
|
|
11
12
|
require_relative "cli/commands/update"
|
|
12
13
|
require_relative "cli/commands/wait"
|
|
13
14
|
require_relative "cli/commands/deliver"
|
|
@@ -31,6 +32,7 @@ module Ace
|
|
|
31
32
|
["read", "Read authenticated lifecycle request facts"],
|
|
32
33
|
["show", "Show HITL event details"],
|
|
33
34
|
["list", "List HITL events"],
|
|
35
|
+
["observe", "Read semantic event revisions"],
|
|
34
36
|
["update", "Update HITL event metadata or answer"],
|
|
35
37
|
["send", "Send a HITL event through the configured adapter routes"],
|
|
36
38
|
["wait", "Wait for an answer on a specific HITL event"],
|
|
@@ -58,6 +60,7 @@ module Ace
|
|
|
58
60
|
register "read", CLI::Commands::Read
|
|
59
61
|
register "show", CLI::Commands::Show
|
|
60
62
|
register "list", CLI::Commands::List
|
|
63
|
+
register "observe", CLI::Commands::Observe
|
|
61
64
|
register "update", CLI::Commands::Update
|
|
62
65
|
register "send", CLI::Commands::Send
|
|
63
66
|
register "wait", CLI::Commands::Wait
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require "digest"
|
|
3
|
+
require "json"
|
|
4
|
+
|
|
5
|
+
module Ace
|
|
6
|
+
module Hitl
|
|
7
|
+
module Molecules
|
|
8
|
+
# Read-only semantic projection. No private text is emitted; delivery
|
|
9
|
+
# timestamps, filesystem metadata and observer acknowledgements are not
|
|
10
|
+
# decision changes. Canonical HITL remains the only event owner.
|
|
11
|
+
class EventObservation
|
|
12
|
+
def initialize(manager: Organisms::HitlManager.new)
|
|
13
|
+
@manager = manager
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def call(scope: "current", limit: 500, owner: nil)
|
|
17
|
+
raise ArgumentError, "invalid observation limit" unless (1..2000).cover?(limit)
|
|
18
|
+
events = @manager.list(in_folder: "next", scope: scope, limit: limit, strict: true)
|
|
19
|
+
raise ArgumentError, "observation exceeds configured event budget" if events.size > limit
|
|
20
|
+
address = owner && Molecules::HitlAddressResolver.new(config: @manager.config).resolve(owner)
|
|
21
|
+
events = events.select { |event| incoming?(event, address) } if address
|
|
22
|
+
rows = events.map do |event|
|
|
23
|
+
semantic = [event.id, event.type, event.status, event.result, event.kind,
|
|
24
|
+
event.title, event.content, event.answer, event.questions,
|
|
25
|
+
Array(event.tags).sort, canonical(event.recipient), canonical(event.reply_to),
|
|
26
|
+
event.metadata.values_at("task", "assignment", "step", "step_name", "resume_instructions")]
|
|
27
|
+
{"key" => Digest::SHA256.hexdigest(event.file_path.to_s),
|
|
28
|
+
"id" => event.id, "revision" => Digest::SHA256.hexdigest(JSON.generate(canonical(semantic))),
|
|
29
|
+
"type" => event.type, "status" => event.status, "result" => event.result,
|
|
30
|
+
"task" => event.metadata["task"], "assignment" => event.metadata["assignment"]}
|
|
31
|
+
end
|
|
32
|
+
{"schema" => "ace.hitl.observation/v1", "events" => rows.sort_by { |row| row["key"] }}
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
# Questions created locally are outbound until actually answered. A
|
|
38
|
+
# worker's reply belongs to that worker, not every linked-worktree actor.
|
|
39
|
+
# Native instructions have no recipient; their explicit import root owns them.
|
|
40
|
+
def incoming?(event, address)
|
|
41
|
+
local = File.expand_path(event.file_path).start_with?(File.expand_path(@manager.root_dir) + File::SEPARATOR)
|
|
42
|
+
return local if Array(event.tags).include?("hermes-instruction")
|
|
43
|
+
if event.question? && event.answered?
|
|
44
|
+
return local && event.reply_to &&
|
|
45
|
+
event.reply_to["machine"] == @manager.config.dig("hitl", "machine") &&
|
|
46
|
+
File.expand_path(event.reply_to["folder"].to_s) == File.expand_path(@manager.root_dir)
|
|
47
|
+
end
|
|
48
|
+
recipient = event.recipient
|
|
49
|
+
recipient && address.all? { |key, value| recipient[key] == value }
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def canonical(value)
|
|
53
|
+
case value
|
|
54
|
+
when Hash then value.sort.to_h.transform_values { |item| canonical(item) }
|
|
55
|
+
when Array then value.map { |item| canonical(item) }
|
|
56
|
+
else value
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -94,10 +94,12 @@ module Ace
|
|
|
94
94
|
}
|
|
95
95
|
end
|
|
96
96
|
|
|
97
|
-
def list(status: nil, kind: nil, type: nil, delivery: nil, in_folder: "next", tags: [], scope: nil)
|
|
97
|
+
def list(status: nil, kind: nil, type: nil, delivery: nil, in_folder: "next", tags: [], scope: nil, limit: nil, strict: false)
|
|
98
98
|
effective_scope = @scope_resolver.effective_scope(scope)
|
|
99
99
|
scan_results = scan_results_for_scope(effective_scope, in_folder: in_folder)
|
|
100
|
+
raise ArgumentError, "observation exceeds configured event budget" if limit && scan_results.size > limit
|
|
100
101
|
events = load_events(scan_results)
|
|
102
|
+
raise ArgumentError, "incomplete HITL observation" if strict && events.size != scan_results.size
|
|
101
103
|
|
|
102
104
|
events = events.select { |event| event.status == status } if status
|
|
103
105
|
events = events.select { |event| event.kind == kind } if kind
|
data/lib/ace/hitl/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ace-hitl
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.24.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-23 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: ace-hitl-contract
|
|
@@ -160,6 +160,7 @@ files:
|
|
|
160
160
|
- lib/ace/hitl/cli/commands/duty.rb
|
|
161
161
|
- lib/ace/hitl/cli/commands/lifecycle_command.rb
|
|
162
162
|
- lib/ace/hitl/cli/commands/list.rb
|
|
163
|
+
- lib/ace/hitl/cli/commands/observe.rb
|
|
163
164
|
- lib/ace/hitl/cli/commands/operator_question.rb
|
|
164
165
|
- lib/ace/hitl/cli/commands/pending.rb
|
|
165
166
|
- lib/ace/hitl/cli/commands/read.rb
|
|
@@ -198,6 +199,7 @@ files:
|
|
|
198
199
|
- lib/ace/hitl/lifecycle/tls_service.rb
|
|
199
200
|
- lib/ace/hitl/live_client.rb
|
|
200
201
|
- lib/ace/hitl/models/hitl_event.rb
|
|
202
|
+
- lib/ace/hitl/molecules/event_observation.rb
|
|
201
203
|
- lib/ace/hitl/molecules/hitl_address_resolver.rb
|
|
202
204
|
- lib/ace/hitl/molecules/hitl_answer_editor.rb
|
|
203
205
|
- lib/ace/hitl/molecules/hitl_config_loader.rb
|