# Cross-Code Review Report — Job 14187d43

- **Reviewer**: cline (session: `herdr:canary-projects-multi-agent-mux-creator-cline`)
- **Commit under review**: `14b9de1` — `fix(herdr): ensure unique agent name via sha1 truncation and align mock errors`
- **Cumulative diff vs base**: clean working tree (`(no changes since base commit)` per brief)
- **Scope**: SHA-1 hash truncation for Herdr 0.8.0 name uniqueness (`.agents/skills/lib_py/agents/sanitize.py`, `.agents/skills/lib.sh`), Mock Herdr error output alignment (`tests/conftest.py`), early-abort regex updates (`lib.sh`), and test updates (`tests/test_sanitize_and_mock_errors.py`, `tests/test_sanity.py`).

---

## 1. Methodology

Cross-code review performed across three axes, with Bash↔Python parity as a first-class concern because the sanitize contract is implemented twice:

1. **Lint / static correctness** — syntax, shell quoting, regex anchoring, duplicate-definition consistency, import resolution.
2. **Functionality** — collision-freedom, byte-for-byte Bash↔Python parity, error-class coverage vs. the early-abort regex, lookup-path correctness.
3. **Loss / regression** — whether removed assertions reduced coverage, whether the new truncation breaks existing contracts, orphaned code.

Verification combined (a) direct file reads of all 5 changed files, (b) manual parity/collision computation in both Bash and Python, and (c) execution of the test suite (see §5).

---

## 2. Per-File Findings

### 2.1 `.agents/skills/lib_py/agents/sanitize.py`

- The legacy `s[:16]-s[-15:]` truncation is replaced with `f"{s[:23]}-{h}"` where `h = sha1(s)[:8]` (23 + 1 + 8 = 32). Hashing the **full pre-truncation string** (not the prefix) is the correct choice: it guarantees that two names sharing both prefix and suffix — exactly the sibling-workspace collision case — still differ.
- Empty-string handling returns `"agent"` (line 13), which now matches the Bash copy (line 32). This closes the prior Bash↔Python divergence documented in job `c30845cb` (Bash `"x-"` vs Python `"agent"`).
- Minor: the module-level docstring was dropped (replaced by a bare `import hashlib`). A docstring is not required, but its removal is a (cosmetic) loss of inline documentation. **Not blocking.**

### 2.2 `.agents/skills/lib.sh` (two copies: lines 29–52 and 216–239)

- Both copies of `_sanitize_herdr_agent_name` were updated **identically** (verified by reading both ranges). Consistency between the library section and the shim section is preserved.
- The hash is computed with a tool cascade `shasum → sha1sum → openssl → python3`, and `printf '%s' "$s"` (no trailing newline) is used as the hash input — matching Python's `s.encode('utf-8')`. Parity verified empirically (§5.2).
- `agent get` lookup (lines 286–307): the legacy prefix/suffix heuristic `an.startswith(tn[:14]) and an.endswith(tn[-12:])` is correctly replaced with `an == tn or an == stn` where `stn = sanitize_herdr_agent_name(tn)`. The inline Python imports `sanitize_herdr_agent_name` from `lib_py.agents.sanitize`, which resolves because lib.sh exports `PYTHONPATH="$SKILL_DIR"` (line 25). **Correct.**
- Early-abort regex (line 528): `"^usage:|unknown option|unknown flag|missing required|invalid_agent_name|^error:"`. The two new alternatives (`missing required`, `invalid_agent_name`) align with the mock's new error strings (`missing required --pane`, JSON `invalid_agent_name`). Anchoring semantics are correct under `grep -E`: `^usage:` and `^error:` bind only to their alternatives; `invalid_agent_name` is an unanchored substring match that catches the JSON error payload. **Correct.**

