PR #48 already carries the 4.8.5 lockstep bump. Merge-workspace review: round 1 (@35935f9) claude agy grok NOT PASS (test portability: tomllib on Python 3.9, /proc and /tmp on macOS), codex no verdict (model at capacity, budget spent); fixed in36f0b8dande8d9151. Round 2 (@e8d9151) codex NOT PASS (unrunnable config check passed an unchecked merge, odd pids closed a pane, nan dropped the user's settings); fixed inab93776. Round 3 (@ab93776) 4/4 PASS. Full suite atab93776on macOS / Python 3.9: 1456 passed / 0 failed / 38 skipped. Reports and the round-3 identity sidecars go to .agents/reports/<session>/. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
4.5 KiB
Review: PR #48 round 3 @ ab93776
- Role: Reviewer (grok)
- Identity: loop
loop-20261005T085016Z-c0f6eb, basee8d9151226d8139c7b5688e83d035a3a747aeb2d, headab93776d6d1b8ca534c14b6be53f61dc3a0fa2a9, treef49ffdc8e95dc316f752fd81b2d55a0efddf1a12, one commit, clean snapshot - Scope:
git diff e8d9151 HEAD. Four files, +125/−4,git diff --checkclean. Main stayedc5c7eff. - Verified read-only at
/var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261005T085016Z-c0f6eb/1.
Codex R1–R3
| Codex | ab93776 |
|---|---|
R1. herdr_rejects raising (TimeoutExpired, OSError) was treated as a pass, so an unchecked merge could be handed to the server. A schema error in that file makes herdr drop the whole file and turn restore back on. |
_write_checked (herdr_config.py:247-258) no longer returns success on that exception. If the candidate is the merged body, it warns not using an unchecked merge and continues. The loop's next candidate is MINIMAL (:241). The merged text is not what remains: test_an_unrunnable_check_never_hands_over_an_unchecked_merge writes confirm_close = "invalid-bool", raises on the check, and the file on disk parses as only resume_agents_on_restore = false. The user file is unchanged. |
R2. _shell_in_foreground used ==, so 0/0, False/False, ""/"", and -1/-1 closed a pane. |
A value counts only when it is an int, not a bool, and > 0 (herdr_restore.py:46-55). Both pids must pass, and they must be equal. tests/test_issue45_restore_unit.py stubs herdr: those eight odd pairs, a missing process_info, and a busy pane (4242 vs 4300) do not close; 4242/4242 does. |
R3. Reparse used ==, and nan != nan, so one valid nan dropped the rest of the user's settings. |
_same_doc (herdr_config.py:140-149) treats two floats as equal when both are nan, and walks dicts and lists. server_config_text uses it at :171. The three cases (top-level, array including -nan, nested inline table) keep confirm_close and warn nothing. |
MINIMAL when the check cannot run
Codex asked to return no path if the check of MINIMAL also cannot run. This commit writes MINIMAL and warns using the fixed minimal config unchecked (:257-258).
That is the right call. lib.sh starts the server with restore on when the config path is empty. Returning None would reopen #45 in the one case where no check can be obtained (timeout, missing binary, OSError). MINIMAL is the constant [session]\nresume_agents_on_restore = false\n (:51), not a user document, and test_real_herdr_accepts_every_result already shows herdr 0.9.1 accepts it whenever config check can run. The unchecked write happens only when that command cannot be executed, so there is no schema verdict to wait for. Unknown nonzero exits are still ignored unless the output contains parse error or using defaults (herdr_rejects, :190-191); herdr uses a nonzero status for a dropped setting that does not drop the file.
_same_doc beside ==
For values a TOML round trip produces, it matches ==, plus nan. Dict keys are compared as a set (a.keys() == b.keys()), list order is kept (zip), datetimes use ==, and inf / -inf follow ==.
Two pairs differ, both stricter: True == 1 is true and _same_doc(True, 1) is false; 1 == 1.0 is true and _same_doc(1, 1.0) is false. The writer emits a bool before the int branch (_value, :108-111) and emits a float with repr (:117), so a document tomllib parsed does not come back as the other type. A round trip that did change type fails closed into MINIMAL with a warning, which == would have accepted.
Scope
The delta is herdr_config.py, herdr_restore.py, the two new tests in test_issue45_herdr_config.py, and tests/test_issue45_restore_unit.py. No skill text, inventory, or version line. 4.8.5 is not on main; the fallback to the key-only file is already what VERSIONS.md describes.
Tests
Python 3.9.6, the four files in the brief, --basetemp=/tmp/2a66follow.bPQAFP: 53 passed, 34 skipped in 77.84s. The skips are the needs tomllib cases, including the new R1 and R3 tests. test_issue45_restore_unit.py ran.
Python 3.11, the same venv named in the brief, tests/test_issue45_herdr_config.py and tests/test_issue45_restore_unit.py, HOME pointed at an empty temp directory: 67 passed in 0.41s.
No mamt45 process remained. ~/.config/herdr/config.toml mtime stayed 1784456394, the directory mtime stayed 1791183576, and mam-server-config.toml was not created there. Snapshot git status was empty.
[VERDICT: PASS]