diff --git a/docs/roadmap/audit.md b/docs/roadmap/audit.md new file mode 100644 index 0000000..49b5149 --- /dev/null +++ b/docs/roadmap/audit.md @@ -0,0 +1,174 @@ +# Codebase Audit + +## Audit Metadata + +- **Production target:** `92e89076a268089e703978fb9d7176200e93344c` +- **Branch at target:** `main` +- **Audit date:** 2026-08-08 +- **Go version:** `go1.26.5 linux/amd64` +- **PromptKit version:** `gitea.maximumdirect.net/eric/promptkit v0.5.0` +- **Knowledge-graph project:** `notarius-audit-92e8907` +- **Knowledge-graph target:** branch `main`, head + `92e89076a268089e703978fb9d7176200e93344c` +- **Initial worktree:** Clean. There were no pre-existing production or roadmap + changes to record. + +The commit above is the production snapshot under audit. Later commits that +change only roadmap audit documents do not change that production target. + +## Executive Summary + +Pending final synthesis. The initial baseline is healthy, and the architecture +and dependency-boundary review found one Low documentation finding and no +production dependency inversion. + +## Finding Index + +Final cross-area ordering is pending synthesis. + +| ID | Severity | Category | Title | +| --- | --- | --- | --- | +| ARCH-001 | Low | Documentation/Comments | Repair broken ADR cross-references | + +## Findings + +### Architecture And Dependency Boundaries + +### ARCH-001 — Repair broken ADR cross-references + +- **Severity:** Low +- **Category:** Documentation/Comments +- **Evidence:** + `docs/adr/0012-resolve-opaque-entity-identifiers-deterministically.md:15` + links ADR-0003 as `0003-strongly-typed-stage-interfaces.md`, and line 17 + links ADR-0009 as + `0009-prefer-minimal-evidence-grounded-extraction-artifacts.md`. Neither file + exists. The maintained files are + `0003-typed-interfaces-with-two-zone-data-model.md` and + `0009-minimal-evidence-grounded-extraction-artifacts.md`. +- **Impact:** Readers and documentation tooling cannot follow ADR-0012 to the + two architectural decisions it explicitly relies on. Runtime behavior is + unaffected. +- **Recommendation:** Correct only the two relative link targets in ADR-0012. +- **Preserve:** Keep the accepted decision text and its intended references to + ADR-0003 and ADR-0009 unchanged. +- **Validation:** Run a relative Markdown-link check across `docs/adr/` and + confirm both targets resolve; verify the change contains no decision-text + edits. +- **Grouping:** Independent. + + + +## Intentional Complexity And Duplication To Preserve + +- `internal/modules/generic/register.Register`, + `internal/modules/seriatim/register.Register`, and + `internal/modules/dnd/register.Register` deliberately expose the same small + registrar shape while retaining family-local registration policy and + diagnostics. Combining them would move extension ownership out of the domain + registrars and weaken the composition boundary established by ADR-0004. +- `internal/modules/dnd/register.registerModules`, `registerEvidence`, + `registerValidators`, and `registerDefaultChains` use explicit typed + registration lists. At this architectural pass, that repetition preserves + artifact Go types, module-specific validator order, and registrar-owned + production policy. Later D&D stages may evaluate individual shared + mechanics, but should not replace these lists with a dynamically typed + registration engine. +- `internal/framework/pipeline.RegisterArtifactCodec` and + `exactTypedValue` perform apparently repetitive exact-type checks around + private erasure. The checks deliberately turn incompatible values into + errors at each erased boundary rather than permitting a panic or accepting a + near-matching type, preserving ADR-0003. + +## Areas Reviewed Without Findings + +### Architecture And Dependency Boundaries + +- **Composition root:** `internal/cli.newProductionComponents` constructs the + complete registry set and asset registry, then invokes only the generic, + Seriatim, and D&D family registrars. Direct production imports confirm that + `internal/cli` is the only layer importing those registrar packages. +- **Dependency direction:** A direct production import map found no core or + framework package importing `internal/modules`, no module importing + `internal/cli`, no concrete generic or Seriatim module importing D&D, and no + module importing the file-backed checkpoint, chunk-plan, debug, file-I/O, or + debug-bundle implementations. PromptKit is imported directly only by + `internal/framework/llm`. +- **Graph cross-layer calls:** The refreshed graph reported one + framework-to-module edge from `pipeline.Prepare` to a symbol named `request` + in a D&D validator test. Tracing it showed a confidence `0.06` suffix match + from the local closure call in `Prepare`; `trace_path` classified the target + as test-only, and the production import map disproved a dependency. The graph + reported no module-to-CLI calls. +- **Assets leaf:** `assets/package.go` imports only `embed` and `io/fs`, embeds + content, and exposes the read-only `FS() fs.FS` accessor. It contains no + business logic and has no `internal` or PromptKit dependency. +- **Fixed pipeline shape:** `pipeline.ResolvePipeline` resolves input and + chunk once, fixed extract/merge/normalize bindings per artifact lane, and one + output binding. Ordered steps are barriers around those fixed lanes rather + than arbitrary graph topology. `pipeline.Prepare`, `Runner.Run`, + `runPreparedSteps`, and `runLanes` retain that shape through construction and + execution. +- **Typed artifact boundary:** Typed registrations retain the exact Go type for + codecs and lane operations. Private erasure in `RegisterArtifactCodec` and + `exactTypedValue` verifies exact types and returns contextual errors; + normalized values cross into output through serialized artifacts. +- **Physical-state ownership:** The CLI owns root selection, store factories, + and durable file placement (`chunkPlanStoreForRun`, checkpoint/debug setup, + and `writeOutputFiles`). The framework receives collaborator interfaces and + returns logical output files. The generic JSON output module's direct import + of `internal/framework/chunkmap` validates and republishes the accepted + serialized chunk-map contract; it neither chooses a physical root nor writes + files. +- **Accepted architectural decisions:** ADRs 0001–0005 and 0007–0012 were read + against the current high-level composition. Apart from ARCH-001, the + composition root, fixed ordered pipeline, typed boundary, domain packaging, + canonical chunk-plan policy, separate state surfaces, checkpoint policy, + evidence rules, workload profile ownership, centralized asset leaf, and + deterministic entity identity boundary have corresponding current owners. + +## Validation Record + +| Date | Scope | Command or check | Result | +| --- | --- | --- | --- | +| 2026-08-08 | Initial worktree | `git status --short` | Pass; no output | +| 2026-08-08 | Knowledge graph | Full index as `notarius-audit-92e8907` | Pass; 8,322 nodes and 47,887 edges; branch/head matched the production target | +| 2026-08-08 | Baseline tests | `go test ./...` | Pass | +| 2026-08-08 | Baseline static analysis | `go vet ./...` | Pass | +| 2026-08-08 | Baseline build | `go build ./cmd/notarius` | Pass | +| 2026-08-08 | Baseline whitespace | `git diff --check` | Pass | +| 2026-08-08 | Production imports | Direct `go list` import-edge audit plus graph call tracing | Pass; no production dependency inversion found | +| 2026-08-08 | Accepted ADR links | Relative Markdown-link target scan under `docs/adr/` | Two unresolved targets recorded as ARCH-001 | + +## Coverage Matrix + +| Audit area | Status | Packages and documents inspected | Validation run | Finding IDs | +| --- | --- | --- | --- | --- | +| Architecture and dependency boundaries | Reviewed | Architecture, documentation, and testing policies; internal overview; accepted ADRs; `internal/cli/catalog.go`; production registrars; root `assets` package; representative pipeline, typed-codec, output, and state-owner symbols | Full baseline, fresh graph, direct import map, cross-layer call traces, ADR link scan | ARCH-001 | +| Configuration and CLI composition | Pending | — | — | — | +| Pipeline resolution, preparation, and typed registries | Pending | — | — | — | +| References and ordered handoffs | Pending | — | — | — | +| Execution, validation, retry, and concurrency | Pending | — | — | — | +| State, checkpoints, debugging, and file safety | Pending | — | — | — | +| LLM runtime, prompt filesystems, and assets | Pending | — | — | — | +| Generic and Seriatim modules | Pending | — | — | — | +| Shared D&D types, codecs, and family mechanics | Pending | — | — | — | +| NPC, item, and location registries | Pending | — | — | — | +| NPC, item, and location occurrences | Pending | — | — | — | +| Spells, scene chunking, and scene descriptions | Pending | — | — | — | +| Combat turns and enemy events | Pending | — | — | — | +| Test ownership, comments, and final synthesis | Pending | — | — | — |