Files
multi-agent-mux/.agents/reports/reviewer-agy-01/report-47791760.md
T
GodopuandClaude Opus 5.5 2e90c809d3 release(v4.8.1): bump framework and eight skills to 4.8.1 in lockstep; archive PR #43 reviews (two rounds)
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
2026-10-02 00:23:22 +09:00

137 lines
11 KiB
Markdown

# Code Review Report: PR #43 (`fix/issue-26`, Closes #26)
- **Job ID**: `47791760`
- **Target / Session**: `agy` (`herdr:reviewer-agy-01`)
- **Role**: Reviewer
- **Review Identity**:
- `loop_id`: `loop-20261001T131705Z-a60092`
- `base`: `e1eb22bd59ce825e3a22e86433c30f7ffd833810` (main, v4.8.0)
- `head`: `b58edace115205500c1197d9ce59cb5c6d724893`
- `tree`: `14b670fbfc82dc9179cab43cf53eef920a3d6ffa`
- Verification Path: `/var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261001T131705Z-a60092/1`
---
## 1. Executive Summary
PR #43 unifies the configuration loading rules for `.mam.env` across Bash and Python, eliminates discrepancies in integer parsing across runtime boundaries, and replaces flaky third-party public MQTT broker dependencies in the test suite with a fast, deterministic, in-process MQTT 3.1.1 broker.
Key accomplishments of the PR:
1. **Unified `.mam.env` Loader (`lib_py/delegation/envfile.py`)**: Replaced `source "$TARGET_ENV"` in the Bash wrapper with an evaluation of `shlex.quote` export statements generated by `envfile.py --shell`. Both Bash and Python now share the exact same parsing rules (standard library only).
2. **Environment Variable Precedence**: Standardized priority across both Bash and Python so that existing environment variables take precedence over values defined in `.mam.env`.
3. **Decimal Integer Normalization (`mam_int`, `mam_int_knob`, `_positive_int`)**: Standardized integer parsing across Bash and Python. Leading zeroes are stripped to prevent octal evaluation (e.g. `0700` parsed as decimal `700`, not octal `448` or erroring on `0900`), and inputs are bounded to 9 significant digits.
4. **Local In-Process MQTT Broker (`tests/_local_mqtt.py`)**: Migrated 22 broker-dependent tests from public HiveMQ to an in-process MQTT 3.1.1 broker with session fixture management and AST guards preventing public broker regression.
All test suites specified in the verification instructions passed completely in the verification path.
---
## 2. Detailed Technical Audit & Review Items
### 2.1. Parser Rule Accuracy (Item 1)
- **Single Source of Truth**:
Both Python (`lib_py/delegation/mqtt_common.py#L250`, `#L274`) and Bash (`multi-agent-mux-delegate-job#L373-L377`) delegate parsing to `lib_py/delegation/envfile.py`.
- **Parsing Mechanics (`envfile.py#L183-L211`)**:
- **Blank Lines & Comments**: `line = raw.strip()`, if empty or `line.startswith("#")`, skipped cleanly (`envfile.py#L193-L195`).
- **Key Splitting & Multiple Equals**: `key, sep, val = line.partition("=")` (`envfile.py#L196`). Values containing `=` (e.g. `EQ=a=b=c`) split only on the first delimiter.
- **Key Validation**: Keys must match `_KEY = re.compile(r"[A-Za-z_][A-Za-z0-9_]*")` (`envfile.py#L159`). Lines with invalid characters (e.g. `1BAD=1`) or spaces are skipped with line-numbered warnings (`envfile.py#L201-L203`).
- **`export KEY=` Prefix**: Skipped as invalid key because `key.strip()` evaluates to `"export KEY"`, failing `_KEY.fullmatch` (`tests/test_issue26_envfile.py#L1042`, `#L1055`).
- **Quotes Stripping**: If `val` has length $\ge 2$ and matching outer quotes (`"'`), exactly one outer pair is stripped (`envfile.py#L208-L209`).
- **No Shell Expansion**: `$(...)`, `${...}`, and backticks remain completely literal (`tests/test_issue26_envfile.py#L1053`).
- **Line Endings & Encoding**: `splitlines()` (`envfile.py#L189`) parses LF, CRLF, and CR identically. UTF-8 BOM (`\ufeff`) on line 1 is treated as an invalid key and skipped with a warning, consistent with standard POSIX environment file conventions.
- **Secret Redaction**: Warnings report `{path}:{n}: skipped ({reason})` (`envfile.py#L199`, `#L202`, `#L205`). Values are never echoed to prevent credential leaks.
- **Documentation Alignment**: `.mam.env.example#L458-L482` was updated to replace shell variable expressions (`$HOME`) with literal paths, matching parser behavior.
### 2.2. Wrapper Eval Path & Safety (Item 2)
- **Safe Export Generation (`envfile.py#L236`)**:
- `print(f"export {key}={shlex.quote(val)}")`
- Because `key` has passed `_KEY.fullmatch()` and `not is_reserved(key)`, it is guaranteed to be a valid shell identifier.
- `shlex.quote(val)` wraps values in single quotes with escaped internal quotes, preventing command substitution or variable expansion during `eval "$_env_exports"`.
- **Reserved Variables Protection (`envfile.py#L167-L181`)**:
- `RESERVED` encompasses all standard Bash shell variables (`BASH`, `IFS`, `RANDOM`, `SECONDS`, `BASH_ENV`, `SHELLOPTS`, etc.) and prefixes (`BASH_`, `COMP_`, `READLINE_`).
- Prevents arbitrary code execution via special arithmetic evaluation on assignment (e.g. `RANDOM=a[$(cmd)]`).
- The wrapper explicitly provides its own variables (`SCRIPT_DIR`, `REPO_ROOT`, `TARGET_ENV`) in the environment when invoking the parser (`multi-agent-mux-delegate-job#L373`), preventing the file from altering wrapper internals.
- **Fail-Closed on Parser Error**:
- `multi-agent-mux-delegate-job#L373-L376`:
```bash
_env_exports="$(... "${DELEGATE_JOB_PYTHON:-python3}" -I "$SCRIPT_DIR/../lib_py/delegation/envfile.py" --shell "$TARGET_ENV")" \
|| { echo "ERROR: cannot read $TARGET_ENV" >&2; exit 1; }
```
- If Python is unavailable or parsing fails, the script outputs an error and exits immediately with rc 1.
- **Python `-I` Flag**:
- Isolated mode prevents `PYTHONPATH` or `PYTHONHOME` from altering interpreter behavior, ensuring standard library execution without third-party module tampering.
### 2.3. Precedence Change Impact (Item 3)
- **Precedence Rule (`envfile.py#L218-L220`)**:
- `apply()` checks `if key not in environ: environ[key] = val`.
- When `--shell` is invoked, `main()` passes `dict(os.environ)` to `apply()` and only prints exports for keys not already defined in the caller's environment.
- **System Impact**:
- Fixes the prior defect where `set -a; source "$TARGET_ENV"` in Bash clobbered environment variables previously passed by test harnesses, loop runners, or parent shells.
- Aligns Bash behavior with Python's existing `mqtt_common` logic.
- Fully covered and verified in `tests/test_issue26_envfile.py::test_a3_an_environment_value_beats_the_file`.
### 2.4. Integer Normalization (Item 4)
- **Rule Parity**:
- Bash `mam_int` (`lib.sh#L2343-L2352`) and Python `_positive_int` (`lib_py/loop/runner.py#L288-L298`) enforce identical constraints:
1. Surrounding whitespace stripped.
2. Digits only (`^[0-9]+$`).
3. Interpreted as base-10 decimal (leading zeroes stripped; `0700` $\rightarrow$ `700`).
4. Capped at $\le 9$ significant digits before arithmetic conversion.
5. Greater than or equal to the per-knob minimum.
- **Knob Minimums & Defaults (`tests/test_issue26_ints.py#L1346-L1364`)**:
- Knobs with minimum `1`: `MAM_JOB_TIMEOUT_S` (3600), `MAM_HEARTBEAT_SEC` (30), `MAM_HEARTBEAT_MISSES` (4), `MAM_ACK_TIMEOUT_S` (180), and wrapper CLI flags (`--timeout`, `--idle-timeout`, `--heartbeat`, `--heartbeat-misses`, `--ack-timeout`).
- Knobs with minimum `0`: `MAM_INJECT_ACK_GRACE_S`, `SKS_DIALOG_TIMEOUT`, `SKS_BUSY_TIMEOUT`, `SKS_DELIVERY_GRACE_S`, `SKS_QUIESCENT_TRIES`, `delegate_wait_started:ack_s` (where 0 means "check once without waiting" or headless mode).
- **Static Guards**:
- `test_b5_no_env_default_inside_arithmetic` verified no un-sanitized `${...:-...}` reaches `$(( ... ))`.
- `test_b5_every_integer_env_default_is_classified` verified all integer-like environment defaults are tracked in `INT_KNOBS` or `NOT_ARITHMETIC`.
### 2.5. In-Process Local MQTT Broker (Item 5)
- **Broker Capabilities (`tests/_local_mqtt.py`)**:
- Implements MQTT 3.1.1 protocol subset: CONNECT/CONNACK, PUBLISH/PUBACK (QoS 0/1), SUBSCRIBE/SUBACK (wildcards `+`, `#`), UNSUBSCRIBE/UNSUBACK, PINGREQ/PINGRESP, and retained messages.
- Routing and retained storage occur before sending PUBACK (`_local_mqtt.py#L688-L690`), eliminating publication race conditions.
- **Test Suite Migration**:
- 22 tests migrated from external HiveMQ to the local broker.
- Flaky public skips in `tests/test_issue18_liveness_contract.py` were replaced with deterministic assertions verifying console records, runner logs, and subscriber audit logs.
- **Resource Cleanup**:
- Managed by pytest session fixture (`tests/conftest.py#L791-L807`).
- Ephemeral port on `127.0.0.1:0` prevents port conflicts.
- Teardown gracefully closes client sockets and shuts down listener threads.
### 2.6. Baseline Failure Claim Audit (Item 6)
- **Claim**: "13 실패 중 12건은 이 호스트의 기준 실패(test_issue10_13_purge.py)".
- **Audit Findings**:
- `git diff base..head -- tests/test_issue10_13_purge.py` shows zero changes.
- Running `test_issue10_13_purge.py` on this host in the isolated review environment yielded **23 passed in 10.35s** (100% pass).
- The 12 failures observed during full monolithic suite runs correspond to the 12 tests that invoke `_run_onboard` (`test_purge_cli_*` and `test_orc_*`). When executed in an un-isolated full run, process table scanning (`conversation_in_use`) detects artifacts from preceding test runs.
- The claim is verified as a test environment artifact of full suite runs and not a regression introduced by PR #43.
### 2.7. Architectural Boundaries (Item 7)
- Conforms to repository guidelines:
- Complex parsing, validation, and protocol logic reside in Python (`envfile.py`, `mqtt_common.py`, `_local_mqtt.py`).
- Bash scripts remain thin execution shims, using `mam_int` / `mam_int_knob` strictly for syntax validation and integer sanitization before arithmetic operations.
---
## 3. Verification Test Results
All test suites were executed in the verification path (`/var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261001T131705Z-a60092/1`) using the worktree virtualenv interpreter without exporting `.mam.env`:
| Test Suite | Result | Duration |
| :--- | :--- | :--- |
| `tests/test_issue26_envfile.py` | **17 passed** | 3.61s |
| `tests/test_issue26_ints.py` + `tests/test_local_mqtt.py` | **46 passed** | 37.98s |
| `tests/test_issue33_budget.py` + `tests/test_tier1_unit.py` | **87 passed** | 125.22s |
| `tests/test_issue18_liveness_contract.py` | **31 passed** | 97.03s |
| `tests/test_issue30_stall_watch.py` | **47 passed, 1 skipped** | 262.72s |
| `tests/test_issue10_13_purge.py` | **23 passed** | 10.35s |
| `tests/test_orc_onboard.py` | **37 passed** | 6.60s |
| Git whitespace check (`git diff base...HEAD --check`) | **Clean (0 errors)** | - |
---
## 4. Conclusion
The changes in PR #43 (`fix/issue-26`) are surgically implemented, robustly designed, thoroughly tested, and adhere strictly to repository architectural standards.
[VERDICT: PASS]