Reconcile lifecycle documentation

This commit is contained in:
2026-08-10 23:18:29 +00:00
parent feba7b9d74
commit 801adb385d
9 changed files with 137 additions and 19 deletions

View File

@@ -279,6 +279,15 @@ For each `pipeline.scriptorium.artifacts.<name>`:
Narratio adds `session_id=narratio-session-<session_id>` to every Scriptorium request for sticky upstream LLM routing. If an artifact config sets `vars.session_id`, Narratio replaces that value before invoking Scriptorium. Use a different variable name if a prompt needs the raw Narratio session ID as content.
Without `--artifacts`, analyze executes enabled configured artifacts. With an
explicit `--artifacts` list, the exact named configured artifacts are the
one-invocation execution set even if their `enabled` values are false; the list
does not automatically include dependencies. Named artifacts must therefore be
configured with valid executable fields, and their configured dependencies must
already be available to analyze. This override affects analyze planning only;
publish uses the list only to filter configured
`narratio.artifact.<name>` output rules.
For each artifact input `pipeline.scriptorium.artifacts.<name>.inputs.<input_name>`:
| Field | Type | Required | Rule |

View File

@@ -45,6 +45,15 @@ ID.
- `available`: local file exists and validates;
- `provenance`: availability source.
Configured definitions are always registered. Without an explicit selection,
the effective analyze set contains enabled definitions. With `--artifacts`, the
exact named configured definitions become the effective set for that invocation,
regardless of their `enabled` value; dependencies are not added implicitly.
Availability is separate from executability: a non-executable configured output
may be reused from a canonical non-empty file, while an executable definition
is generated by analyze. Extraction entries are registered from configuration
and become available only after compatible extraction evidence is hydrated.
Current provenance values:
- `generated.current_analyze_run`
@@ -81,6 +90,10 @@ Previous-session sources (`narratio.previous_session.artifact.*`):
- prefer manifest-backed previous-input paths;
- fallback to existing previous-cache filesystem paths.
Source absence is evaluated by the consuming artifact input. An optional input
is omitted from that invocation; a required input fails resolution. This is
separate from a stage's lifecycle outcome.
Validation by content type:
- transcript JSON built-ins: JSON with top-level `segments` array;

View File

@@ -8,13 +8,15 @@ Execute selected configured Scriptorium artifacts in dependency order and materi
- configured artifacts from `pipeline.scriptorium.artifacts`
- optional selected artifact keys supplied through the stage environment
- built-in/configured/previous-session source references in artifact inputs
- built-in, configured, extraction, and previous-session source references in
artifact inputs
Supported source families:
- built-ins: `narratio.transcript.*`, `narratio.bounds.session`
- prepared stable inputs: `narratio.input.players`, `narratio.input.party`,
`narratio.input.glossary`
- configured artifacts: `narratio.artifact.<key>`
- extraction lanes: `narratio.extraction.<key>`
- previous-session cache: `narratio.previous_session.artifact.<key>`
## Outputs
@@ -24,11 +26,22 @@ Supported source families:
## Key Behavior
- skips with metadata when Scriptorium config is missing or no executable artifacts remain.
- builds runtime artifact catalog (built-ins + configured artifacts).
- when Scriptorium is absent or no configured artifact is executable, completes
successfully with no outputs and records explanatory metadata. This is not an
explicit self-skip: both manifests record success, satisfy publish's
prerequisite, and an ordinary later run reuses the result until forced.
- builds a runtime artifact catalog containing built-ins, configured artifacts,
and configured extraction lanes. Extraction availability is hydrated only
from compatible successful extraction evidence.
- uses enabled configured artifacts by default. An explicit `--artifacts`
selection is a one-invocation override: it makes exactly the named configured
artifacts executable even when disabled, and does not automatically include
dependencies. A selected artifact's dependencies must instead already be
available to the catalog.
- marks non-executable configured artifacts as reusable when output files already exist.
- validates selected artifact dependency order (cycle-safe topo ordering).
- resolves required/optional inputs per artifact source definition.
- omits an unavailable optional input; an unavailable required input fails.
- resolves prepared stable input sources from `inputs/*.yml` materialized by `prepare`.
- resolves previous-session sources from local `previous/` cache only.
- runs optional render-debug, then artifact execution.

View File

