From c04432e40b3be96ab0df6061cdc4afffa34d3997 Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Mon, 8 Jun 2026 13:15:46 -0500 Subject: [PATCH] Revise and solidify the implementation roadmap --- docs/roadmap/implementation.md | 98 ++++++++++++++++++++++++++-------- 1 file changed, 77 insertions(+), 21 deletions(-) diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index 6a6af51..bcbbeca 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -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 `; @@ -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