- 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
7.0 KiB
7.0 KiB
📋 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 inhermes.py, (2) theHERDR_EPOCHcapture moved from post-TUI-wait to pre-spawn increate_session.sh(fix "F1"), (3)multi-agent-mux-resume/SKILL.mdalignment, and (4) two new tests —test_hermes_verify_artifact_spawn_epoch_timing_f1andtest_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:
- [Low — edge case, fail-open] In
verify_artifact, a row withstarted_atNULL/0 bypasses the epoch check (if ctx.epoch and started_at and …). The production schema declaresstarted_at REAL NOT NULL, so this is unreachable in practice (same as prior review §3.3). Behavior is fail-open by design; acceptable. - [Low — cosmetic] In
discover(), whenctx.epochis 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. - [Info]
test_hermes_reconcile_full_block_integrationre-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. - [Info] Trailing blank lines at end of the new test functions (cosmetic only).
4. Regression Risk Assessment
- The
HERDR_EPOCHmove 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]