agent-run-supervisor 0.1.0__tar.gz

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.
Files changed (65) hide show
  1. agent_run_supervisor-0.1.0/LICENSE +21 -0
  2. agent_run_supervisor-0.1.0/PKG-INFO +311 -0
  3. agent_run_supervisor-0.1.0/README.md +285 -0
  4. agent_run_supervisor-0.1.0/pyproject.toml +48 -0
  5. agent_run_supervisor-0.1.0/setup.cfg +4 -0
  6. agent_run_supervisor-0.1.0/src/agent_run_supervisor/__init__.py +5 -0
  7. agent_run_supervisor-0.1.0/src/agent_run_supervisor/__main__.py +3 -0
  8. agent_run_supervisor-0.1.0/src/agent_run_supervisor/caller.py +301 -0
  9. agent_run_supervisor-0.1.0/src/agent_run_supervisor/cli.py +192 -0
  10. agent_run_supervisor-0.1.0/src/agent_run_supervisor/commands.py +381 -0
  11. agent_run_supervisor-0.1.0/src/agent_run_supervisor/event_store.py +159 -0
  12. agent_run_supervisor-0.1.0/src/agent_run_supervisor/exit_classifier.py +137 -0
  13. agent_run_supervisor-0.1.0/src/agent_run_supervisor/fixtures/acpx-0.12.0/success-codex-sentinel/stdout.ndjson +15 -0
  14. agent_run_supervisor-0.1.0/src/agent_run_supervisor/hermes_caller/__init__.py +74 -0
  15. agent_run_supervisor-0.1.0/src/agent_run_supervisor/hermes_caller/events.py +245 -0
  16. agent_run_supervisor-0.1.0/src/agent_run_supervisor/hermes_caller/feishu_adapter.py +61 -0
  17. agent_run_supervisor-0.1.0/src/agent_run_supervisor/hermes_caller/hermes.py +135 -0
  18. agent_run_supervisor-0.1.0/src/agent_run_supervisor/hermes_caller/intake.py +136 -0
  19. agent_run_supervisor-0.1.0/src/agent_run_supervisor/hermes_caller/task.py +21 -0
  20. agent_run_supervisor-0.1.0/src/agent_run_supervisor/hermes_caller/verdict.py +93 -0
  21. agent_run_supervisor-0.1.0/src/agent_run_supervisor/hermes_caller/view_model.py +144 -0
  22. agent_run_supervisor-0.1.0/src/agent_run_supervisor/live_stream.py +131 -0
  23. agent_run_supervisor-0.1.0/src/agent_run_supervisor/parser.py +487 -0
  24. agent_run_supervisor-0.1.0/src/agent_run_supervisor/policy.py +291 -0
  25. agent_run_supervisor-0.1.0/src/agent_run_supervisor/preflight.py +493 -0
  26. agent_run_supervisor-0.1.0/src/agent_run_supervisor/process_liveness.py +240 -0
  27. agent_run_supervisor-0.1.0/src/agent_run_supervisor/redaction.py +134 -0
  28. agent_run_supervisor-0.1.0/src/agent_run_supervisor/result.py +77 -0
  29. agent_run_supervisor-0.1.0/src/agent_run_supervisor/retention.py +455 -0
  30. agent_run_supervisor-0.1.0/src/agent_run_supervisor/role.py +327 -0
  31. agent_run_supervisor-0.1.0/src/agent_run_supervisor/runner.py +800 -0
  32. agent_run_supervisor-0.1.0/src/agent_run_supervisor/session.py +583 -0
  33. agent_run_supervisor-0.1.0/src/agent_run_supervisor/session_runtime.py +780 -0
  34. agent_run_supervisor-0.1.0/src/agent_run_supervisor/workspace.py +105 -0
  35. agent_run_supervisor-0.1.0/src/agent_run_supervisor.egg-info/PKG-INFO +311 -0
  36. agent_run_supervisor-0.1.0/src/agent_run_supervisor.egg-info/SOURCES.txt +63 -0
  37. agent_run_supervisor-0.1.0/src/agent_run_supervisor.egg-info/dependency_links.txt +1 -0
  38. agent_run_supervisor-0.1.0/src/agent_run_supervisor.egg-info/entry_points.txt +2 -0
  39. agent_run_supervisor-0.1.0/src/agent_run_supervisor.egg-info/requires.txt +7 -0
  40. agent_run_supervisor-0.1.0/src/agent_run_supervisor.egg-info/top_level.txt +1 -0
  41. agent_run_supervisor-0.1.0/tests/test_caller.py +414 -0
  42. agent_run_supervisor-0.1.0/tests/test_cli_commands.py +889 -0
  43. agent_run_supervisor-0.1.0/tests/test_cli_smoke.py +67 -0
  44. agent_run_supervisor-0.1.0/tests/test_event_store.py +125 -0
  45. agent_run_supervisor-0.1.0/tests/test_exit_classifier.py +93 -0
  46. agent_run_supervisor-0.1.0/tests/test_live_event_stream.py +328 -0
  47. agent_run_supervisor-0.1.0/tests/test_parser.py +293 -0
  48. agent_run_supervisor-0.1.0/tests/test_parser_incremental.py +123 -0
  49. agent_run_supervisor-0.1.0/tests/test_policy.py +458 -0
  50. agent_run_supervisor-0.1.0/tests/test_preflight.py +384 -0
  51. agent_run_supervisor-0.1.0/tests/test_process_liveness.py +213 -0
  52. agent_run_supervisor-0.1.0/tests/test_redaction.py +77 -0
  53. agent_run_supervisor-0.1.0/tests/test_result_event_schema.py +72 -0
  54. agent_run_supervisor-0.1.0/tests/test_retention.py +384 -0
  55. agent_run_supervisor-0.1.0/tests/test_role.py +228 -0
  56. agent_run_supervisor-0.1.0/tests/test_runner_dry_run.py +155 -0
  57. agent_run_supervisor-0.1.0/tests/test_runner_exec.py +368 -0
  58. agent_run_supervisor-0.1.0/tests/test_session_runtime.py +1135 -0
  59. agent_run_supervisor-0.1.0/tests/test_session_store.py +1048 -0
  60. agent_run_supervisor-0.1.0/tests/test_session_strategy_guard.py +105 -0
  61. agent_run_supervisor-0.1.0/tests/test_smoke_codex_acpx.py +209 -0
  62. agent_run_supervisor-0.1.0/tests/test_smoke_persistent_session.py +173 -0
  63. agent_run_supervisor-0.1.0/tests/test_static_safety_scan.py +53 -0
  64. agent_run_supervisor-0.1.0/tests/test_validate_contract_fixtures.py +372 -0
  65. agent_run_supervisor-0.1.0/tests/test_workspace_gate.py +224 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 agent-run-supervisor authors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,311 @@
