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 |