Files
narratio/docs/roadmap/cleanup.md

207 lines
9.8 KiB
Markdown

# Roadmap: Pre-1.0 Code Cleanup
Status: Implemented
This roadmap turns the remaining findings in `docs/roadmap/audit.md` into decision-complete implementation stages. It follows the policy documents under `docs/policy/` and preserves current public CLI, config, storage layout, manifest, and stage behavior unless a stage explicitly says otherwise.
## Goals
- Reduce repeated path, file, source-policy, and read-only inspection logic before 1.0.
- Keep Narratio explicit, stage-driven, and easy to review.
- Keep storage adapters free of campaign/session/run/root-prefix semantics.
- Keep command output text-only and command-specific.
- Keep implementation changes small enough for focused prompts and focused tests.
## Non-Goals
- Do not introduce a generic workflow engine or DAG abstraction.
- Do not introduce a generic CLI framework.
- Do not introduce a broad manifest abstraction.
- Do not move secret loading into storage adapters.
- Do not make storage adapters infer Narratio path or key semantics.
- Do not add compatibility aliases for retired archive/promote, campaign, transcript, or previous-session source names.
- Do not move restore's remote-key include/exclude policy out of restore unless another caller is added.
## Stage 1: Path and File Mechanics (Implemented)
Add shared mechanics for root-scoped path safety and atomic file operations.
Implementation decisions:
- Add root-scoped helpers in `internal/pathsafe`:
- join a slash-style relative path safely under a root;
- derive a safe slash-style relative path from a path under a root;
- reject empty paths, absolute paths, traversal, and paths outside the root.
- Add a small dependency-light `internal/fileops` package for shared file installation mechanics:
- atomic byte write;
- atomic file copy;
- atomic file copy with SHA-256 checksum;
- install an already-downloaded temp file with permissions.
- Prefer `internal/fileops` over extending `artifacts.LocalStore`, because the same mechanics are used by app, stage, audio, artifacts, and manifest code.
- Keep higher-level semantics local:
- restore decides which remote keys are in scope;
- audio decides cache hit/miss behavior;
- manifest decides JSON marshaling and validation;
- stages decide canonical output materialization.
Implementation targets:
- Replace duplicate root-escape checks in restore planning, run-local output handling, previous-cache path conversion, and artifact local path helpers where doing so keeps behavior identical.
- Replace duplicate temp-write/copy/rename mechanics in artifact local store, audio cache materialization, restore execution, and prepare helpers where the call site can keep its current error context.
- Leave manifest save behavior unchanged if sharing it would obscure manifest-specific validation or error text.
Tests:
- `go test ./internal/pathsafe -v`
- `go test ./internal/audio -v`
- `go test ./internal/app -run Restore -v`
- `go test ./internal/stage -run Prepare -v`
- `go test ./...`
Acceptance criteria:
- Root escape, absolute path, empty path, Windows separator, and valid relative path cases are covered by path-safe tests.
- Atomic helper tests prove temp files are cleaned up on failure and checksums match final file contents.
- Restore, prepare, and audio cache behavior remain unchanged.
## Stage 2: Artifact Source Policy (Implemented)
Finish centralizing artifact source vocabulary and validation in `internal/artifactpolicy`.
Implementation decisions:
- Extend `internal/artifactpolicy` with Scriptorium-input policy helpers:
- classify and validate built-in, configured, and previous-session source IDs;
- validate referenced configured artifact keys against the configured artifact set;
- expose a previous-session source descriptor for callers that need the configured artifact key.
- Keep runtime artifact lookup in `internal/artifacts`.
- Keep missing, required, optional, and operator-guidance behavior at call sites:
- config validation still produces field-specific errors;
- analyze still decides whether missing inputs fail or skip;
- previous-cache planning still decides required vs optional behavior.
- Do not make `artifactpolicy` inspect manifests, files, object storage, or runtime catalogs.
Implementation targets:
- Replace source parsing and static built-in checks in config validation with artifactpolicy helpers.
- Update analyze input resolution to consume the shared classification/descriptors while preserving current error messages and required/optional behavior.
- Update previous-cache planning to use shared previous-session source descriptors where source vocabulary is involved.
- Keep publish output destination derivation through `artifactpolicy.ResolvePublishedDestination`.
Tests:
- `go test ./internal/artifactpolicy -v`
- `go test ./internal/config -v`
- `go test ./internal/stage -run Analyze -v`
- `go test ./internal/previouscache -v`
- `go test ./...`
Acceptance criteria:
- Valid Scriptorium input source cases pass through one shared policy path.
- Invalid source format and unknown configured artifact references keep clear config-field errors.
- Analyze behavior for required/optional built-in, configured, and previous-session sources is unchanged.
- Previous-cache candidate ordering and required/optional behavior are unchanged.
## Stage 3: Read-Only Inspection Layer (Implemented)
Extract shared read-only session inspection checks for `session validate` and `session status`.
Implementation decisions:
- Keep the new inspection helpers in `internal/app`; they are command orchestration helpers, not stage or storage adapter behavior.
- Create small result types for checks, but do not create a generic reporting framework.
- Keep command-specific rendering local:
- `session validate` renders findings and fails on `ERROR`;
- `session status` renders state and does not fail for missing local/remote state unless config loading fails.
- Do not download artifact bodies for inspection unless current behavior already does so.
Implementation targets:
- Extract stable input checks from `operator_findings.go` into a reusable inspection helper.
- Extract local and remote audio presence checks that mirror prepare's selection rules without materializing audio.
- Extract previous-session readiness checks using existing current-state and previous-cache planning mechanics where possible.
- Extract effective lock and remote current-state inspection into reusable command helpers.
- Keep artifact catalog rendering separate from these checks.
Tests:
- `go test ./internal/app -run 'SessionValidate|Status' -v`
- `go test ./internal/previouscache -v`
- `go test ./internal/stage -run Prepare -v`
- `go test ./...`
Acceptance criteria:
- `session validate` and `session status` agree on local/remote audio and previous-session readiness facts.
- Missing current run pointer/manifest behavior remains command-appropriate: validation reports an error; status reports unavailable state.
- Existing lock and remote current-state behavior is unchanged.
## Stage 4: Optional CLI Edge Cleanup (Implemented)
Only implement this stage if Stage 1-3 leave meaningful repeated parser code.
Implementation decisions:
- Add at most one small parser helper for commands with `session_id` plus one additional positional argument.
- Use it for `session locks add` and `session locks remove` if it reduces duplication without obscuring syntax.
- Keep command handlers explicit.
- Do not change public syntax, flag names, help text meaning, or error semantics.
Tests:
- `go test ./internal/app -run 'Session|Locks|RunStage' -v`
- `go test ./...`
Acceptance criteria:
- Positional `session_id` and `--session-id` mismatch errors remain unchanged.
- Missing source arguments for lock add/remove remain clear.
- No new command aliases are introduced.
## Stage 5: Final Sweep (Implemented)
Run final validation after the implementation stages.
Required searches:
- `rg -n "archive|promote|promoted|promotion" internal docs examples cmd`
- `rg -n "narratio.transcript.merged|narratio.transcript.full|narratio.transcript.trimmed" internal docs examples`
- `rg -n "previous_session_artifact|promote_artifacts|pipeline.archive" internal docs examples`
- `rg -n "CreateTemp|Rename|copyFileAtomic|WriteFileAtomic|DownloadObjectToTemp" internal`
Expected search results:
- Retired terminology should remain only where intentionally historical or where fixture names make it unrelated to current behavior.
- Old transcript and old config/source names should not appear in runtime code, tests, examples, or current-behavior docs.
- File-operation searches should show centralized helpers plus acceptable direct uses where package-specific behavior remains intentional.
Required tests:
- `go test ./internal/artifactpolicy -v`
- `go test ./internal/artifacts -v`
- `go test ./internal/config -v`
- `go test ./internal/stage -run 'Analyze|Prepare|Publish' -v`
- `go test ./internal/app -run 'SessionValidate|Status|Restore|Locks|RunStage' -v`
- `go test ./internal/previouscache -v`
- `go test ./internal/audio -v`
- `go test ./internal/pathsafe -v`
- `go test ./internal/adapters/storage -v`
- `go test ./internal/manifest -v`
- `go test ./...`
Roadmap cleanup:
- Mark each completed stage as implemented only after its code, tests, and any internal docs are updated.
- Keep this file as planned work until the implementation stages land.
- Do not update canonical user/operator docs unless implementation changes visible behavior, which this roadmap does not intend.
## Assumptions
- Public CLI and config behavior remains unchanged throughout this cleanup.
- `internal/fileops` is the preferred home for shared atomic file mechanics.
- `internal/artifactpolicy` remains the source-policy home.
- `internal/artifacts` remains the path/key/current-state home.
- `internal/app` remains the command-loading, inspection, and rendering home.
- Stage packages keep stage execution policy and adapter interaction.