mesh(audit): v0.4.1 polish bundle — poison-record taxonomy filter, SEQ_LOCK_DEGRADED ordering, errno hoist, fdopen wrapper symmetry (from #221 R5)
Bundle of v0.4.1 polish items extracted from #221 review feedback. All non-blocking, all backward-compatible. Filed as one issue to keep tracker noise low — each section can land as its own small commit or as a single sweep.
**Source:** PR #221 review threads from yinsong1986 dated 2026-06-02 / 2026-06-03 (post-approval `[FOLLOW-UP]` markers).
---
## 1. Poison-record taxonomy filter at `audit.py:593`
The seed-walk filter (`_load_seq_counters`, line ~593) explicitly excludes `PSK_DEGRADED` and `SIGN_FAILED` poison sentinels but not the R4-introduced `SEQ_LOCK_DEGRADED` sentinel. Today the filter is correct only by virtue of two downstream invariants:
1. `seq > 0` at line 585 rejects all `SEQ_LOCK_DEGRADED` records (written with `seq=0` at line 1035), and
2. The HMAC compare at line 597 fails against the literal string sentinel.
If a future change ever assigns a non-zero placeholder seq to a `SEQ_LOCK_DEGRADED` record (e.g. `last_known_seq + 1`), this filter silently allows the poison through and a forged poison record could seed `_SEQ_COUNTERS`.
**Fix:** make the relationship explicit in the filter:
```python
if not isinstance(sig, str) or sig in ("PSK_DEGRADED", "SIGN_FAILED", "SEQ_LOCK_DEGRADED"):
```
Cheap defence-in-depth and documents the full poison-record set in one place.
---
## 2. `SEQ_LOCK_DEGRADED` poison records share `seq=0` for incident triage (`audit.py:1056`)
Multiple consecutive symlink-swap attempts produce N records with identical `(peer_id, seq=0)` and no internal ordering. The verifier path is correct (these flag `bad_signature` and the per-peer cursor doesn't advance), but operational forensics is degraded: an incident responder can't count distinct attempts or correlate timestamps with seq positions.
**Fix options:**
- Synthetic decreasing seq (-1, -2, ...) gated on `seq_lock_degraded_reason is not None`, or
- Separate `attempt_id` field that increments per-poison-record-write
Cosmetic but cheap to add; meaningfully improves triage.
---
## 3. `import errno` should hoist to module top (`audit.py:414`)
Per AGENTS.md > Key Conventions #4 ("Imports at file top — unless lazy-loading heavy deps with documented reason"), `errno` is a stdlib stub with no import cost and should not live inside an `except OSError` body. Hoist to module-level imports.
Also: the surrounding comment block (L407-432 in `_seq_flock`) is unusually long for an in-function explanation. Most of it could move to the `SeqLockSymlinkError` class docstring at L809-819 (where it's already partially duplicated) and leave a 2-line breadcrumb here pointing at the class. Style/readability nit.
---
## 4. `fdopen` wrapper dead-code at `audit.py:1165` (mirrors R3 fix at L703-728)
The `try: ... except Exception: try: os.close(fd) except OSError: pass; raise` cleanup wrapper around `with os.fdopen(fd, "a", ...) as fh:` is the same dead-code shape R3 already excised from `_persist_seq_counters`. The context manager closes `fd` on any in-block exception; the outer `os.close` unconditionally hits EBADF (suppressed by the inner `except OSError`).
**Fix:** drop the wrapper and let `with os.fdopen(...) as fh:` own fd cleanup directly — symmetric with the R3 fix. If the `except` is kept for `fdopen`-itself-raising defence, narrow to `except OSError:` per AGENTS.md > Review Learnings (#86).
---
## Acceptance criteria
- [ ] Poison-record filter at L593 enumerates all three sentinels explicitly
- [ ] `SEQ_LOCK_DEGRADED` records carry an ordering field (decreasing seq OR `attempt_id`)
- [ ] `import errno` is at file top
- [ ] `_seq_flock` long comment block reduced to a 2-line breadcrumb pointing at `SeqLockSymlinkError` docstring
- [ ] `fdopen` wrapper at L1165 either deleted or narrowed to `except OSError`
- [ ] No behavioural changes to existing pin tests
## Out of scope
- The NFS `fcntl.flock` deployment caveat — separate v0.4.1 issue (deployment-shaped, not polish-shaped)
- The `_load_seq_counters` retry semantics (`audit_log_seeded` flag-flip outside `try:`) — separate v0.4.1 issue (behavioural, not polish-shaped)
---
*Filed as v0.4.1 follow-up after #221 was approved by sundargthb on 2026-06-03 with the disposition "all queue for v0.4.1 follow-ups, none of them backward-incompatible."*
0 条评论