Issue #26: one .mam.env parser for the wrapper and the Python tools, decimal integer knobs, tests on a local MQTT broker. Merge-workspace review: round 1 (@b58edac) claude agy PASS, codex NOT PASS (R1-R4), grok no verdict (its late report, archived as report-c9ed5b14.md, found R1 too); round 2 (@0eec795) 4/4 PASS. Reports and round-2 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
79 lines
6.1 KiB
Markdown
79 lines
6.1 KiB
Markdown
# Code Review Report (Round 2 Delta): PR #43 (`fix/issue-26`)
|
||
|
||
- **Job ID**: `9a1aef9d`
|
||
- **Target / Session**: `agy` (`herdr:reviewer-agy-01`)
|
||
- **Role**: Reviewer
|
||
- **Review Identity**:
|
||
- `loop_id`: `loop-20261001T140030Z-34381f`
|
||
- `base`: `e1eb22bd59ce825e3a22e86433c30f7ffd833810` (main, v4.8.0)
|
||
- `head`: `0eec795cd1b46f7a28b9a1cc87ef8577619a731f`
|
||
- `tree`: `584eac551f880232896b898cc43156f28ae1bacb`
|
||
- Verification Path: `/var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261001T140030Z-34381f/1`
|
||
|
||
---
|
||
|
||
## 1. Executive Summary
|
||
|
||
This report covers the Round 2 delta review of PR #43 (`fix/issue-26`, commit `0eec795`), evaluating the fixes applied in response to Round 1 review findings from Codex (R1–R4) and Claude (R1, R2).
|
||
|
||
In Round 1, `agy` assessed PR #43 as **PASS**. Commit `0eec795` incorporates surgical improvements addressing all identified edge cases:
|
||
1. **Unreadable configuration error handling (Codex R1)**: `envfile.parse()` raises `EnvFileError` upon I/O or UTF-8 decoding failure, causing `--shell` and the Bash wrapper to exit with rc 1 (matching pre-#26 fail-closed semantics). Python entry points (`mqtt_common._parse_env_file`) also propagate this exception rather than running on empty defaults.
|
||
2. **Strict ASCII digit & whitespace matching (Codex R2)**: `lib.sh` `mam_int` now explicitly matches ASCII whitespace (`$' \t\n\r\v\f'`) and ASCII digits (`0123456789`), eliminating locale differences (such as Unicode space matching under `en_US.UTF-8` vs `C`).
|
||
3. **Explicit empty flag rejection (Codex R3)**: Options tracking via `_INT_FLAGS_GIVEN` ensures that explicitly passed empty values (e.g. `--timeout ""`) are strictly rejected with an error instead of silently falling back to default values.
|
||
4. **NUL byte handling parity (Codex R4)**: Lines containing NUL bytes (`\0`) are skipped with a warning naming the line number in both Bash and Python loaders.
|
||
5. **Documentation clarity (Claude R1, R2)**: `.mam.env.example` includes a comprehensive `FORMAT` specification, and wrapper error messages have been clarified.
|
||
|
||
All test suites passed in the verification path.
|
||
|
||
---
|
||
|
||
## 2. Review Findings & Audit Items
|
||
|
||
### 2.1. Audit of Round 1 Blocker Resolutions in `0eec795`
|
||
|
||
| Finding | Description & Location | Resolution in `0eec795` | Status |
|
||
| :--- | :--- | :--- | :--- |
|
||
| **Codex R1** | Unreadable env file proceeded with defaults in wrapper | `envfile.parse` raises `EnvFileError` on `OSError`/`UnicodeDecodeError`. `--shell` exits with rc 1 $\rightarrow$ wrapper exits rc 1. Python loader stops similarly (`envfile.py#L210-L211`, `#L257-L259`). | **CLOSED** |
|
||
| **Codex R2** | Locale-dependent `[[:space:]]` and `[0-9]` in `mam_int` | `mam_int` explicitly matches ASCII characters `[ \t\n\r\v\f]` and `[0123456789]` (`lib.sh#L76-L78`), aligning with Python `_positive_int`. | **CLOSED** |
|
||
| **Codex R3** | Explicit empty flags bypassed validation | `_INT_FLAGS_GIVEN` records supplied flags; explicitly provided empty values are validated and rejected (`multi-agent-mux-delegate-job#L455-L476`). | **CLOSED** |
|
||
| **Codex R4** | Divergent behavior on NUL bytes | Lines containing `\0` are cleanly skipped with `{path}:{n}: skipped (NUL byte)` warning across both loaders (`envfile.py#L216-L218`). | **CLOSED** |
|
||
| **Claude R1** | Missing format specification in example file | Added detailed `FORMAT` comment block to `.mam.env.example#L14-L26`. | **CLOSED** |
|
||
| **Claude R2** | Wrapper error message wording mismatch | Wrapper prints `ERROR: cannot load ... (see the line above)` (`multi-agent-mux-delegate-job#L405`). | **CLOSED** |
|
||
|
||
---
|
||
|
||
### 2.2. Evaluation of Python Entry Point Read Failure Behavior (Brief Question)
|
||
|
||
> **Question from Brief**: Is stopping with an exception upon `.mam.env` read/decode failure the right design for Python entry points (e.g. `publish_event.py` within agent sessions), or should it warn and continue?
|
||
|
||
**Recommendation**: **Stopping with an exception (`EnvFileError` / exit rc 1) is the correct and necessary design.**
|
||
- **Fail-Closed Security**: `.mam.env` exists to specify vital connection parameters (broker host, port, TLS settings, credentials). If a file exists on disk but is unreadable (permission failure or encoding corruption), silently continuing would cause processes to connect to default or public brokers with missing authentication, potentially causing silent timeouts or security exposures.
|
||
- **Symmetry with Bash**: Prior to #26, Bash `source "$TARGET_ENV"` failed with an error on unreadable files. Allowing Python to warn and continue while Bash exits with rc 1 would create an inconsistent split-brain runtime state between the wrapper and delegated Python processes.
|
||
- **Granular Error Scoping**: Syntactic errors on individual lines (unrecognized keys, reserved names, NUL bytes) continue to be safely skipped with line warnings. Halting is strictly reserved for catastrophic file-level I/O / decoding failures where the configuration file cannot be read as a whole.
|
||
|
||
---
|
||
|
||
## 3. Verification Test Results
|
||
|
||
Tests executed in verification path `/var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261001T140030Z-34381f/1`:
|
||
|
||
| Test Suite | Result | Duration |
|
||
| :--- | :--- | :--- |
|
||
| `tests/test_issue26_envfile.py` | **20 passed** | ~6.5s |
|
||
| `tests/test_issue26_ints.py` | **51 passed** | ~40s |
|
||
| `tests/test_local_mqtt.py` | **5 passed** | ~4s |
|
||
| `tests/test_issue18_liveness_contract.py` | **31 passed** | 97.19s |
|
||
| `tests/test_tier1_unit.py` | **67 passed** | 60.45s |
|
||
| `tests/test_issue10_13_purge.py` | **23 passed** | 10.35s |
|
||
| Git whitespace check (`git diff base...HEAD --check`) | **Clean (0 errors)** | - |
|
||
|
||
*(Note on `test_acceptance2` in `test_issue18_liveness_contract.py`: Under heavy CPU scheduling load across large test batches, wall-clock wait duration `${ACK_WAITED_S}` can measure 5s instead of 4s, which is an ambient timing tolerance in test_issue18 and unrelated to PR #43 changes. When executed individually, all 31 tests pass 100%.)*
|
||
|
||
---
|
||
|
||
## 4. Conclusion
|
||
|
||
Commit `0eec795` thoroughly and cleanly resolves all issues raised in Round 1. The implementation remains minimal, robust, and compliant with all project architectural standards.
|
||
|
||
[VERDICT: PASS]
|