1
+ Metadata-Version: 2.4
2
+ Name: agent-run-supervisor
3
+ Version: 0.1.0
4
+ Summary: Supervise external AGENT runs through acpx/ACP with auditable artifacts
5
+ Author: agent-run-supervisor authors
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/jovijovi/agent-run-supervisor
8
+ Project-URL: Repository, https://github.com/jovijovi/agent-run-supervisor
9
+ Project-URL: Issues, https://github.com/jovijovi/agent-run-supervisor/issues
10
+ Keywords: agent,acp,acpx,supervisor,audit,local-first
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3 :: Only
16
+ Classifier: Topic :: Software Development :: Quality Assurance
17
+ Requires-Python: >=3.11
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Provides-Extra: dev
21
+ Requires-Dist: pytest<10,>=8; extra == "dev"
22
+ Provides-Extra: release
23
+ Requires-Dist: build<2,>=1; extra == "release"
24
+ Requires-Dist: twine<7,>=5; extra == "release"
25
+ Dynamic: license-file
26
+
27
+ <!-- Hero -->
28
+ <p align="center">
29
+ <img src="docs/assets/branding/readme-hero.png" alt="Agent Run Supervisor" width="860">
30
+ </p>
31
+
32
+ <!-- Language links -->
33
+ <p align="center">
34
+ <b>English</b>
35
+ &nbsp;·&nbsp;
36
+ <a href="README.zh-CN.md">简体中文</a>
37
+ </p>
38
+
39
+ <p align="center">
40
+ A small, <b>local-first</b> Python library &amp; dev CLI that supervises<br>
41
+ ACP/acpx external AGENT runs and turns runner behavior into <b>redacted, auditable evidence</b>.
42
+ </p>
43
+
44
+ <p align="center">
45
+ <code>Python&nbsp;≥&nbsp;3.11</code>
46
+ &nbsp;·&nbsp;
47
+ <code>stdlib-only</code>
48
+ &nbsp;·&nbsp;
49
+ <code>local-first</code>
50
+ &nbsp;·&nbsp;
51
+ <code>MIT</code>
52
+ &nbsp;·&nbsp;
53
+ <code>status:&nbsp;0.1.0</code>
54
+ </p>
55
+
56
+ ---
57
+
58
+ ## What it does
59
+
60
+ Every project that drives an external AGENT through **ACP/acpx** re-implements the same
61
+ plumbing: launching and babysitting the runner subprocess, compiling a permission policy,
62
+ parsing a stream of observed events, classifying exit behavior, and redacting artifacts
63
+ before anything touches disk. Done ad-hoc, each caller grows its own subtly-unsafe copy.
64
+
65
+ `agent-run-supervisor` factors that into one independent, **local** supervisor layer. A caller
66
+ picks a role, a prompt, and a working directory; the supervisor validates the role, compiles a
67
+ default-deny policy and a shell-free argv, supervises the run, parses observed output into
68
+ normalized events, classifies a **supervisor-owned status**, and writes **redacted,
69
+ restrictive-permission local artifacts**. The caller gets auditable evidence — not a tangle of
70
+ runner-lifecycle code.
71
+
72
+ The product covers **two execution modes**, both implemented for local use: one-shot exec and a
73
+ local persistent-session lifecycle (create/send/status/close/abort/list — see
74
+ [Roadmap](#roadmap)). It is deliberately **not** Sachima, a Gateway plugin, an IM adapter, or a
75
+ daemon, and it never emits a business verdict (`business_verdict` is always `null`).
76
+
77
+ ## How it works
78
+
79
+ <p align="center">
80
+ <img src="docs/assets/diagrams/how-it-works.svg" alt="How agent-run-supervisor validates a role, supervises ACP/acpx, observes an external AGENT, and writes redacted local artifacts" width="900">
81
+ </p>
82
+
83
+ Four principles keep it honest:
84
+
85
+ - **Supervisor, not business judge.** Runner/protocol completion is never a business verdict;
86
+ `business_verdict` stays `null` and caller-owned.
87
+ - **Auditable by default.** Runs produce deterministic, redacted artifacts with restrictive
88
+ permissions (`0700` dirs, `0600` files, atomic final writes).
89
+ - **Fail closed on uncertainty.** Invalid roles, cwd-outside-roots, malformed stdout, protocol
90
+ drift, denied permissions, and watchdog timeouts all resolve to deterministic non-success
91
+ statuses — an invalid cwd creates **no** artifacts at all.
92
+ - **Honest security claims.** `allowed_roots` validates cwd/config **intent** only — it is
93
+ **not** an OS/filesystem sandbox.
94
+
95
+ Out of scope — caller/platform territory: public ingress, real IM delivery, Gateway lifecycle,
96
+ production config writes, live/default-on behavior, `@all` fan-out, and agent-to-agent routing.
97
+
98
+ ## Install and use
99
+
100
+ ```bash
101
+ pip install agent-run-supervisor
102
+ ```
103
+
104
+ Or install from a source checkout (see [Development](#development)).
105
+
106
+ ```bash
107
+ # Validate an AgentRoleSpec (JSON) and print its stable role hash
108
+ agent-run-supervisor validate-role <role-file>.json
109
+
110
+ # Replay an observed acpx stdout stream through the parser (deterministic, launches no AGENT)
111
+ agent-run-supervisor replay \
112
+ fixtures/acpx-0.12.0/success-codex-sentinel/stdout.ndjson
113
+
114
+ # Probe local readiness (read-only, never launches an AGENT)
115
+ agent-run-supervisor doctor
116
+
117
+ # Dry-run: compile policy + argv and persist preview artifacts, launch nothing
118
+ agent-run-supervisor run \
119
+ --role <role-file>.json --prompt-file <prompt>.txt --no-real-run
120
+
121
+ # Real one-shot exec: supervise a local `acpx exec` under the role's policy
122
+ # (requires acpx/Node available locally; launches ONE explicit, local AGENT)
123
+ agent-run-supervisor run \
124
+ --role <role-file>.json --prompt-file <prompt>.txt
125
+
126
+ # Local persistent-session lifecycle (role must use a persistent session strategy):
127
+ # create → send turn(s) → status → close/abort. create/send/status/close/abort drive a
128
+ # real local acpx session and need Node + acpx; `session list` is local read-only and
129
+ # launches no AGENT.
130
+ agent-run-supervisor session create \
131
+ --role <role-file>.json --session-id <id>
132
+ agent-run-supervisor session send \
133
+ --role <role-file>.json --session-id <id> --prompt-file <prompt>.txt
134
+ agent-run-supervisor session status \
135
+ --role <role-file>.json --session-id <id>
136
+ agent-run-supervisor session close \
137
+ --role <role-file>.json --session-id <id>
138
+ agent-run-supervisor session abort \
139
+ --role <role-file>.json --session-id <id>
140
+ agent-run-supervisor session list
141
+
142
+ # Plan or apply local artifact retention/cleanup (dry-run by default; --apply deletes)
143
+ agent-run-supervisor cleanup
144
+ ```
145
+
146
+ From a source checkout without installing, prefix commands with `PYTHONPATH=src python3 -m agent_run_supervisor` instead of `agent-run-supervisor`.
147
+
148
+ ```bash
149
+ # Clone and enter the repository
150
+ git clone https://github.com/jovijovi/agent-run-supervisor.git
151
+ cd agent-run-supervisor
152
+
153
+ # Example: validate-role from checkout (no install)
154
+ PYTHONPATH=src python3 -m agent_run_supervisor validate-role <role-file>.json
155
+ ```
156
+
157
+ ### Codex/acpx smoke helper
158
+
159
+ For an explicit local connectivity check that exercises both supervised Codex surfaces —
160
+ one-shot exec first, then a two-turn persistent session — use the maintained helper:
161
+
162
+ ```bash
163
+ python3 scripts/smoke_codex_acpx.py --model 'gpt-5.5[xhigh]'
164
+ ```
165
+
166
+ The helper creates temporary no-tool roles, asks Codex for exact sentinel replies, verifies
167
+ `business_verdict = null`, closes the persistent session, and cleans artifacts by default
168
+ (`--keep-artifacts` keeps the temp scratch/runs/sessions directories). It intentionally uses
169
+ `runner.acpx_binary = null`, so the existing compiler invokes the pinned
170
+ `npx -y acpx@0.12.0` path.
171
+
172
+ Use the exact Codex ACP model IDs advertised by the ACP session, such as
173
+ `gpt-5.5[xhigh]`, `gpt-5.5[high]`, or `gpt-5.4-mini[medium]`. A bare id like
174
+ `gpt-5.5` can be rejected with `the ACP agent did not advertise that model`, and the
175
+ helper refuses it before launching anything.
176
+
177
+ Once installed (`pip install -e .`), the same surface is available as the
178
+ `agent-run-supervisor <command> …` console script.
179
+
180
+ Run artifacts land under `.agent-run-supervisor/runs/<run_id>/` — redacted prompt/env/argv, the
181
+ generated policy, observed stdout (NDJSON), normalized events, stderr, `result.json`
182
+ (`business_verdict = null`), and `redaction-report.json`. Persistent-session artifacts land under
183
+ `.agent-run-supervisor/sessions/<session_id>/` (local record, redacted `management/` summaries,
184
+ and one redacted `turns/<turn_id>/` directory per send). The `cleanup` command plans and (only
185
+ with `--apply`) deletes aged run/session artifacts, confined to the resolved
186
+ `.agent-run-supervisor` root and never touching open/live-locked sessions.
187
+
188
+ ## Environment requirements
189
+
190
+ | Need | Requirement |
191
+ |---|---|
192
+ | Runtime | **Python ≥ 3.11**, standard-library only — zero third-party runtime dependencies. |
193
+ | Tests (optional) | `pytest >= 8, < 10` (the `dev` extra). |
194
+ | Real AGENT runs / session turns | **Node + acpx + the target AGENT CLI** available locally — required for `run` (without `--no-real-run`) and for the real `session create/send/status/close/abort` turn & management commands. The Codex smoke helper specifically needs `npx` plus Codex CLI via `CODEX_PATH` or `PATH`. |
195
+ | No-AGENT commands | `validate-role`, `replay`, `doctor`, `run --no-real-run`, `session list`, and `cleanup` (dry-run) need **no** Node/acpx and launch **no** AGENT. |
196
+
197
+ ## Development
198
+
199
+ Primary path uses [uv](https://docs.astral.sh/uv/) for a reproducible dev environment.
200
+ Short commands are available via the root [`Makefile`](Makefile):
201
+
202
+ ```bash
203
+ git clone https://github.com/jovijovi/agent-run-supervisor.git
204
+ cd agent-run-supervisor
205
+ make sync # uv sync --extra dev --extra release
206
+ make verify # full local gates (same as CI)
207
+ make build # sdist/wheel + twine check
208
+ make smoke # build + installed-wheel smoke
209
+ make clean # remove build artifacts, caches, local scratch data
210
+ make help # list all targets
211
+ ```
212
+
213
+ Equivalent without Make:
214
+
215
+ ```bash
216
+ uv sync --extra dev --extra release
217
+ ./scripts/verify_local.sh
218
+ ```
219
+
220
+ `make verify` / `./scripts/verify_local.sh` is the single local gate entry — it mirrors CI and
221
+ [`docs/roadmap/current-status.md`](docs/roadmap/current-status.md) §6 (tests, doctor/replay smoke,
222
+ docs index/drift, static safety scan, build/twine check, and installed-wheel smoke).
223
+
224
+ **pip fallback** (without uv):
225
+
226
+ ```bash
227
+ pip install -e '.[dev,release]'
228
+ python3 -m pytest -q
229
+ ```
230
+
231
+ ## Publishing
232
+
233
+ **Production PyPI** — tag-triggered via GitHub Actions Trusted Publishing (no API tokens in the
234
+ repo):
235
+
236
+ ```bash
237
+ make verify # or ./scripts/verify_local.sh
238
+ # bump version in pyproject.toml + CHANGELOG.md, merge to main
239
+ make release-tag # prints git tag vX.Y.Z && git push commands
240
+ agent-run-supervisor doctor # after pip install from PyPI
241
+ ```
242
+
243
+ **TestPyPI dry-run** (local upload with API token in env — never commit tokens):
244
+
245
+ ```bash
246
+ export TWINE_USERNAME=__token__
247
+ export TWINE_PASSWORD=pypi-... # TestPyPI token
248
+ make release-test # verify + upload to TestPyPI
249
+
250
+ pip install --index-url https://test.pypi.org/simple/ \
251
+ --extra-index-url https://pypi.org/simple/ \
252
+ agent-run-supervisor==0.1.0
253
+ agent-run-supervisor doctor
254
+ ```
255
+
256
+ Maintainers must configure PyPI Trusted Publishing for workflow `release.yml` and environment
257
+ `pypi` before the first production tag push. See `docs/plans/2026-07-06-p3-engineering-basics.md`
258
+ for the operator checklist.
259
+
260
+ ## Quality and test indicators
261
+
262
+ Factual local gates that keep the supervisor honest (run from the repository root with
263
+ `./scripts/verify_local.sh`, or step-by-step):
264
+
265
+ | Indicator | Evidence |
266
+ |---|---|
267
+ | Full local gate | `make verify` or `./scripts/verify_local.sh` — mirrors CI verify workflow. |
268
+ | Unit / integration tests | **Full pytest suite** — `uv run pytest -q` (current local acceptance: full suite passing). |
269
+ | acpx contract | acpx `0.12.0` fixtures + validator — `scripts/validate_contract_fixtures.py fixtures/acpx-0.12.0`. |
270
+ | Import / syntax smoke | `python -m compileall -q src scripts tests`. |
271
+ | Doctor (read-only) | `… doctor` never launches an AGENT (`launched_real_agent = false`). |
272
+ | Package checks | `python -m build` + `twine check dist/*`, plus an installed-wheel `agent-run-supervisor doctor` smoke. |
273
+ | Safe artifacts | Redacted artifacts · `business_verdict = null` · EventStore `0700`/`0600` atomic NDJSON. |
274
+
275
+ ```bash
276
+ uv sync --extra dev --extra release
277
+ ./scripts/verify_local.sh
278
+ ```
279
+
280
+ ## Roadmap
281
+
282
+ High-level direction only — full phase status, acceptance, and non-approvals live in
283
+ [`docs/roadmap/current-status.md`](docs/roadmap/current-status.md) and
284
+ [`docs/roadmap/features.md`](docs/roadmap/features.md).
285
+
286
+ - **Done — foundations + both execution modes.** Role/policy/parser/store foundation, real local
287
+ `acpx exec` supervision (role-bound, outer watchdog, kill metadata), and the local
288
+ persistent-session lifecycle (create/send/multi-turn-resume/status/close/abort/list, locks,
289
+ stale-lock recovery) are implemented and closed for local use.
290
+ - **Done — hardening + local caller integration.** Full read-only doctor probe set, confined
291
+ artifact retention/cleanup, a documented result/event schema, process-liveness crash recovery,
292
+ the generic local caller boundary, and a local/offline Hermes caller + offline Feishu
293
+ view-model adapter are merged.
294
+ - **Backlog — deeper hardening (not started).** `npx` strict-offline enforcement, stronger
295
+ redaction/DLP plus a caller allowlist, and a lock-release audit trail are tracked as backlog
296
+ only. Any live/platform integration (real Feishu/IM delivery, Sachima, Gateway lifecycle,
297
+ public ingress) stays out of scope and requires separate approval.
298
+
299
+ ## License
300
+
301
+ © the `agent-run-supervisor` authors. Released under the **[MIT](https://opensource.org/license/mit)**
302
+ license (`license = "MIT"` and [`LICENSE`](LICENSE)). Pre-release software
303
+ (`0.1.0`); surfaces and result schemas may still change before a stable `1.0.0`.
304
+
305
+ <p align="center">
306
+ <img src="docs/assets/branding/logo-mark.png" alt="agent-run-supervisor logo mark" width="72" height="72">
307
+ <br>
308
+ <sub><b>agent-run-supervisor</b> — a supervisor, not a business judge.</sub>
309
+ <br>
310
+ <sub><a href="README.zh-CN.md">简体中文 README</a></sub>
311
+ </p>
@@ -0,0 +1,285 @@
1
+ <!-- Hero -->
2
+ <p align="center">
3
+ <img src="docs/assets/branding/readme-hero.png" alt="Agent Run Supervisor" width="860">
4
+ </p>
5
+
6
+ <!-- Language links -->
7
+ <p align="center">
8
+ <b>English</b>
9
+ &nbsp;·&nbsp;
10
+ <a href="README.zh-CN.md">简体中文</a>
11
+ </p>
12
+
13
+ <p align="center">
14
+ A small, <b>local-first</b> Python library &amp; dev CLI that supervises<br>
15
+ ACP/acpx external AGENT runs and turns runner behavior into <b>redacted, auditable evidence</b>.
16
+ </p>
17
+
18
+ <p align="center">
19
+ <code>Python&nbsp;≥&nbsp;3.11</code>
20
+ &nbsp;·&nbsp;
21
+ <code>stdlib-only</code>
22
+ &nbsp;·&nbsp;
23
+ <code>local-first</code>
24
+ &nbsp;·&nbsp;
25
+ <code>MIT</code>
26
+ &nbsp;·&nbsp;
27
+ <code>status:&nbsp;0.1.0</code>
28
+ </p>
29
+
30
+ ---
31
+
32
+ ## What it does
33
+
34
+ Every project that drives an external AGENT through **ACP/acpx** re-implements the same
35
+ plumbing: launching and babysitting the runner subprocess, compiling a permission policy,
36
+ parsing a stream of observed events, classifying exit behavior, and redacting artifacts
37
+ before anything touches disk. Done ad-hoc, each caller grows its own subtly-unsafe copy.
38
+
39
+ `agent-run-supervisor` factors that into one independent, **local** supervisor layer. A caller
40
+ picks a role, a prompt, and a working directory; the supervisor validates the role, compiles a
41
+ default-deny policy and a shell-free argv, supervises the run, parses observed output into
42
+ normalized events, classifies a **supervisor-owned status**, and writes **redacted,
43
+ restrictive-permission local artifacts**. The caller gets auditable evidence — not a tangle of
44
+ runner-lifecycle code.
45
+
46
+ The product covers **two execution modes**, both implemented for local use: one-shot exec and a
47
+ local persistent-session lifecycle (create/send/status/close/abort/list — see
48
+ [Roadmap](#roadmap)). It is deliberately **not** Sachima, a Gateway plugin, an IM adapter, or a
49
+ daemon, and it never emits a business verdict (`business_verdict` is always `null`).
50
+
51
+ ## How it works
52
+
53
+ <p align="center">
54
+ <img src="docs/assets/diagrams/how-it-works.svg" alt="How agent-run-supervisor validates a role, supervises ACP/acpx, observes an external AGENT, and writes redacted local artifacts" width="900">
55
+ </p>
56
+
57
+ Four principles keep it honest:
58
+
59
+ - **Supervisor, not business judge.** Runner/protocol completion is never a business verdict;
60
+ `business_verdict` stays `null` and caller-owned.
61
+ - **Auditable by default.** Runs produce deterministic, redacted artifacts with restrictive
62
+ permissions (`0700` dirs, `0600` files, atomic final writes).
63
+ - **Fail closed on uncertainty.** Invalid roles, cwd-outside-roots, malformed stdout, protocol
64
+ drift, denied permissions, and watchdog timeouts all resolve to deterministic non-success
65
+ statuses — an invalid cwd creates **no** artifacts at all.
66
+ - **Honest security claims.** `allowed_roots` validates cwd/config **intent** only — it is
67
+ **not** an OS/filesystem sandbox.
68
+
69
+ Out of scope — caller/platform territory: public ingress, real IM delivery, Gateway lifecycle,
70
+ production config writes, live/default-on behavior, `@all` fan-out, and agent-to-agent routing.
71
+
72
+ ## Install and use
73
+
74
+ ```bash
75
+ pip install agent-run-supervisor
76
+ ```
77
+
78
+ Or install from a source checkout (see [Development](#development)).
79
+
80
+ ```bash
81
+ # Validate an AgentRoleSpec (JSON) and print its stable role hash
82
+ agent-run-supervisor validate-role <role-file>.json
83
+
84
+ # Replay an observed acpx stdout stream through the parser (deterministic, launches no AGENT)
85
+ agent-run-supervisor replay \
86
+ fixtures/acpx-0.12.0/success-codex-sentinel/stdout.ndjson
87
+
88
+ # Probe local readiness (read-only, never launches an AGENT)
89
+ agent-run-supervisor doctor
90
+
91
+ # Dry-run: compile policy + argv and persist preview artifacts, launch nothing
92
+ agent-run-supervisor run \
93
+ --role <role-file>.json --prompt-file <prompt>.txt --no-real-run
94
+
95
+ # Real one-shot exec: supervise a local `acpx exec` under the role's policy
96
+ # (requires acpx/Node available locally; launches ONE explicit, local AGENT)
97
+ agent-run-supervisor run \
98
+ --role <role-file>.json --prompt-file <prompt>.txt
99
+
100
+ # Local persistent-session lifecycle (role must use a persistent session strategy):
101
+ # create → send turn(s) → status → close/abort. create/send/status/close/abort drive a
102
+ # real local acpx session and need Node + acpx; `session list` is local read-only and
103
+ # launches no AGENT.
104
+ agent-run-supervisor session create \
105
+ --role <role-file>.json --session-id <id>
106
+ agent-run-supervisor session send \
107
+ --role <role-file>.json --session-id <id> --prompt-file <prompt>.txt
108
+ agent-run-supervisor session status \
109
+ --role <role-file>.json --session-id <id>
110
+ agent-run-supervisor session close \
111
+ --role <role-file>.json --session-id <id>
112
+ agent-run-supervisor session abort \
113
+ --role <role-file>.json --session-id <id>
114
+ agent-run-supervisor session list
115
+
116
+ # Plan or apply local artifact retention/cleanup (dry-run by default; --apply deletes)
117
+ agent-run-supervisor cleanup
118
+ ```
119
+
120
+ From a source checkout without installing, prefix commands with `PYTHONPATH=src python3 -m agent_run_supervisor` instead of `agent-run-supervisor`.
121
+
122
+ ```bash
123
+ # Clone and enter the repository
124
+ git clone https://github.com/jovijovi/agent-run-supervisor.git
125
+ cd agent-run-supervisor
126
+
127
+ # Example: validate-role from checkout (no install)
128
+ PYTHONPATH=src python3 -m agent_run_supervisor validate-role <role-file>.json
129
+ ```
130
+
131
+ ### Codex/acpx smoke helper
132
+
133
+ For an explicit local connectivity check that exercises both supervised Codex surfaces —
134
+ one-shot exec first, then a two-turn persistent session — use the maintained helper:
135
+
136
+ ```bash
137
+ python3 scripts/smoke_codex_acpx.py --model 'gpt-5.5[xhigh]'
138
+ ```
139
+
140
+ The helper creates temporary no-tool roles, asks Codex for exact sentinel replies, verifies
141
+ `business_verdict = null`, closes the persistent session, and cleans artifacts by default
142
+ (`--keep-artifacts` keeps the temp scratch/runs/sessions directories). It intentionally uses
143
+ `runner.acpx_binary = null`, so the existing compiler invokes the pinned
144
+ `npx -y acpx@0.12.0` path.
145
+
146
+ Use the exact Codex ACP model IDs advertised by the ACP session, such as
147
+ `gpt-5.5[xhigh]`, `gpt-5.5[high]`, or `gpt-5.4-mini[medium]`. A bare id like
148
+ `gpt-5.5` can be rejected with `the ACP agent did not advertise that model`, and the
149
+ helper refuses it before launching anything.
150
+
151
+ Once installed (`pip install -e .`), the same surface is available as the
152
+ `agent-run-supervisor <command> …` console script.
153
+
154
+ Run artifacts land under `.agent-run-supervisor/runs/<run_id>/` — redacted prompt/env/argv, the
155
+ generated policy, observed stdout (NDJSON), normalized events, stderr, `result.json`
156
+ (`business_verdict = null`), and `redaction-report.json`. Persistent-session artifacts land under
157
+ `.agent-run-supervisor/sessions/<session_id>/` (local record, redacted `management/` summaries,
158
+ and one redacted `turns/<turn_id>/` directory per send). The `cleanup` command plans and (only
159
+ with `--apply`) deletes aged run/session artifacts, confined to the resolved
160
+ `.agent-run-supervisor` root and never touching open/live-locked sessions.
161
+
162
+ ## Environment requirements
163
+
164
+ | Need | Requirement |
165
+ |---|---|
166
+ | Runtime | **Python ≥ 3.11**, standard-library only — zero third-party runtime dependencies. |
167
+ | Tests (optional) | `pytest >= 8, < 10` (the `dev` extra). |
168
+ | Real AGENT runs / session turns | **Node + acpx + the target AGENT CLI** available locally — required for `run` (without `--no-real-run`) and for the real `session create/send/status/close/abort` turn & management commands. The Codex smoke helper specifically needs `npx` plus Codex CLI via `CODEX_PATH` or `PATH`. |
169
+ | No-AGENT commands | `validate-role`, `replay`, `doctor`, `run --no-real-run`, `session list`, and `cleanup` (dry-run) need **no** Node/acpx and launch **no** AGENT. |
170
+
171
+ ## Development
172
+
173
+ Primary path uses [uv](https://docs.astral.sh/uv/) for a reproducible dev environment.
174
+ Short commands are available via the root [`Makefile`](Makefile):
175
+
176
+ ```bash
177
+ git clone https://github.com/jovijovi/agent-run-supervisor.git
178
+ cd agent-run-supervisor
179
+ make sync # uv sync --extra dev --extra release
180
+ make verify # full local gates (same as CI)
181
+ make build # sdist/wheel + twine check
182
+ make smoke # build + installed-wheel smoke
183
+ make clean # remove build artifacts, caches, local scratch data
184
+ make help # list all targets
185
+ ```
186
+
187
+ Equivalent without Make:
188
+
189
+ ```bash
190
+ uv sync --extra dev --extra release
191
+ ./scripts/verify_local.sh
192
+ ```
193
+
194
+ `make verify` / `./scripts/verify_local.sh` is the single local gate entry — it mirrors CI and
195
+ [`docs/roadmap/current-status.md`](docs/roadmap/current-status.md) §6 (tests, doctor/replay smoke,
196
+ docs index/drift, static safety scan, build/twine check, and installed-wheel smoke).
197
+
198
+ **pip fallback** (without uv):
199
+
200
+ ```bash
201
+ pip install -e '.[dev,release]'
202
+ python3 -m pytest -q
203
+ ```
204
+
205
+ ## Publishing
206
+
207
+ **Production PyPI** — tag-triggered via GitHub Actions Trusted Publishing (no API tokens in the
208
+ repo):
209
+
210
+ ```bash
211
+ make verify # or ./scripts/verify_local.sh
212
+ # bump version in pyproject.toml + CHANGELOG.md, merge to main
213
+ make release-tag # prints git tag vX.Y.Z && git push commands
214
+ agent-run-supervisor doctor # after pip install from PyPI
215
+ ```
216
+
217
+ **TestPyPI dry-run** (local upload with API token in env — never commit tokens):
218
+
219
+ ```bash
220
+ export TWINE_USERNAME=__token__
221
+ export TWINE_PASSWORD=pypi-... # TestPyPI token
222
+ make release-test # verify + upload to TestPyPI
223
+
224
+ pip install --index-url https://test.pypi.org/simple/ \
225
+ --extra-index-url https://pypi.org/simple/ \
226
+ agent-run-supervisor==0.1.0
227
+ agent-run-supervisor doctor
228
+ ```
229
+
230
+ Maintainers must configure PyPI Trusted Publishing for workflow `release.yml` and environment
231
+ `pypi` before the first production tag push. See `docs/plans/2026-07-06-p3-engineering-basics.md`
232
+ for the operator checklist.
233
+
234
+ ## Quality and test indicators
235
+
236
+ Factual local gates that keep the supervisor honest (run from the repository root with
237
+ `./scripts/verify_local.sh`, or step-by-step):
238
+
239
+ | Indicator | Evidence |
240
+ |---|---|
241
+ | Full local gate | `make verify` or `./scripts/verify_local.sh` — mirrors CI verify workflow. |
242
+ | Unit / integration tests | **Full pytest suite** — `uv run pytest -q` (current local acceptance: full suite passing). |
243
+ | acpx contract | acpx `0.12.0` fixtures + validator — `scripts/validate_contract_fixtures.py fixtures/acpx-0.12.0`. |
244
+ | Import / syntax smoke | `python -m compileall -q src scripts tests`. |
245
+ | Doctor (read-only) | `… doctor` never launches an AGENT (`launched_real_agent = false`). |
246
+ | Package checks | `python -m build` + `twine check dist/*`, plus an installed-wheel `agent-run-supervisor doctor` smoke. |
247
+ | Safe artifacts | Redacted artifacts · `business_verdict = null` · EventStore `0700`/`0600` atomic NDJSON. |
248
+
249
+ ```bash
250
+ uv sync --extra dev --extra release
251
+ ./scripts/verify_local.sh
252
+ ```
253
+
254
+ ## Roadmap
255
+
256
+ High-level direction only — full phase status, acceptance, and non-approvals live in
257
+ [`docs/roadmap/current-status.md`](docs/roadmap/current-status.md) and
258
+ [`docs/roadmap/features.md`](docs/roadmap/features.md).
259
+
260
+ - **Done — foundations + both execution modes.** Role/policy/parser/store foundation, real local
261
+ `acpx exec` supervision (role-bound, outer watchdog, kill metadata), and the local
262
+ persistent-session lifecycle (create/send/multi-turn-resume/status/close/abort/list, locks,
263
+ stale-lock recovery) are implemented and closed for local use.
264
+ - **Done — hardening + local caller integration.** Full read-only doctor probe set, confined
265
+ artifact retention/cleanup, a documented result/event schema, process-liveness crash recovery,
266
+ the generic local caller boundary, and a local/offline Hermes caller + offline Feishu
267
+ view-model adapter are merged.
268
+ - **Backlog — deeper hardening (not started).** `npx` strict-offline enforcement, stronger
269
+ redaction/DLP plus a caller allowlist, and a lock-release audit trail are tracked as backlog
270
+ only. Any live/platform integration (real Feishu/IM delivery, Sachima, Gateway lifecycle,
271
+ public ingress) stays out of scope and requires separate approval.
272
+
273
+ ## License
274
+
275
+ © the `agent-run-supervisor` authors. Released under the **[MIT](https://opensource.org/license/mit)**
276
+ license (`license = "MIT"` and [`LICENSE`](LICENSE)). Pre-release software
277
+ (`0.1.0`); surfaces and result schemas may still change before a stable `1.0.0`.
278
+
279
+ <p align="center">
280
+ <img src="docs/assets/branding/logo-mark.png" alt="agent-run-supervisor logo mark" width="72" height="72">
281
+ <br>
282
+ <sub><b>agent-run-supervisor</b> — a supervisor, not a business judge.</sub>
283
+ <br>
284
+ <sub><a href="README.zh-CN.md">简体中文 README</a></sub>
285
+ </p>
@@ -0,0 +1,48 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77.0.3"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "agent-run-supervisor"
7
+ version = "0.1.0"
8
+ description = "Supervise external AGENT runs through acpx/ACP with auditable artifacts"
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [{ name = "agent-run-supervisor authors" }]
14
+ keywords = ["agent", "acp", "acpx", "supervisor", "audit", "local-first"]
15
+ classifiers = [
16
+ "Development Status :: 3 - Alpha",
17
+ "Intended Audience :: Developers",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3.11",
20
+ "Programming Language :: Python :: 3 :: Only",
21
+ "Topic :: Software Development :: Quality Assurance",
22
+ ]
23
+ dependencies = []
24
+
25
+ [project.urls]
26
+ Homepage = "https://github.com/jovijovi/agent-run-supervisor"
27
+ Repository = "https://github.com/jovijovi/agent-run-supervisor"
28
+ Issues = "https://github.com/jovijovi/agent-run-supervisor/issues"
29
+
30
+ [project.optional-dependencies]
31
+ dev = ["pytest>=8,<10"]
32
+ release = ["build>=1,<2", "twine>=5,<7"]
33
+
34
+ [project.scripts]
35
+ agent-run-supervisor = "agent_run_supervisor.cli:main"
36
+
37
+ [tool.setuptools.packages.find]
38
+ where = ["src"]
39
+ include = ["agent_run_supervisor*"]
40
+
41
+
42
+ [tool.setuptools.package-data]
43
+ agent_run_supervisor = ["fixtures/acpx-0.12.0/success-codex-sentinel/stdout.ndjson"]
44
+
45
+ [tool.pytest.ini_options]
46
+ testpaths = ["tests"]
47
+ addopts = "-q"
48
+ pythonpath = ["src", "."]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,5 @@
1
+ """agent-run-supervisor local ACP/acpx run and session supervision toolkit."""
2
+
3
+ __version__ = "0.0.0"
4
+
5
+ __all__ = ["__version__"]