diff --git a/docs/releases/README.md b/docs/releases/README.md index f747f90..c553357 100644 --- a/docs/releases/README.md +++ b/docs/releases/README.md @@ -11,6 +11,7 @@ See the [release procedure](../release.md) for creating a candidate and tag. When asynchronous publication succeeds, the corresponding Gitea release is the canonical source for downloadable binaries and checksums. +- [v3.1.0](v3.1.0.md) - [v3.0.0](v3.0.0.md) - [v2.2.1](v2.2.1.md) - [v2.2.0](v2.2.0.md) diff --git a/docs/releases/v3.1.0.md b/docs/releases/v3.1.0.md new file mode 100644 index 0000000..4692752 --- /dev/null +++ b/docs/releases/v3.1.0.md @@ -0,0 +1,40 @@ +# Narratio v3.1.0 + +This minor release adds explicit provider-credential forwarding to Scriptorium +for trim bounds generation and artifact analysis. + +## Compatibility and upgrade + +Existing pipelines remain valid. An omitted, null, or empty +`pipeline.scriptorium.credentials` list continues to forward no provider keys. +When Scriptorium needs a credential, provision its environment variable through +Narratio's existing environment or secrets-directory mechanism and list the +exact name in the pipeline, for example: + +```yaml +scriptorium: + credentials: [OPENROUTER_API_KEY] +``` + +Selected references must resolve to nonempty values when Narratio loads the +pipeline, even if the current command will not run Scriptorium. A Narratio +overlay replaces the complete list, and `[]` clears it. After correcting a +failed trim or analysis invocation, retry normally; successful work need not be +forced solely because a credential was added or rotated. See +[Scriptorium credentials](../config.md#scriptorium-credentials) and the +[401 troubleshooting guide](../troubleshooting.md#scriptorium-returns-http-401-during-trim-or-analyze). + +## Changes + +- Forward selected, already-resolved credential names and values to Scriptorium + for trim, analysis, character-family generation, and render-debug calls. + Scriptorium still owns provider and profile selection; Narratio does not add + a model-request `--api-key-env` override. +- Register selected values for captured subprocess-output and failure-diagnostic + redaction. Inspection and invocation metadata contain credential names, never + their values. This protection does not scan files Scriptorium writes directly. +- Reuse the credential-forwarding boundary shared with Audita and Notarius. + Retire the completed Scriptorium credential-forwarding bug report from the + source roadmap; its history remains in Git. + +[COPYRIGHT](https://gitea.maximumdirect.net/eric/narratio/src/tag/v3.1.0/COPYRIGHT) | [LICENSE](https://gitea.maximumdirect.net/eric/narratio/src/tag/v3.1.0/LICENSE) | [ATTRIBUTION](https://gitea.maximumdirect.net/eric/narratio/src/tag/v3.1.0/docs/oss/attribution.md) diff --git a/docs/roadmap/bug-report-trim.yml b/docs/roadmap/bug-report-trim.yml deleted file mode 100644 index b599869..0000000 --- a/docs/roadmap/bug-report-trim.yml +++ /dev/null @@ -1,90 +0,0 @@ -title: Scriptorium credentials are not forwarded during trim bounds generation -status: implemented; release pending -resolution: >- - Scriptorium now accepts credentials using the same resolved-secret forwarding - and redaction helper as Audita and Notarius. Both trim and analyze, including - render-debug calls, forward the selected names without provider overrides. - See docs/config.md for the current configuration contract. Consumer Ansible - role exposure and dependency-pin updates remain downstream follow-up work. -reported_on: "2026-09-29" -audience: Narratio maintainers - -consumer_context: >- - The rakestraw.dnd Ansible collection deploys Narratio v3.0.0 and - Scriptorium v0.15.0. The suite provisions credentials through Narratio's - existing secrets mechanism. An operator deployed the suite to pipeline-dnd - and encountered an authentication failure while generating session bounds. - -observed_behavior: - stage: trim - prompt: dnd.session_bounds - original_error: |- - time=2026-09-29T17:33:17.399Z level=INFO msg="stage failed" stage=trim error="trim: scriptorium bounds generation failed: run scriptorium artifact (binary=\"/usr/local/bin/scriptorium\"): command failed with exit code 1 (executable=\"/usr/local/bin/scriptorium\" args=[run --prompt dnd.session_bounds --config /usr/local/etc/scriptorium/config.yml --input transcript=/var/lib/narratio/work/centaurs/2026-09-20/transcripts/final.json --var session_id=narratio-session-2026-09-20 --timeout 10m0s --out /var/lib/narratio/work/centaurs/2026-09-20/runs/20260929T173314Z-a5aa9d26/trim/outputs/artifacts/session_bounds.json] cwd=\"\" timeout=10m0s exit_code=1 timed_out=false canceled=false stdout_log=\"/var/lib/narratio/work/centaurs/2026-09-20/runs/20260929T173314Z-a5aa9d26/trim/logs/scriptorium.bounds.stdout.log\" stderr_log=\"/var/lib/narratio/work/centaurs/2026-09-20/runs/20260929T173314Z-a5aa9d26/trim/logs/scriptorium.bounds.stderr.log\" stderr_tail=\"run error: failed to generate output: provider returned HTTP status 401\"): exit status 1" - -suspected_root_cause: - summary: >- - Narratio loads credentials but does not forward OPENROUTER_API_KEY to - Scriptorium. Its subprocess environment is filtered, and the trim request - does not select a credential for explicit forwarding. No public Scriptorium - credential-list setting exists to let the consumer supply that selection. - evidence_from_v3_0_0: - - file: internal/adapters/subprocess/diagnostics.go - observation: >- - buildChildEnvironment inherits only allowlisted names plus explicit - overrides. OPENROUTER_API_KEY is not an inherited name. - - file: internal/adapters/scriptorium/subprocess.go - observation: >- - credentialEnvironment forwards a key only when APIKeyEnv is nonempty. - An empty selection produces no credential environment override. - - file: internal/stage/trim.go - observation: The bounds RunArtifactRequest does not populate APIKeyEnv. - - file: internal/stage/analyze_artifact_execution.go - observation: >- - The analyze RunArtifactRequest also leaves APIKeyEnv unset, so the - same gap potentially affects artifact and artifact-family generation. - - file: docs/config.md - observation: >- - Audita and Notarius expose credential lists; Scriptorium has no - equivalent public field. - confidence_and_limits: >- - The forwarding gap is established by source inspection and is consistent - with the reported failure. The deployed host and credential validity were - not independently inspected. HTTP 401 alone does not distinguish a missing - credential from an invalid one. No live provider request was made during - diagnosis. Exporting a key into Narratio's environment alone does not - overcome the child-environment filter. - -proposed_configuration_addition: - status: implemented; awaiting downstream release adoption - field: pipeline.scriptorium.credentials - example: | - pipeline: - scriptorium: - credentials: - - OPENROUTER_API_KEY - desired_behavior: - - >- - Accept a list of credential environment-variable names, analogous to - pipeline.audita.credentials and pipeline.notarius.credentials. Store - reference names, not secret values, in ordinary configuration. - - >- - Resolve the listed names through Narratio's existing environment and - secrets bootstrap behavior, retaining its existing precedence. - - >- - Make the selected credentials available to Scriptorium for both trim - bounds generation and analyze artifact/family generation. Scriptorium - retains ownership of provider and profile selection. - - >- - Support provider-specific names without hard-coding OpenRouter as the - only provider or requiring a separate credential setting for each stage. - consumer_follow_up: >- - After an upstream release, expose the field in the standalone Narratio - Ansible role, select OPENROUTER_API_KEY in the D&D pipeline defaults, and - update the coordinated role/collection dependency pins. Existing credential - provisioning can remain unchanged. - -scope: >- - This report requests an operator-facing credential-forwarding fix, not a - particular internal implementation. It does not request a wrapper executable, - an Ansible-managed parallel credential loader, or changes to Scriptorium's - provider/profile contracts.