# 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 (G1–G4). 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 `) 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).