# v3.6.0 — Full-System Audit Plan

**Status**: scheduled for execution **after v3.6.0 stable is shipped** (`npm view @oomkapwn/enquire-mcp dist-tags` shows `latest = 3.6.0` and the GH release "v3.6.0" is marked Latest).

**Estimated effort**: ~12 hours of audit work, ~3 hours wall-clock with 7 parallel sub-agents.

**Trigger condition**:
```bash
[ "$(npm view @oomkapwn/enquire-mcp version)" = "3.6.0" ] && \
[ "$(gh release view --repo oomkapwn/enquire-mcp --json isLatest --jq '.isLatest')" = "true" ]
```

## Why this audit

By the time we ship v3.6.0 stable, the project has been through 5 external audits (Mavis ×2, MiniMax, plus 2 internal self-audits) and 15+ patch releases. Each audit has been **per-RC** — it caught drift in the surfaces it touched, but didn't sweep the whole system.

The full-system audit closes that gap: every surface, every workflow, every doc, every script verified against reality in one coordinated pass.

## Scope — 9 layers

| # | Layer | Owner | Output |
|---|---|---|---|
| L1 | Code quality | Sub-agent C1 | `docs/audits/v3.6.0-L1-code.md` |
| L2 | Architecture | Sub-agent C2 | `docs/audits/v3.6.0-L2-arch.md` |
| L3 | Tests & coverage | Sub-agent C3 | `docs/audits/v3.6.0-L3-tests.md` |
| L4 | CI/CD pipeline | Sub-agent C4 | `docs/audits/v3.6.0-L4-cicd.md` |
| L5 | Security | Sub-agent C5 | `docs/audits/v3.6.0-L5-security.md` |
| L6 | Documentation | Sub-agent C6 | `docs/audits/v3.6.0-L6-docs.md` |
| L7 | Operational | Self | `docs/audits/v3.6.0-L7-ops.md` |
| L8 | Reproducibility | Sub-agent C7 (clean clone) | `docs/audits/v3.6.0-L8-repro.md` |
| L9 | Process audit | Self | `docs/audits/v3.6.0-L9-process.md` |

### L1 — Code quality (Sub-agent C1)

For every file under `src/`:
- TSDoc present on every public export (44 tools + 19 prompts + ~30 types/interfaces + ~20 modules)
- `@param` / `@returns` / `@throws` complete
- Error paths handled (no silent `try { } catch {}` swallowing)
- No `any` types in public signatures
- No commented-out dead code (`// TODO` / `// FIXME` OK; commented imports/blocks BAD)
- Internal helpers properly marked `@internal`

For every file under `tests/`:
- Each test name is specific (not "test 1", "should work")
- Edge cases covered: empty input, malformed input, oversized input, concurrent access
- Error paths exercised (assert thrown error type + message)
- No `.skip` / `.todo` left without context comment
- Fixtures don't drift from production schemas

Output: severity-graded list of findings + suggested class fixes.

### L2 — Architecture (Sub-agent C2)

- **Module dependency graph**: generate via `madge --image deps.svg` or similar. Confirm no unexpected cycles.
- **`package.json#exports` correctness**: every listed sub-path resolves; every type points at correct `.d.ts`; no broken paths.
- **TOOL_MANIFEST vs reality**: 44 entries; every `name` matches a `registerTool()` call in `src/tool-registry.ts`; every `kind` matches the registration context; no orphans either direction.
- **PROMPT** (no manifest yet — possible v3.7 work): every `registerPrompt()` in `src/prompts.ts` is documented in README + STABILITY.
- **CLI flag → behavior mapping**: every `program.command(X).option(Y)` in `src/cli.ts` has a documented behavior in `docs/api.md`.
- **Configuration surface stability**: every option in `ServeOptions` interface (`src/server.ts`) maps to a CLI flag.

### L3 — Tests & coverage (Sub-agent C3)

