ace-hitl 0.13.0 → 0.14.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/.ace-defaults/hitl/config.yml +0 -0
- data/.ace-defaults/nav/protocols/skill-sources/ace-hitl.yml +0 -0
- data/.ace-defaults/nav/protocols/wfi-sources/ace-hitl.yml +0 -0
- data/CHANGELOG.md +21 -0
- data/Rakefile +0 -0
- data/docs/demo/ace-hitl-scope-and-answer.tape.yml +0 -0
- data/docs/demo/fixtures/demo-context.md +0 -0
- data/docs/usage.md +8 -2
- data/handbook/README.md +0 -0
- data/handbook/skills/as-hitl/SKILL.md +0 -0
- data/handbook/workflow-instructions/hitl.wf.md +0 -0
- data/lib/ace/hitl/atoms/hitl_effect_validator.rb +0 -0
- data/lib/ace/hitl/atoms/hitl_file_pattern.rb +0 -0
- data/lib/ace/hitl/atoms/hitl_id_formatter.rb +0 -0
- data/lib/ace/hitl/cli/commands/create.rb +0 -0
- data/lib/ace/hitl/cli/commands/list.rb +0 -0
- data/lib/ace/hitl/cli/commands/serve.rb +2 -0
- data/lib/ace/hitl/cli/commands/show.rb +0 -0
- data/lib/ace/hitl/lifecycle/service.rb +9 -11
- data/lib/ace/hitl/lifecycle/store.rb +18 -2
- data/lib/ace/hitl/models/hitl_event.rb +0 -0
- data/lib/ace/hitl/molecules/hitl_answer_editor.rb +0 -0
- data/lib/ace/hitl/molecules/hitl_config_loader.rb +0 -0
- data/lib/ace/hitl/molecules/hitl_creator.rb +0 -0
- data/lib/ace/hitl/molecules/hitl_display_formatter.rb +0 -0
- data/lib/ace/hitl/molecules/hitl_loader.rb +0 -0
- data/lib/ace/hitl/molecules/hitl_resolver.rb +0 -0
- data/lib/ace/hitl/molecules/hitl_scanner.rb +0 -0
- data/lib/ace/hitl/molecules/resume_dispatcher.rb +0 -0
- data/lib/ace/hitl/molecules/worktree_scope_resolver.rb +0 -0
- data/lib/ace/hitl/version.rb +1 -1
- metadata +8 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d921414979ccc0569dbfc0c8e102b3aa29c929f5e9ccde725968dc2a7227da9a
|
|
4
|
+
data.tar.gz: fb5c118b0f25a93507602223c5fb7f0751149883c4ead52ab96018d2651e4664
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 67d4f65668300b1c111937e9f0dd11aa4ab11684db06c0cbe65cc2f73d227601985b32734bcd21849e82740a7bf44133fbdeb4bd860c45836e2f8cd541874d25
|
|
7
|
+
data.tar.gz: a7ee80f146804aedf4f7f14d901c6678cee3e8de3d909feb79ef189b5c36a97980a3ce0892760943533907bbce766847848492f3c8e9f8578064ba859261f699
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.14.0] - 2026-10-11
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Add `ace-hitl serve --group` so each repository authority can expose its lifecycle socket through a dedicated control group.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- Direct unsafe socket-directory failures to dedicated service-owned directories that do not contain unrelated service sockets.
|
|
19
|
+
- Apply the configured authority group to root-owned public lifecycle projections as well as the service socket.
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- Refuse startup if the configured socket group cannot be resolved or assigned, and retag existing public projections to the configured group before serving.
|
|
24
|
+
|
|
25
|
+
## [0.13.1] - 2026-10-10
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
|
|
29
|
+
- Require the published producer and consumer patch versions containing the protected context and managed-attempt APIs; exclude incompatible prior dependency graphs.
|
|
30
|
+
|
|
10
31
|
## [0.13.0] - 2026-10-08
|
|
11
32
|
|
|
12
33
|
### Added
|
data/Rakefile
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
data/docs/usage.md
CHANGED
|
@@ -170,10 +170,16 @@ document — the same file and traversal trust rules as ace-lab
|
|
|
170
170
|
|
|
171
171
|
```bash
|
|
172
172
|
# Deployment (root runs the service under its own account):
|
|
173
|
-
ace-hitl serve
|
|
174
|
-
|
|
173
|
+
ace-hitl serve --socket /run/ace-hitl-project/lifecycle.sock \
|
|
174
|
+
--store-root /var/lib/ace-hitl-project --group ace-hitl-project
|
|
175
|
+
# ACE_HITL_SOCKET, ACE_HITL_STORE_ROOT and ACE_HITL_GRANTS_PATH may supply paths.
|
|
175
176
|
```
|
|
176
177
|
|
|
178
|
+
Give each authority a dedicated service/root-owned, non-world-writable socket
|
|
179
|
+
directory and a dedicated control group. Do not place its socket in `/run/lab`
|
|
180
|
+
or another directory containing unrelated service sockets: granting the
|
|
181
|
+
transport access to that directory's shared group can expose those endpoints.
|
|
182
|
+
|
|
177
183
|
Store layout (all service-owned): `0711` traverse-only root;
|
|
178
184
|
`requests/ answers/ secrets/ effects/ locks/ terminals/` are `0700`;
|
|
179
185
|
`public/` is `0755` with `0440` non-secret projections. There is no
|
data/handbook/README.md
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -19,6 +19,7 @@ module Ace
|
|
|
19
19
|
desc "Run the authenticated HITL store boundary service (peer-credential access)"
|
|
20
20
|
|
|
21
21
|
option :socket, type: :string, desc: "Boundary socket path (default: ACE_HITL_SOCKET or /run/lab/hitl.sock)"
|
|
22
|
+
option :group, type: :string, desc: "Dedicated control group allowed to connect (default: lab-control)"
|
|
22
23
|
option :store_root, type: :string, desc: "Private store root (default: ACE_HITL_STORE_ROOT or /run/lab/hitl)"
|
|
23
24
|
option :grants_path, type: :string, desc: "Trusted grants document (default: ACE_HITL_GRANTS_PATH or /etc/lab/ace-lab/authorization.yml)"
|
|
24
25
|
option :repo_root, type: :string, desc: "Candidate repository for the managed attempt authority"
|
|
@@ -41,6 +42,7 @@ module Ace
|
|
|
41
42
|
binding: binding_policy,
|
|
42
43
|
policy: policy,
|
|
43
44
|
socket_path: socket_path(options),
|
|
45
|
+
group: options[:group] || Lifecycle::Store::DEFAULT_GROUP,
|
|
44
46
|
logger: options[:verbose] ? ->(message) { warn message } : nil
|
|
45
47
|
)
|
|
46
48
|
service.run
|
|
File without changes
|
|
@@ -139,22 +139,19 @@ module Ace
|
|
|
139
139
|
|
|
140
140
|
def prepare!
|
|
141
141
|
begin
|
|
142
|
+
group_id = Etc.getgrnam(@group).gid
|
|
142
143
|
verify_socket_directory!
|
|
143
144
|
acquire_endpoint_lock!
|
|
144
145
|
recover_stale_endpoint!
|
|
145
146
|
@server = UNIXServer.open(@socket_path)
|
|
146
147
|
@endpoint_identity = endpoint_identity
|
|
148
|
+
File.chown(nil, group_id, @socket_path)
|
|
149
|
+
File.chmod(DEFAULT_SOCKET_MODE, @socket_path)
|
|
150
|
+
rescue ArgumentError => e
|
|
151
|
+
raise TransportError, "the HITL boundary control group is unavailable (#{e.message})"
|
|
147
152
|
rescue SystemCallError, IOError => e
|
|
148
153
|
raise TransportError, "the HITL boundary endpoint is not usable (#{e.class}: #{e.message})"
|
|
149
154
|
end
|
|
150
|
-
File.chmod(DEFAULT_SOCKET_MODE, @socket_path)
|
|
151
|
-
begin
|
|
152
|
-
File.chown(nil, Etc.getgrnam(@group).gid, @socket_path)
|
|
153
|
-
rescue ArgumentError, SystemCallError
|
|
154
|
-
# A service that cannot set the control group keeps the
|
|
155
|
-
# owner-only socket; the peer-credential gate still applies.
|
|
156
|
-
nil
|
|
157
|
-
end
|
|
158
155
|
begin
|
|
159
156
|
root_store.ensure_layout!
|
|
160
157
|
rescue SystemCallError => e
|
|
@@ -204,7 +201,8 @@ module Ace
|
|
|
204
201
|
|
|
205
202
|
raise TransportError,
|
|
206
203
|
"HITL boundary socket directory is not protected: #{dir} " \
|
|
207
|
-
"(
|
|
204
|
+
"(use a dedicated service/root-owned, non-world-writable directory; " \
|
|
205
|
+
"do not share a directory containing unrelated service sockets)"
|
|
208
206
|
end
|
|
209
207
|
|
|
210
208
|
def authenticate!(socket)
|
|
@@ -236,7 +234,7 @@ module Ace
|
|
|
236
234
|
policy: @policy,
|
|
237
235
|
identity: peer,
|
|
238
236
|
vault: @vault,
|
|
239
|
-
proposal_clock: @proposal_clock, stopping: -> { @stopping }
|
|
237
|
+
proposal_clock: @proposal_clock, stopping: -> { @stopping }, group: @group
|
|
240
238
|
)
|
|
241
239
|
end
|
|
242
240
|
|
|
@@ -371,7 +369,7 @@ module Ace
|
|
|
371
369
|
end
|
|
372
370
|
|
|
373
371
|
def root_store
|
|
374
|
-
Store.new(root: @root, binding: @binding, policy: @policy)
|
|
372
|
+
Store.new(root: @root, binding: @binding, policy: @policy, group: @group)
|
|
375
373
|
end
|
|
376
374
|
|
|
377
375
|
def log(message)
|
|
@@ -79,7 +79,8 @@ module Ace
|
|
|
79
79
|
|
|
80
80
|
def initialize(root:, binding:, policy: AccessPolicy.new,
|
|
81
81
|
identity: Identity, ownership: AtomicJson::DEFAULT_OWNERSHIP,
|
|
82
|
-
poll_seconds: CONSUME_POLL_SECONDS, vault: :file, proposal_clock: -> { Time.now.utc },
|
|
82
|
+
poll_seconds: CONSUME_POLL_SECONDS, vault: :file, proposal_clock: -> { Time.now.utc },
|
|
83
|
+
stopping: -> { false }, group: DEFAULT_GROUP)
|
|
83
84
|
raise ArgumentError, "a binding policy is required (fail closed without one)" unless binding
|
|
84
85
|
raise ArgumentError, "an access policy is required (fail closed without one)" unless policy
|
|
85
86
|
|
|
@@ -92,6 +93,7 @@ module Ace
|
|
|
92
93
|
@vault = vault == :file ? OtpVault::FileVault : vault
|
|
93
94
|
@proposal_clock = proposal_clock
|
|
94
95
|
@stopping = stopping
|
|
96
|
+
@group = group
|
|
95
97
|
end
|
|
96
98
|
|
|
97
99
|
# ---- requester side ------------------------------------------------
|
|
@@ -585,6 +587,7 @@ module Ace
|
|
|
585
587
|
FileUtils.mkdir_p(dir)
|
|
586
588
|
File.chmod(mode, dir)
|
|
587
589
|
end
|
|
590
|
+
retag_public_projections! if @identity.root?
|
|
588
591
|
nil
|
|
589
592
|
end
|
|
590
593
|
|
|
@@ -1083,7 +1086,20 @@ module Ace
|
|
|
1083
1086
|
end
|
|
1084
1087
|
|
|
1085
1088
|
def group_id
|
|
1086
|
-
@group_id ||= @identity.group_id(
|
|
1089
|
+
@group_id ||= @identity.group_id(@group)
|
|
1090
|
+
end
|
|
1091
|
+
|
|
1092
|
+
def retag_public_projections!
|
|
1093
|
+
public_dir.children.each do |path|
|
|
1094
|
+
next unless path.basename.to_s.end_with?(".json")
|
|
1095
|
+
|
|
1096
|
+
stat = File.lstat(path)
|
|
1097
|
+
unless stat.file? && !stat.symlink?
|
|
1098
|
+
raise StateError, "public lifecycle projection is not a regular file"
|
|
1099
|
+
end
|
|
1100
|
+
File.chmod(PUBLIC_MODE, path)
|
|
1101
|
+
@ownership.chown(path, AtomicJson::Ownership.new(uid: stat.uid, gid: group_id))
|
|
1102
|
+
end
|
|
1087
1103
|
end
|
|
1088
1104
|
end
|
|
1089
1105
|
end
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
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.14.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-12 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: ace-hitl-contract
|
|
@@ -15,14 +15,14 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - "~>"
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version:
|
|
18
|
+
version: 0.2.1
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - "~>"
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version:
|
|
25
|
+
version: 0.2.1
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
27
|
name: ace-support-core
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -113,28 +113,28 @@ dependencies:
|
|
|
113
113
|
requirements:
|
|
114
114
|
- - "~>"
|
|
115
115
|
- !ruby/object:Gem::Version
|
|
116
|
-
version: '0.
|
|
116
|
+
version: '0.67'
|
|
117
117
|
type: :runtime
|
|
118
118
|
prerelease: false
|
|
119
119
|
version_requirements: !ruby/object:Gem::Requirement
|
|
120
120
|
requirements:
|
|
121
121
|
- - "~>"
|
|
122
122
|
- !ruby/object:Gem::Version
|
|
123
|
-
version: '0.
|
|
123
|
+
version: '0.67'
|
|
124
124
|
- !ruby/object:Gem::Dependency
|
|
125
125
|
name: ace-herdr
|
|
126
126
|
requirement: !ruby/object:Gem::Requirement
|
|
127
127
|
requirements:
|
|
128
128
|
- - "~>"
|
|
129
129
|
- !ruby/object:Gem::Version
|
|
130
|
-
version:
|
|
130
|
+
version: 0.5.1
|
|
131
131
|
type: :runtime
|
|
132
132
|
prerelease: false
|
|
133
133
|
version_requirements: !ruby/object:Gem::Requirement
|
|
134
134
|
requirements:
|
|
135
135
|
- - "~>"
|
|
136
136
|
- !ruby/object:Gem::Version
|
|
137
|
-
version:
|
|
137
|
+
version: 0.5.1
|
|
138
138
|
description: Provides the dedicated ace-hitl package surface for human in the loop
|
|
139
139
|
(HITL) semantics and CLI workflows.
|
|
140
140
|
email:
|