# Workspace internals ## Purpose Define the local durable and run-local workspace model used by stages, manifests, resume, and archive. ## Inputs and Outputs Inputs: - `pipeline.workspace.root` - `session.campaign` - `session.session_id` - generated `run_id` Outputs: - Session manifest at `{workspace.root}/work/{campaign}/{session_id}/manifest.json` - Run manifest at `{workspace.root}/work/{campaign}/{session_id}/runs/{run_id}/manifest.json` - Canonical durable session directories and run-local stage trees ## Boundaries Owns: - Session-level path layout (`inputs/`, `audio/`, `transcripts/`, `artifacts/`, `reports/`, `logs/`, `config/`, `current/`, `runs/`, `previous/`) - `previous/manifest.json` and `previous/artifacts/**` are reserved for previous-session cache state materialized by `prepare` or `restore` - Run-local stage sandbox layout under `runs/{run_id}/{stage}/` - Session lock acquisition/release (`.lock`) Does not own: - Stage business logic - Remote archive semantics (documented in `stage-archive.md`) - CLI argument parsing ## Config Fields Used - `pipeline.workspace.root` - `pipeline.workspace.cleanup_after_archive` - `pipeline.spool.root` - `pipeline.spool.delete_audio_after_archive` - `pipeline.cache.root` - `pipeline.cache.s3_audio` - `session.campaign` - `session.session_id` ## External Adapters Used None directly in this subsystem. Stages may use object storage adapters and then write local outputs into this layout. ## State and Manifest Behavior - Session state is persisted in the session manifest (`manifest.Manifest`). - Invocation history is persisted per run in run manifests under `runs/{run_id}/manifest.json`. - During each run, stage outputs are often written run-local first (`runs/{run_id}/{stage}/outputs/...`) and promoted to canonical session paths after stage success. - `manifest.Artifacts` entries record `ProducerRunID` for durable outputs. - For S3 audio sessions, `prepare` records work/cache paths, S3 provenance, and spool path when the invocation downloaded the object. - `previous/**` is reconstructed from configured previous-session requirements; restore uses the previous session's committed current archive rather than treating current-session archived `previous/**` as authoritative. - Durable cache state under `pipeline.cache.root` is not workspace state and is preserved by default by `narratio clean`. - `narratio clean ` removes the session work root and session spool root. - `narratio clean --all` removes all local session work under `workspace.root/work` and spool children under `spool.root`. - `narratio clean --clear-cache` is the explicit opt-in for deleting matching S3 audio cache entries. ## Skip and Resume Behavior - Skip/resume decisions are made in `internal/app` (`run_control.go`, `resume.go`) using stage status in the session manifest. - `--force` reruns selected stages and marks downstream previously-succeeded stages as `stale`. - Workspace layout is idempotent (`EnsureLayoutFor`) and reused across runs. ## Failure Behavior - Failures preserve manifests and run-local files for inspection. - Lock conflicts fail fast via `ErrLockConflict`. - Cleanup can fail post-archive; failure is recorded in archive stage metadata and returned by the run. ## Tests to Inspect Before Changing - `internal/artifacts/local_test.go` - `internal/stage/run_local_test.go` - `internal/app/run_control_test.go` - `internal/app/resume_run_stage_test.go` - `internal/app/post_archive_cleanup_test.go` ## Architectural Invariants - Session root is campaign-aware: `{workspace.root}/work/{campaign}/{session_id}`. - Run roots are always nested: `runs/{run_id}` under the session root. - Run-local output promotion must end in canonical session paths. - `previous/**` is session-durable state and must not be treated as run-local output scratch state. - Automatic post-archive cleanup only targets run-scoped directories and must never delete configured root directories. - Manual `clean` may delete session-scoped directories or the `workspace.root/work` directory, but it must preserve configured root directories and reject unsafe targets.