- **Observation (non-blocking):** the Bash fallback (`else h=$(python3 ... || echo "00000000")`) would, in the degenerate case where *all* of `shasum`/`sha1sum`/`openssl`/`python3` are unavailable, emit a constant `00000000` suffix for every long name — reintroducing the very collisions this commit fixes. In practice this path is unreachable (`python3` is a hard dependency of lib.sh itself, and `shasum` is always present on macOS / `sha1sum` on Linux), so it is a theoretical robustness note only. A future improvement could hash a disambiguating fallback (e.g. a counter or `${#s}`), but it is **not** a defect for this review.

### 2.3 `tests/conftest.py` (mock Herdr `agent start` handler)

- Unknown-flag rejection (lines 425–427): `sys.stderr.write("unknown option: " + ... + "\n"); sys.exit(1)`. Matches real Herdr 0.8.0 `unknown option: --env` format.
- Required-arg validation (lines 429–432): `missing required --pane` / `missing required --kind`. Matches the abort-regex alternative `missing required`.
- Name validation (lines 434–446): emits a JSON error payload with `error.code == "invalid_agent_name"`, which the abort-regex catches via the `invalid_agent_name` substring. **Aligned with real 0.8.0 output and with the lib.sh abort gate.**
- Validation ordering (unknown flags → required args → name) is sound: each early test in `test_mock_herdr_error_formatting_and_abort` hits the intended branch.

### 2.4 `tests/test_sanitize_and_mock_errors.py` (new)

- `test_sanitize_sibling_workspace_non_collision`: asserts the 4 real sibling workspaces (all `canary-projects-*-creator-claude`) sanitize to 4 distinct 32-char names. This is a **direct regression test for the collision bug** the legacy `s[:16]-s[-15:]` rule caused. Verified manually (§5.2): the 4 outputs are distinct with differing SHA-1 suffixes.
- `test_sanitize_bash_python_parity`: 11 edge cases (incl. empty, digit-leading, underscore-leading, 32- and 33-char boundaries) assert byte-for-byte Bash↔Python equality. **Strong contract test.** All pass.
- `test_mock_herdr_error_formatting_and_abort`: exercises all three new error classes and asserts both the exact stderr substring and that it matches the abort regex. **Correct and complete.**

### 2.5 `tests/test_sanity.py`

- The old `assert session_name.endswith("-creator-claude")` (herdr-registered name) was removed and replaced with:
  - `assert len(session_name) <= 32`
  - `assert session_name == sanitize_herdr_agent_name(sessions[0]["name"])`
- **Not a coverage loss.** The old `endswith("-creator-claude")` on the *herdr-registered* name is incompatible with the new (correct) truncation — a long workspace name truncates to `canary-projects-multi-a-039bb460`, which legitimately no longer ends with `-creator-claude`. The replacement assertion is *stronger*: it verifies the herdr agent key equals the sanitized form of the yaml session name, i.e. it pins the sanitize contract across the two stores. The unsanitized yaml name is still checked for `endswith("-creator-claude")` on line 72, so the semantic suffix check is retained where it is actually valid.

---

## 3. Cross-Cutting Consistency Checks

| Check | Result |
|---|---|
| Bash `_sanitize_herdr_agent_name` == Python `sanitize_herdr_agent_name` (11 cases incl. empty, digit/underscore leading, 32/33-char boundaries) | ✅ Identical (verified by `test_sanitize_bash_python_parity` + manual run) |
| Empty-string divergence (job `c30845cb`) resolved | ✅ Both return `"agent"` |
| Sibling-workspace collision (the root cause) eliminated | ✅ 4/4 unique 32-char names |
| Mock error strings ⊆ lib.sh abort regex | ✅ `unknown option`, `missing required`, `invalid_agent_name` all match |
| `agent get` lookup uses sanitized name (no legacy heuristic) | ✅ `an == tn or an == stn` |
| Two Bash copies of the function are identical | ✅ Lines 29–52 == 216–239 |
| Removed `endswith` assertion compensated by stronger contract assertion | ✅ |
| PYTHONPATH for inline `from lib_py.agents.sanitize import ...` | ✅ Set at lib.sh:25 |

---

## 4. Issues Identified

**Blocking issues:** none.

