138 lines
8.3 KiB
Markdown
138 lines
8.3 KiB
Markdown
# Implementation Plan: Independent Output Destinations
|
||
|
||
**Last updated:** 2026-10-03
|
||
**Status:** Complete; Stages 1–2 implemented and verified.
|
||
**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
|
||
|
||
**Completion:** Complete — targeted CLI and subprocess tests pass; reviewed diff and whitespace checks.
|
||
|
||
**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`.
|
||
|
||
**Completion:** Complete — the full Go test suite, maintained configuration
|
||
examples, affected Markdown links, and whitespace checks pass.
|
||
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.
|