Revise and solidify the implementation roadmap

This commit is contained in:
2026-06-08 13:15:46 -05:00
parent 8f3ef33f18
commit c04432e40b

View File

@@ -60,6 +60,9 @@ any stage as implemented outside `docs/roadmap/` until that stage has landed.
of duplicating path rules.
- Update implemented-behavior docs and examples in the same change as the
corresponding behavior. Keep future behavior in roadmap docs only.
- A feature group is not complete until its paired documentation stage lands.
Do not move the roadmap item out of future/planned status until the behavior,
tests, current-behavior docs, and examples for that group are complete.
- Run the stage-specific tests before moving to the next stage. Run
`go test ./...` after each completed feature group.
@@ -181,6 +184,7 @@ Required coverage:
## Stage 3: Reconciliation Documentation And Examples
Goal: make implemented reconciliation behavior visible outside roadmap docs.
The reconciliation feature group is not complete until this stage lands.
Implementation:
@@ -264,10 +268,10 @@ go test ./internal/state
Do not enable shared-root publish behavior until Stage 5.
## Stage 5: Shared-Root Publish Planning And Execution
## Stage 5: Shared-Root Publish Planning And Comparison
Goal: allow multiple pipelines to publish disjoint managed paths into one
shared destination root.
Goal: teach publish planning to reason about shared-root owner scopes without
writing shared-root outputs yet.
Implementation:
@@ -290,6 +294,34 @@ Implementation:
from the new plan;
- owner-scoped `merge` retains prior outputs for that owner that are absent
from the new plan.
- Return plans that include the current owner scope, retained owner outputs,
owner outputs to delete, and owner outputs to write.
- Keep execution disabled for shared-root write actions until Stage 6.
Tests:
```sh
go test ./internal/publish ./internal/state
go test ./internal/app
```
Required coverage:
- planning treats absent owner state as publishable for that owner;
- planning preserves other owners in the planned retained state;
- path conflict with another owner plans or returns a conflict failure;
- unmanaged path collision plans or returns an unmanaged-content failure;
- owner-scoped `replace` selects only that owner's omitted outputs for deletion;
- owner-scoped `merge` retains that owner's omitted outputs;
- current single-owner planning remains covered.
## Stage 6: Shared-Root Publish Execution
Goal: allow multiple pipelines to publish disjoint managed paths into one
shared destination root.
Implementation:
- Preserve unrelated owners and their outputs exactly.
- Preserve and update timestamps:
- top-level `created_at` remains the original root creation time;
@@ -321,9 +353,10 @@ Required coverage:
- shared-root dry-run writes no outputs or state;
- current single-owner behavior remains covered.
## Stage 6: Shared-Root Documentation And Examples
## Stage 7: Shared-Root Documentation And Examples
Goal: document implemented shared-root behavior.
The shared-root feature group is not complete until this stage lands.
Implementation:
@@ -344,7 +377,7 @@ go test ./internal/config
go test ./...
```
## Stage 7: Reconcile-State Planning Core
## Stage 8: Reconcile-State Planning Core
Goal: add app-level planning and state helpers for reconcile-state without
adding CLI execution first.
@@ -353,8 +386,7 @@ Implementation:
- Add `internal/app` reconcile-state use case types:
- options with config path, pipeline id, destination id, all-owners flag,
dry-run flag, stdout, and output format if the existing format pattern is
reused;
dry-run flag, stdout, and output format;
- report struct with destination identity, backend, root path, state schema,
owner scope, checked count, missing managed outputs, unmanaged entries, and
changed/would-change status.
@@ -390,9 +422,10 @@ Required coverage:
- invalid state fails without rewrite;
- shared-root owner-scope and all-owner repair both work.
## Stage 8: Reconcile-State CLI And Docs
## Stage 9: Reconcile-State CLI And Docs
Goal: expose reconcile-state as an operator command.
The reconcile-state feature group is not complete until this stage lands.
Implementation:
@@ -427,7 +460,7 @@ Required coverage:
- text and JSON reports;
- no deletion of destination files.
## Stage 9: Prune Config And Planning Core
## Stage 10: Prune Config And Planning Core
Goal: add retention config and pure prune planning.
@@ -473,9 +506,9 @@ Required coverage:
- deterministic tie-breaking;
- shared-root owner scope preservation.
## Stage 10: Prune Execution, CLI, And Docs
## Stage 11: Prune Execution Core
Goal: expose safe managed-output pruning.
Goal: implement safe managed-output pruning below the CLI layer.
Implementation:
@@ -492,6 +525,37 @@ Implementation:
- never delete unmanaged files;
- do not delete `.distributor.json` unless a later roadmap explicitly permits
empty-state removal.
- Do not add CLI dispatch in this stage.
- Return a prune report that can later be rendered by text and JSON CLI output.
- Do not add one-off retention overrides in the initial implementation.
- Let local and SSH/SFTP backend helpers prune empty directories only where
they already do so safely. Preserve object-storage prefix markers unless they
are managed output records.
Tests:
```sh
go test ./internal/config
go test ./internal/app ./internal/state
go test ./internal/storage/fake
```
Required coverage:
- dry-run reports deletes without deleting files or rewriting state;
- apply deletes only managed output paths;
- unmanaged files under the destination root are preserved;
- partial delete failure preserves accurate state for confirmed deleted and
undeleted outputs;
- shared-root pruning preserves other owners when scoped to one owner.
## Stage 12: Prune CLI And Docs
Goal: expose safe managed-output pruning as an operator command. The prune
feature group is not complete until this stage lands.
Implementation:
- Add `prune` CLI dispatch and help.
- Add CLI flags:
- `--config <path>`;
@@ -504,10 +568,6 @@ Implementation:
reports without writing. `--apply` deletes planned managed outputs and
rewrites state after confirmed deletes.
- JSON output should use the existing app JSON envelope pattern.
- Do not add one-off retention overrides in the initial implementation.
- Let local and SSH/SFTP backend helpers prune empty directories only where
they already do so safely. Preserve object-storage prefix markers unless they
are managed output records.
- Update `docs/config.md`, `docs/cli.md`, `docs/operations.md`,
`docs/troubleshooting.md`, `docs/integrations/destination-state.md`,
`docs/internal/state.md`, `docs/internal/publish.md`, and
@@ -524,12 +584,8 @@ go test ./...
Required coverage:
- dry-run reports deletes without deleting files or rewriting state;
- apply deletes only managed output paths;
- unmanaged files under the destination root are preserved;
- partial delete failure preserves accurate state for confirmed deleted and
undeleted outputs;
- shared-root pruning preserves other owners when scoped to one owner;
- CLI requires exactly one of `--dry-run` or `--apply`;
- text and JSON reports;
- CLI apply gating and report output.
## Final Verification