Initialize repository snapshot

This commit is contained in:
Vault Sovereign
2025-12-27 00:10:32 +00:00
commit 110d644e10
281 changed files with 40331 additions and 0 deletions

22
spec/sentinel/README.md Normal file
View File

@@ -0,0 +1,22 @@
# Sentinel v1 Schemas (v1)
This directory contains implementer-facing, machine-checkable schemas and deterministic verification rules for Sentinel v1.
- `canonicalization.md`: normative hashing + Merkle + root publication rules.
- `event.schema.json`: minimal event schema for `receipts*.jsonl` export.
- `seal.schema.json`: minimal schema for `seal.json` inside an Ouroboros seal bundle.
- `integrity.schema.json`: optional schema for `integrity.json` (hashes of bundle files).
- `verifier_manifest.schema.json`: optional schema for `verifier_manifest.json` (tool/version expectations).
Related v1 documents:
- `spec/SENTINEL_OFFLINE_VERIFIER_REQUIREMENTS.md`
- `spec/SENTINEL_V1_CONTRACT_MATRIX.md`
Reference verifier + testvector:
- Verifier: `tools/vm_verify_sentinel_bundle.py`
- Testvector bundle: `testvectors/sentinel/black-box-that-refused/`
Quick run:
```bash
python3 tools/vm_verify_sentinel_bundle.py --bundle testvectors/sentinel/black-box-that-refused --strict
```

View File

@@ -0,0 +1,123 @@
# Sentinel v1 Canonicalization & Hashing Rules
This document defines deterministic event hashing and Merkle root computation for Sentinel v1. Verification MUST be deterministic across platforms given the same artifacts.
## 1) Hash function (`hash_algo`)
`hash_algo` MUST be one of:
- `blake3` (recommended)
- `sha256` (fallback for constrained platforms)
The chosen `hash_algo` MUST be constant for a given Sentinel instance/build. Verifiers MUST reject mixed algorithms within a single bundle unless explicitly versioned.
### 1.1 `vmhash`
`vmhash(data: bytes) -> string` returns:
- `"blake3:" + hex(blake3(data))` when `hash_algo=blake3`
- `"sha256:" + hex(sha256(data))` when `hash_algo=sha256`
`hex(...)` is lowercase hex with no separators.
## 2) JSON canonicalization (`canonicalization_version`)
`canonicalization_version` for Sentinel v1 events is:
- `sentinel-event-jcs-v1`
Canonical JSON MUST use RFC 8785 (JSON Canonicalization Scheme, “JCS”):
- UTF-8 encoding
- Object keys sorted lexicographically
- No insignificant whitespace
- Numbers encoded per JCS rules
If a platform cannot implement full JCS, it MUST NOT claim `sentinel-event-jcs-v1`.
## 3) Event canonical bytes
Each exported event is a JSON object that conforms to `event.schema.json`.
`event_canonical_bytes` is the UTF-8 bytes of the JCS-canonicalized event object.
## 4) Event hash + hash chain
### 4.1 `event_hash`
`event_hash` MUST be computed over the canonical bytes of the event object *excluding* the `event_hash` field itself.
Define:
- `event_without_event_hash = event` with the `event_hash` property removed (if present)
- `event_canonical_bytes = jcs_bytes(event_without_event_hash)`
Then:
`event_hash = vmhash(event_canonical_bytes)`
For exported artifacts, `event_hash` MUST be present in the event record and verifiers MUST recompute and compare it.
### 4.2 `prev_event_hash`
- For `seq = 0` (or the first event in a new ledger): `prev_event_hash = "0"`
- For `seq = n > 0`: `prev_event_hash` MUST equal the computed `event_hash` of the immediately preceding event (`seq = n-1`) in the same ledger.
This provides fast tamper evidence even without Merkle recomputation.
## 5) Operation digest (`op_digest`)
`op_digest` commits to the *normalized* operation descriptor.
Define the normalized object:
```json
{
"op": "<op>",
"params": { "canonical": "params" }
}
```
Normalization rules:
- `op` MUST be a stable, versioned identifier (e.g., `sentinel.export_seal.v1`).
- `params` MUST be JSON (no NaN/Infinity); omit unset fields rather than using null where possible.
- Canonicalize the object using `sentinel-event-jcs-v1`, then hash:
`op_digest = vmhash(jcs_bytes({"op": op, "params": params}))`
## 6) Merkle root (`ROOT.current.txt`)
### 6.1 Leaves
The Merkle tree commits to the ordered list of event hashes:
`leaves = [event_hash(seq=0), event_hash(seq=1), ...]`
Each leaf is a `vmhash` string (`algo:hex`).
Note on ranged bundles: A verifier can only recompute the global Merkle roots for an arbitrary `since_seq > 0` bundle if it is also given a verifiable Merkle continuation state (e.g., a frontier snapshot) at `since_seq-1`. Otherwise, verification MUST fall back to hash-chain + file-integrity checks for that range, or the bundle MUST start at `since_seq = 0`.
### 6.2 Parent computation (VaultMesh-style)
To compute a parent from two children:
- Let `left_hex = left.split(":", 1)[-1]`
- Let `right_hex = right.split(":", 1)[-1]`
- `parent = vmhash( (left_hex + right_hex).encode("utf-8") )`
If the level has an odd count, duplicate the last element (i.e., `right = left`).
### 6.3 Empty tree root
If there are no leaves, the root MUST be:
`vmhash(b"empty")`
### 6.4 Root publication file format
`ROOT.current.txt` MUST be human-readable and parseable as key/value lines:
```
format=vm-sentinel-root-v1
root=<algo:hex>
seq=<u64>
updated_at=<ISO-8601 Z>
hash_algo=<blake3|sha256>
canonicalization_version=sentinel-event-jcs-v1
```
Additional keys MAY be included, but verifiers MUST ignore unknown keys.

