Report missing Scriptorium credential forwarding

This commit is contained in:
2026-09-29 17:40:35 +00:00
parent d53a64650b
commit 9389f69eb0

View File

@@ -0,0 +1,84 @@
title: Scriptorium credentials are not forwarded during trim bounds generation
status: reported
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: proposed; not currently supported
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.