@@ -25,7 +25,10 @@ Exact remote placement and the operator workflow belong in
## Key Behavior
- stage can self-skip when publish disabled or run upload disabled.
- when publishing or run upload is disabled, completes successfully with no
outputs and records explanatory metadata. This is not an explicit self-skip:
both manifests record success, and an ordinary later run reuses that result
until publish is forced.
- validates prerequisite stage success and object-store availability.
- derives a deterministic run-archive allowlist from the validated run
`manifest.json`: declared run-local outputs, logs, generated configs, and the

View File

@@ -20,7 +20,9 @@ Render Markdown transcript artifacts from normalized JSON transcripts via Seriat
- resolves inputs manifest-first, then canonical fallback.
- writes run-local outputs first, then materializes canonical session outputs.
- records input provenance, output paths, adapter metadata, logs, and generated config refs.
- skips with stage metadata when `pipeline.render.enabled=false`.
- when `pipeline.render.enabled=false`, completes successfully with no outputs
and records explanatory metadata. This is not an explicit self-skip: both
manifests record success, and enabling render later requires a forced run.
## Failure Semantics

View File

@@ -92,6 +92,14 @@ Execution rules:
repeated self-skip with the same reason and no outputs is stable and does not
perpetually rerun downstream work.
An explicit self-skip is a durable `skipped` stage outcome that later runs
reconsider. It differs from successful no-output execution: disabled `render`
and `publish`, and absent or no-executable `analyze`, record `succeeded` with
metadata and no outputs. Ordinary later runs reuse those successful results;
force the affected stage after enabling or configuring it. Optional artifact
inputs are omitted only from the consuming artifact invocation and do not make
the stage self-skip.
Single-stage execution:
```bash

View File

@@ -12,7 +12,7 @@ into this document. The line ranges below are stable references to the evidence
and acceptance criteria that the implementing agent must read for each stage.
This plan owns remediation progress; a separate `audit.md` tracker is not needed.
All stages are pending when this plan is created.
All stages begin pending when this plan is created.
| Stage | Summary | Primary findings | Status |
| ---: | --- | --- | --- |
@@ -36,18 +36,18 @@ All stages are pending when this plan is created.
| 18 | Serialize restore transitions and make restored paths portable | RSK-006, RSK-008 | Completed |
| 19 | Bind audio cache reuse to remote object identity | RSK-007 | Completed |
| 20 | Unify previous-source readiness and eliminate duplicate transfers | COR-010, EFF-001 | Completed |
| 21 | Tighten configuration parsing, values, and expectations | COR-012COR-015, TST-011, TST-014 | Pending |
| 22 | Make product configuration truthful and own remote temp files | COR-024, RSK-009, ARC-004 | Pending |
| 23 | Stream WhisperX uploads and make the adapter race-safe | COR-016, EFF-002, TST-001 | Pending |
| 24 | Correct prepare/transcribe transition semantics | COR-017COR-019, TST-008 | Pending |
| 25 | Enforce output-path authority and shared singleton resolution | ARC-006, DUP-006 | Pending |
| 26 | Centralize typed extraction-bundle evidence | DUP-007 | Pending |
| 27 | Bind extraction reuse to direct transcript identity | COR-020, TST-009 | Pending |
| 28 | Establish one effective artifact set and catalog bootstrap | COR-022, ARC-007, DUP-008 | Pending |
| 29 | Make analyze resolution typed, optional, actionable, and deterministic | COR-021, COR-023, RSK-015, SIM-003, TST-010 | Pending |
| 30 | Remove misleading contracts and align Audita ownership | ARC-001, ARC-005, SIM-004, COM-003, COM-006 | Pending |
| 31 | Enforce CI validation and streamline the assembled test suite | TST-012, TST-015 | Pending |
| 32 | Reconcile lifecycle/analyze documentation and close the remediation | COM-002, COM-005 | Pending |
| 21 | Tighten configuration parsing, values, and expectations | COR-012COR-015, TST-011, TST-014 | Completed |
| 22 | Make product configuration truthful and own remote temp files | COR-024, RSK-009, ARC-004 | Completed |
| 23 | Stream WhisperX uploads and make the adapter race-safe | COR-016, EFF-002, TST-001 | Completed |
| 24 | Correct prepare/transcribe transition semantics | COR-017COR-019, TST-008 | Completed |
| 25 | Enforce output-path authority and shared singleton resolution | ARC-006, DUP-006 | Completed |
| 26 | Centralize typed extraction-bundle evidence | DUP-007 | Completed |
| 27 | Bind extraction reuse to direct transcript identity | COR-020, TST-009 | Completed |
| 28 | Establish one effective artifact set and catalog bootstrap | COR-022, ARC-007, DUP-008 | Completed |
| 29 | Make analyze resolution typed, optional, actionable, and deterministic | COR-021, COR-023, RSK-015, SIM-003, TST-010 | Completed |
| 30 | Remove misleading contracts and align Audita ownership | ARC-001, ARC-005, SIM-004, COM-003, COM-006 | Completed |
| 31 | Enforce CI validation and streamline the assembled test suite | TST-012, TST-015 | Completed |
| 32 | Reconcile lifecycle/analyze documentation and close the remediation | COM-002, COM-005 | Completed |
## Governing decisions
@@ -1082,6 +1082,8 @@ documentation/example checks, verify clean generated/example state, inspect the
final diff and repository status, and mark this stage complete only when no
required remediation remains.
**Status:** Completed.
## Finding traceability inventory
This inventory assigns exactly one primary implementation stage to each confirmed

View File

@@ -436,7 +436,7 @@ Diagnostics:
```bash
ls -la /path/to/secrets_dir
env | grep -E 'OBJECT_STORAGE|AWS|AUDITA|SCRIPTORIUM'
env | sed 's/=.*//' | grep -E 'OBJECT_STORAGE|AWS|AUDITA|SCRIPTORIUM'
```
Safe fix:

View File

@@ -5,6 +5,7 @@ import (
"os"
"path/filepath"
"regexp"
"strconv"
"strings"
"testing"
@@ -65,6 +66,26 @@ func TestReleaseWorkflowRequiresValidation(t *testing.T) {
}
}
func TestRoadmapTraceabilityOwnersAreComplete(t *testing.T) {
root := repositoryRoot(t)
data, err := os.ReadFile(filepath.Join(root, "docs", "roadmap", "implementation.md"))
if err != nil {
t.Fatalf("read implementation roadmap: %v", err)
}
statuses := roadmapSummaryStatuses(t, string(data))
checked := 0
for _, owner := range roadmapTraceabilityOwners(t, string(data)) {
checked++
if statuses[owner] != "Completed" {
t.Errorf("traceability owner %d has status %q, want Completed", owner, statuses[owner])
}
}
if checked == 0 {
t.Fatal("roadmap traceability inventory has no owners")
}
}
func repositoryRoot(t *testing.T) string {
t.Helper()
root, err := filepath.Abs(filepath.Join("..", ".."))
@@ -124,6 +145,53 @@ func relativeToRoot(root, path string) string {
return relative
}
func roadmapSummaryStatuses(t *testing.T, document string) map[int]string {
t.Helper()
statuses := map[int]string{}
for _, line := range strings.Split(document, "\n") {
fields := strings.Split(line, "|")
if len(fields) != 6 {
continue
}
owner, err := strconv.Atoi(strings.TrimSpace(fields[1]))
if err != nil {
continue
}
statuses[owner] = strings.TrimSpace(fields[4])
}
if len(statuses) == 0 {
t.Fatal("roadmap summary has no status entries")
}
return statuses
}
func roadmapTraceabilityOwners(t *testing.T, document string) []int {
t.Helper()
const inventoryHeading = "## Finding traceability inventory"
const nextHeading = "## Open Questions"
start := strings.Index(document, inventoryHeading)
if start < 0 {
t.Fatal("roadmap traceability inventory is missing")
}
inventory := document[start+len(inventoryHeading):]
if end := strings.Index(inventory, nextHeading); end >= 0 {
inventory = inventory[:end]
}
owners := []int{}
for _, line := range strings.Split(inventory, "\n") {
fields := strings.Split(line, "|")
if len(fields) != 4 {
continue
}
owner, err := strconv.Atoi(strings.TrimSpace(fields[2]))
if err == nil {
owners = append(owners, owner)
}
}
return owners
}
type woodpeckerWorkflow struct {
Steps map[string]woodpeckerStep `yaml:"steps"`
}