ace-hitl 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 +7 -0
- data/.ace-defaults/hitl/config.yml +3 -0
- data/.ace-defaults/nav/protocols/skill-sources/ace-hitl.yml +13 -0
- data/.ace-defaults/nav/protocols/wfi-sources/ace-hitl.yml +13 -0
- data/CHANGELOG.md +128 -0
- data/README.md +42 -0
- data/Rakefile +10 -0
- data/docs/demo/ace-hitl-scope-and-answer.tape.yml +37 -0
- data/docs/demo/fixtures/demo-context.md +7 -0
- data/docs/usage.md +112 -0
- data/exe/ace-hitl +18 -0
- data/handbook/README.md +14 -0
- data/handbook/skills/as-hitl/SKILL.md +29 -0
- data/handbook/workflow-instructions/hitl.wf.md +110 -0
- data/lib/ace/hitl/atoms/hitl_file_pattern.rb +20 -0
- data/lib/ace/hitl/atoms/hitl_id_formatter.rb +15 -0
- data/lib/ace/hitl/cli/commands/create.rb +76 -0
- data/lib/ace/hitl/cli/commands/list.rb +63 -0
- data/lib/ace/hitl/cli/commands/show.rb +79 -0
- data/lib/ace/hitl/cli/commands/update.rb +127 -0
- data/lib/ace/hitl/cli/commands/wait.rb +74 -0
- data/lib/ace/hitl/cli.rb +62 -0
- data/lib/ace/hitl/models/hitl_event.rb +32 -0
- data/lib/ace/hitl/molecules/hitl_answer_editor.rb +25 -0
- data/lib/ace/hitl/molecules/hitl_config_loader.rb +50 -0
- data/lib/ace/hitl/molecules/hitl_creator.rb +207 -0
- data/lib/ace/hitl/molecules/hitl_display_formatter.rb +53 -0
- data/lib/ace/hitl/molecules/hitl_loader.rb +113 -0
- data/lib/ace/hitl/molecules/hitl_resolver.rb +30 -0
- data/lib/ace/hitl/molecules/hitl_scanner.rb +42 -0
- data/lib/ace/hitl/molecules/resume_dispatcher.rb +99 -0
- data/lib/ace/hitl/molecules/worktree_scope_resolver.rb +77 -0
- data/lib/ace/hitl/organisms/hitl_manager.rb +462 -0
- data/lib/ace/hitl/version.rb +7 -0
- data/lib/ace/hitl.rb +24 -0
- metadata +164 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 96a4def785b91ef54a793fc989a19dc9e716dbf806129d82351bcf487245383c
|
|
4
|
+
data.tar.gz: 8f611901bbe6fc4ebf003baab73f0dff2de801c98f260011ceeeb4b655465af3
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 7a84118d6cbdd5fed6e868e0b2eff28dcdcc8cc41692feea61dfcd79bd37e84cc42f81d4dd63af122a42007770995cc85b0fbf29d6408d83cf5668997f803052
|
|
7
|
+
data.tar.gz: 857c322f44dab838002765b159112906d42f7708a308037fb5f5618c47cc21b5cd6547fec3b55e23ed7fc7306b583c8b17e9b94e71d822929290054c2bf612b3
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
# Skill Sources Protocol Configuration for ace-hitl gem
|
|
3
|
+
# This enables canonical skill discovery from the installed ace-hitl gem
|
|
4
|
+
|
|
5
|
+
name: ace-hitl
|
|
6
|
+
type: gem
|
|
7
|
+
description: Canonical skills from ace-hitl gem
|
|
8
|
+
priority: 10
|
|
9
|
+
|
|
10
|
+
config:
|
|
11
|
+
relative_path: handbook/skills
|
|
12
|
+
pattern: "*/SKILL.md"
|
|
13
|
+
enabled: true
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
# WFI Sources Protocol Configuration for ace-hitl gem
|
|
3
|
+
# This enables workflow discovery from the installed ace-hitl gem
|
|
4
|
+
|
|
5
|
+
name: ace-hitl
|
|
6
|
+
type: gem
|
|
7
|
+
description: HITL workflow instructions from ace-hitl gem
|
|
8
|
+
priority: 10
|
|
9
|
+
|
|
10
|
+
config:
|
|
11
|
+
relative_path: handbook/workflow-instructions
|
|
12
|
+
pattern: "*.wf.md"
|
|
13
|
+
enabled: true
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `ace-hitl` will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.8.0] - 2026-04-02
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- Changed `ace-hitl list` default status behavior to include all statuses in the selected folder scope when `--status` is omitted (instead of implicitly filtering to `pending`).
|
|
15
|
+
- Updated list row rendering to task-like compact output with leading status icons for each HITL event.
|
|
16
|
+
|
|
17
|
+
### Technical
|
|
18
|
+
|
|
19
|
+
- Updated list command/docs/workflow wording and command-level tests to reflect explicit pending filtering (`--status pending`) and icon-led row assertions.
|
|
20
|
+
|
|
21
|
+
## [0.7.0] - 2026-04-02
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- Renamed the canonical HITL object terminology from "item" to "event" across CLI help/output, package docs, and workflow instructions.
|
|
26
|
+
- Performed immediate API/contract cutover for `HitlManager` resolution payloads from `:item` to `:event`.
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
- Added a list-output stats footer (`HITL Events: ...`) for `ace-hitl list`, including empty-result output and filtered `X of Y` summaries.
|
|
31
|
+
- Added explicit lifecycle event naming contract documentation under the `hitl.event.*` namespace.
|
|
32
|
+
|
|
33
|
+
## [0.6.0] - 2026-04-02
|
|
34
|
+
|
|
35
|
+
### Changed
|
|
36
|
+
|
|
37
|
+
- Switched the default HITL runtime root from `.ace-hitl` to `.ace-local/hitl` to align with ACE local-artifact layout conventions.
|
|
38
|
+
|
|
39
|
+
### Technical
|
|
40
|
+
|
|
41
|
+
- Updated scope and status test fixtures that embedded legacy `.ace-hitl` paths to use `.ace-local/hitl`.
|
|
42
|
+
|
|
43
|
+
## [0.5.0] - 2026-04-02
|
|
44
|
+
|
|
45
|
+
### Added
|
|
46
|
+
|
|
47
|
+
- Added `ace-hitl wait <id>` polling support with per-event lease metadata (`waiter_*`) so agents wait only on their own HITL question IDs by default.
|
|
48
|
+
- Added requester session metadata capture (`requester_provider`, `requester_model`, `requester_session_id`) from assignment session traces during HITL creation.
|
|
49
|
+
- Added resume fallback dispatch plumbing for answered items through provider session resume and command fallback paths.
|
|
50
|
+
|
|
51
|
+
### Changed
|
|
52
|
+
|
|
53
|
+
- Extended `ace-hitl update` with `--resume` to dispatch answer handoff only when no active waiter lease is detected.
|
|
54
|
+
- Updated HITL workflow and usage docs to make polling the default reliability path and resume dispatch the explicit fallback path.
|
|
55
|
+
|
|
56
|
+
### Technical
|
|
57
|
+
|
|
58
|
+
- Added CLI/manager regression coverage for wait timeout/success paths and resume dispatch skip/dispatch behavior.
|
|
59
|
+
|
|
60
|
+
## [0.4.3] - 2026-04-02
|
|
61
|
+
|
|
62
|
+
### Changed
|
|
63
|
+
|
|
64
|
+
- Switched `ace-hitl` configuration loading to ACE shared namespace resolution (`Ace::Support::Config`), with defaults fallback behavior for resilience.
|
|
65
|
+
- Added a package-owned `handbook/` skeleton (`agents/`, `guides/`, `skills/`, `templates/`, `workflow-instructions/`) for architectural consistency.
|
|
66
|
+
|
|
67
|
+
### Fixed
|
|
68
|
+
|
|
69
|
+
- Collapsed combined `ace-hitl update` metadata and answer mutations into one locked read/mutate/write cycle to avoid double write passes.
|
|
70
|
+
|
|
71
|
+
### Technical
|
|
72
|
+
|
|
73
|
+
- Added `ace-support-config` as a runtime dependency in `ace-hitl.gemspec`.
|
|
74
|
+
|
|
75
|
+
## [0.4.2] - 2026-04-01
|
|
76
|
+
|
|
77
|
+
### Fixed
|
|
78
|
+
|
|
79
|
+
- Made `ace-hitl update` honor scoped multi-worktree resolution semantics (`--scope`) consistent with `show`.
|
|
80
|
+
- Prevented duplicate HITL IDs during rapid event creation by regenerating IDs when collisions are detected.
|
|
81
|
+
- Narrowed loader exception handling so programming errors surface instead of being silently treated as not-found.
|
|
82
|
+
|
|
83
|
+
### Technical
|
|
84
|
+
|
|
85
|
+
- Added CLI regression coverage for scoped `update` behavior and ID collision avoidance.
|
|
86
|
+
|
|
87
|
+
## [0.4.1] - 2026-04-01
|
|
88
|
+
|
|
89
|
+
### Technical
|
|
90
|
+
|
|
91
|
+
- Updated CLI version contract tests to assert the current `Ace::Hitl::VERSION` (`0.4.0`) after the 0.4.0 release line.
|
|
92
|
+
|
|
93
|
+
## [0.4.0] - 2026-04-01
|
|
94
|
+
|
|
95
|
+
### Added
|
|
96
|
+
|
|
97
|
+
- Added smart multi-worktree scope resolution for `ace-hitl list` and `ace-hitl show` with explicit `--scope current|all`.
|
|
98
|
+
- Added context-aware default scope behavior: linked worktrees default to current scope, main checkout defaults to all-scope operator view.
|
|
99
|
+
- Added strict all-scope ambiguity handling for `show` with candidate path reporting.
|
|
100
|
+
|
|
101
|
+
### Changed
|
|
102
|
+
|
|
103
|
+
- Changed `ace-hitl list` default behavior to show only `pending` items when `--status` is omitted.
|
|
104
|
+
- Changed `ace-hitl show` to perform local-first lookup with implicit all-scope fallback only when scope is not explicitly provided.
|
|
105
|
+
- Changed show output to include explicit resolved-location details for cross-worktree item resolution.
|
|
106
|
+
- Updated usage and README documentation to describe local-first HITL semantics versus global `ace-overseer` dashboard usage.
|
|
107
|
+
|
|
108
|
+
## [0.3.0] - 2026-04-01
|
|
109
|
+
|
|
110
|
+
### Added
|
|
111
|
+
|
|
112
|
+
- Implemented full HITL event store behavior with package-owned model/molecules/manager flow.
|
|
113
|
+
- Added complete CLI behavior for `create`, `list`, `show`, and `update` with filtering and mutation options.
|
|
114
|
+
- Added usage documentation for end-to-end item management flows.
|
|
115
|
+
|
|
116
|
+
### Fixed
|
|
117
|
+
|
|
118
|
+
- Corrected answer section updates to handle empty `## Answer` blocks and persist answer text reliably.
|
|
119
|
+
- Updated CLI tests to align with current package version and answer-write behavior.
|
|
120
|
+
|
|
121
|
+
## [0.2.0] - 2026-04-01
|
|
122
|
+
|
|
123
|
+
### Added
|
|
124
|
+
|
|
125
|
+
- Initial package skeleton for `ace-hitl`.
|
|
126
|
+
- Root and package executables (`bin/ace-hitl`, `ace-hitl/exe/ace-hitl`).
|
|
127
|
+
- Minimal CLI registry for `list`, `show`, `create`, and `update`.
|
|
128
|
+
- Baseline docs and config scaffold.
|
data/README.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# ace-hitl
|
|
2
|
+
|
|
3
|
+
`ace-hitl` manages ACE human-in-the-loop (HITL) events in `.ace-local/hitl/`.
|
|
4
|
+
|
|
5
|
+
Canonical workflow and skill for agents:
|
|
6
|
+
|
|
7
|
+
- Workflow: `wfi://hitl`
|
|
8
|
+
- Skill: `as-hitl`
|
|
9
|
+
|
|
10
|
+
## Commands
|
|
11
|
+
|
|
12
|
+
- `ace-hitl create` creates a HITL event
|
|
13
|
+
- `ace-hitl list` lists HITL events with filters (`--scope current|all`, all statuses by default)
|
|
14
|
+
- `ace-hitl show` renders event details, path, or raw content (`--scope current|all`)
|
|
15
|
+
- `ace-hitl update` updates frontmatter, answer content, and folder location
|
|
16
|
+
- `ace-hitl wait` polls a specific HITL event until answered (`--poll-every`, `--timeout`)
|
|
17
|
+
|
|
18
|
+
`ace-hitl` is a blocker-resolution tool, not a global dashboard:
|
|
19
|
+
|
|
20
|
+
- linked worktree default: local (`--scope current`)
|
|
21
|
+
- main checkout default: operator view (`--scope all`)
|
|
22
|
+
|
|
23
|
+
Use `ace-overseer status` for a global worktree dashboard.
|
|
24
|
+
|
|
25
|
+
## Examples
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
ace-hitl list
|
|
29
|
+
ace-hitl list --scope all
|
|
30
|
+
ace-hitl create "Which auth strategy?" --kind decision --question "JWT or sessions?"
|
|
31
|
+
ace-hitl show abc123 --content
|
|
32
|
+
ace-hitl show abc123 --scope current
|
|
33
|
+
ace-hitl update abc123 --answer "Use JWT with server-side refresh tokens."
|
|
34
|
+
ace-hitl wait abc123
|
|
35
|
+
ace-hitl update abc123 --answer "Use JWT with server-side refresh tokens." --resume
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Ownership Boundary
|
|
39
|
+
|
|
40
|
+
`ace-hitl` owns HITL-specific event semantics and markdown contract.
|
|
41
|
+
|
|
42
|
+
`ace-support-items` remains generic support infrastructure and should not absorb HITL-specific domain behavior.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Showcase ace-hitl scope-aware CLI surface and answer markdown preservation regression coverage
|
|
3
|
+
tags:
|
|
4
|
+
- ace-hitl
|
|
5
|
+
- feature-demo
|
|
6
|
+
- scope
|
|
7
|
+
settings:
|
|
8
|
+
font_size: 16
|
|
9
|
+
width: 1100
|
|
10
|
+
height: 620
|
|
11
|
+
format: gif
|
|
12
|
+
setup:
|
|
13
|
+
- sandbox
|
|
14
|
+
- copy-fixtures
|
|
15
|
+
scenes:
|
|
16
|
+
- name: Demo context
|
|
17
|
+
commands:
|
|
18
|
+
- type: cat fixtures/demo-context.md
|
|
19
|
+
sleep: 4s
|
|
20
|
+
- name: Show scope-aware list/show CLI flags
|
|
21
|
+
commands:
|
|
22
|
+
- type: clear
|
|
23
|
+
sleep: 1s
|
|
24
|
+
- type: ace-hitl list --help
|
|
25
|
+
sleep: 5s
|
|
26
|
+
- type: ace-hitl show --help
|
|
27
|
+
sleep: 5s
|
|
28
|
+
- name: Verify ambiguity and heading-preservation behavior
|
|
29
|
+
commands:
|
|
30
|
+
- type: clear
|
|
31
|
+
sleep: 1s
|
|
32
|
+
- type: ace-test test/commands/hitl_cli_test.rb --filter test_show_scope_all_errors_on_ambiguous_ref_with_candidates
|
|
33
|
+
sleep: 5s
|
|
34
|
+
- type: ace-test test/commands/hitl_cli_test.rb --filter test_update_answer_preserves_markdown_headings_in_answer_body
|
|
35
|
+
sleep: 5s
|
|
36
|
+
teardown:
|
|
37
|
+
- cleanup
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# ace-hitl scope + answer integrity demo
|
|
2
|
+
|
|
3
|
+
This demo highlights two user-facing outcomes from PR #275:
|
|
4
|
+
- `ace-hitl list/show` expose explicit scope controls for multi-worktree reads.
|
|
5
|
+
- Answer updates preserve markdown headings inside `## Answer` content.
|
|
6
|
+
|
|
7
|
+
Verification commands in the demo run focused CLI-contract tests.
|
data/docs/usage.md
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
---
|
|
2
|
+
doc-type: user
|
|
3
|
+
title: ace-hitl Usage Guide
|
|
4
|
+
purpose: Practical CLI usage reference for ace-hitl event creation, triage, and resolution
|
|
5
|
+
flows.
|
|
6
|
+
ace-docs:
|
|
7
|
+
last-updated: '2026-04-02'
|
|
8
|
+
last-checked: '2026-04-02'
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# ace-hitl Usage
|
|
12
|
+
|
|
13
|
+
Canonical handbook resources:
|
|
14
|
+
|
|
15
|
+
- Workflow: `wfi://hitl`
|
|
16
|
+
- Skill: `as-hitl`
|
|
17
|
+
|
|
18
|
+
Runtime store default: `.ace-local/hitl/` (legacy `.ace-hitl/` is no longer used as default).
|
|
19
|
+
|
|
20
|
+
## Create
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
ace-hitl create "Which auth strategy?" \
|
|
24
|
+
--kind decision \
|
|
25
|
+
--question "JWT or sessions?" \
|
|
26
|
+
--question "Refresh token storage?" \
|
|
27
|
+
--assignment 8qr5kx \
|
|
28
|
+
--step 020 \
|
|
29
|
+
--step-name implement-auth \
|
|
30
|
+
--resume "/as-assign-drive 8qr5kx"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Common completion-attention handoff:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
ace-hitl create "Review completed assignment results" \
|
|
37
|
+
--kind approval \
|
|
38
|
+
--question "Please confirm next action for 8qr5kx." \
|
|
39
|
+
--assignment 8qr5kx \
|
|
40
|
+
--step completion \
|
|
41
|
+
--step-name assignment-complete \
|
|
42
|
+
--resume "/as-assign-drive 8qr5kx"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## List
|
|
46
|
+
|
|
47
|
+
`ace-hitl list` is local-first by default:
|
|
48
|
+
|
|
49
|
+
- in a linked worktree: behaves like `--scope current`
|
|
50
|
+
- in the main checkout: behaves like `--scope all`
|
|
51
|
+
- if `--status` is omitted: includes all statuses in the selected folder scope
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
ace-hitl list
|
|
55
|
+
ace-hitl list --scope current
|
|
56
|
+
ace-hitl list --scope all
|
|
57
|
+
ace-hitl list --status pending
|
|
58
|
+
ace-hitl list --kind decision
|
|
59
|
+
ace-hitl list --kind clarification --status pending
|
|
60
|
+
ace-hitl list --tags auth,security
|
|
61
|
+
ace-hitl list --in archive
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Show
|
|
65
|
+
|
|
66
|
+
`ace-hitl show` also accepts `--scope current|all`.
|
|
67
|
+
Without `--scope`, lookup is local-first; if not found and smart scope is active, it retries across all worktrees.
|
|
68
|
+
When lookup resolves outside the current worktree, output includes an explicit `Resolved Location:` line.
|
|
69
|
+
When using `--scope all`, ambiguous matches return an error with candidate paths so the operator can select the intended event explicitly.
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
ace-hitl show abc123
|
|
73
|
+
ace-hitl show abc123 --scope current
|
|
74
|
+
ace-hitl show abc123 --scope all
|
|
75
|
+
ace-hitl show abc123 --path
|
|
76
|
+
ace-hitl show abc123 --content
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Update
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
ace-hitl update abc123 --set status=in-progress
|
|
83
|
+
ace-hitl update abc123 --add tags=reviewed
|
|
84
|
+
ace-hitl update abc123 --remove tags=stale
|
|
85
|
+
ace-hitl update abc123 --answer "Use JWT with server-side refresh tokens."
|
|
86
|
+
ace-hitl update abc123 --move-to archive
|
|
87
|
+
ace-hitl update abc123 --move-to next
|
|
88
|
+
ace-hitl update abc123 --answer "close the assignment" --resume
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Wait (Polling Default)
|
|
92
|
+
|
|
93
|
+
Wait only for a specific HITL id. This is the default reliability path for the requester agent.
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
ace-hitl wait abc123
|
|
97
|
+
ace-hitl wait abc123 --poll-every 600 --timeout 14400
|
|
98
|
+
ace-hitl wait abc123 --scope current
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Lifecycle Event Names
|
|
102
|
+
|
|
103
|
+
Canonical namespace for HITL lifecycle signaling:
|
|
104
|
+
|
|
105
|
+
- `hitl.event.created`
|
|
106
|
+
- `hitl.event.answered`
|
|
107
|
+
- `hitl.event.wait_started`
|
|
108
|
+
- `hitl.event.wait_timed_out`
|
|
109
|
+
- `hitl.event.resume_dispatched`
|
|
110
|
+
- `hitl.event.resume_skipped_waiter_active`
|
|
111
|
+
- `hitl.event.resume_failed`
|
|
112
|
+
- `hitl.event.archived`
|
data/exe/ace-hitl
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require_relative "../lib/ace/hitl"
|
|
5
|
+
|
|
6
|
+
args = ARGV.empty? ? ["--help"] : ARGV
|
|
7
|
+
|
|
8
|
+
trap("INT") { exit 130 }
|
|
9
|
+
|
|
10
|
+
begin
|
|
11
|
+
Ace::Hitl::HitlCLI.start(args)
|
|
12
|
+
rescue Ace::Support::Cli::Error => e
|
|
13
|
+
warn e.message
|
|
14
|
+
exit(e.exit_code)
|
|
15
|
+
rescue ArgumentError => e
|
|
16
|
+
warn "Error: #{e.message}"
|
|
17
|
+
exit(1)
|
|
18
|
+
end
|
data/handbook/README.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# ace-hitl Handbook
|
|
2
|
+
|
|
3
|
+
Package-owned handbook skeleton for HITL workflows, skills, and guides.
|
|
4
|
+
|
|
5
|
+
- `agents/`: package-local agent definitions
|
|
6
|
+
- `workflow-instructions/`: canonical HITL workflows (`.wf.md`)
|
|
7
|
+
- `skills/`: canonical skill definitions (`SKILL.md`)
|
|
8
|
+
- `guides/`: package-specific guidance docs (`.g.md`)
|
|
9
|
+
- `templates/`: reusable prompt/doc templates
|
|
10
|
+
|
|
11
|
+
Current canonical entries:
|
|
12
|
+
|
|
13
|
+
- `wfi://hitl`
|
|
14
|
+
- `as-hitl`
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: as-hitl
|
|
3
|
+
description: Manage human-attention blockers and completion handoffs with ace-hitl
|
|
4
|
+
# bundle: wfi://hitl
|
|
5
|
+
# agent: general-purpose
|
|
6
|
+
user-invocable: true
|
|
7
|
+
allowed-tools:
|
|
8
|
+
- Bash(ace-hitl:*)
|
|
9
|
+
- Bash(ace-assign:*)
|
|
10
|
+
- Bash(ace-bundle:*)
|
|
11
|
+
- Read
|
|
12
|
+
argument-hint: "[create|list|show|update] [options]"
|
|
13
|
+
last_modified: 2026-04-02
|
|
14
|
+
source: ace-hitl
|
|
15
|
+
integration:
|
|
16
|
+
targets:
|
|
17
|
+
- claude
|
|
18
|
+
- codex
|
|
19
|
+
- gemini
|
|
20
|
+
- opencode
|
|
21
|
+
- pi
|
|
22
|
+
providers: {}
|
|
23
|
+
skill:
|
|
24
|
+
kind: workflow
|
|
25
|
+
execution:
|
|
26
|
+
workflow: wfi://hitl
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
Load and run `ace-bundle wfi://hitl` in the current project, then follow the loaded workflow as the source of truth and execute it end-to-end instead of only summarizing it.
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
---
|
|
2
|
+
doc-type: workflow
|
|
3
|
+
title: HITL Workflow
|
|
4
|
+
purpose: Standardize human-attention handling for blocked and completed work using ace-hitl events.
|
|
5
|
+
ace-docs:
|
|
6
|
+
last-updated: '2026-04-02'
|
|
7
|
+
last-checked: '2026-04-02'
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# HITL Workflow
|
|
11
|
+
|
|
12
|
+
## Goal
|
|
13
|
+
|
|
14
|
+
Use `ace-hitl` as the canonical contract whenever agent flow needs explicit human attention.
|
|
15
|
+
|
|
16
|
+
## When To Use HITL
|
|
17
|
+
|
|
18
|
+
Create a HITL event in exactly two cases:
|
|
19
|
+
|
|
20
|
+
1. **Blocker requiring human judgment** (ambiguity, product decision, policy/approval gate).
|
|
21
|
+
2. **Work is complete but explicit user attention is required** before follow-up actions.
|
|
22
|
+
|
|
23
|
+
Do not create HITL events for routine status updates that do not require user action.
|
|
24
|
+
|
|
25
|
+
## Commands
|
|
26
|
+
|
|
27
|
+
### 1) Create a blocker HITL
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
ace-hitl create "Need product decision" \
|
|
31
|
+
--kind decision \
|
|
32
|
+
--question "Should retries be visible?" \
|
|
33
|
+
--assignment <assignment-id> \
|
|
34
|
+
--step <step-number> \
|
|
35
|
+
--step-name <step-name> \
|
|
36
|
+
--resume "/as-assign-drive <assignment-id>"
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
If the active assignment step is blocked, fail it using canonical format:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
ace-assign fail --message "HITL: <hitl-id> <hitl-path>" --assignment "<assignment-id>"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### 2) Create a completion-attention HITL
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
ace-hitl create "Review completed assignment results" \
|
|
49
|
+
--kind approval \
|
|
50
|
+
--question "Please confirm next action for <assignment-id>." \
|
|
51
|
+
--assignment <assignment-id> \
|
|
52
|
+
--step completion \
|
|
53
|
+
--step-name assignment-complete \
|
|
54
|
+
--resume "/as-assign-drive <assignment-id>"
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### 3) Discover HITL work
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
ace-hitl list
|
|
61
|
+
ace-hitl list --scope current
|
|
62
|
+
ace-hitl list --scope all
|
|
63
|
+
ace-hitl list --status pending
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### 4) Resolve and archive
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
ace-hitl show <hitl-id>
|
|
70
|
+
ace-hitl update <hitl-id> --answer "<human decision>"
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Polling is the default reliability path for the requesting agent:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
ace-hitl wait <hitl-id>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
If the waiter is no longer active, operator fallback can dispatch resume:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
ace-hitl update <hitl-id> --answer "<human decision>" --resume
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Completion Contract
|
|
86
|
+
|
|
87
|
+
After answer is applied:
|
|
88
|
+
|
|
89
|
+
- Continue normal assignment retry/resume flow.
|
|
90
|
+
- Keep `ace-assign` mechanics unchanged (no paused assignment state).
|
|
91
|
+
- Archive HITL event after resolution.
|
|
92
|
+
|
|
93
|
+
## Event Names
|
|
94
|
+
|
|
95
|
+
Canonical lifecycle namespace: `hitl.event.*`
|
|
96
|
+
|
|
97
|
+
- `hitl.event.created`
|
|
98
|
+
- `hitl.event.answered`
|
|
99
|
+
- `hitl.event.wait_started`
|
|
100
|
+
- `hitl.event.wait_timed_out`
|
|
101
|
+
- `hitl.event.resume_dispatched`
|
|
102
|
+
- `hitl.event.resume_skipped_waiter_active`
|
|
103
|
+
- `hitl.event.resume_failed`
|
|
104
|
+
- `hitl.event.archived`
|
|
105
|
+
|
|
106
|
+
## Success Criteria
|
|
107
|
+
|
|
108
|
+
- Blockers always produce canonical `HITL: <id> <path>` failure reason.
|
|
109
|
+
- Human-required completion handoffs generate approval HITL events.
|
|
110
|
+
- Resolved HITL events are archived only after successful resume dispatch.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ace
|
|
4
|
+
module Hitl
|
|
5
|
+
module Atoms
|
|
6
|
+
class HitlFilePattern
|
|
7
|
+
FILE_EXTENSION = ".hitl.s.md"
|
|
8
|
+
FILE_GLOB = "*#{FILE_EXTENSION}"
|
|
9
|
+
|
|
10
|
+
def self.folder_name(id, slug)
|
|
11
|
+
slug.nil? || slug.empty? ? id : "#{id}-#{slug}"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.filename(id, slug)
|
|
15
|
+
"#{folder_name(id, slug)}#{FILE_EXTENSION}"
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "ace/support/cli"
|
|
4
|
+
|
|
5
|
+
module Ace
|
|
6
|
+
module Hitl
|
|
7
|
+
module CLI
|
|
8
|
+
module Commands
|
|
9
|
+
class Create < Ace::Support::Cli::Command
|
|
10
|
+
include Ace::Support::Cli::Base
|
|
11
|
+
|
|
12
|
+
desc "Create HITL event"
|
|
13
|
+
|
|
14
|
+
argument :title, required: false, desc: "HITL event title"
|
|
15
|
+
|
|
16
|
+
option :kind, type: :string, aliases: %w[-k], desc: "Kind: clarification, decision, approval"
|
|
17
|
+
option :question, type: :string, repeat: true, aliases: %w[-Q], desc: "Question line (repeatable)"
|
|
18
|
+
option :tags, type: :string, aliases: %w[-T], desc: "Comma-separated tags"
|
|
19
|
+
option :assignment, type: :string, desc: "Assignment reference"
|
|
20
|
+
option :step, type: :string, desc: "Step number"
|
|
21
|
+
option :"step-name", type: :string, desc: "Step name"
|
|
22
|
+
option :resume, type: :string, desc: "Resume instructions"
|
|
23
|
+
option :"move-to", type: :string, aliases: %w[-m], desc: "Target folder (archive, next)"
|
|
24
|
+
|
|
25
|
+
option :quiet, type: :boolean, aliases: %w[-q], desc: "Suppress non-essential output"
|
|
26
|
+
option :verbose, type: :boolean, aliases: %w[-v], desc: "Show verbose output"
|
|
27
|
+
option :debug, type: :boolean, aliases: %w[-d], desc: "Show debug output"
|
|
28
|
+
|
|
29
|
+
def call(title: nil, **options)
|
|
30
|
+
unless title && !title.strip.empty?
|
|
31
|
+
raise Ace::Support::Cli::Error.new("Title required")
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
kind = options[:kind]
|
|
35
|
+
validate_kind!(kind) if kind
|
|
36
|
+
|
|
37
|
+
questions = Array(options[:question]).map(&:strip).reject(&:empty?)
|
|
38
|
+
tags = parse_tags(options[:tags])
|
|
39
|
+
|
|
40
|
+
manager = Ace::Hitl::Organisms::HitlManager.new
|
|
41
|
+
event = manager.create(
|
|
42
|
+
title,
|
|
43
|
+
kind: kind,
|
|
44
|
+
questions: questions,
|
|
45
|
+
tags: tags,
|
|
46
|
+
assignment: options[:assignment],
|
|
47
|
+
step: options[:step],
|
|
48
|
+
step_name: options[:"step-name"],
|
|
49
|
+
resume_instructions: options[:resume],
|
|
50
|
+
move_to: options[:"move-to"]
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
folder_info = event.special_folder ? " (#{event.special_folder})" : ""
|
|
54
|
+
puts "HITL event created: #{event.id} #{event.title}#{folder_info}"
|
|
55
|
+
puts " Path: #{event.file_path}"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
private
|
|
59
|
+
|
|
60
|
+
def validate_kind!(kind)
|
|
61
|
+
allowed = %w[clarification decision approval]
|
|
62
|
+
return if allowed.include?(kind)
|
|
63
|
+
|
|
64
|
+
raise Ace::Support::Cli::Error.new("Invalid kind '#{kind}'. Allowed: #{allowed.join(", ")}")
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def parse_tags(raw)
|
|
68
|
+
return [] unless raw
|
|
69
|
+
|
|
70
|
+
raw.split(",").map(&:strip).reject(&:empty?)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|