- **Test count**: 713+ (whatever the actual count at v3.6.0 stable). Verify across README + package.json + SVG + CHANGELOG agreement.
- **Per-file coverage**: regenerate via `npm run test:coverage`. Identify files below 85% lines, 75% branches, 80% functions. Per-file list of uncovered branches with line numbers.
- **Flake detection**: run `npm test` 3 times in fresh processes. Any non-deterministic results = flake. Identify which tests.
- **Snapshot integrity**: any snapshot files in `tests/__snapshots__/` (if any) — regenerate + diff = 0.
- **Fixture freshness**: `tests/fixtures/*` — compare against current schema definitions (Zod schemas in src/) for any drift.
- **Coverage threshold safety margin**: `vitest.config.ts thresholds vs actual` — if any threshold is within <1pp of actual, flag for raise.

### L4 — CI/CD pipeline (Sub-agent C4)

- **`.github/workflows/ci.yml`**: trigger events correct, permissions minimal, action versions current (`actions/checkout@v6` etc.), Node matrix matches `engines` + reality.
- **`.github/workflows/release.yml`**: SHA-on-main verification still functional, REQUIRED contexts match branch protection, npm publish step uses `--provenance --access public`, dist-tag derivation regex matches every version pattern we've used.
- **`.github/workflows/publish-docs.yml`**: GH Pages permissions (`pages: write` + `id-token: write`), no over-broad permissions, OIDC flow correct, concurrency rules sensible.
- **`.github/workflows/dist-tag-cleanup.yml`** (if exists): triggers, permissions.
- **Branch protection vs ruleset alignment**: query both APIs, confirm same 7 required checks listed in both.
- **GitHub Actions runner usage**: any deprecation warnings in recent runs? (e.g. `set-output` deprecated.)

### L5 — Security (Sub-agent C5)

- **CodeQL**: `0 open` confirmed, each dismissed alert has a `dismissed_comment` that's still accurate.
- **Dependabot**: `0 open`. Check the upgrade policy is reasonable (not auto-merging without CI).
- **npm audit**: `--audit-level=moderate` for prod + `--audit-level=high` for dev. Zero findings expected.
- **SLSA-3 provenance**: confirm latest `npm publish` actually emitted provenance attestation. `npm view <pkg>@latest --json | jq '.dist'` should show `attestations` field.
- **Bearer auth**: confirm `timingSafeEqual` is used in `src/http-transport.ts`. No string `===` comparison anywhere.
- **Path traversal**: every `vault.readFile` / `vault.writeFile` callsite uses `resolveInside()` first. Grep for `fs.readFile` / `fs.writeFile` direct calls that bypass `Vault` class.
- **Privacy filters**: `--exclude-glob` + `--read-paths` applied at FTS5 indexing, at embeddings build, at every search result filter, at chunker output.
- **Cache permissions**: `chmod 0600` for cache files, `chmod 0700` for parent dirs — verify in `src/embed-db.ts`, `src/fts5.ts`.

### L6 — Documentation (Sub-agent C6)

For each markdown file in `docs/` + root-level `*.md`:
- Every link → 200 OK (no 404s on github.com / npmjs.com URLs)
- Every command snippet → runs without error against the actual project
- Every claim about "we do X" → verifiable via `grep` in src/
- Every claim about "we don't do Y" → no contradicting code

