9.8 KiB
Roadmap: Publish Contract
Status: Planned
Problem
Narratio currently uses several terms for one operator-facing concept:
archiveis the stage that uploads run state and commits remote current state.publishis the convenience command that force-runs the archive stage.promote,promoted, andpromote_artifactsdescribe configured top-level remote output writes.
This mixed vocabulary makes the public contract harder to explain. Operators should not need to distinguish "archive the run", "publish the run", and "promote artifacts" when these are all part of the same publish action.
The public model should use:
publishfor the stage, command, config section, and action;publishedfor an expected remote output that exists at its top-level current destination;publish rulesfor the configured source-to-destination output rules;lockedfor sources whose top-level published destination must not be overwritten;run historyfor immutable per-run records underruns/<run_id>/.
Target Model
The public stage is publish.
The convenience command:
narratio publish <session_id>
is equivalent to:
narratio run-stage publish <session_id> --force
Pipeline configuration uses publish:
publish:
enabled: true
upload_run: true
outputs:
- source: narratio.transcript.final_trimmed
- source: narratio.artifact.session_recap
locks:
- source: narratio.artifact.session_recap
reason: Final recap was manually edited.
Publish output rules are source-based. Each rule writes one artifact source to
a top-level remote destination. If dest is omitted, Narratio derives the
destination from the artifact registry or configured artifact output path.
The mutable remote lock store remains:
{session_prefix}/locks.yml
Remote availability output uses published:
Published:
- narratio.transcript.final_trimmed remote=published
- narratio.artifact.session_recap locked remote=published
The remote key layout is otherwise unchanged:
- immutable run history stays under
{session_prefix}/runs/{run_id}/; - current state stays under
{session_prefix}/current/manifest.json; - the final commit marker stays
{session_prefix}/current/run_id.txt; current/run_id.txtis still written last.
Compatibility Policy
This is a hard cutover.
After implementation:
pipeline.archiveis rejected by strict YAML decoding.pipeline.archive.promote_artifactsis rejected.pipeline.workspace.cleanup_after_archiveis rejected.pipeline.spool.delete_audio_after_archiveis rejected.narratio run-stage archive <session_id>is an unknown stage.- manifests that record an
archivestage are not migrated. - old archive/promotion metadata keys are not read as compatibility fallbacks.
Existing remote objects are not moved or renamed. Remote layout remains stable; the rename changes configuration, stage names, status output, metadata, helper names, tests, examples, and documentation.
Implementation Stages
Stage 1: Public Schema and Stage Cutover
Status: Planned
Switch the public config and stage contract to publish terminology.
Implementation requirements:
- Replace
pipeline.archivewithpipeline.publish. - Replace
archive.promote_artifactswithpublish.outputs. - Keep output rule fields:
sourcedestrequired
- Replace
pipeline.archive.lockswithpipeline.publish.locks. - Rename post-publish cleanup fields:
pipeline.workspace.cleanup_after_publishpipeline.spool.delete_audio_after_publish
- Rename the registered stage from
archivetopublish. - Update stage order so
publishruns afteranalyzeand beforenotify. - Update top-level
narratio publishto target stagepublish. - Keep
run-stage --artifacts <names> publishsupport. - Reject
run-stage --artifacts <names>for stages other thananalyzeandpublish. - Preserve the remote commit ordering and storage adapter boundaries.
Acceptance criteria:
narratio run-stage publish <session_id>executes the publish stage.narratio publish <session_id>force-runs the publish stage.narratio run-stage archive <session_id>fails clearly as an unknown stage.- Old archive config fields fail strict decoding.
- New publish config fields load, default, and validate.
Stage 2: Runtime Terminology and Metadata Cutover
Status: Planned
Rename implementation concepts and runtime output to publish terminology.
Implementation requirements:
- Rename archive/promotion config and runtime types conceptually to publish/output terms.
- Rename the remote key helper intent from promoted artifact to published output while keeping generated keys unchanged.
- Change helper output:
Promoted:becomesPublished:remote=promotedbecomesremote=published- lock output uses
published/not-published
- Rename publish-stage metadata, including:
promoted_pathstopublished_pathspromoted_files_uploadedtopublished_files_uploadedskipped_optional_promotionstoskipped_optional_outputsskipped_unselected_promotionstoskipped_unselected_outputslocked_promotion_counttolocked_output_countlocked_promotionstolocked_outputs
- Update previous-cache and restore logic to use the
publishstage andpublished_pathsmetadata only. - Keep run-local stage output materialization separate from remote publish terminology. If local helper names are confusing, rename them to materialization-oriented names rather than publish names.
Acceptance criteria:
- Status and artifact helper output use
Published:andremote=published. - Publish metadata contains only publish/output terminology.
- Previous-cache and restore behavior works with publish metadata and does not depend on old archive metadata.
- Storage adapters still receive explicit keys and no AWS SDK details leak into app or stage logic.
Stage 3: Documentation, Examples, and Final Cleanup
Status: Planned
Update implemented-behavior docs and remove stale public terminology after the runtime cutover lands.
Implementation requirements:
- Update current-behavior docs:
docs/config.mddocs/cli.mddocs/operations.mddocs/troubleshooting.mddocs/architecture.md- relevant files under
docs/internal/
- Rename
docs/internal/stage-archive.mdtodocs/internal/stage-publish.md. - Update internal documentation links and references.
- Update examples to use:
publish.outputspublish.lockscleanup_after_publishdelete_audio_after_publish
- Update tests and final searches so old terminology remains only in this roadmap as historical context.
Acceptance criteria:
- Maintained examples load and validate.
- Current-behavior docs describe only implemented publish terminology.
- Internal docs describe run history, published outputs, locks, and current commit ordering clearly.
- Old user-facing archive/promote wording is removed except where discussing historical behavior in this roadmap.
Test Guidance
Focused tests:
go test ./internal/config -vgo test ./internal/app -vgo test ./internal/stage -vgo test ./internal/artifacts -v
Full validation:
go test ./...
Config tests to add or update:
publish.outputsdefaults and validates.publish.outputs[].destderives from the artifact registry when omitted.publish.locksvalidates with the same source rules as publish outputs.- old
archivefails strict decode. - old
promote_artifactsfails strict decode. - old cleanup fields fail strict decode.
App and stage tests to add or update:
- stage order uses
publishbeforenotify. run-stage publishsucceeds.run-stage archivefails clearly.narratio publishforce-runs thepublishstage.--artifactsis accepted forrun-stage publish.--artifactserror text namesanalyzeandpublish.- status and artifact list output show
Published:andremote=published. - lock output says
publishedornot-published. - previous-cache and restore use
publishstage metadata.
Final searches:
- Config/stage names:
pipeline.archivearchive:promote_artifactscleanup_after_archivedelete_audio_after_archive
- User-facing output:
Promoted:remote=promotednot-promoted
- Runtime symbols and metadata:
ArchiveConfigArchivePromotionRuleS3PromotedArtifactKeypromoted_pathspromoted_files_uploadedlocked_promotions
Expected remaining matches should be limited to this roadmap and narrowly justified historical references until the roadmap is fully retired.
Architecture Guardrails
- Keep Narratio explicit and stage-driven.
- Do not introduce a generic workflow or DAG abstraction.
- Keep strict YAML decoding.
- Keep remote path construction centralized.
- Keep storage details behind
storage.ObjectStore. - Keep AWS SDK types inside storage adapters.
- Preserve manifest-driven resume and restore behavior.
- Preserve current-state commit ordering with
current/run_id.txtwritten last. - Keep raw secrets out of configs, manifests, logs, generated configs, and publish metadata.
- Keep planned behavior only in this roadmap until implementation lands.
Assumptions
- This is a breaking public/config/stage contract change.
- No compatibility aliases are retained.
- No migration logic is needed for in-progress local manifests.
- No migration logic is needed for old remote manifests.
- Existing remote objects are not moved or renamed.
publishmeans uploading run history, writing configured published outputs, and committing current state.run historyis the preferred term for immutable per-run records underruns/<run_id>/.archiveremains acceptable only as a generic English concept in historical roadmap context, not as a public Narratio command, config field, stage name, or metadata term after implementation.