# 🔍 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]
