# Narratio -> Scriptorium CLI Integration ## 1. Purpose This document defines how Narratio should invoke Scriptorium through the **public CLI**. This is a **subprocess integration contract**, not an internal Go API contract. ## 2. Assumptions - `scriptorium` is installed and available on `PATH`. - Scriptorium is configured with `config.yml`. - `config.yml` provides `prompt_dir`, `profile_dir`, and `schema_dir` as needed. - Prompt and profile libraries are already deployed for the environment. - Narratio provides prepared artifact files (for example polished transcript, glossary, previous recap, campaign notes). - Initial integration is synchronous subprocess execution. - Narratio remains the orchestrator. In normal operation, Narratio does not need to pass `--prompt-dir` and `--profile-dir` if they are supplied by Scriptorium config. Narratio may pass `--config ` when it must use a non-default Scriptorium config file. ## 3. Core Commands Narratio May Call Primary commands for subprocess integration: - `scriptorium run` - `scriptorium render` For production generation, use `scriptorium run`. `scriptorium render` is for debugging, dry-runs, test assertions, and validating command construction without LLM execution. Note: `scriptorium serve` and HTTP API exist, but they are not the initial integration path. ## 4. Command Selection Guidance - Use `run` to generate an output artifact. - Use `render` to inspect the prepared prompt and effective settings without calling the LLM. - Use `render --format json` when Narratio/tests need structured prepare output. ## 5. Recommended `run` Invocation Shape Production shape: ```bash scriptorium run \ --prompt \ --input transcript= \ --out ``` Common optional additions: - `--config `: use a specific Scriptorium config file. - `--profile `: override prompt default profile. - `--var name=value` (repeatable): small metadata values. - `--input name=path` (repeatable): additional named artifacts. - `--timeout `: per-run timeout override. - Runtime model override flags (`--llm-base-url`, `--model`, etc.) only for exceptional/operator-directed cases. ## 6. Recommended `render` Invocation Shape Human-readable debug shape: ```bash scriptorium render \ --prompt \ --input transcript= \ --format text ``` Structured debug/test shape: ```bash scriptorium render \ --prompt \ --input transcript= \ --format json \ --out ``` `render` does **not** call the LLM, does **not** validate model output, and does **not** perform repair. ## 7. Inputs - Pass inputs as repeated `--input name=path` flags. - `name` must match the Prompt Definition input name. - Prefer absolute paths, or paths relative to a working directory controlled by Narratio. - Pass Audita output as the primary transcript input. - Additional inputs may include glossary, previous recap, campaign notes, event logs, final state maps, or other prompt-specific artifacts. - Scriptorium reads input files directly; Narratio does not need to inline file content for CLI use. ## 8. Variables Use repeated `--var name=value` for small metadata values. Typical examples: - `session_date` - `session_id` - `campaign_name` - `previous_session_id` - `output_kind` Large content belongs in input files, not `--var` values. ## 9. Prompt IDs and Output Artifact Types Narratio should treat prompt IDs as configuration, not hardcoded business logic. Narratio config may map stage/output names to prompt IDs, for example: - session recap prompt - structured event extraction prompt - glossary suggestion prompt - player-facing summary prompt Prompt IDs used by Narratio should come from the deployed Scriptorium prompt library. ## 10. Profiles - Prompts may declare `default_profile`. - Narratio may omit `--profile` to use prompt default profile. - Narratio may pass `--profile` to force profile selection. - This enables environment/profile selection like `local-fast`, `local-quality`, `frontier`, `batch`, or test profiles. - Profile names should generally be Narratio configuration values. ## 11. Runtime Overrides Supported runtime override flags: - `--llm-base-url` - `--model` - `--api-key-env` - `--temperature` - `--max-tokens` - `--top-p` - `--timeout` Guidance: - Keep normal model/runtime settings in Execution Profiles. - Use runtime overrides only for explicit per-run exceptions, tests, or operator overrides. - Never pass raw API keys on the command line. - `--api-key-env` names an environment variable; Narratio must ensure that variable is set in subprocess environment. ## 12. Config Behavior - Default config path: `/etc/scriptorium/config.yml`. - `--config ` overrides default path. - Missing default config is allowed by Scriptorium. - If `--config` is provided explicitly, the file must exist and be valid. - CLI flags override `config.yml`. - `config.yml` overrides built-in application defaults. Narratio can either: - rely on system default config path, or - carry an explicit config path and pass `--config`. ## 13. Environment Handling Subprocess environment recommendations: - Pass through required API-key environment variables referenced by `api_key_env`. - Do not pass raw API keys as CLI arguments. - Avoid logging full environment dumps. - Capture stdout and stderr separately. - Use a controlled working directory. - Prefer absolute artifact paths. ## 14. Output Handling For `scriptorium run`: - Use `--out` when Narratio needs durable artifact files. - Without `--out`, artifact content is written to stdout. - Preferred orchestration pattern: always use `--out`, then treat the file as stage output artifact. - Capture stderr for diagnostics. For `scriptorium render`: - Use `--out` to store render diagnostics. - Use `--format json` when tests need to inspect selected profile, effective runtime settings, input hashes, prompt hash, and rendered messages. ## 15. Exit Status and Errors Current CLI behavior (verified from implementation/tests): - `0`: success. - `1`: runtime/parse/config/load/render/generation/IO error. - `2`: run completed but output validation failed (`ValidationFailed`). Additional details: - On `run`, output artifact write happens before exit code selection. If validation fails, artifact may still be written and exit code is `2`. - `stderr` carries both errors and normal run summary output; non-empty stderr alone does not imply failure. - `render` returns `0` on success and `1` on failures. Narratio should treat non-zero exit codes as failed stage execution, but may record generated artifact paths if a run exited `2` and output file exists. ## 16. Recommended Narratio Integration Pattern 1. Build CLI args from Narratio stage configuration. 2. Use subprocess context cancellation/timeout. 3. Pass absolute input paths. 4. Pass `--out` to a session-scoped artifact path. 5. Add `--var` metadata values. 6. Optionally add `--config`. 7. Optionally add `--profile`. 8. Ensure required API-key env vars are present. 9. Run subprocess synchronously. 10. Capture stdout/stderr separately. 11. On success, store output artifact path and invocation metadata in stage artifacts. 12. On failure, store exit code and stderr diagnostics in stage status. ## 17. Suggested Narratio Configuration Shape Illustrative `pipeline.yml` shape: ```yaml scriptorium: binary: scriptorium config_path: /etc/scriptorium/config.yml timeout: 10m render_debug: false artifacts: session_recap: enabled: true prompt_id: dnd.session_recap profile_id: local-quality # optional output_path: artifacts/session_recap.md timeout: 10m render_debug: false # optional artifact override inputs: transcript: source: trimmed_transcript required: true previous_recap: source: previous_session_artifact artifact: session_recap path: "" # optional required: false vars: session_id: true session_date: true campaign_name: true previous_session_id: true output_kind: session_recap ``` The key idea: map Narratio artifact names to prompt ID, optional profile, expected inputs, vars, and output destination. ## 18. Testing Strategy for Narratio Integration - Use `scriptorium render --format json` to verify command construction without LLM calls. - Use dedicated test prompt/profile libraries for integration tests. - Use small fixture transcripts. - Verify missing-input failure behavior. - Verify prompt `default_profile` behavior. - Verify explicit `--profile` override behavior. - Verify `--config` behavior (default and explicit). - Verify output file creation when `--out` is used. - Verify stderr capture on failures. - Avoid real API keys in tests. ## 19. Security and Privacy Notes - Never pass raw API keys on command line. - Do not log full rendered prompts by default; transcripts may contain sensitive content. - Avoid logging prompt content unless explicit debug mode is enabled. - Treat generated artifacts as potentially sensitive. - Use session-scoped, access-controlled output paths. - `api_key_env` names should come from environment management, not embedded secrets. ## 20. Initial D&D Artifact Generation Examples These are examples only. Use prompt IDs from the deployed prompt library. Session recap: ```bash scriptorium run \ --prompt dnd.session_recap \ --input transcript=/work/campaign-7/session-42/transcript.polished.md \ --input glossary=/work/campaign-7/session-42/glossary.yml \ --out /work/campaign-7/session-42/artifacts/session_recap.md ``` Structured events: ```bash scriptorium run \ --prompt dnd.structured_events \ --input transcript=/work/campaign-7/session-42/transcript.polished.md \ --out /work/campaign-7/session-42/artifacts/structured_events.json ``` Glossary suggestions: ```bash scriptorium run \ --prompt dnd.glossary_suggestions \ --input transcript=/work/campaign-7/session-42/transcript.polished.md \ --input previous_recap=/work/campaign-7/session-41/artifacts/session_recap.md \ --out /work/campaign-7/session-42/artifacts/glossary_suggestions.md ``` Player-facing summary: ```bash scriptorium run \ --prompt dnd.player_summary \ --input transcript=/work/campaign-7/session-42/transcript.polished.md \ --input structured_events=/work/campaign-7/session-42/artifacts/structured_events.json \ --out /work/campaign-7/session-42/artifacts/player_summary.md ``` ## 21. Non-Goals Initial Narratio integration should not: - call Scriptorium internal Go packages - use HTTP API as the primary path - expect Scriptorium to read S3 refs directly - make Scriptorium responsible for Narratio stage state - make Scriptorium responsible for notification - require Scriptorium to understand D&D workflow semantics beyond prompt definitions ## 22. Future Extension Notes Possible later extensions: - HTTP API integration - S3 artifact references if Scriptorium adds S3 reader support - richer render diagnostics and policy controls - token budgeting/prompt-size checks - batch execution if Scriptorium later adds batch support