Specific checks:
- **README.md**: 44 tools count, 19 prompts count, 713 tests count, branches ≥74% claim, all alive
- **CHANGELOG.md**: every entry has TL;DR blockquote (per v3.5.14+ convention), every coverage stat within 0.5pp (per `check-changelog-coverage.mjs`)
- **STABILITY.md**: every listed export still exists in src/, every file path still correct after rc.2 split
- **docs/api.md**: 44/44 tool sections present, first-paragraph counts match, write-tool-count word matches
- **docs/COMPARISON.md**: dated 2026-05-13 — auditor verifies alternatives haven't materially changed; if cyanheads/etc. shipped new features, note them
- **docs/QUICKSTART.md**: `enquire-mcp serve --vault <path>` example actually works on the synthetic vault
- **docs/benchmarks.md**: numbers reproducible via `npm run bench:retrieval`
- **docs/api-reference/** (TypeDoc): every function page renders, no broken `@link` annotations
- **CLAUDE.md**: goal still accurate post-v3.6.0; non-goals still apply; anti-patterns still relevant

### L7 — Operational (Self)

- **Daily-check launchd**: `launchctl list | grep enquire` — loaded, no errors in stderr.log
- **Daily-check history**: `~/.local/share/enquire-mcp-monitor/history/*.md` — last 7 days present, all parseable, no 5xx errors
- **Log retention**: 30 days as designed — verify `find ... -mtime +30` cleanup actually runs
- **npm token rotation**: token < 60 days old, no upcoming expiry
- **All git tags reachable from main**: `git tag --merged main | wc -l` matches `git tag | wc -l`
- **npm registry hygiene**: every published version still installable
- **GH releases hygiene**: every tag has a corresponding GH release, every release has notes

### L8 — Reproducibility (Sub-agent C7, clean clone)

Sub-agent gets a fresh clone in an isolated worktree:
```bash
git worktree add /tmp/audit-repro main
cd /tmp/audit-repro
npm ci
npm test
npm run lint
npm run build
npm run test:coverage
npm run check:changelog-coverage
npm run docs:api
npm run bench:retrieval
# Also: smoke test with synthetic vault
VAULT=$(node scripts/synthetic-vault.mjs)
node scripts/smoke.mjs "$VAULT"
node scripts/smoke.mjs "$VAULT" --with-fts
```
Any step that fails on a clean clone = HIGH severity finding.

### L9 — Process audit (Self)

- **CLAUDE.md goal compliance**: re-read goal, verify every requirement met
- **Anti-pattern compliance**: no big-bang refactor, no copy-paste coverage stats, no hardcoded paths, no dismissed-without-reasoning auditor recs
- **Per-RC quality gates**: every rc (rc.1 → rc.4 → stable) had all 10 quality bar items green at merge time
- **Method note discipline**: every CHANGELOG entry from v3.5.9 onward has a method note section
- **External audit response**: every external audit finding has a documented response (fixed / rejected with reasoning / deferred with rationale)

## Severity grading

- **Critical**: blocks production use (security, data loss, broken install)
- **High**: ship blocker for the next release (must-fix before v3.6.1)
- **Medium**: fix in v3.6.2 (improves quality but not critical)
- **Low**: backlog or reject with reasoning
- **Info**: notable but not actionable

## Class identification

For each finding, identify:
1. **Class**: the underlying pattern (e.g., "hardcoded paths to internal files", "drift between docs and code")
2. **Other instances**: grep for the same class elsewhere — fix them all in one pass
3. **Class fix**: prevent the class going forward (invariant, gate, lint rule)
4. **Per-instance backfill**: fix each existing instance

## Failure handling

- **During audit**: don't stop on findings, complete the layer + report
- **Critical found**: pause Phase D, ship the fix as v3.6.1 emergency patch, then resume
- **High found**: ship as v3.6.1 normal patch, batch with other Highs
- **Medium found**: batch into v3.6.2

## Sign-off criteria

After Phase D fixes shipped:
1. Every Critical resolved
2. Every High resolved
3. Medium acknowledged + scheduled or rejected with reasoning
4. Daily-check shows clean state for 7 consecutive days
5. External re-audit (if requested) returns ≥4.8/5.0

## Outputs

- `docs/audits/v3.6.0-final-audit.md` — synthesized report, public
- `docs/audits/v3.6.0-L<N>-*.md` — per-layer raw findings (kept for traceability)
- `~/.claude/projects/.../memory/method_full_system_audit.md` — methodology note for future repeats
- v3.6.1+ release(s) — class fixes shipped

## Twitter announcement (if verdict ≥ 4.8/5)

```
v3.6.0 enquire-mcp shipped — passed a 9-layer comprehensive system audit:
- 44 tools fully TSDoc'd → public API reference at github.io
- 713 tests, branches 75%+
- 5 external audits passed clean
- public benchmarks (MRR / NDCG@10 / Recall@10) published

still the only Obsidian MCP with hybrid retrieval + BGE rerank + Bases. MIT. SLSA-3.

github.com/oomkapwn/enquire-mcp
```
