# Stage: publish ## Purpose Upload run/session outputs to object storage and atomically advance remote current state. ## Inputs - successful prerequisite stages: `prepare`, `transcribe`, `merge`, `polish`, `normalize`, `trim`, `analyze` - run root `runs/{run_id}/**` - publish output rules (`pipeline.publish.outputs`) - effective publish locks (static + remote merged lock set) - local `previous/**` files when present ## Outputs - uploaded run files under remote `runs/{run_id}/...` (excluding `audio/**`) - uploaded selected publish outputs under session prefix - uploaded `previous/**` files under session prefix when present - uploaded `current/manifest.json` - uploaded `current/run_id.txt` written last ## Key Behavior - stage can self-skip when publish disabled or run upload disabled. - validates prerequisite stage success and object-store availability. - collects deterministic run file list plus run `manifest.json`. - resolves publish output sources through runtime artifact catalog and manifest-aware resolution. - selected artifact filter applies to configured artifact sources only. - locked outputs are skipped intentionally (including required ones). - optional missing outputs are skipped; required missing unlocked outputs fail. - writes remote current manifest before current run pointer. ## Metadata Signals Includes counts/lists for: - run uploads - published output uploads - previous uploads - skipped optional outputs - skipped unselected outputs - locked outputs - current-state key paths - `current_pointer_written` ## Invariants - `current/run_id.txt` is the remote commit marker and is written last. - run upload excludes `audio/**`. - publish locks are not overridden by `--force`.