Add canonical assertion envelopes for v0.4.0
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Thinkloom implementation status
|
||||
|
||||
Status date: 2026-07-17
|
||||
Status date: 2026-07-18
|
||||
|
||||
## Completed locally
|
||||
|
||||
@@ -12,6 +12,7 @@ Status date: 2026-07-17
|
||||
- M5 finalization/style/history: editorial action previews, editable style traits and disallowed habits, saved versions, comparison summary, restore, release checkpoints, provenance timeline, and contribution relationships.
|
||||
- M7 export/backup/evidence: Markdown, HTML, PDF, text, backup ZIP, evidence ZIP, sanitization disclosure, hashes, manifest, atomic finalization, and strict ZIP import validation.
|
||||
- Provenance Stage 2 contract (v0.3.0): 38 JSON Schema Draft 2020-12 schemas, valid/invalid fixture suites, canonical JSON and JSONL vectors, event-chain vectors, protected-record/key-rotation vectors, retention-policy vectors, and a formal release-files Merkle construction.
|
||||
- Canonical assertion envelopes (v0.4.0): immutable provenance assertions, point-in-time evaluations, six semantic registries, independent confidence dimensions, evidence classes, stable reason codes, and deterministic dependency-invalidation vectors.
|
||||
- Product surface: Sites, Next, Vinext, Cloudflare, and browser-companion code and configuration have been removed. Tauri is the sole application target.
|
||||
|
||||
## External release gates
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
# Thinkloom prompt configuration
|
||||
|
||||
Thinkloom 0.3.0 exposes every instruction sent to a language model as editable JSON. The desktop app creates a prompts folder in its operating-system configuration directory and shows its exact path under Settings → Prompt configuration. Use Open prompt folder to open it.
|
||||
Thinkloom 0.4.0 exposes every instruction sent to a language model as editable JSON. The desktop app creates a prompts folder in its operating-system configuration directory and shows its exact path under Settings → Prompt configuration. Use Open prompt folder to open it.
|
||||
|
||||
Prompt files are loaded immediately before every model request. Save a valid edit, then make the next request; no restart or rebuild is required. Thinkloom never overwrites existing user prompt files during startup or an update.
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ See [PROMPTS.md](PROMPTS.md) for each file's effect, variables, editing workflow
|
||||
|
||||
The approved Thinkloom 1.0 provenance architecture is documented in the [Stage 1 normative provenance specification](docs/provenance/README.md). It defines the future single-writer subsystem, canonical records, segmented ledger, recovery protocol, retention policy, native verification, and release bindings.
|
||||
|
||||
Thinkloom 0.3.0 includes the formal Stage 2 schema package and deterministic verification vectors. The current native provenance writer must not be represented as conforming until the later implementation and fault-injection stages are complete.
|
||||
Thinkloom 0.4.0 extends the formal Stage 2 package with canonical provenance assertions, point-in-time evaluations, versioned semantic registries, and deterministic invalidation vectors. The current native provenance writer must not be represented as conforming until the later implementation and fault-injection stages are complete.
|
||||
|
||||
## Provider setup
|
||||
|
||||
|
||||
@@ -34,6 +34,11 @@ Stage 1 is complete only when every item below is represented without contradict
|
||||
| Stale-context handling | Specification §14; State Machines §3 | Complete |
|
||||
| Native verification authority | Specification §15 | Complete |
|
||||
| Verification findings/statuses and gates | Specification §15 | Complete |
|
||||
| Immutable assertion and point-in-time evaluation separation | Specification §15.1 | Complete |
|
||||
| Exact/degraded/refused/stale/unverified assertion semantics | Specification §15.1 | Complete |
|
||||
| Independent confidence dimensions without percentages | Specification §15.1 | Complete |
|
||||
| Structured invalidation dependencies and evidence classes | Specification §15.1 | Complete |
|
||||
| Unknown evidence never silently becomes exact | Specification §15.1 | Complete |
|
||||
| Historical index generator warning behavior | Specification §§15–16 | Complete |
|
||||
| Deterministic derived-index rules | Specification §16 | Complete |
|
||||
| Two-stage Git checkpoint without circularity | Specification §17; State Machines §6 | Complete |
|
||||
@@ -70,6 +75,10 @@ Required outputs:
|
||||
- Deterministic derived-index fixtures.
|
||||
- Backup/release manifest and Merkle-root fixtures.
|
||||
- Verification-report fixtures for every status and severity.
|
||||
- Provenance-assertion and assertion-evaluation fixtures.
|
||||
- Versioned assertion lifecycle, reason-code, confidence-dimension, evidence-class, and boundary-kind registries.
|
||||
- Assertion self-digest, dependency invalidation, superseding evaluation, and consumer-decision vectors.
|
||||
- Invalid fixtures proving unknown provenance, generation, compatibility, or confidence cannot validate as exact.
|
||||
|
||||
Stage 2 must preserve the distinction between the provenance schema version and the Thinkloom application version.
|
||||
|
||||
@@ -165,6 +174,15 @@ For each boundary, tests MUST prove one of:
|
||||
- Manual edit transactions after generated-text acceptance
|
||||
- Transcript correction after downstream use
|
||||
- Range verification across UTF-8, Unicode scalar, UTF-16, and editor coordinates
|
||||
- Assertion source anchors prior evidence without circularly anchoring the assertion-recording event
|
||||
- Assertion self-digest excludes only `assertion_sha256`
|
||||
- Exact, degraded, refused, stale, and unverified assertion evaluations
|
||||
- Every confidence dimension is explicit and contains no numeric authorship percentage
|
||||
- Unknown provenance, generation, compatibility, or confidence rejects exact evaluation
|
||||
- Mandatory-live, mandatory-retained, advisory, and shadow evidence behave distinctly
|
||||
- Digest and generation changes deterministically invalidate dependent evaluations
|
||||
- Later evaluations supersede current usability without mutating earlier assertion or evaluation records
|
||||
- Derived projections never synthesize exact without an authoritative exact evaluation
|
||||
|
||||
## 7. Privacy, secret, and encryption tests
|
||||
|
||||
|
||||
@@ -8,4 +8,4 @@ This directory contains the approved normative specification and formal Stage 2
|
||||
- [Stage 2 Completion and Verification](STAGE-2-SCHEMA-PACKAGE.md)
|
||||
- [Stage 2 JSON Schema package](../../schemas/provenance/v1/README.md)
|
||||
|
||||
Thinkloom 0.3.0 includes the 38-schema Draft 2020-12 package, valid and invalid fixtures, and deterministic conformance vectors. The native writer does not yet implement this contract and must not be represented as conforming until the later implementation and fault-injection stages are complete.
|
||||
Thinkloom 0.4.0 includes the 40-schema Draft 2020-12 package, versioned assertion registries, valid and invalid fixtures, and deterministic conformance vectors. The native writer does not yet implement this contract and must not be represented as conforming until the later implementation and fault-injection stages are complete.
|
||||
|
||||
@@ -11,7 +11,7 @@ This specification defines the authority, persistence, integrity, privacy, recov
|
||||
|
||||
It supersedes the provenance-specific transaction order, single-ledger layout, mutable-record assumptions, live-database snapshot method, and release-binding sequence in the earlier MVP architecture and implementation plans. It does not supersede their product requirements, native Tauri boundary, preview-first generation model, user-control requirements, accessibility requirements, or prohibition on retained audio.
|
||||
|
||||
Thinkloom 0.3.0 includes the formal Stage 2 schemas and verification vectors, but its native writer is not represented as conforming to this specification. Full conformance begins only after the native implementation and required fault-injection tests are complete.
|
||||
Thinkloom 0.4.0 includes the formal Stage 2 schemas, canonical assertion envelopes, and verification vectors, but its native writer is not represented as conforming to this specification. Full conformance begins only after the native implementation and required fault-injection tests are complete.
|
||||
|
||||
## 2. Normative language
|
||||
|
||||
@@ -37,7 +37,7 @@ The strongest valid claim without an external anchor is:
|
||||
|
||||
The following hierarchy is binding:
|
||||
|
||||
1. **Immutable filesystem records and the provenance ledger** are authoritative evidence.
|
||||
1. **Immutable filesystem records, canonical provenance assertions, point-in-time assertion evaluations, and the provenance ledger** are authoritative evidence when bound by ledger references.
|
||||
2. **Canonical publication files and manuscript revisions** are authoritative publication content when bound by ledger references.
|
||||
3. **Release manifests** are authoritative bindings for a completed release.
|
||||
4. **SQLite** stores operational state, UI state, write intents, idempotency indexes, and rebuildable query indexes.
|
||||
@@ -85,7 +85,7 @@ Large PDFs, ZIP packages, and regenerable binaries SHOULD remain outside ordinar
|
||||
|
||||
## 6. Identifiers and event ordering
|
||||
|
||||
Stable sortable identifiers SHOULD use ULIDs with type prefixes, including `event_`, `record_`, `intent_`, `turn_`, `session_`, `invocation_`, `revision_`, `fragment_`, `checkpoint_`, and `release_`.
|
||||
Stable sortable identifiers SHOULD use ULIDs with type prefixes, including `event_`, `record_`, `intent_`, `turn_`, `session_`, `invocation_`, `revision_`, `fragment_`, `checkpoint_`, `release_`, `assertion_`, and `evaluation_`.
|
||||
|
||||
Identifiers MAY be allocated before an operation commits. Abandoned identifiers MUST NOT be reused.
|
||||
|
||||
@@ -161,6 +161,8 @@ The following records become immutable after creation:
|
||||
- Sealed ledger segment and segment manifest
|
||||
- Release manifest
|
||||
- Protected record envelope
|
||||
- Provenance assertion
|
||||
- Assertion evaluation
|
||||
|
||||
Mutable concepts MUST use immutable ordered revisions. `current.json` files and similar pointers MAY exist only as derived, non-authoritative conveniences.
|
||||
|
||||
@@ -307,6 +309,8 @@ The verifier MUST check, as applicable:
|
||||
- Source Git commit and tag bindings
|
||||
- Deterministic derived-index reproducibility
|
||||
- Protected record envelopes, and plaintext when keys are available
|
||||
- Provenance assertions
|
||||
- Assertion evaluations
|
||||
|
||||
Finding severities are `INFO`, `WARNING`, `ERROR`, and `CRITICAL`. Overall statuses are:
|
||||
|
||||
@@ -322,6 +326,45 @@ Incremental verification MAY use a cached verified chain head. The cache is non-
|
||||
|
||||
Release and import gates MUST follow the approved status matrix: `INCOMPLETE`, `FAILED`, and `UNSAFE` block release; unverified imports never enter an active project destination.
|
||||
|
||||
### 15.1 Canonical provenance assertions and evaluations
|
||||
|
||||
A promoted fact or artifact relationship MUST be represented by an immutable `provenance-assertion` record rather than inferred from a derived index, UI state, or application-specific internal structure. An assertion states what was claimed, which generation and lifecycle phase it belongs to, which subsystem produced it, which retained evidence supports it, and which dependencies can invalidate its use.
|
||||
|
||||
An assertion MUST contain:
|
||||
|
||||
- Stable assertion, project, subject, and object identities
|
||||
- A machine-readable predicate
|
||||
- A source anchor naming a prior authoritative event, its sequence, and its event digest
|
||||
- Explicit source-generation coordinates
|
||||
- The lifecycle phase at which the relationship was asserted
|
||||
- Producer subsystem and application version
|
||||
- A provenance basis and retained evidence references
|
||||
- Structured invalidation dependencies with expected digests, expected generations, evidence class, and required/advisory role
|
||||
- A stable reason code
|
||||
- An exact assertion self-digest identity excluding only `assertion_sha256`
|
||||
|
||||
The event that records an assertion MUST reference the already-written assertion record and digest. The assertion source anchor MUST identify basis evidence and MUST NOT identify the recording event when that would create a circular digest dependency.
|
||||
|
||||
Time-dependent conclusions MUST NOT mutate the assertion. They MUST be stored as immutable `assertion-evaluation` records evaluated against an explicit chain head, event sequence, and project epoch. A later evaluation supersedes an earlier conclusion for current use without erasing or rewriting it.
|
||||
|
||||
Assertion evaluation statuses are:
|
||||
|
||||
- `exact`: all required provenance, generation, integrity, identity, chronology, derivation, authorship, and completeness inputs are known, compatible, and sufficient for the asserted scope.
|
||||
- `degraded`: the assertion remains usable only with an explicitly bounded limitation.
|
||||
- `refused`: policy, authorization, unsupported compatibility, or another mandatory gate prohibits a conclusion.
|
||||
- `stale`: a dependency digest, generation, or source anchor no longer matches the evaluation target.
|
||||
- `unverified`: required evaluation has not completed or mandatory evidence is unavailable without a demonstrated contradiction.
|
||||
|
||||
Every evaluation MUST assess these dimensions independently: `integrity`, `identity`, `chronology`, `derivation`, `authorship`, and `completeness`. Dimension values are `exact`, `degraded`, `unverified`, or `not_applicable`. Numeric confidence scores and human-versus-AI percentages MUST NOT be used.
|
||||
|
||||
An `exact` evaluation MUST have no uncertainty boundary, MUST contain valid results for every non-shadow dependency, and MUST contain no `degraded` or `unverified` confidence dimension. Shadow evidence never contributes authority and MAY remain unevaluated without changing exactness. A non-exact evaluation MUST identify the exact boundary, affected dimensions, dependencies when applicable, and a stable reason code. Unknown provenance, source generation, compatibility, or confidence MUST NOT silently produce an `exact` evaluation.
|
||||
|
||||
Evidence classes are `mandatory_live`, `mandatory_retained`, `advisory`, and `shadow`. Missing or incompatible mandatory evidence prohibits `exact`. Advisory or shadow evidence MAY degrade completeness or another named dimension but MUST NOT silently change an authoritative assertion.
|
||||
|
||||
Assertion and evaluation reason codes, lifecycle phases, statuses, dimensions, evidence classes, and boundary kinds MUST come from versioned machine-readable registries included in the schema package. Consumers MUST decide usability from these canonical records and registries rather than reopening producer-specific internal state.
|
||||
|
||||
Derived indexes and reports MAY project assertions and the latest applicable evaluations, but remain non-authoritative consumers. They MUST NOT synthesize an `exact` result when no valid authoritative evaluation exists.
|
||||
|
||||
## 16. Derived indexes
|
||||
|
||||
Derived indexes MUST be reproducible from authoritative records. Deterministic index content MUST use stable sorting, locale-independent comparison, canonical inputs, fixed schema/configuration, no random identifiers, and no current timestamp.
|
||||
@@ -449,6 +492,8 @@ manuscript-revision.schema.json
|
||||
edit-transaction.schema.json
|
||||
text-fragment-reference.schema.json
|
||||
derived-index-manifest.schema.json
|
||||
provenance-assertion.schema.json
|
||||
assertion-evaluation.schema.json
|
||||
verification-report.schema.json
|
||||
backup-manifest.schema.json
|
||||
release-manifest.schema.json
|
||||
@@ -457,7 +502,7 @@ sanitized-export-manifest.schema.json
|
||||
purge-manifest.schema.json
|
||||
```
|
||||
|
||||
Prompt-template and other self-digesting schemas MUST define exact digest identity objects. Migration schemas are deferred until after Thinkloom 1.0.0.
|
||||
Prompt-template, provenance-assertion, and other self-digesting schemas MUST define exact digest identity objects. Migration schemas are deferred until after Thinkloom 1.0.0.
|
||||
|
||||
## 25. Required implementation characteristics
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Thinkloom Stage 2 Provenance Schema Package
|
||||
|
||||
Status: **Complete for Thinkloom 0.3.0**
|
||||
Status: **Complete for Thinkloom 0.4.0**
|
||||
Schema family: **1.0**
|
||||
Dialect: **JSON Schema Draft 2020-12**
|
||||
Runtime conformance: **Not yet implemented**
|
||||
@@ -11,14 +11,14 @@ Stage 2 formalizes the approved provenance architecture without changing native
|
||||
|
||||
## Package
|
||||
|
||||
The machine-readable package is in [`schemas/provenance/v1`](../../schemas/provenance/v1/README.md). `catalog.json` identifies all 38 schemas, the schema and application versions, compatibility, fixture locations, and the generator.
|
||||
The machine-readable package is in [`schemas/provenance/v1`](../../schemas/provenance/v1/README.md). `catalog.json` identifies all 40 schemas, the schema and application versions, compatibility, fixture locations, and the generator.
|
||||
|
||||
Each schema has:
|
||||
|
||||
- one valid canonical fixture;
|
||||
- invalid cases for every top-level required field and the closed-object policy;
|
||||
- populated nested cases for enum, const, pattern, numeric, string, and array bounds; and
|
||||
- explicit conditional failures for protected records and recovery envelopes where ordinary keyword mutation is insufficient.
|
||||
- explicit conditional failures for protected records, recovery envelopes, assertion generations, and exact evaluation rules where ordinary keyword mutation is insufficient.
|
||||
|
||||
## Deterministic vectors
|
||||
|
||||
@@ -33,8 +33,11 @@ The vector suite covers:
|
||||
- device and recovery key envelopes plus key rotation;
|
||||
- non-mutating sanitized exports and omission-rule disclosure;
|
||||
- deterministic derived indexes;
|
||||
- backup and release manifests plus the release-files Merkle root; and
|
||||
- all verification statuses and finding severities.
|
||||
- backup and release manifests plus the release-files Merkle root;
|
||||
- all verification statuses and finding severities;
|
||||
- immutable assertion envelopes and exact self-digest identity;
|
||||
- point-in-time exact, degraded, refused, stale, and unverified evaluations; and
|
||||
- versioned reason, lifecycle, confidence, evidence, boundary, and consumer-decision registries.
|
||||
|
||||
## Verification
|
||||
|
||||
@@ -54,4 +57,4 @@ The schema tests are also part of `npm test`. Generated output must be committed
|
||||
|
||||
## Next boundary
|
||||
|
||||
Thinkloom 0.3.0 must not claim native provenance conformance. The next implementation stage replaces the MVP persistence path with the approved single-writer protocol and then executes the durable-boundary fault-injection matrix.
|
||||
Thinkloom 0.4.0 must not claim native provenance conformance. The next implementation stage replaces the MVP persistence path with the approved single-writer protocol and then executes the durable-boundary fault-injection matrix.
|
||||
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "thinkloom",
|
||||
"version": "0.3.0",
|
||||
"version": "0.4.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "thinkloom",
|
||||
"version": "0.3.0",
|
||||
"version": "0.4.0",
|
||||
"license": "AGPL-3.0-only",
|
||||
"dependencies": {
|
||||
"@tiptap/markdown": "^3.28.0",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "thinkloom",
|
||||
"version": "0.3.0",
|
||||
"version": "0.4.0",
|
||||
"author": "Christopher Chambers",
|
||||
"license": "AGPL-3.0-only",
|
||||
"repository": "https://github.com/Labyricorn/thinkloom-openai-hackathon.git",
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
# Thinkloom provenance schemas 1.0
|
||||
|
||||
This generated package is the formal Stage 2 contract for the approved provenance architecture. It targets JSON Schema Draft 2020-12 and ships with 38 schemas, valid fixtures, invalid fixture suites, and deterministic verification vectors.
|
||||
This generated package is the formal Stage 2 contract for the approved provenance architecture. It targets JSON Schema Draft 2020-12 and ships with 40 schemas, valid fixtures, invalid fixture suites, and deterministic verification vectors.
|
||||
|
||||
- `catalog.json` is the machine-readable inventory.
|
||||
- `*.schema.json` are the formal contracts.
|
||||
- `registries` defines assertion lifecycle, evaluation status, confidence, evidence, boundary, and reason semantics.
|
||||
- `fixtures/valid` contains one canonical valid instance per schema.
|
||||
- `fixtures/invalid` covers required fields, closed-object policy, and populated enum, pattern, and numeric/string/array bounds.
|
||||
- `vectors` fixes canonicalization, timestamps, paths, JSONL, event and segment chains, self-digests, protected records, key rotation and recovery, retention policy, sanitized export, deterministic indexes, verification reports, backups, and release-Merkle behavior.
|
||||
- `vectors` fixes canonicalization, timestamps, paths, JSONL, event and segment chains, self-digests, protected records, key rotation and recovery, retention policy, sanitized export, deterministic indexes, verification reports, canonical assertions and evaluations, dependency invalidation, backups, and release-Merkle behavior.
|
||||
|
||||
Regenerate with `npm run provenance:schema:generate`. Verify with `npm run provenance:schema:test`. Generated files must be committed together with generator and vector changes. Runtime adoption is a later implementation stage; presence of this package does not imply the current native writer already conforms.
|
||||
|
||||
@@ -0,0 +1,779 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://thinkloom.app/schemas/provenance/1.0/assertion-evaluation.schema.json",
|
||||
"title": "Point-in-time assertion evaluation",
|
||||
"description": "Immutable verifier conclusion about one assertion at an explicit chain head and project epoch.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"schema_version": {
|
||||
"const": "1.0"
|
||||
},
|
||||
"evaluation_id": {
|
||||
"type": "string",
|
||||
"pattern": "^evaluation_[0-9A-HJKMNP-TV-Z]{26}$"
|
||||
},
|
||||
"assertion_id": {
|
||||
"type": "string",
|
||||
"pattern": "^assertion_[0-9A-HJKMNP-TV-Z]{26}$"
|
||||
},
|
||||
"assertion_sha256": {
|
||||
"type": "string",
|
||||
"pattern": "^sha256:[a-f0-9]{64}$"
|
||||
},
|
||||
"project_id": {
|
||||
"type": "string",
|
||||
"pattern": "^project_[0-9A-HJKMNP-TV-Z]{26}$"
|
||||
},
|
||||
"evaluated_against": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"chain_head": {
|
||||
"type": "string",
|
||||
"pattern": "^sha256:[a-f0-9]{64}$"
|
||||
},
|
||||
"event_sequence": {
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
},
|
||||
"project_epoch": {
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
},
|
||||
"schema_catalog_sha256": {
|
||||
"type": "string",
|
||||
"pattern": "^sha256:[a-f0-9]{64}$"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"chain_head",
|
||||
"event_sequence",
|
||||
"project_epoch",
|
||||
"schema_catalog_sha256"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"evaluator": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"subsystem": {
|
||||
"type": "string",
|
||||
"pattern": "^[a-z][a-z0-9_]+$"
|
||||
},
|
||||
"application_version": {
|
||||
"type": "string",
|
||||
"pattern": "^\\d+\\.\\d+\\.\\d+$"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"subsystem",
|
||||
"application_version"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"status": {
|
||||
"enum": [
|
||||
"exact",
|
||||
"degraded",
|
||||
"refused",
|
||||
"stale",
|
||||
"unverified"
|
||||
]
|
||||
},
|
||||
"confidence": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"integrity": {
|
||||
"enum": [
|
||||
"exact",
|
||||
"degraded",
|
||||
"unverified",
|
||||
"not_applicable"
|
||||
]
|
||||
},
|
||||
"identity": {
|
||||
"enum": [
|
||||
"exact",
|
||||
"degraded",
|
||||
"unverified",
|
||||
"not_applicable"
|
||||
]
|
||||
},
|
||||
"chronology": {
|
||||
"enum": [
|
||||
"exact",
|
||||
"degraded",
|
||||
"unverified",
|
||||
"not_applicable"
|
||||
]
|
||||
},
|
||||
"derivation": {
|
||||
"enum": [
|
||||
"exact",
|
||||
"degraded",
|
||||
"unverified",
|
||||
"not_applicable"
|
||||
]
|
||||
},
|
||||
"authorship": {
|
||||
"enum": [
|
||||
"exact",
|
||||
"degraded",
|
||||
"unverified",
|
||||
"not_applicable"
|
||||
]
|
||||
},
|
||||
"completeness": {
|
||||
"enum": [
|
||||
"exact",
|
||||
"degraded",
|
||||
"unverified",
|
||||
"not_applicable"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"integrity",
|
||||
"identity",
|
||||
"chronology",
|
||||
"derivation",
|
||||
"authorship",
|
||||
"completeness"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"boundary": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"kind": {
|
||||
"enum": [
|
||||
"missing_provenance",
|
||||
"unknown_generation",
|
||||
"evidence_access",
|
||||
"compatibility",
|
||||
"dependency_change",
|
||||
"policy",
|
||||
"interpretation",
|
||||
"coverage"
|
||||
]
|
||||
},
|
||||
"affected_dimensions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"enum": [
|
||||
"integrity",
|
||||
"identity",
|
||||
"chronology",
|
||||
"derivation",
|
||||
"authorship",
|
||||
"completeness"
|
||||
]
|
||||
},
|
||||
"minItems": 1,
|
||||
"uniqueItems": true
|
||||
},
|
||||
"dependency_ids": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"pattern": "^[a-z][a-z0-9_]*_[0-9A-HJKMNP-TV-Z]{26}$"
|
||||
},
|
||||
"uniqueItems": true
|
||||
},
|
||||
"compatibility": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"required_schema": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"observed_schema": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"required_schema",
|
||||
"observed_schema"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind",
|
||||
"affected_dimensions",
|
||||
"dependency_ids",
|
||||
"compatibility"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"dependency_results": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"dependency_id": {
|
||||
"type": "string",
|
||||
"pattern": "^[a-z][a-z0-9_]*_[0-9A-HJKMNP-TV-Z]{26}$"
|
||||
},
|
||||
"evidence_class": {
|
||||
"enum": [
|
||||
"mandatory_live",
|
||||
"mandatory_retained",
|
||||
"advisory",
|
||||
"shadow"
|
||||
]
|
||||
},
|
||||
"status": {
|
||||
"enum": [
|
||||
"valid",
|
||||
"missing",
|
||||
"changed",
|
||||
"inaccessible",
|
||||
"incompatible",
|
||||
"not_evaluated"
|
||||
]
|
||||
},
|
||||
"observed_sha256": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^sha256:[a-f0-9]{64}$"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"observed_generation": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"project_epoch": {
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
},
|
||||
"artifact_revision": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"transcript_revision": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"project_epoch",
|
||||
"artifact_revision",
|
||||
"transcript_revision"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"dependency_id",
|
||||
"evidence_class",
|
||||
"status",
|
||||
"observed_sha256",
|
||||
"observed_generation"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"minItems": 1
|
||||
},
|
||||
"reason_code": {
|
||||
"enum": [
|
||||
"DIRECT_HASH_LINKED_DERIVATION",
|
||||
"VERIFIED_TRANSITIVE_DERIVATION",
|
||||
"REQUIRED_PROVENANCE_UNKNOWN",
|
||||
"SOURCE_GENERATION_UNKNOWN",
|
||||
"REQUIRED_EVIDENCE_MISSING",
|
||||
"DEPENDENCY_DIGEST_MISMATCH",
|
||||
"DEPENDENCY_GENERATION_MISMATCH",
|
||||
"SOURCE_ANCHOR_STALE",
|
||||
"SCHEMA_INCOMPATIBLE",
|
||||
"POLICY_REFUSED",
|
||||
"AUTHORIZED_EVIDENCE_UNAVAILABLE",
|
||||
"ADVISORY_EVIDENCE_UNAVAILABLE",
|
||||
"ASSERTION_NOT_EVALUATED",
|
||||
"AUTHORSHIP_UNCERTAIN",
|
||||
"CHRONOLOGY_INCOMPLETE",
|
||||
"COMPLETENESS_INCOMPLETE"
|
||||
]
|
||||
},
|
||||
"supersedes_evaluation_id": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^evaluation_[0-9A-HJKMNP-TV-Z]{26}$"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"evaluated_at": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"schema_version",
|
||||
"evaluation_id",
|
||||
"assertion_id",
|
||||
"assertion_sha256",
|
||||
"project_id",
|
||||
"evaluated_against",
|
||||
"evaluator",
|
||||
"status",
|
||||
"confidence",
|
||||
"boundary",
|
||||
"dependency_results",
|
||||
"reason_code",
|
||||
"supersedes_evaluation_id",
|
||||
"evaluated_at"
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"allOf": [
|
||||
{
|
||||
"if": {
|
||||
"properties": {
|
||||
"status": {
|
||||
"const": "exact"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
"properties": {
|
||||
"boundary": {
|
||||
"type": "null"
|
||||
},
|
||||
"reason_code": {
|
||||
"enum": [
|
||||
"DIRECT_HASH_LINKED_DERIVATION",
|
||||
"VERIFIED_TRANSITIVE_DERIVATION"
|
||||
]
|
||||
},
|
||||
"confidence": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"integrity": {
|
||||
"enum": [
|
||||
"exact",
|
||||
"not_applicable"
|
||||
]
|
||||
},
|
||||
"identity": {
|
||||
"enum": [
|
||||
"exact",
|
||||
"not_applicable"
|
||||
]
|
||||
},
|
||||
"chronology": {
|
||||
"enum": [
|
||||
"exact",
|
||||
"not_applicable"
|
||||
]
|
||||
},
|
||||
"derivation": {
|
||||
"enum": [
|
||||
"exact",
|
||||
"not_applicable"
|
||||
]
|
||||
},
|
||||
"authorship": {
|
||||
"enum": [
|
||||
"exact",
|
||||
"not_applicable"
|
||||
]
|
||||
},
|
||||
"completeness": {
|
||||
"enum": [
|
||||
"exact",
|
||||
"not_applicable"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"integrity",
|
||||
"identity",
|
||||
"chronology",
|
||||
"derivation",
|
||||
"authorship",
|
||||
"completeness"
|
||||
]
|
||||
},
|
||||
"dependency_results": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"if": {
|
||||
"properties": {
|
||||
"evidence_class": {
|
||||
"const": "shadow"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"evidence_class"
|
||||
]
|
||||
},
|
||||
"else": {
|
||||
"properties": {
|
||||
"status": {
|
||||
"const": "valid"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": {
|
||||
"properties": {
|
||||
"status": {
|
||||
"not": {
|
||||
"const": "exact"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
"properties": {
|
||||
"boundary": {
|
||||
"not": {
|
||||
"type": "null"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": {
|
||||
"properties": {
|
||||
"status": {
|
||||
"const": "degraded"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
"properties": {
|
||||
"reason_code": {
|
||||
"enum": [
|
||||
"ADVISORY_EVIDENCE_UNAVAILABLE",
|
||||
"AUTHORSHIP_UNCERTAIN",
|
||||
"CHRONOLOGY_INCOMPLETE",
|
||||
"COMPLETENESS_INCOMPLETE"
|
||||
]
|
||||
},
|
||||
"confidence": {
|
||||
"type": "object",
|
||||
"anyOf": [
|
||||
{
|
||||
"properties": {
|
||||
"integrity": {
|
||||
"const": "degraded"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"integrity"
|
||||
]
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"identity": {
|
||||
"const": "degraded"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"identity"
|
||||
]
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"chronology": {
|
||||
"const": "degraded"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"chronology"
|
||||
]
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"derivation": {
|
||||
"const": "degraded"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"derivation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"authorship": {
|
||||
"const": "degraded"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"authorship"
|
||||
]
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"completeness": {
|
||||
"const": "degraded"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"completeness"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"dependency_results": {
|
||||
"type": "array",
|
||||
"not": {
|
||||
"contains": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"evidence_class": {
|
||||
"enum": [
|
||||
"mandatory_live",
|
||||
"mandatory_retained"
|
||||
]
|
||||
},
|
||||
"status": {
|
||||
"not": {
|
||||
"const": "valid"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"evidence_class",
|
||||
"status"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": {
|
||||
"properties": {
|
||||
"status": {
|
||||
"const": "refused"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
"properties": {
|
||||
"reason_code": {
|
||||
"enum": [
|
||||
"SCHEMA_INCOMPATIBLE",
|
||||
"POLICY_REFUSED",
|
||||
"AUTHORIZED_EVIDENCE_UNAVAILABLE"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": {
|
||||
"properties": {
|
||||
"status": {
|
||||
"const": "stale"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
"properties": {
|
||||
"reason_code": {
|
||||
"enum": [
|
||||
"DEPENDENCY_DIGEST_MISMATCH",
|
||||
"DEPENDENCY_GENERATION_MISMATCH",
|
||||
"SOURCE_ANCHOR_STALE"
|
||||
]
|
||||
},
|
||||
"dependency_results": {
|
||||
"type": "array",
|
||||
"contains": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
"const": "changed"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status"
|
||||
]
|
||||
},
|
||||
"minContains": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": {
|
||||
"properties": {
|
||||
"status": {
|
||||
"const": "unverified"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
"properties": {
|
||||
"reason_code": {
|
||||
"enum": [
|
||||
"REQUIRED_PROVENANCE_UNKNOWN",
|
||||
"SOURCE_GENERATION_UNKNOWN",
|
||||
"REQUIRED_EVIDENCE_MISSING",
|
||||
"AUTHORIZED_EVIDENCE_UNAVAILABLE",
|
||||
"ASSERTION_NOT_EVALUATED",
|
||||
"CHRONOLOGY_INCOMPLETE",
|
||||
"COMPLETENESS_INCOMPLETE"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"examples": [
|
||||
{
|
||||
"schema_version": "1.0",
|
||||
"evaluation_id": "evaluation_01J0000000000000000000000W",
|
||||
"assertion_id": "assertion_01J0000000000000000000000V",
|
||||
"assertion_sha256": "sha256:f6770d587b8f2af9a86ceaa67f9dd7346fe46708f2654871424c0431a7f9e826",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"evaluated_against": {
|
||||
"chain_head": "sha256:6666666666666666666666666666666666666666666666666666666666666666",
|
||||
"event_sequence": 3,
|
||||
"project_epoch": 1,
|
||||
"schema_catalog_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777"
|
||||
},
|
||||
"evaluator": {
|
||||
"subsystem": "native_verifier",
|
||||
"application_version": "0.4.0"
|
||||
},
|
||||
"status": "exact",
|
||||
"confidence": {
|
||||
"integrity": "exact",
|
||||
"identity": "exact",
|
||||
"chronology": "exact",
|
||||
"derivation": "exact",
|
||||
"authorship": "not_applicable",
|
||||
"completeness": "exact"
|
||||
},
|
||||
"boundary": null,
|
||||
"dependency_results": [
|
||||
{
|
||||
"dependency_id": "event_01J00000000000000000000004",
|
||||
"evidence_class": "mandatory_retained",
|
||||
"status": "valid",
|
||||
"observed_sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555",
|
||||
"observed_generation": {
|
||||
"project_epoch": 1,
|
||||
"artifact_revision": 12,
|
||||
"transcript_revision": 4
|
||||
}
|
||||
},
|
||||
{
|
||||
"dependency_id": "record_01J00000000000000000000005",
|
||||
"evidence_class": "mandatory_live",
|
||||
"status": "valid",
|
||||
"observed_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888",
|
||||
"observed_generation": {
|
||||
"project_epoch": 1,
|
||||
"artifact_revision": 12,
|
||||
"transcript_revision": 4
|
||||
}
|
||||
},
|
||||
{
|
||||
"dependency_id": "turn_01J00000000000000000000007",
|
||||
"evidence_class": "advisory",
|
||||
"status": "valid",
|
||||
"observed_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777",
|
||||
"observed_generation": {
|
||||
"project_epoch": 1,
|
||||
"artifact_revision": 12,
|
||||
"transcript_revision": 4
|
||||
}
|
||||
},
|
||||
{
|
||||
"dependency_id": "idea_01J00000000000000000000009",
|
||||
"evidence_class": "shadow",
|
||||
"status": "not_evaluated",
|
||||
"observed_sha256": null,
|
||||
"observed_generation": null
|
||||
}
|
||||
],
|
||||
"reason_code": "DIRECT_HASH_LINKED_DERIVATION",
|
||||
"supersedes_evaluation_id": null,
|
||||
"evaluated_at": "2026-07-17T18:44:12.789Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -124,7 +124,7 @@
|
||||
"examples": [
|
||||
{
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
|
||||
@@ -2,14 +2,59 @@
|
||||
"catalog_version": "1.0",
|
||||
"dialect": "https://json-schema.org/draft/2020-12/schema",
|
||||
"provenance_schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"compatible_application_versions": [
|
||||
"0.3.0"
|
||||
"0.4.0"
|
||||
],
|
||||
"native_writer_conformance": false,
|
||||
"registries": [
|
||||
{
|
||||
"name": "assertion-lifecycle-phases",
|
||||
"description": "Immutable assertion lifecycle phase observed when the relationship was asserted.",
|
||||
"id": "https://thinkloom.app/schemas/provenance/1.0/registries/assertion-lifecycle-phases.json",
|
||||
"file": "registries/assertion-lifecycle-phases.json"
|
||||
},
|
||||
{
|
||||
"name": "assertion-evaluation-statuses",
|
||||
"description": "Consumer-facing point-in-time assertion conclusions.",
|
||||
"id": "https://thinkloom.app/schemas/provenance/1.0/registries/assertion-evaluation-statuses.json",
|
||||
"file": "registries/assertion-evaluation-statuses.json"
|
||||
},
|
||||
{
|
||||
"name": "assertion-confidence-dimensions",
|
||||
"description": "Independent non-numeric confidence dimensions.",
|
||||
"id": "https://thinkloom.app/schemas/provenance/1.0/registries/assertion-confidence-dimensions.json",
|
||||
"file": "registries/assertion-confidence-dimensions.json"
|
||||
},
|
||||
{
|
||||
"name": "assertion-evidence-classes",
|
||||
"description": "Evidence availability and authority requirements.",
|
||||
"id": "https://thinkloom.app/schemas/provenance/1.0/registries/assertion-evidence-classes.json",
|
||||
"file": "registries/assertion-evidence-classes.json"
|
||||
},
|
||||
{
|
||||
"name": "assertion-boundary-kinds",
|
||||
"description": "Machine-readable boundaries preventing an unqualified exact conclusion.",
|
||||
"id": "https://thinkloom.app/schemas/provenance/1.0/registries/assertion-boundary-kinds.json",
|
||||
"file": "registries/assertion-boundary-kinds.json"
|
||||
},
|
||||
{
|
||||
"name": "assertion-reason-codes",
|
||||
"description": "Stable explanations for assertion creation and evaluation outcomes.",
|
||||
"id": "https://thinkloom.app/schemas/provenance/1.0/registries/assertion-reason-codes.json",
|
||||
"file": "registries/assertion-reason-codes.json"
|
||||
}
|
||||
],
|
||||
"normative_specification": "../../../docs/provenance/STAGE-1-NORMATIVE-SPECIFICATION.md",
|
||||
"generated_by": "scripts/generate-provenance-stage2.mjs",
|
||||
"schemas": [
|
||||
{
|
||||
"name": "assertion-evaluation",
|
||||
"id": "https://thinkloom.app/schemas/provenance/1.0/assertion-evaluation.schema.json",
|
||||
"file": "assertion-evaluation.schema.json",
|
||||
"valid_fixture": "fixtures/valid/assertion-evaluation.valid.json",
|
||||
"invalid_fixture": "fixtures/invalid/assertion-evaluation.invalid.json"
|
||||
},
|
||||
{
|
||||
"name": "backup-manifest",
|
||||
"id": "https://thinkloom.app/schemas/provenance/1.0/backup-manifest.schema.json",
|
||||
@@ -178,6 +223,13 @@
|
||||
"valid_fixture": "fixtures/valid/prompt-template-reference.valid.json",
|
||||
"invalid_fixture": "fixtures/invalid/prompt-template-reference.invalid.json"
|
||||
},
|
||||
{
|
||||
"name": "provenance-assertion",
|
||||
"id": "https://thinkloom.app/schemas/provenance/1.0/provenance-assertion.schema.json",
|
||||
"file": "provenance-assertion.schema.json",
|
||||
"valid_fixture": "fixtures/valid/provenance-assertion.valid.json",
|
||||
"invalid_fixture": "fixtures/invalid/provenance-assertion.invalid.json"
|
||||
},
|
||||
{
|
||||
"name": "provenance-event",
|
||||
"id": "https://thinkloom.app/schemas/provenance/1.0/provenance-event.schema.json",
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
},
|
||||
"record_id": {
|
||||
"type": "string",
|
||||
"pattern": "^record_[0-9A-HJKMNP-TV-Z]{26}$"
|
||||
"pattern": "^[a-z][a-z0-9_]*_[0-9A-HJKMNP-TV-Z]{26}$"
|
||||
},
|
||||
"record_type": {
|
||||
"enum": [
|
||||
@@ -23,6 +23,8 @@
|
||||
"edit_transaction",
|
||||
"prompt_template",
|
||||
"model_configuration",
|
||||
"provenance_assertion",
|
||||
"assertion_evaluation",
|
||||
"release_file",
|
||||
"source",
|
||||
"other"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@
|
||||
{
|
||||
"description": "backup-manifest.schema_version: reject missing required property",
|
||||
"instance": {
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
@@ -57,7 +57,7 @@
|
||||
"description": "backup-manifest.project_id: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
"sqlite_snapshot": {
|
||||
@@ -83,7 +83,7 @@
|
||||
"description": "backup-manifest.created_at: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
"sqlite_snapshot": {
|
||||
@@ -109,7 +109,7 @@
|
||||
"description": "backup-manifest.source_chain_head: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"sqlite_snapshot": {
|
||||
@@ -135,7 +135,7 @@
|
||||
"description": "backup-manifest.sqlite_snapshot: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
@@ -154,7 +154,7 @@
|
||||
"description": "backup-manifest.files: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
@@ -174,7 +174,7 @@
|
||||
"description": "backup-manifest.protected: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
@@ -200,7 +200,7 @@
|
||||
"description": "backup-manifest.recovery_key_envelope_path: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
@@ -226,7 +226,7 @@
|
||||
"description": "backup-manifest: reject unexpected property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
@@ -254,7 +254,7 @@
|
||||
"description": "backup-manifest.schema_version: reject value different from const",
|
||||
"instance": {
|
||||
"schema_version": "__INVALID_CONST__",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
@@ -308,7 +308,7 @@
|
||||
"description": "backup-manifest.project_id: reject pattern mismatch",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "invalid-id",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
@@ -335,7 +335,7 @@
|
||||
"description": "backup-manifest.created_at: reject pattern mismatch",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "not-a-timestamp",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
@@ -362,7 +362,7 @@
|
||||
"description": "backup-manifest.source_chain_head: reject pattern mismatch",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:INVALID",
|
||||
@@ -389,7 +389,7 @@
|
||||
"description": "backup-manifest.sqlite_snapshot.path: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
@@ -415,7 +415,7 @@
|
||||
"description": "backup-manifest.sqlite_snapshot.sha256: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
@@ -441,7 +441,7 @@
|
||||
"description": "backup-manifest.sqlite_snapshot.size: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
@@ -467,7 +467,7 @@
|
||||
"description": "backup-manifest.sqlite_snapshot.sqlite_version: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
@@ -493,7 +493,7 @@
|
||||
"description": "backup-manifest.sqlite_snapshot.database_schema_version: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
@@ -519,7 +519,7 @@
|
||||
"description": "backup-manifest.sqlite_snapshot.completed_at: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
@@ -545,7 +545,7 @@
|
||||
"description": "backup-manifest.sqlite_snapshot: reject unexpected property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
@@ -573,7 +573,7 @@
|
||||
"description": "backup-manifest.sqlite_snapshot.path: reject pattern mismatch",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
@@ -600,7 +600,7 @@
|
||||
"description": "backup-manifest.sqlite_snapshot.path: reject string below minLength",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
@@ -627,7 +627,7 @@
|
||||
"description": "backup-manifest.sqlite_snapshot.sha256: reject pattern mismatch",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
@@ -654,7 +654,7 @@
|
||||
"description": "backup-manifest.sqlite_snapshot.size: reject value below minimum",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
@@ -681,7 +681,7 @@
|
||||
"description": "backup-manifest.sqlite_snapshot.sqlite_version: reject string below minLength",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
@@ -708,7 +708,7 @@
|
||||
"description": "backup-manifest.sqlite_snapshot.database_schema_version: reject value below minimum",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
@@ -735,7 +735,7 @@
|
||||
"description": "backup-manifest.sqlite_snapshot.completed_at: reject pattern mismatch",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
@@ -762,7 +762,7 @@
|
||||
"description": "backup-manifest.files: reject array below minItems",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
@@ -783,7 +783,7 @@
|
||||
"description": "backup-manifest.files[0].path: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
@@ -809,7 +809,7 @@
|
||||
"description": "backup-manifest.files[0].sha256: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
@@ -835,7 +835,7 @@
|
||||
"description": "backup-manifest.files[0].size: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
@@ -861,7 +861,7 @@
|
||||
"description": "backup-manifest.files[0]: reject unexpected property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
@@ -889,7 +889,7 @@
|
||||
"description": "backup-manifest.files[0].path: reject pattern mismatch",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
@@ -916,7 +916,7 @@
|
||||
"description": "backup-manifest.files[0].path: reject string below minLength",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
@@ -943,7 +943,7 @@
|
||||
"description": "backup-manifest.files[0].sha256: reject pattern mismatch",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
@@ -970,7 +970,7 @@
|
||||
"description": "backup-manifest.files[0].size: reject value below minimum",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
{
|
||||
"description": "project-manifest.schema_version: reject missing required property",
|
||||
"instance": {
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"title": "The Attention Commons",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
@@ -33,7 +33,7 @@
|
||||
"description": "project-manifest.project_id: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"title": "The Attention Commons",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"updated_at": "2026-07-17T18:43:11.456Z",
|
||||
@@ -47,7 +47,7 @@
|
||||
"description": "project-manifest.title: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"updated_at": "2026-07-17T18:43:11.456Z",
|
||||
@@ -61,7 +61,7 @@
|
||||
"description": "project-manifest.created_at: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"title": "The Attention Commons",
|
||||
"updated_at": "2026-07-17T18:43:11.456Z",
|
||||
@@ -75,7 +75,7 @@
|
||||
"description": "project-manifest.updated_at: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"title": "The Attention Commons",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
@@ -89,7 +89,7 @@
|
||||
"description": "project-manifest.current_phase: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"title": "The Attention Commons",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
@@ -103,7 +103,7 @@
|
||||
"description": "project-manifest.publication_status: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"title": "The Attention Commons",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
@@ -117,7 +117,7 @@
|
||||
"description": "project-manifest.provenance_policy_id: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"title": "The Attention Commons",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
@@ -131,7 +131,7 @@
|
||||
"description": "project-manifest.audio_retained: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"title": "The Attention Commons",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
@@ -145,7 +145,7 @@
|
||||
"description": "project-manifest: reject unexpected property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"title": "The Attention Commons",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
@@ -161,7 +161,7 @@
|
||||
"description": "project-manifest.schema_version: reject value different from const",
|
||||
"instance": {
|
||||
"schema_version": "__INVALID_CONST__",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"title": "The Attention Commons",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
@@ -191,7 +191,7 @@
|
||||
"description": "project-manifest.project_id: reject pattern mismatch",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "invalid-id",
|
||||
"title": "The Attention Commons",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
@@ -206,7 +206,7 @@
|
||||
"description": "project-manifest.title: reject string below minLength",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"title": "",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
@@ -221,7 +221,7 @@
|
||||
"description": "project-manifest.created_at: reject pattern mismatch",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"title": "The Attention Commons",
|
||||
"created_at": "not-a-timestamp",
|
||||
@@ -236,7 +236,7 @@
|
||||
"description": "project-manifest.updated_at: reject pattern mismatch",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"title": "The Attention Commons",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
@@ -251,7 +251,7 @@
|
||||
"description": "project-manifest.current_phase: reject value outside enum",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"title": "The Attention Commons",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
@@ -266,7 +266,7 @@
|
||||
"description": "project-manifest.publication_status: reject value outside enum",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"title": "The Attention Commons",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
@@ -281,7 +281,7 @@
|
||||
"description": "project-manifest.provenance_policy_id: reject pattern mismatch",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"title": "The Attention Commons",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
@@ -296,7 +296,7 @@
|
||||
"description": "project-manifest.audio_retained: reject value different from const",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"title": "The Attention Commons",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"creation_application_version": "0.3.0",
|
||||
"creation_application_version": "0.4.0",
|
||||
"retention_classification": "project_record",
|
||||
"template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777",
|
||||
"created_at": "2026-07-17T18:42:10.123Z"
|
||||
@@ -33,7 +33,7 @@
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"creation_application_version": "0.3.0",
|
||||
"creation_application_version": "0.4.0",
|
||||
"retention_classification": "project_record",
|
||||
"template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777",
|
||||
"created_at": "2026-07-17T18:42:10.123Z"
|
||||
@@ -52,7 +52,7 @@
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"creation_application_version": "0.3.0",
|
||||
"creation_application_version": "0.4.0",
|
||||
"retention_classification": "project_record",
|
||||
"template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777",
|
||||
"created_at": "2026-07-17T18:42:10.123Z"
|
||||
@@ -71,7 +71,7 @@
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"creation_application_version": "0.3.0",
|
||||
"creation_application_version": "0.4.0",
|
||||
"retention_classification": "project_record",
|
||||
"template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777",
|
||||
"created_at": "2026-07-17T18:42:10.123Z"
|
||||
@@ -90,7 +90,7 @@
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"creation_application_version": "0.3.0",
|
||||
"creation_application_version": "0.4.0",
|
||||
"retention_classification": "project_record",
|
||||
"template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777",
|
||||
"created_at": "2026-07-17T18:42:10.123Z"
|
||||
@@ -104,7 +104,7 @@
|
||||
"version": 1,
|
||||
"purpose": "draft_from_selected_ideas",
|
||||
"canonical_template_body": "Use {{context}} to draft a passage.",
|
||||
"creation_application_version": "0.3.0",
|
||||
"creation_application_version": "0.4.0",
|
||||
"retention_classification": "project_record",
|
||||
"template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777",
|
||||
"created_at": "2026-07-17T18:42:10.123Z"
|
||||
@@ -143,7 +143,7 @@
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"creation_application_version": "0.3.0",
|
||||
"creation_application_version": "0.4.0",
|
||||
"template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777",
|
||||
"created_at": "2026-07-17T18:42:10.123Z"
|
||||
}
|
||||
@@ -162,7 +162,7 @@
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"creation_application_version": "0.3.0",
|
||||
"creation_application_version": "0.4.0",
|
||||
"retention_classification": "project_record",
|
||||
"created_at": "2026-07-17T18:42:10.123Z"
|
||||
}
|
||||
@@ -181,7 +181,7 @@
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"creation_application_version": "0.3.0",
|
||||
"creation_application_version": "0.4.0",
|
||||
"retention_classification": "project_record",
|
||||
"template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777"
|
||||
}
|
||||
@@ -200,7 +200,7 @@
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"creation_application_version": "0.3.0",
|
||||
"creation_application_version": "0.4.0",
|
||||
"retention_classification": "project_record",
|
||||
"template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
@@ -221,7 +221,7 @@
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"creation_application_version": "0.3.0",
|
||||
"creation_application_version": "0.4.0",
|
||||
"retention_classification": "project_record",
|
||||
"template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777",
|
||||
"created_at": "2026-07-17T18:42:10.123Z"
|
||||
@@ -241,7 +241,7 @@
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"creation_application_version": "0.3.0",
|
||||
"creation_application_version": "0.4.0",
|
||||
"retention_classification": "project_record",
|
||||
"template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777",
|
||||
"created_at": "2026-07-17T18:42:10.123Z"
|
||||
@@ -261,7 +261,7 @@
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"creation_application_version": "0.3.0",
|
||||
"creation_application_version": "0.4.0",
|
||||
"retention_classification": "project_record",
|
||||
"template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777",
|
||||
"created_at": "2026-07-17T18:42:10.123Z"
|
||||
@@ -281,7 +281,7 @@
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"creation_application_version": "0.3.0",
|
||||
"creation_application_version": "0.4.0",
|
||||
"retention_classification": "project_record",
|
||||
"template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777",
|
||||
"created_at": "2026-07-17T18:42:10.123Z"
|
||||
@@ -301,7 +301,7 @@
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"creation_application_version": "0.3.0",
|
||||
"creation_application_version": "0.4.0",
|
||||
"retention_classification": "project_record",
|
||||
"template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777",
|
||||
"created_at": "2026-07-17T18:42:10.123Z"
|
||||
@@ -341,7 +341,7 @@
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"creation_application_version": "0.3.0",
|
||||
"creation_application_version": "0.4.0",
|
||||
"retention_classification": "__INVALID_ENUM__",
|
||||
"template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777",
|
||||
"created_at": "2026-07-17T18:42:10.123Z"
|
||||
@@ -361,7 +361,7 @@
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"creation_application_version": "0.3.0",
|
||||
"creation_application_version": "0.4.0",
|
||||
"retention_classification": "project_record",
|
||||
"template_sha256": "sha256:INVALID",
|
||||
"created_at": "2026-07-17T18:42:10.123Z"
|
||||
@@ -381,7 +381,7 @@
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"creation_application_version": "0.3.0",
|
||||
"creation_application_version": "0.4.0",
|
||||
"retention_classification": "project_record",
|
||||
"template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777",
|
||||
"created_at": "not-a-timestamp"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@
|
||||
{
|
||||
"description": "release-manifest.schema_version: reject missing required property",
|
||||
"instance": {
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
@@ -67,7 +67,7 @@
|
||||
"description": "release-manifest.release_id: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
"created_at": "2026-07-17T18:43:11.456Z",
|
||||
@@ -98,7 +98,7 @@
|
||||
"description": "release-manifest.project_id: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"version": "1.0.0",
|
||||
"created_at": "2026-07-17T18:43:11.456Z",
|
||||
@@ -129,7 +129,7 @@
|
||||
"description": "release-manifest.version: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:43:11.456Z",
|
||||
@@ -160,7 +160,7 @@
|
||||
"description": "release-manifest.created_at: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
@@ -191,7 +191,7 @@
|
||||
"description": "release-manifest.source_commit: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
@@ -222,7 +222,7 @@
|
||||
"description": "release-manifest.source_chain_head: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
@@ -253,7 +253,7 @@
|
||||
"description": "release-manifest.source_manuscript: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
@@ -281,7 +281,7 @@
|
||||
"description": "release-manifest.sanitized: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
@@ -312,7 +312,7 @@
|
||||
"description": "release-manifest.files: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
@@ -332,7 +332,7 @@
|
||||
"description": "release-manifest.release_files_merkle_root: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
@@ -363,7 +363,7 @@
|
||||
"description": "release-manifest.merkle_algorithm: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
@@ -394,7 +394,7 @@
|
||||
"description": "release-manifest: reject unexpected property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
@@ -427,7 +427,7 @@
|
||||
"description": "release-manifest.schema_version: reject value different from const",
|
||||
"instance": {
|
||||
"schema_version": "__INVALID_CONST__",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
@@ -491,7 +491,7 @@
|
||||
"description": "release-manifest.release_id: reject pattern mismatch",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "invalid-id",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
@@ -523,7 +523,7 @@
|
||||
"description": "release-manifest.project_id: reject pattern mismatch",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "invalid-id",
|
||||
"version": "1.0.0",
|
||||
@@ -555,7 +555,7 @@
|
||||
"description": "release-manifest.version: reject pattern mismatch",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": " invalid!",
|
||||
@@ -587,7 +587,7 @@
|
||||
"description": "release-manifest.created_at: reject pattern mismatch",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
@@ -619,7 +619,7 @@
|
||||
"description": "release-manifest.source_commit: reject pattern mismatch",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
@@ -651,7 +651,7 @@
|
||||
"description": "release-manifest.source_chain_head: reject pattern mismatch",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
@@ -683,7 +683,7 @@
|
||||
"description": "release-manifest.source_manuscript.path: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
@@ -714,7 +714,7 @@
|
||||
"description": "release-manifest.source_manuscript.sha256: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
@@ -745,7 +745,7 @@
|
||||
"description": "release-manifest.source_manuscript: reject unexpected property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
@@ -778,7 +778,7 @@
|
||||
"description": "release-manifest.source_manuscript.path: reject pattern mismatch",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
@@ -810,7 +810,7 @@
|
||||
"description": "release-manifest.source_manuscript.path: reject string below minLength",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
@@ -842,7 +842,7 @@
|
||||
"description": "release-manifest.source_manuscript.sha256: reject pattern mismatch",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
@@ -874,7 +874,7 @@
|
||||
"description": "release-manifest.files: reject array below minItems",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
@@ -895,7 +895,7 @@
|
||||
"description": "release-manifest.files[0].path: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
@@ -926,7 +926,7 @@
|
||||
"description": "release-manifest.files[0].sha256: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
@@ -957,7 +957,7 @@
|
||||
"description": "release-manifest.files[0].size: reject missing required property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
@@ -988,7 +988,7 @@
|
||||
"description": "release-manifest.files[0]: reject unexpected property",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
@@ -1021,7 +1021,7 @@
|
||||
"description": "release-manifest.files[0].path: reject pattern mismatch",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
@@ -1053,7 +1053,7 @@
|
||||
"description": "release-manifest.files[0].path: reject string below minLength",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
@@ -1085,7 +1085,7 @@
|
||||
"description": "release-manifest.files[0].sha256: reject pattern mismatch",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
@@ -1117,7 +1117,7 @@
|
||||
"description": "release-manifest.files[0].size: reject value below minimum",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
@@ -1149,7 +1149,7 @@
|
||||
"description": "release-manifest.release_files_merkle_root: reject pattern mismatch",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
@@ -1181,7 +1181,7 @@
|
||||
"description": "release-manifest.merkle_algorithm: reject value different from const",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
{
|
||||
"schema": "https://thinkloom.app/schemas/provenance/1.0/assertion-evaluation.schema.json",
|
||||
"description": "Valid Point-in-time assertion evaluation example.",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"evaluation_id": "evaluation_01J0000000000000000000000W",
|
||||
"assertion_id": "assertion_01J0000000000000000000000V",
|
||||
"assertion_sha256": "sha256:f6770d587b8f2af9a86ceaa67f9dd7346fe46708f2654871424c0431a7f9e826",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"evaluated_against": {
|
||||
"chain_head": "sha256:6666666666666666666666666666666666666666666666666666666666666666",
|
||||
"event_sequence": 3,
|
||||
"project_epoch": 1,
|
||||
"schema_catalog_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777"
|
||||
},
|
||||
"evaluator": {
|
||||
"subsystem": "native_verifier",
|
||||
"application_version": "0.4.0"
|
||||
},
|
||||
"status": "exact",
|
||||
"confidence": {
|
||||
"integrity": "exact",
|
||||
"identity": "exact",
|
||||
"chronology": "exact",
|
||||
"derivation": "exact",
|
||||
"authorship": "not_applicable",
|
||||
"completeness": "exact"
|
||||
},
|
||||
"boundary": null,
|
||||
"dependency_results": [
|
||||
{
|
||||
"dependency_id": "event_01J00000000000000000000004",
|
||||
"evidence_class": "mandatory_retained",
|
||||
"status": "valid",
|
||||
"observed_sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555",
|
||||
"observed_generation": {
|
||||
"project_epoch": 1,
|
||||
"artifact_revision": 12,
|
||||
"transcript_revision": 4
|
||||
}
|
||||
},
|
||||
{
|
||||
"dependency_id": "record_01J00000000000000000000005",
|
||||
"evidence_class": "mandatory_live",
|
||||
"status": "valid",
|
||||
"observed_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888",
|
||||
"observed_generation": {
|
||||
"project_epoch": 1,
|
||||
"artifact_revision": 12,
|
||||
"transcript_revision": 4
|
||||
}
|
||||
},
|
||||
{
|
||||
"dependency_id": "turn_01J00000000000000000000007",
|
||||
"evidence_class": "advisory",
|
||||
"status": "valid",
|
||||
"observed_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777",
|
||||
"observed_generation": {
|
||||
"project_epoch": 1,
|
||||
"artifact_revision": 12,
|
||||
"transcript_revision": 4
|
||||
}
|
||||
},
|
||||
{
|
||||
"dependency_id": "idea_01J00000000000000000000009",
|
||||
"evidence_class": "shadow",
|
||||
"status": "not_evaluated",
|
||||
"observed_sha256": null,
|
||||
"observed_generation": null
|
||||
}
|
||||
],
|
||||
"reason_code": "DIRECT_HASH_LINKED_DERIVATION",
|
||||
"supersedes_evaluation_id": null,
|
||||
"evaluated_at": "2026-07-17T18:44:12.789Z"
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
"description": "Valid Project backup manifest example.",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"description": "Valid Project manifest example.",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"title": "The Attention Commons",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"creation_application_version": "0.3.0",
|
||||
"creation_application_version": "0.4.0",
|
||||
"retention_classification": "project_record",
|
||||
"template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777",
|
||||
"created_at": "2026-07-17T18:42:10.123Z"
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
{
|
||||
"schema": "https://thinkloom.app/schemas/provenance/1.0/provenance-assertion.schema.json",
|
||||
"description": "Valid Canonical provenance assertion example.",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"assertion_id": "assertion_01J0000000000000000000000V",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"subject": {
|
||||
"entity_type": "artifact_revision",
|
||||
"entity_id": "revision_01J0000000000000000000000B",
|
||||
"content_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
|
||||
},
|
||||
"predicate": "derived_from",
|
||||
"object": {
|
||||
"entity_type": "invocation_output",
|
||||
"entity_id": "record_01J00000000000000000000005",
|
||||
"content_sha256": "sha256:9999999999999999999999999999999999999999999999999999999999999999"
|
||||
},
|
||||
"source_anchor": {
|
||||
"event_id": "event_01J00000000000000000000004",
|
||||
"event_sequence": 2,
|
||||
"event_hash": "sha256:5555555555555555555555555555555555555555555555555555555555555555"
|
||||
},
|
||||
"source_generation": {
|
||||
"project_epoch": 1,
|
||||
"artifact_revision": 12,
|
||||
"transcript_revision": 4
|
||||
},
|
||||
"lifecycle_phase": "accepted_into_work",
|
||||
"producer": {
|
||||
"subsystem": "provenance_writer",
|
||||
"application_version": "0.4.0"
|
||||
},
|
||||
"provenance": {
|
||||
"basis": "direct_record",
|
||||
"evidence": [
|
||||
{
|
||||
"evidence_id": "event_01J00000000000000000000004",
|
||||
"evidence_type": "provenance_event",
|
||||
"content_sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555"
|
||||
},
|
||||
{
|
||||
"evidence_id": "record_01J00000000000000000000005",
|
||||
"evidence_type": "invocation_response",
|
||||
"content_sha256": "sha256:9999999999999999999999999999999999999999999999999999999999999999"
|
||||
}
|
||||
]
|
||||
},
|
||||
"dependencies": [
|
||||
{
|
||||
"dependency_id": "event_01J00000000000000000000004",
|
||||
"dependency_type": "provenance_event",
|
||||
"expected_sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555",
|
||||
"expected_generation": {
|
||||
"project_epoch": 1,
|
||||
"artifact_revision": 12,
|
||||
"transcript_revision": 4
|
||||
},
|
||||
"evidence_class": "mandatory_retained",
|
||||
"role": "source_anchor",
|
||||
"confidence_dimensions": [
|
||||
"integrity",
|
||||
"chronology",
|
||||
"derivation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dependency_id": "record_01J00000000000000000000005",
|
||||
"dependency_type": "model_configuration",
|
||||
"expected_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888",
|
||||
"expected_generation": {
|
||||
"project_epoch": 1,
|
||||
"artifact_revision": 12,
|
||||
"transcript_revision": 4
|
||||
},
|
||||
"evidence_class": "mandatory_live",
|
||||
"role": "model_configuration",
|
||||
"confidence_dimensions": [
|
||||
"identity",
|
||||
"derivation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dependency_id": "turn_01J00000000000000000000007",
|
||||
"dependency_type": "transcript_turn",
|
||||
"expected_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777",
|
||||
"expected_generation": {
|
||||
"project_epoch": 1,
|
||||
"artifact_revision": 12,
|
||||
"transcript_revision": 4
|
||||
},
|
||||
"evidence_class": "advisory",
|
||||
"role": "authorship_basis",
|
||||
"confidence_dimensions": [
|
||||
"authorship",
|
||||
"completeness"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dependency_id": "idea_01J00000000000000000000009",
|
||||
"dependency_type": "shadow_comparison",
|
||||
"expected_sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222",
|
||||
"expected_generation": {
|
||||
"project_epoch": 1,
|
||||
"artifact_revision": 12,
|
||||
"transcript_revision": 4
|
||||
},
|
||||
"evidence_class": "shadow",
|
||||
"role": "other",
|
||||
"confidence_dimensions": [
|
||||
"completeness"
|
||||
]
|
||||
}
|
||||
],
|
||||
"reason_code": "DIRECT_HASH_LINKED_DERIVATION",
|
||||
"created_at": "2026-07-17T18:43:11.456Z",
|
||||
"assertion_sha256": "sha256:f6770d587b8f2af9a86ceaa67f9dd7346fe46708f2654871424c0431a7f9e826"
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
"description": "Valid Release manifest example.",
|
||||
"instance": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
"examples": [
|
||||
{
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"title": "The Attention Commons",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"creation_application_version": "0.3.0",
|
||||
"creation_application_version": "0.4.0",
|
||||
"retention_classification": "project_record",
|
||||
"template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777",
|
||||
"created_at": "2026-07-17T18:42:10.123Z"
|
||||
|
||||
@@ -0,0 +1,557 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://thinkloom.app/schemas/provenance/1.0/provenance-assertion.schema.json",
|
||||
"title": "Canonical provenance assertion",
|
||||
"description": "Immutable machine-evaluable subject-predicate-object assertion anchored to prior authoritative evidence. Its digest identity excludes only assertion_sha256.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"schema_version": {
|
||||
"const": "1.0"
|
||||
},
|
||||
"assertion_id": {
|
||||
"type": "string",
|
||||
"pattern": "^assertion_[0-9A-HJKMNP-TV-Z]{26}$"
|
||||
},
|
||||
"project_id": {
|
||||
"type": "string",
|
||||
"pattern": "^project_[0-9A-HJKMNP-TV-Z]{26}$"
|
||||
},
|
||||
"subject": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"entity_type": {
|
||||
"enum": [
|
||||
"project",
|
||||
"artifact_revision",
|
||||
"manuscript_revision",
|
||||
"idea_revision",
|
||||
"transcript_revision",
|
||||
"invocation_request",
|
||||
"invocation_output",
|
||||
"prompt_template",
|
||||
"model_configuration",
|
||||
"release",
|
||||
"assertion",
|
||||
"other"
|
||||
]
|
||||
},
|
||||
"entity_id": {
|
||||
"type": "string",
|
||||
"pattern": "^[a-z][a-z0-9_]*_[0-9A-HJKMNP-TV-Z]{26}$"
|
||||
},
|
||||
"content_sha256": {
|
||||
"type": "string",
|
||||
"pattern": "^sha256:[a-f0-9]{64}$"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"entity_type",
|
||||
"entity_id",
|
||||
"content_sha256"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"predicate": {
|
||||
"type": "string",
|
||||
"pattern": "^[a-z][a-z0-9_]+$"
|
||||
},
|
||||
"object": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"entity_type": {
|
||||
"enum": [
|
||||
"project",
|
||||
"artifact_revision",
|
||||
"manuscript_revision",
|
||||
"idea_revision",
|
||||
"transcript_revision",
|
||||
"invocation_request",
|
||||
"invocation_output",
|
||||
"prompt_template",
|
||||
"model_configuration",
|
||||
"release",
|
||||
"assertion",
|
||||
"other"
|
||||
]
|
||||
},
|
||||
"entity_id": {
|
||||
"type": "string",
|
||||
"pattern": "^[a-z][a-z0-9_]*_[0-9A-HJKMNP-TV-Z]{26}$"
|
||||
},
|
||||
"content_sha256": {
|
||||
"type": "string",
|
||||
"pattern": "^sha256:[a-f0-9]{64}$"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"entity_type",
|
||||
"entity_id",
|
||||
"content_sha256"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"source_anchor": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"event_id": {
|
||||
"type": "string",
|
||||
"pattern": "^event_[0-9A-HJKMNP-TV-Z]{26}$"
|
||||
},
|
||||
"event_sequence": {
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
},
|
||||
"event_hash": {
|
||||
"type": "string",
|
||||
"pattern": "^sha256:[a-f0-9]{64}$"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"event_id",
|
||||
"event_sequence",
|
||||
"event_hash"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"source_generation": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"project_epoch": {
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
},
|
||||
"artifact_revision": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"transcript_revision": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"project_epoch",
|
||||
"artifact_revision",
|
||||
"transcript_revision"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"lifecycle_phase": {
|
||||
"enum": [
|
||||
"proposed",
|
||||
"generated",
|
||||
"staged_preview",
|
||||
"accepted_into_work",
|
||||
"revised",
|
||||
"finalized",
|
||||
"published",
|
||||
"superseded",
|
||||
"purged"
|
||||
]
|
||||
},
|
||||
"producer": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"subsystem": {
|
||||
"type": "string",
|
||||
"pattern": "^[a-z][a-z0-9_]+$"
|
||||
},
|
||||
"application_version": {
|
||||
"type": "string",
|
||||
"pattern": "^\\d+\\.\\d+\\.\\d+$"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"subsystem",
|
||||
"application_version"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"provenance": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"basis": {
|
||||
"enum": [
|
||||
"direct_record",
|
||||
"deterministic_derivation",
|
||||
"declared_relationship",
|
||||
"verifier_observation"
|
||||
]
|
||||
},
|
||||
"evidence": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"evidence_id": {
|
||||
"type": "string",
|
||||
"pattern": "^[a-z][a-z0-9_]*_[0-9A-HJKMNP-TV-Z]{26}$"
|
||||
},
|
||||
"evidence_type": {
|
||||
"type": "string",
|
||||
"pattern": "^[a-z][a-z0-9_]+$"
|
||||
},
|
||||
"content_sha256": {
|
||||
"type": "string",
|
||||
"pattern": "^sha256:[a-f0-9]{64}$"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"evidence_id",
|
||||
"evidence_type",
|
||||
"content_sha256"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"minItems": 1
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"basis",
|
||||
"evidence"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"dependencies": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"dependency_id": {
|
||||
"type": "string",
|
||||
"pattern": "^[a-z][a-z0-9_]*_[0-9A-HJKMNP-TV-Z]{26}$"
|
||||
},
|
||||
"dependency_type": {
|
||||
"type": "string",
|
||||
"pattern": "^[a-z][a-z0-9_]+$"
|
||||
},
|
||||
"expected_sha256": {
|
||||
"type": "string",
|
||||
"pattern": "^sha256:[a-f0-9]{64}$"
|
||||
},
|
||||
"expected_generation": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"project_epoch": {
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
},
|
||||
"artifact_revision": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"transcript_revision": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"project_epoch",
|
||||
"artifact_revision",
|
||||
"transcript_revision"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"evidence_class": {
|
||||
"enum": [
|
||||
"mandatory_live",
|
||||
"mandatory_retained",
|
||||
"advisory",
|
||||
"shadow"
|
||||
]
|
||||
},
|
||||
"role": {
|
||||
"enum": [
|
||||
"source_anchor",
|
||||
"content_basis",
|
||||
"model_configuration",
|
||||
"prompt_template",
|
||||
"authorship_basis",
|
||||
"chronology_basis",
|
||||
"compatibility_basis",
|
||||
"other"
|
||||
]
|
||||
},
|
||||
"confidence_dimensions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"enum": [
|
||||
"integrity",
|
||||
"identity",
|
||||
"chronology",
|
||||
"derivation",
|
||||
"authorship",
|
||||
"completeness"
|
||||
]
|
||||
},
|
||||
"minItems": 1,
|
||||
"uniqueItems": true
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"dependency_id",
|
||||
"dependency_type",
|
||||
"expected_sha256",
|
||||
"expected_generation",
|
||||
"evidence_class",
|
||||
"role",
|
||||
"confidence_dimensions"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"minItems": 1
|
||||
},
|
||||
"reason_code": {
|
||||
"enum": [
|
||||
"DIRECT_HASH_LINKED_DERIVATION",
|
||||
"VERIFIED_TRANSITIVE_DERIVATION"
|
||||
]
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$"
|
||||
},
|
||||
"assertion_sha256": {
|
||||
"type": "string",
|
||||
"pattern": "^sha256:[a-f0-9]{64}$"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"schema_version",
|
||||
"assertion_id",
|
||||
"project_id",
|
||||
"subject",
|
||||
"predicate",
|
||||
"object",
|
||||
"source_anchor",
|
||||
"source_generation",
|
||||
"lifecycle_phase",
|
||||
"producer",
|
||||
"provenance",
|
||||
"dependencies",
|
||||
"reason_code",
|
||||
"created_at",
|
||||
"assertion_sha256"
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"allOf": [
|
||||
{
|
||||
"if": {
|
||||
"properties": {
|
||||
"subject": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"entity_type": {
|
||||
"const": "artifact_revision"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"entity_type"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"subject"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
"properties": {
|
||||
"source_generation": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"artifact_revision": {
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"artifact_revision"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": {
|
||||
"properties": {
|
||||
"subject": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"entity_type": {
|
||||
"const": "transcript_revision"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"entity_type"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"subject"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
"properties": {
|
||||
"source_generation": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"transcript_revision": {
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"transcript_revision"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"examples": [
|
||||
{
|
||||
"schema_version": "1.0",
|
||||
"assertion_id": "assertion_01J0000000000000000000000V",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"subject": {
|
||||
"entity_type": "artifact_revision",
|
||||
"entity_id": "revision_01J0000000000000000000000B",
|
||||
"content_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
|
||||
},
|
||||
"predicate": "derived_from",
|
||||
"object": {
|
||||
"entity_type": "invocation_output",
|
||||
"entity_id": "record_01J00000000000000000000005",
|
||||
"content_sha256": "sha256:9999999999999999999999999999999999999999999999999999999999999999"
|
||||
},
|
||||
"source_anchor": {
|
||||
"event_id": "event_01J00000000000000000000004",
|
||||
"event_sequence": 2,
|
||||
"event_hash": "sha256:5555555555555555555555555555555555555555555555555555555555555555"
|
||||
},
|
||||
"source_generation": {
|
||||
"project_epoch": 1,
|
||||
"artifact_revision": 12,
|
||||
"transcript_revision": 4
|
||||
},
|
||||
"lifecycle_phase": "accepted_into_work",
|
||||
"producer": {
|
||||
"subsystem": "provenance_writer",
|
||||
"application_version": "0.4.0"
|
||||
},
|
||||
"provenance": {
|
||||
"basis": "direct_record",
|
||||
"evidence": [
|
||||
{
|
||||
"evidence_id": "event_01J00000000000000000000004",
|
||||
"evidence_type": "provenance_event",
|
||||
"content_sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555"
|
||||
},
|
||||
{
|
||||
"evidence_id": "record_01J00000000000000000000005",
|
||||
"evidence_type": "invocation_response",
|
||||
"content_sha256": "sha256:9999999999999999999999999999999999999999999999999999999999999999"
|
||||
}
|
||||
]
|
||||
},
|
||||
"dependencies": [
|
||||
{
|
||||
"dependency_id": "event_01J00000000000000000000004",
|
||||
"dependency_type": "provenance_event",
|
||||
"expected_sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555",
|
||||
"expected_generation": {
|
||||
"project_epoch": 1,
|
||||
"artifact_revision": 12,
|
||||
"transcript_revision": 4
|
||||
},
|
||||
"evidence_class": "mandatory_retained",
|
||||
"role": "source_anchor",
|
||||
"confidence_dimensions": [
|
||||
"integrity",
|
||||
"chronology",
|
||||
"derivation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dependency_id": "record_01J00000000000000000000005",
|
||||
"dependency_type": "model_configuration",
|
||||
"expected_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888",
|
||||
"expected_generation": {
|
||||
"project_epoch": 1,
|
||||
"artifact_revision": 12,
|
||||
"transcript_revision": 4
|
||||
},
|
||||
"evidence_class": "mandatory_live",
|
||||
"role": "model_configuration",
|
||||
"confidence_dimensions": [
|
||||
"identity",
|
||||
"derivation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dependency_id": "turn_01J00000000000000000000007",
|
||||
"dependency_type": "transcript_turn",
|
||||
"expected_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777",
|
||||
"expected_generation": {
|
||||
"project_epoch": 1,
|
||||
"artifact_revision": 12,
|
||||
"transcript_revision": 4
|
||||
},
|
||||
"evidence_class": "advisory",
|
||||
"role": "authorship_basis",
|
||||
"confidence_dimensions": [
|
||||
"authorship",
|
||||
"completeness"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dependency_id": "idea_01J00000000000000000000009",
|
||||
"dependency_type": "shadow_comparison",
|
||||
"expected_sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222",
|
||||
"expected_generation": {
|
||||
"project_epoch": 1,
|
||||
"artifact_revision": 12,
|
||||
"transcript_revision": 4
|
||||
},
|
||||
"evidence_class": "shadow",
|
||||
"role": "other",
|
||||
"confidence_dimensions": [
|
||||
"completeness"
|
||||
]
|
||||
}
|
||||
],
|
||||
"reason_code": "DIRECT_HASH_LINKED_DERIVATION",
|
||||
"created_at": "2026-07-17T18:43:11.456Z",
|
||||
"assertion_sha256": "sha256:f6770d587b8f2af9a86ceaa67f9dd7346fe46708f2654871424c0431a7f9e826"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"registry_version": "1.0",
|
||||
"provenance_schema_version": "1.0",
|
||||
"application_version": "0.4.0",
|
||||
"name": "assertion-boundary-kinds",
|
||||
"description": "Machine-readable boundaries preventing an unqualified exact conclusion.",
|
||||
"entries": [
|
||||
{
|
||||
"code": "missing_provenance",
|
||||
"meaning": "Required provenance basis or evidence identity is absent."
|
||||
},
|
||||
{
|
||||
"code": "unknown_generation",
|
||||
"meaning": "A required source or dependency generation is unknown."
|
||||
},
|
||||
{
|
||||
"code": "evidence_access",
|
||||
"meaning": "Evidence exists or is expected but cannot currently be accessed."
|
||||
},
|
||||
{
|
||||
"code": "compatibility",
|
||||
"meaning": "The observed schema or producer contract is incompatible."
|
||||
},
|
||||
{
|
||||
"code": "dependency_change",
|
||||
"meaning": "A dependency digest, generation, or source anchor changed."
|
||||
},
|
||||
{
|
||||
"code": "policy",
|
||||
"meaning": "A retention, authorization, or disclosure policy prohibits evaluation."
|
||||
},
|
||||
{
|
||||
"code": "interpretation",
|
||||
"meaning": "Evidence integrity is known but its asserted interpretation is limited."
|
||||
},
|
||||
{
|
||||
"code": "coverage",
|
||||
"meaning": "The evaluation does not cover every element required by the assertion scope."
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"registry_version": "1.0",
|
||||
"provenance_schema_version": "1.0",
|
||||
"application_version": "0.4.0",
|
||||
"name": "assertion-confidence-dimensions",
|
||||
"description": "Independent non-numeric confidence dimensions.",
|
||||
"values": [
|
||||
"exact",
|
||||
"degraded",
|
||||
"unverified",
|
||||
"not_applicable"
|
||||
],
|
||||
"entries": [
|
||||
{
|
||||
"code": "integrity",
|
||||
"meaning": "Whether canonical bytes, digests, and chain bindings validate."
|
||||
},
|
||||
{
|
||||
"code": "identity",
|
||||
"meaning": "Whether referenced subjects, objects, producers, and evidence identities resolve."
|
||||
},
|
||||
{
|
||||
"code": "chronology",
|
||||
"meaning": "Whether ordering and generation coordinates are complete and consistent."
|
||||
},
|
||||
{
|
||||
"code": "derivation",
|
||||
"meaning": "Whether the asserted transformation or relationship is supported by evidence."
|
||||
},
|
||||
{
|
||||
"code": "authorship",
|
||||
"meaning": "Whether the claimed actor relationship is supported without percentage attribution."
|
||||
},
|
||||
{
|
||||
"code": "completeness",
|
||||
"meaning": "Whether all evidence required for the asserted scope was evaluated."
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"registry_version": "1.0",
|
||||
"provenance_schema_version": "1.0",
|
||||
"application_version": "0.4.0",
|
||||
"name": "assertion-evaluation-statuses",
|
||||
"description": "Consumer-facing point-in-time assertion conclusions.",
|
||||
"entries": [
|
||||
{
|
||||
"code": "exact",
|
||||
"consumer_action": "promote",
|
||||
"meaning": "All mandatory evidence and relevant confidence dimensions support the asserted scope."
|
||||
},
|
||||
{
|
||||
"code": "degraded",
|
||||
"consumer_action": "warn",
|
||||
"meaning": "Use is possible only within the recorded uncertainty boundary."
|
||||
},
|
||||
{
|
||||
"code": "refused",
|
||||
"consumer_action": "refuse",
|
||||
"meaning": "Policy, authorization, or compatibility prohibits a conclusion."
|
||||
},
|
||||
{
|
||||
"code": "stale",
|
||||
"consumer_action": "reevaluate",
|
||||
"meaning": "A source anchor, digest, or generation dependency changed."
|
||||
},
|
||||
{
|
||||
"code": "unverified",
|
||||
"consumer_action": "withhold_exact",
|
||||
"meaning": "Mandatory evaluation or evidence is incomplete without a demonstrated contradiction."
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"registry_version": "1.0",
|
||||
"provenance_schema_version": "1.0",
|
||||
"application_version": "0.4.0",
|
||||
"name": "assertion-evidence-classes",
|
||||
"description": "Evidence availability and authority requirements.",
|
||||
"entries": [
|
||||
{
|
||||
"code": "mandatory_live",
|
||||
"exact_effect": "required",
|
||||
"meaning": "Current accessible evidence is required for exact evaluation."
|
||||
},
|
||||
{
|
||||
"code": "mandatory_retained",
|
||||
"exact_effect": "required",
|
||||
"meaning": "Retained authoritative evidence and its digest are required for exact evaluation."
|
||||
},
|
||||
{
|
||||
"code": "advisory",
|
||||
"exact_effect": "may_degrade",
|
||||
"meaning": "Absence may degrade a named dimension but does not alter authoritative evidence."
|
||||
},
|
||||
{
|
||||
"code": "shadow",
|
||||
"exact_effect": "no_authority",
|
||||
"meaning": "Comparison-only evidence that never becomes authoritative by observation."
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"registry_version": "1.0",
|
||||
"provenance_schema_version": "1.0",
|
||||
"application_version": "0.4.0",
|
||||
"name": "assertion-lifecycle-phases",
|
||||
"description": "Immutable assertion lifecycle phase observed when the relationship was asserted.",
|
||||
"entries": [
|
||||
{
|
||||
"code": "proposed",
|
||||
"meaning": "A relationship has been proposed but not adopted."
|
||||
},
|
||||
{
|
||||
"code": "generated",
|
||||
"meaning": "A relationship was produced by a deterministic or model-assisted operation."
|
||||
},
|
||||
{
|
||||
"code": "staged_preview",
|
||||
"meaning": "The relationship is visible for review but not accepted into canonical work."
|
||||
},
|
||||
{
|
||||
"code": "accepted_into_work",
|
||||
"meaning": "The relationship was explicitly accepted into canonical project work."
|
||||
},
|
||||
{
|
||||
"code": "revised",
|
||||
"meaning": "The relationship describes a later immutable revision."
|
||||
},
|
||||
{
|
||||
"code": "finalized",
|
||||
"meaning": "The relationship belongs to finalized project content."
|
||||
},
|
||||
{
|
||||
"code": "published",
|
||||
"meaning": "The relationship is bound into a published release."
|
||||
},
|
||||
{
|
||||
"code": "superseded",
|
||||
"meaning": "A later assertion replaces this relationship for current interpretation without erasing it."
|
||||
},
|
||||
{
|
||||
"code": "purged",
|
||||
"meaning": "The relationship is affected by an explicitly disclosed emergency reconstitution."
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
{
|
||||
"registry_version": "1.0",
|
||||
"provenance_schema_version": "1.0",
|
||||
"application_version": "0.4.0",
|
||||
"name": "assertion-reason-codes",
|
||||
"description": "Stable explanations for assertion creation and evaluation outcomes.",
|
||||
"entries": [
|
||||
{
|
||||
"code": "DIRECT_HASH_LINKED_DERIVATION",
|
||||
"permitted_statuses": [
|
||||
"exact"
|
||||
],
|
||||
"meaning": "The asserted relationship is supported by direct retained records and matching digests."
|
||||
},
|
||||
{
|
||||
"code": "VERIFIED_TRANSITIVE_DERIVATION",
|
||||
"permitted_statuses": [
|
||||
"exact"
|
||||
],
|
||||
"meaning": "A deterministic verified chain of assertions supports the relationship."
|
||||
},
|
||||
{
|
||||
"code": "REQUIRED_PROVENANCE_UNKNOWN",
|
||||
"permitted_statuses": [
|
||||
"unverified"
|
||||
],
|
||||
"meaning": "Required provenance basis or evidence identity is unknown."
|
||||
},
|
||||
{
|
||||
"code": "SOURCE_GENERATION_UNKNOWN",
|
||||
"permitted_statuses": [
|
||||
"unverified"
|
||||
],
|
||||
"meaning": "A required project, artifact, or transcript generation is unknown."
|
||||
},
|
||||
{
|
||||
"code": "REQUIRED_EVIDENCE_MISSING",
|
||||
"permitted_statuses": [
|
||||
"unverified"
|
||||
],
|
||||
"meaning": "Evidence required for evaluation is absent."
|
||||
},
|
||||
{
|
||||
"code": "DEPENDENCY_DIGEST_MISMATCH",
|
||||
"permitted_statuses": [
|
||||
"stale"
|
||||
],
|
||||
"meaning": "A dependency digest differs from the asserted expectation."
|
||||
},
|
||||
{
|
||||
"code": "DEPENDENCY_GENERATION_MISMATCH",
|
||||
"permitted_statuses": [
|
||||
"stale"
|
||||
],
|
||||
"meaning": "A dependency generation differs from the asserted expectation."
|
||||
},
|
||||
{
|
||||
"code": "SOURCE_ANCHOR_STALE",
|
||||
"permitted_statuses": [
|
||||
"stale"
|
||||
],
|
||||
"meaning": "The source anchor no longer matches the evaluation target."
|
||||
},
|
||||
{
|
||||
"code": "SCHEMA_INCOMPATIBLE",
|
||||
"permitted_statuses": [
|
||||
"refused"
|
||||
],
|
||||
"meaning": "The available schema cannot be evaluated under the required contract."
|
||||
},
|
||||
{
|
||||
"code": "POLICY_REFUSED",
|
||||
"permitted_statuses": [
|
||||
"refused"
|
||||
],
|
||||
"meaning": "Policy explicitly prohibits producing the requested conclusion."
|
||||
},
|
||||
{
|
||||
"code": "AUTHORIZED_EVIDENCE_UNAVAILABLE",
|
||||
"permitted_statuses": [
|
||||
"refused",
|
||||
"unverified"
|
||||
],
|
||||
"meaning": "Required protected evidence cannot be evaluated with current authorization."
|
||||
},
|
||||
{
|
||||
"code": "ADVISORY_EVIDENCE_UNAVAILABLE",
|
||||
"permitted_statuses": [
|
||||
"degraded"
|
||||
],
|
||||
"meaning": "Advisory evidence is unavailable and the named confidence dimensions are degraded."
|
||||
},
|
||||
{
|
||||
"code": "ASSERTION_NOT_EVALUATED",
|
||||
"permitted_statuses": [
|
||||
"unverified"
|
||||
],
|
||||
"meaning": "No authoritative evaluation has completed for this assertion and target."
|
||||
},
|
||||
{
|
||||
"code": "AUTHORSHIP_UNCERTAIN",
|
||||
"permitted_statuses": [
|
||||
"degraded"
|
||||
],
|
||||
"meaning": "Evidence does not support an exact authorship interpretation."
|
||||
},
|
||||
{
|
||||
"code": "CHRONOLOGY_INCOMPLETE",
|
||||
"permitted_statuses": [
|
||||
"degraded",
|
||||
"unverified"
|
||||
],
|
||||
"meaning": "Ordering or generation evidence is incomplete."
|
||||
},
|
||||
{
|
||||
"code": "COMPLETENESS_INCOMPLETE",
|
||||
"permitted_statuses": [
|
||||
"degraded",
|
||||
"unverified"
|
||||
],
|
||||
"meaning": "The evaluation does not cover all evidence required by its asserted scope."
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -114,7 +114,7 @@
|
||||
"examples": [
|
||||
{
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
||||
"vector_version": "1.0",
|
||||
"backup_manifest": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"source_chain_head": "sha256:51935af27a4c989a014d975eab929f41fccafadedfbf1baafa15e3ce2a27a66d",
|
||||
@@ -26,7 +26,7 @@
|
||||
},
|
||||
"release_manifest": {
|
||||
"schema_version": "1.0",
|
||||
"application_version": "0.3.0",
|
||||
"application_version": "0.4.0",
|
||||
"release_id": "release_01J0000000000000000000000E",
|
||||
"project_id": "project_01J00000000000000000000001",
|
||||
"version": "1.0.0",
|
||||
|
||||
@@ -13,11 +13,11 @@
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"creation_application_version": "0.3.0",
|
||||
"creation_application_version": "0.4.0",
|
||||
"retention_classification": "project_record",
|
||||
"created_at": "2026-07-17T18:42:10.123Z"
|
||||
},
|
||||
"digest": "sha256:73055322741f5a248ae79ca2c38f699e40da7b5b5576f83a615a9816ddab8ba3",
|
||||
"digest": "sha256:d13871e34755e1e115d5b58bd96286f9ce02b82f774247ad2bb1f41e8de0c3d8",
|
||||
"complete_record": {
|
||||
"schema_version": "1.0",
|
||||
"template_id": "template_01J0000000000000000000000F",
|
||||
@@ -30,10 +30,10 @@
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"creation_application_version": "0.3.0",
|
||||
"creation_application_version": "0.4.0",
|
||||
"retention_classification": "project_record",
|
||||
"created_at": "2026-07-17T18:42:10.123Z",
|
||||
"template_sha256": "sha256:73055322741f5a248ae79ca2c38f699e40da7b5b5576f83a615a9816ddab8ba3"
|
||||
"template_sha256": "sha256:d13871e34755e1e115d5b58bd96286f9ce02b82f774247ad2bb1f41e8de0c3d8"
|
||||
},
|
||||
"excluded_fields": [
|
||||
"template_sha256"
|
||||
|
||||
@@ -8,6 +8,7 @@ const output = path.join(root, "schemas", "provenance", "v1");
|
||||
const validDir = path.join(output, "fixtures", "valid");
|
||||
const invalidDir = path.join(output, "fixtures", "invalid");
|
||||
const vectorDir = path.join(output, "vectors");
|
||||
const registryDir = path.join(output, "registries");
|
||||
const baseId = "https://thinkloom.app/schemas/provenance/1.0";
|
||||
const draft = "https://json-schema.org/draft/2020-12/schema";
|
||||
const timestampValue = "2026-07-17T18:42:10.123Z";
|
||||
@@ -22,6 +23,7 @@ const ids = {
|
||||
checkpoint: typedId("checkpoint", "D"), release: typedId("release", "E"), template: typedId("template", "F"), key: typedId("key", "G"),
|
||||
policy: typedId("policy", "H"), correction: typedId("correction", "J"), normalization: typedId("normalization", "K"), disposition: typedId("disposition", "M"),
|
||||
transaction: typedId("transaction", "N"), failure: typedId("failure", "P"), stream: typedId("stream", "Q"), purge: typedId("purge", "R"),
|
||||
assertion: typedId("assertion", "V"), evaluation: typedId("evaluation", "W"),
|
||||
};
|
||||
|
||||
if (!Object.values(ids).every((value) => /^[a-z]+_[0-9A-HJKMNP-TV-Z]{26}$/.test(value))) throw new Error("Generated fixture identifier is invalid.");
|
||||
@@ -31,6 +33,7 @@ const timestamp = { type: "string", format: "date-time", pattern: "^\\d{4}-\\d{2
|
||||
const sha = { type: "string", pattern: "^sha256:[a-f0-9]{64}$" };
|
||||
const ulidPattern = "[0-9A-HJKMNP-TV-Z]{26}";
|
||||
const identifier = (prefix) => ({ type: "string", pattern: `^${prefix}_${ulidPattern}$` });
|
||||
const typedIdentifier = { type: "string", pattern: `^[a-z][a-z0-9_]*_${ulidPattern}$` };
|
||||
const repositoryPath = { type: "string", minLength: 1, pattern: "^(?!/)(?![A-Za-z]:)(?!.*\\\\)(?!.*(?:^|/)\\.\\.?(?:/|$))[^\\u0000-\\u001f]+$" };
|
||||
const nonEmptyString = { type: "string", minLength: 1 };
|
||||
const jsonValue = {};
|
||||
@@ -40,6 +43,60 @@ const arrayOf = (items, options = {}) => ({ type: "array", items, ...options });
|
||||
const mapOf = (additionalProperties) => ({ type: "object", additionalProperties });
|
||||
const closed = (properties, required = Object.keys(properties), extra = {}) => ({ type: "object", properties, required, additionalProperties: false, ...extra });
|
||||
|
||||
const assertionLifecyclePhases = ["proposed", "generated", "staged_preview", "accepted_into_work", "revised", "finalized", "published", "superseded", "purged"];
|
||||
const assertionEvaluationStatuses = ["exact", "degraded", "refused", "stale", "unverified"];
|
||||
const confidenceDimensions = ["integrity", "identity", "chronology", "derivation", "authorship", "completeness"];
|
||||
const confidenceValues = ["exact", "degraded", "unverified", "not_applicable"];
|
||||
const evidenceClasses = ["mandatory_live", "mandatory_retained", "advisory", "shadow"];
|
||||
const assertionBoundaryKinds = ["missing_provenance", "unknown_generation", "evidence_access", "compatibility", "dependency_change", "policy", "interpretation", "coverage"];
|
||||
const dependencyResultStatuses = ["valid", "missing", "changed", "inaccessible", "incompatible", "not_evaluated"];
|
||||
const assertionReasonCodes = [
|
||||
"DIRECT_HASH_LINKED_DERIVATION",
|
||||
"VERIFIED_TRANSITIVE_DERIVATION",
|
||||
"REQUIRED_PROVENANCE_UNKNOWN",
|
||||
"SOURCE_GENERATION_UNKNOWN",
|
||||
"REQUIRED_EVIDENCE_MISSING",
|
||||
"DEPENDENCY_DIGEST_MISMATCH",
|
||||
"DEPENDENCY_GENERATION_MISMATCH",
|
||||
"SOURCE_ANCHOR_STALE",
|
||||
"SCHEMA_INCOMPATIBLE",
|
||||
"POLICY_REFUSED",
|
||||
"AUTHORIZED_EVIDENCE_UNAVAILABLE",
|
||||
"ADVISORY_EVIDENCE_UNAVAILABLE",
|
||||
"ASSERTION_NOT_EVALUATED",
|
||||
"AUTHORSHIP_UNCERTAIN",
|
||||
"CHRONOLOGY_INCOMPLETE",
|
||||
"COMPLETENESS_INCOMPLETE",
|
||||
];
|
||||
const assertionBoundaryMeanings = {
|
||||
missing_provenance: "Required provenance basis or evidence identity is absent.",
|
||||
unknown_generation: "A required source or dependency generation is unknown.",
|
||||
evidence_access: "Evidence exists or is expected but cannot currently be accessed.",
|
||||
compatibility: "The observed schema or producer contract is incompatible.",
|
||||
dependency_change: "A dependency digest, generation, or source anchor changed.",
|
||||
policy: "A retention, authorization, or disclosure policy prohibits evaluation.",
|
||||
interpretation: "Evidence integrity is known but its asserted interpretation is limited.",
|
||||
coverage: "The evaluation does not cover every element required by the assertion scope.",
|
||||
};
|
||||
const assertionReasonMeanings = {
|
||||
DIRECT_HASH_LINKED_DERIVATION: "The asserted relationship is supported by direct retained records and matching digests.",
|
||||
VERIFIED_TRANSITIVE_DERIVATION: "A deterministic verified chain of assertions supports the relationship.",
|
||||
REQUIRED_PROVENANCE_UNKNOWN: "Required provenance basis or evidence identity is unknown.",
|
||||
SOURCE_GENERATION_UNKNOWN: "A required project, artifact, or transcript generation is unknown.",
|
||||
REQUIRED_EVIDENCE_MISSING: "Evidence required for evaluation is absent.",
|
||||
DEPENDENCY_DIGEST_MISMATCH: "A dependency digest differs from the asserted expectation.",
|
||||
DEPENDENCY_GENERATION_MISMATCH: "A dependency generation differs from the asserted expectation.",
|
||||
SOURCE_ANCHOR_STALE: "The source anchor no longer matches the evaluation target.",
|
||||
SCHEMA_INCOMPATIBLE: "The available schema cannot be evaluated under the required contract.",
|
||||
POLICY_REFUSED: "Policy explicitly prohibits producing the requested conclusion.",
|
||||
AUTHORIZED_EVIDENCE_UNAVAILABLE: "Required protected evidence cannot be evaluated with current authorization.",
|
||||
ADVISORY_EVIDENCE_UNAVAILABLE: "Advisory evidence is unavailable and the named confidence dimensions are degraded.",
|
||||
ASSERTION_NOT_EVALUATED: "No authoritative evaluation has completed for this assertion and target.",
|
||||
AUTHORSHIP_UNCERTAIN: "Evidence does not support an exact authorship interpretation.",
|
||||
CHRONOLOGY_INCOMPLETE: "Ordering or generation evidence is incomplete.",
|
||||
COMPLETENESS_INCOMPLETE: "The evaluation does not cover all evidence required by its asserted scope.",
|
||||
};
|
||||
|
||||
const schemas = new Map();
|
||||
function add(name, title, body, example, description) {
|
||||
const schema = { $schema: draft, $id: `${baseId}/${name}.schema.json`, title, description, ...body, examples: [example] };
|
||||
@@ -83,8 +140,8 @@ const contentReferenceExample = {
|
||||
};
|
||||
add("content-reference", "Content reference", closed({
|
||||
schema_version: schemaVersion,
|
||||
record_id: identifier("record"),
|
||||
record_type: { enum: ["conversation_turn", "invocation_request", "invocation_response", "invocation_failure", "idea_revision", "manuscript_revision", "edit_transaction", "prompt_template", "model_configuration", "release_file", "source", "other"] },
|
||||
record_id: typedIdentifier,
|
||||
record_type: { enum: ["conversation_turn", "invocation_request", "invocation_response", "invocation_failure", "idea_revision", "manuscript_revision", "edit_transaction", "prompt_template", "model_configuration", "provenance_assertion", "assertion_evaluation", "release_file", "source", "other"] },
|
||||
sha256: sha,
|
||||
path: nullable(repositoryPath),
|
||||
revision_id: nullable(identifier("revision")),
|
||||
@@ -99,7 +156,7 @@ add("provenance-policy", "Provenance policy", closed({
|
||||
}), policyExample, "Prospective project retention, protection, and export defaults.");
|
||||
|
||||
const projectExample = {
|
||||
schema_version: "1.0", application_version: "0.3.0", project_id: ids.project, title: "The Attention Commons", created_at: timestampValue, updated_at: laterTimestamp, current_phase: "ideation", publication_status: "working", provenance_policy_id: ids.policy, audio_retained: false,
|
||||
schema_version: "1.0", application_version: "0.4.0", project_id: ids.project, title: "The Attention Commons", created_at: timestampValue, updated_at: laterTimestamp, current_phase: "ideation", publication_status: "working", provenance_policy_id: ids.policy, audio_retained: false,
|
||||
};
|
||||
add("project-manifest", "Project manifest", closed({
|
||||
schema_version: schemaVersion, application_version: { type: "string", pattern: "^\\d+\\.\\d+\\.\\d+$" }, project_id: identifier("project"), title: nonEmptyString, description: { type: "string" }, created_at: timestamp, updated_at: timestamp, current_phase: { enum: ["ideation", "drafting", "finalization"] }, publication_status: { enum: ["working", "finalized", "published"] }, provenance_policy_id: identifier("policy"), audio_retained: { const: false },
|
||||
@@ -125,7 +182,7 @@ add("chain-head", "Chain head", closed({ schema_version: schemaVersion, project_
|
||||
const segmentExample = { schema_version: "1.0", project_id: ids.project, segment_number: 1, previous_segment_file_hash: null, first_event_hash: digest("4"), final_event_hash: digest("5"), first_event_sequence: 1, final_event_sequence: 2, event_count: 2, byte_length: 1024, segment_file_hash: digest("6"), sealed_at: timestampValue };
|
||||
add("ledger-segment-manifest", "Ledger segment manifest", closed({ schema_version: schemaVersion, project_id: identifier("project"), segment_number: { type: "integer", minimum: 1 }, previous_segment_file_hash: nullable(sha), first_event_hash: sha, final_event_hash: sha, first_event_sequence: { type: "integer", minimum: 1 }, final_event_sequence: { type: "integer", minimum: 1 }, event_count: { type: "integer", minimum: 1 }, byte_length: { type: "integer", minimum: 1 }, segment_file_hash: sha, sealed_at: timestamp }), segmentExample, "Immutable seal for one ledger segment.");
|
||||
|
||||
const promptExample = { schema_version: "1.0", template_id: ids.template, version: 1, purpose: "draft_from_selected_ideas", canonical_template_body: "Use {{context}} to draft a passage.", variables: { context: { description: "Selected idea context", required: true } }, creation_application_version: "0.3.0", retention_classification: "project_record", template_sha256: digest("7"), created_at: timestampValue };
|
||||
const promptExample = { schema_version: "1.0", template_id: ids.template, version: 1, purpose: "draft_from_selected_ideas", canonical_template_body: "Use {{context}} to draft a passage.", variables: { context: { description: "Selected idea context", required: true } }, creation_application_version: "0.4.0", retention_classification: "project_record", template_sha256: digest("7"), created_at: timestampValue };
|
||||
add("prompt-template", "Prompt template", closed({ schema_version: schemaVersion, template_id: identifier("template"), version: { type: "integer", minimum: 1 }, purpose: { type: "string", pattern: "^[a-z][a-z0-9_]+$" }, canonical_template_body: nonEmptyString, variables: mapOf(closed({ description: nonEmptyString, required: { type: "boolean" } })), creation_application_version: { type: "string", pattern: "^\\d+\\.\\d+\\.\\d+$" }, retention_classification: { enum: ["application_default", "project_record", "protected_project_record"] }, template_sha256: sha, created_at: timestamp }), promptExample, "Immutable versioned prompt template. Its digest identity excludes template_sha256.");
|
||||
|
||||
const promptRefExample = { schema_version: "1.0", template_id: ids.template, version: 1, path: "records/prompt-templates/drafting/template.json", template_sha256: digest("7") };
|
||||
@@ -236,17 +293,189 @@ add("disposition-revision", "Invocation disposition revision", closed({ schema_v
|
||||
const indexManifestExample = { schema_version: "1.0", index_type: "contribution_graph", source_chain_head: digest("f"), source_event_count: 42, generator: { name: "thinkloom-indexer", version: "1.0.0", configuration_sha256: digest("0") }, content_sha256: digest("1"), generated_at: timestampValue };
|
||||
add("derived-index-manifest", "Derived index manifest", closed({ schema_version: schemaVersion, index_type: { enum: ["content_index", "contribution_graph", "manuscript_lineage", "checkpoint_index"] }, source_chain_head: sha, source_event_count: { type: "integer", minimum: 0 }, generator: closed({ name: nonEmptyString, version: { type: "string", pattern: "^\\d+\\.\\d+\\.\\d+$" }, configuration_sha256: sha }), content_sha256: sha, generated_at: timestamp }), indexManifestExample, "Non-authoritative reproducibility metadata for a derived index.");
|
||||
|
||||
const generationCoordinates = closed({
|
||||
project_epoch: { type: "integer", minimum: 1 },
|
||||
artifact_revision: nullable({ type: "integer", minimum: 1 }),
|
||||
transcript_revision: nullable({ type: "integer", minimum: 1 }),
|
||||
});
|
||||
const assertionEntityReference = closed({
|
||||
entity_type: { enum: ["project", "artifact_revision", "manuscript_revision", "idea_revision", "transcript_revision", "invocation_request", "invocation_output", "prompt_template", "model_configuration", "release", "assertion", "other"] },
|
||||
entity_id: typedIdentifier,
|
||||
content_sha256: sha,
|
||||
});
|
||||
const assertionProducer = closed({
|
||||
subsystem: { type: "string", pattern: "^[a-z][a-z0-9_]+$" },
|
||||
application_version: { type: "string", pattern: "^\\d+\\.\\d+\\.\\d+$" },
|
||||
});
|
||||
const assertionEvidence = closed({
|
||||
evidence_id: typedIdentifier,
|
||||
evidence_type: { type: "string", pattern: "^[a-z][a-z0-9_]+$" },
|
||||
content_sha256: sha,
|
||||
});
|
||||
const assertionDependency = closed({
|
||||
dependency_id: typedIdentifier,
|
||||
dependency_type: { type: "string", pattern: "^[a-z][a-z0-9_]+$" },
|
||||
expected_sha256: sha,
|
||||
expected_generation: generationCoordinates,
|
||||
evidence_class: { enum: evidenceClasses },
|
||||
role: { enum: ["source_anchor", "content_basis", "model_configuration", "prompt_template", "authorship_basis", "chronology_basis", "compatibility_basis", "other"] },
|
||||
confidence_dimensions: arrayOf({ enum: confidenceDimensions }, { minItems: 1, uniqueItems: true }),
|
||||
});
|
||||
const assertionIdentity = {
|
||||
schema_version: "1.0",
|
||||
assertion_id: ids.assertion,
|
||||
project_id: ids.project,
|
||||
subject: { entity_type: "artifact_revision", entity_id: ids.revision2, content_sha256: digest("e") },
|
||||
predicate: "derived_from",
|
||||
object: { entity_type: "invocation_output", entity_id: ids.record, content_sha256: digest("9") },
|
||||
source_anchor: { event_id: ids.event2, event_sequence: 2, event_hash: digest("5") },
|
||||
source_generation: { project_epoch: 1, artifact_revision: 12, transcript_revision: 4 },
|
||||
lifecycle_phase: "accepted_into_work",
|
||||
producer: { subsystem: "provenance_writer", application_version: "0.4.0" },
|
||||
provenance: { basis: "direct_record", evidence: [{ evidence_id: ids.event2, evidence_type: "provenance_event", content_sha256: digest("5") }, { evidence_id: ids.record, evidence_type: "invocation_response", content_sha256: digest("9") }] },
|
||||
dependencies: [
|
||||
{ dependency_id: ids.event2, dependency_type: "provenance_event", expected_sha256: digest("5"), expected_generation: { project_epoch: 1, artifact_revision: 12, transcript_revision: 4 }, evidence_class: "mandatory_retained", role: "source_anchor", confidence_dimensions: ["integrity", "chronology", "derivation"] },
|
||||
{ dependency_id: ids.record, dependency_type: "model_configuration", expected_sha256: digest("8"), expected_generation: { project_epoch: 1, artifact_revision: 12, transcript_revision: 4 }, evidence_class: "mandatory_live", role: "model_configuration", confidence_dimensions: ["identity", "derivation"] },
|
||||
{ dependency_id: ids.turn, dependency_type: "transcript_turn", expected_sha256: digest("7"), expected_generation: { project_epoch: 1, artifact_revision: 12, transcript_revision: 4 }, evidence_class: "advisory", role: "authorship_basis", confidence_dimensions: ["authorship", "completeness"] },
|
||||
{ dependency_id: ids.idea, dependency_type: "shadow_comparison", expected_sha256: digest("2"), expected_generation: { project_epoch: 1, artifact_revision: 12, transcript_revision: 4 }, evidence_class: "shadow", role: "other", confidence_dimensions: ["completeness"] },
|
||||
],
|
||||
reason_code: "DIRECT_HASH_LINKED_DERIVATION",
|
||||
created_at: laterTimestamp,
|
||||
};
|
||||
const assertionExample = { ...assertionIdentity, assertion_sha256: sha256(assertionIdentity) };
|
||||
const assertionRules = {
|
||||
allOf: [
|
||||
{
|
||||
if: { properties: { subject: { type: "object", properties: { entity_type: { const: "artifact_revision" } }, required: ["entity_type"] } }, required: ["subject"] },
|
||||
then: { properties: { source_generation: { type: "object", properties: { artifact_revision: { type: "integer", minimum: 1 } }, required: ["artifact_revision"] } } },
|
||||
},
|
||||
{
|
||||
if: { properties: { subject: { type: "object", properties: { entity_type: { const: "transcript_revision" } }, required: ["entity_type"] } }, required: ["subject"] },
|
||||
then: { properties: { source_generation: { type: "object", properties: { transcript_revision: { type: "integer", minimum: 1 } }, required: ["transcript_revision"] } } },
|
||||
},
|
||||
],
|
||||
};
|
||||
add("provenance-assertion", "Canonical provenance assertion", closed({
|
||||
schema_version: schemaVersion,
|
||||
assertion_id: identifier("assertion"),
|
||||
project_id: identifier("project"),
|
||||
subject: assertionEntityReference,
|
||||
predicate: { type: "string", pattern: "^[a-z][a-z0-9_]+$" },
|
||||
object: assertionEntityReference,
|
||||
source_anchor: closed({ event_id: identifier("event"), event_sequence: { type: "integer", minimum: 1 }, event_hash: sha }),
|
||||
source_generation: generationCoordinates,
|
||||
lifecycle_phase: { enum: assertionLifecyclePhases },
|
||||
producer: assertionProducer,
|
||||
provenance: closed({ basis: { enum: ["direct_record", "deterministic_derivation", "declared_relationship", "verifier_observation"] }, evidence: arrayOf(assertionEvidence, { minItems: 1 }) }),
|
||||
dependencies: arrayOf(assertionDependency, { minItems: 1 }),
|
||||
reason_code: { enum: ["DIRECT_HASH_LINKED_DERIVATION", "VERIFIED_TRANSITIVE_DERIVATION"] },
|
||||
created_at: timestamp,
|
||||
assertion_sha256: sha,
|
||||
}, undefined, assertionRules), assertionExample, "Immutable machine-evaluable subject-predicate-object assertion anchored to prior authoritative evidence. Its digest identity excludes only assertion_sha256.");
|
||||
|
||||
const confidenceAssessment = closed(Object.fromEntries(confidenceDimensions.map((dimension) => [dimension, { enum: confidenceValues }])));
|
||||
const assertionBoundary = closed({
|
||||
kind: { enum: assertionBoundaryKinds },
|
||||
affected_dimensions: arrayOf({ enum: confidenceDimensions }, { minItems: 1, uniqueItems: true }),
|
||||
dependency_ids: arrayOf(typedIdentifier, { uniqueItems: true }),
|
||||
compatibility: nullable(closed({ required_schema: nonEmptyString, observed_schema: nullable(nonEmptyString) })),
|
||||
});
|
||||
const dependencyResult = closed({
|
||||
dependency_id: typedIdentifier,
|
||||
evidence_class: { enum: evidenceClasses },
|
||||
status: { enum: dependencyResultStatuses },
|
||||
observed_sha256: nullable(sha),
|
||||
observed_generation: nullable(generationCoordinates),
|
||||
});
|
||||
const evaluationExample = {
|
||||
schema_version: "1.0",
|
||||
evaluation_id: ids.evaluation,
|
||||
assertion_id: ids.assertion,
|
||||
assertion_sha256: assertionExample.assertion_sha256,
|
||||
project_id: ids.project,
|
||||
evaluated_against: { chain_head: digest("6"), event_sequence: 3, project_epoch: 1, schema_catalog_sha256: digest("7") },
|
||||
evaluator: { subsystem: "native_verifier", application_version: "0.4.0" },
|
||||
status: "exact",
|
||||
confidence: { integrity: "exact", identity: "exact", chronology: "exact", derivation: "exact", authorship: "not_applicable", completeness: "exact" },
|
||||
boundary: null,
|
||||
dependency_results: [
|
||||
{ dependency_id: ids.event2, evidence_class: "mandatory_retained", status: "valid", observed_sha256: digest("5"), observed_generation: { project_epoch: 1, artifact_revision: 12, transcript_revision: 4 } },
|
||||
{ dependency_id: ids.record, evidence_class: "mandatory_live", status: "valid", observed_sha256: digest("8"), observed_generation: { project_epoch: 1, artifact_revision: 12, transcript_revision: 4 } },
|
||||
{ dependency_id: ids.turn, evidence_class: "advisory", status: "valid", observed_sha256: digest("7"), observed_generation: { project_epoch: 1, artifact_revision: 12, transcript_revision: 4 } },
|
||||
{ dependency_id: ids.idea, evidence_class: "shadow", status: "not_evaluated", observed_sha256: null, observed_generation: null },
|
||||
],
|
||||
reason_code: "DIRECT_HASH_LINKED_DERIVATION",
|
||||
supersedes_evaluation_id: null,
|
||||
evaluated_at: "2026-07-17T18:44:12.789Z",
|
||||
};
|
||||
const exactConfidenceProperties = Object.fromEntries(confidenceDimensions.map((dimension) => [dimension, { enum: ["exact", "not_applicable"] }]));
|
||||
const evaluationRules = {
|
||||
allOf: [
|
||||
{
|
||||
if: { properties: { status: { const: "exact" } }, required: ["status"] },
|
||||
then: { properties: {
|
||||
boundary: { type: "null" },
|
||||
reason_code: { enum: ["DIRECT_HASH_LINKED_DERIVATION", "VERIFIED_TRANSITIVE_DERIVATION"] },
|
||||
confidence: { type: "object", properties: exactConfidenceProperties, required: confidenceDimensions },
|
||||
dependency_results: { type: "array", items: { type: "object", if: { properties: { evidence_class: { const: "shadow" } }, required: ["evidence_class"] }, else: { properties: { status: { const: "valid" } }, required: ["status"] } } },
|
||||
} },
|
||||
},
|
||||
{
|
||||
if: { properties: { status: { not: { const: "exact" } } }, required: ["status"] },
|
||||
then: { properties: { boundary: { not: { type: "null" } } } },
|
||||
},
|
||||
{
|
||||
if: { properties: { status: { const: "degraded" } }, required: ["status"] },
|
||||
then: { properties: {
|
||||
reason_code: { enum: ["ADVISORY_EVIDENCE_UNAVAILABLE", "AUTHORSHIP_UNCERTAIN", "CHRONOLOGY_INCOMPLETE", "COMPLETENESS_INCOMPLETE"] },
|
||||
confidence: { type: "object", anyOf: confidenceDimensions.map((dimension) => ({ properties: { [dimension]: { const: "degraded" } }, required: [dimension] })) },
|
||||
dependency_results: { type: "array", not: { contains: { type: "object", properties: { evidence_class: { enum: ["mandatory_live", "mandatory_retained"] }, status: { not: { const: "valid" } } }, required: ["evidence_class", "status"] } } },
|
||||
} },
|
||||
},
|
||||
{
|
||||
if: { properties: { status: { const: "refused" } }, required: ["status"] },
|
||||
then: { properties: { reason_code: { enum: ["SCHEMA_INCOMPATIBLE", "POLICY_REFUSED", "AUTHORIZED_EVIDENCE_UNAVAILABLE"] } } },
|
||||
},
|
||||
{
|
||||
if: { properties: { status: { const: "stale" } }, required: ["status"] },
|
||||
then: { properties: {
|
||||
reason_code: { enum: ["DEPENDENCY_DIGEST_MISMATCH", "DEPENDENCY_GENERATION_MISMATCH", "SOURCE_ANCHOR_STALE"] },
|
||||
dependency_results: { type: "array", contains: { type: "object", properties: { status: { const: "changed" } }, required: ["status"] }, minContains: 1 },
|
||||
} },
|
||||
},
|
||||
{
|
||||
if: { properties: { status: { const: "unverified" } }, required: ["status"] },
|
||||
then: { properties: { reason_code: { enum: ["REQUIRED_PROVENANCE_UNKNOWN", "SOURCE_GENERATION_UNKNOWN", "REQUIRED_EVIDENCE_MISSING", "AUTHORIZED_EVIDENCE_UNAVAILABLE", "ASSERTION_NOT_EVALUATED", "CHRONOLOGY_INCOMPLETE", "COMPLETENESS_INCOMPLETE"] } } },
|
||||
},
|
||||
],
|
||||
};
|
||||
add("assertion-evaluation", "Point-in-time assertion evaluation", closed({
|
||||
schema_version: schemaVersion,
|
||||
evaluation_id: identifier("evaluation"),
|
||||
assertion_id: identifier("assertion"),
|
||||
assertion_sha256: sha,
|
||||
project_id: identifier("project"),
|
||||
evaluated_against: closed({ chain_head: sha, event_sequence: { type: "integer", minimum: 1 }, project_epoch: { type: "integer", minimum: 1 }, schema_catalog_sha256: sha }),
|
||||
evaluator: assertionProducer,
|
||||
status: { enum: assertionEvaluationStatuses },
|
||||
confidence: confidenceAssessment,
|
||||
boundary: nullable(assertionBoundary),
|
||||
dependency_results: arrayOf(dependencyResult, { minItems: 1 }),
|
||||
reason_code: { enum: assertionReasonCodes },
|
||||
supersedes_evaluation_id: nullable(identifier("evaluation")),
|
||||
evaluated_at: timestamp,
|
||||
}, undefined, evaluationRules), evaluationExample, "Immutable verifier conclusion about one assertion at an explicit chain head and project epoch.");
|
||||
const verificationExample = { schema_version: "1.0", verification_id: ids.record, project_id: ids.project, status: "VERIFIED_WITH_WARNINGS", verified_through_event_id: ids.event, verified_chain_head: digest("4"), checked_segments: 1, checked_events: 1, checked_records: 4, findings: [{ severity: "WARNING", code: "INDEX_STALE", message: "Contribution index is stale.", authoritative_evidence_affected: false, path: "provenance/indexes/contribution-graph.json", event_id: null }], verifier_version: "1.0.0", completed_at: laterTimestamp };
|
||||
add("verification-report", "Verification report", closed({ schema_version: schemaVersion, verification_id: identifier("record"), project_id: identifier("project"), status: { enum: ["VERIFIED", "VERIFIED_WITH_WARNINGS", "INCOMPLETE", "FAILED", "UNSAFE"] }, verified_through_event_id: nullable(identifier("event")), verified_chain_head: nullable(sha), checked_segments: { type: "integer", minimum: 0 }, checked_events: { type: "integer", minimum: 0 }, checked_records: { type: "integer", minimum: 0 }, findings: arrayOf(finding), verifier_version: { type: "string", pattern: "^\\d+\\.\\d+\\.\\d+$" }, completed_at: timestamp }), verificationExample, "Authoritative native verification result rendered by the UI.");
|
||||
|
||||
const backupExample = { schema_version: "1.0", application_version: "0.3.0", project_id: ids.project, created_at: timestampValue, source_chain_head: digest("4"), sqlite_snapshot: { path: "database-snapshot/state.sqlite", sha256: digest("2"), size: 4096, sqlite_version: "3.46.0", database_schema_version: 1, completed_at: timestampValue }, files: [{ path: "project.json", sha256: digest("3"), size: 256 }], protected: false, recovery_key_envelope_path: null };
|
||||
const backupExample = { schema_version: "1.0", application_version: "0.4.0", project_id: ids.project, created_at: timestampValue, source_chain_head: digest("4"), sqlite_snapshot: { path: "database-snapshot/state.sqlite", sha256: digest("2"), size: 4096, sqlite_version: "3.46.0", database_schema_version: 1, completed_at: timestampValue }, files: [{ path: "project.json", sha256: digest("3"), size: 256 }], protected: false, recovery_key_envelope_path: null };
|
||||
add("backup-manifest", "Project backup manifest", closed({ schema_version: schemaVersion, application_version: { type: "string", pattern: "^\\d+\\.\\d+\\.\\d+$" }, project_id: identifier("project"), created_at: timestamp, source_chain_head: sha, sqlite_snapshot: closed({ path: repositoryPath, sha256: sha, size: { type: "integer", minimum: 1 }, sqlite_version: nonEmptyString, database_schema_version: { type: "integer", minimum: 1 }, completed_at: timestamp }), files: arrayOf(fileEntry, { minItems: 1 }), protected: { type: "boolean" }, recovery_key_envelope_path: nullable(repositoryPath) }), backupExample, "Complete staged-backup inventory including a verified online SQLite snapshot.");
|
||||
|
||||
const releaseStateExample = { schema_version: "1.0", release_id: ids.release, project_id: ids.project, state: "RELEASE_STAGED", state_sequence: 5, source_commit: "0123456789abcdef0123456789abcdef01234567", source_chain_head: digest("4"), updated_at: laterTimestamp, failure: null };
|
||||
add("release-state", "Release state", closed({ schema_version: schemaVersion, release_id: identifier("release"), project_id: identifier("project"), state: { enum: ["WORKING", "FREEZING_SOURCE", "SOURCE_FROZEN", "GENERATING_RELEASE", "RELEASE_STAGED", "RELEASE_VERIFIED", "RELEASE_COMMITTED", "RELEASE_TAGGED", "COMPLETE", "RECOVERABLE", "FAILED"] }, state_sequence: { type: "integer", minimum: 1 }, source_commit: nullable({ type: "string", pattern: "^[a-f0-9]{40,64}$" }), source_chain_head: nullable(sha), updated_at: timestamp, failure: nullable(nonEmptyString) }), releaseStateExample, "Durable idempotent release-finalization state.");
|
||||
|
||||
const releaseFiles = [{ path: "manuscript/final-manuscript.md", sha256: digest("4"), size: 1024 }, { path: "evidence/creative-process-report.md", sha256: digest("5"), size: 512 }];
|
||||
const releaseExample = { schema_version: "1.0", application_version: "0.3.0", release_id: ids.release, project_id: ids.project, version: "1.0.0", created_at: laterTimestamp, source_commit: "0123456789abcdef0123456789abcdef01234567", source_chain_head: digest("4"), source_manuscript: { path: "manuscript/final-manuscript.md", sha256: digest("4") }, sanitized: false, files: releaseFiles, release_files_merkle_root: releaseMerkleRoot(releaseFiles), merkle_algorithm: "thinkloom-release-merkle-v1" };
|
||||
const releaseExample = { schema_version: "1.0", application_version: "0.4.0", release_id: ids.release, project_id: ids.project, version: "1.0.0", created_at: laterTimestamp, source_commit: "0123456789abcdef0123456789abcdef01234567", source_chain_head: digest("4"), source_manuscript: { path: "manuscript/final-manuscript.md", sha256: digest("4") }, sanitized: false, files: releaseFiles, release_files_merkle_root: releaseMerkleRoot(releaseFiles), merkle_algorithm: "thinkloom-release-merkle-v1" };
|
||||
add("release-manifest", "Release manifest", closed({ schema_version: schemaVersion, application_version: { type: "string", pattern: "^\\d+\\.\\d+\\.\\d+$" }, release_id: identifier("release"), project_id: identifier("project"), version: { type: "string", pattern: "^\\d+\\.\\d+\\.\\d+$" }, created_at: timestamp, source_commit: { type: "string", pattern: "^[a-f0-9]{40,64}$" }, source_chain_head: sha, source_manuscript: closed({ path: repositoryPath, sha256: sha }), sanitized: { type: "boolean" }, files: arrayOf(fileEntry, { minItems: 1 }), release_files_merkle_root: sha, merkle_algorithm: { const: "thinkloom-release-merkle-v1" } }), releaseExample, "Non-self-referential binding of a frozen source to verified release files.");
|
||||
|
||||
const sanitizedExample = { schema_version: "1.0", export_id: ids.record, project_id: ids.project, source_chain_head: digest("4"), profile: "sanitized", omission_rules: [{ category: "private_conversation", action: "exclude", count: 2 }], rules_sha256: digest("6"), files: [{ path: "final-manuscript.md", sha256: digest("4"), size: 1024 }], created_at: laterTimestamp };
|
||||
@@ -391,6 +620,29 @@ function invalidCases(name, schema, example) {
|
||||
instance.key_derivation = null;
|
||||
});
|
||||
}
|
||||
if (name === "provenance-assertion") {
|
||||
push("provenance-assertion: artifact generation must be explicit", (instance) => {
|
||||
instance.source_generation.artifact_revision = null;
|
||||
});
|
||||
|
||||
}
|
||||
if (name === "assertion-evaluation") {
|
||||
push("assertion-evaluation: unknown confidence cannot be exact", (instance) => {
|
||||
instance.confidence.derivation = "unverified";
|
||||
});
|
||||
push("assertion-evaluation: exact cannot carry an uncertainty boundary", (instance) => {
|
||||
instance.boundary = { kind: "coverage", affected_dimensions: ["completeness"], dependency_ids: [], compatibility: null };
|
||||
});
|
||||
push("assertion-evaluation: exact requires every dependency to validate", (instance) => {
|
||||
instance.dependency_results[0].status = "missing";
|
||||
instance.dependency_results[0].observed_sha256 = null;
|
||||
});
|
||||
push("assertion-evaluation: stale requires a changed dependency", (instance) => {
|
||||
instance.status = "stale";
|
||||
instance.boundary = { kind: "dependency_change", affected_dimensions: ["integrity"], dependency_ids: [instance.dependency_results[0].dependency_id], compatibility: null };
|
||||
instance.reason_code = "DEPENDENCY_DIGEST_MISMATCH";
|
||||
});
|
||||
}
|
||||
if (!cases.length) throw new Error(`No invalid fixture cases generated for ${name}.`);
|
||||
return cases;
|
||||
}
|
||||
@@ -400,7 +652,7 @@ async function writeJson(filePath, value) {
|
||||
}
|
||||
|
||||
await rm(output, { recursive: true, force: true });
|
||||
await Promise.all([validDir, invalidDir, vectorDir].map((directory) => mkdir(directory, { recursive: true })));
|
||||
await Promise.all([validDir, invalidDir, vectorDir, registryDir].map((directory) => mkdir(directory, { recursive: true })));
|
||||
|
||||
for (const name of schemaNames) {
|
||||
const schema = schemas.get(name);
|
||||
@@ -416,13 +668,104 @@ for (const name of schemaNames) {
|
||||
});
|
||||
}
|
||||
|
||||
const registries = [
|
||||
{
|
||||
name: "assertion-lifecycle-phases",
|
||||
description: "Immutable assertion lifecycle phase observed when the relationship was asserted.",
|
||||
entries: [
|
||||
{ code: "proposed", meaning: "A relationship has been proposed but not adopted." },
|
||||
{ code: "generated", meaning: "A relationship was produced by a deterministic or model-assisted operation." },
|
||||
{ code: "staged_preview", meaning: "The relationship is visible for review but not accepted into canonical work." },
|
||||
{ code: "accepted_into_work", meaning: "The relationship was explicitly accepted into canonical project work." },
|
||||
{ code: "revised", meaning: "The relationship describes a later immutable revision." },
|
||||
{ code: "finalized", meaning: "The relationship belongs to finalized project content." },
|
||||
{ code: "published", meaning: "The relationship is bound into a published release." },
|
||||
{ code: "superseded", meaning: "A later assertion replaces this relationship for current interpretation without erasing it." },
|
||||
{ code: "purged", meaning: "The relationship is affected by an explicitly disclosed emergency reconstitution." },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "assertion-evaluation-statuses",
|
||||
description: "Consumer-facing point-in-time assertion conclusions.",
|
||||
entries: [
|
||||
{ code: "exact", consumer_action: "promote", meaning: "All mandatory evidence and relevant confidence dimensions support the asserted scope." },
|
||||
{ code: "degraded", consumer_action: "warn", meaning: "Use is possible only within the recorded uncertainty boundary." },
|
||||
{ code: "refused", consumer_action: "refuse", meaning: "Policy, authorization, or compatibility prohibits a conclusion." },
|
||||
{ code: "stale", consumer_action: "reevaluate", meaning: "A source anchor, digest, or generation dependency changed." },
|
||||
{ code: "unverified", consumer_action: "withhold_exact", meaning: "Mandatory evaluation or evidence is incomplete without a demonstrated contradiction." },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "assertion-confidence-dimensions",
|
||||
description: "Independent non-numeric confidence dimensions.",
|
||||
values: confidenceValues,
|
||||
entries: [
|
||||
{ code: "integrity", meaning: "Whether canonical bytes, digests, and chain bindings validate." },
|
||||
{ code: "identity", meaning: "Whether referenced subjects, objects, producers, and evidence identities resolve." },
|
||||
{ code: "chronology", meaning: "Whether ordering and generation coordinates are complete and consistent." },
|
||||
{ code: "derivation", meaning: "Whether the asserted transformation or relationship is supported by evidence." },
|
||||
{ code: "authorship", meaning: "Whether the claimed actor relationship is supported without percentage attribution." },
|
||||
{ code: "completeness", meaning: "Whether all evidence required for the asserted scope was evaluated." },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "assertion-evidence-classes",
|
||||
description: "Evidence availability and authority requirements.",
|
||||
entries: [
|
||||
{ code: "mandatory_live", exact_effect: "required", meaning: "Current accessible evidence is required for exact evaluation." },
|
||||
{ code: "mandatory_retained", exact_effect: "required", meaning: "Retained authoritative evidence and its digest are required for exact evaluation." },
|
||||
{ code: "advisory", exact_effect: "may_degrade", meaning: "Absence may degrade a named dimension but does not alter authoritative evidence." },
|
||||
{ code: "shadow", exact_effect: "no_authority", meaning: "Comparison-only evidence that never becomes authoritative by observation." },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "assertion-boundary-kinds",
|
||||
description: "Machine-readable boundaries preventing an unqualified exact conclusion.",
|
||||
entries: assertionBoundaryKinds.map((code) => ({ code, meaning: assertionBoundaryMeanings[code] })),
|
||||
},
|
||||
{
|
||||
name: "assertion-reason-codes",
|
||||
description: "Stable explanations for assertion creation and evaluation outcomes.",
|
||||
entries: [
|
||||
{ code: "DIRECT_HASH_LINKED_DERIVATION", permitted_statuses: ["exact"] },
|
||||
{ code: "VERIFIED_TRANSITIVE_DERIVATION", permitted_statuses: ["exact"] },
|
||||
{ code: "REQUIRED_PROVENANCE_UNKNOWN", permitted_statuses: ["unverified"] },
|
||||
{ code: "SOURCE_GENERATION_UNKNOWN", permitted_statuses: ["unverified"] },
|
||||
{ code: "REQUIRED_EVIDENCE_MISSING", permitted_statuses: ["unverified"] },
|
||||
{ code: "DEPENDENCY_DIGEST_MISMATCH", permitted_statuses: ["stale"] },
|
||||
{ code: "DEPENDENCY_GENERATION_MISMATCH", permitted_statuses: ["stale"] },
|
||||
{ code: "SOURCE_ANCHOR_STALE", permitted_statuses: ["stale"] },
|
||||
{ code: "SCHEMA_INCOMPATIBLE", permitted_statuses: ["refused"] },
|
||||
{ code: "POLICY_REFUSED", permitted_statuses: ["refused"] },
|
||||
{ code: "AUTHORIZED_EVIDENCE_UNAVAILABLE", permitted_statuses: ["refused", "unverified"] },
|
||||
{ code: "ADVISORY_EVIDENCE_UNAVAILABLE", permitted_statuses: ["degraded"] },
|
||||
{ code: "ASSERTION_NOT_EVALUATED", permitted_statuses: ["unverified"] },
|
||||
{ code: "AUTHORSHIP_UNCERTAIN", permitted_statuses: ["degraded"] },
|
||||
{ code: "CHRONOLOGY_INCOMPLETE", permitted_statuses: ["degraded", "unverified"] },
|
||||
{ code: "COMPLETENESS_INCOMPLETE", permitted_statuses: ["degraded", "unverified"] },
|
||||
],
|
||||
},
|
||||
].map((registry) => ({
|
||||
registry_version: "1.0",
|
||||
provenance_schema_version: "1.0",
|
||||
application_version: "0.4.0",
|
||||
...registry,
|
||||
entries: registry.entries.map((entry) => registry.name === "assertion-reason-codes" ? { ...entry, meaning: assertionReasonMeanings[entry.code] } : entry),
|
||||
}));
|
||||
for (const registry of registries) await writeJson(path.join(registryDir, `${registry.name}.json`), registry);
|
||||
const catalog = {
|
||||
catalog_version: "1.0",
|
||||
dialect: draft,
|
||||
provenance_schema_version: "1.0",
|
||||
application_version: "0.3.0",
|
||||
compatible_application_versions: ["0.3.0"],
|
||||
application_version: "0.4.0",
|
||||
compatible_application_versions: ["0.4.0"],
|
||||
native_writer_conformance: false,
|
||||
registries: registries.map(({ name, description }) => ({
|
||||
name,
|
||||
description,
|
||||
id: `${baseId}/registries/${name}.json`,
|
||||
file: `registries/${name}.json`,
|
||||
})),
|
||||
normative_specification: "../../../docs/provenance/STAGE-1-NORMATIVE-SPECIFICATION.md",
|
||||
generated_by: "scripts/generate-provenance-stage2.mjs",
|
||||
schemas: schemaNames.map((name) => ({
|
||||
@@ -695,7 +1038,106 @@ await writeJson(path.join(vectorDir, "backup-and-release-manifests.json"), {
|
||||
release_manifest: { ...releaseExample, source_chain_head: baseEvents.at(-1).event_hash },
|
||||
binding_rule: "Backup and release inventories bind the same frozen authoritative chain head while remaining distinct artifact classes.",
|
||||
});
|
||||
const readme = `# Thinkloom provenance schemas 1.0\n\nThis generated package is the formal Stage 2 contract for the approved provenance architecture. It targets JSON Schema Draft 2020-12 and ships with ${schemaNames.length} schemas, valid fixtures, invalid fixture suites, and deterministic verification vectors.\n\n- \`catalog.json\` is the machine-readable inventory.\n- \`*.schema.json\` are the formal contracts.\n- \`fixtures/valid\` contains one canonical valid instance per schema.\n- \`fixtures/invalid\` covers required fields, closed-object policy, and populated enum, pattern, and numeric/string/array bounds.\n- \`vectors\` fixes canonicalization, timestamps, paths, JSONL, event and segment chains, self-digests, protected records, key rotation and recovery, retention policy, sanitized export, deterministic indexes, verification reports, backups, and release-Merkle behavior.\n\nRegenerate with \`npm run provenance:schema:generate\`. Verify with \`npm run provenance:schema:test\`. Generated files must be committed together with generator and vector changes. Runtime adoption is a later implementation stage; presence of this package does not imply the current native writer already conforms.\n`;
|
||||
const vectorAssertionIdentity = {
|
||||
...assertionIdentity,
|
||||
source_anchor: { event_id: baseEvents[1].event_id, event_sequence: baseEvents[1].event_sequence, event_hash: baseEvents[1].event_hash },
|
||||
dependencies: assertionIdentity.dependencies.map((dependency, index) => index === 0 ? { ...dependency, expected_sha256: baseEvents[1].event_hash } : dependency),
|
||||
};
|
||||
const vectorAssertion = { ...vectorAssertionIdentity, assertion_sha256: sha256(vectorAssertionIdentity) };
|
||||
const assertionRecordingEvent = {
|
||||
...eventExample,
|
||||
event_id: typedId("event", "Y"),
|
||||
event_sequence: 4,
|
||||
timestamp: "2026-07-17T18:45:13.012Z",
|
||||
event_type: "ASSERTION_RECORDED",
|
||||
inputs: [{ ...contentReferenceExample, record_id: baseEvents[1].event_id, record_type: "other", sha256: baseEvents[1].event_hash, path: "provenance/ledger/active.jsonl", revision_id: null, range: null }],
|
||||
outputs: [{ ...contentReferenceExample, record_id: vectorAssertion.assertion_id, record_type: "provenance_assertion", sha256: vectorAssertion.assertion_sha256, path: "records/assertions/assertion.json", revision_id: null, range: null }],
|
||||
relationships: { parent_event_ids: [baseEvents[1].event_id], invocation_id: null },
|
||||
metadata: { summary: "Recorded canonical provenance assertion", assertion_id: vectorAssertion.assertion_id },
|
||||
previous_event_hash: baseEvents.at(-1).event_hash,
|
||||
event_hash: "",
|
||||
};
|
||||
assertionRecordingEvent.event_hash = hashEvent(assertionRecordingEvent);
|
||||
const exactAssertionEvaluation = {
|
||||
...evaluationExample,
|
||||
assertion_sha256: vectorAssertion.assertion_sha256,
|
||||
evaluated_against: { ...evaluationExample.evaluated_against, chain_head: assertionRecordingEvent.event_hash, event_sequence: assertionRecordingEvent.event_sequence },
|
||||
dependency_results: evaluationExample.dependency_results.map((result, index) => index === 0 ? { ...result, observed_sha256: baseEvents[1].event_hash } : result),
|
||||
};
|
||||
const degradedAssertionEvaluation = {
|
||||
...exactAssertionEvaluation,
|
||||
evaluation_id: typedId("evaluation", "X"),
|
||||
status: "degraded",
|
||||
confidence: { ...exactAssertionEvaluation.confidence, authorship: "degraded", completeness: "degraded" },
|
||||
boundary: { kind: "evidence_access", affected_dimensions: ["authorship", "completeness"], dependency_ids: [ids.turn], compatibility: null },
|
||||
dependency_results: exactAssertionEvaluation.dependency_results.map((result) => result.dependency_id === ids.turn ? { ...result, status: "missing", observed_sha256: null, observed_generation: null } : result),
|
||||
reason_code: "ADVISORY_EVIDENCE_UNAVAILABLE",
|
||||
supersedes_evaluation_id: exactAssertionEvaluation.evaluation_id,
|
||||
evaluated_at: "2026-07-17T18:45:13.012Z",
|
||||
};
|
||||
const staleAssertionEvaluation = {
|
||||
...degradedAssertionEvaluation,
|
||||
evaluation_id: typedId("evaluation", "Y"),
|
||||
evaluated_against: { ...degradedAssertionEvaluation.evaluated_against, chain_head: digest("a"), event_sequence: 5 },
|
||||
status: "stale",
|
||||
confidence: { integrity: "degraded", identity: "exact", chronology: "degraded", derivation: "degraded", authorship: "unverified", completeness: "degraded" },
|
||||
boundary: { kind: "dependency_change", affected_dimensions: ["integrity", "chronology", "derivation"], dependency_ids: [ids.event2], compatibility: null },
|
||||
dependency_results: exactAssertionEvaluation.dependency_results.map((result) => result.dependency_id === ids.event2 ? { ...result, status: "changed", observed_sha256: digest("0"), observed_generation: { project_epoch: 1, artifact_revision: 13, transcript_revision: 4 } } : result),
|
||||
reason_code: "DEPENDENCY_GENERATION_MISMATCH",
|
||||
supersedes_evaluation_id: degradedAssertionEvaluation.evaluation_id,
|
||||
evaluated_at: "2026-07-17T18:46:14.345Z",
|
||||
};
|
||||
const refusedAssertionEvaluation = {
|
||||
...staleAssertionEvaluation,
|
||||
evaluation_id: typedId("evaluation", "Z"),
|
||||
status: "refused",
|
||||
confidence: { integrity: "exact", identity: "unverified", chronology: "exact", derivation: "unverified", authorship: "not_applicable", completeness: "unverified" },
|
||||
boundary: { kind: "compatibility", affected_dimensions: ["identity", "derivation", "completeness"], dependency_ids: [ids.record], compatibility: { required_schema: "1.0", observed_schema: "2.0" } },
|
||||
dependency_results: exactAssertionEvaluation.dependency_results.map((result) => result.dependency_id === ids.record ? { ...result, status: "incompatible", observed_sha256: null, observed_generation: null } : result),
|
||||
reason_code: "SCHEMA_INCOMPATIBLE",
|
||||
supersedes_evaluation_id: staleAssertionEvaluation.evaluation_id,
|
||||
evaluated_at: "2026-07-17T18:47:15.678Z",
|
||||
};
|
||||
const unverifiedAssertionEvaluation = {
|
||||
...refusedAssertionEvaluation,
|
||||
evaluation_id: typedId("evaluation", "0"),
|
||||
status: "unverified",
|
||||
confidence: { integrity: "exact", identity: "unverified", chronology: "exact", derivation: "unverified", authorship: "not_applicable", completeness: "unverified" },
|
||||
boundary: { kind: "evidence_access", affected_dimensions: ["identity", "derivation", "completeness"], dependency_ids: [ids.record], compatibility: null },
|
||||
dependency_results: exactAssertionEvaluation.dependency_results.map((result) => result.dependency_id === ids.record ? { ...result, status: "inaccessible", observed_sha256: null, observed_generation: null } : result),
|
||||
reason_code: "AUTHORIZED_EVIDENCE_UNAVAILABLE",
|
||||
supersedes_evaluation_id: refusedAssertionEvaluation.evaluation_id,
|
||||
evaluated_at: "2026-07-17T18:48:16.901Z",
|
||||
};
|
||||
await writeJson(path.join(vectorDir, "assertion-envelope-and-invalidation.json"), {
|
||||
vector_version: "1.0",
|
||||
assertion_recording_event: assertionRecordingEvent,
|
||||
assertion: vectorAssertion,
|
||||
assertion_identity: vectorAssertionIdentity,
|
||||
evaluations: [exactAssertionEvaluation, degradedAssertionEvaluation, staleAssertionEvaluation, refusedAssertionEvaluation, unverifiedAssertionEvaluation],
|
||||
consumer_decisions: [
|
||||
{ status: "exact", action: "promote" },
|
||||
{ status: "degraded", action: "warn" },
|
||||
{ status: "refused", action: "refuse" },
|
||||
{ status: "stale", action: "reevaluate" },
|
||||
{ status: "unverified", action: "withhold_exact" },
|
||||
],
|
||||
forbidden_exact_cases: {
|
||||
unknown_provenance: { ...vectorAssertion, provenance: undefined },
|
||||
unknown_confidence: { ...exactAssertionEvaluation, confidence: { ...exactAssertionEvaluation.confidence, derivation: "unverified" } },
|
||||
incompatible_dependency: { ...exactAssertionEvaluation, dependency_results: exactAssertionEvaluation.dependency_results.map((result, index) => index === 0 ? { ...result, status: "incompatible" } : result) },
|
||||
uncertainty_boundary: { ...exactAssertionEvaluation, boundary: { kind: "coverage", affected_dimensions: ["completeness"], dependency_ids: [], compatibility: null } },
|
||||
unknown_artifact_generation: { ...vectorAssertion, source_generation: { ...vectorAssertion.source_generation, artifact_revision: null } },
|
||||
},
|
||||
invariants: [
|
||||
"The source anchor identifies prior basis evidence and differs from the later assertion-recording event.",
|
||||
"The assertion digest excludes only assertion_sha256.",
|
||||
"Evaluations are immutable point-in-time conclusions; later records supersede current use without mutation.",
|
||||
"Unknown provenance, generation, compatibility, or confidence never produces exact.",
|
||||
"Consumers decide from canonical assertions, evaluations, and registries without producer-specific internal state.",
|
||||
],
|
||||
});
|
||||
const readme = `# Thinkloom provenance schemas 1.0\n\nThis generated package is the formal Stage 2 contract for the approved provenance architecture. It targets JSON Schema Draft 2020-12 and ships with ${schemaNames.length} schemas, valid fixtures, invalid fixture suites, and deterministic verification vectors.\n\n- \`catalog.json\` is the machine-readable inventory.\n- \`*.schema.json\` are the formal contracts.\n- \`registries\` defines assertion lifecycle, evaluation status, confidence, evidence, boundary, and reason semantics.\n- \`fixtures/valid\` contains one canonical valid instance per schema.\n- \`fixtures/invalid\` covers required fields, closed-object policy, and populated enum, pattern, and numeric/string/array bounds.\n- \`vectors\` fixes canonicalization, timestamps, paths, JSONL, event and segment chains, self-digests, protected records, key rotation and recovery, retention policy, sanitized export, deterministic indexes, verification reports, canonical assertions and evaluations, dependency invalidation, backups, and release-Merkle behavior.\n\nRegenerate with \`npm run provenance:schema:generate\`. Verify with \`npm run provenance:schema:test\`. Generated files must be committed together with generator and vector changes. Runtime adoption is a later implementation stage; presence of this package does not imply the current native writer already conforms.\n`;
|
||||
await writeFile(path.join(output, "README.md"), readme, "utf8");
|
||||
|
||||
console.log(`Generated ${schemaNames.length} provenance schemas and fixtures in ${path.relative(root, output)}.`);
|
||||
Generated
+1
-1
@@ -3980,7 +3980,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "thinkloom"
|
||||
version = "0.3.0"
|
||||
version = "0.4.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"hex",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "thinkloom"
|
||||
version = "0.3.0"
|
||||
version = "0.4.0"
|
||||
description = "Local-first writing studio with creative provenance"
|
||||
authors = ["Christopher Chambers"]
|
||||
license = "AGPL-3.0-only"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "Thinkloom",
|
||||
"version": "0.3.0",
|
||||
"version": "0.4.0",
|
||||
"identifier": "com.thinkloom.desktop",
|
||||
"build": {
|
||||
"beforeDevCommand": "npm run dev",
|
||||
|
||||
+1
-1
@@ -220,6 +220,6 @@ export default function Thinkloom() {
|
||||
<section className="settings-section panel wide prompt-settings"><div className="settings-heading"><span className="settings-number">04</span><div><h2>Prompt configuration</h2><p>Technical users can tune every instruction sent to the model.</p></div></div><p><strong>conversation.json</strong> affects Ideation replies. <strong>drafting.json</strong> affects passage and editorial previews. Files reload before every model request, so no restart is needed.</p><code className="prompt-path">{promptPath || "Preparing prompt files…"}</code><div className="project-actions"><button className="secondary-button" onClick={() => void openPromptFolder()}>Open prompt folder</button></div><small>README.md in this folder documents every field, variable, effect, validation rule, and reset procedure.</small></section>
|
||||
</div></section>}
|
||||
</section>
|
||||
<footer className="app-footer"><span>Thinkloom 0.3.0</span><span>Local-first · audio retention always off</span><span>{project.events.at(-1)?.hash ?? "No history"}</span></footer>
|
||||
<footer className="app-footer"><span>Thinkloom 0.4.0</span><span>Local-first · audio retention always off</span><span>{project.events.at(-1)?.hash ?? "No history"}</span></footer>
|
||||
</main>;
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ test("externalizes and documents every model prompt", async () => {
|
||||
}
|
||||
|
||||
const version = JSON.parse(packageRaw).version;
|
||||
assert.equal(version, "0.3.0");
|
||||
assert.equal(version, "0.4.0");
|
||||
const packageLock = JSON.parse(packageLockRaw);
|
||||
assert.equal(packageLock.version, version);
|
||||
assert.equal(packageLock.packages[""].version, version);
|
||||
|
||||
@@ -24,12 +24,12 @@ function validator() {
|
||||
}
|
||||
|
||||
const requiredSchemas = [
|
||||
"backup-manifest", "chain-head", "content-reference", "conversation-session", "derived-index-manifest",
|
||||
"assertion-evaluation", "backup-manifest", "chain-head", "content-reference", "conversation-session", "derived-index-manifest",
|
||||
"disposition-revision", "edit-transaction", "encrypted-key-envelope", "idea", "idea-revision",
|
||||
"invocation-failure", "invocation-request", "invocation-response", "invocation-state", "invocation-stream-state",
|
||||
"invocation-stream-summary", "ledger-segment-manifest", "manuscript-revision", "model-capability-snapshot",
|
||||
"model-configuration-snapshot", "project-key-manifest", "project-manifest", "prompt-template",
|
||||
"prompt-template-reference", "provenance-event", "provenance-policy", "purge-manifest", "record-envelope",
|
||||
"prompt-template-reference", "provenance-assertion", "provenance-event", "provenance-policy", "purge-manifest", "record-envelope",
|
||||
"recovery-key-envelope", "release-manifest", "release-state", "sanitized-export-manifest", "text-fragment-reference",
|
||||
"transcript-correction", "transcript-normalization", "transcript-turn", "verification-report", "write-intent",
|
||||
];
|
||||
@@ -37,8 +37,8 @@ const requiredSchemas = [
|
||||
test("catalogs every approved Stage 2 schema under Draft 2020-12", () => {
|
||||
assert.equal(catalog.catalog_version, "1.0");
|
||||
assert.equal(catalog.provenance_schema_version, "1.0");
|
||||
assert.equal(catalog.application_version, "0.3.0");
|
||||
assert.deepEqual(catalog.compatible_application_versions, ["0.3.0"]);
|
||||
assert.equal(catalog.application_version, "0.4.0");
|
||||
assert.deepEqual(catalog.compatible_application_versions, ["0.4.0"]);
|
||||
assert.equal(catalog.native_writer_conformance, false);
|
||||
assert.equal(catalog.dialect, "https://json-schema.org/draft/2020-12/schema");
|
||||
assert.deepEqual(catalog.schemas.map(({ name }) => name), requiredSchemas);
|
||||
@@ -48,6 +48,19 @@ test("catalogs every approved Stage 2 schema under Draft 2020-12", () => {
|
||||
}
|
||||
});
|
||||
|
||||
test("publishes complete versioned assertion registries", async () => {
|
||||
const expected = ["assertion-boundary-kinds", "assertion-confidence-dimensions", "assertion-evaluation-statuses", "assertion-evidence-classes", "assertion-lifecycle-phases", "assertion-reason-codes"];
|
||||
assert.deepEqual(catalog.registries.map(({ name }) => name).sort(), expected);
|
||||
for (const entry of catalog.registries) {
|
||||
const registry = await readJson(entry.file);
|
||||
assert.equal(registry.registry_version, "1.0");
|
||||
assert.equal(registry.provenance_schema_version, "1.0");
|
||||
assert.equal(registry.application_version, "0.4.0");
|
||||
assert.ok(registry.entries.length > 0);
|
||||
assert.ok(registry.entries.every(({ meaning }) => typeof meaning === "string" && meaning.length > 0));
|
||||
assert.equal(new Set(registry.entries.map(({ code }) => code)).size, registry.entries.length);
|
||||
}
|
||||
});
|
||||
test("accepts every valid fixture", async () => {
|
||||
const ajv = validator();
|
||||
for (const entry of schemaEntries) {
|
||||
@@ -239,4 +252,70 @@ test("validates backup and release manifests bound to one chain head", async ()
|
||||
assert.equal(validateRelease(vector.release_manifest), true, ajv.errorsText(validateRelease.errors));
|
||||
assert.equal(vector.backup_manifest.source_chain_head, vector.release_manifest.source_chain_head);
|
||||
assert.equal(releaseMerkleRoot(vector.release_manifest.files), vector.release_manifest.release_files_merkle_root);
|
||||
});
|
||||
});
|
||||
test("keeps canonical assertions immutable while evaluations change over time", async () => {
|
||||
const ajv = validator();
|
||||
const vector = await readJson("vectors", "assertion-envelope-and-invalidation.json");
|
||||
const validateAssertion = ajv.getSchema("https://thinkloom.app/schemas/provenance/1.0/provenance-assertion.schema.json");
|
||||
const validateEvaluation = ajv.getSchema("https://thinkloom.app/schemas/provenance/1.0/assertion-evaluation.schema.json");
|
||||
|
||||
assert.equal(validateAssertion(vector.assertion), true, ajv.errorsText(validateAssertion.errors));
|
||||
assert.equal(sha256(vector.assertion_identity), vector.assertion.assertion_sha256);
|
||||
const identity = { ...vector.assertion };
|
||||
delete identity.assertion_sha256;
|
||||
assert.deepEqual(identity, vector.assertion_identity);
|
||||
const validateEvent = ajv.getSchema("https://thinkloom.app/schemas/provenance/1.0/provenance-event.schema.json");
|
||||
assert.equal(validateEvent(vector.assertion_recording_event), true, ajv.errorsText(validateEvent.errors));
|
||||
assert.equal(hashEvent(vector.assertion_recording_event), vector.assertion_recording_event.event_hash);
|
||||
assert.notEqual(vector.assertion.source_anchor.event_id, vector.assertion_recording_event.event_id);
|
||||
assert.ok(vector.assertion_recording_event.event_sequence > vector.assertion.source_anchor.event_sequence);
|
||||
assert.equal(vector.assertion_recording_event.outputs[0].record_id, vector.assertion.assertion_id);
|
||||
assert.equal(vector.assertion_recording_event.outputs[0].sha256, vector.assertion.assertion_sha256);
|
||||
|
||||
const expectedStatuses = ["exact", "degraded", "refused", "stale", "unverified"];
|
||||
assert.deepEqual([...new Set(vector.evaluations.map(({ status }) => status))].sort(), expectedStatuses.sort());
|
||||
for (const [index, evaluation] of vector.evaluations.entries()) {
|
||||
assert.equal(validateEvaluation(evaluation), true, `${evaluation.status}: ${ajv.errorsText(validateEvaluation.errors)}`);
|
||||
assert.equal(evaluation.assertion_id, vector.assertion.assertion_id);
|
||||
assert.equal(evaluation.assertion_sha256, vector.assertion.assertion_sha256);
|
||||
assert.deepEqual(evaluation.dependency_results.map(({ dependency_id }) => dependency_id).sort(), vector.assertion.dependencies.map(({ dependency_id }) => dependency_id).sort());
|
||||
for (const result of evaluation.dependency_results) {
|
||||
assert.equal(result.evidence_class, vector.assertion.dependencies.find(({ dependency_id }) => dependency_id === result.dependency_id).evidence_class);
|
||||
}
|
||||
assert.deepEqual(Object.keys(evaluation.confidence).sort(), ["authorship", "chronology", "completeness", "derivation", "identity", "integrity"]);
|
||||
assert.equal(Object.hasOwn(evaluation.confidence, "score"), false);
|
||||
if (index) assert.equal(evaluation.supersedes_evaluation_id, vector.evaluations[index - 1].evaluation_id);
|
||||
}
|
||||
|
||||
const exact = vector.evaluations.find(({ status }) => status === "exact");
|
||||
assert.equal(exact.boundary, null);
|
||||
assert.equal(Object.values(exact.confidence).some((value) => ["degraded", "unverified"].includes(value)), false);
|
||||
assert.equal(exact.dependency_results.filter(({ evidence_class }) => evidence_class !== "shadow").every(({ status }) => status === "valid"), true);
|
||||
assert.ok(exact.dependency_results.some(({ evidence_class, status }) => evidence_class === "shadow" && status === "not_evaluated"));
|
||||
assert.ok(vector.evaluations.find(({ status }) => status === "stale").dependency_results.some(({ status }) => status === "changed"));
|
||||
|
||||
for (const [name, invalid] of Object.entries(vector.forbidden_exact_cases)) {
|
||||
const validate = ["unknown_provenance", "unknown_artifact_generation"].includes(name) ? validateAssertion : validateEvaluation;
|
||||
assert.equal(validate(invalid), false, `${name} must not validate`);
|
||||
}
|
||||
assert.doesNotMatch(JSON.stringify(vector), /human.{0,20}percentage|authorship.{0,20}score/i);
|
||||
});
|
||||
|
||||
test("keeps assertion status, reason, confidence, and evidence semantics registry-driven", async () => {
|
||||
const vector = await readJson("vectors", "assertion-envelope-and-invalidation.json");
|
||||
const registries = Object.fromEntries(await Promise.all(catalog.registries.map(async (entry) => [entry.name, await readJson(entry.file)])));
|
||||
const statusRegistry = registries["assertion-evaluation-statuses"];
|
||||
const reasonRegistry = registries["assertion-reason-codes"];
|
||||
const evidenceRegistry = registries["assertion-evidence-classes"];
|
||||
const lifecycleRegistry = registries["assertion-lifecycle-phases"];
|
||||
|
||||
assert.ok(lifecycleRegistry.entries.some(({ code }) => code === vector.assertion.lifecycle_phase));
|
||||
assert.deepEqual(vector.consumer_decisions, statusRegistry.entries.map(({ code: status, consumer_action: action }) => ({ status, action })));
|
||||
for (const evaluation of vector.evaluations) {
|
||||
const reason = reasonRegistry.entries.find(({ code }) => code === evaluation.reason_code);
|
||||
assert.ok(reason, evaluation.reason_code);
|
||||
assert.ok(reason.permitted_statuses.includes(evaluation.status), `${evaluation.reason_code} cannot explain ${evaluation.status}`);
|
||||
}
|
||||
assert.deepEqual(evidenceRegistry.entries.map(({ code }) => code), ["mandatory_live", "mandatory_retained", "advisory", "shadow"]);
|
||||
assert.deepEqual(evidenceRegistry.entries.map(({ exact_effect }) => exact_effect), ["required", "required", "may_degrade", "no_authority"]);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user