View File

@@ -0,0 +1,68 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "VaultMesh Sentinel v1 Event",
"type": "object",
"additionalProperties": false,
"required": [
"event_id",
"seq",
"ts",
"event_type",
"actor",
"cap_hash",
"op",
"op_digest",
"result",
"trace_id",
"prev_event_hash",
"event_hash",
"payload"
],
"properties": {
"event_id": { "type": "string", "format": "uuid" },
"seq": { "type": "integer", "minimum": 0 },
"ts": {
"description": "Monotonic + wallclock if available. Accepts ISO-8601 Z or a structured object.",
"anyOf": [
{ "type": "string" },
{
"type": "object",
"additionalProperties": false,
"required": ["wall"],
"properties": {
"wall": { "type": "string", "format": "date-time" },
"mono_ns": { "type": "integer", "minimum": 0 }
}
}
]
},
"event_type": {
"type": "string",
"enum": [
"action_intent",
"policy_decision",
"action_executed",
"shadow_receipt",
"cap_grant",
"cap_revoke",
"seal_created",
"root_published",
"corruption_detected",
"tamper_signal",
"boot_event",
"health_event"
]
},
"actor": { "type": "string", "minLength": 1 },
"cap_hash": { "type": "string", "minLength": 1 },
"op": { "type": "string", "minLength": 1 },
"op_digest": { "type": "string", "minLength": 1 },
"result": { "type": "string", "enum": ["ok", "deny", "error"] },
"root_before": { "type": "string" },
"root_after": { "type": "string" },
"trace_id": { "type": "string", "format": "uuid" },
"prev_event_hash": { "type": "string", "minLength": 1 },
"event_hash": { "type": "string" },
"payload": { "type": "object" }
}
}

View File

@@ -0,0 +1,24 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "VaultMesh Sentinel v1 Integrity Manifest (integrity.json)",
"type": "object",
"additionalProperties": false,
"required": ["format", "hash_algo", "files"],
"properties": {
"format": { "type": "string", "const": "vm-sentinel-integrity-v1" },
"hash_algo": { "type": "string", "enum": ["blake3", "sha256"] },
"files": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["path", "digest"],
"properties": {
"path": { "type": "string" },
"digest": { "type": "string" },
"size_bytes": { "type": "integer", "minimum": 0 }
}
}
}
}
}

View File

@@ -0,0 +1,62 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "VaultMesh Sentinel v1 Seal Bundle (seal.json)",
"type": "object",
"additionalProperties": false,
"required": [
"format",
"sentinel_version",
"schema_version",
"hash_algo",
"canonicalization_version",
"seal_id",
"created_at",
"range",
"root",
"files"
],
"properties": {
"format": { "type": "string", "const": "vm-sentinel-seal-v1" },
"sentinel_version": { "type": "string" },
"schema_version": { "type": "string" },
"hash_algo": { "type": "string", "enum": ["blake3", "sha256"] },
"canonicalization_version": { "type": "string" },
"seal_id": { "type": "string" },
"created_at": { "type": "string", "format": "date-time" },
"instance_id": { "type": "string" },
"ledger_type": { "type": "string", "enum": ["sqlite", "jsonl"] },
"range": {
"type": "object",
"additionalProperties": false,
"required": ["since_seq", "until_seq"],
"properties": {
"since_seq": { "type": "integer", "minimum": 0 },
"until_seq": { "type": "integer", "minimum": 0 },
"since_ts": { "type": "string" },
"until_ts": { "type": "string" }
}
},
"root": {
"type": "object",
"additionalProperties": false,
"required": ["start", "end"],
"properties": {
"start": { "type": "string" },
"end": { "type": "string" },
"seq": { "type": "integer", "minimum": 0 }
}
},
"files": {
"type": "object",
"additionalProperties": false,
"required": ["receipts", "roots", "integrity", "verifier_manifest"],
"properties": {
"receipts": { "type": "string" },
"roots": { "type": "string" },
"integrity": { "type": "string" },
"verifier_manifest": { "type": "string" }
}
},
"notes": { "type": "string" }
}
}

View File

@@ -0,0 +1,23 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "VaultMesh Sentinel v1 Verifier Manifest (verifier_manifest.json)",
"type": "object",
"additionalProperties": false,
"required": ["format", "sentinel_version", "schema_version", "canonicalization_version"],
"properties": {
"format": { "type": "string", "const": "vm-sentinel-verifier-manifest-v1" },
"sentinel_version": { "type": "string" },
"schema_version": { "type": "string" },
"hash_algo": { "type": "string", "enum": ["blake3", "sha256"] },
"canonicalization_version": { "type": "string" },
"verifier": {
"type": "object",
"additionalProperties": true,
"properties": {
"name": { "type": "string" },
"version": { "type": "string" },
"sha256": { "type": "string" }
}
}
}
}