Files
narratio/docs/internal/command-restore.md

4.3 KiB

Internal: Command Restore

Purpose

Define the implemented narratio restore contract: committed remote-state discovery, deterministic plan classification, safe file install semantics, and restore reporting.

Inputs and outputs

Inputs:

  • CLI flags: --config, --session, --session-id, --previous-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.

Restore path scope:

  • includes:
    • manifest.json
    • transcripts/**
    • artifacts/**
    • previous/**
    • audio/** only when --include-audio is set
  • excludes:
    • runs/**
    • logs/**
    • reports/**
    • config/**
    • inputs/**
    • remote current/** pointer files as local restore targets

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/**, previous/**
    • include audio/** only with --include-audio
    • exclude runs/**, logs/**, reports/**, config/**, inputs/**
  • Command remains standalone; no implicit run --restore behavior.