# ๐Ÿ” Cross-Code Review โ€” Hermes Agent Support Implementation, Follow-Up (Job fcb16ed6) - **Reviewer**: `planner-reviewer-claude-01` - **Target diff**: revised implementation of `plan-28f9b565.md`, superseding the diff reviewed in job `685bb381` (`[VERDICT: PASS]`, with 2 non-blocking findings). This diff addresses both of those findings plus adds two proactive fixes not previously flagged. - **Method**: same as the prior review โ€” read every changed file's live post-diff state directly (branch `support-hermes`), traced call chains, ran `bash -n` syntax checks, and ran the actual test suite. --- ## 1. Disposition of my Previous Review's Findings (job 685bb381) | Finding | Status this round | |---|---| | ยง4.1: `multi-agent-mux-resume/SKILL.md` doc example was stale (didn't include `--no-restore-cwd --yolo --accept-hooks`) | โœ… **Fixed.** Now reads `hermes) CMD_FULL="hermes --resume $UUID --no-restore-cwd --yolo --accept-hooks" ;;` โ€” verified it matches `resume_session.sh`'s real fallback string exactly (modulo the illustrative literal binary name, consistent with how the doc renders every other agent's row). | | ยง4.2: `_sibling_claimed_uuids` set on the hermes row in `reconcile.sh` but never read by `hermes.py::verify_artifact()` (unlike `agy`'s adapter-level pattern) | **Not touched directly** โ€” `hermes.py::verify_artifact()` still doesn't read `ctx.row`. This is unchanged from the prior diff and remains a minor architectural-parity note, not a live bug (the explicit loop-level `if uuid in sibling_claimed: continue` in `reconcile.sh` still enforces it correctly on its own, confirmed again this round โ€” see ยง3). Still non-blocking. | --- ## 2. New Changes Beyond the Prior Diff (not requested by my previous review โ€” found and verified independently) ### 2.1 `hermes.py::discover()` rewritten to return multiple candidates (previously `LIMIT 1`) ```python def discover(self, ctx: DiscoveryContext) -> list: ... if ctx.epoch: rows = conn.execute("SELECT id FROM sessions WHERE cwd=? AND started_at >= ? ORDER BY started_at DESC LIMIT 20", ...) else: rows = conn.execute("SELECT id FROM sessions WHERE cwd=? ORDER BY started_at DESC LIMIT 20", ...) ... candidates = [] for (cand,) in rows: if cand and self.verify_artifact(cand, ctx): candidates.append(cand) return candidates ``` This is a genuine, previously-unflagged fix: the old `discover()` used `fetchone()`/`LIMIT 1`, making hermes the only adapter whose `discover()` could never surface more than one candidate โ€” inconsistent with `grok.py`/`agy.py`/`cline.py`, whose `discover()` methods already return every verified candidate. **Checked for regression risk**: grepped every call site of `.discover(` across the repo โ€” the only real caller is `workspace_uuid.py:81` (`for cand in adapter.discover(ctx):`), which already iterates rather than indexing, so it handles 0/1/many candidates identically regardless of agent. No caller assumes a single-element list. This change makes hermes consistent with the rest of the framework rather than introducing risk. The new `test_hermes_verify_artifact_spawn_epoch_timing_f1` test specifically exercises `discover()` with a mix of old (`started_at < epoch`) and fresh rows and asserts only the fresh one survives โ€” I re-ran it directly, passes. ### 2.2 `create_session.sh`: `HERDR_EPOCH` capture moved earlier, before `spawn()` ```diff +HERDR_EPOCH=$(date +%s) +NOW_ISO=$(date -u +'%Y-%m-%dT%H:%M:%SZ') + spawn ... -HERDR_EPOCH=$(date +%s) -NOW_ISO=$(date -u +'%Y-%m-%dT%H:%M:%SZ') ``` This closes a real timing edge case in Rev.2's own epoch-based fix that neither my review nor the plan itself had caught: previously `HERDR_EPOCH` was captured **after** `spawn()`, `wait_for_tui_ready`, and pane-metadata resolution โ€” all of which can take multiple seconds. Since `HERDR_EPOCH` becomes `herdr_session_epoch` in the registry and flows into `ctx.epoch` for the new `started_at >= ctx.epoch` check, a late-captured epoch could end up **later** than the freshly-spawned session's own `started_at`, causing the epoch guard to falsely reject the very session it was meant to validate โ€” self-defeating. Capturing it immediately before `spawn()` guarantees `HERDR_EPOCH <= started_at` for the session about to be created. **Verified this is safe for every agent, not just hermes**: `HERDR_EPOCH` is a single shared line (not gated by `$AGENT`), consumed generically by `verify_session_uuid`'s `epoch = row.get("herdr_session_epoch", 0)` for all agents. For claude/agy/grok, whose `verify_artifact()` implementations use `os.path.getmtime(path) < ctx.epoch`, an earlier epoch can only make that check *more* lenient (smaller epoch โ†’ less likely to be `>` a file's mtime), never *more* restrictive โ€” so this is a strictly safe, general robustness improvement, not a hermes-only special case. `grep -rn "HERDR_EPOCH"` confirms its only consumer (`create_session.sh:346`, feeding `lib.sh`'s YAML-write step) is unaffected by the earlier capture point โ€” it only needs the variable to exist by the time it's read, which it still does. --- ## 3. Re-Verification of Everything from the Prior (Already-PASSed) Review Re-traced and re-confirmed unchanged/still-correct (identical diff hash `974a367` for `reconcile.sh` vs. the prior review โ€” no regression risk here, but re-verified functionally with the fuller test run below): - Core `C-ambiguous` epoch fix (`verify_artifact` row-level `started_at` check + `reconcile.sh`'s `started_at >= ?` SQL filter + sibling-exclusion loop) โ€” still correct, still passes its dual-direction regression test. - `--yolo --accept-hooks` / `--no-restore-cwd` wiring across `spawn_spec`/`resume_spec`/`create_session.sh`/`resume_session.sh`/both `SKILL.md` files โ€” consistent everywhere, no drift. - `input_prompt`/`input_placeholder`/`input_rule_pattern`/`ready_tokens` โ€” unchanged, still correct. `bash -n` on `create_session.sh` (re-checked after the epoch-timing edit) โ€” valid. --- ## 4. Test Suite โ€” Functional Verification ``` .venv/bin/python -m pytest tests/test_a4_adapter_contract.py -q -v โ†’ 19 passed (17 from before + 2 new: test_hermes_verify_artifact_spawn_epoch_timing_f1, test_hermes_reconcile_full_block_integration) .venv/bin/python -m pytest tests/ -q โ†’ 441 passed in 625.89s (0:10:25), exit code 0 ``` I ran the full suite myself (not the diff's own claims) rather than sampling only the adapter-contract file, given this diff touches session-creation timing (`create_session.sh`) which is broader-surface than the previous diff. **441 passed vs. 439 in the previous review โ€” the +2 matches exactly the two new hermes regression tests added in this diff, and there are zero failures.** --- ## 5. Findings Carried Forward (non-blocking, unchanged from job 685bb381) - `_sibling_claimed_uuids` is still set-but-unread at the `hermes.py` adapter level (ยง1 above). Still recommend either removing the unused field or moving the check into `verify_artifact()` for architectural parity with `agy`'s pattern โ€” purely a consistency/future-proofing item, not a live defect. No new findings beyond that one. No design rework is warranted โ€” this round demonstrably improved on the already-PASSed implementation rather than introducing regressions. --- ## 6. Verdict Both items from my previous review are now closed (one fully fixed, one confirmed still non-blocking and unchanged), and the two additional changes in this diff (`discover()` multi-candidate parity, `HERDR_EPOCH` pre-spawn capture) are correct, well-targeted fixes to real edge cases in the underlying epoch-based design โ€” verified independently via call-site tracing and the full test suite, not accepted on the diff's own say-so. No correctness defects found; no escalation warranted. [VERDICT: PASS]