9.5 KiB
Roadmap: Session-Oriented CLI Cleanup
Status: Implemented
Problem
Narratio's public CLI has accumulated too many top-level commands. Several commands are session-scoped operator helpers, but they currently appear as independent top-level verbs:
planstatusrestoreartifacts listlockssession validatesession init
This makes the command surface harder to learn because the CLI does not clearly separate primary workflow actions from session inspection, initialization, restore, and helper operations.
Target Model
Keep primary workflow commands at top level:
runrun-stageresumeanalyzepublishcleansession
Keep clean top-level because it can operate on one session or all local
sessions and is a workspace maintenance command, not only a session helper.
Move session-scoped helper commands under narratio session and use positional
session identifiers:
narratio session init <session_id> [--remote|--output <path>] [--flags]narratio session validate <session_id> [--flags]narratio session status <session_id> [--flags]narratio session plan <session_id> [--flags]narratio session restore <session_id> [--flags]narratio session artifacts <session_id> [--remote] [--flags]narratio session locks <session_id> [--flags]narratio session locks add <session_id> <source> [--reason <text>] [--force] [--flags]narratio session locks remove <session_id> <source> [--flags]
Update top-level workflow commands to use positional session identifiers:
narratio run <session_id> [--flags]narratio resume <session_id> [--flags]narratio analyze <session_id> [--flags]narratio publish <session_id> [--flags]narratio run-stage <stage> <session_id> [--flags]
The positional session ID replaces --session-id as the primary public
interface. Existing --config, --campaign, --session, and
--previous-session-id flags remain available where they are meaningful.
Command Mapping
| Current command | Target command |
|---|---|
narratio run --session-id <id> |
narratio run <id> |
narratio resume --session-id <id> |
narratio resume <id> |
narratio analyze --session-id <id> |
narratio analyze <id> |
narratio publish --session-id <id> |
narratio publish <id> |
narratio run-stage [flags] <stage> --session-id <id> |
narratio run-stage <stage> <id> [flags] |
narratio plan --session-id <id> |
narratio session plan <id> |
narratio status --session-id <id> |
narratio session status <id> |
narratio restore --session-id <id> |
narratio session restore <id> |
narratio artifacts list --session-id <id> |
narratio session artifacts <id> |
narratio locks --session-id <id> |
narratio session locks <id> |
narratio locks add --session-id <id> <source> |
narratio session locks add <id> <source> |
narratio locks remove --session-id <id> <source> |
narratio session locks remove <id> <source> |
narratio session validate --session-id <id> |
narratio session validate <id> |
narratio session init --session-id <id> |
narratio session init <id> |
narratio clean --session-id <id> |
narratio clean <id> |
narratio clean --all |
unchanged |
clean remains top-level, but its session-scoped form should also move from
--session-id to positional <session_id> for consistency.
Compatibility Policy
This is a hard public CLI cleanup after the migration step lands.
During Step 1, old forms may remain as compatibility aliases to keep the implementation reviewable. During Step 2, remove the old forms from command dispatch, tests, docs, and examples:
- remove top-level
plan; - remove top-level
status; - remove top-level
restore; - remove top-level
artifacts; - remove top-level
locks; - remove
--session-idfrom the public command syntax for session-aware commands.
Do not keep long-term deprecated aliases unless a later roadmap explicitly chooses a compatibility window.
status --manifest does not fit the session-oriented command shape. Remove it
from the public CLI in this cleanup. If direct manifest inspection is needed
later, add a separate diagnostic command in a future roadmap rather than keeping
it as a special case in session status.
Implementation Step 1: Add New Session-Oriented Interface
Status: Implemented
Add the target command forms while preserving current behavior internally.
Implementation requirements:
- Add positional session ID parsing helpers in
internal/app. - Keep the existing
loadCommandConfigbehavior and populateconfig.SessionLoadOptions.SessionIDfrom the positional ID. - Add or update command wrappers:
Run(ctx, args, out)parsesrun <session_id>.Resume(ctx, args, out)parsesresume <session_id>.Analyze(ctx, args, out)parsesanalyze <session_id>.Publish(ctx, args, out)parsespublish <session_id>.RunStage(ctx, args, out)parsesrun-stage <stage> <session_id>.Clean(ctx, args, out)parsesclean <session_id>and keepsclean --all.
- Extend
Session(ctx, args, out)dispatch to support:init <session_id>validate <session_id>status <session_id>plan <session_id>restore <session_id>artifacts <session_id>locks <session_id>locks add <session_id> <source>locks remove <session_id> <source>
- Keep storage access through the existing app-level object-store helper.
- Keep AWS SDK details behind storage adapters.
- Keep the runner, stages, manifest behavior, archive behavior, restore planning, lock semantics, and artifact catalog behavior unchanged.
Acceptance criteria:
- New forms execute the same code paths and produce equivalent results.
- Positional session ID mismatch with concrete local or remote
session.ymlfails through existing session identity checks. - Remote session fallback still uses the positional session ID as the lookup value.
- Current command tests cover the new forms before old forms are removed.
Implementation Step 2: Remove Old Public Forms
Status: Implemented
Remove compatibility aliases and make the session-oriented interface the only documented and supported public CLI.
Implementation requirements:
- Remove top-level dispatch for:
planstatusrestoreartifactslocks
- Remove
--session-idflags from public session-aware commands. - Keep
--previous-session-idas an expected previous-session identity flag. - Keep explicit
--session <path>for loading a local concrete session file, but still require the positional session ID for commands that operate on a session. - Remove
status --manifest. - Update usage text and invalid-command errors.
- Update
docs/cli.mdanddocs/operations.mdto use only the new forms. - Update any roadmap docs that mention old helper command names.
- Update tests to expect old top-level helper commands and
--session-idforms to fail.
Acceptance criteria:
- Top-level command list is exactly:
runrun-stageresumeanalyzepublishcleansession
- All session-oriented commands use
narratio session <subcommand> <session_id> [--flags], except nested lock mutation forms, which usenarratio session locks add|remove <session_id> <source> [--flags]. clean <session_id>andclean --allremain top-level.- Current-behavior docs and tests no longer advertise
--session-id.
Test Guidance
Focused tests:
go test ./internal/app -run TestExecute -vgo test ./internal/app -run 'Session|Status|Restore|Clean|Locks|Artifacts|Plan|RunStage|Analyze|Publish' -vgo test ./internal/config -v
Full validation:
go test ./...
Test cases to add or update:
run <session_id>loads local and remote sessions through the existing config path.resume <session_id>,analyze <session_id>, andpublish <session_id>preserve current behavior.run-stage <stage> <session_id>preserves current run-stage output and force/artifact-selection behavior.session plan <session_id>replaces top-levelplan.session status <session_id>replaces top-level session status.session validate <session_id>replacessession validate --session-id.session init <session_id>writes the same local or remote concretesession.yml.session restore <session_id>preserves restore planning/execution.session artifacts <session_id> --remotepreserves promoted-output availability reporting.session locks <session_id>,session locks add <session_id> <source>, andsession locks remove <session_id> <source>preserve static/remote lock semantics.clean <session_id>preserves session cleanup behavior, whileclean --allremains unchanged.- Old top-level helper commands fail after Step 2.
--session-idfails after Step 2.status --manifestfails after Step 2.
Documentation Guidance
Update only after implementation lands:
docs/cli.mddocs/operations.md- any internal docs that list command names or examples
Keep planned behavior only in this roadmap until the command refactor is implemented.
Architecture Guardrails
- Keep Narratio explicit and stage-driven.
- Do not introduce a generic workflow or command framework abstraction.
- Reuse existing app command helpers where practical.
- Keep config loading strict and centralized.
- Keep storage details behind
storage.ObjectStore. - Keep secret-backed object-store construction in
internal/app. - Preserve manifest-driven resume and restore behavior.
- Treat command renaming as a public CLI contract change, not a runtime stage behavior change.