Establish codebase audit baseline

This commit is contained in:
2026-08-08 20:50:15 +00:00
parent 92e89076a2
commit 7868c26be7

174
docs/roadmap/audit.md Normal file
View File

@@ -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.
<!--
Finding template for later audit stages:
### AREA-001 — Concise title
- **Severity:** High, Medium, or Low
- **Category:** Correctness, Efficiency, Duplication, Simplicity, Test Quality,
or Documentation/Comments
- **Evidence:** Exact files, symbols, call paths, and observed behavior
- **Impact:** The concrete risk or cost
- **Recommendation:** A bounded implementation direction
- **Preserve:** Invariants and contracts that remediation must retain
- **Validation:** Focused checks that would demonstrate success
- **Grouping:** Independent, or the IDs with which this should be implemented
-->
## 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 00010005 and 00070012 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 | — | — | — |