2026-08-10 00:42:44 +00:00
|
|
|
# Internal: Extract Stage
|
|
|
|
|
|
|
|
|
|
## Responsibility
|
|
|
|
|
|
2026-08-29 18:00:22 +00:00
|
|
|
`extract` runs after `render` and before `analyze`. It converts the canonical
|
2026-08-10 00:42:44 +00:00
|
|
|
`narratio.transcript.final_trimmed` JSON into configured Notarius lane artifacts.
|
2026-08-10 02:10:37 +00:00
|
|
|
An omitted or disabled Notarius section makes the stage explicitly self-skip
|
|
|
|
|
with reason `notarius_disabled`, no outputs, and no Notarius runner.
|
2026-08-10 00:42:44 +00:00
|
|
|
|
|
|
|
|
The external protocol is documented in the
|
|
|
|
|
[Notarius integration contract](../integrations/notarius.md). Configuration
|
|
|
|
|
fields belong in [Configuration](../config.md), and physical paths and force
|
|
|
|
|
procedures belong in [Operations](../operations.md).
|
|
|
|
|
|
|
|
|
|
## Lifecycle
|
|
|
|
|
|
|
|
|
|
`internal/stage/extract.go`:
|
|
|
|
|
|
|
|
|
|
1. resolves the final trimmed transcript from the shared artifact catalog;
|
2026-08-29 15:40:23 +00:00
|
|
|
2. resolves every configured prepared reference through the shared
|
|
|
|
|
manifest-authoritative identity resolver before creating run-local output;
|
2026-08-29 16:18:40 +00:00
|
|
|
3. streams each verified reference into an invocation-local snapshot and
|
|
|
|
|
rejects any source change observed while copying;
|
2026-08-30 13:14:33 +00:00
|
|
|
4. fingerprints the byte- and provenance-bearing Notarius invocation evidence,
|
|
|
|
|
including sorted reference identities;
|
2026-08-29 16:18:40 +00:00
|
|
|
5. creates a run-local staging directory and invokes the injected
|
2026-08-10 00:42:44 +00:00
|
|
|
`notarius.Runner`;
|
2026-08-29 16:18:40 +00:00
|
|
|
6. revalidates the reference snapshots, then validates the v2 successful
|
|
|
|
|
receipt, confined index, management documents, configured required lane
|
|
|
|
|
descriptors, validation summaries, and regular payload files;
|
|
|
|
|
7. atomically promotes the complete bundle to its immutable durable location;
|
|
|
|
|
8. records one non-selectable `notarius_index` output and one selectable
|
2026-08-10 00:42:44 +00:00
|
|
|
`notarius_lane` output per configured lane; and
|
2026-08-29 16:18:40 +00:00
|
|
|
9. registers each lane as `narratio.extraction.<output_key>` for downstream
|
2026-08-10 00:42:44 +00:00
|
|
|
Scriptorium and publish resolution.
|
|
|
|
|
|
|
|
|
|
Lane records retain checksum, contract, producer run ID, and Notarius system,
|
|
|
|
|
run, pipeline, and lane provenance. Stage metadata retains the durable bundle
|
|
|
|
|
root, receipt, diagnostic paths, rejection/warning summaries, producing
|
2026-08-10 22:15:53 +00:00
|
|
|
Narratio run ID, the resolved trimmed-input identity, and invocation
|
|
|
|
|
fingerprint. The input identity binds the exact transcript bytes, canonical
|
|
|
|
|
source ID, producer stage/output/run identity, and resolution provenance.
|
2026-08-29 15:40:23 +00:00
|
|
|
Reference metadata contains only selector, source ID, canonical session-relative
|
|
|
|
|
path, checksum, and size; adapter requests receive selector and absolute
|
2026-08-29 16:18:40 +00:00
|
|
|
invocation-local snapshot path, never payload contents. Snapshot bytes must
|
|
|
|
|
match the prepared identity both before and after Notarius runs, so a concurrent
|
|
|
|
|
prepared-file replacement cannot make recorded provenance describe different
|
|
|
|
|
bytes from those supplied to Notarius.
|
2026-09-02 01:01:44 +00:00
|
|
|
Validation completes before the single durable rename, so a rejected result
|
|
|
|
|
cannot expose a partial durable bundle.
|
2026-08-10 00:42:44 +00:00
|
|
|
|
2026-08-10 02:10:37 +00:00
|
|
|
Any executed extraction outcome that replaces a different effective outcome
|
2026-08-29 18:00:22 +00:00
|
|
|
marks succeeded analysis and delivery dependents stale. Render is an independent
|
|
|
|
|
sibling and remains current. Repeating the same disabled self-skip with no
|
|
|
|
|
outputs is stable and does not repeatedly invalidate dependent stages.
|
2026-08-10 02:10:37 +00:00
|
|
|
|
2026-08-10 00:42:44 +00:00
|
|
|
## Resume Validation
|
|
|
|
|
|
2026-08-30 13:14:33 +00:00
|
|
|
Before the focused validator runs, the application compares extract's versioned
|
|
|
|
|
semantic fingerprint. It covers enablement, Notarius pipeline identity, sorted
|
|
|
|
|
reference selector/source mappings, sorted declared output contracts, and each
|
|
|
|
|
canonical `narratio.extraction.<key>` output identity. It excludes executable,
|
|
|
|
|
timeout, working directory, config path, and private Notarius config contents.
|
|
|
|
|
|
|
|
|
|
`internal/stage/extract_resume.go` then permits a skip only when the existing
|
|
|
|
|
stage record still matches the current byte- and provenance-bearing invocation
|
|
|
|
|
evidence. That evidence covers the current direct trimmed-transcript identity,
|
|
|
|
|
sorted prepared-reference identities, pipeline identity, and configured output
|
|
|
|
|
contracts. The same reference helper and transcript identity are resolved again
|
|
|
|
|
for artifact evidence, so changing current transcript bytes, reference bytes,
|
|
|
|
|
or producer identity makes the prior extraction obsolete. Operational runner
|
|
|
|
|
settings do not invalidate otherwise current durable evidence.
|
2026-08-10 00:42:44 +00:00
|
|
|
|
2026-08-29 15:40:23 +00:00
|
|
|
A valid prepared-reference change makes extraction non-resumable. Missing,
|
|
|
|
|
unsafe, or checksum-inconsistent prepared evidence is a hard validation error
|
|
|
|
|
with prepare-force guidance because an immediate extract rerun cannot succeed.
|
|
|
|
|
|
2026-08-10 00:42:44 +00:00
|
|
|
The validator then checks the producing run identity, canonical immutable
|
|
|
|
|
bundle root, path confinement and absence of symlink components, receipt
|
|
|
|
|
identity, exactly one canonical index, the exact configured source set,
|
|
|
|
|
contracts and provenance, regular-file status, and stored checksums. Missing or
|
|
|
|
|
obsolete results are non-resumable and run again; unsafe filesystem conditions
|
|
|
|
|
return an error rather than silently accepting or replacing data.
|
|
|
|
|
|
2026-08-30 13:14:33 +00:00
|
|
|
Neither contract can observe files imported by Notarius configuration, profile
|
|
|
|
|
contents, prompt/module definitions, or other transitive inputs. Operators must
|
|
|
|
|
force extraction after changing any such private input behind a stable
|
|
|
|
|
identifier.
|
2026-08-10 00:42:44 +00:00
|
|
|
|
|
|
|
|
## Failure Behavior
|
|
|
|
|
|
|
|
|
|
Adapter startup, timeout, nonzero exit, receipt decoding, path confinement,
|
2026-08-29 14:41:22 +00:00
|
|
|
index compatibility, inconsistent warning or diagnostic envelopes,
|
|
|
|
|
required-lane rejection or incomplete validation, payload inspection,
|
2026-09-02 01:01:44 +00:00
|
|
|
checksum, or installation errors fail the stage through ordinary manifest
|
2026-08-29 14:41:22 +00:00
|
|
|
transition handling.
|
2026-08-10 00:42:44 +00:00
|
|
|
Stdout receipt and stderr diagnostics remain separate. Downstream stages are
|
|
|
|
|
not given selectable extraction sources unless the complete configured result
|
2026-09-02 01:01:44 +00:00
|
|
|
has passed validation and installation.
|
2026-08-10 00:42:44 +00:00
|
|
|
|
2026-08-10 03:04:20 +00:00
|
|
|
When a replacement attempt begins, the current session-stage record no longer
|
|
|
|
|
advertises payload from the previous success. A failed replacement therefore
|
|
|
|
|
has no current outputs, logs, generated configuration references, or metadata,
|
2026-09-03 04:22:19 +00:00
|
|
|
while the earlier immutable promoted bundle remains available for audit and
|
|
|
|
|
recovery.
|
2026-08-10 03:04:20 +00:00
|
|
|
|
2026-08-10 00:42:44 +00:00
|
|
|
## Implementation And Focused Tests
|
|
|
|
|
|
2026-08-10 02:10:37 +00:00
|
|
|
- Stage execution, selection, and resume validation: `internal/stage/extract.go`,
|
|
|
|
|
`internal/stage/extract_resume.go`,
|
2026-08-30 13:14:33 +00:00
|
|
|
`internal/stage/extract_test.go`,
|
|
|
|
|
`internal/stage/semantic_contracts_delivery.go`
|
2026-08-10 00:42:44 +00:00
|
|
|
- Subprocess boundary: `internal/adapters/notarius/subprocess.go`,
|
|
|
|
|
`internal/adapters/notarius/subprocess_test.go`
|
|
|
|
|
- Catalog hydration: `internal/artifacts/extraction_catalog.go`,
|
|
|
|
|
`internal/artifacts/extraction_catalog_test.go`
|
|
|
|
|
- Composition and downstream behavior: `internal/app/runner_test.go`,
|
|
|
|
|
`internal/stage/analyze_test.go`, `internal/stage/publish_test.go`
|