From 26af27eb52e54c099aa4371412387eecc022a84c Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 6 Jul 2026 16:07:16 +0000 Subject: [PATCH] docs: document final artifact sealing contract Co-authored-by: Sara Loera --- docs/docs.json | 3 +- docs/explanation/artifacts.mdx | 74 +++++++++++++++-- docs/reference/final.mdx | 141 +++++++++++++++++++++++++++++++++ 3 files changed, 212 insertions(+), 6 deletions(-) create mode 100644 docs/reference/final.mdx diff --git a/docs/docs.json b/docs/docs.json index 955c7ba..df6db55 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -95,7 +95,8 @@ "pages": [ "reference/events", "reference/state", - "reference/summary" + "reference/summary", + "reference/final" ] }, { diff --git a/docs/explanation/artifacts.mdx b/docs/explanation/artifacts.mdx index e27739f..11f82dd 100644 --- a/docs/explanation/artifacts.mdx +++ b/docs/explanation/artifacts.mdx @@ -1,6 +1,6 @@ --- title: "Artifacts" -description: "Understanding the files Noēsis produces: summary.json, state.json, events.jsonl, and more." +description: "Understanding the files Noēsis produces: summary.json, state.json, events.jsonl, final.json, and more." --- Every Noēsis episode produces a set of structured artifacts that capture the complete cognitive trace. These files enable replay, debugging, auditing, and analysis. @@ -14,15 +14,22 @@ Every Noēsis episode produces a set of structured artifacts that capture the co events.jsonl # cognitive event timeline with lineage summary.json # metrics and KPIs (insight.metrics) state.json # plan, beliefs, memory, outcomes + final.json # terminal seal marker manifest.json # SHA-256 catalog + optional HMAC learn.jsonl # learning signals (optional) prompts.jsonl # prompt provenance (opt-in, ADR-005) + checkpoints/ # checkpoint anchors for paused runs ``` **Episode IDs** use ULID format (monotonic, sortable, 48-bit timestamp + 80-bit entropy). **Directive and governance IDs** use deterministic UUIDv5 for reproducible lineage tracking. +Terminal runs seal with both `final.json` and `manifest.json`. Paused or +interrupted runs are intentionally unsealed until they continue or terminate; +expect `events.jsonl`, `state.json`, `learn.jsonl`, and checkpoint files before +the terminal artifacts appear. + ## summary.json The summary captures episode outcomes, metrics, and cross-references. @@ -334,6 +341,55 @@ noesis events ep_abc123 --phase act noesis events ep_abc123 -j | jq '.[] | select(.phase == "plan")' ``` +## final.json + +`final.json` is the terminal seal marker for a run. If it exists, Noesis has +finished finalization for the run and lifecycle writes such as `interrupt`, +`checkpoint`, and `resume_run` are rejected. + +### Schema + +```json +{ + "schema_version": "final/2.0.0", + "episode_id": "ep_2024_abc123_s0", + "process_id": "proc_abc123", + "run_index": 1, + "finalized_at": "2024-01-15T10:30:05Z", + "outcome": "success", + "verification_status": "verified" +} +``` + +| Field | Description | +| --- | --- | +| `schema_version` | Final marker schema (`final/2.0.0`) | +| `episode_id` | Run or episode ID being sealed | +| `process_id` | Process identity that owns the run | +| `run_index` | One-based run number within that process | +| `finalized_at` | ISO 8601 finalization timestamp | +| `outcome` | Terminal outcome (`success`, `failed`, `vetoed`, `cancelled`, `interrupted`, `error`) | +| `verification_status` | Verification class (`verified`, `unverified`, `not_applicable`) | + +### Sealing order + +Noesis writes `final.json` before `manifest.json`, then writes the manifest with +`final.json` included in its file list. If manifest writing fails, Noesis removes +`final.json` so the run is not incorrectly marked sealed. + + +Treat a run as sealed only when `final.json` exists and `manifest.json` includes +an entry for `final.json`. + + +### Paused runs + +Approval pauses and pause-on-veto flows emit `run.interrupt` and +`run.checkpoint` events, then write checkpoint anchors under +`checkpoints//checkpoint.json`. These runs remain unsealed: no +`final.json` or `manifest.json` is required until the run continues to a terminal +outcome. + ## manifest.json The manifest provides integrity verification for all artifacts with SHA-256 hashes and optional signatures. @@ -365,6 +421,11 @@ The manifest provides integrity verification for all artifacts with SHA-256 hash | `files` | Array of files with `name`, `sha256`, `size_bytes`, `kind` (`summary`, `state`, `events`, `learn`, `attachment`, `custom`) | | `signature` | Optional signature block with algorithm, key ID, value, timestamp | +`summary.json`, `state.json`, `events.jsonl`, and `learn.jsonl` are tracked by +default when present. Other files in the run directory, including `final.json` +and checkpoint files, are included as attachments unless explicitly tracked with +a narrower kind. + ### Artifact immutability guarantees All artifacts are written atomically using this pattern: @@ -389,16 +450,16 @@ def verify_manifest(episode_dir: Path) -> bool: with open(manifest_path) as f: manifest = json.load(f) - for filename, info in manifest["files"].items(): - file_path = episode_dir / filename + for info in manifest["files"]: + file_path = episode_dir / info["name"] # Check size - if file_path.stat().st_size != info["size"]: + if file_path.stat().st_size != info["size_bytes"]: return False # Check hash with open(file_path, "rb") as f: - actual_hash = hashlib.sha256(f.read()).hexdigest() + actual_hash = f"sha256:{hashlib.sha256(f.read()).hexdigest()}" if actual_hash != info["sha256"]: return False @@ -535,4 +596,7 @@ store.vacuum() # Remove episodes older than 14 days Complete summary schema documentation. + + Complete final.json sealing contract. + diff --git a/docs/reference/final.mdx b/docs/reference/final.mdx new file mode 100644 index 0000000..46c6c70 --- /dev/null +++ b/docs/reference/final.mdx @@ -0,0 +1,141 @@ +--- +title: "Final schema" +description: "Complete reference for the Noesis final.json sealing marker." +--- + +The `final.json` artifact is the terminal marker for a run. Its presence means +Noesis finished finalization, wrote the final contract, and then wrote +`manifest.json` with `final.json` included in the manifest file list. + +Current final schema version: `final/2.0.0` ([JSON schema](/schema/final/2.0.0.json)). + +## Schema overview + +```json +{ + "schema_version": "final/2.0.0", + "episode_id": "ep_2024_abc123_s0", + "process_id": "proc_a1b2c3", + "run_index": 1, + "finalized_at": "2024-01-15T10:30:05Z", + "outcome": "success", + "verification_status": "verified" +} +``` + +## Root fields + + +Final artifact schema. Currently `"final/2.0.0"`. + + + +Run or episode identifier for the artifact directory being sealed. + + + +Process identity that owns this run. Finalization requires this value so sealed +artifacts can be tied back to the process registry. + + + +One-based run number within the process. + + + +ISO 8601 timestamp when `final.json` was written. + + + +Terminal outcome class. Allowed values are `"success"`, `"failed"`, +`"vetoed"`, `"cancelled"`, `"interrupted"`, and `"error"`. + + + +Verification class for the terminal outcome. Allowed values are `"verified"`, +`"unverified"`, and `"not_applicable"`. + + +## Outcome mapping + +The current core finalization path maps runtime and verification outcomes into +the final contract as follows: + +| Runtime condition | `outcome` | `verification_status` | +| --- | --- | --- | +| Adapter succeeded and verification assertions passed | `success` | `verified` | +| Adapter succeeded and no verification was provided | `success` | `unverified` | +| Adapter succeeded but verification assertions failed | `failed` | `verified` | +| Adapter errored or was skipped | `error` | `not_applicable` | +| Terminal state was explicitly vetoed | `vetoed` | `not_applicable` | + +`cancelled` and `interrupted` are part of the schema's terminal outcome +vocabulary. Current pause/checkpoint flows keep interrupted runs unsealed until +they continue or terminate. + +## Sealing lifecycle + +Terminal finalization uses this order: + +1. Write `summary.json`, `state.json`, `learn.jsonl` when applicable, and other + runtime artifacts. +2. Write `final.json`. +3. Write `manifest.json`, which includes `final.json`. + +If manifest writing fails after `final.json` is written, Noesis removes +`final.json` before raising the error. A run should not be treated as sealed +unless both `final.json` and `manifest.json` are present and the manifest lists +the final marker. + + +Once `final.json` exists, lifecycle mutations such as `interrupt`, `checkpoint`, +`resume`, and `resume_run` are rejected with `RunSealedError`. + + +## Paused and interrupted runs + +Paused approval flows are intentionally unsealed: + +- `run.interrupt` and `run.checkpoint` are recorded in `events.jsonl` +- checkpoint files are written under `checkpoints//checkpoint.json` +- `run.state_projection.payload.links` includes non-terminal links such as + `events` and `learn` +- `summary.json`, `manifest.json`, and `final.json` are not guaranteed until the + run continues to a terminal state + +Use `resume_run(...)` after approval to continue the same run ID. When +continuation reaches a terminal outcome, Noesis emits terminal projection +evidence and seals the run. + +## Operational checks + +```bash +# Confirm a run is sealed. +test -f .noesis/episodes//final.json +test -f .noesis/episodes//manifest.json + +# Inspect the final contract. +jq '{episode_id, process_id, run_index, outcome, verification_status}' \ + .noesis/episodes//final.json + +# Confirm the manifest covers final.json. +jq '.files[] | select(.name == "final.json")' \ + .noesis/episodes//manifest.json +``` + +## Related references + + + + How final markers fit into the episode artifact bundle. + + + Lifecycle APIs and common sealed-run errors. + + + Runtime lifecycle events for interrupts, checkpoints, resumes, and state projections. + + + Terminal and non-terminal state projection links. + +