docs(plans): implementation plan for per-component reference docs

28-task plan: scaffold, AuditLog pilot (approval gate), 24-doc parallel
fan-out, index+README, verification pass. Co-located .tasks.json for resume.
This commit is contained in:
Joseph Doherty
2026-06-03 15:24:05 -04:00
parent e89cf2b278
commit 5e106df9e6
2 changed files with 346 additions and 0 deletions
@@ -0,0 +1,312 @@
# Component Reference Documentation Implementation Plan
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers-extended-cc:executing-plans to implement this plan task-by-task.
**Goal:** Generate 25 StyleGuide-conformant developer-reference docs in `docs/components/` (one per component), derived from the actual `src/` code, accurate and complete.
**Architecture:** Pilot exemplar (`AuditLog.md`) sets the template and voice; once approved it is the literal pattern for a parallel fan-out (one subagent per remaining component, each reading its real source + spec); a verification pass then confirms code-accuracy, StyleGuide conformance, and resolving links before an index + README link are added.
**Tech Stack:** Markdown docs; source is C#/.NET (Akka.NET) under `src/`; `StyleGuide.md` defines the writing rules; the design is in `docs/plans/2026-06-03-component-reference-docs-design.md`.
**The "test" for a doc:** unlike code TDD, the pass/fail gate is the **verification checklist** (Task 27): every referenced type/method/file/config-key exists in `src/`; StyleGuide rules hold; required sections present; relative links resolve. Treat that checklist as the acceptance test each doc must pass.
---
## Reference: the StyleGuide checklist (every doc must satisfy)
Every generated doc is written to these rules (condensed from `StyleGuide.md`). This block is handed verbatim to each fan-out subagent.
- **Tone:** technical, direct, present tense ("The actor validates…", not "will validate"). Explain *why*, not only *what*. No marketing words (`powerful`, `robust`, `seamless`, `blazing`, `cutting-edge`, `efficient`, etc.).
- **Real code only:** every `csharp`/`razor`/`yaml`/`json` snippet must be copied or directly derived from actual source in the component. **Never invent** types, methods, or config keys. Snippets are 525 lines with enough class/method context to locate them.
- **Names match code exactly:** `ScadaGatewayActor`, `IRequiredActor<T>`, `appsettings.json`, `ScadaBridge:Timeout` — in backticks, exact casing.
- **Headings:** `#` = Title Case document title; `##` = Title Case sections; `###` = Sentence case.
- **Code blocks:** always language-tagged (`csharp`, `json`, `bash`, `xml`, `sql`, `yaml`, `html`, `css`, `javascript`, `razor`).
- **Links:** relative paths, descriptive link text (no "click here"). Spec link target is `../requirements/Component-<Name>.md`.
- **No temporary info:** no dates, version numbers, or "coming soon".
- **Don't document the obvious** or duplicate XML doc comments; reference the file instead.
- **Required sections (minimum):** Overview, Dependencies & Interactions, Related Documentation. Others (Key Concepts, Architecture, Usage, Configuration, Troubleshooting) included only when the component warrants them.
## Reference: per-doc section template
```
# <Title Case Name>
<12 sentence purpose>
## Overview (always)
## Key Concepts (if the component has domain terms a dev must know)
## Architecture (main types, data/message flow, real code snippets)
## Usage (primary entry points / how it is invoked, real code)
## Configuration (appsettings/options as a table; real keys only)
## Dependencies & Interactions (always; cross-linked to other component docs)
## Troubleshooting (failure modes / health signals, where applicable)
## Related Documentation (always; spec link + related docs)
```
## Reference: component → source map
| Component (doc) | Source to read |
|---|---|
| `AuditLog.md` | `src/ZB.MOM.WW.ScadaBridge.AuditLog/` |
| `CentralUI.md` | `src/ZB.MOM.WW.ScadaBridge.CentralUI/` (exclude the TreeView component) |
| `CLI.md` | `src/ZB.MOM.WW.ScadaBridge.CLI/` |
| `ClusterInfrastructure.md` | `src/ZB.MOM.WW.ScadaBridge.ClusterInfrastructure/` |
| `Commons.md` | `src/ZB.MOM.WW.ScadaBridge.Commons/` |
| `Communication.md` | `src/ZB.MOM.WW.ScadaBridge.Communication/` |
| `ConfigurationDatabase.md` | `src/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase/` |
| `DataConnectionLayer.md` | `src/ZB.MOM.WW.ScadaBridge.DataConnectionLayer/` |
| `DeploymentManager.md` | `src/ZB.MOM.WW.ScadaBridge.DeploymentManager/` |
| `ExternalSystemGateway.md` | `src/ZB.MOM.WW.ScadaBridge.ExternalSystemGateway/` |
| `HealthMonitoring.md` | `src/ZB.MOM.WW.ScadaBridge.HealthMonitoring/` |
| `Host.md` | `src/ZB.MOM.WW.ScadaBridge.Host/` |
| `InboundAPI.md` | `src/ZB.MOM.WW.ScadaBridge.InboundAPI/` |
| `ManagementService.md` | `src/ZB.MOM.WW.ScadaBridge.ManagementService/` |
| `NotificationOutbox.md` | `src/ZB.MOM.WW.ScadaBridge.NotificationOutbox/` |
| `NotificationService.md` | `src/ZB.MOM.WW.ScadaBridge.NotificationService/` |
| `Security.md` | `src/ZB.MOM.WW.ScadaBridge.Security/` |
| `SiteCallAudit.md` | `src/ZB.MOM.WW.ScadaBridge.SiteCallAudit/` |
| `SiteEventLogging.md` | `src/ZB.MOM.WW.ScadaBridge.SiteEventLogging/` |
| `SiteRuntime.md` | `src/ZB.MOM.WW.ScadaBridge.SiteRuntime/` |
| `StoreAndForward.md` | `src/ZB.MOM.WW.ScadaBridge.StoreAndForward/` |
| `TemplateEngine.md` | `src/ZB.MOM.WW.ScadaBridge.TemplateEngine/` |
| `Transport.md` | `src/ZB.MOM.WW.ScadaBridge.Transport/` |
| `TraefikProxy.md` | `docker/traefik/traefik.yml` + Host `/health/active` in `src/ZB.MOM.WW.ScadaBridge.Host/Program.cs` (examples in `yaml`/`bash`/`json`) |
| `TreeView.md` | `src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Shared/TreeView.razor`, `TreeView.razor.css`, `TreeViewSelectionMode.cs` (examples in `razor`/`csharp`/`css`) |
Each doc also reads its existing spec `docs/requirements/Component-<Name>.md` for domain cross-check. **Where code and spec disagree, the code wins.**
---
## Task 0: Scaffold + shared assets
**Classification:** small
**Estimated implement time:** ~3 min
**Parallelizable with:** none (prerequisite for all)
**Files:**
- Create: `docs/components/` (folder)
- Create: `tools/check-doc-links.sh`
**Step 1: Create the docs folder**
```bash
mkdir -p docs/components
```
**Step 2: Write a relative-link checker**
`tools/check-doc-links.sh` — verifies every relative markdown link in `docs/components/*.md` resolves to a real file (used by Task 27).
```bash
#!/usr/bin/env bash
# Check that all relative markdown links under docs/components resolve.
set -uo pipefail
cd "$(dirname "$0")/.."
fail=0
for f in docs/components/*.md; do
[ -e "$f" ] || continue
# extract ](target) links, ignore http(s):, anchors, and mailto
grep -oE '\]\([^)]+\)' "$f" | sed -E 's/^\]\(//; s/\)$//' | while read -r link; do
case "$link" in
http://*|https://*|mailto:*|\#*) continue ;;
esac
target="${link%%#*}" # strip #anchor
[ -z "$target" ] && continue
resolved="$(cd "$(dirname "$f")" && cd "$(dirname "$target")" 2>/dev/null && pwd)/$(basename "$target")"
if [ ! -e "$resolved" ]; then
echo "BROKEN: $f -> $link"
fi
done
done
echo "link check done"
```
**Step 3: Make it executable and run on the (empty) folder**
Run: `chmod +x tools/check-doc-links.sh && bash tools/check-doc-links.sh`
Expected: `link check done` with no `BROKEN:` lines.
**Step 4: Commit**
```bash
git add docs/components tools/check-doc-links.sh
git commit -m "docs(components): scaffold reference-docs folder + link checker"
```
---
## Task 1: Pilot exemplar — `AuditLog.md` ⛔ approval gate
**Classification:** standard
**Estimated implement time:** ~6 min
**Parallelizable with:** none (blocks all fan-out tasks)
**Files:**
- Create: `docs/components/AuditLog.md`
**Read for context (do not edit):**
- `src/ZB.MOM.WW.ScadaBridge.AuditLog/` (all `.cs`)
- `docs/requirements/Component-AuditLog.md`
- `StyleGuide.md`
**Step 1: Read the source and spec**
Read every `.cs` under `src/ZB.MOM.WW.ScadaBridge.AuditLog/` and the spec. Note the real type names (`AuditLogIngestActor`, `SiteAuditTelemetryActor`, `SiteAuditReconciliationActor`, `AuditLogPurgeActor`, the `AuditLog` entity/table, options classes) and config keys.
**Step 2: Write `docs/components/AuditLog.md`**
Follow the section template and the StyleGuide checklist above. Every `csharp` snippet must be real code from the project. Include: Overview (central+site role, the "why"); Key Concepts (script trust boundary, `ExecutionId` vs `CorrelationId`); Architecture (the singleton actors + ingest paths + the table, with real snippets); Usage (how rows are written on the hot path + central direct-write); Configuration (payload caps, retention, redaction — real keys as a table); Dependencies & Interactions (Site Call Audit, Notification Outbox, ConfigurationDatabase, Communication — cross-linked); Troubleshooting (telemetry loss → reconciliation, audit-write-never-aborts-action); Related Documentation (`../requirements/Component-AuditLog.md` + related component docs).
**Step 3: Self-check against the checklist**
Re-read the doc against the StyleGuide checklist. Confirm: no invented APIs, present tense, language-tagged blocks, no marketing words, no dates/versions, relative spec link present.
**Step 4: STOP — request user approval of the exemplar**
This doc is the template for all 24 fan-out tasks. Present it to the user and get explicit approval (adjust voice/depth/sections per feedback) **before** any fan-out task runs. Do not proceed past this gate automatically.
**Step 5: Commit**
```bash
git add docs/components/AuditLog.md
git commit -m "docs(components): AuditLog reference doc (pilot exemplar)"
```
---
## Tasks 225: Fan-out — one reference doc per remaining component
**These 24 tasks are identical in shape; they differ only by component.** Each is dispatched as its own subagent. **All 24 are mutually parallelizable** (each writes a distinct file) and **all depend on Task 1** (they use the approved `AuditLog.md` as the literal template). The executor caps concurrency at ~56.
**Canonical task contract (applies to every Task 225):**
**Classification:** standard
**Estimated implement time:** ~5 min
**Parallelizable with:** every other fan-out task (Tasks 225)
**Files:**
- Create: `docs/components/<Name>.md`
**Read for context (do not edit):**
- The component's source (see the component → source map above)
- `docs/requirements/Component-<Name>.md`
- `docs/components/AuditLog.md` (the approved template)
- `StyleGuide.md`
**Steps:**
1. Read the component's real source (all relevant `.cs`/`.razor`/config) and its spec. Inventory the real type names, entry points, and config keys.
2. Write `docs/components/<Name>.md` mirroring the structure, voice, and depth of the approved `AuditLog.md`, following the section template and the StyleGuide checklist. Include only sections the component warrants (always Overview, Dependencies & Interactions, Related Documentation).
3. Every code snippet must be real code from this component — no invented APIs. Cross-link dependencies to sibling `docs/components/*.md` and the spec to `../requirements/Component-<Name>.md`.
4. Return the list of source files the doc drew from.
5. Commit: `git add docs/components/<Name>.md && git commit -m "docs(components): <Name> reference doc"`.
**Per-task instances:**
| Task | Doc | Notes |
|---|---|---|
| 2 | `Commons.md` | Shared POCO entities, interfaces, message contracts; Types/Interfaces/Entities/Messages layout |
| 3 | `ConfigurationDatabase.md` | EF Core repos, unit-of-work, `IAuditService`, migrations |
| 4 | `Communication.md` | ClusterClient command/control + gRPC streaming; Central/Site comm actors |
| 5 | `ClusterInfrastructure.md` | Akka cluster setup, active/standby, SBR, singletons |
| 6 | `Host.md` | Single binary, role-based component registration, Akka bootstrap, `/health/ready` |
| 7 | `Security.md` | LDAP bind, cookie+JWT sessions, role/site-scoped authz |
| 8 | `TemplateEngine.md` | Modeling, inheritance, composition, validation, flattening, diffs (large — read broadly) |
| 9 | `DeploymentManager.md` | Central deploy pipeline, instance lifecycle |
| 10 | `SiteRuntime.md` | Site actor hierarchy, script compilation, alarms, site stream (large) |
| 11 | `DataConnectionLayer.md` | Protocol abstraction, Become/Stash state machine, native alarm seam |
| 12 | `StoreAndForward.md` | Buffering, retry, parking, SQLite, replication |
| 13 | `ExternalSystemGateway.md` | HTTP/REST, Call/CachedCall, error classification |
| 14 | `NotificationService.md` | SMTP/OAuth2 delivery adapters, central-only delivery |
| 15 | `NotificationOutbox.md` | Central S&F singleton, `Notifications` table, dispatcher, KPIs |
| 16 | `SiteCallAudit.md` | `SiteCalls` table, telemetry, reconciliation, Retry/Discard relay |
| 17 | `HealthMonitoring.md` | Site metrics collection + central reporting |
| 18 | `SiteEventLogging.md` | Local event logs, retention/cap, central query |
| 19 | `InboundAPI.md` | `POST /api/{method}`, API-key auth, extended type system |
| 20 | `ManagementService.md` | Management actor, receptionist registration, admin ops |
| 21 | `CLI.md` | System.CommandLine tool over HTTP management API |
| 22 | `Transport.md` | Encrypted bundle export/import, conflict resolution, `BundleImportId` |
| 23 | `CentralUI.md` | Blazor Server, custom components, nav, real-time push (exclude TreeView) |
| 24 | `TraefikProxy.md` | From `docker/traefik/traefik.yml` + Host `/health/active`; `yaml`/`bash`/`json` examples |
| 25 | `TreeView.md` | From CentralUI `TreeView.razor`/`.css`/`TreeViewSelectionMode.cs`; `razor`/`csharp`/`css` |
---
## Task 26: Index + README link
**Classification:** small
**Estimated implement time:** ~4 min
**Parallelizable with:** none (needs all docs present)
**Files:**
- Create: `docs/components/README.md`
- Modify: `README.md` (add a link to the new reference set)
**Step 1: Write `docs/components/README.md`**
An index: H1 + 12 sentence purpose, then a table of all 25 docs with a one-line description each (mirror the README component table ordering / CLAUDE.md component list). Relative links to each `*.md`.
**Step 2: Link from the root README**
Add a short subsection under the Repository Layout / docs description pointing to `docs/components/` as the developer reference set (distinct from the `docs/requirements/` specs).
**Step 3: Commit**
```bash
git add docs/components/README.md README.md
git commit -m "docs(components): index + link from README"
```
---
## Task 27: Verification & fix pass
**Classification:** standard
**Estimated implement time:** ~6 min (fans out one reviewer per doc; fixes are small follow-ups)
**Files:**
- Modify: any `docs/components/*.md` flagged by review
**Step 1: Link check (scripted)**
Run: `bash tools/check-doc-links.sh`
Expected: no `BROKEN:` lines. Fix any broken relative links.
**Step 2: StyleGuide lint (scripted spot-checks)**
```bash
# banned marketing words
grep -rniE 'powerful|robust|seamless|blazing|cutting-edge|world-class' docs/components/ || echo "no marketing words"
# untagged code fences (a bare ``` opening a block)
grep -rnE '^```$' docs/components/ || echo "all fences tagged"
# stray dates / version numbers
grep -rnE '\b20[0-9]{2}-[0-9]{2}-[0-9]{2}\b|\bv[0-9]+\.[0-9]+' docs/components/ || echo "no dates/versions"
```
Fix anything these surface (note: a closing fence also matches `^```$`; verify each hit is genuinely an untagged opener).
**Step 3: Accuracy review (agent fan-out, one per doc)**
Dispatch a reviewer subagent per doc: given `docs/components/<Name>.md` + the component's source, verify **every** referenced type, method, file, and config key actually exists in `src/` (no invented APIs), and that described behavior matches the code. Each reviewer returns a list of inaccuracies (or "clean").
**Step 4: Apply fixes**
Correct every inaccuracy flagged in Step 3. Re-run Steps 12 after edits.
**Step 5: Final acceptance check**
Confirm: 25 docs present in `docs/components/` + index; each has Overview, Dependencies & Interactions, Related Documentation; link check clean; no flagged inaccuracies remain.
**Step 6: Commit**
```bash
git add docs/components
git commit -m "docs(components): verification pass — fix accuracy/conformance/links"
```
---
## Notes
- **Do not push.** The user runs `/pushit` as a separate, explicit step after reviewing the full set.
- **Untracked siblings** (`StyleGuide.md`, `ScadaBridge-docs-*.md`) are out of scope for these commits; stage only the files each task names.
- The pilot approval gate (Task 1, Step 4) is mandatory — fan-out must not begin until the exemplar is approved.
@@ -0,0 +1,34 @@
{
"planPath": "docs/plans/2026-06-03-component-reference-docs.md",
"tasks": [
{"id": 19, "subject": "Task 0: Scaffold + shared assets", "status": "pending"},
{"id": 20, "subject": "Task 1: Pilot exemplar AuditLog.md (approval gate)", "status": "pending", "blockedBy": [19]},
{"id": 21, "subject": "Task 2: Commons.md reference doc", "status": "pending", "blockedBy": [20]},
{"id": 22, "subject": "Task 3: ConfigurationDatabase.md reference doc", "status": "pending", "blockedBy": [20]},
{"id": 23, "subject": "Task 4: Communication.md reference doc", "status": "pending", "blockedBy": [20]},
{"id": 24, "subject": "Task 5: ClusterInfrastructure.md reference doc", "status": "pending", "blockedBy": [20]},
{"id": 25, "subject": "Task 6: Host.md reference doc", "status": "pending", "blockedBy": [20]},
{"id": 26, "subject": "Task 7: Security.md reference doc", "status": "pending", "blockedBy": [20]},
{"id": 27, "subject": "Task 8: TemplateEngine.md reference doc", "status": "pending", "blockedBy": [20]},
{"id": 28, "subject": "Task 9: DeploymentManager.md reference doc", "status": "pending", "blockedBy": [20]},
{"id": 29, "subject": "Task 10: SiteRuntime.md reference doc", "status": "pending", "blockedBy": [20]},
{"id": 30, "subject": "Task 11: DataConnectionLayer.md reference doc", "status": "pending", "blockedBy": [20]},
{"id": 31, "subject": "Task 12: StoreAndForward.md reference doc", "status": "pending", "blockedBy": [20]},
{"id": 32, "subject": "Task 13: ExternalSystemGateway.md reference doc", "status": "pending", "blockedBy": [20]},
{"id": 33, "subject": "Task 14: NotificationService.md reference doc", "status": "pending", "blockedBy": [20]},
{"id": 34, "subject": "Task 15: NotificationOutbox.md reference doc", "status": "pending", "blockedBy": [20]},
{"id": 35, "subject": "Task 16: SiteCallAudit.md reference doc", "status": "pending", "blockedBy": [20]},
{"id": 36, "subject": "Task 17: HealthMonitoring.md reference doc", "status": "pending", "blockedBy": [20]},
{"id": 37, "subject": "Task 18: SiteEventLogging.md reference doc", "status": "pending", "blockedBy": [20]},
{"id": 38, "subject": "Task 19: InboundAPI.md reference doc", "status": "pending", "blockedBy": [20]},
{"id": 39, "subject": "Task 20: ManagementService.md reference doc", "status": "pending", "blockedBy": [20]},
{"id": 40, "subject": "Task 21: CLI.md reference doc", "status": "pending", "blockedBy": [20]},
{"id": 41, "subject": "Task 22: Transport.md reference doc", "status": "pending", "blockedBy": [20]},
{"id": 42, "subject": "Task 23: CentralUI.md reference doc", "status": "pending", "blockedBy": [20]},
{"id": 43, "subject": "Task 24: TraefikProxy.md reference doc", "status": "pending", "blockedBy": [20]},
{"id": 44, "subject": "Task 25: TreeView.md reference doc", "status": "pending", "blockedBy": [20]},
{"id": 45, "subject": "Task 26: Index + README link", "status": "pending", "blockedBy": [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44]},
{"id": 46, "subject": "Task 27: Verification & fix pass", "status": "pending", "blockedBy": [45]}
],
"lastUpdated": "2026-06-03"
}