docs(plan): documentation audit design (live-reference corpus, 4 dimensions, fill-every-gap)

This commit is contained in:
Joseph Doherty
2026-06-03 13:59:02 -04:00
parent c6d9b20d9f
commit 47acdde78d
@@ -0,0 +1,146 @@
# Documentation Audit — Design
**Date:** 2026-06-03
**Status:** Approved (brainstorming complete) → ready for writing-plans
**Branch:** `docs/documentation-audit` (off `master` @ `c6d9b20`)
## Goal
Perform an in-depth audit of the **live reference documentation** to ensure
accuracy and completeness, correcting issues in place and writing
documentation for every shipped-but-undocumented feature.
## Decisions
These were settled during brainstorming and are not open for re-litigation in
the plan:
| Dimension | Decision |
|---|---|
| **Corpus** | Live reference docs only — top-level `docs/*.md` current-reference set, `docs/drivers/*.md`, `README.md`, `CLAUDE.md` (32 files). Excludes `docs/v1`, `docs/v2`, `docs/plans`, `docs/reqs`, `docs/v3`, `looseends.md`. |
| **Output mode** | Fix in place, single pass → corrected docs + a change summary (delivered in chat, not committed). |
| **Checks** | All four dimensions: structural integrity, stale-status reconciliation, code-reality cross-check, completeness gaps. |
| **Gap handling** | Fill **every** gap — write documentation for all undocumented shipped features, small or large. |
| **Approach** | C — deterministic baseline → code-first inventory → grouped vertical passes. |
## Out of scope
- Historical tiers (`v1/`, `v2/`, `plans/`, `reqs/`, `v3/`, `looseends.md`) — they
are point-in-time records and are not edited.
- The XML doc-comment pass (handled separately by the `/fixdocs` run on branch
`chore/fixdocs-xml-doc-comments`).
- Code changes. This is a documentation effort. If the audit finds a genuine
**code** bug, it is *flagged in the summary, not fixed*.
- Secrets must never be introduced into docs: `sql_login.txt`, `pki/`, and the
dev gateway API key stay out of any committed file.
## Corpus & subsystem grouping
Phase 1 runs one full-depth pass per group (G1G4). G5 is the Phase-2
reconciliation group.
| Group | Files |
|---|---|
| **G1 — Server core & data path** | `OpcUaServer.md`, `AddressSpace.md`, `ReadWriteOperations.md`, `IncrementalSync.md`, `VirtualTags.md`, `ScriptedAlarms.md`, `AlarmTracking.md` |
| **G2 — Drivers** | `docs/drivers/`: `README.md`, `Galaxy.md`, `FOCAS.md`, + 7 `*-Test-Fixture.md` (`AbLegacy`, `AbServer`, `FOCAS`, `Modbus`, `OpcUaClient`, `S7`, `TwinCAT`) |
| **G3 — Security & operational** | `security.md`, `Redundancy.md`, `Reservations.md`, `ServiceHosting.md`, `StatusDashboard.md` |
| **G4 — Client & CLI tooling** | `Client.CLI.md`, `Client.UI.md`, `DriverClis.md`, `Driver.{Modbus,AbCip,AbLegacy,S7,TwinCAT,FOCAS}.Cli.md` |
| **G5 — Index & root (reconcile last)** | `docs/README.md`, `CLAUDE.md` |
**Already-suspected findings** (the design accounts for them; verify during the pass):
- Top-level `AlarmTracking.md` may be **orphaned** — the README index links to
`v1/AlarmTracking.md`, not the top-level file. Resolve in G1.
- `StatusDashboard.md` is a **stub pointer** (superseded by `v2/admin-ui.md`).
Resolve in G3.
- `CLAUDE.md` references both `docs/security.md` and `docs/Security.md` — a
**case mismatch** that works on macOS but breaks on the Linux docker host.
Resolve in G5.
## Phase 0 — deterministic baseline + code-first inventory
Two transient working artifacts produced **before any doc is edited**, kept
under a scratch dir and **not committed** (lesson from the fixdocs run, where
`OtOpcUa-docs-*.md` cluttered the repo root):
**(a) Structural checker.** Walks all 32 docs, extracts every markdown link and
inline source path (`src/...`, `docs/...`, `scripts/...`, `tests/...`), and
resolves each against the filesystem. Output: broken links / dead paths / case
mismatches. Deterministic and re-runnable — it is also the Phase-2 exit gate.
**(b) Feature inventory from source.** Enumerated from code, *not* docs, so
"fill every gap" has ground truth:
- **Drivers** — the driver projects under `src/Drivers/` (+ the
`Historian.Wonderware` sidecar).
- **Capabilities** — the `Core.Abstractions` interfaces (`IReadable`,
`IWritable`, `ITagDiscovery`, `ISubscribable`, `IAlarmSource`,
`IHistoryProvider`, `IHostConnectivityProbe`, `IPerCallHostResolver`).
- **Config surface** — `appsettings.json` sections + bound Options classes
(Security, Authentication.Ldap, Redundancy, MxAccess, …) and documented env
vars (`OTOPCUA_ROLES`, …).
- **CLI surface** — command verbs + flags from the `System.CommandLine`
definitions in the client + 6 driver CLIs.
- **Security profiles** — the values `SecurityProfileResolver` actually
resolves.
Diffing the inventory against the docs yields the completeness worklist (what
ships but is not documented) and grounds the code-reality cross-check.
## Phase 1 — per-group fix methodology
Each group is a vertical pass. For every doc in the group, all four dimensions
are applied in order, then the group is committed together:
1. **Structural** — apply the doc's Phase-0 link/path findings: repair broken
links, repoint moved `src/...` paths to current locations, fix case
mismatches, resolve orphans (re-link, merge, or retire), replace stub
pointers with real content or a correct pointer.
2. **Stale-status** — locate state words / banners (`blocked`, `pending`,
`not yet`, `planned`, `TODO`, `as of <date>`) and reconcile each against
current reality (source + git history + known facts: v2 feature-complete,
native alarms verified working). Rewrite to present-tense truth or delete if
obsolete.
3. **Code-reality cross-check** — verify every technical claim (namespace,
class, file, `appsettings` key, env var, CLI verb/flag, described behavior)
against the Phase-0 inventory and a direct source read. **Fixes go to the
doc to match the code, never the reverse.** A genuine code bug is flagged in
the summary, not changed.
4. **Completeness** — take this group's slice of the inventory diff and write
the missing docs: small inline additions for a missing key/flag, new
sections or whole new pages for an undocumented driver/subsystem. Every new
page is linked from its index (`README.md` / `drivers/README.md`).
**Hard scope rule:** edits land only in the 32 in-scope files. If an in-scope
doc links into an out-of-scope tier and the *target moved*, fix the **link in
the live doc** — never edit the historical artifact.
## Phase 2 — reconciliation & validation
**Cross-doc reconciliation (G5):** `docs/README.md` index integrity (every
listed doc exists and is correctly described; newly written docs are added),
"superseded by" pointers correct, and `CLAUDE.md` reconciled against reality
(the `security.md`/`Security.md` casing, retired-project notes, the docs it
names as canonical).
**Validation — the audit's "tests" are two re-runnable gates plus review:**
- **Structural gate** — re-run the Phase-0 checker → **zero** broken links /
dead paths / case mismatches.
- **Completeness gate** — re-run the inventory diff → every shipped feature is
documented, or each deliberate exclusion is listed with a reason.
- **Spot-verification** — a sample of code-reality fixes re-checked against
source with `file:line` citations in the summary.
- Each group is a reviewable commit; nothing touches code, secrets, or
out-of-scope tiers.
## Output
The change summary (in chat, not committed): fixes grouped by dimension, the
list of new docs written for completeness, and any code bugs flagged-not-fixed.
## Brainstorming task references
Native tasks created during brainstorming: #53 (explore), #54 (clarify), #55
(approaches), #56 (present design), #57 (write design doc), #58 (transition to
writing-plans).