Files
audita/docs/roadmap/implementation.md

133 lines
8.1 KiB
Markdown

# Implementation Plan: Independent Output Destinations
**Last updated:** 2026-10-03
**Status:** Ready for implementation.
**Audience:** gpt-5.6-terra coding agent.
## Scope and Execution
Implement the target behavior in the [Narratio feature roadmap](narratio-feature.md),
in Stage 1 then Stage 2. That roadmap owns the user intent and external contract;
this plan owns the implementation sequence and verification. The original
[Narratio request](feature-request-narratio.md) supplies consumer context. The
completed policy-adoption plan previously at this path remains available at
[its final committed revision](https://gitea.maximumdirect.net/eric/audita/src/commit/61bc467a03da17d52481faa5db96d9e048815be7/docs/roadmap/implementation.md).
Begin with [development guidance](../development.md) and the applicable
[agent](../policy/agents.md), [architecture](../policy/architecture.md),
[documentation](../policy/documentation.md), and
[testing](../policy/testing.md) policies. Use graph-first code discovery as the
agent policy directs. Commit each completed unit with a short, plain English
message; do not release, tag, or push as part of this feature. No approval gate
is needed between stages.
Keep the change at the CLI destination-selection boundary. `--report-dir` is
already parsed as a ConfigKit override of `reporting.stdout_dir`; retain that
mapping so effective-configuration views and flag precedence remain intact.
For `process` only, also retain whether the caller explicitly supplied the flag.
The configured `reporting.stdout_dir` value alone must not redirect file-output
reports. Do not add a configuration key, alter report schemas, add output-root
separation rules, or change the output session's existing lifecycle merely to
support this selection.
Use this selection rule after configuration is loaded:
| Reporting state and transcript destination | Selected ordinary report directory |
| --- | --- |
| Reporting disabled | None; do not preflight or create the chosen report directory |
| Reporting enabled, stdout transcript | Effective `reporting.stdout_dir`, including any `--report-dir` override |
| Reporting enabled, file transcript, explicit `--report-dir` | Effective `reporting.stdout_dir` from that flag |
| Reporting enabled, file transcript, no explicit `--report-dir` | Parent of `--output FILE` |
An active selected report directory must be nonblank. A blank
`reporting.stdout_dir` must not newly invalidate file output when no explicit
`--report-dir` was supplied. Continue to let existing configuration validation
handle invalid setting values; this plan does not add special handling for an
invalid but inactive flag. Existing `--work-dir` and effective
`diagnostics.debug` controls already select and enable debug capture
independently. Selecting `--report-dir` or `--work-dir` alone never turns on
reporting or debug capture. A failed report still appears in the selected
directory only when the existing output lifecycle would produce it; failures
before report initialization remain outside that guarantee.
## Stage 1 — Implement Explicit Report-Destination Selection
**Files:** `internal/cli/config_input.go`, `internal/cli/process.go`,
`internal/cli/run.go`, `internal/cli/config_input_test.go`, and the existing
affected subprocess test in `cmd/audita/main_integration_test.go`.
1. In `configInput`, record explicit `--report-dir` presence from the parsed
flag set's `Visit` callback. Preserve the existing ConfigKit override and
its `--report-dir` provenance. Do not infer explicitness from the effective
config value, because a default, file, or overlay can yield the same value.
Other commands may continue accepting the override for inspection without
changing their behavior.
2. Extend `selectedReportDir` to accept that explicitness and implement the
table above. Make `runProcess` pass the new input to it, then continue
passing the selected path to the existing `diagnostics.PrepareOutput` call.
Leave `PrepareOutput` collision, preflight, initialization, failure, and
finalization behavior in place. Leave the existing `cfg.Diagnostics.Debug`
and `cfg.Diagnostics.WorkDir` path into debug startup intact.
3. Update focused CLI tests for explicit presence and selection: file output
with explicit flag uses the selected directory; file output with only a
configured or overlay `reporting.stdout_dir` still uses the output parent;
stdout uses the effective report directory; disabled reporting selects no
active report directory. Test active blank values only where they affect
selection. Retain coverage that the flag remains a ConfigKit override.
4. Replace the existing subprocess assertion in
`TestSubprocessReportingAndDebugSelections` that relies on an ignored
`--report-dir` with the new behavior. Keep its separate check that an
inactive destination is not probed. Avoid duplicating every unit-selection
case at the subprocess layer.
5. Update `audita process` help so it no longer says `--report-dir` is ignored
with file output. Keep help aligned with the selection rule above.
**Stage completion:** Run targeted tests for the changed CLI and subprocess
packages (`go test ./internal/cli ./cmd/audita`) and `git diff --check`. Review
the diff for accidental configuration-schema changes or newly strengthened
destination constraints, then commit the coherent code/test unit.
## Stage 2 — Verify End-to-End Behavior and Update the Public Contract
**Files:** `cmd/audita/main_integration_test.go`, `docs/cli.md`,
`docs/config.md`, `docs/operations.md`,
`docs/integrations/subprocess.md`, and `docs/roadmap/narratio-feature.md`.
Touch another document only if its current statement actually conflicts with
the new behavior.
1. Add one representative subprocess success case with distinct transcript
file, report directory, and debug root, enabling debug explicitly. Verify
the transcript, ordinary reports, and `run-<id>` debug capture appear at
their selected destinations and that the report files are not placed beside
the transcript. Reuse the existing test fixture; do not prescribe a new
report format or a Narratio-specific directory layout.
2. Add a subprocess case based on the invalid-input fixture used by
`TestSubprocessInvalidInputLeavesFailedReports`. It fails **after** report
initialization; check that its available failed-status reports use an
explicit report directory. Preserve the existing test of default placement
and the existing early-failure semantics. Rely on current output-session
collision and inactive-debug tests where they already prove the behavior;
add a narrow test only if this new CLI route exposes an uncovered interaction.
3. Change the CLI, configuration, operations, and subprocess documents to state
the four selection cases above. Explain that a config-file or overlay value
for `reporting.stdout_dir` remains stdout-only, while an explicit
`--report-dir` flag selects reports for either transcript destination.
Clarify that `--work-dir` chooses a
debug root without enabling capture and that configuration or `--debug` can
enable it. Describe reports after failures only to the extent the current
output lifecycle supplies them. Leave the canonical output-file schema
document unchanged unless this work exposes a factual error in it.
4. Review the completed behavior against the feature roadmap's acceptance
criteria. Run `go test ./...`, check documentation links and examples, and
run `git diff --check`. If a test fails, resolve that failure before marking
the feature complete; do not add unrelated gates. Mark the feature roadmap
implemented once the final behavior and documentation are verified, then
review the staged diff and commit the completed unit with a short, plain
English message. Leave a clean workspace.
No open policy or design decision is required to execute these stages. The
explicit-flag precedence, preserved defaults, inactive-destination behavior,
failure-report limit, and existing debug controls are settled in the feature
roadmap. If implementation uncovers a conflict with an established contract,
report the concrete conflict instead of silently broadening this feature.