# Self-audit after v3.1.9

Done after the AUDIT_FINDINGS_FOR_CLAUDE.md refresh at commit
30d8b71. This cross-checks what v3.1.9 actually fixed vs. what
the external audit flagged vs. what v3.2.0 still owes.

Audit commit: `30d8b71`  (previous `6f23d01` before.)
Audit tool: `claude-code-audit` (external)
My cross-check commit: `9508035` (v3.1.9 release).

## External audit findings

### §1.1 Redundant entry points — **PARTIALLY ADDRESSED**

- ✅ `src/mcp_server.py` simplified from 50 LOC globals()+
  `__getattr__` pattern to 32 LOC star-import + `main`
  re-export. Public surface preserved (105 symbols verified).
- ⚠️ `mcp_server.py` top-level shim **intentionally kept** its
  47-LOC `exec(compile(_SOURCE, ...))` pattern after a test
  regression surfaced: `tests/test_mcp_v140.py` uses
  `patch.object(self.mod, "fts_query", ...)` on this module and
  the patch must propagate to the tool functions. A plain
  re-export breaks those patches because tool functions resolve
  `fts_query` through their own originating module, not the
  importer's namespace. Docstring now explains this.
- ✅ `src/mind_mem/mcp_entry.py` unchanged — it's the canonical
  console-script entry (`mind-mem-mcp`).

Net: structural improvement where safe; fundamental
deduplication (drop the top-level shim entirely) waits for v4.0
when the console-script entry is the only documented path.

### §1.2 God object — **UNCHANGED**

`src/mind_mem/mcp_server.py` still 4604 LOC hosting 57 MCP
tools + 8 resources + cross-cutting infra. The full
decomposition plan is shipped in
`docs/v3.2.0-mcp-decomposition-plan.md` (14 tool modules +
6 infra modules + 8 resource modules across 16 per-PR
increments). Actual moves happen in v3.2.0 because they touch
the production MCP surface and benefit from staged rollout.

### §1.3 Validation duality — **PARTIALLY ADDRESSED**

- ✅ `validate.sh` emits a stderr deprecation warning on every
  invocation (v3.1.8, commit `4b0116e`).
- ✅ Opt-out env var `MIND_MEM_VALIDATE_BASH=1` for parity audits.
- ✅ `tests/test_validate_sh_deprecation.py` pins the warning
  text + opt-out semantics.
- ⚠️ `validate.sh` body unchanged — still 663 LOC of bash checks
  that run in parallel with `validate_py.py`. Full conversion
  to a thin shim that execs `python3 -m mind_mem.validate_py`
  requires parity verification across the V2.1-V2.9 bash check
  codes, which is a v3.2.0 PR.
- ⚠️ `_task_status_literals.sh` was called out by the audit as
  "perpetuating the DRY violation across languages." Counter-
  argument: it's AUTO-GENERATED from `enums.py` by
  `scripts/regen_bash_literals.py` — the DRY fix is exactly
  that the bash source no longer hand-codes the literals. The
  file exists so the bash validator can still read the
  authoritative list, and disappears once the bash validator
  does.

Net: migration path is clear and documented; full collapse
happens when the bash validator retires.

### §1.4 Storage protocol bypass — **UNCHANGED**

`src/mind_mem/capture.py` lines 258-268 directly open + lock +
read + write `SIGNALS.md`:

```python
def append_signals(workspace: str, signals: list[dict], date_str: str) -> int:
    signals_path = os.path.join(workspace, "intelligence", "SIGNALS.md")
    ...
    with FileLock(signals_path):
        with open(signals_path, "r", encoding="utf-8") as f:
            existing = f.read()
        ...
        with open(signals_path, "a", encoding="utf-8") as f:
            f.write(...)
```

This bypasses the `BlockStore` abstraction the audit flagged.
Full fix is the Phase 5 PR in
`docs/v3.2.0-blockstore-routing-plan.md`: `BlockStore.
write_block()` method lands on the protocol, the Markdown
implementation wraps today's `_safe_copy` code path, and
`capture.py` switches to `store.write_block(signal_block)`. No
on-disk format change.

### §2.2 Atomicity scope — **UNCHANGED**

Snapshot still excludes `maintenance/` wholesale. Plan in
`docs/v3.2.0-atomicity-scope-plan.md`: subdivide into
`maintenance/tracked/` (snapshot-included) +
`maintenance/append-only/` (excluded). Per-file categorisation
pass + migration helper = v3.2.0.

## Things the external audit did NOT catch

- **__init__.py version drift.** v3.1.8 shipped with
  `pyproject.toml=3.1.8` but `__init__.py` still at `3.1.7`.
  Would have surfaced in CI via `test_versions_match` but the
  release-commit CI run was cancelled by the concurrency group
  when the niah-Benchmark wiring follow-up landed right after.
  v3.1.9 closes this.

## Regression tests

- `tests/test_check_version.py::test_versions_match` — gates all
  three version sources. Currently green.
- `tests/test_validate_sh_deprecation.py` — pins deprecation
  warning + opt-out.
- `tests/test_edge_cases.py::TestMCPEdgeCases` — validates the
  top-level `mcp_server.py` shim's symbol re-export.
- `tests/test_mcp_v140.py::TestSQLiteBusyError` — validates the
  top-level shim's `patch.object` propagation (was the blocker
  that forced the exec pattern).

All 3362/3362 pytest tests pass locally on `9508035`.

## v3.2.0 scope — what v3.1.9 leaves open

1. `docs/v3.2.0-mcp-decomposition-plan.md` — 16 per-PR mcp
   decomposition PRs.
2. `docs/v3.2.0-blockstore-routing-plan.md` — BlockStore
   protocol extension + capture.py rewire + Postgres backend.
3. `docs/v3.2.0-atomicity-scope-plan.md` — maintenance/
   subdivision + migration helper.
4. Full `validate.sh` → Python forwarder collapse.

Each plan includes a per-PR breakdown with rollback points. v3.2.0
is the next feature release; v3.1.x continues hotfixes only.
