harnex 0.9.0 → 0.10.1
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 +122 -0
- data/README.md +38 -38
- data/TECHNICAL.md +17 -15
- data/docs/codex-appserver.md +16 -13
- data/docs/configuration.md +11 -4
- data/docs/dispatch-telemetry.md +189 -112
- data/docs/events.md +2 -3
- data/guides/01_dispatch.md +29 -32
- data/guides/04_monitoring.md +4 -4
- data/lib/harnex/artifact_report.rb +455 -6
- data/lib/harnex/cli.rb +11 -3
- data/lib/harnex/commands/artifact_report.rb +8 -7
- data/lib/harnex/commands/doctor.rb +1 -1
- data/lib/harnex/commands/run.rb +22 -37
- data/lib/harnex/commands/status.rb +0 -2
- data/lib/harnex/commands/telemetry.rb +110 -0
- data/lib/harnex/commands/wait.rb +0 -1
- data/lib/harnex/config.rb +6 -2
- data/lib/harnex/core.rb +200 -14
- data/lib/harnex/dispatch_history.rb +3 -3
- data/lib/harnex/retention.rb +13 -4
- data/lib/harnex/runtime/session.rb +317 -160
- data/lib/harnex/telemetry_reconciler.rb +494 -0
- data/lib/harnex/terminal_status.rb +7 -20
- data/lib/harnex/version.rb +2 -2
- data/lib/harnex.rb +2 -0
- 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: 869ca6ae88939347c40b89586d058fcb64ea2785981155afebcfcb8ffcb7bf4f
|
|
4
|
+
data.tar.gz: e66e87cc0839ec329a394c9e17ba784e690d094d6ac639232dbc85638c11f9dc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6da098e592bd3937ceb378f8cd3c654675c213d3d5c79606a206eb5ddb043dba3e38bc3f05d39e9562add5f2779bd53981ca5a7ba1c17e85e1b9f837f3e59cc3
|
|
7
|
+
data.tar.gz: 63a34a367fd56167001f530aad631e8f8b17739fd7f209a949847245a68b66b79cef3664cf657918b3fea07c567482d738dbe16aa2773d1f5acd2ccda2a53318
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,127 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.10.1] - 2026-08-04 | 12:20 AM | IST
|
|
4
|
+
|
|
5
|
+
Patch release candidate: closes the recovery and regression-checking gap left
|
|
6
|
+
after `0.10.0` removed the upstream telemetry mirror. The canonical
|
|
7
|
+
`.harnex/dispatch.jsonl` stream remains the only writer; this release adds
|
|
8
|
+
operator tooling to prove and repair that stream without schema migration.
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- `harnex telemetry assert-canonical` validates the canonical dispatch stream
|
|
13
|
+
and, when explicit `--source` paths are supplied, fails closed on missing or
|
|
14
|
+
conflicting rich end rows. It is read-only, tolerates mixed-era history
|
|
15
|
+
including open v2 starts and legacy rows, and emits bounded redacted reports.
|
|
16
|
+
- `harnex telemetry reconcile` uses the same analysis, defaults to dry-run, and
|
|
17
|
+
only appends missing rich end rows when `--apply` is passed. It never rewrites,
|
|
18
|
+
deletes, sorts, migrates, cleans source files, or discovers sources
|
|
19
|
+
automatically.
|
|
20
|
+
- Source paths may be files or directories. Directory scans are bounded to
|
|
21
|
+
`.json`/`.jsonl`, skip `.git`, symlinks, and the resolved canonical stream,
|
|
22
|
+
ignore unrelated generic JSON, and treat identity or payload conflicts as
|
|
23
|
+
zero-write failures.
|
|
24
|
+
|
|
25
|
+
## [0.10.0] - 2026-08-03 | 01:44 PM | IST
|
|
26
|
+
|
|
27
|
+
Minor bump, **breaking**: `--summary-out` is removed outright, so the canonical
|
|
28
|
+
`.harnex/dispatch.jsonl` is the only telemetry destination. Also fixes four
|
|
29
|
+
runner reliability defects found while verifying that removal — concurrent
|
|
30
|
+
registry corruption, a delivered send reported as failed, a corrupt registry
|
|
31
|
+
entry crashing every session scan, and a closed stdout wedging the wrapped
|
|
32
|
+
agent.
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
|
|
36
|
+
- **Concurrent registry writes no longer corrupt each other** (#66).
|
|
37
|
+
`write_registry` derived its temp path from the pid alone, but several
|
|
38
|
+
threads in one session write the same registry — the startup persist, the
|
|
39
|
+
inbox delivery thread, and one thread per API client. One thread renamed the
|
|
40
|
+
file another was still writing, and the loser raised `Errno::ENOENT`
|
|
41
|
+
(2080 failures in a 2400-write reproduction; now zero). Writes are also no
|
|
42
|
+
longer defeated by a state directory that was reaped mid-session.
|
|
43
|
+
- **A failed registry write no longer fails an already delivered send** (#66).
|
|
44
|
+
Registry persistence runs *after* the prompt has reached the agent, so a
|
|
45
|
+
bookkeeping failure was reporting a dispatched turn as failed — enough to
|
|
46
|
+
make an orchestrator retry work already in flight. Post-injection refresh now
|
|
47
|
+
warns; startup persistence stays strict so an undiscoverable session still
|
|
48
|
+
fails loudly instead of running unreachable.
|
|
49
|
+
- **One corrupt registry file no longer crashes every session scan** (#66).
|
|
50
|
+
A non-numeric pid raised `ArgumentError` out of `active_sessions`, taking
|
|
51
|
+
down `harnex status`, `harnex send`, and `harnex pane`. Such an entry is now
|
|
52
|
+
treated as dead and pruned, matching the existing self-healing for
|
|
53
|
+
unparseable JSON.
|
|
54
|
+
- **A closed stdout no longer wedges the wrapped agent** (#66).
|
|
55
|
+
`Errno::EPIPE`/`EBADF` are not `IOError` subclasses, so they escaped the
|
|
56
|
+
output reader's rescue and killed the thread; the PTY then stopped draining
|
|
57
|
+
and the agent blocked forever on write, presenting as an agent hang with no
|
|
58
|
+
harness error. Draining is now unconditional and stdout echo is best-effort.
|
|
59
|
+
Both reader loops report an unexpected exit instead of vanishing silently.
|
|
60
|
+
- `Retention` metadata writes route through the shared atomic writer instead of
|
|
61
|
+
repeating the same pid-only temp-name pattern.
|
|
62
|
+
|
|
63
|
+
### Removed
|
|
64
|
+
|
|
65
|
+
- **BREAKING: `--summary-out` is gone** (#65). `.harnex/dispatch.jsonl` is now
|
|
66
|
+
the only destination a dispatch writes telemetry to. Passing `--summary-out
|
|
67
|
+
PATH` or `--summary-out=PATH` is rejected as an unknown flag and exits
|
|
68
|
+
non-zero; it is deliberately not a silent ignore, so a stale caller fails
|
|
69
|
+
immediately rather than believing it still has a second copy. 0.9.0 demoted
|
|
70
|
+
the flag to an explicit-only mirror but left it in place; that mirror was the
|
|
71
|
+
source of a three-times-hand-reconciled stranded-telemetry class.
|
|
72
|
+
- `summary_out_path` no longer appears on `dispatch_start` or `dispatch_end`
|
|
73
|
+
rows, and `summary_out` no longer appears in `harnex status --json`,
|
|
74
|
+
`harnex wait`, or `harnex watch` payloads. The `summary` event no longer
|
|
75
|
+
carries `mirror_path`.
|
|
76
|
+
|
|
77
|
+
### Added
|
|
78
|
+
|
|
79
|
+
- **Harness-authored observed-state receipts** (#64): every dispatch now writes
|
|
80
|
+
a canonical `harnex.artifact_report.v1` receipt without worker-authored JSON.
|
|
81
|
+
Receipts carry explicit `receipt.author=harnex` provenance, start/end Git
|
|
82
|
+
state (committed plus staged/unstaged/untracked paths and LOC), bounded Codex
|
|
83
|
+
command exits, turn acceptance, and usage. The receipt is written before a
|
|
84
|
+
structured `task_complete` event and refreshed with final teardown telemetry.
|
|
85
|
+
- Every session receives a default repo-keyed receipt under
|
|
86
|
+
`~/.local/state/harnex/receipts/`; `--artifact-report` now overrides that
|
|
87
|
+
destination. Live status, detached/tmux launch payloads, dispatch-start rows,
|
|
88
|
+
and dispatch-end metadata expose the receipt and claims paths.
|
|
89
|
+
- Review workers may write a bounded optional block to
|
|
90
|
+
`HARNEX_ARTIFACT_CLAIMS_PATH` (`summary`, `verdict`, and P1/P2/P3 counts).
|
|
91
|
+
Claims are sanitized and copied into the receipt but never participate in
|
|
92
|
+
completion acceptance or final-receipt validity.
|
|
93
|
+
- Receipt files and claims inputs join the existing 45-day / 1-GiB retention
|
|
94
|
+
policy as a third independently configurable directory, including
|
|
95
|
+
`HARNEX_RECEIPTS_MAX_AGE_DAYS` / `HARNEX_RECEIPTS_MAX_BYTES` and live/current
|
|
96
|
+
path protection.
|
|
97
|
+
|
|
98
|
+
### Changed
|
|
99
|
+
|
|
100
|
+
- `TerminalStatus` resolves exclusively from the canonical stream. It
|
|
101
|
+
previously preferred the mirror file named by a record's `summary_out_path`,
|
|
102
|
+
which — with the writer removed — would have let a leftover mirror from an
|
|
103
|
+
older release resolve status from stale data. A pre-existing mirror file on
|
|
104
|
+
disk now has no effect on any id.
|
|
105
|
+
- `status["source"]` reports `dispatch_end` where it previously reported
|
|
106
|
+
`summary_out` for rich end rows. `dispatch_history`, `dispatch_start`,
|
|
107
|
+
`live`, `registry`, and `none` are unchanged.
|
|
108
|
+
- `artifact-report validate --final` preserves the legacy manual-v1 contract
|
|
109
|
+
while recognizing the additive harness-receipt contract. Harness receipts
|
|
110
|
+
validate observed acceptance and zero-delta evidence; failed exploratory
|
|
111
|
+
command exits remain factual telemetry for queue policy rather than allowing
|
|
112
|
+
worker claims to decide receipt validity.
|
|
113
|
+
- Artifact fingerprints are now internal claims-freshness bookkeeping only.
|
|
114
|
+
Pre-existing, stale, malformed, or missing worker reports are overwritten by
|
|
115
|
+
fresh harness proof instead of becoming work-acceptance failures. The legacy
|
|
116
|
+
`init` command and `--require-artifact-report` flag remain compatible, but
|
|
117
|
+
neither an explicit path nor model-authored proof is required.
|
|
118
|
+
- Codex autonomous completion still rejects acknowledgment-only turns as
|
|
119
|
+
`completed_no_activity`; optional claims cannot satisfy the observed-activity
|
|
120
|
+
gate. Receipt write/validation failure is fail-closed as `report_invalid`.
|
|
121
|
+
- Git observation now baselines the starting worktree so uncommitted product
|
|
122
|
+
edits are included while unchanged pre-existing dirt and harness-owned
|
|
123
|
+
dispatch/receipt files are excluded.
|
|
124
|
+
|
|
3
125
|
## [0.9.0] - 2026-08-03 | 01:11 AM | IST
|
|
4
126
|
|
|
5
127
|
Minor bump: the durable dispatch row family is now v2, `--summary-out` changes
|
data/README.md
CHANGED
|
@@ -206,8 +206,8 @@ bare `--watch` means babysitter mode.
|
|
|
206
206
|
|
|
207
207
|
For one-shot startup prompts, add `--auto-stop`. It requires `--context`.
|
|
208
208
|
A Codex app-server turn launched from `--context` only counts as accepted
|
|
209
|
-
autonomous work when structured command/tool activity
|
|
210
|
-
|
|
209
|
+
autonomous work when structured command/tool activity or a Git delta proves
|
|
210
|
+
activity. Optional receipt claims cannot satisfy this gate. An acknowledgment-only turn emits
|
|
211
211
|
`outcome.class=completed_no_activity`, makes `watch --until done` return
|
|
212
212
|
non-zero, and auto-stops with a non-zero verdict instead of reporting success.
|
|
213
213
|
PTY adapters still stop on prompt return because they do not expose equivalent
|
|
@@ -258,13 +258,12 @@ and one rich v2 `dispatch_end` row at teardown. Both use the canonical stream:
|
|
|
258
258
|
`<git-root>/.harnex/dispatch.jsonl` inside a git repo, or
|
|
259
259
|
`~/.local/state/harnex/dispatch.jsonl` otherwise. The end row combines the
|
|
260
260
|
history envelope with usage, context, attribution, outcome, attempt,
|
|
261
|
-
reliability, queue/orchestration, and
|
|
261
|
+
reliability, queue/orchestration, and a harness-authored observed-state receipt.
|
|
262
262
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
when the live registry is gone. Mixed legacy v1 and v2 rows remain readable.
|
|
263
|
+
The canonical stream is the only destination; there is no flag to mirror a
|
|
264
|
+
second copy elsewhere. `harnex history`, `harnex status --id ID --json`, and
|
|
265
|
+
`harnex wait` all read the canonical stream when the live registry is gone.
|
|
266
|
+
Mixed legacy v1 and v2 rows remain readable.
|
|
268
267
|
|
|
269
268
|
Use `harnex history` to inspect it:
|
|
270
269
|
|
|
@@ -279,36 +278,37 @@ Dispatch briefs can declare soft budget metadata through `--meta`:
|
|
|
279
278
|
harnex run pi --meta '{"read_budget_lines":2000,"output_ceiling_lines":800}' ...
|
|
280
279
|
```
|
|
281
280
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
281
|
+
Every dispatch gets a canonical `harnex.artifact_report.v1` receipt generated
|
|
282
|
+
by Harnex from observed state: start/end Git SHA and delta, changed paths and
|
|
283
|
+
LOC, structured command exits when the transport exposes them, turn outcome,
|
|
284
|
+
and usage. No model-authored proof JSON or `--artifact-report` flag is needed.
|
|
285
|
+
The default file lives under `~/.local/state/harnex/receipts/`; the live status
|
|
286
|
+
payload and final dispatch row expose its absolute path.
|
|
287
|
+
|
|
288
|
+
Use `--artifact-report PATH` only to override that destination. During the run,
|
|
289
|
+
`HARNEX_ARTIFACT_REPORT_PATH` names the harness-owned final file and
|
|
290
|
+
`HARNEX_ARTIFACT_CLAIMS_PATH` names a separate optional worker input. A review
|
|
291
|
+
worker may attach bounded context without controlling acceptance:
|
|
292
|
+
|
|
293
|
+
```json
|
|
294
|
+
{
|
|
295
|
+
"claims": {
|
|
296
|
+
"summary": "Review complete; one P2 remains.",
|
|
297
|
+
"verdict": "changes_requested",
|
|
298
|
+
"findings": { "P1": 0, "P2": 1, "P3": 0 }
|
|
299
|
+
}
|
|
300
|
+
}
|
|
293
301
|
```
|
|
294
302
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
Without `--require-artifact-report`, report defects remain fail-soft warning
|
|
305
|
-
telemetry. With it, a missing, malformed, unsupported, oversized,
|
|
306
|
-
contract-incomplete, rejected, or unchanged stale report makes the work verdict
|
|
307
|
-
non-zero. A fresh explicit `no_change` report can prove an intentional no-delta
|
|
308
|
-
task without fake edits. Harnex records compact `artifact_report`, `validation`,
|
|
309
|
-
and `artifacts` blocks plus `outcome.class` / `outcome.report_status`; Git
|
|
310
|
-
changes alone never imply semantic acceptance, and JSON printed in final prose
|
|
311
|
-
is never scraped as a sidecar.
|
|
303
|
+
Harnex sanitizes that block and writes it into the receipt; malformed, stale,
|
|
304
|
+
or missing claims are ignored. Claims and final prose can never turn an
|
|
305
|
+
otherwise rejected completion into accepted proof. `harnex artifact-report
|
|
306
|
+
validate PATH --final` validates the harness receipt for consumers, while the
|
|
307
|
+
older `init` command and legacy worker-authored v1 validation remain available
|
|
308
|
+
for compatibility. `--require-artifact-report` is also retained for existing
|
|
309
|
+
scripts but no longer requires an explicit path. A receipt write failure fails
|
|
310
|
+
closed as `report_invalid`; ordinary workers no longer fail because they forgot
|
|
311
|
+
or malformed proof JSON.
|
|
312
312
|
|
|
313
313
|
Queue runners can pass first-class attribution without hiding it in prose:
|
|
314
314
|
|
|
@@ -427,7 +427,7 @@ See [recipes/03_buddy.md](recipes/03_buddy.md) for the full pattern.
|
|
|
427
427
|
| `harnex events --id <id>` | Stream structured session events (`--snapshot` for non-blocking dump) |
|
|
428
428
|
| `harnex history` | List completed dispatches from `.harnex/dispatch.jsonl` |
|
|
429
429
|
| `harnex wait --id <id>` | Block until process exit by default; use `--until done` for unattended work completion or `--until task_complete` for exact structured turn completion |
|
|
430
|
-
| `harnex artifact-report init\|validate PATH` |
|
|
430
|
+
| `harnex artifact-report init\|validate PATH` | Validate harness-authored `harnex.artifact_report.v1` receipts; `init` remains for legacy/manual documents |
|
|
431
431
|
| `harnex doctor` | Run dependency and retention diagnostics; `--sweep` reports session drift, `--prune --dry-run` previews retention, and `--prune` applies it |
|
|
432
432
|
| `harnex guide` | Getting started walkthrough |
|
|
433
433
|
| `harnex agents-guide` | Agent-facing dispatch, chain, buddy, monitoring, and naming guides |
|
|
@@ -448,7 +448,7 @@ longer used. Remove stale `~/.claude/skills/harnex-*` or
|
|
|
448
448
|
- [GUIDE.md](GUIDE.md) — getting started walkthrough with examples
|
|
449
449
|
- [TECHNICAL.md](TECHNICAL.md) — full command reference, flags, HTTP API, architecture
|
|
450
450
|
- [docs/dispatch-telemetry.md](docs/dispatch-telemetry.md) — v2 dispatch stream and field contract
|
|
451
|
-
- [docs/configuration.md](docs/configuration.md) — phase allowlists and events/output retention
|
|
451
|
+
- [docs/configuration.md](docs/configuration.md) — phase allowlists and events/output/receipt retention
|
|
452
452
|
|
|
453
453
|
## License
|
|
454
454
|
|
data/TECHNICAL.md
CHANGED
|
@@ -30,17 +30,16 @@ harnex run codex -- --cd ~/other/repo
|
|
|
30
30
|
| `--context TXT` | Give the agent a task on startup |
|
|
31
31
|
| `--auto-stop` | With `--context`, stop after accepted task completion |
|
|
32
32
|
| `--meta JSON` | Attach bounded caller metadata |
|
|
33
|
-
| `--summary-out PATH` | Mirror the canonical v2 dispatch end row to another JSONL file |
|
|
34
33
|
| `--phase TEXT` | First-class phase attribution (optionally repo-allowlisted) |
|
|
35
|
-
| `--artifact-report PATH` |
|
|
36
|
-
| `--require-artifact-report` |
|
|
34
|
+
| `--artifact-report PATH` | Override the harness-authored v1 receipt destination |
|
|
35
|
+
| `--require-artifact-report` | Compatibility strict flag; default receipt path is sufficient |
|
|
37
36
|
| `--fast` | For Codex, use `service_tier="fast"` instead of default `flex` |
|
|
38
37
|
| `--timeout SEC` | Wait budget for detached registration |
|
|
39
38
|
|
|
40
39
|
Codex app-server auto-stop rejects completion with no structured command/tool
|
|
41
|
-
activity
|
|
42
|
-
|
|
43
|
-
and
|
|
40
|
+
activity or Git delta as `completed_no_activity`. Every transport gets a
|
|
41
|
+
harness-authored observed-state receipt; optional worker claims never determine
|
|
42
|
+
acceptance, and receipt-write failure is fail-closed.
|
|
44
43
|
|
|
45
44
|
### `harnex doctor` — Preflight, drift, and retention
|
|
46
45
|
|
|
@@ -51,22 +50,23 @@ harnex doctor --prune --dry-run
|
|
|
51
50
|
harnex doctor --prune
|
|
52
51
|
```
|
|
53
52
|
|
|
54
|
-
Plain output includes adapter prerequisites and events/output retention status.
|
|
53
|
+
Plain output includes adapter prerequisites and events/output/receipt retention status.
|
|
55
54
|
`--sweep` adds read-only live-session/tmux drift diagnostics. `--prune --dry-run`
|
|
56
55
|
previews age/size-cap deletions; `--prune` applies them while preserving current
|
|
57
56
|
and live-session files. See [docs/configuration.md](docs/configuration.md).
|
|
58
57
|
|
|
59
|
-
### `harnex artifact-report` —
|
|
58
|
+
### `harnex artifact-report` — Validate receipts and legacy proof
|
|
60
59
|
|
|
61
60
|
```bash
|
|
62
61
|
harnex artifact-report init .harnex/reports/worker.json
|
|
63
62
|
harnex artifact-report validate .harnex/reports/worker.json --final
|
|
64
63
|
```
|
|
65
64
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
validation
|
|
65
|
+
Normal runs write their own final receipt, so workers do not call `init`.
|
|
66
|
+
`validate` emits bounded machine-readable field diagnostics; `--final` accepts
|
|
67
|
+
a complete harness receipt whose observed terminal state was accepted. `init`
|
|
68
|
+
remains for legacy/manual v1 documents, whose older successful-validation
|
|
69
|
+
contract is still supported.
|
|
70
70
|
|
|
71
71
|
### `harnex send` — Talk to a running agent
|
|
72
72
|
|
|
@@ -115,6 +115,8 @@ Use `--json` for full payloads. JSON includes:
|
|
|
115
115
|
|
|
116
116
|
- `log_mtime` (ISO8601 or `null`) — transcript file mtime
|
|
117
117
|
- `log_idle_s` (Integer or `null`) — seconds since last transcript write
|
|
118
|
+
- `artifact_report_path` — harness-owned final observed-state receipt
|
|
119
|
+
- `artifact_claims_path` — optional bounded worker-claims input
|
|
118
120
|
|
|
119
121
|
Use `--all` for all repos.
|
|
120
122
|
|
|
@@ -134,8 +136,8 @@ harnex history --json | jq .
|
|
|
134
136
|
|
|
135
137
|
Reads the canonical v2 stream at `<git-root>/.harnex/dispatch.jsonl`; use
|
|
136
138
|
`--global` for `~/.local/state/harnex/dispatch.jsonl` outside a repo. Each run
|
|
137
|
-
has one `dispatch_start` plus one rich `dispatch_end`.
|
|
138
|
-
|
|
139
|
+
has one `dispatch_start` plus one rich `dispatch_end`. That stream is the only
|
|
140
|
+
destination; no flag mirrors the end row into a second file.
|
|
139
141
|
|
|
140
142
|
### `harnex logs` — Read session transcripts
|
|
141
143
|
|
|
@@ -320,7 +322,7 @@ When you run `harnex run codex --id worker`:
|
|
|
320
322
|
hash(repo_root + id) % port_span + base_port
|
|
321
323
|
walk forward until a free port is found
|
|
322
324
|
6. Start HTTP server on 127.0.0.1:<port>
|
|
323
|
-
7. Opportunistically enforce configured age/size retention for events/output,
|
|
325
|
+
7. Opportunistically enforce configured age/size retention for events/output/receipts,
|
|
324
326
|
preserving current and live-session files; then write registry file:
|
|
325
327
|
~/.local/state/harnex/sessions/<repo_hash>--<id>.json
|
|
326
328
|
and open transcript file:
|
data/docs/codex-appserver.md
CHANGED
|
@@ -42,7 +42,7 @@ After the handshake the client is ready to issue `thread/start` and
|
|
|
42
42
|
|-----------------------------|--------------------|-------|
|
|
43
43
|
| `thread/started` | (metadata) | Stashes `threadId` |
|
|
44
44
|
| `turn/started` | `turn_started` | Carries `turnId` |
|
|
45
|
-
| `turn/completed` | `task_complete` or `task_failed` | Failed/interrupted statuses emit `task_failed` with the Codex error. A completed `--context` turn emits `task_complete` only with structured command/tool activity
|
|
45
|
+
| `turn/completed` | `task_complete` or `task_failed` | Failed/interrupted statuses emit `task_failed` with the Codex error. A completed `--context` turn emits `task_complete` only with structured command/tool activity or a Git delta; otherwise it emits typed `completed_no_activity`. Harnex writes the observed-state receipt before the successful event. |
|
|
46
46
|
| `item/started` | (silent) | Streaming deltas opted out |
|
|
47
47
|
| `item/completed` | `item_completed` + synthesized transcript | See "tmux/STDOUT" below |
|
|
48
48
|
| `error` | `error` | Turn-level Codex error notification; preserves nested `error.message` and does not count as a transport disconnect. |
|
|
@@ -102,19 +102,21 @@ harnex wait --id cx-i-242 --until task_complete --timeout 300
|
|
|
102
102
|
|
|
103
103
|
`--until done` returns non-zero when it sees `task_failed` or failed terminal
|
|
104
104
|
telemetry. This includes acknowledgment-only autonomous `--context` turns
|
|
105
|
-
(`outcome_class=completed_no_activity`) and
|
|
106
|
-
(`
|
|
107
|
-
|
|
108
|
-
|
|
105
|
+
(`outcome_class=completed_no_activity`) and the rare receipt-write failure
|
|
106
|
+
(`report_invalid`). Harnex classifies completion from app-server item counters
|
|
107
|
+
and Git state; it does not inspect final-answer prose or trust worker claims.
|
|
108
|
+
The task-complete/task-failed waiters
|
|
109
109
|
tail the events JSONL — not the API socket — so they keep working across
|
|
110
110
|
restarts and are adapter-agnostic.
|
|
111
111
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
`
|
|
116
|
-
|
|
117
|
-
|
|
112
|
+
Every blind dispatch receives a harness-authored receipt. No worker report is
|
|
113
|
+
required: Harnex captures command exits, Git state, completion, and usage, then
|
|
114
|
+
writes `HARNEX_ARTIFACT_REPORT_PATH` before emitting `task_complete`. Use
|
|
115
|
+
`--artifact-report PATH` only to choose a fixed destination; otherwise the
|
|
116
|
+
status/end row points to the default state-directory path. Review workers may
|
|
117
|
+
write advisory summary/verdict/P1-P3 counts to `HARNEX_ARTIFACT_CLAIMS_PATH`.
|
|
118
|
+
Claims and report-shaped `agentMessage` text cannot satisfy the activity gate.
|
|
119
|
+
Consumers can run `harnex artifact-report validate PATH --final` afterward.
|
|
118
120
|
|
|
119
121
|
## `harnex doctor`
|
|
120
122
|
|
|
@@ -152,8 +154,9 @@ for autonomous worker dispatches; legacy-pty is for interactive/TUI use.
|
|
|
152
154
|
- **`task_failed` immediately after dispatch.** Check
|
|
153
155
|
`harnex events --id <session>`. Provider/model failures retain their Codex
|
|
154
156
|
error message. `completed_no_activity` means the turn ended with no
|
|
155
|
-
command/tool or Git
|
|
156
|
-
|
|
157
|
+
command/tool or Git activity. `report_invalid` now primarily identifies a
|
|
158
|
+
harness receipt-write failure; old rows may still contain the legacy
|
|
159
|
+
`report_missing` / `report_rejected` classes. Common provider failures
|
|
157
160
|
include auth environment variables (for example `OPENAI_API_KEY` /
|
|
158
161
|
`AZURE_OPENAI_API_KEY`) and model unavailability.
|
|
159
162
|
|
data/docs/configuration.md
CHANGED
|
@@ -46,14 +46,15 @@ The effective value is the first-class `harnex run --phase TEXT` value, or
|
|
|
46
46
|
The allowlist must be an array of non-empty strings. Policy must be `warn` or
|
|
47
47
|
`reject`.
|
|
48
48
|
|
|
49
|
-
## Events and
|
|
49
|
+
## Events, output, and receipt retention
|
|
50
50
|
|
|
51
|
-
Per-session event JSONL
|
|
52
|
-
directory and are not the durable dispatch stream:
|
|
51
|
+
Per-session event JSONL, output transcripts, and generated proof receipts live
|
|
52
|
+
under Harnex's local state directory and are not the durable dispatch stream:
|
|
53
53
|
|
|
54
54
|
```text
|
|
55
55
|
~/.local/state/harnex/events/
|
|
56
56
|
~/.local/state/harnex/output/
|
|
57
|
+
~/.local/state/harnex/receipts/
|
|
57
58
|
```
|
|
58
59
|
|
|
59
60
|
Defaults apply independently to each directory:
|
|
@@ -73,6 +74,10 @@ Override them in repo configuration:
|
|
|
73
74
|
"output": {
|
|
74
75
|
"max_age_days": 45,
|
|
75
76
|
"max_bytes": 1073741824
|
|
77
|
+
},
|
|
78
|
+
"receipts": {
|
|
79
|
+
"max_age_days": 45,
|
|
80
|
+
"max_bytes": 1073741824
|
|
76
81
|
}
|
|
77
82
|
}
|
|
78
83
|
}
|
|
@@ -85,10 +90,12 @@ HARNEX_EVENTS_MAX_AGE_DAYS
|
|
|
85
90
|
HARNEX_EVENTS_MAX_BYTES
|
|
86
91
|
HARNEX_OUTPUT_MAX_AGE_DAYS
|
|
87
92
|
HARNEX_OUTPUT_MAX_BYTES
|
|
93
|
+
HARNEX_RECEIPTS_MAX_AGE_DAYS
|
|
94
|
+
HARNEX_RECEIPTS_MAX_BYTES
|
|
88
95
|
```
|
|
89
96
|
|
|
90
97
|
Limits must be positive integers. Harnex deletes only regular files directly
|
|
91
|
-
owned by the `events` and `
|
|
98
|
+
owned by the `events`, `output`, and `receipts` directories: expired files first, then the
|
|
92
99
|
oldest unprotected files until the size cap is met. It never follows paths
|
|
93
100
|
outside those directories. Files for the current session, live registry PIDs,
|
|
94
101
|
and alive uncompleted dispatch-start rows are protected. If protected files
|