**Non-blocking observations:**
1. **(Robustness, theoretical)** The Bash hash fallback `echo "00000000"` would collapse all long names to the same suffix if every hash tool were unavailable. Unreachable in any supported environment (macOS has `shasum`; Linux has `sha1sum`; `python3` is itself a lib.sh dependency), so not a defect — but a future hardening could disambiguate the fallback.
2. **(Maintainability, pre-existing)** `_sanitize_herdr_agent_name` is duplicated in lib.sh (library section + shim section). Both copies are consistent after this commit, so no action is required here, but the duplication remains a drift risk.
3. **(Cosmetic)** `sanitize.py` lost its module docstring; behavior is unaffected.

None of these rise to the level of requiring a fix, and none warrant replanning.

---

## 5. Test Verification

### 5.1 Directly-affected code paths (regression baseline + new tests)
```
tests/test_herdr_shim_contract.py
tests/test_tier1_unit.py
tests/test_sanity.py
tests/test_sanitize_and_mock_errors.py
=> 39 passed in 19.54s
```
This covers the documented regression baseline (36, per prior jobs `cdd44bb3`/`1c80f10e`) plus the 3 new tests introduced by this commit.

### 5.2 Manual parity / collision verification (Bash + Python)
```
canary-projects-educative-export-tools-creator-claude  -> canary-projects-educati-9da57e6e  (32)
canary-projects-getting-started-a2a-creator-claude     -> canary-projects-getting-48a65fbb  (32)
canary-projects-multi-agent-mux-creator-claude        -> canary-projects-multi-a-039bb460  (32)
canary-projects-pu-riverpod-cookbook-creator-claude    -> canary-projects-pu-rive-5e30d500  (32)
unique: True   (collision eliminated)
"" -> "agent"   (both Bash and Python; divergence resolved)
"exact-32-chars-long-name-1234567" -> unchanged (32, not truncated; both)
"123_starts_digit" -> "x-123_starts_digit" (both)
```
Bash and Python outputs are byte-for-byte identical across all cases.

### 5.3 Remaining (non-e2e) test files
```
tests/test_deploy_freshness.py test_deploy_layout.py test_deploy_registry_merge.py
tests/test_a4_adapter_contract.py test_b4_session_created.py test_b7_diff_untracked.py
tests/test_uuid_target.py test_workspace_scope.py test_o1_rebuttal.py
tests/test_o3_scoped_guard.py test_orc_onboard.py test_b8_send_keys_verification.py
tests/test_o2_race_free_lock.py
=> 181 passed in 172.03s
```

### 5.4 e2e / integration suites (tier2/3/4)
```
tests/test_tier2_component.py test_tier3_integration.py test_tier4_e2e.py
=> 36 passed in 192.70s (0:03:12)
```
These suites spawn `reconcile.sh --subscribe --idle-timeout 0` loops and are inherently long-running (~3 min). **All 36 pass with 0 failures / 0 errors.** These suites exercise the monitor/reconcile/e2e subsystems, none of which are touched by commit `14b9de1`; their clean pass confirms no collateral regression.

### 5.5 Aggregate
- **Full suite: 256 tests pass** (39 + 181 + 36), with **0 failures, 0 errors** — matching the commit message's "256/256 passed" claim.
- Coverage spans every module, including all changed code paths (sanitize truncation, mock errors, abort regex, `agent get` lookup) and all unaffected subsystems (deploy, adapters, reconcile, e2e).
- All assertions in the new `test_sanitize_and_mock_errors.py` pass.

---

## 6. Verdict

The commit correctly replaces the collision-prone legacy truncation with a collision-free SHA-1 suffix scheme, keeps the Bash and Python implementations byte-for-byte identical (including the previously-divergent empty-string case), aligns the mock Herdr error output with real Herdr 0.8.0 and with the lib.sh early-abort regex, and simplifies the `agent get` lookup to use the sanitized name. Test changes replace a now-invalid `endswith` assertion with a stronger sanitize-contract assertion rather than weakening coverage. No blocking issues were found; the only notes are theoretical/non-blocking.

[VERDICT: PASS]