87 lines
4.0 KiB
Markdown
87 lines
4.0 KiB
Markdown
# Internal: Command Restore
|
|
|
|
## Purpose
|
|
Define the implemented `narratio restore` command contract: committed remote-state discovery, deterministic planning, safe file installation, conflict policy, and restore reporting.
|
|
|
|
## Inputs and outputs
|
|
Inputs:
|
|
- CLI flags: `--config`, `--session`, `--session-id`, `--dry-run`, `--force`, `--include-audio`.
|
|
- Resolved/validated `pipeline.yml` and `session.yml`.
|
|
- Configured remote object store.
|
|
- Remote committed current-state markers (`current/run_id.txt`, `current/manifest.json`).
|
|
|
|
Outputs:
|
|
- Dry-run summary to stdout (plan + counts).
|
|
- Non-dry-run completion summary to stdout.
|
|
- Local durable session files restored under canonical session root.
|
|
- Non-dry-run restore report at `reports/restore-latest.json`.
|
|
|
|
## Boundaries
|
|
Owns:
|
|
- Restore command flag parsing and command wiring.
|
|
- Remote current-state discovery and identity validation.
|
|
- Restore plan construction and conflict classification.
|
|
- Restore execution for planned downloads.
|
|
- Restore report model and persistence.
|
|
|
|
Does not own:
|
|
- Stage execution orchestration (`run`, `resume`, `run-stage`).
|
|
- Archive publish behavior (owned by archive stage).
|
|
- Storage transport implementation details (owned by storage adapters).
|
|
|
|
## Config fields used
|
|
- Config/session discovery and templating fields consumed by all commands.
|
|
- `pipeline.workspace.root` (local restore target root).
|
|
- `pipeline.storage.*` (remote backend + archive identity derivation).
|
|
- `pipeline.storage.s3.*` identity components used by archive prefix helpers.
|
|
- `session.session_id`
|
|
- `session.campaign`
|
|
|
|
## External adapters used
|
|
- `storage.ObjectStore` for `Exists`, `List`, `Download`.
|
|
- `artifacts.Store` (`LocalStore`) for layout and session lock management.
|
|
- `manifest.LocalStore` for manifest decode/validation and identity checks.
|
|
|
|
## State and manifest behavior
|
|
- Restore is not a pipeline run and does not create a run manifest.
|
|
- Restore uses committed remote current state only:
|
|
- `current/run_id.txt` must exist and be non-empty.
|
|
- `current/manifest.json` must decode and match requested session/campaign.
|
|
- Non-dry-run writes restore files to canonical session paths.
|
|
- Manifest install behavior:
|
|
- validated before replacement.
|
|
- installed last among download actions.
|
|
- existing local manifest is preserved if restored manifest validation/install fails.
|
|
- Non-dry-run report persists summary/action status metadata in `reports/restore-latest.json`.
|
|
|
|
## Skip and resume behavior
|
|
- Restore does not participate in stage skip/resume decisions.
|
|
- Restore provides durable local state so subsequent stage commands can resume or rerun based on restored manifest state.
|
|
- Dry-run is read-only and returns plan output only.
|
|
|
|
## Failure behavior
|
|
- Fails when storage backend is unavailable or archive identity cannot be resolved.
|
|
- Fails when remote current pointer/manifest is missing or invalid.
|
|
- Fails when remote manifest identity mismatches requested campaign/session.
|
|
- Fails on local conflicts unless `--force` is set.
|
|
- Fails fast on session lock acquisition conflict for non-dry-run execution.
|
|
- On execution failure, previously installed files remain; no rollback is performed.
|
|
|
|
## Tests to inspect before changing
|
|
- `internal/app/restore_test.go`
|
|
- `internal/app/restore_discovery_test.go`
|
|
- `internal/app/restore_plan_test.go`
|
|
- `internal/app/restore_execution_test.go`
|
|
- `internal/app/restore_workflow_test.go`
|
|
- `internal/artifacts/archive_identity_test.go`
|
|
|
|
## Architectural invariants
|
|
- Restore relies on centralized archive identity/key helpers (`internal/artifacts`) rather than ad hoc key building.
|
|
- `current/run_id.txt` is the remote commit marker; restore must not infer committed state from incidental files.
|
|
- Local path mapping is traversal-safe and constrained to session root.
|
|
- Restore scope is deterministic and path-classified:
|
|
- include `manifest.json`, `transcripts/**`, `artifacts/**`
|
|
- include `audio/**` only with `--include-audio`
|
|
- exclude `runs/**`, `logs/**`, `reports/**`, `config/**`, `inputs/**`
|
|
- Command remains standalone; no implicit `run --restore` behavior.
|