Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@
"pages": [
"reference/events",
"reference/state",
"reference/summary"
"reference/summary",
"reference/final"
]
},
{
Expand Down
74 changes: 69 additions & 5 deletions docs/explanation/artifacts.mdx
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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
```

<Info>
**Episode IDs** use ULID format (monotonic, sortable, 48-bit timestamp + 80-bit entropy). **Directive and governance IDs** use deterministic UUIDv5 for reproducible lineage tracking.
</Info>

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.
Expand Down Expand Up @@ -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.

<Tip>
Treat a run as sealed only when `final.json` exists and `manifest.json` includes
an entry for `final.json`.
</Tip>

### Paused runs

Approval pauses and pause-on-veto flows emit `run.interrupt` and
`run.checkpoint` events, then write checkpoint anchors under
`checkpoints/<checkpoint_id>/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.
Expand Down Expand Up @@ -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:
Expand All @@ -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
Expand Down Expand Up @@ -535,4 +596,7 @@ store.vacuum() # Remove episodes older than 14 days
<Card title="Summary reference" icon="file" href="/reference/summary">
Complete summary schema documentation.
</Card>
<Card title="Final reference" icon="lock" href="/reference/final">
Complete final.json sealing contract.
</Card>
</CardGroup>
141 changes: 141 additions & 0 deletions docs/reference/final.mdx
Original file line number Diff line number Diff line change
@@ -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

<ResponseField name="schema_version" type="string" required>
Final artifact schema. Currently `"final/2.0.0"`.
</ResponseField>

<ResponseField name="episode_id" type="string" required>
Run or episode identifier for the artifact directory being sealed.
</ResponseField>

<ResponseField name="process_id" type="string" required>
Process identity that owns this run. Finalization requires this value so sealed
artifacts can be tied back to the process registry.
</ResponseField>

<ResponseField name="run_index" type="integer" required>
One-based run number within the process.
</ResponseField>

<ResponseField name="finalized_at" type="string" required>
ISO 8601 timestamp when `final.json` was written.
</ResponseField>

<ResponseField name="outcome" type="string" required>
Terminal outcome class. Allowed values are `"success"`, `"failed"`,
`"vetoed"`, `"cancelled"`, `"interrupted"`, and `"error"`.
</ResponseField>

<ResponseField name="verification_status" type="string" required>
Verification class for the terminal outcome. Allowed values are `"verified"`,
`"unverified"`, and `"not_applicable"`.
</ResponseField>

## 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.

<Warning>
Once `final.json` exists, lifecycle mutations such as `interrupt`, `checkpoint`,
`resume`, and `resume_run` are rejected with `RunSealedError`.
</Warning>

## 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_id>/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/<episode_id>/final.json
test -f .noesis/episodes/<episode_id>/manifest.json

# Inspect the final contract.
jq '{episode_id, process_id, run_index, outcome, verification_status}' \
.noesis/episodes/<episode_id>/final.json

# Confirm the manifest covers final.json.
jq '.files[] | select(.name == "final.json")' \
.noesis/episodes/<episode_id>/manifest.json
```

## Related references

<CardGroup cols={2}>
<Card title="Artifacts" icon="folder" href="/explanation/artifacts">
How final markers fit into the episode artifact bundle.
</Card>
<Card title="Python API" icon="code" href="/reference/python-api">
Lifecycle APIs and common sealed-run errors.
</Card>
<Card title="Events" icon="list" href="/reference/events">
Runtime lifecycle events for interrupts, checkpoints, resumes, and state projections.
</Card>
<Card title="State" icon="database" href="/reference/state">
Terminal and non-terminal state projection links.
</Card>
</CardGroup>
Loading