- Add --yolo and --accept-hooks headless auto-approval flags to spawn_spec and resume_spec
- Define Hermes TUI input delimiters (input_prompt='❯', input_rule_pattern='─{10,}')
- Refactor verify_artifact and discover in hermes.py using session started_at timestamps
- Fix HERDR_EPOCH capture timing before spawn in create_session.sh to prevent epoch race
- Update reconcile.sh for hermes drift-C multi-candidate and sibling claimed exclusion
- Add Hermes contract, epoch filtering, and C-ambiguous unit tests (140 passed)
- Add agent evaluation report and final review reports for Hermes support
55 lines
7.0 KiB
Markdown
55 lines
7.0 KiB
Markdown
# 📋 Code Review Report — Hermes Support Modernization Rev.3 (Job ca4539e8)
|
||
|
||
- **Reviewer**: `reviewer-hermes-01` (role: reviewer)
|
||
- **Reviewed diff**: branch `support-hermes` — 7 files, +231/−34 (working tree, unstaged) plus 2 untracked report/plan documents
|
||
- **Delta vs. previous review (job b45fb1d4, verdict PASS)**: this revision adds (1) a multi-candidate `discover()` rewrite in `hermes.py`, (2) the `HERDR_EPOCH` capture moved from post-TUI-wait to pre-spawn in `create_session.sh` (fix "F1"), (3) `multi-agent-mux-resume/SKILL.md` alignment, and (4) two new tests — `test_hermes_verify_artifact_spawn_epoch_timing_f1` and `test_hermes_reconcile_full_block_integration` ("F3").
|
||
- **Method**: static audit of every changed file, cross-layer consistency checks, full test-suite execution, shell/python syntax checks. No project files modified.
|
||
|
||
---
|
||
|
||
## 1. Verification Evidence (all checked, not assumed)
|
||
|
||
| # | Check | Result |
|
||
|---|---|---|
|
||
| 1 | Full test suite (`pytest tests/`) | ✅ **441 passed, 0 failures** (584.8 s) — includes the 5 hermes tests from Rev.2 plus the 2 new F1/F3 tests |
|
||
| 2 | `bash -n` on create/reconcile/resume scripts; `py_compile` on hermes.py + tests | ✅ clean |
|
||
| 3 | `HERDR_EPOCH` capture timing | ✅ now at create_session.sh:222, immediately before `spawn` (line 225). Previously captured at line ~290 (post `wait_for_tui_ready`) — i.e. potentially **after** the agent process had already inserted its `started_at` row into `state.db`, which would make the recorded `herdr_session_epoch` ≥ `started_at` and cause `verify_artifact`'s epoch filter to reject the session's own row. The move eliminates that race; the F1 test (`test_hermes_verify_artifact_spawn_epoch_timing_f1`) encodes exactly this scenario (fresh row at T0+0.1 verifies; old row at T0−3600 rejected; `discover(ctx_spawn) == ['u-fresh']`). |
|
||
| 4 | `HERDR_EPOCH` consumer consistency | ✅ only consumers are the yaml registration (line 346, via `atomic_dump_yaml`) and SKILL.md's documented workflow (updated comment matches the new placement: "stamp the epoch locally … we just spawned this session ourselves"); no other script reads `HERDR_EPOCH`, so the earlier capture cannot break downstream consumers |
|
||
| 5 | `discover()` rewrite vs. reconcile.sh drift-C | ✅ now structurally aligned: epoch-filtered multi-row query (`started_at >= ? LIMIT 20`) when `ctx.epoch` is set, unfiltered fallback when 0, per-candidate `verify_artifact()`, returns **list** (multiple candidates flow to `find_workspace_uuid`'s `emit()` which prints the first and exits — same first-match semantics as before; ambiguity surfaced by reconcile, which is the component responsible for C-ambiguous). Closes the §3.1 follow-up item from my previous review (b45fb1d4). |
|
||
| 6 | `discover()` caller contract | ✅ sole production caller is `workspace_uuid.py:81` (`adapter.discover(ctx)` → iterate/emit) — list return type matches; `DiscoveryContext.epoch` is populated by `verify_session_uuid` in discover mode, and by `find_workspace_uuid_main` the ctx carries epoch=0 (unfiltered branch), which is correct there because tier-1/running-id exclusion already disambiguates |
|
||
| 7 | Resume command three-way consistency | ✅ adapter `resume_spec()`, `resume_session.sh` fallback (line 110), **and now `multi-agent-mux-resume/SKILL.md`** (line 90) all emit `hermes --resume $UUID --no-restore-cwd --yolo --accept-hooks` |
|
||
| 8 | Spawn command three-way consistency | ✅ `spawn_spec()` / `create_session.sh:188` / `multi-agent-mux-create/SKILL.md:157` all `hermes --yolo --accept-hooks` |
|
||
| 9 | F3 sibling-exclusion test vs. reconcile.sh block | ✅ `test_hermes_reconcile_full_block_integration` replicates the block's candidate-gathering (SQL epoch filter + `_sibling_claimed_uuids` skip + `verify_session_uuid`) and asserts exactly `['u-target']` with a claimed sibling present — matches reconcile.sh:740–767 line-for-line semantics |
|
||
| 10 | Previously verified facts (unchanged in this revision) | ✅ carried over from b45fb1d4: CLI flags exist on installed hermes; `state.db` schema (`started_at REAL NOT NULL` + index); facts-emitter readiness plumbing; reconcile block = agy pattern; `verify_session_uuid` ↔ `verify_artifact` epoch-mode agreement |
|
||
|
||
## 2. Plan DoD Cross-Check (plan §5 → diff)
|
||
|
||
All b45fb1d4 DoD items remain satisfied (no regression between revisions — re-verified the adapter file end-to-end). New in this revision:
|
||
|
||
| Item | Status |
|
||
|---|---|
|
||
| `discover()` aligned with reconcile pattern (my prior review's follow-up recommendation) | ✅ adopted — multi-candidate + epoch filter, exception-safe (`except: return []`) |
|
||
| F1 spawn-epoch race fixed and regression-tested | ✅ capture moved pre-spawn; dedicated test with realistic timing (T0+0.1s fresh row) |
|
||
| F3 sibling-exclusion behavior regression-tested | ✅ dedicated test simulating the reconcile block |
|
||
| Resume SKILL.md docs gap (hermes resume line lacked flags) | ✅ updated, matches script and adapter |
|
||
|
||
## 3. Findings
|
||
|
||
No blocking defects. Non-blocking observations:
|
||
|
||
1. **[Low — edge case, fail-open]** In `verify_artifact`, a row with `started_at` NULL/0 bypasses the epoch check (`if ctx.epoch and started_at and …`). The production schema declares `started_at REAL NOT NULL`, so this is unreachable in practice (same as prior review §3.3). Behavior is fail-open by design; acceptable.
|
||
2. **[Low — cosmetic]** In `discover()`, when `ctx.epoch` is 0 the unfiltered query can return historical sessions for the same cwd; however the sole caller (`find_workspace_uuid`) already excludes running/orchestrator-claimed UUIDs and prefers per-row own-id, so mis-pinning risk is bounded. The epoch-0 branch exists precisely to serve that caller. Acceptable.
|
||
3. **[Info]** `test_hermes_reconcile_full_block_integration` re-implements the reconcile block's gathering logic in Python rather than executing reconcile.sh itself. This is a reasonable unit-level compromise (the shell integration path is covered by the tier-2/3 suites); noted for future hardening if drift between test and block is a concern.
|
||
4. **[Info]** Trailing blank lines at end of the new test functions (cosmetic only).
|
||
|
||
## 4. Regression Risk Assessment
|
||
|
||
- The `HERDR_EPOCH` move is the only behavioral change to a shared creation path, and it is strictly in the safer direction: an epoch stamped *earlier* widens (never narrows) the acceptable-candidate window, and the C-ambiguous guard remains the backstop for over-wide windows. Consumers verified — no reader expects the post-spawn value.
|
||
- `discover()`'s list-return is contract-compatible with its only caller; the epoch-0 branch preserves prior behavior for that path.
|
||
- Live corroboration: this review session itself is running on the reviewed adapter stack (spawn → onboarding → event publication → job execution) with zero stalls.
|
||
|
||
## 5. Verdict
|
||
|
||
Both previously-identified follow-ups (discover() alignment, epoch-timing race) are now fixed, the fixes carry dedicated regression tests, the full suite passes with zero regressions (441 tests), and all three layers (adapter / scripts / SKILL docs) remain mutually consistent. No new defect found.
|
||
|
||
[VERDICT: PASS] |