Validate portable workspace identifiers

This commit is contained in:
2026-08-10 17:35:52 +00:00
parent 0b40cf8026
commit 1dccf5f140
31 changed files with 490 additions and 48 deletions

View File

@@ -38,6 +38,15 @@ If local session discovery fails and a `session_id` is known, Narratio attempts
using configured object storage.
### Identity segments
Campaign IDs (`campaign_id` and `default_campaign_id`), session IDs, previous
session IDs, and Narratio run IDs are opaque portable segments. They must use
only ASCII letters, digits, `.`, `_`, and `-`; empty values, `.`/`..`, path
separators, drive forms, whitespace, control characters, and non-ASCII text are
rejected. Narratio does not trim or rewrite these values. Existing manifests or
remote state with an unsafe legacy identity must be migrated before use.
## Validation and Merge Rules
- YAML decode is strict (`KnownFields(true)`): unknown fields fail load.
@@ -272,7 +281,7 @@ For each artifact input `pipeline.scriptorium.artifacts.<name>.inputs.<input_nam
| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| `campaign_id` | string | Yes | canonical campaign identity |
| `campaign_id` | string | Yes | canonical opaque campaign identity |
| `session_template_file` | string | No | used by `session init` when set |
| `inputs.speakers_file` | string | Yes | stable input default |
| `inputs.autocorrect_file` | string | Yes | stable input default |
@@ -284,9 +293,9 @@ For each artifact input `pipeline.scriptorium.artifacts.<name>.inputs.<input_nam
| Field | Type | Required in session file | Notes |
| --- | --- | --- | --- |
| `session_id` | string | Yes | must match CLI session target when provided |
| `previous_session_id` | string | No | must not equal `session_id` |
| `campaign` | string | No | filled from `campaign_id` during resolve if omitted |
| `session_id` | string | Yes | opaque identity; must match CLI session target when provided |
| `previous_session_id` | string | No | opaque identity; must not equal `session_id` |
| `campaign` | string | No | opaque identity; filled from `campaign_id` during resolve if omitted |
| `date` | string | No | metadata |
| `title` | string | No | metadata |
| `inputs.speakers_file` | string | No | overrides campaign stable input |

View File

@@ -30,9 +30,11 @@ and content validator. The focused stage documents own their input/output flow;
- extraction source ID format: `narratio.extraction.<output_key>`
- previous-session source ID format: `narratio.previous_session.artifact.<artifact_key>`
All formats are validated by strict source-policy rules. Extraction sources are
registered only from `pipeline.notarius.outputs`; the Notarius index has no
selectable source ID.
All formats are validated by strict source-policy rules. Configured artifact and
extraction keys use `^[a-z][a-z0-9_]*$`; source parsers never normalize an
unrecognized token into a valid source. Extraction sources are registered only
from `pipeline.notarius.outputs`; the Notarius index has no selectable source
ID.
## Runtime Catalog
@@ -131,6 +133,12 @@ Caller policy is intentionally outside artifacts helpers:
- spool/cache paths;
- S3 session/run/current-state key layout.
Campaign, session, and Narratio run IDs are validated as portable opaque
segments at configuration and artifact boundaries before they can be used in a
workspace or S3 namespace. Previous-artifact destinations remain typed,
multi-segment relative paths and are confined beneath `previous/artifacts`; they
are not treated as opaque identifiers.
See [Workspace Internals](workspace.md) for how callers consume local helpers
and [Operations](../operations.md#local-state-layout) for the authoritative
physical layout.

View File

@@ -17,6 +17,11 @@ Explain the session-progress and invocation-audit models implemented by
- durable `artifacts` records
- per-stage `stages` map
Session, campaign, and run identities in local and downloaded manifests must be
portable opaque segments. Unsafe legacy identities are rejected with migration
guidance rather than being normalized into a different workspace or remote
namespace.
The model admits these stage states:
- `pending`

View File

@@ -17,7 +17,7 @@ All stages are pending when this plan is created.
| Stage | Summary | Primary findings | Status |
| ---: | --- | --- | --- |
| 1 | Align data classification and group workspace modes | RSK-004 | Completed |
| 2 | Enforce safe identifiers and fuzz path/source contracts | COR-002, TST-013 | Pending |
| 2 | Enforce safe identifiers and fuzz path/source contracts | COR-002, TST-013 | Completed |
| 3 | Consolidate crash-durable atomic file replacement | RSK-002, DUP-001, DUP-005 | Pending |
| 4 | Add confined destination and download/install capabilities | COR-003, DUP-003, TST-003 | Pending |
| 5 | Confine recursive cleanup and replace sentinel locks | RSK-003 | Pending |