diff --git a/IMPLEMENTATION_STATUS.md b/IMPLEMENTATION_STATUS.md index 3145193..5dfe9a7 100644 --- a/IMPLEMENTATION_STATUS.md +++ b/IMPLEMENTATION_STATUS.md @@ -11,6 +11,7 @@ Status date: 2026-07-17 - M4 drafting workspace: TipTap structured editor, dominant three-panel layout, selective context, staged generation, all acceptance destinations, partial acceptance, manual editing, undo/redo, and autosave. - 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. - Product surface: Sites, Next, Vinext, Cloudflare, and browser-companion code and configuration have been removed. Tauri is the sole application target. ## External release gates @@ -26,7 +27,7 @@ These items cannot be honestly certified from this workspace alone and need proj ## Remaining hardening -- Replace the current MVP provenance persistence path with the approved [Thinkloom 1.0 Stage 1 normative provenance subsystem](docs/provenance/README.md). The specification is complete; formal schemas, fixtures, native implementation, and fault-injection conformance remain future stages. +- Replace the current MVP provenance persistence path with the approved [Thinkloom 1.0 Stage 1 normative provenance subsystem](docs/provenance/README.md). The specification and formal schemas/fixtures are complete; native implementation and fault-injection conformance remain future stages. - Run microphone/VAD/transcription integration tests once the approved model assets are supplied. - Run signed clean-install, upgrade, downgrade-warning, and uninstall tests on each release platform. diff --git a/PROMPTS.md b/PROMPTS.md index 5608de9..cf6bf3f 100644 --- a/PROMPTS.md +++ b/PROMPTS.md @@ -1,6 +1,6 @@ # Thinkloom prompt configuration -Thinkloom 0.2.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.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. 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. diff --git a/README.md b/README.md index 19d5584..6827db1 100644 --- a/README.md +++ b/README.md @@ -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. -This specification is a forward implementation contract. The current 0.2.0 provenance implementation must not be represented as already conforming to it. +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. ## Provider setup diff --git a/docs/provenance/README.md b/docs/provenance/README.md index ba1fa8c..ef2e0ac 100644 --- a/docs/provenance/README.md +++ b/docs/provenance/README.md @@ -1,9 +1,11 @@ # Thinkloom provenance specification -This directory contains the approved Stage 1 normative specification for the Thinkloom 1.0 provenance subsystem. +This directory contains the approved normative specification and formal Stage 2 contract for the Thinkloom 1.0 provenance subsystem. - [Stage 1 Normative Specification](STAGE-1-NORMATIVE-SPECIFICATION.md) - [State Machines and Recovery Protocols](STATE-MACHINES.md) - [Stage 1 Completion Checklist](COMPLETION-CHECKLIST.md) +- [Stage 2 Completion and Verification](STAGE-2-SCHEMA-PACKAGE.md) +- [Stage 2 JSON Schema package](../../schemas/provenance/v1/README.md) -These documents govern future schema and implementation work. They do not describe the current 0.2.0 implementation as already compliant. +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. diff --git a/docs/provenance/STAGE-1-NORMATIVE-SPECIFICATION.md b/docs/provenance/STAGE-1-NORMATIVE-SPECIFICATION.md index b1059f4..845cb16 100644 --- a/docs/provenance/STAGE-1-NORMATIVE-SPECIFICATION.md +++ b/docs/provenance/STAGE-1-NORMATIVE-SPECIFICATION.md @@ -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. -The current Thinkloom 0.2.0 implementation is not represented as conforming to this specification. Conformance begins only after the Stage 2 schemas, fixtures, native implementation, and required fault-injection tests are complete. +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. ## 2. Normative language diff --git a/docs/provenance/STAGE-2-SCHEMA-PACKAGE.md b/docs/provenance/STAGE-2-SCHEMA-PACKAGE.md new file mode 100644 index 0000000..1cc9f2f --- /dev/null +++ b/docs/provenance/STAGE-2-SCHEMA-PACKAGE.md @@ -0,0 +1,57 @@ +# Thinkloom Stage 2 Provenance Schema Package + +Status: **Complete for Thinkloom 0.3.0** +Schema family: **1.0** +Dialect: **JSON Schema Draft 2020-12** +Runtime conformance: **Not yet implemented** + +## Scope + +Stage 2 formalizes the approved provenance architecture without changing native application behavior. It provides deterministic contracts and verification evidence for the later native-writer implementation. Migration support remains deferred until after Thinkloom 1.0.0. + +## 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. + +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. + +## Deterministic vectors + +The vector suite covers: + +- RFC 8785-compatible serialization after Thinkloom Unicode NFC preprocessing; +- prohibited non-finite, undefined, and NFC-colliding values; +- exact millisecond UTC timestamps and repository-relative path restrictions; +- LF-only canonical JSONL, contiguous events, event self-digests, and cross-segment seals; +- prompt-template, protected-record, event, and release self-digest identities; +- minimal and full-private retention behavior; +- 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. + +## Verification + +Regenerate deterministically: + +```powershell +npm run provenance:schema:generate +``` + +Validate schemas, fixtures, and vectors: + +```powershell +npm run provenance:schema:test +``` + +The schema tests are also part of `npm test`. Generated output must be committed with its generator and tests. A clean regeneration is required before changing any formal schema or vector. + +## 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. diff --git a/eslint.config.mjs b/eslint.config.mjs index 97fabb6..7272cb9 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -16,7 +16,7 @@ export default tseslint.config( rules: { ...reactHooks.configs.recommended.rules }, }, { - files: ["tests/**/*.mjs"], + files: ["tests/**/*.mjs", "scripts/**/*.mjs"], languageOptions: { globals: globals.node }, }, ); diff --git a/package-lock.json b/package-lock.json index 4939d90..b739d35 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "thinkloom", - "version": "0.2.0", + "version": "0.3.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "thinkloom", - "version": "0.2.0", + "version": "0.3.0", "license": "AGPL-3.0-only", "dependencies": { "@tiptap/markdown": "^3.28.0", @@ -23,6 +23,8 @@ "@types/react": "19.2.14", "@types/react-dom": "19.2.3", "@vitejs/plugin-react": "6.0.2", + "ajv": "^8.17.1", + "ajv-formats": "^3.0.1", "eslint": "9.39.4", "eslint-plugin-react-hooks": "7.1.1", "globals": "14.0.0", @@ -415,6 +417,30 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, "node_modules/@eslint/js": { "version": "9.39.4", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", @@ -1990,22 +2016,40 @@ } }, "node_modules/ajv": { - "version": "6.15.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", - "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, "funding": { "type": "github", "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -2372,6 +2416,30 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, "node_modules/espree": { "version": "10.4.0", "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", @@ -2466,6 +2534,23 @@ "dev": true, "license": "MIT" }, + "node_modules/fast-uri": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.3.tgz", + "integrity": "sha512-i70LwGWUduXqzicKXWshooq+sWL1K3WUU5rKZNG/0i3a1OSoX3HqhH5WbWwTmqWfor4urUakGPiRQcleRZTwOg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -2703,9 +2788,9 @@ "license": "MIT" }, "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true, "license": "MIT" }, @@ -3162,6 +3247,16 @@ "react": "^19.2.6" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", diff --git a/package.json b/package.json index f7a7d72..fc06fdc 100644 --- a/package.json +++ b/package.json @@ -1,21 +1,25 @@ { "name": "thinkloom", - "version": "0.2.0", + "version": "0.3.0", "author": "Christopher Chambers", "license": "AGPL-3.0-only", "repository": "https://github.com/Labyricorn/thinkloom-openai-hackathon.git", "homepage": "https://github.com/Labyricorn/thinkloom-openai-hackathon", "private": true, "type": "module", - "engines": { "node": ">=22.13.0" }, + "engines": { + "node": ">=22.13.0" + }, "scripts": { "dev": "vite --port 1420 --strictPort", "build": "npm run typecheck && vite build", "preview": "vite preview", "typecheck": "tsc --noEmit", - "lint": "eslint src tests vite.config.ts", - "test": "npm run typecheck && node tests/native-app.test.mjs", - "tauri": "tauri" + "lint": "eslint src tests scripts vite.config.ts", + "test": "npm run typecheck && node tests/native-app.test.mjs && npm run provenance:schema:test", + "tauri": "tauri", + "provenance:schema:generate": "node scripts/generate-provenance-stage2.mjs", + "provenance:schema:test": "node tests/provenance-schema.test.mjs" }, "dependencies": { "@tiptap/markdown": "^3.28.0", @@ -32,6 +36,8 @@ "@types/react": "19.2.14", "@types/react-dom": "19.2.3", "@vitejs/plugin-react": "6.0.2", + "ajv": "^8.17.1", + "ajv-formats": "^3.0.1", "eslint": "9.39.4", "eslint-plugin-react-hooks": "7.1.1", "globals": "14.0.0", diff --git a/schemas/provenance/v1/README.md b/schemas/provenance/v1/README.md new file mode 100644 index 0000000..e6d4222 --- /dev/null +++ b/schemas/provenance/v1/README.md @@ -0,0 +1,11 @@ +# 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. + +- `catalog.json` is the machine-readable inventory. +- `*.schema.json` are the formal contracts. +- `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. + +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. diff --git a/schemas/provenance/v1/backup-manifest.schema.json b/schemas/provenance/v1/backup-manifest.schema.json new file mode 100644 index 0000000..c3acd72 --- /dev/null +++ b/schemas/provenance/v1/backup-manifest.schema.json @@ -0,0 +1,150 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/backup-manifest.schema.json", + "title": "Project backup manifest", + "description": "Complete staged-backup inventory including a verified online SQLite snapshot.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "application_version": { + "type": "string", + "pattern": "^\\d+\\.\\d+\\.\\d+$" + }, + "project_id": { + "type": "string", + "pattern": "^project_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "created_at": { + "type": "string", + "format": "date-time", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$" + }, + "source_chain_head": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + }, + "sqlite_snapshot": { + "type": "object", + "properties": { + "path": { + "type": "string", + "minLength": 1, + "pattern": "^(?!/)(?![A-Za-z]:)(?!.*\\\\)(?!.*(?:^|/)\\.\\.?(?:/|$))[^\\u0000-\\u001f]+$" + }, + "sha256": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + }, + "size": { + "type": "integer", + "minimum": 1 + }, + "sqlite_version": { + "type": "string", + "minLength": 1 + }, + "database_schema_version": { + "type": "integer", + "minimum": 1 + }, + "completed_at": { + "type": "string", + "format": "date-time", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$" + } + }, + "required": [ + "path", + "sha256", + "size", + "sqlite_version", + "database_schema_version", + "completed_at" + ], + "additionalProperties": false + }, + "files": { + "type": "array", + "items": { + "type": "object", + "properties": { + "path": { + "type": "string", + "minLength": 1, + "pattern": "^(?!/)(?![A-Za-z]:)(?!.*\\\\)(?!.*(?:^|/)\\.\\.?(?:/|$))[^\\u0000-\\u001f]+$" + }, + "sha256": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + }, + "size": { + "type": "integer", + "minimum": 0 + } + }, + "required": [ + "path", + "sha256", + "size" + ], + "additionalProperties": false + }, + "minItems": 1 + }, + "protected": { + "type": "boolean" + }, + "recovery_key_envelope_path": { + "anyOf": [ + { + "type": "string", + "minLength": 1, + "pattern": "^(?!/)(?![A-Za-z]:)(?!.*\\\\)(?!.*(?:^|/)\\.\\.?(?:/|$))[^\\u0000-\\u001f]+$" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "schema_version", + "application_version", + "project_id", + "created_at", + "source_chain_head", + "sqlite_snapshot", + "files", + "protected", + "recovery_key_envelope_path" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "sqlite_version": "3.46.0", + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [ + { + "path": "project.json", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": 256 + } + ], + "protected": false, + "recovery_key_envelope_path": null + } + ] +} diff --git a/schemas/provenance/v1/catalog.json b/schemas/provenance/v1/catalog.json new file mode 100644 index 0000000..96e3663 --- /dev/null +++ b/schemas/provenance/v1/catalog.json @@ -0,0 +1,280 @@ +{ + "catalog_version": "1.0", + "dialect": "https://json-schema.org/draft/2020-12/schema", + "provenance_schema_version": "1.0", + "application_version": "0.3.0", + "compatible_application_versions": [ + "0.3.0" + ], + "native_writer_conformance": false, + "normative_specification": "../../../docs/provenance/STAGE-1-NORMATIVE-SPECIFICATION.md", + "generated_by": "scripts/generate-provenance-stage2.mjs", + "schemas": [ + { + "name": "backup-manifest", + "id": "https://thinkloom.app/schemas/provenance/1.0/backup-manifest.schema.json", + "file": "backup-manifest.schema.json", + "valid_fixture": "fixtures/valid/backup-manifest.valid.json", + "invalid_fixture": "fixtures/invalid/backup-manifest.invalid.json" + }, + { + "name": "chain-head", + "id": "https://thinkloom.app/schemas/provenance/1.0/chain-head.schema.json", + "file": "chain-head.schema.json", + "valid_fixture": "fixtures/valid/chain-head.valid.json", + "invalid_fixture": "fixtures/invalid/chain-head.invalid.json" + }, + { + "name": "content-reference", + "id": "https://thinkloom.app/schemas/provenance/1.0/content-reference.schema.json", + "file": "content-reference.schema.json", + "valid_fixture": "fixtures/valid/content-reference.valid.json", + "invalid_fixture": "fixtures/invalid/content-reference.invalid.json" + }, + { + "name": "conversation-session", + "id": "https://thinkloom.app/schemas/provenance/1.0/conversation-session.schema.json", + "file": "conversation-session.schema.json", + "valid_fixture": "fixtures/valid/conversation-session.valid.json", + "invalid_fixture": "fixtures/invalid/conversation-session.invalid.json" + }, + { + "name": "derived-index-manifest", + "id": "https://thinkloom.app/schemas/provenance/1.0/derived-index-manifest.schema.json", + "file": "derived-index-manifest.schema.json", + "valid_fixture": "fixtures/valid/derived-index-manifest.valid.json", + "invalid_fixture": "fixtures/invalid/derived-index-manifest.invalid.json" + }, + { + "name": "disposition-revision", + "id": "https://thinkloom.app/schemas/provenance/1.0/disposition-revision.schema.json", + "file": "disposition-revision.schema.json", + "valid_fixture": "fixtures/valid/disposition-revision.valid.json", + "invalid_fixture": "fixtures/invalid/disposition-revision.invalid.json" + }, + { + "name": "edit-transaction", + "id": "https://thinkloom.app/schemas/provenance/1.0/edit-transaction.schema.json", + "file": "edit-transaction.schema.json", + "valid_fixture": "fixtures/valid/edit-transaction.valid.json", + "invalid_fixture": "fixtures/invalid/edit-transaction.invalid.json" + }, + { + "name": "encrypted-key-envelope", + "id": "https://thinkloom.app/schemas/provenance/1.0/encrypted-key-envelope.schema.json", + "file": "encrypted-key-envelope.schema.json", + "valid_fixture": "fixtures/valid/encrypted-key-envelope.valid.json", + "invalid_fixture": "fixtures/invalid/encrypted-key-envelope.invalid.json" + }, + { + "name": "idea", + "id": "https://thinkloom.app/schemas/provenance/1.0/idea.schema.json", + "file": "idea.schema.json", + "valid_fixture": "fixtures/valid/idea.valid.json", + "invalid_fixture": "fixtures/invalid/idea.invalid.json" + }, + { + "name": "idea-revision", + "id": "https://thinkloom.app/schemas/provenance/1.0/idea-revision.schema.json", + "file": "idea-revision.schema.json", + "valid_fixture": "fixtures/valid/idea-revision.valid.json", + "invalid_fixture": "fixtures/invalid/idea-revision.invalid.json" + }, + { + "name": "invocation-failure", + "id": "https://thinkloom.app/schemas/provenance/1.0/invocation-failure.schema.json", + "file": "invocation-failure.schema.json", + "valid_fixture": "fixtures/valid/invocation-failure.valid.json", + "invalid_fixture": "fixtures/invalid/invocation-failure.invalid.json" + }, + { + "name": "invocation-request", + "id": "https://thinkloom.app/schemas/provenance/1.0/invocation-request.schema.json", + "file": "invocation-request.schema.json", + "valid_fixture": "fixtures/valid/invocation-request.valid.json", + "invalid_fixture": "fixtures/invalid/invocation-request.invalid.json" + }, + { + "name": "invocation-response", + "id": "https://thinkloom.app/schemas/provenance/1.0/invocation-response.schema.json", + "file": "invocation-response.schema.json", + "valid_fixture": "fixtures/valid/invocation-response.valid.json", + "invalid_fixture": "fixtures/invalid/invocation-response.invalid.json" + }, + { + "name": "invocation-state", + "id": "https://thinkloom.app/schemas/provenance/1.0/invocation-state.schema.json", + "file": "invocation-state.schema.json", + "valid_fixture": "fixtures/valid/invocation-state.valid.json", + "invalid_fixture": "fixtures/invalid/invocation-state.invalid.json" + }, + { + "name": "invocation-stream-state", + "id": "https://thinkloom.app/schemas/provenance/1.0/invocation-stream-state.schema.json", + "file": "invocation-stream-state.schema.json", + "valid_fixture": "fixtures/valid/invocation-stream-state.valid.json", + "invalid_fixture": "fixtures/invalid/invocation-stream-state.invalid.json" + }, + { + "name": "invocation-stream-summary", + "id": "https://thinkloom.app/schemas/provenance/1.0/invocation-stream-summary.schema.json", + "file": "invocation-stream-summary.schema.json", + "valid_fixture": "fixtures/valid/invocation-stream-summary.valid.json", + "invalid_fixture": "fixtures/invalid/invocation-stream-summary.invalid.json" + }, + { + "name": "ledger-segment-manifest", + "id": "https://thinkloom.app/schemas/provenance/1.0/ledger-segment-manifest.schema.json", + "file": "ledger-segment-manifest.schema.json", + "valid_fixture": "fixtures/valid/ledger-segment-manifest.valid.json", + "invalid_fixture": "fixtures/invalid/ledger-segment-manifest.invalid.json" + }, + { + "name": "manuscript-revision", + "id": "https://thinkloom.app/schemas/provenance/1.0/manuscript-revision.schema.json", + "file": "manuscript-revision.schema.json", + "valid_fixture": "fixtures/valid/manuscript-revision.valid.json", + "invalid_fixture": "fixtures/invalid/manuscript-revision.invalid.json" + }, + { + "name": "model-capability-snapshot", + "id": "https://thinkloom.app/schemas/provenance/1.0/model-capability-snapshot.schema.json", + "file": "model-capability-snapshot.schema.json", + "valid_fixture": "fixtures/valid/model-capability-snapshot.valid.json", + "invalid_fixture": "fixtures/invalid/model-capability-snapshot.invalid.json" + }, + { + "name": "model-configuration-snapshot", + "id": "https://thinkloom.app/schemas/provenance/1.0/model-configuration-snapshot.schema.json", + "file": "model-configuration-snapshot.schema.json", + "valid_fixture": "fixtures/valid/model-configuration-snapshot.valid.json", + "invalid_fixture": "fixtures/invalid/model-configuration-snapshot.invalid.json" + }, + { + "name": "project-key-manifest", + "id": "https://thinkloom.app/schemas/provenance/1.0/project-key-manifest.schema.json", + "file": "project-key-manifest.schema.json", + "valid_fixture": "fixtures/valid/project-key-manifest.valid.json", + "invalid_fixture": "fixtures/invalid/project-key-manifest.invalid.json" + }, + { + "name": "project-manifest", + "id": "https://thinkloom.app/schemas/provenance/1.0/project-manifest.schema.json", + "file": "project-manifest.schema.json", + "valid_fixture": "fixtures/valid/project-manifest.valid.json", + "invalid_fixture": "fixtures/invalid/project-manifest.invalid.json" + }, + { + "name": "prompt-template", + "id": "https://thinkloom.app/schemas/provenance/1.0/prompt-template.schema.json", + "file": "prompt-template.schema.json", + "valid_fixture": "fixtures/valid/prompt-template.valid.json", + "invalid_fixture": "fixtures/invalid/prompt-template.invalid.json" + }, + { + "name": "prompt-template-reference", + "id": "https://thinkloom.app/schemas/provenance/1.0/prompt-template-reference.schema.json", + "file": "prompt-template-reference.schema.json", + "valid_fixture": "fixtures/valid/prompt-template-reference.valid.json", + "invalid_fixture": "fixtures/invalid/prompt-template-reference.invalid.json" + }, + { + "name": "provenance-event", + "id": "https://thinkloom.app/schemas/provenance/1.0/provenance-event.schema.json", + "file": "provenance-event.schema.json", + "valid_fixture": "fixtures/valid/provenance-event.valid.json", + "invalid_fixture": "fixtures/invalid/provenance-event.invalid.json" + }, + { + "name": "provenance-policy", + "id": "https://thinkloom.app/schemas/provenance/1.0/provenance-policy.schema.json", + "file": "provenance-policy.schema.json", + "valid_fixture": "fixtures/valid/provenance-policy.valid.json", + "invalid_fixture": "fixtures/invalid/provenance-policy.invalid.json" + }, + { + "name": "purge-manifest", + "id": "https://thinkloom.app/schemas/provenance/1.0/purge-manifest.schema.json", + "file": "purge-manifest.schema.json", + "valid_fixture": "fixtures/valid/purge-manifest.valid.json", + "invalid_fixture": "fixtures/invalid/purge-manifest.invalid.json" + }, + { + "name": "record-envelope", + "id": "https://thinkloom.app/schemas/provenance/1.0/record-envelope.schema.json", + "file": "record-envelope.schema.json", + "valid_fixture": "fixtures/valid/record-envelope.valid.json", + "invalid_fixture": "fixtures/invalid/record-envelope.invalid.json" + }, + { + "name": "recovery-key-envelope", + "id": "https://thinkloom.app/schemas/provenance/1.0/recovery-key-envelope.schema.json", + "file": "recovery-key-envelope.schema.json", + "valid_fixture": "fixtures/valid/recovery-key-envelope.valid.json", + "invalid_fixture": "fixtures/invalid/recovery-key-envelope.invalid.json" + }, + { + "name": "release-manifest", + "id": "https://thinkloom.app/schemas/provenance/1.0/release-manifest.schema.json", + "file": "release-manifest.schema.json", + "valid_fixture": "fixtures/valid/release-manifest.valid.json", + "invalid_fixture": "fixtures/invalid/release-manifest.invalid.json" + }, + { + "name": "release-state", + "id": "https://thinkloom.app/schemas/provenance/1.0/release-state.schema.json", + "file": "release-state.schema.json", + "valid_fixture": "fixtures/valid/release-state.valid.json", + "invalid_fixture": "fixtures/invalid/release-state.invalid.json" + }, + { + "name": "sanitized-export-manifest", + "id": "https://thinkloom.app/schemas/provenance/1.0/sanitized-export-manifest.schema.json", + "file": "sanitized-export-manifest.schema.json", + "valid_fixture": "fixtures/valid/sanitized-export-manifest.valid.json", + "invalid_fixture": "fixtures/invalid/sanitized-export-manifest.invalid.json" + }, + { + "name": "text-fragment-reference", + "id": "https://thinkloom.app/schemas/provenance/1.0/text-fragment-reference.schema.json", + "file": "text-fragment-reference.schema.json", + "valid_fixture": "fixtures/valid/text-fragment-reference.valid.json", + "invalid_fixture": "fixtures/invalid/text-fragment-reference.invalid.json" + }, + { + "name": "transcript-correction", + "id": "https://thinkloom.app/schemas/provenance/1.0/transcript-correction.schema.json", + "file": "transcript-correction.schema.json", + "valid_fixture": "fixtures/valid/transcript-correction.valid.json", + "invalid_fixture": "fixtures/invalid/transcript-correction.invalid.json" + }, + { + "name": "transcript-normalization", + "id": "https://thinkloom.app/schemas/provenance/1.0/transcript-normalization.schema.json", + "file": "transcript-normalization.schema.json", + "valid_fixture": "fixtures/valid/transcript-normalization.valid.json", + "invalid_fixture": "fixtures/invalid/transcript-normalization.invalid.json" + }, + { + "name": "transcript-turn", + "id": "https://thinkloom.app/schemas/provenance/1.0/transcript-turn.schema.json", + "file": "transcript-turn.schema.json", + "valid_fixture": "fixtures/valid/transcript-turn.valid.json", + "invalid_fixture": "fixtures/invalid/transcript-turn.invalid.json" + }, + { + "name": "verification-report", + "id": "https://thinkloom.app/schemas/provenance/1.0/verification-report.schema.json", + "file": "verification-report.schema.json", + "valid_fixture": "fixtures/valid/verification-report.valid.json", + "invalid_fixture": "fixtures/invalid/verification-report.invalid.json" + }, + { + "name": "write-intent", + "id": "https://thinkloom.app/schemas/provenance/1.0/write-intent.schema.json", + "file": "write-intent.schema.json", + "valid_fixture": "fixtures/valid/write-intent.valid.json", + "invalid_fixture": "fixtures/invalid/write-intent.invalid.json" + } + ] +} diff --git a/schemas/provenance/v1/chain-head.schema.json b/schemas/provenance/v1/chain-head.schema.json new file mode 100644 index 0000000..bdba103 --- /dev/null +++ b/schemas/provenance/v1/chain-head.schema.json @@ -0,0 +1,58 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/chain-head.schema.json", + "title": "Chain head", + "description": "Durable pointer to the last committed provenance event.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "project_id": { + "type": "string", + "pattern": "^project_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "active_segment_number": { + "type": "integer", + "minimum": 1 + }, + "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}$" + }, + "updated_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", + "project_id", + "active_segment_number", + "event_id", + "event_sequence", + "event_hash", + "updated_at" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "active_segment_number": 1, + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "updated_at": "2026-07-17T18:42:10.123Z" + } + ] +} diff --git a/schemas/provenance/v1/content-reference.schema.json b/schemas/provenance/v1/content-reference.schema.json new file mode 100644 index 0000000..ef5dbd9 --- /dev/null +++ b/schemas/provenance/v1/content-reference.schema.json @@ -0,0 +1,98 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/content-reference.schema.json", + "title": "Content reference", + "description": "Content-addressed link to an authoritative record or revision.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "record_id": { + "type": "string", + "pattern": "^record_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "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" + ] + }, + "sha256": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + }, + "path": { + "anyOf": [ + { + "type": "string", + "minLength": 1, + "pattern": "^(?!/)(?![A-Za-z]:)(?!.*\\\\)(?!.*(?:^|/)\\.\\.?(?:/|$))[^\\u0000-\\u001f]+$" + }, + { + "type": "null" + } + ] + }, + "revision_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^revision_[0-9A-HJKMNP-TV-Z]{26}$" + }, + { + "type": "null" + } + ] + }, + "range": { + "anyOf": [ + { + "$ref": "https://thinkloom.app/schemas/provenance/1.0/text-fragment-reference.schema.json" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "schema_version", + "record_id", + "record_type", + "sha256", + "path", + "revision_id", + "range" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ] +} diff --git a/schemas/provenance/v1/conversation-session.schema.json b/schemas/provenance/v1/conversation-session.schema.json new file mode 100644 index 0000000..e3443a1 --- /dev/null +++ b/schemas/provenance/v1/conversation-session.schema.json @@ -0,0 +1,87 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/conversation-session.schema.json", + "title": "Conversation session", + "description": "Canonical conversation-session metadata without audio retention.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "session_id": { + "type": "string", + "pattern": "^session_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "project_id": { + "type": "string", + "pattern": "^project_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "title": { + "type": "string" + }, + "mode": { + "enum": [ + "typed", + "voice", + "mixed" + ] + }, + "started_at": { + "type": "string", + "format": "date-time", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$" + }, + "ended_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$" + }, + { + "type": "null" + } + ] + }, + "turn_count": { + "type": "integer", + "minimum": 0 + }, + "audio_retained": { + "const": false + }, + "retention_mode": { + "enum": [ + "minimal", + "full_private" + ] + } + }, + "required": [ + "schema_version", + "session_id", + "project_id", + "title", + "mode", + "started_at", + "ended_at", + "turn_count", + "audio_retained", + "retention_mode" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "session_id": "session_01J00000000000000000000006", + "project_id": "project_01J00000000000000000000001", + "title": "Opening discussion", + "mode": "typed", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "turn_count": 2, + "audio_retained": false, + "retention_mode": "minimal" + } + ] +} diff --git a/schemas/provenance/v1/derived-index-manifest.schema.json b/schemas/provenance/v1/derived-index-manifest.schema.json new file mode 100644 index 0000000..b2b29b2 --- /dev/null +++ b/schemas/provenance/v1/derived-index-manifest.schema.json @@ -0,0 +1,85 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/derived-index-manifest.schema.json", + "title": "Derived index manifest", + "description": "Non-authoritative reproducibility metadata for a derived index.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "index_type": { + "enum": [ + "content_index", + "contribution_graph", + "manuscript_lineage", + "checkpoint_index" + ] + }, + "source_chain_head": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + }, + "source_event_count": { + "type": "integer", + "minimum": 0 + }, + "generator": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1 + }, + "version": { + "type": "string", + "pattern": "^\\d+\\.\\d+\\.\\d+$" + }, + "configuration_sha256": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + } + }, + "required": [ + "name", + "version", + "configuration_sha256" + ], + "additionalProperties": false + }, + "content_sha256": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + }, + "generated_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", + "index_type", + "source_chain_head", + "source_event_count", + "generator", + "content_sha256", + "generated_at" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "index_type": "contribution_graph", + "source_chain_head": "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "source_event_count": 42, + "generator": { + "name": "thinkloom-indexer", + "version": "1.0.0", + "configuration_sha256": "sha256:0000000000000000000000000000000000000000000000000000000000000000" + }, + "content_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "generated_at": "2026-07-17T18:42:10.123Z" + } + ] +} diff --git a/schemas/provenance/v1/disposition-revision.schema.json b/schemas/provenance/v1/disposition-revision.schema.json new file mode 100644 index 0000000..17118b6 --- /dev/null +++ b/schemas/provenance/v1/disposition-revision.schema.json @@ -0,0 +1,154 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/disposition-revision.schema.json", + "title": "Invocation disposition revision", + "description": "Immutable ordered record of user action on one model result.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "disposition_id": { + "type": "string", + "pattern": "^disposition_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "invocation_id": { + "type": "string", + "pattern": "^invocation_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "revision_number": { + "type": "integer", + "minimum": 1 + }, + "status": { + "enum": [ + "staged", + "accepted", + "partially_accepted", + "rejected", + "discarded" + ] + }, + "accepted_ranges": { + "type": "array", + "items": { + "$ref": "https://thinkloom.app/schemas/provenance/1.0/text-fragment-reference.schema.json" + } + }, + "rejected_ranges": { + "type": "array", + "items": { + "$ref": "https://thinkloom.app/schemas/provenance/1.0/text-fragment-reference.schema.json" + } + }, + "destination": { + "anyOf": [ + { + "type": "object", + "properties": { + "revision_id": { + "type": "string", + "pattern": "^revision_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "path": { + "type": "string", + "minLength": 1, + "pattern": "^(?!/)(?![A-Za-z]:)(?!.*\\\\)(?!.*(?:^|/)\\.\\.?(?:/|$))[^\\u0000-\\u001f]+$" + }, + "operation": { + "enum": [ + "insert", + "replace", + "append", + "new_section" + ] + }, + "position": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "revision_id", + "path", + "operation", + "position" + ], + "additionalProperties": false + }, + { + "type": "null" + } + ] + }, + "stale_context_resolution": { + "enum": [ + "not_stale", + "revalidated", + "rebased", + "explicitly_confirmed", + "rejected" + ] + }, + "decided_at": { + "type": "string", + "format": "date-time", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$" + }, + "event_id": { + "type": "string", + "pattern": "^event_[0-9A-HJKMNP-TV-Z]{26}$" + } + }, + "required": [ + "schema_version", + "disposition_id", + "invocation_id", + "revision_number", + "status", + "accepted_ranges", + "rejected_ranges", + "destination", + "stale_context_resolution", + "decided_at", + "event_id" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + ] +} diff --git a/schemas/provenance/v1/edit-transaction.schema.json b/schemas/provenance/v1/edit-transaction.schema.json new file mode 100644 index 0000000..e955e58 --- /dev/null +++ b/schemas/provenance/v1/edit-transaction.schema.json @@ -0,0 +1,150 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/edit-transaction.schema.json", + "title": "Manuscript edit transaction", + "description": "Meaningful coalesced manual or acceptance-driven edit transaction.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "transaction_id": { + "type": "string", + "pattern": "^transaction_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "project_id": { + "type": "string", + "pattern": "^project_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "base_revision_id": { + "type": "string", + "pattern": "^revision_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "result_revision_id": { + "type": "string", + "pattern": "^revision_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "started_at": { + "type": "string", + "format": "date-time", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$" + }, + "ended_at": { + "type": "string", + "format": "date-time", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$" + }, + "operations": { + "type": "array", + "items": { + "type": "object", + "properties": { + "operation_type": { + "enum": [ + "insert", + "delete", + "replace", + "move", + "format" + ] + }, + "source_range": { + "anyOf": [ + { + "$ref": "https://thinkloom.app/schemas/provenance/1.0/text-fragment-reference.schema.json" + }, + { + "type": "null" + } + ] + }, + "destination_position": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "null" + } + ] + }, + "inserted_text_sha256": { + "anyOf": [ + { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + }, + { + "type": "null" + } + ] + }, + "result_fragment_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^fragment_[0-9A-HJKMNP-TV-Z]{26}$" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "operation_type", + "source_range", + "destination_position", + "inserted_text_sha256", + "result_fragment_id" + ], + "additionalProperties": false + }, + "minItems": 1 + }, + "preimage_sha256": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + }, + "result_sha256": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + } + }, + "required": [ + "schema_version", + "transaction_id", + "project_id", + "base_revision_id", + "result_revision_id", + "started_at", + "ended_at", + "operations", + "preimage_sha256", + "result_sha256" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "transaction_id": "transaction_01J0000000000000000000000N", + "project_id": "project_01J00000000000000000000001", + "base_revision_id": "revision_01J0000000000000000000000A", + "result_revision_id": "revision_01J0000000000000000000000B", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "operations": [ + { + "operation_type": "insert", + "source_range": null, + "destination_position": 0, + "inserted_text_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "result_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "preimage_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "result_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + } + ] +} diff --git a/schemas/provenance/v1/encrypted-key-envelope.schema.json b/schemas/provenance/v1/encrypted-key-envelope.schema.json new file mode 100644 index 0000000..123fcf7 --- /dev/null +++ b/schemas/provenance/v1/encrypted-key-envelope.schema.json @@ -0,0 +1,114 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/encrypted-key-envelope.schema.json", + "title": "Encrypted key envelope", + "description": "Authenticated envelope wrapping a project data-encryption key.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "envelope_id": { + "type": "string", + "pattern": "^record_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "key_id": { + "type": "string", + "pattern": "^key_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "envelope_type": { + "enum": [ + "device", + "recovery" + ] + }, + "algorithm": { + "enum": [ + "xchacha20-poly1305" + ] + }, + "key_derivation": { + "anyOf": [ + { + "type": "object", + "properties": { + "algorithm": { + "const": "argon2id" + }, + "memory_kib": { + "type": "integer", + "minimum": 65536 + }, + "iterations": { + "type": "integer", + "minimum": 1 + }, + "parallelism": { + "type": "integer", + "minimum": 1 + }, + "salt": { + "type": "string", + "minLength": 16 + } + }, + "required": [ + "algorithm", + "memory_kib", + "iterations", + "parallelism", + "salt" + ], + "additionalProperties": false + }, + { + "type": "null" + } + ] + }, + "nonce": { + "type": "string", + "minLength": 32 + }, + "wrapped_key": { + "type": "string", + "minLength": 16 + }, + "ciphertext_sha256": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + }, + "created_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", + "envelope_id", + "key_id", + "envelope_type", + "algorithm", + "key_derivation", + "nonce", + "wrapped_key", + "ciphertext_sha256", + "created_at" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "envelope_id": "record_01J00000000000000000000005", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "device", + "algorithm": "xchacha20-poly1305", + "key_derivation": null, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/backup-manifest.invalid.json b/schemas/provenance/v1/fixtures/invalid/backup-manifest.invalid.json new file mode 100644 index 0000000..681b276 --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/backup-manifest.invalid.json @@ -0,0 +1,997 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/backup-manifest.schema.json", + "cases": [ + { + "description": "backup-manifest.schema_version: reject missing required property", + "instance": { + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "sqlite_version": "3.46.0", + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [ + { + "path": "project.json", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": 256 + } + ], + "protected": false, + "recovery_key_envelope_path": null + } + }, + { + "description": "backup-manifest.application_version: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "sqlite_version": "3.46.0", + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [ + { + "path": "project.json", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": 256 + } + ], + "protected": false, + "recovery_key_envelope_path": null + } + }, + { + "description": "backup-manifest.project_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "sqlite_version": "3.46.0", + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [ + { + "path": "project.json", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": 256 + } + ], + "protected": false, + "recovery_key_envelope_path": null + } + }, + { + "description": "backup-manifest.created_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "sqlite_version": "3.46.0", + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [ + { + "path": "project.json", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": 256 + } + ], + "protected": false, + "recovery_key_envelope_path": null + } + }, + { + "description": "backup-manifest.source_chain_head: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "sqlite_version": "3.46.0", + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [ + { + "path": "project.json", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": 256 + } + ], + "protected": false, + "recovery_key_envelope_path": null + } + }, + { + "description": "backup-manifest.sqlite_snapshot: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "files": [ + { + "path": "project.json", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": 256 + } + ], + "protected": false, + "recovery_key_envelope_path": null + } + }, + { + "description": "backup-manifest.files: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "sqlite_version": "3.46.0", + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "protected": false, + "recovery_key_envelope_path": null + } + }, + { + "description": "backup-manifest.protected: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "sqlite_version": "3.46.0", + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [ + { + "path": "project.json", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": 256 + } + ], + "recovery_key_envelope_path": null + } + }, + { + "description": "backup-manifest.recovery_key_envelope_path: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "sqlite_version": "3.46.0", + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [ + { + "path": "project.json", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": 256 + } + ], + "protected": false + } + }, + { + "description": "backup-manifest: reject unexpected property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "sqlite_version": "3.46.0", + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [ + { + "path": "project.json", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": 256 + } + ], + "protected": false, + "recovery_key_envelope_path": null, + "__unexpected": true + } + }, + { + "description": "backup-manifest.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "sqlite_version": "3.46.0", + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [ + { + "path": "project.json", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": 256 + } + ], + "protected": false, + "recovery_key_envelope_path": null + } + }, + { + "description": "backup-manifest.application_version: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "application_version": " invalid!", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "sqlite_version": "3.46.0", + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [ + { + "path": "project.json", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": 256 + } + ], + "protected": false, + "recovery_key_envelope_path": null + } + }, + { + "description": "backup-manifest.project_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "invalid-id", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "sqlite_version": "3.46.0", + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [ + { + "path": "project.json", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": 256 + } + ], + "protected": false, + "recovery_key_envelope_path": null + } + }, + { + "description": "backup-manifest.created_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "not-a-timestamp", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "sqlite_version": "3.46.0", + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [ + { + "path": "project.json", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": 256 + } + ], + "protected": false, + "recovery_key_envelope_path": null + } + }, + { + "description": "backup-manifest.source_chain_head: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:INVALID", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "sqlite_version": "3.46.0", + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [ + { + "path": "project.json", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": 256 + } + ], + "protected": false, + "recovery_key_envelope_path": null + } + }, + { + "description": "backup-manifest.sqlite_snapshot.path: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "sqlite_version": "3.46.0", + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [ + { + "path": "project.json", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": 256 + } + ], + "protected": false, + "recovery_key_envelope_path": null + } + }, + { + "description": "backup-manifest.sqlite_snapshot.sha256: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "size": 4096, + "sqlite_version": "3.46.0", + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [ + { + "path": "project.json", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": 256 + } + ], + "protected": false, + "recovery_key_envelope_path": null + } + }, + { + "description": "backup-manifest.sqlite_snapshot.size: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "sqlite_version": "3.46.0", + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [ + { + "path": "project.json", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": 256 + } + ], + "protected": false, + "recovery_key_envelope_path": null + } + }, + { + "description": "backup-manifest.sqlite_snapshot.sqlite_version: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [ + { + "path": "project.json", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": 256 + } + ], + "protected": false, + "recovery_key_envelope_path": null + } + }, + { + "description": "backup-manifest.sqlite_snapshot.database_schema_version: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "sqlite_version": "3.46.0", + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [ + { + "path": "project.json", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": 256 + } + ], + "protected": false, + "recovery_key_envelope_path": null + } + }, + { + "description": "backup-manifest.sqlite_snapshot.completed_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "sqlite_version": "3.46.0", + "database_schema_version": 1 + }, + "files": [ + { + "path": "project.json", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": 256 + } + ], + "protected": false, + "recovery_key_envelope_path": null + } + }, + { + "description": "backup-manifest.sqlite_snapshot: reject unexpected property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "sqlite_version": "3.46.0", + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z", + "__unexpected": true + }, + "files": [ + { + "path": "project.json", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": 256 + } + ], + "protected": false, + "recovery_key_envelope_path": null + } + }, + { + "description": "backup-manifest.sqlite_snapshot.path: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "../outside-project", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "sqlite_version": "3.46.0", + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [ + { + "path": "project.json", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": 256 + } + ], + "protected": false, + "recovery_key_envelope_path": null + } + }, + { + "description": "backup-manifest.sqlite_snapshot.path: reject string below minLength", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "sqlite_version": "3.46.0", + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [ + { + "path": "project.json", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": 256 + } + ], + "protected": false, + "recovery_key_envelope_path": null + } + }, + { + "description": "backup-manifest.sqlite_snapshot.sha256: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:INVALID", + "size": 4096, + "sqlite_version": "3.46.0", + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [ + { + "path": "project.json", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": 256 + } + ], + "protected": false, + "recovery_key_envelope_path": null + } + }, + { + "description": "backup-manifest.sqlite_snapshot.size: reject value below minimum", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 0, + "sqlite_version": "3.46.0", + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [ + { + "path": "project.json", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": 256 + } + ], + "protected": false, + "recovery_key_envelope_path": null + } + }, + { + "description": "backup-manifest.sqlite_snapshot.sqlite_version: reject string below minLength", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "sqlite_version": "", + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [ + { + "path": "project.json", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": 256 + } + ], + "protected": false, + "recovery_key_envelope_path": null + } + }, + { + "description": "backup-manifest.sqlite_snapshot.database_schema_version: reject value below minimum", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "sqlite_version": "3.46.0", + "database_schema_version": 0, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [ + { + "path": "project.json", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": 256 + } + ], + "protected": false, + "recovery_key_envelope_path": null + } + }, + { + "description": "backup-manifest.sqlite_snapshot.completed_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "sqlite_version": "3.46.0", + "database_schema_version": 1, + "completed_at": "not-a-timestamp" + }, + "files": [ + { + "path": "project.json", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": 256 + } + ], + "protected": false, + "recovery_key_envelope_path": null + } + }, + { + "description": "backup-manifest.files: reject array below minItems", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "sqlite_version": "3.46.0", + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [], + "protected": false, + "recovery_key_envelope_path": null + } + }, + { + "description": "backup-manifest.files[0].path: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "sqlite_version": "3.46.0", + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [ + { + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": 256 + } + ], + "protected": false, + "recovery_key_envelope_path": null + } + }, + { + "description": "backup-manifest.files[0].sha256: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "sqlite_version": "3.46.0", + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [ + { + "path": "project.json", + "size": 256 + } + ], + "protected": false, + "recovery_key_envelope_path": null + } + }, + { + "description": "backup-manifest.files[0].size: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "sqlite_version": "3.46.0", + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [ + { + "path": "project.json", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333" + } + ], + "protected": false, + "recovery_key_envelope_path": null + } + }, + { + "description": "backup-manifest.files[0]: reject unexpected property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "sqlite_version": "3.46.0", + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [ + { + "path": "project.json", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": 256, + "__unexpected": true + } + ], + "protected": false, + "recovery_key_envelope_path": null + } + }, + { + "description": "backup-manifest.files[0].path: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "sqlite_version": "3.46.0", + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [ + { + "path": "../outside-project", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": 256 + } + ], + "protected": false, + "recovery_key_envelope_path": null + } + }, + { + "description": "backup-manifest.files[0].path: reject string below minLength", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "sqlite_version": "3.46.0", + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [ + { + "path": "", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": 256 + } + ], + "protected": false, + "recovery_key_envelope_path": null + } + }, + { + "description": "backup-manifest.files[0].sha256: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "sqlite_version": "3.46.0", + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [ + { + "path": "project.json", + "sha256": "sha256:INVALID", + "size": 256 + } + ], + "protected": false, + "recovery_key_envelope_path": null + } + }, + { + "description": "backup-manifest.files[0].size: reject value below minimum", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "sqlite_version": "3.46.0", + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [ + { + "path": "project.json", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": -1 + } + ], + "protected": false, + "recovery_key_envelope_path": null + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/chain-head.invalid.json b/schemas/provenance/v1/fixtures/invalid/chain-head.invalid.json new file mode 100644 index 0000000..1ec40ae --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/chain-head.invalid.json @@ -0,0 +1,179 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/chain-head.schema.json", + "cases": [ + { + "description": "chain-head.schema_version: reject missing required property", + "instance": { + "project_id": "project_01J00000000000000000000001", + "active_segment_number": 1, + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "chain-head.project_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "active_segment_number": 1, + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "chain-head.active_segment_number: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "chain-head.event_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "active_segment_number": 1, + "event_sequence": 1, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "chain-head.event_sequence: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "active_segment_number": 1, + "event_id": "event_01J00000000000000000000003", + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "chain-head.event_hash: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "active_segment_number": 1, + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "chain-head.updated_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "active_segment_number": 1, + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "chain-head: reject unexpected property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "active_segment_number": 1, + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "updated_at": "2026-07-17T18:42:10.123Z", + "__unexpected": true + } + }, + { + "description": "chain-head.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "project_id": "project_01J00000000000000000000001", + "active_segment_number": 1, + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "chain-head.project_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "project_id": "invalid-id", + "active_segment_number": 1, + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "chain-head.active_segment_number: reject value below minimum", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "active_segment_number": 0, + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "chain-head.event_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "active_segment_number": 1, + "event_id": "invalid-id", + "event_sequence": 1, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "chain-head.event_sequence: reject value below minimum", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "active_segment_number": 1, + "event_id": "event_01J00000000000000000000003", + "event_sequence": 0, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "chain-head.event_hash: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "active_segment_number": 1, + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "event_hash": "sha256:INVALID", + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "chain-head.updated_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "active_segment_number": 1, + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "updated_at": "not-a-timestamp" + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/content-reference.invalid.json b/schemas/provenance/v1/fixtures/invalid/content-reference.invalid.json new file mode 100644 index 0000000..75f0317 --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/content-reference.invalid.json @@ -0,0 +1,585 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/content-reference.schema.json", + "cases": [ + { + "description": "content-reference.schema_version: reject missing required property", + "instance": { + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + }, + { + "description": "content-reference.record_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + }, + { + "description": "content-reference.record_type: reject missing required property", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + }, + { + "description": "content-reference.sha256: reject missing required property", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + }, + { + "description": "content-reference.path: reject missing required property", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + }, + { + "description": "content-reference.revision_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + }, + { + "description": "content-reference.range: reject missing required property", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A" + } + }, + { + "description": "content-reference: reject unexpected property", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + }, + "__unexpected": true + } + }, + { + "description": "content-reference.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + }, + { + "description": "content-reference.record_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "record_id": "invalid-id", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + }, + { + "description": "content-reference.record_type: reject value outside enum", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "__INVALID_ENUM__", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + }, + { + "description": "content-reference.sha256: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:INVALID", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + }, + { + "description": "content-reference.path: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "../outside-project", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + }, + { + "description": "content-reference.path: reject string below minLength", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + }, + { + "description": "content-reference.revision_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "invalid-id", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + }, + { + "description": "content-reference.range.schema_version: reject missing required property", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + }, + { + "description": "content-reference.range.document_revision_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + }, + { + "description": "content-reference.range.coordinate_system: reject missing required property", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + }, + { + "description": "content-reference.range.start: reject missing required property", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + }, + { + "description": "content-reference.range.end: reject missing required property", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + }, + { + "description": "content-reference.range.preimage_sha256: reject missing required property", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + }, + { + "description": "content-reference.range.text_fragment_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111" + } + } + }, + { + "description": "content-reference.range: reject unexpected property", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C", + "__unexpected": true + } + } + }, + { + "description": "content-reference.range.schema_version: reject value different from const", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "__INVALID_CONST__", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + }, + { + "description": "content-reference.range.document_revision_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "invalid-id", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + }, + { + "description": "content-reference.range.coordinate_system: reject value outside enum", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "__INVALID_ENUM__", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + }, + { + "description": "content-reference.range.start: reject value below minimum", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": -1, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + }, + { + "description": "content-reference.range.end: reject value below minimum", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": -1, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + }, + { + "description": "content-reference.range.preimage_sha256: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:INVALID", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + }, + { + "description": "content-reference.range.text_fragment_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "invalid-id" + } + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/conversation-session.invalid.json b/schemas/provenance/v1/fixtures/invalid/conversation-session.invalid.json new file mode 100644 index 0000000..dc42394 --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/conversation-session.invalid.json @@ -0,0 +1,296 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/conversation-session.schema.json", + "cases": [ + { + "description": "conversation-session.schema_version: reject missing required property", + "instance": { + "session_id": "session_01J00000000000000000000006", + "project_id": "project_01J00000000000000000000001", + "title": "Opening discussion", + "mode": "typed", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "turn_count": 2, + "audio_retained": false, + "retention_mode": "minimal" + } + }, + { + "description": "conversation-session.session_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "title": "Opening discussion", + "mode": "typed", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "turn_count": 2, + "audio_retained": false, + "retention_mode": "minimal" + } + }, + { + "description": "conversation-session.project_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "session_id": "session_01J00000000000000000000006", + "title": "Opening discussion", + "mode": "typed", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "turn_count": 2, + "audio_retained": false, + "retention_mode": "minimal" + } + }, + { + "description": "conversation-session.title: reject missing required property", + "instance": { + "schema_version": "1.0", + "session_id": "session_01J00000000000000000000006", + "project_id": "project_01J00000000000000000000001", + "mode": "typed", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "turn_count": 2, + "audio_retained": false, + "retention_mode": "minimal" + } + }, + { + "description": "conversation-session.mode: reject missing required property", + "instance": { + "schema_version": "1.0", + "session_id": "session_01J00000000000000000000006", + "project_id": "project_01J00000000000000000000001", + "title": "Opening discussion", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "turn_count": 2, + "audio_retained": false, + "retention_mode": "minimal" + } + }, + { + "description": "conversation-session.started_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "session_id": "session_01J00000000000000000000006", + "project_id": "project_01J00000000000000000000001", + "title": "Opening discussion", + "mode": "typed", + "ended_at": "2026-07-17T18:43:11.456Z", + "turn_count": 2, + "audio_retained": false, + "retention_mode": "minimal" + } + }, + { + "description": "conversation-session.ended_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "session_id": "session_01J00000000000000000000006", + "project_id": "project_01J00000000000000000000001", + "title": "Opening discussion", + "mode": "typed", + "started_at": "2026-07-17T18:42:10.123Z", + "turn_count": 2, + "audio_retained": false, + "retention_mode": "minimal" + } + }, + { + "description": "conversation-session.turn_count: reject missing required property", + "instance": { + "schema_version": "1.0", + "session_id": "session_01J00000000000000000000006", + "project_id": "project_01J00000000000000000000001", + "title": "Opening discussion", + "mode": "typed", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "audio_retained": false, + "retention_mode": "minimal" + } + }, + { + "description": "conversation-session.audio_retained: reject missing required property", + "instance": { + "schema_version": "1.0", + "session_id": "session_01J00000000000000000000006", + "project_id": "project_01J00000000000000000000001", + "title": "Opening discussion", + "mode": "typed", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "turn_count": 2, + "retention_mode": "minimal" + } + }, + { + "description": "conversation-session.retention_mode: reject missing required property", + "instance": { + "schema_version": "1.0", + "session_id": "session_01J00000000000000000000006", + "project_id": "project_01J00000000000000000000001", + "title": "Opening discussion", + "mode": "typed", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "turn_count": 2, + "audio_retained": false + } + }, + { + "description": "conversation-session: reject unexpected property", + "instance": { + "schema_version": "1.0", + "session_id": "session_01J00000000000000000000006", + "project_id": "project_01J00000000000000000000001", + "title": "Opening discussion", + "mode": "typed", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "turn_count": 2, + "audio_retained": false, + "retention_mode": "minimal", + "__unexpected": true + } + }, + { + "description": "conversation-session.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "session_id": "session_01J00000000000000000000006", + "project_id": "project_01J00000000000000000000001", + "title": "Opening discussion", + "mode": "typed", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "turn_count": 2, + "audio_retained": false, + "retention_mode": "minimal" + } + }, + { + "description": "conversation-session.session_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "session_id": "invalid-id", + "project_id": "project_01J00000000000000000000001", + "title": "Opening discussion", + "mode": "typed", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "turn_count": 2, + "audio_retained": false, + "retention_mode": "minimal" + } + }, + { + "description": "conversation-session.project_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "session_id": "session_01J00000000000000000000006", + "project_id": "invalid-id", + "title": "Opening discussion", + "mode": "typed", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "turn_count": 2, + "audio_retained": false, + "retention_mode": "minimal" + } + }, + { + "description": "conversation-session.mode: reject value outside enum", + "instance": { + "schema_version": "1.0", + "session_id": "session_01J00000000000000000000006", + "project_id": "project_01J00000000000000000000001", + "title": "Opening discussion", + "mode": "__INVALID_ENUM__", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "turn_count": 2, + "audio_retained": false, + "retention_mode": "minimal" + } + }, + { + "description": "conversation-session.started_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "session_id": "session_01J00000000000000000000006", + "project_id": "project_01J00000000000000000000001", + "title": "Opening discussion", + "mode": "typed", + "started_at": "not-a-timestamp", + "ended_at": "2026-07-17T18:43:11.456Z", + "turn_count": 2, + "audio_retained": false, + "retention_mode": "minimal" + } + }, + { + "description": "conversation-session.ended_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "session_id": "session_01J00000000000000000000006", + "project_id": "project_01J00000000000000000000001", + "title": "Opening discussion", + "mode": "typed", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "not-a-timestamp", + "turn_count": 2, + "audio_retained": false, + "retention_mode": "minimal" + } + }, + { + "description": "conversation-session.turn_count: reject value below minimum", + "instance": { + "schema_version": "1.0", + "session_id": "session_01J00000000000000000000006", + "project_id": "project_01J00000000000000000000001", + "title": "Opening discussion", + "mode": "typed", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "turn_count": -1, + "audio_retained": false, + "retention_mode": "minimal" + } + }, + { + "description": "conversation-session.audio_retained: reject value different from const", + "instance": { + "schema_version": "1.0", + "session_id": "session_01J00000000000000000000006", + "project_id": "project_01J00000000000000000000001", + "title": "Opening discussion", + "mode": "typed", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "turn_count": 2, + "audio_retained": true, + "retention_mode": "minimal" + } + }, + { + "description": "conversation-session.retention_mode: reject value outside enum", + "instance": { + "schema_version": "1.0", + "session_id": "session_01J00000000000000000000006", + "project_id": "project_01J00000000000000000000001", + "title": "Opening discussion", + "mode": "typed", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "turn_count": 2, + "audio_retained": false, + "retention_mode": "__INVALID_ENUM__" + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/derived-index-manifest.invalid.json b/schemas/provenance/v1/fixtures/invalid/derived-index-manifest.invalid.json new file mode 100644 index 0000000..5a354a1 --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/derived-index-manifest.invalid.json @@ -0,0 +1,329 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/derived-index-manifest.schema.json", + "cases": [ + { + "description": "derived-index-manifest.schema_version: reject missing required property", + "instance": { + "index_type": "contribution_graph", + "source_chain_head": "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "source_event_count": 42, + "generator": { + "name": "thinkloom-indexer", + "version": "1.0.0", + "configuration_sha256": "sha256:0000000000000000000000000000000000000000000000000000000000000000" + }, + "content_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "generated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "derived-index-manifest.index_type: reject missing required property", + "instance": { + "schema_version": "1.0", + "source_chain_head": "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "source_event_count": 42, + "generator": { + "name": "thinkloom-indexer", + "version": "1.0.0", + "configuration_sha256": "sha256:0000000000000000000000000000000000000000000000000000000000000000" + }, + "content_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "generated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "derived-index-manifest.source_chain_head: reject missing required property", + "instance": { + "schema_version": "1.0", + "index_type": "contribution_graph", + "source_event_count": 42, + "generator": { + "name": "thinkloom-indexer", + "version": "1.0.0", + "configuration_sha256": "sha256:0000000000000000000000000000000000000000000000000000000000000000" + }, + "content_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "generated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "derived-index-manifest.source_event_count: reject missing required property", + "instance": { + "schema_version": "1.0", + "index_type": "contribution_graph", + "source_chain_head": "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "generator": { + "name": "thinkloom-indexer", + "version": "1.0.0", + "configuration_sha256": "sha256:0000000000000000000000000000000000000000000000000000000000000000" + }, + "content_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "generated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "derived-index-manifest.generator: reject missing required property", + "instance": { + "schema_version": "1.0", + "index_type": "contribution_graph", + "source_chain_head": "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "source_event_count": 42, + "content_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "generated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "derived-index-manifest.content_sha256: reject missing required property", + "instance": { + "schema_version": "1.0", + "index_type": "contribution_graph", + "source_chain_head": "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "source_event_count": 42, + "generator": { + "name": "thinkloom-indexer", + "version": "1.0.0", + "configuration_sha256": "sha256:0000000000000000000000000000000000000000000000000000000000000000" + }, + "generated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "derived-index-manifest.generated_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "index_type": "contribution_graph", + "source_chain_head": "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "source_event_count": 42, + "generator": { + "name": "thinkloom-indexer", + "version": "1.0.0", + "configuration_sha256": "sha256:0000000000000000000000000000000000000000000000000000000000000000" + }, + "content_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111" + } + }, + { + "description": "derived-index-manifest: reject unexpected property", + "instance": { + "schema_version": "1.0", + "index_type": "contribution_graph", + "source_chain_head": "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "source_event_count": 42, + "generator": { + "name": "thinkloom-indexer", + "version": "1.0.0", + "configuration_sha256": "sha256:0000000000000000000000000000000000000000000000000000000000000000" + }, + "content_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "generated_at": "2026-07-17T18:42:10.123Z", + "__unexpected": true + } + }, + { + "description": "derived-index-manifest.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "index_type": "contribution_graph", + "source_chain_head": "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "source_event_count": 42, + "generator": { + "name": "thinkloom-indexer", + "version": "1.0.0", + "configuration_sha256": "sha256:0000000000000000000000000000000000000000000000000000000000000000" + }, + "content_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "generated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "derived-index-manifest.index_type: reject value outside enum", + "instance": { + "schema_version": "1.0", + "index_type": "__INVALID_ENUM__", + "source_chain_head": "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "source_event_count": 42, + "generator": { + "name": "thinkloom-indexer", + "version": "1.0.0", + "configuration_sha256": "sha256:0000000000000000000000000000000000000000000000000000000000000000" + }, + "content_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "generated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "derived-index-manifest.source_chain_head: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "index_type": "contribution_graph", + "source_chain_head": "sha256:INVALID", + "source_event_count": 42, + "generator": { + "name": "thinkloom-indexer", + "version": "1.0.0", + "configuration_sha256": "sha256:0000000000000000000000000000000000000000000000000000000000000000" + }, + "content_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "generated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "derived-index-manifest.source_event_count: reject value below minimum", + "instance": { + "schema_version": "1.0", + "index_type": "contribution_graph", + "source_chain_head": "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "source_event_count": -1, + "generator": { + "name": "thinkloom-indexer", + "version": "1.0.0", + "configuration_sha256": "sha256:0000000000000000000000000000000000000000000000000000000000000000" + }, + "content_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "generated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "derived-index-manifest.generator.name: reject missing required property", + "instance": { + "schema_version": "1.0", + "index_type": "contribution_graph", + "source_chain_head": "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "source_event_count": 42, + "generator": { + "version": "1.0.0", + "configuration_sha256": "sha256:0000000000000000000000000000000000000000000000000000000000000000" + }, + "content_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "generated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "derived-index-manifest.generator.version: reject missing required property", + "instance": { + "schema_version": "1.0", + "index_type": "contribution_graph", + "source_chain_head": "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "source_event_count": 42, + "generator": { + "name": "thinkloom-indexer", + "configuration_sha256": "sha256:0000000000000000000000000000000000000000000000000000000000000000" + }, + "content_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "generated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "derived-index-manifest.generator.configuration_sha256: reject missing required property", + "instance": { + "schema_version": "1.0", + "index_type": "contribution_graph", + "source_chain_head": "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "source_event_count": 42, + "generator": { + "name": "thinkloom-indexer", + "version": "1.0.0" + }, + "content_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "generated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "derived-index-manifest.generator: reject unexpected property", + "instance": { + "schema_version": "1.0", + "index_type": "contribution_graph", + "source_chain_head": "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "source_event_count": 42, + "generator": { + "name": "thinkloom-indexer", + "version": "1.0.0", + "configuration_sha256": "sha256:0000000000000000000000000000000000000000000000000000000000000000", + "__unexpected": true + }, + "content_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "generated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "derived-index-manifest.generator.name: reject string below minLength", + "instance": { + "schema_version": "1.0", + "index_type": "contribution_graph", + "source_chain_head": "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "source_event_count": 42, + "generator": { + "name": "", + "version": "1.0.0", + "configuration_sha256": "sha256:0000000000000000000000000000000000000000000000000000000000000000" + }, + "content_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "generated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "derived-index-manifest.generator.version: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "index_type": "contribution_graph", + "source_chain_head": "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "source_event_count": 42, + "generator": { + "name": "thinkloom-indexer", + "version": " invalid!", + "configuration_sha256": "sha256:0000000000000000000000000000000000000000000000000000000000000000" + }, + "content_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "generated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "derived-index-manifest.generator.configuration_sha256: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "index_type": "contribution_graph", + "source_chain_head": "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "source_event_count": 42, + "generator": { + "name": "thinkloom-indexer", + "version": "1.0.0", + "configuration_sha256": "sha256:INVALID" + }, + "content_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "generated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "derived-index-manifest.content_sha256: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "index_type": "contribution_graph", + "source_chain_head": "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "source_event_count": 42, + "generator": { + "name": "thinkloom-indexer", + "version": "1.0.0", + "configuration_sha256": "sha256:0000000000000000000000000000000000000000000000000000000000000000" + }, + "content_sha256": "sha256:INVALID", + "generated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "derived-index-manifest.generated_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "index_type": "contribution_graph", + "source_chain_head": "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "source_event_count": 42, + "generator": { + "name": "thinkloom-indexer", + "version": "1.0.0", + "configuration_sha256": "sha256:0000000000000000000000000000000000000000000000000000000000000000" + }, + "content_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "generated_at": "not-a-timestamp" + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/disposition-revision.invalid.json b/schemas/provenance/v1/fixtures/invalid/disposition-revision.invalid.json new file mode 100644 index 0000000..a9acd0a --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/disposition-revision.invalid.json @@ -0,0 +1,1366 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/disposition-revision.schema.json", + "cases": [ + { + "description": "disposition-revision.schema_version: reject missing required property", + "instance": { + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.disposition_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.invocation_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.revision_number: reject missing required property", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.status: reject missing required property", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.accepted_ranges: reject missing required property", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.rejected_ranges: reject missing required property", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.destination: reject missing required property", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.stale_context_resolution: reject missing required property", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.decided_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.event_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "disposition-revision: reject unexpected property", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004", + "__unexpected": true + } + }, + { + "description": "disposition-revision.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.disposition_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "disposition_id": "invalid-id", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.invocation_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invalid-id", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.revision_number: reject value below minimum", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 0, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.status: reject value outside enum", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "__INVALID_ENUM__", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.accepted_ranges[0].schema_version: reject missing required property", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.accepted_ranges[0].document_revision_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.accepted_ranges[0].coordinate_system: reject missing required property", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.accepted_ranges[0].start: reject missing required property", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.accepted_ranges[0].end: reject missing required property", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.accepted_ranges[0].preimage_sha256: reject missing required property", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.accepted_ranges[0].text_fragment_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.accepted_ranges[0]: reject unexpected property", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C", + "__unexpected": true + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.accepted_ranges[0].schema_version: reject value different from const", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "__INVALID_CONST__", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.accepted_ranges[0].document_revision_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "invalid-id", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.accepted_ranges[0].coordinate_system: reject value outside enum", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "__INVALID_ENUM__", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.accepted_ranges[0].start: reject value below minimum", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": -1, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.accepted_ranges[0].end: reject value below minimum", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": -1, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.accepted_ranges[0].preimage_sha256: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:INVALID", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.accepted_ranges[0].text_fragment_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "invalid-id" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.destination.revision_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.destination.path: reject missing required property", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.destination.operation: reject missing required property", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.destination.position: reject missing required property", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert" + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.destination: reject unexpected property", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0, + "__unexpected": true + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.destination.revision_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "invalid-id", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.destination.path: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "../outside-project", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.destination.path: reject string below minLength", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.destination.operation: reject value outside enum", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "__INVALID_ENUM__", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.destination.position: reject value below minimum", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": -1 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.stale_context_resolution: reject value outside enum", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "__INVALID_ENUM__", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.decided_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "not-a-timestamp", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "disposition-revision.event_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "invalid-id" + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/edit-transaction.invalid.json b/schemas/provenance/v1/fixtures/invalid/edit-transaction.invalid.json new file mode 100644 index 0000000..c4c75b5 --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/edit-transaction.invalid.json @@ -0,0 +1,689 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/edit-transaction.schema.json", + "cases": [ + { + "description": "edit-transaction.schema_version: reject missing required property", + "instance": { + "transaction_id": "transaction_01J0000000000000000000000N", + "project_id": "project_01J00000000000000000000001", + "base_revision_id": "revision_01J0000000000000000000000A", + "result_revision_id": "revision_01J0000000000000000000000B", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "operations": [ + { + "operation_type": "insert", + "source_range": null, + "destination_position": 0, + "inserted_text_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "result_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "preimage_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "result_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + } + }, + { + "description": "edit-transaction.transaction_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "base_revision_id": "revision_01J0000000000000000000000A", + "result_revision_id": "revision_01J0000000000000000000000B", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "operations": [ + { + "operation_type": "insert", + "source_range": null, + "destination_position": 0, + "inserted_text_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "result_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "preimage_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "result_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + } + }, + { + "description": "edit-transaction.project_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "transaction_id": "transaction_01J0000000000000000000000N", + "base_revision_id": "revision_01J0000000000000000000000A", + "result_revision_id": "revision_01J0000000000000000000000B", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "operations": [ + { + "operation_type": "insert", + "source_range": null, + "destination_position": 0, + "inserted_text_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "result_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "preimage_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "result_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + } + }, + { + "description": "edit-transaction.base_revision_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "transaction_id": "transaction_01J0000000000000000000000N", + "project_id": "project_01J00000000000000000000001", + "result_revision_id": "revision_01J0000000000000000000000B", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "operations": [ + { + "operation_type": "insert", + "source_range": null, + "destination_position": 0, + "inserted_text_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "result_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "preimage_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "result_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + } + }, + { + "description": "edit-transaction.result_revision_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "transaction_id": "transaction_01J0000000000000000000000N", + "project_id": "project_01J00000000000000000000001", + "base_revision_id": "revision_01J0000000000000000000000A", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "operations": [ + { + "operation_type": "insert", + "source_range": null, + "destination_position": 0, + "inserted_text_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "result_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "preimage_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "result_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + } + }, + { + "description": "edit-transaction.started_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "transaction_id": "transaction_01J0000000000000000000000N", + "project_id": "project_01J00000000000000000000001", + "base_revision_id": "revision_01J0000000000000000000000A", + "result_revision_id": "revision_01J0000000000000000000000B", + "ended_at": "2026-07-17T18:43:11.456Z", + "operations": [ + { + "operation_type": "insert", + "source_range": null, + "destination_position": 0, + "inserted_text_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "result_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "preimage_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "result_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + } + }, + { + "description": "edit-transaction.ended_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "transaction_id": "transaction_01J0000000000000000000000N", + "project_id": "project_01J00000000000000000000001", + "base_revision_id": "revision_01J0000000000000000000000A", + "result_revision_id": "revision_01J0000000000000000000000B", + "started_at": "2026-07-17T18:42:10.123Z", + "operations": [ + { + "operation_type": "insert", + "source_range": null, + "destination_position": 0, + "inserted_text_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "result_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "preimage_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "result_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + } + }, + { + "description": "edit-transaction.operations: reject missing required property", + "instance": { + "schema_version": "1.0", + "transaction_id": "transaction_01J0000000000000000000000N", + "project_id": "project_01J00000000000000000000001", + "base_revision_id": "revision_01J0000000000000000000000A", + "result_revision_id": "revision_01J0000000000000000000000B", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "preimage_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "result_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + } + }, + { + "description": "edit-transaction.preimage_sha256: reject missing required property", + "instance": { + "schema_version": "1.0", + "transaction_id": "transaction_01J0000000000000000000000N", + "project_id": "project_01J00000000000000000000001", + "base_revision_id": "revision_01J0000000000000000000000A", + "result_revision_id": "revision_01J0000000000000000000000B", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "operations": [ + { + "operation_type": "insert", + "source_range": null, + "destination_position": 0, + "inserted_text_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "result_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "result_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + } + }, + { + "description": "edit-transaction.result_sha256: reject missing required property", + "instance": { + "schema_version": "1.0", + "transaction_id": "transaction_01J0000000000000000000000N", + "project_id": "project_01J00000000000000000000001", + "base_revision_id": "revision_01J0000000000000000000000A", + "result_revision_id": "revision_01J0000000000000000000000B", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "operations": [ + { + "operation_type": "insert", + "source_range": null, + "destination_position": 0, + "inserted_text_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "result_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "preimage_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd" + } + }, + { + "description": "edit-transaction: reject unexpected property", + "instance": { + "schema_version": "1.0", + "transaction_id": "transaction_01J0000000000000000000000N", + "project_id": "project_01J00000000000000000000001", + "base_revision_id": "revision_01J0000000000000000000000A", + "result_revision_id": "revision_01J0000000000000000000000B", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "operations": [ + { + "operation_type": "insert", + "source_range": null, + "destination_position": 0, + "inserted_text_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "result_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "preimage_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "result_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "__unexpected": true + } + }, + { + "description": "edit-transaction.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "transaction_id": "transaction_01J0000000000000000000000N", + "project_id": "project_01J00000000000000000000001", + "base_revision_id": "revision_01J0000000000000000000000A", + "result_revision_id": "revision_01J0000000000000000000000B", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "operations": [ + { + "operation_type": "insert", + "source_range": null, + "destination_position": 0, + "inserted_text_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "result_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "preimage_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "result_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + } + }, + { + "description": "edit-transaction.transaction_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "transaction_id": "invalid-id", + "project_id": "project_01J00000000000000000000001", + "base_revision_id": "revision_01J0000000000000000000000A", + "result_revision_id": "revision_01J0000000000000000000000B", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "operations": [ + { + "operation_type": "insert", + "source_range": null, + "destination_position": 0, + "inserted_text_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "result_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "preimage_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "result_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + } + }, + { + "description": "edit-transaction.project_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "transaction_id": "transaction_01J0000000000000000000000N", + "project_id": "invalid-id", + "base_revision_id": "revision_01J0000000000000000000000A", + "result_revision_id": "revision_01J0000000000000000000000B", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "operations": [ + { + "operation_type": "insert", + "source_range": null, + "destination_position": 0, + "inserted_text_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "result_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "preimage_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "result_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + } + }, + { + "description": "edit-transaction.base_revision_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "transaction_id": "transaction_01J0000000000000000000000N", + "project_id": "project_01J00000000000000000000001", + "base_revision_id": "invalid-id", + "result_revision_id": "revision_01J0000000000000000000000B", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "operations": [ + { + "operation_type": "insert", + "source_range": null, + "destination_position": 0, + "inserted_text_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "result_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "preimage_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "result_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + } + }, + { + "description": "edit-transaction.result_revision_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "transaction_id": "transaction_01J0000000000000000000000N", + "project_id": "project_01J00000000000000000000001", + "base_revision_id": "revision_01J0000000000000000000000A", + "result_revision_id": "invalid-id", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "operations": [ + { + "operation_type": "insert", + "source_range": null, + "destination_position": 0, + "inserted_text_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "result_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "preimage_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "result_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + } + }, + { + "description": "edit-transaction.started_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "transaction_id": "transaction_01J0000000000000000000000N", + "project_id": "project_01J00000000000000000000001", + "base_revision_id": "revision_01J0000000000000000000000A", + "result_revision_id": "revision_01J0000000000000000000000B", + "started_at": "not-a-timestamp", + "ended_at": "2026-07-17T18:43:11.456Z", + "operations": [ + { + "operation_type": "insert", + "source_range": null, + "destination_position": 0, + "inserted_text_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "result_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "preimage_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "result_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + } + }, + { + "description": "edit-transaction.ended_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "transaction_id": "transaction_01J0000000000000000000000N", + "project_id": "project_01J00000000000000000000001", + "base_revision_id": "revision_01J0000000000000000000000A", + "result_revision_id": "revision_01J0000000000000000000000B", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "not-a-timestamp", + "operations": [ + { + "operation_type": "insert", + "source_range": null, + "destination_position": 0, + "inserted_text_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "result_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "preimage_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "result_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + } + }, + { + "description": "edit-transaction.operations: reject array below minItems", + "instance": { + "schema_version": "1.0", + "transaction_id": "transaction_01J0000000000000000000000N", + "project_id": "project_01J00000000000000000000001", + "base_revision_id": "revision_01J0000000000000000000000A", + "result_revision_id": "revision_01J0000000000000000000000B", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "operations": [], + "preimage_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "result_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + } + }, + { + "description": "edit-transaction.operations[0].operation_type: reject missing required property", + "instance": { + "schema_version": "1.0", + "transaction_id": "transaction_01J0000000000000000000000N", + "project_id": "project_01J00000000000000000000001", + "base_revision_id": "revision_01J0000000000000000000000A", + "result_revision_id": "revision_01J0000000000000000000000B", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "operations": [ + { + "source_range": null, + "destination_position": 0, + "inserted_text_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "result_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "preimage_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "result_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + } + }, + { + "description": "edit-transaction.operations[0].source_range: reject missing required property", + "instance": { + "schema_version": "1.0", + "transaction_id": "transaction_01J0000000000000000000000N", + "project_id": "project_01J00000000000000000000001", + "base_revision_id": "revision_01J0000000000000000000000A", + "result_revision_id": "revision_01J0000000000000000000000B", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "operations": [ + { + "operation_type": "insert", + "destination_position": 0, + "inserted_text_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "result_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "preimage_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "result_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + } + }, + { + "description": "edit-transaction.operations[0].destination_position: reject missing required property", + "instance": { + "schema_version": "1.0", + "transaction_id": "transaction_01J0000000000000000000000N", + "project_id": "project_01J00000000000000000000001", + "base_revision_id": "revision_01J0000000000000000000000A", + "result_revision_id": "revision_01J0000000000000000000000B", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "operations": [ + { + "operation_type": "insert", + "source_range": null, + "inserted_text_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "result_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "preimage_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "result_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + } + }, + { + "description": "edit-transaction.operations[0].inserted_text_sha256: reject missing required property", + "instance": { + "schema_version": "1.0", + "transaction_id": "transaction_01J0000000000000000000000N", + "project_id": "project_01J00000000000000000000001", + "base_revision_id": "revision_01J0000000000000000000000A", + "result_revision_id": "revision_01J0000000000000000000000B", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "operations": [ + { + "operation_type": "insert", + "source_range": null, + "destination_position": 0, + "result_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "preimage_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "result_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + } + }, + { + "description": "edit-transaction.operations[0].result_fragment_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "transaction_id": "transaction_01J0000000000000000000000N", + "project_id": "project_01J00000000000000000000001", + "base_revision_id": "revision_01J0000000000000000000000A", + "result_revision_id": "revision_01J0000000000000000000000B", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "operations": [ + { + "operation_type": "insert", + "source_range": null, + "destination_position": 0, + "inserted_text_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + } + ], + "preimage_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "result_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + } + }, + { + "description": "edit-transaction.operations[0]: reject unexpected property", + "instance": { + "schema_version": "1.0", + "transaction_id": "transaction_01J0000000000000000000000N", + "project_id": "project_01J00000000000000000000001", + "base_revision_id": "revision_01J0000000000000000000000A", + "result_revision_id": "revision_01J0000000000000000000000B", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "operations": [ + { + "operation_type": "insert", + "source_range": null, + "destination_position": 0, + "inserted_text_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "result_fragment_id": "fragment_01J0000000000000000000000C", + "__unexpected": true + } + ], + "preimage_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "result_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + } + }, + { + "description": "edit-transaction.operations[0].operation_type: reject value outside enum", + "instance": { + "schema_version": "1.0", + "transaction_id": "transaction_01J0000000000000000000000N", + "project_id": "project_01J00000000000000000000001", + "base_revision_id": "revision_01J0000000000000000000000A", + "result_revision_id": "revision_01J0000000000000000000000B", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "operations": [ + { + "operation_type": "__INVALID_ENUM__", + "source_range": null, + "destination_position": 0, + "inserted_text_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "result_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "preimage_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "result_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + } + }, + { + "description": "edit-transaction.operations[0].destination_position: reject value below minimum", + "instance": { + "schema_version": "1.0", + "transaction_id": "transaction_01J0000000000000000000000N", + "project_id": "project_01J00000000000000000000001", + "base_revision_id": "revision_01J0000000000000000000000A", + "result_revision_id": "revision_01J0000000000000000000000B", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "operations": [ + { + "operation_type": "insert", + "source_range": null, + "destination_position": -1, + "inserted_text_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "result_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "preimage_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "result_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + } + }, + { + "description": "edit-transaction.operations[0].inserted_text_sha256: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "transaction_id": "transaction_01J0000000000000000000000N", + "project_id": "project_01J00000000000000000000001", + "base_revision_id": "revision_01J0000000000000000000000A", + "result_revision_id": "revision_01J0000000000000000000000B", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "operations": [ + { + "operation_type": "insert", + "source_range": null, + "destination_position": 0, + "inserted_text_sha256": "sha256:INVALID", + "result_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "preimage_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "result_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + } + }, + { + "description": "edit-transaction.operations[0].result_fragment_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "transaction_id": "transaction_01J0000000000000000000000N", + "project_id": "project_01J00000000000000000000001", + "base_revision_id": "revision_01J0000000000000000000000A", + "result_revision_id": "revision_01J0000000000000000000000B", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "operations": [ + { + "operation_type": "insert", + "source_range": null, + "destination_position": 0, + "inserted_text_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "result_fragment_id": "invalid-id" + } + ], + "preimage_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "result_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + } + }, + { + "description": "edit-transaction.preimage_sha256: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "transaction_id": "transaction_01J0000000000000000000000N", + "project_id": "project_01J00000000000000000000001", + "base_revision_id": "revision_01J0000000000000000000000A", + "result_revision_id": "revision_01J0000000000000000000000B", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "operations": [ + { + "operation_type": "insert", + "source_range": null, + "destination_position": 0, + "inserted_text_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "result_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "preimage_sha256": "sha256:INVALID", + "result_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + } + }, + { + "description": "edit-transaction.result_sha256: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "transaction_id": "transaction_01J0000000000000000000000N", + "project_id": "project_01J00000000000000000000001", + "base_revision_id": "revision_01J0000000000000000000000A", + "result_revision_id": "revision_01J0000000000000000000000B", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "operations": [ + { + "operation_type": "insert", + "source_range": null, + "destination_position": 0, + "inserted_text_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "result_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "preimage_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "result_sha256": "sha256:INVALID" + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/encrypted-key-envelope.invalid.json b/schemas/provenance/v1/fixtures/invalid/encrypted-key-envelope.invalid.json new file mode 100644 index 0000000..dc484f4 --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/encrypted-key-envelope.invalid.json @@ -0,0 +1,296 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/encrypted-key-envelope.schema.json", + "cases": [ + { + "description": "encrypted-key-envelope.schema_version: reject missing required property", + "instance": { + "envelope_id": "record_01J00000000000000000000005", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "device", + "algorithm": "xchacha20-poly1305", + "key_derivation": null, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "encrypted-key-envelope.envelope_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "device", + "algorithm": "xchacha20-poly1305", + "key_derivation": null, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "encrypted-key-envelope.key_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J00000000000000000000005", + "envelope_type": "device", + "algorithm": "xchacha20-poly1305", + "key_derivation": null, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "encrypted-key-envelope.envelope_type: reject missing required property", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J00000000000000000000005", + "key_id": "key_01J0000000000000000000000G", + "algorithm": "xchacha20-poly1305", + "key_derivation": null, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "encrypted-key-envelope.algorithm: reject missing required property", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J00000000000000000000005", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "device", + "key_derivation": null, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "encrypted-key-envelope.key_derivation: reject missing required property", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J00000000000000000000005", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "device", + "algorithm": "xchacha20-poly1305", + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "encrypted-key-envelope.nonce: reject missing required property", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J00000000000000000000005", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "device", + "algorithm": "xchacha20-poly1305", + "key_derivation": null, + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "encrypted-key-envelope.wrapped_key: reject missing required property", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J00000000000000000000005", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "device", + "algorithm": "xchacha20-poly1305", + "key_derivation": null, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "encrypted-key-envelope.ciphertext_sha256: reject missing required property", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J00000000000000000000005", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "device", + "algorithm": "xchacha20-poly1305", + "key_derivation": null, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "encrypted-key-envelope.created_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J00000000000000000000005", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "device", + "algorithm": "xchacha20-poly1305", + "key_derivation": null, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + } + }, + { + "description": "encrypted-key-envelope: reject unexpected property", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J00000000000000000000005", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "device", + "algorithm": "xchacha20-poly1305", + "key_derivation": null, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z", + "__unexpected": true + } + }, + { + "description": "encrypted-key-envelope.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "envelope_id": "record_01J00000000000000000000005", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "device", + "algorithm": "xchacha20-poly1305", + "key_derivation": null, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "encrypted-key-envelope.envelope_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "envelope_id": "invalid-id", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "device", + "algorithm": "xchacha20-poly1305", + "key_derivation": null, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "encrypted-key-envelope.key_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J00000000000000000000005", + "key_id": "invalid-id", + "envelope_type": "device", + "algorithm": "xchacha20-poly1305", + "key_derivation": null, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "encrypted-key-envelope.envelope_type: reject value outside enum", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J00000000000000000000005", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "__INVALID_ENUM__", + "algorithm": "xchacha20-poly1305", + "key_derivation": null, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "encrypted-key-envelope.algorithm: reject value outside enum", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J00000000000000000000005", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "device", + "algorithm": "__INVALID_ENUM__", + "key_derivation": null, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "encrypted-key-envelope.nonce: reject string below minLength", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J00000000000000000000005", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "device", + "algorithm": "xchacha20-poly1305", + "key_derivation": null, + "nonce": "", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "encrypted-key-envelope.wrapped_key: reject string below minLength", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J00000000000000000000005", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "device", + "algorithm": "xchacha20-poly1305", + "key_derivation": null, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "encrypted-key-envelope.ciphertext_sha256: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J00000000000000000000005", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "device", + "algorithm": "xchacha20-poly1305", + "key_derivation": null, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:INVALID", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "encrypted-key-envelope.created_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J00000000000000000000005", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "device", + "algorithm": "xchacha20-poly1305", + "key_derivation": null, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "not-a-timestamp" + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/idea-revision.invalid.json b/schemas/provenance/v1/fixtures/invalid/idea-revision.invalid.json new file mode 100644 index 0000000..0fe4b32 --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/idea-revision.invalid.json @@ -0,0 +1,539 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/idea-revision.schema.json", + "cases": [ + { + "description": "idea-revision.schema_version: reject missing required property", + "instance": { + "revision_id": "revision_01J0000000000000000000000A", + "idea_id": "idea_01J00000000000000000000009", + "revision_number": 1, + "title": "Attention as civic infrastructure", + "summary": "Institutions influence shared attention.", + "detail": "Treat attention as a public condition.", + "tags": [ + "thesis" + ], + "source_turn_ids": [ + "turn_01J00000000000000000000007" + ], + "parent_idea_ids": [], + "created_by": "mixed", + "created_at": "2026-07-17T18:42:10.123Z", + "content_sha256": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + } + }, + { + "description": "idea-revision.revision_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "idea_id": "idea_01J00000000000000000000009", + "revision_number": 1, + "title": "Attention as civic infrastructure", + "summary": "Institutions influence shared attention.", + "detail": "Treat attention as a public condition.", + "tags": [ + "thesis" + ], + "source_turn_ids": [ + "turn_01J00000000000000000000007" + ], + "parent_idea_ids": [], + "created_by": "mixed", + "created_at": "2026-07-17T18:42:10.123Z", + "content_sha256": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + } + }, + { + "description": "idea-revision.idea_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "revision_number": 1, + "title": "Attention as civic infrastructure", + "summary": "Institutions influence shared attention.", + "detail": "Treat attention as a public condition.", + "tags": [ + "thesis" + ], + "source_turn_ids": [ + "turn_01J00000000000000000000007" + ], + "parent_idea_ids": [], + "created_by": "mixed", + "created_at": "2026-07-17T18:42:10.123Z", + "content_sha256": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + } + }, + { + "description": "idea-revision.revision_number: reject missing required property", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "idea_id": "idea_01J00000000000000000000009", + "title": "Attention as civic infrastructure", + "summary": "Institutions influence shared attention.", + "detail": "Treat attention as a public condition.", + "tags": [ + "thesis" + ], + "source_turn_ids": [ + "turn_01J00000000000000000000007" + ], + "parent_idea_ids": [], + "created_by": "mixed", + "created_at": "2026-07-17T18:42:10.123Z", + "content_sha256": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + } + }, + { + "description": "idea-revision.title: reject missing required property", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "idea_id": "idea_01J00000000000000000000009", + "revision_number": 1, + "summary": "Institutions influence shared attention.", + "detail": "Treat attention as a public condition.", + "tags": [ + "thesis" + ], + "source_turn_ids": [ + "turn_01J00000000000000000000007" + ], + "parent_idea_ids": [], + "created_by": "mixed", + "created_at": "2026-07-17T18:42:10.123Z", + "content_sha256": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + } + }, + { + "description": "idea-revision.summary: reject missing required property", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "idea_id": "idea_01J00000000000000000000009", + "revision_number": 1, + "title": "Attention as civic infrastructure", + "detail": "Treat attention as a public condition.", + "tags": [ + "thesis" + ], + "source_turn_ids": [ + "turn_01J00000000000000000000007" + ], + "parent_idea_ids": [], + "created_by": "mixed", + "created_at": "2026-07-17T18:42:10.123Z", + "content_sha256": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + } + }, + { + "description": "idea-revision.detail: reject missing required property", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "idea_id": "idea_01J00000000000000000000009", + "revision_number": 1, + "title": "Attention as civic infrastructure", + "summary": "Institutions influence shared attention.", + "tags": [ + "thesis" + ], + "source_turn_ids": [ + "turn_01J00000000000000000000007" + ], + "parent_idea_ids": [], + "created_by": "mixed", + "created_at": "2026-07-17T18:42:10.123Z", + "content_sha256": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + } + }, + { + "description": "idea-revision.tags: reject missing required property", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "idea_id": "idea_01J00000000000000000000009", + "revision_number": 1, + "title": "Attention as civic infrastructure", + "summary": "Institutions influence shared attention.", + "detail": "Treat attention as a public condition.", + "source_turn_ids": [ + "turn_01J00000000000000000000007" + ], + "parent_idea_ids": [], + "created_by": "mixed", + "created_at": "2026-07-17T18:42:10.123Z", + "content_sha256": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + } + }, + { + "description": "idea-revision.source_turn_ids: reject missing required property", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "idea_id": "idea_01J00000000000000000000009", + "revision_number": 1, + "title": "Attention as civic infrastructure", + "summary": "Institutions influence shared attention.", + "detail": "Treat attention as a public condition.", + "tags": [ + "thesis" + ], + "parent_idea_ids": [], + "created_by": "mixed", + "created_at": "2026-07-17T18:42:10.123Z", + "content_sha256": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + } + }, + { + "description": "idea-revision.parent_idea_ids: reject missing required property", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "idea_id": "idea_01J00000000000000000000009", + "revision_number": 1, + "title": "Attention as civic infrastructure", + "summary": "Institutions influence shared attention.", + "detail": "Treat attention as a public condition.", + "tags": [ + "thesis" + ], + "source_turn_ids": [ + "turn_01J00000000000000000000007" + ], + "created_by": "mixed", + "created_at": "2026-07-17T18:42:10.123Z", + "content_sha256": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + } + }, + { + "description": "idea-revision.created_by: reject missing required property", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "idea_id": "idea_01J00000000000000000000009", + "revision_number": 1, + "title": "Attention as civic infrastructure", + "summary": "Institutions influence shared attention.", + "detail": "Treat attention as a public condition.", + "tags": [ + "thesis" + ], + "source_turn_ids": [ + "turn_01J00000000000000000000007" + ], + "parent_idea_ids": [], + "created_at": "2026-07-17T18:42:10.123Z", + "content_sha256": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + } + }, + { + "description": "idea-revision.created_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "idea_id": "idea_01J00000000000000000000009", + "revision_number": 1, + "title": "Attention as civic infrastructure", + "summary": "Institutions influence shared attention.", + "detail": "Treat attention as a public condition.", + "tags": [ + "thesis" + ], + "source_turn_ids": [ + "turn_01J00000000000000000000007" + ], + "parent_idea_ids": [], + "created_by": "mixed", + "content_sha256": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + } + }, + { + "description": "idea-revision.content_sha256: reject missing required property", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "idea_id": "idea_01J00000000000000000000009", + "revision_number": 1, + "title": "Attention as civic infrastructure", + "summary": "Institutions influence shared attention.", + "detail": "Treat attention as a public condition.", + "tags": [ + "thesis" + ], + "source_turn_ids": [ + "turn_01J00000000000000000000007" + ], + "parent_idea_ids": [], + "created_by": "mixed", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "idea-revision: reject unexpected property", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "idea_id": "idea_01J00000000000000000000009", + "revision_number": 1, + "title": "Attention as civic infrastructure", + "summary": "Institutions influence shared attention.", + "detail": "Treat attention as a public condition.", + "tags": [ + "thesis" + ], + "source_turn_ids": [ + "turn_01J00000000000000000000007" + ], + "parent_idea_ids": [], + "created_by": "mixed", + "created_at": "2026-07-17T18:42:10.123Z", + "content_sha256": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "__unexpected": true + } + }, + { + "description": "idea-revision.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "revision_id": "revision_01J0000000000000000000000A", + "idea_id": "idea_01J00000000000000000000009", + "revision_number": 1, + "title": "Attention as civic infrastructure", + "summary": "Institutions influence shared attention.", + "detail": "Treat attention as a public condition.", + "tags": [ + "thesis" + ], + "source_turn_ids": [ + "turn_01J00000000000000000000007" + ], + "parent_idea_ids": [], + "created_by": "mixed", + "created_at": "2026-07-17T18:42:10.123Z", + "content_sha256": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + } + }, + { + "description": "idea-revision.revision_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "revision_id": "invalid-id", + "idea_id": "idea_01J00000000000000000000009", + "revision_number": 1, + "title": "Attention as civic infrastructure", + "summary": "Institutions influence shared attention.", + "detail": "Treat attention as a public condition.", + "tags": [ + "thesis" + ], + "source_turn_ids": [ + "turn_01J00000000000000000000007" + ], + "parent_idea_ids": [], + "created_by": "mixed", + "created_at": "2026-07-17T18:42:10.123Z", + "content_sha256": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + } + }, + { + "description": "idea-revision.idea_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "idea_id": "invalid-id", + "revision_number": 1, + "title": "Attention as civic infrastructure", + "summary": "Institutions influence shared attention.", + "detail": "Treat attention as a public condition.", + "tags": [ + "thesis" + ], + "source_turn_ids": [ + "turn_01J00000000000000000000007" + ], + "parent_idea_ids": [], + "created_by": "mixed", + "created_at": "2026-07-17T18:42:10.123Z", + "content_sha256": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + } + }, + { + "description": "idea-revision.revision_number: reject value below minimum", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "idea_id": "idea_01J00000000000000000000009", + "revision_number": 0, + "title": "Attention as civic infrastructure", + "summary": "Institutions influence shared attention.", + "detail": "Treat attention as a public condition.", + "tags": [ + "thesis" + ], + "source_turn_ids": [ + "turn_01J00000000000000000000007" + ], + "parent_idea_ids": [], + "created_by": "mixed", + "created_at": "2026-07-17T18:42:10.123Z", + "content_sha256": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + } + }, + { + "description": "idea-revision.title: reject string below minLength", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "idea_id": "idea_01J00000000000000000000009", + "revision_number": 1, + "title": "", + "summary": "Institutions influence shared attention.", + "detail": "Treat attention as a public condition.", + "tags": [ + "thesis" + ], + "source_turn_ids": [ + "turn_01J00000000000000000000007" + ], + "parent_idea_ids": [], + "created_by": "mixed", + "created_at": "2026-07-17T18:42:10.123Z", + "content_sha256": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + } + }, + { + "description": "idea-revision.summary: reject string below minLength", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "idea_id": "idea_01J00000000000000000000009", + "revision_number": 1, + "title": "Attention as civic infrastructure", + "summary": "", + "detail": "Treat attention as a public condition.", + "tags": [ + "thesis" + ], + "source_turn_ids": [ + "turn_01J00000000000000000000007" + ], + "parent_idea_ids": [], + "created_by": "mixed", + "created_at": "2026-07-17T18:42:10.123Z", + "content_sha256": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + } + }, + { + "description": "idea-revision.tags[0]: reject string below minLength", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "idea_id": "idea_01J00000000000000000000009", + "revision_number": 1, + "title": "Attention as civic infrastructure", + "summary": "Institutions influence shared attention.", + "detail": "Treat attention as a public condition.", + "tags": [ + "" + ], + "source_turn_ids": [ + "turn_01J00000000000000000000007" + ], + "parent_idea_ids": [], + "created_by": "mixed", + "created_at": "2026-07-17T18:42:10.123Z", + "content_sha256": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + } + }, + { + "description": "idea-revision.source_turn_ids[0]: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "idea_id": "idea_01J00000000000000000000009", + "revision_number": 1, + "title": "Attention as civic infrastructure", + "summary": "Institutions influence shared attention.", + "detail": "Treat attention as a public condition.", + "tags": [ + "thesis" + ], + "source_turn_ids": [ + "invalid-id" + ], + "parent_idea_ids": [], + "created_by": "mixed", + "created_at": "2026-07-17T18:42:10.123Z", + "content_sha256": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + } + }, + { + "description": "idea-revision.created_by: reject value outside enum", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "idea_id": "idea_01J00000000000000000000009", + "revision_number": 1, + "title": "Attention as civic infrastructure", + "summary": "Institutions influence shared attention.", + "detail": "Treat attention as a public condition.", + "tags": [ + "thesis" + ], + "source_turn_ids": [ + "turn_01J00000000000000000000007" + ], + "parent_idea_ids": [], + "created_by": "__INVALID_ENUM__", + "created_at": "2026-07-17T18:42:10.123Z", + "content_sha256": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + } + }, + { + "description": "idea-revision.created_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "idea_id": "idea_01J00000000000000000000009", + "revision_number": 1, + "title": "Attention as civic infrastructure", + "summary": "Institutions influence shared attention.", + "detail": "Treat attention as a public condition.", + "tags": [ + "thesis" + ], + "source_turn_ids": [ + "turn_01J00000000000000000000007" + ], + "parent_idea_ids": [], + "created_by": "mixed", + "created_at": "not-a-timestamp", + "content_sha256": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + } + }, + { + "description": "idea-revision.content_sha256: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "idea_id": "idea_01J00000000000000000000009", + "revision_number": 1, + "title": "Attention as civic infrastructure", + "summary": "Institutions influence shared attention.", + "detail": "Treat attention as a public condition.", + "tags": [ + "thesis" + ], + "source_turn_ids": [ + "turn_01J00000000000000000000007" + ], + "parent_idea_ids": [], + "created_by": "mixed", + "created_at": "2026-07-17T18:42:10.123Z", + "content_sha256": "sha256:INVALID" + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/idea.invalid.json b/schemas/provenance/v1/fixtures/invalid/idea.invalid.json new file mode 100644 index 0000000..cad3932 --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/idea.invalid.json @@ -0,0 +1,179 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/idea.schema.json", + "cases": [ + { + "description": "idea.schema_version: reject missing required property", + "instance": { + "idea_id": "idea_01J00000000000000000000009", + "project_id": "project_01J00000000000000000000001", + "current_revision_id": "revision_01J0000000000000000000000A", + "status": "accepted", + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "idea.idea_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "current_revision_id": "revision_01J0000000000000000000000A", + "status": "accepted", + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "idea.project_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "idea_id": "idea_01J00000000000000000000009", + "current_revision_id": "revision_01J0000000000000000000000A", + "status": "accepted", + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "idea.current_revision_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "idea_id": "idea_01J00000000000000000000009", + "project_id": "project_01J00000000000000000000001", + "status": "accepted", + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "idea.status: reject missing required property", + "instance": { + "schema_version": "1.0", + "idea_id": "idea_01J00000000000000000000009", + "project_id": "project_01J00000000000000000000001", + "current_revision_id": "revision_01J0000000000000000000000A", + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "idea.created_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "idea_id": "idea_01J00000000000000000000009", + "project_id": "project_01J00000000000000000000001", + "current_revision_id": "revision_01J0000000000000000000000A", + "status": "accepted", + "updated_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "idea.updated_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "idea_id": "idea_01J00000000000000000000009", + "project_id": "project_01J00000000000000000000001", + "current_revision_id": "revision_01J0000000000000000000000A", + "status": "accepted", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "idea: reject unexpected property", + "instance": { + "schema_version": "1.0", + "idea_id": "idea_01J00000000000000000000009", + "project_id": "project_01J00000000000000000000001", + "current_revision_id": "revision_01J0000000000000000000000A", + "status": "accepted", + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z", + "__unexpected": true + } + }, + { + "description": "idea.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "idea_id": "idea_01J00000000000000000000009", + "project_id": "project_01J00000000000000000000001", + "current_revision_id": "revision_01J0000000000000000000000A", + "status": "accepted", + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "idea.idea_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "idea_id": "invalid-id", + "project_id": "project_01J00000000000000000000001", + "current_revision_id": "revision_01J0000000000000000000000A", + "status": "accepted", + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "idea.project_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "idea_id": "idea_01J00000000000000000000009", + "project_id": "invalid-id", + "current_revision_id": "revision_01J0000000000000000000000A", + "status": "accepted", + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "idea.current_revision_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "idea_id": "idea_01J00000000000000000000009", + "project_id": "project_01J00000000000000000000001", + "current_revision_id": "invalid-id", + "status": "accepted", + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "idea.status: reject value outside enum", + "instance": { + "schema_version": "1.0", + "idea_id": "idea_01J00000000000000000000009", + "project_id": "project_01J00000000000000000000001", + "current_revision_id": "revision_01J0000000000000000000000A", + "status": "__INVALID_ENUM__", + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "idea.created_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "idea_id": "idea_01J00000000000000000000009", + "project_id": "project_01J00000000000000000000001", + "current_revision_id": "revision_01J0000000000000000000000A", + "status": "accepted", + "created_at": "not-a-timestamp", + "updated_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "idea.updated_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "idea_id": "idea_01J00000000000000000000009", + "project_id": "project_01J00000000000000000000001", + "current_revision_id": "revision_01J0000000000000000000000A", + "status": "accepted", + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "not-a-timestamp" + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/invocation-failure.invalid.json b/schemas/provenance/v1/fixtures/invalid/invocation-failure.invalid.json new file mode 100644 index 0000000..ae4cdce --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/invocation-failure.invalid.json @@ -0,0 +1,249 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/invocation-failure.schema.json", + "cases": [ + { + "description": "invocation-failure.schema_version: reject missing required property", + "instance": { + "failure_id": "failure_01J0000000000000000000000P", + "invocation_id": "invocation_01J00000000000000000000008", + "code": "PROVIDER_TIMEOUT", + "category": "provider", + "recoverable": true, + "bounded_summary": "The provider did not respond within the configured timeout.", + "partial_output_preserved": false, + "occurred_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-failure.failure_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "code": "PROVIDER_TIMEOUT", + "category": "provider", + "recoverable": true, + "bounded_summary": "The provider did not respond within the configured timeout.", + "partial_output_preserved": false, + "occurred_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-failure.invocation_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "failure_id": "failure_01J0000000000000000000000P", + "code": "PROVIDER_TIMEOUT", + "category": "provider", + "recoverable": true, + "bounded_summary": "The provider did not respond within the configured timeout.", + "partial_output_preserved": false, + "occurred_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-failure.code: reject missing required property", + "instance": { + "schema_version": "1.0", + "failure_id": "failure_01J0000000000000000000000P", + "invocation_id": "invocation_01J00000000000000000000008", + "category": "provider", + "recoverable": true, + "bounded_summary": "The provider did not respond within the configured timeout.", + "partial_output_preserved": false, + "occurred_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-failure.category: reject missing required property", + "instance": { + "schema_version": "1.0", + "failure_id": "failure_01J0000000000000000000000P", + "invocation_id": "invocation_01J00000000000000000000008", + "code": "PROVIDER_TIMEOUT", + "recoverable": true, + "bounded_summary": "The provider did not respond within the configured timeout.", + "partial_output_preserved": false, + "occurred_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-failure.recoverable: reject missing required property", + "instance": { + "schema_version": "1.0", + "failure_id": "failure_01J0000000000000000000000P", + "invocation_id": "invocation_01J00000000000000000000008", + "code": "PROVIDER_TIMEOUT", + "category": "provider", + "bounded_summary": "The provider did not respond within the configured timeout.", + "partial_output_preserved": false, + "occurred_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-failure.bounded_summary: reject missing required property", + "instance": { + "schema_version": "1.0", + "failure_id": "failure_01J0000000000000000000000P", + "invocation_id": "invocation_01J00000000000000000000008", + "code": "PROVIDER_TIMEOUT", + "category": "provider", + "recoverable": true, + "partial_output_preserved": false, + "occurred_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-failure.partial_output_preserved: reject missing required property", + "instance": { + "schema_version": "1.0", + "failure_id": "failure_01J0000000000000000000000P", + "invocation_id": "invocation_01J00000000000000000000008", + "code": "PROVIDER_TIMEOUT", + "category": "provider", + "recoverable": true, + "bounded_summary": "The provider did not respond within the configured timeout.", + "occurred_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-failure.occurred_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "failure_id": "failure_01J0000000000000000000000P", + "invocation_id": "invocation_01J00000000000000000000008", + "code": "PROVIDER_TIMEOUT", + "category": "provider", + "recoverable": true, + "bounded_summary": "The provider did not respond within the configured timeout.", + "partial_output_preserved": false + } + }, + { + "description": "invocation-failure: reject unexpected property", + "instance": { + "schema_version": "1.0", + "failure_id": "failure_01J0000000000000000000000P", + "invocation_id": "invocation_01J00000000000000000000008", + "code": "PROVIDER_TIMEOUT", + "category": "provider", + "recoverable": true, + "bounded_summary": "The provider did not respond within the configured timeout.", + "partial_output_preserved": false, + "occurred_at": "2026-07-17T18:43:11.456Z", + "__unexpected": true + } + }, + { + "description": "invocation-failure.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "failure_id": "failure_01J0000000000000000000000P", + "invocation_id": "invocation_01J00000000000000000000008", + "code": "PROVIDER_TIMEOUT", + "category": "provider", + "recoverable": true, + "bounded_summary": "The provider did not respond within the configured timeout.", + "partial_output_preserved": false, + "occurred_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-failure.failure_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "failure_id": "invalid-id", + "invocation_id": "invocation_01J00000000000000000000008", + "code": "PROVIDER_TIMEOUT", + "category": "provider", + "recoverable": true, + "bounded_summary": "The provider did not respond within the configured timeout.", + "partial_output_preserved": false, + "occurred_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-failure.invocation_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "failure_id": "failure_01J0000000000000000000000P", + "invocation_id": "invalid-id", + "code": "PROVIDER_TIMEOUT", + "category": "provider", + "recoverable": true, + "bounded_summary": "The provider did not respond within the configured timeout.", + "partial_output_preserved": false, + "occurred_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-failure.code: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "failure_id": "failure_01J0000000000000000000000P", + "invocation_id": "invocation_01J00000000000000000000008", + "code": " invalid!", + "category": "provider", + "recoverable": true, + "bounded_summary": "The provider did not respond within the configured timeout.", + "partial_output_preserved": false, + "occurred_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-failure.category: reject value outside enum", + "instance": { + "schema_version": "1.0", + "failure_id": "failure_01J0000000000000000000000P", + "invocation_id": "invocation_01J00000000000000000000008", + "code": "PROVIDER_TIMEOUT", + "category": "__INVALID_ENUM__", + "recoverable": true, + "bounded_summary": "The provider did not respond within the configured timeout.", + "partial_output_preserved": false, + "occurred_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-failure.bounded_summary: reject string below minLength", + "instance": { + "schema_version": "1.0", + "failure_id": "failure_01J0000000000000000000000P", + "invocation_id": "invocation_01J00000000000000000000008", + "code": "PROVIDER_TIMEOUT", + "category": "provider", + "recoverable": true, + "bounded_summary": "", + "partial_output_preserved": false, + "occurred_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-failure.bounded_summary: reject string above maxLength", + "instance": { + "schema_version": "1.0", + "failure_id": "failure_01J0000000000000000000000P", + "invocation_id": "invocation_01J00000000000000000000008", + "code": "PROVIDER_TIMEOUT", + "category": "provider", + "recoverable": true, + "bounded_summary": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "partial_output_preserved": false, + "occurred_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-failure.occurred_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "failure_id": "failure_01J0000000000000000000000P", + "invocation_id": "invocation_01J00000000000000000000008", + "code": "PROVIDER_TIMEOUT", + "category": "provider", + "recoverable": true, + "bounded_summary": "The provider did not respond within the configured timeout.", + "partial_output_preserved": false, + "occurred_at": "not-a-timestamp" + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/invocation-request.invalid.json b/schemas/provenance/v1/fixtures/invalid/invocation-request.invalid.json new file mode 100644 index 0000000..9b75b59 --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/invocation-request.invalid.json @@ -0,0 +1,5229 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/invocation-request.schema.json", + "cases": [ + { + "description": "invocation-request.schema_version: reject missing required property", + "instance": { + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.invocation_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.project_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.purpose: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.initiated_by_event_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.retention_mode: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.provider: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.model_configuration_sha256: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.prompt_template: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.messages: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.context_references: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.manuscript_revision_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.idea_revision_ids: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.conversation_head: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.submitted_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.redactions: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "invocation-request: reject unexpected property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ], + "__unexpected": true + } + }, + { + "description": "invocation-request.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.invocation_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "invocation_id": "invalid-id", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.project_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "invalid-id", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.purpose: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": " invalid!", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.initiated_by_event_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "invalid-id", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.retention_mode: reject value outside enum", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "__INVALID_ENUM__", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.provider.provider_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.provider.model_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.provider.processing_mode: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.provider: reject unexpected property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local", + "__unexpected": true + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.provider.provider_id: reject string below minLength", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.provider.model_id: reject string below minLength", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.provider.processing_mode: reject value outside enum", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "__INVALID_ENUM__" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.model_configuration_sha256: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:INVALID", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.prompt_template.schema_version: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.prompt_template.template_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.prompt_template.version: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.prompt_template.path: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.prompt_template.template_sha256: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.prompt_template: reject unexpected property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777", + "__unexpected": true + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.prompt_template.schema_version: reject value different from const", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "__INVALID_CONST__", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.prompt_template.template_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "invalid-id", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.prompt_template.version: reject value below minimum", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 0, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.prompt_template.path: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "../outside-project", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.prompt_template.path: reject string below minLength", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.prompt_template.template_sha256: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:INVALID" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.messages[0].role: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.messages[0].content: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user" + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.messages[0]: reject unexpected property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage.", + "__unexpected": true + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.messages[0].role: reject value outside enum", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "__INVALID_ENUM__", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.messages[0].content: reject string below minLength", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "" + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.context_references[0].schema_version: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.context_references[0].record_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.context_references[0].record_type: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.context_references[0].sha256: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.context_references[0].path: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.context_references[0].revision_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.context_references[0].range: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A" + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.context_references[0]: reject unexpected property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + }, + "__unexpected": true + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.context_references[0].schema_version: reject value different from const", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "__INVALID_CONST__", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.context_references[0].record_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "invalid-id", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.context_references[0].record_type: reject value outside enum", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "__INVALID_ENUM__", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.context_references[0].sha256: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:INVALID", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.context_references[0].path: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "../outside-project", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.context_references[0].path: reject string below minLength", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.context_references[0].revision_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "invalid-id", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.context_references[0].range.schema_version: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.context_references[0].range.document_revision_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.context_references[0].range.coordinate_system: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.context_references[0].range.start: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.context_references[0].range.end: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.context_references[0].range.preimage_sha256: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.context_references[0].range.text_fragment_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.context_references[0].range: reject unexpected property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C", + "__unexpected": true + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.context_references[0].range.schema_version: reject value different from const", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "__INVALID_CONST__", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.context_references[0].range.document_revision_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "invalid-id", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.context_references[0].range.coordinate_system: reject value outside enum", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "__INVALID_ENUM__", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.context_references[0].range.start: reject value below minimum", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": -1, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.context_references[0].range.end: reject value below minimum", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": -1, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.context_references[0].range.preimage_sha256: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:INVALID", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.context_references[0].range.text_fragment_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "invalid-id" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.manuscript_revision_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "invalid-id", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.idea_revision_ids[0]: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "invalid-id" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.conversation_head: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "invalid-id", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.submitted_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "not-a-timestamp", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.redactions[0].category: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.redactions[0].replacement: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier" + } + ] + } + }, + { + "description": "invocation-request.redactions[0]: reject unexpected property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]", + "__unexpected": true + } + ] + } + }, + { + "description": "invocation-request.redactions[0].category: reject value outside enum", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "__INVALID_ENUM__", + "replacement": "[redacted]" + } + ] + } + }, + { + "description": "invocation-request.redactions[0].replacement: reject string below minLength", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "" + } + ] + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/invocation-response.invalid.json b/schemas/provenance/v1/fixtures/invalid/invocation-response.invalid.json new file mode 100644 index 0000000..67ed59f --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/invocation-response.invalid.json @@ -0,0 +1,737 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/invocation-response.schema.json", + "cases": [ + { + "description": "invocation-response.schema_version: reject missing required property", + "instance": { + "record_id": "record_01J00000000000000000000005", + "invocation_id": "invocation_01J00000000000000000000008", + "retention_mode": "full_private", + "content_type": "draft_preview", + "retained_text": "Attention is personal in experience and public in consequence.", + "finish_reason": "stop", + "usage": { + "input_tokens": 120, + "output_tokens": 14 + }, + "provider_metadata": { + "request_id": "local-0001", + "load_duration_milliseconds": 120 + }, + "validation": { + "schema_valid": true, + "repair_attempted": false + }, + "content_sha256": "sha256:9999999999999999999999999999999999999999999999999999999999999999", + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-response.record_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "retention_mode": "full_private", + "content_type": "draft_preview", + "retained_text": "Attention is personal in experience and public in consequence.", + "finish_reason": "stop", + "usage": { + "input_tokens": 120, + "output_tokens": 14 + }, + "provider_metadata": { + "request_id": "local-0001", + "load_duration_milliseconds": 120 + }, + "validation": { + "schema_valid": true, + "repair_attempted": false + }, + "content_sha256": "sha256:9999999999999999999999999999999999999999999999999999999999999999", + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-response.invocation_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "retention_mode": "full_private", + "content_type": "draft_preview", + "retained_text": "Attention is personal in experience and public in consequence.", + "finish_reason": "stop", + "usage": { + "input_tokens": 120, + "output_tokens": 14 + }, + "provider_metadata": { + "request_id": "local-0001", + "load_duration_milliseconds": 120 + }, + "validation": { + "schema_valid": true, + "repair_attempted": false + }, + "content_sha256": "sha256:9999999999999999999999999999999999999999999999999999999999999999", + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-response.retention_mode: reject missing required property", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "invocation_id": "invocation_01J00000000000000000000008", + "content_type": "draft_preview", + "retained_text": "Attention is personal in experience and public in consequence.", + "finish_reason": "stop", + "usage": { + "input_tokens": 120, + "output_tokens": 14 + }, + "provider_metadata": { + "request_id": "local-0001", + "load_duration_milliseconds": 120 + }, + "validation": { + "schema_valid": true, + "repair_attempted": false + }, + "content_sha256": "sha256:9999999999999999999999999999999999999999999999999999999999999999", + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-response.content_type: reject missing required property", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "invocation_id": "invocation_01J00000000000000000000008", + "retention_mode": "full_private", + "retained_text": "Attention is personal in experience and public in consequence.", + "finish_reason": "stop", + "usage": { + "input_tokens": 120, + "output_tokens": 14 + }, + "provider_metadata": { + "request_id": "local-0001", + "load_duration_milliseconds": 120 + }, + "validation": { + "schema_valid": true, + "repair_attempted": false + }, + "content_sha256": "sha256:9999999999999999999999999999999999999999999999999999999999999999", + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-response.retained_text: reject missing required property", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "invocation_id": "invocation_01J00000000000000000000008", + "retention_mode": "full_private", + "content_type": "draft_preview", + "finish_reason": "stop", + "usage": { + "input_tokens": 120, + "output_tokens": 14 + }, + "provider_metadata": { + "request_id": "local-0001", + "load_duration_milliseconds": 120 + }, + "validation": { + "schema_valid": true, + "repair_attempted": false + }, + "content_sha256": "sha256:9999999999999999999999999999999999999999999999999999999999999999", + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-response.finish_reason: reject missing required property", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "invocation_id": "invocation_01J00000000000000000000008", + "retention_mode": "full_private", + "content_type": "draft_preview", + "retained_text": "Attention is personal in experience and public in consequence.", + "usage": { + "input_tokens": 120, + "output_tokens": 14 + }, + "provider_metadata": { + "request_id": "local-0001", + "load_duration_milliseconds": 120 + }, + "validation": { + "schema_valid": true, + "repair_attempted": false + }, + "content_sha256": "sha256:9999999999999999999999999999999999999999999999999999999999999999", + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-response.usage: reject missing required property", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "invocation_id": "invocation_01J00000000000000000000008", + "retention_mode": "full_private", + "content_type": "draft_preview", + "retained_text": "Attention is personal in experience and public in consequence.", + "finish_reason": "stop", + "provider_metadata": { + "request_id": "local-0001", + "load_duration_milliseconds": 120 + }, + "validation": { + "schema_valid": true, + "repair_attempted": false + }, + "content_sha256": "sha256:9999999999999999999999999999999999999999999999999999999999999999", + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-response.provider_metadata: reject missing required property", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "invocation_id": "invocation_01J00000000000000000000008", + "retention_mode": "full_private", + "content_type": "draft_preview", + "retained_text": "Attention is personal in experience and public in consequence.", + "finish_reason": "stop", + "usage": { + "input_tokens": 120, + "output_tokens": 14 + }, + "validation": { + "schema_valid": true, + "repair_attempted": false + }, + "content_sha256": "sha256:9999999999999999999999999999999999999999999999999999999999999999", + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-response.validation: reject missing required property", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "invocation_id": "invocation_01J00000000000000000000008", + "retention_mode": "full_private", + "content_type": "draft_preview", + "retained_text": "Attention is personal in experience and public in consequence.", + "finish_reason": "stop", + "usage": { + "input_tokens": 120, + "output_tokens": 14 + }, + "provider_metadata": { + "request_id": "local-0001", + "load_duration_milliseconds": 120 + }, + "content_sha256": "sha256:9999999999999999999999999999999999999999999999999999999999999999", + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-response.content_sha256: reject missing required property", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "invocation_id": "invocation_01J00000000000000000000008", + "retention_mode": "full_private", + "content_type": "draft_preview", + "retained_text": "Attention is personal in experience and public in consequence.", + "finish_reason": "stop", + "usage": { + "input_tokens": 120, + "output_tokens": 14 + }, + "provider_metadata": { + "request_id": "local-0001", + "load_duration_milliseconds": 120 + }, + "validation": { + "schema_valid": true, + "repair_attempted": false + }, + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-response.created_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "invocation_id": "invocation_01J00000000000000000000008", + "retention_mode": "full_private", + "content_type": "draft_preview", + "retained_text": "Attention is personal in experience and public in consequence.", + "finish_reason": "stop", + "usage": { + "input_tokens": 120, + "output_tokens": 14 + }, + "provider_metadata": { + "request_id": "local-0001", + "load_duration_milliseconds": 120 + }, + "validation": { + "schema_valid": true, + "repair_attempted": false + }, + "content_sha256": "sha256:9999999999999999999999999999999999999999999999999999999999999999" + } + }, + { + "description": "invocation-response: reject unexpected property", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "invocation_id": "invocation_01J00000000000000000000008", + "retention_mode": "full_private", + "content_type": "draft_preview", + "retained_text": "Attention is personal in experience and public in consequence.", + "finish_reason": "stop", + "usage": { + "input_tokens": 120, + "output_tokens": 14 + }, + "provider_metadata": { + "request_id": "local-0001", + "load_duration_milliseconds": 120 + }, + "validation": { + "schema_valid": true, + "repair_attempted": false + }, + "content_sha256": "sha256:9999999999999999999999999999999999999999999999999999999999999999", + "created_at": "2026-07-17T18:43:11.456Z", + "__unexpected": true + } + }, + { + "description": "invocation-response.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "record_id": "record_01J00000000000000000000005", + "invocation_id": "invocation_01J00000000000000000000008", + "retention_mode": "full_private", + "content_type": "draft_preview", + "retained_text": "Attention is personal in experience and public in consequence.", + "finish_reason": "stop", + "usage": { + "input_tokens": 120, + "output_tokens": 14 + }, + "provider_metadata": { + "request_id": "local-0001", + "load_duration_milliseconds": 120 + }, + "validation": { + "schema_valid": true, + "repair_attempted": false + }, + "content_sha256": "sha256:9999999999999999999999999999999999999999999999999999999999999999", + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-response.record_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "record_id": "invalid-id", + "invocation_id": "invocation_01J00000000000000000000008", + "retention_mode": "full_private", + "content_type": "draft_preview", + "retained_text": "Attention is personal in experience and public in consequence.", + "finish_reason": "stop", + "usage": { + "input_tokens": 120, + "output_tokens": 14 + }, + "provider_metadata": { + "request_id": "local-0001", + "load_duration_milliseconds": 120 + }, + "validation": { + "schema_valid": true, + "repair_attempted": false + }, + "content_sha256": "sha256:9999999999999999999999999999999999999999999999999999999999999999", + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-response.invocation_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "invocation_id": "invalid-id", + "retention_mode": "full_private", + "content_type": "draft_preview", + "retained_text": "Attention is personal in experience and public in consequence.", + "finish_reason": "stop", + "usage": { + "input_tokens": 120, + "output_tokens": 14 + }, + "provider_metadata": { + "request_id": "local-0001", + "load_duration_milliseconds": 120 + }, + "validation": { + "schema_valid": true, + "repair_attempted": false + }, + "content_sha256": "sha256:9999999999999999999999999999999999999999999999999999999999999999", + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-response.retention_mode: reject value outside enum", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "invocation_id": "invocation_01J00000000000000000000008", + "retention_mode": "__INVALID_ENUM__", + "content_type": "draft_preview", + "retained_text": "Attention is personal in experience and public in consequence.", + "finish_reason": "stop", + "usage": { + "input_tokens": 120, + "output_tokens": 14 + }, + "provider_metadata": { + "request_id": "local-0001", + "load_duration_milliseconds": 120 + }, + "validation": { + "schema_valid": true, + "repair_attempted": false + }, + "content_sha256": "sha256:9999999999999999999999999999999999999999999999999999999999999999", + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-response.content_type: reject value outside enum", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "invocation_id": "invocation_01J00000000000000000000008", + "retention_mode": "full_private", + "content_type": "__INVALID_ENUM__", + "retained_text": "Attention is personal in experience and public in consequence.", + "finish_reason": "stop", + "usage": { + "input_tokens": 120, + "output_tokens": 14 + }, + "provider_metadata": { + "request_id": "local-0001", + "load_duration_milliseconds": 120 + }, + "validation": { + "schema_valid": true, + "repair_attempted": false + }, + "content_sha256": "sha256:9999999999999999999999999999999999999999999999999999999999999999", + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-response.finish_reason: reject string below minLength", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "invocation_id": "invocation_01J00000000000000000000008", + "retention_mode": "full_private", + "content_type": "draft_preview", + "retained_text": "Attention is personal in experience and public in consequence.", + "finish_reason": "", + "usage": { + "input_tokens": 120, + "output_tokens": 14 + }, + "provider_metadata": { + "request_id": "local-0001", + "load_duration_milliseconds": 120 + }, + "validation": { + "schema_valid": true, + "repair_attempted": false + }, + "content_sha256": "sha256:9999999999999999999999999999999999999999999999999999999999999999", + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-response.usage.input_tokens: reject missing required property", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "invocation_id": "invocation_01J00000000000000000000008", + "retention_mode": "full_private", + "content_type": "draft_preview", + "retained_text": "Attention is personal in experience and public in consequence.", + "finish_reason": "stop", + "usage": { + "output_tokens": 14 + }, + "provider_metadata": { + "request_id": "local-0001", + "load_duration_milliseconds": 120 + }, + "validation": { + "schema_valid": true, + "repair_attempted": false + }, + "content_sha256": "sha256:9999999999999999999999999999999999999999999999999999999999999999", + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-response.usage.output_tokens: reject missing required property", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "invocation_id": "invocation_01J00000000000000000000008", + "retention_mode": "full_private", + "content_type": "draft_preview", + "retained_text": "Attention is personal in experience and public in consequence.", + "finish_reason": "stop", + "usage": { + "input_tokens": 120 + }, + "provider_metadata": { + "request_id": "local-0001", + "load_duration_milliseconds": 120 + }, + "validation": { + "schema_valid": true, + "repair_attempted": false + }, + "content_sha256": "sha256:9999999999999999999999999999999999999999999999999999999999999999", + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-response.usage: reject unexpected property", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "invocation_id": "invocation_01J00000000000000000000008", + "retention_mode": "full_private", + "content_type": "draft_preview", + "retained_text": "Attention is personal in experience and public in consequence.", + "finish_reason": "stop", + "usage": { + "input_tokens": 120, + "output_tokens": 14, + "__unexpected": true + }, + "provider_metadata": { + "request_id": "local-0001", + "load_duration_milliseconds": 120 + }, + "validation": { + "schema_valid": true, + "repair_attempted": false + }, + "content_sha256": "sha256:9999999999999999999999999999999999999999999999999999999999999999", + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-response.usage.input_tokens: reject value below minimum", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "invocation_id": "invocation_01J00000000000000000000008", + "retention_mode": "full_private", + "content_type": "draft_preview", + "retained_text": "Attention is personal in experience and public in consequence.", + "finish_reason": "stop", + "usage": { + "input_tokens": -1, + "output_tokens": 14 + }, + "provider_metadata": { + "request_id": "local-0001", + "load_duration_milliseconds": 120 + }, + "validation": { + "schema_valid": true, + "repair_attempted": false + }, + "content_sha256": "sha256:9999999999999999999999999999999999999999999999999999999999999999", + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-response.usage.output_tokens: reject value below minimum", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "invocation_id": "invocation_01J00000000000000000000008", + "retention_mode": "full_private", + "content_type": "draft_preview", + "retained_text": "Attention is personal in experience and public in consequence.", + "finish_reason": "stop", + "usage": { + "input_tokens": 120, + "output_tokens": -1 + }, + "provider_metadata": { + "request_id": "local-0001", + "load_duration_milliseconds": 120 + }, + "validation": { + "schema_valid": true, + "repair_attempted": false + }, + "content_sha256": "sha256:9999999999999999999999999999999999999999999999999999999999999999", + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-response.validation.schema_valid: reject missing required property", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "invocation_id": "invocation_01J00000000000000000000008", + "retention_mode": "full_private", + "content_type": "draft_preview", + "retained_text": "Attention is personal in experience and public in consequence.", + "finish_reason": "stop", + "usage": { + "input_tokens": 120, + "output_tokens": 14 + }, + "provider_metadata": { + "request_id": "local-0001", + "load_duration_milliseconds": 120 + }, + "validation": { + "repair_attempted": false + }, + "content_sha256": "sha256:9999999999999999999999999999999999999999999999999999999999999999", + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-response.validation.repair_attempted: reject missing required property", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "invocation_id": "invocation_01J00000000000000000000008", + "retention_mode": "full_private", + "content_type": "draft_preview", + "retained_text": "Attention is personal in experience and public in consequence.", + "finish_reason": "stop", + "usage": { + "input_tokens": 120, + "output_tokens": 14 + }, + "provider_metadata": { + "request_id": "local-0001", + "load_duration_milliseconds": 120 + }, + "validation": { + "schema_valid": true + }, + "content_sha256": "sha256:9999999999999999999999999999999999999999999999999999999999999999", + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-response.validation: reject unexpected property", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "invocation_id": "invocation_01J00000000000000000000008", + "retention_mode": "full_private", + "content_type": "draft_preview", + "retained_text": "Attention is personal in experience and public in consequence.", + "finish_reason": "stop", + "usage": { + "input_tokens": 120, + "output_tokens": 14 + }, + "provider_metadata": { + "request_id": "local-0001", + "load_duration_milliseconds": 120 + }, + "validation": { + "schema_valid": true, + "repair_attempted": false, + "__unexpected": true + }, + "content_sha256": "sha256:9999999999999999999999999999999999999999999999999999999999999999", + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-response.content_sha256: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "invocation_id": "invocation_01J00000000000000000000008", + "retention_mode": "full_private", + "content_type": "draft_preview", + "retained_text": "Attention is personal in experience and public in consequence.", + "finish_reason": "stop", + "usage": { + "input_tokens": 120, + "output_tokens": 14 + }, + "provider_metadata": { + "request_id": "local-0001", + "load_duration_milliseconds": 120 + }, + "validation": { + "schema_valid": true, + "repair_attempted": false + }, + "content_sha256": "sha256:INVALID", + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-response.created_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "invocation_id": "invocation_01J00000000000000000000008", + "retention_mode": "full_private", + "content_type": "draft_preview", + "retained_text": "Attention is personal in experience and public in consequence.", + "finish_reason": "stop", + "usage": { + "input_tokens": 120, + "output_tokens": 14 + }, + "provider_metadata": { + "request_id": "local-0001", + "load_duration_milliseconds": 120 + }, + "validation": { + "schema_valid": true, + "repair_attempted": false + }, + "content_sha256": "sha256:9999999999999999999999999999999999999999999999999999999999999999", + "created_at": "not-a-timestamp" + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/invocation-state.invalid.json b/schemas/provenance/v1/fixtures/invalid/invocation-state.invalid.json new file mode 100644 index 0000000..a1ce8a5 --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/invocation-state.invalid.json @@ -0,0 +1,132 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/invocation-state.schema.json", + "cases": [ + { + "description": "invocation-state.schema_version: reject missing required property", + "instance": { + "invocation_id": "invocation_01J00000000000000000000008", + "state": "REQUEST_RECORDED", + "state_sequence": 2, + "updated_at": "2026-07-17T18:42:10.123Z", + "failure_id": null + } + }, + { + "description": "invocation-state.invocation_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "state": "REQUEST_RECORDED", + "state_sequence": 2, + "updated_at": "2026-07-17T18:42:10.123Z", + "failure_id": null + } + }, + { + "description": "invocation-state.state: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "state_sequence": 2, + "updated_at": "2026-07-17T18:42:10.123Z", + "failure_id": null + } + }, + { + "description": "invocation-state.state_sequence: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "state": "REQUEST_RECORDED", + "updated_at": "2026-07-17T18:42:10.123Z", + "failure_id": null + } + }, + { + "description": "invocation-state.updated_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "state": "REQUEST_RECORDED", + "state_sequence": 2, + "failure_id": null + } + }, + { + "description": "invocation-state.failure_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "state": "REQUEST_RECORDED", + "state_sequence": 2, + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "invocation-state: reject unexpected property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "state": "REQUEST_RECORDED", + "state_sequence": 2, + "updated_at": "2026-07-17T18:42:10.123Z", + "failure_id": null, + "__unexpected": true + } + }, + { + "description": "invocation-state.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "invocation_id": "invocation_01J00000000000000000000008", + "state": "REQUEST_RECORDED", + "state_sequence": 2, + "updated_at": "2026-07-17T18:42:10.123Z", + "failure_id": null + } + }, + { + "description": "invocation-state.invocation_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "invocation_id": "invalid-id", + "state": "REQUEST_RECORDED", + "state_sequence": 2, + "updated_at": "2026-07-17T18:42:10.123Z", + "failure_id": null + } + }, + { + "description": "invocation-state.state: reject value outside enum", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "state": "__INVALID_ENUM__", + "state_sequence": 2, + "updated_at": "2026-07-17T18:42:10.123Z", + "failure_id": null + } + }, + { + "description": "invocation-state.state_sequence: reject value below minimum", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "state": "REQUEST_RECORDED", + "state_sequence": 0, + "updated_at": "2026-07-17T18:42:10.123Z", + "failure_id": null + } + }, + { + "description": "invocation-state.updated_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "state": "REQUEST_RECORDED", + "state_sequence": 2, + "updated_at": "not-a-timestamp", + "failure_id": null + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/invocation-stream-state.invalid.json b/schemas/provenance/v1/fixtures/invalid/invocation-stream-state.invalid.json new file mode 100644 index 0000000..e1715aa --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/invocation-stream-state.invalid.json @@ -0,0 +1,191 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/invocation-stream-state.schema.json", + "cases": [ + { + "description": "invocation-stream-state.schema_version: reject missing required property", + "instance": { + "stream_id": "stream_01J0000000000000000000000Q", + "invocation_id": "invocation_01J00000000000000000000008", + "state": "STREAMING", + "bytes_received": 512, + "started_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-stream-state.stream_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "state": "STREAMING", + "bytes_received": 512, + "started_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-stream-state.invocation_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "stream_id": "stream_01J0000000000000000000000Q", + "state": "STREAMING", + "bytes_received": 512, + "started_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-stream-state.state: reject missing required property", + "instance": { + "schema_version": "1.0", + "stream_id": "stream_01J0000000000000000000000Q", + "invocation_id": "invocation_01J00000000000000000000008", + "bytes_received": 512, + "started_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-stream-state.bytes_received: reject missing required property", + "instance": { + "schema_version": "1.0", + "stream_id": "stream_01J0000000000000000000000Q", + "invocation_id": "invocation_01J00000000000000000000008", + "state": "STREAMING", + "started_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-stream-state.started_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "stream_id": "stream_01J0000000000000000000000Q", + "invocation_id": "invocation_01J00000000000000000000008", + "state": "STREAMING", + "bytes_received": 512, + "updated_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-stream-state.updated_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "stream_id": "stream_01J0000000000000000000000Q", + "invocation_id": "invocation_01J00000000000000000000008", + "state": "STREAMING", + "bytes_received": 512, + "started_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "invocation-stream-state: reject unexpected property", + "instance": { + "schema_version": "1.0", + "stream_id": "stream_01J0000000000000000000000Q", + "invocation_id": "invocation_01J00000000000000000000008", + "state": "STREAMING", + "bytes_received": 512, + "started_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z", + "__unexpected": true + } + }, + { + "description": "invocation-stream-state.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "stream_id": "stream_01J0000000000000000000000Q", + "invocation_id": "invocation_01J00000000000000000000008", + "state": "STREAMING", + "bytes_received": 512, + "started_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-stream-state.stream_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "stream_id": "invalid-id", + "invocation_id": "invocation_01J00000000000000000000008", + "state": "STREAMING", + "bytes_received": 512, + "started_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-stream-state.invocation_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "stream_id": "stream_01J0000000000000000000000Q", + "invocation_id": "invalid-id", + "state": "STREAMING", + "bytes_received": 512, + "started_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-stream-state.state: reject value outside enum", + "instance": { + "schema_version": "1.0", + "stream_id": "stream_01J0000000000000000000000Q", + "invocation_id": "invocation_01J00000000000000000000008", + "state": "__INVALID_ENUM__", + "bytes_received": 512, + "started_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-stream-state.bytes_received: reject value below minimum", + "instance": { + "schema_version": "1.0", + "stream_id": "stream_01J0000000000000000000000Q", + "invocation_id": "invocation_01J00000000000000000000008", + "state": "STREAMING", + "bytes_received": -1, + "started_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-stream-state.bytes_received: reject value above maximum", + "instance": { + "schema_version": "1.0", + "stream_id": "stream_01J0000000000000000000000Q", + "invocation_id": "invocation_01J00000000000000000000008", + "state": "STREAMING", + "bytes_received": 67108865, + "started_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-stream-state.started_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "stream_id": "stream_01J0000000000000000000000Q", + "invocation_id": "invocation_01J00000000000000000000008", + "state": "STREAMING", + "bytes_received": 512, + "started_at": "not-a-timestamp", + "updated_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-stream-state.updated_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "stream_id": "stream_01J0000000000000000000000Q", + "invocation_id": "invocation_01J00000000000000000000008", + "state": "STREAMING", + "bytes_received": 512, + "started_at": "2026-07-17T18:42:10.123Z", + "updated_at": "not-a-timestamp" + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/invocation-stream-summary.invalid.json b/schemas/provenance/v1/fixtures/invalid/invocation-stream-summary.invalid.json new file mode 100644 index 0000000..77d21f5 --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/invocation-stream-summary.invalid.json @@ -0,0 +1,277 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/invocation-stream-summary.schema.json", + "cases": [ + { + "description": "invocation-stream-summary.schema_version: reject missing required property", + "instance": { + "stream_id": "stream_01J0000000000000000000000Q", + "invocation_id": "invocation_01J00000000000000000000008", + "terminal_state": "COMPLETED", + "bytes_received": 512, + "chunks_received": 4, + "duration_milliseconds": 2400, + "partial_output_preserved": false, + "completed_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-stream-summary.stream_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "terminal_state": "COMPLETED", + "bytes_received": 512, + "chunks_received": 4, + "duration_milliseconds": 2400, + "partial_output_preserved": false, + "completed_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-stream-summary.invocation_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "stream_id": "stream_01J0000000000000000000000Q", + "terminal_state": "COMPLETED", + "bytes_received": 512, + "chunks_received": 4, + "duration_milliseconds": 2400, + "partial_output_preserved": false, + "completed_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-stream-summary.terminal_state: reject missing required property", + "instance": { + "schema_version": "1.0", + "stream_id": "stream_01J0000000000000000000000Q", + "invocation_id": "invocation_01J00000000000000000000008", + "bytes_received": 512, + "chunks_received": 4, + "duration_milliseconds": 2400, + "partial_output_preserved": false, + "completed_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-stream-summary.bytes_received: reject missing required property", + "instance": { + "schema_version": "1.0", + "stream_id": "stream_01J0000000000000000000000Q", + "invocation_id": "invocation_01J00000000000000000000008", + "terminal_state": "COMPLETED", + "chunks_received": 4, + "duration_milliseconds": 2400, + "partial_output_preserved": false, + "completed_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-stream-summary.chunks_received: reject missing required property", + "instance": { + "schema_version": "1.0", + "stream_id": "stream_01J0000000000000000000000Q", + "invocation_id": "invocation_01J00000000000000000000008", + "terminal_state": "COMPLETED", + "bytes_received": 512, + "duration_milliseconds": 2400, + "partial_output_preserved": false, + "completed_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-stream-summary.duration_milliseconds: reject missing required property", + "instance": { + "schema_version": "1.0", + "stream_id": "stream_01J0000000000000000000000Q", + "invocation_id": "invocation_01J00000000000000000000008", + "terminal_state": "COMPLETED", + "bytes_received": 512, + "chunks_received": 4, + "partial_output_preserved": false, + "completed_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-stream-summary.partial_output_preserved: reject missing required property", + "instance": { + "schema_version": "1.0", + "stream_id": "stream_01J0000000000000000000000Q", + "invocation_id": "invocation_01J00000000000000000000008", + "terminal_state": "COMPLETED", + "bytes_received": 512, + "chunks_received": 4, + "duration_milliseconds": 2400, + "completed_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-stream-summary.completed_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "stream_id": "stream_01J0000000000000000000000Q", + "invocation_id": "invocation_01J00000000000000000000008", + "terminal_state": "COMPLETED", + "bytes_received": 512, + "chunks_received": 4, + "duration_milliseconds": 2400, + "partial_output_preserved": false + } + }, + { + "description": "invocation-stream-summary: reject unexpected property", + "instance": { + "schema_version": "1.0", + "stream_id": "stream_01J0000000000000000000000Q", + "invocation_id": "invocation_01J00000000000000000000008", + "terminal_state": "COMPLETED", + "bytes_received": 512, + "chunks_received": 4, + "duration_milliseconds": 2400, + "partial_output_preserved": false, + "completed_at": "2026-07-17T18:43:11.456Z", + "__unexpected": true + } + }, + { + "description": "invocation-stream-summary.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "stream_id": "stream_01J0000000000000000000000Q", + "invocation_id": "invocation_01J00000000000000000000008", + "terminal_state": "COMPLETED", + "bytes_received": 512, + "chunks_received": 4, + "duration_milliseconds": 2400, + "partial_output_preserved": false, + "completed_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-stream-summary.stream_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "stream_id": "invalid-id", + "invocation_id": "invocation_01J00000000000000000000008", + "terminal_state": "COMPLETED", + "bytes_received": 512, + "chunks_received": 4, + "duration_milliseconds": 2400, + "partial_output_preserved": false, + "completed_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-stream-summary.invocation_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "stream_id": "stream_01J0000000000000000000000Q", + "invocation_id": "invalid-id", + "terminal_state": "COMPLETED", + "bytes_received": 512, + "chunks_received": 4, + "duration_milliseconds": 2400, + "partial_output_preserved": false, + "completed_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-stream-summary.terminal_state: reject value outside enum", + "instance": { + "schema_version": "1.0", + "stream_id": "stream_01J0000000000000000000000Q", + "invocation_id": "invocation_01J00000000000000000000008", + "terminal_state": "__INVALID_ENUM__", + "bytes_received": 512, + "chunks_received": 4, + "duration_milliseconds": 2400, + "partial_output_preserved": false, + "completed_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-stream-summary.bytes_received: reject value below minimum", + "instance": { + "schema_version": "1.0", + "stream_id": "stream_01J0000000000000000000000Q", + "invocation_id": "invocation_01J00000000000000000000008", + "terminal_state": "COMPLETED", + "bytes_received": -1, + "chunks_received": 4, + "duration_milliseconds": 2400, + "partial_output_preserved": false, + "completed_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-stream-summary.bytes_received: reject value above maximum", + "instance": { + "schema_version": "1.0", + "stream_id": "stream_01J0000000000000000000000Q", + "invocation_id": "invocation_01J00000000000000000000008", + "terminal_state": "COMPLETED", + "bytes_received": 67108865, + "chunks_received": 4, + "duration_milliseconds": 2400, + "partial_output_preserved": false, + "completed_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-stream-summary.chunks_received: reject value below minimum", + "instance": { + "schema_version": "1.0", + "stream_id": "stream_01J0000000000000000000000Q", + "invocation_id": "invocation_01J00000000000000000000008", + "terminal_state": "COMPLETED", + "bytes_received": 512, + "chunks_received": -1, + "duration_milliseconds": 2400, + "partial_output_preserved": false, + "completed_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-stream-summary.duration_milliseconds: reject value below minimum", + "instance": { + "schema_version": "1.0", + "stream_id": "stream_01J0000000000000000000000Q", + "invocation_id": "invocation_01J00000000000000000000008", + "terminal_state": "COMPLETED", + "bytes_received": 512, + "chunks_received": 4, + "duration_milliseconds": -1, + "partial_output_preserved": false, + "completed_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-stream-summary.duration_milliseconds: reject value above maximum", + "instance": { + "schema_version": "1.0", + "stream_id": "stream_01J0000000000000000000000Q", + "invocation_id": "invocation_01J00000000000000000000008", + "terminal_state": "COMPLETED", + "bytes_received": 512, + "chunks_received": 4, + "duration_milliseconds": 1800001, + "partial_output_preserved": false, + "completed_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "invocation-stream-summary.completed_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "stream_id": "stream_01J0000000000000000000000Q", + "invocation_id": "invocation_01J00000000000000000000008", + "terminal_state": "COMPLETED", + "bytes_received": 512, + "chunks_received": 4, + "duration_milliseconds": 2400, + "partial_output_preserved": false, + "completed_at": "not-a-timestamp" + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/ledger-segment-manifest.invalid.json b/schemas/provenance/v1/fixtures/invalid/ledger-segment-manifest.invalid.json new file mode 100644 index 0000000..85fc48f --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/ledger-segment-manifest.invalid.json @@ -0,0 +1,402 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/ledger-segment-manifest.schema.json", + "cases": [ + { + "description": "ledger-segment-manifest.schema_version: reject missing required property", + "instance": { + "project_id": "project_01J00000000000000000000001", + "segment_number": 1, + "previous_segment_file_hash": null, + "first_event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "final_event_hash": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "first_event_sequence": 1, + "final_event_sequence": 2, + "event_count": 2, + "byte_length": 1024, + "segment_file_hash": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "sealed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "ledger-segment-manifest.project_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "segment_number": 1, + "previous_segment_file_hash": null, + "first_event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "final_event_hash": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "first_event_sequence": 1, + "final_event_sequence": 2, + "event_count": 2, + "byte_length": 1024, + "segment_file_hash": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "sealed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "ledger-segment-manifest.segment_number: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "previous_segment_file_hash": null, + "first_event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "final_event_hash": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "first_event_sequence": 1, + "final_event_sequence": 2, + "event_count": 2, + "byte_length": 1024, + "segment_file_hash": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "sealed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "ledger-segment-manifest.previous_segment_file_hash: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "segment_number": 1, + "first_event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "final_event_hash": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "first_event_sequence": 1, + "final_event_sequence": 2, + "event_count": 2, + "byte_length": 1024, + "segment_file_hash": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "sealed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "ledger-segment-manifest.first_event_hash: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "segment_number": 1, + "previous_segment_file_hash": null, + "final_event_hash": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "first_event_sequence": 1, + "final_event_sequence": 2, + "event_count": 2, + "byte_length": 1024, + "segment_file_hash": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "sealed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "ledger-segment-manifest.final_event_hash: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "segment_number": 1, + "previous_segment_file_hash": null, + "first_event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "first_event_sequence": 1, + "final_event_sequence": 2, + "event_count": 2, + "byte_length": 1024, + "segment_file_hash": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "sealed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "ledger-segment-manifest.first_event_sequence: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "segment_number": 1, + "previous_segment_file_hash": null, + "first_event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "final_event_hash": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "final_event_sequence": 2, + "event_count": 2, + "byte_length": 1024, + "segment_file_hash": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "sealed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "ledger-segment-manifest.final_event_sequence: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "segment_number": 1, + "previous_segment_file_hash": null, + "first_event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "final_event_hash": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "first_event_sequence": 1, + "event_count": 2, + "byte_length": 1024, + "segment_file_hash": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "sealed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "ledger-segment-manifest.event_count: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "segment_number": 1, + "previous_segment_file_hash": null, + "first_event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "final_event_hash": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "first_event_sequence": 1, + "final_event_sequence": 2, + "byte_length": 1024, + "segment_file_hash": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "sealed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "ledger-segment-manifest.byte_length: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "segment_number": 1, + "previous_segment_file_hash": null, + "first_event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "final_event_hash": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "first_event_sequence": 1, + "final_event_sequence": 2, + "event_count": 2, + "segment_file_hash": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "sealed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "ledger-segment-manifest.segment_file_hash: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "segment_number": 1, + "previous_segment_file_hash": null, + "first_event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "final_event_hash": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "first_event_sequence": 1, + "final_event_sequence": 2, + "event_count": 2, + "byte_length": 1024, + "sealed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "ledger-segment-manifest.sealed_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "segment_number": 1, + "previous_segment_file_hash": null, + "first_event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "final_event_hash": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "first_event_sequence": 1, + "final_event_sequence": 2, + "event_count": 2, + "byte_length": 1024, + "segment_file_hash": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + } + }, + { + "description": "ledger-segment-manifest: reject unexpected property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "segment_number": 1, + "previous_segment_file_hash": null, + "first_event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "final_event_hash": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "first_event_sequence": 1, + "final_event_sequence": 2, + "event_count": 2, + "byte_length": 1024, + "segment_file_hash": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "sealed_at": "2026-07-17T18:42:10.123Z", + "__unexpected": true + } + }, + { + "description": "ledger-segment-manifest.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "project_id": "project_01J00000000000000000000001", + "segment_number": 1, + "previous_segment_file_hash": null, + "first_event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "final_event_hash": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "first_event_sequence": 1, + "final_event_sequence": 2, + "event_count": 2, + "byte_length": 1024, + "segment_file_hash": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "sealed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "ledger-segment-manifest.project_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "project_id": "invalid-id", + "segment_number": 1, + "previous_segment_file_hash": null, + "first_event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "final_event_hash": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "first_event_sequence": 1, + "final_event_sequence": 2, + "event_count": 2, + "byte_length": 1024, + "segment_file_hash": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "sealed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "ledger-segment-manifest.segment_number: reject value below minimum", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "segment_number": 0, + "previous_segment_file_hash": null, + "first_event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "final_event_hash": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "first_event_sequence": 1, + "final_event_sequence": 2, + "event_count": 2, + "byte_length": 1024, + "segment_file_hash": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "sealed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "ledger-segment-manifest.first_event_hash: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "segment_number": 1, + "previous_segment_file_hash": null, + "first_event_hash": "sha256:INVALID", + "final_event_hash": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "first_event_sequence": 1, + "final_event_sequence": 2, + "event_count": 2, + "byte_length": 1024, + "segment_file_hash": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "sealed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "ledger-segment-manifest.final_event_hash: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "segment_number": 1, + "previous_segment_file_hash": null, + "first_event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "final_event_hash": "sha256:INVALID", + "first_event_sequence": 1, + "final_event_sequence": 2, + "event_count": 2, + "byte_length": 1024, + "segment_file_hash": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "sealed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "ledger-segment-manifest.first_event_sequence: reject value below minimum", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "segment_number": 1, + "previous_segment_file_hash": null, + "first_event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "final_event_hash": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "first_event_sequence": 0, + "final_event_sequence": 2, + "event_count": 2, + "byte_length": 1024, + "segment_file_hash": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "sealed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "ledger-segment-manifest.final_event_sequence: reject value below minimum", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "segment_number": 1, + "previous_segment_file_hash": null, + "first_event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "final_event_hash": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "first_event_sequence": 1, + "final_event_sequence": 0, + "event_count": 2, + "byte_length": 1024, + "segment_file_hash": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "sealed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "ledger-segment-manifest.event_count: reject value below minimum", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "segment_number": 1, + "previous_segment_file_hash": null, + "first_event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "final_event_hash": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "first_event_sequence": 1, + "final_event_sequence": 2, + "event_count": 0, + "byte_length": 1024, + "segment_file_hash": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "sealed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "ledger-segment-manifest.byte_length: reject value below minimum", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "segment_number": 1, + "previous_segment_file_hash": null, + "first_event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "final_event_hash": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "first_event_sequence": 1, + "final_event_sequence": 2, + "event_count": 2, + "byte_length": 0, + "segment_file_hash": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "sealed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "ledger-segment-manifest.segment_file_hash: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "segment_number": 1, + "previous_segment_file_hash": null, + "first_event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "final_event_hash": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "first_event_sequence": 1, + "final_event_sequence": 2, + "event_count": 2, + "byte_length": 1024, + "segment_file_hash": "sha256:INVALID", + "sealed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "ledger-segment-manifest.sealed_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "segment_number": 1, + "previous_segment_file_hash": null, + "first_event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "final_event_hash": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "first_event_sequence": 1, + "final_event_sequence": 2, + "event_count": 2, + "byte_length": 1024, + "segment_file_hash": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "sealed_at": "not-a-timestamp" + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/manuscript-revision.invalid.json b/schemas/provenance/v1/fixtures/invalid/manuscript-revision.invalid.json new file mode 100644 index 0000000..ef72f26 --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/manuscript-revision.invalid.json @@ -0,0 +1,263 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/manuscript-revision.schema.json", + "cases": [ + { + "description": "manuscript-revision.schema_version: reject missing required property", + "instance": { + "revision_id": "revision_01J0000000000000000000000A", + "project_id": "project_01J00000000000000000000001", + "parent_revision_id": null, + "canonical_markdown_path": "manuscript/revisions/revision.md", + "canonical_markdown_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "word_count": 42, + "created_by": "user", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "manuscript-revision.revision_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "parent_revision_id": null, + "canonical_markdown_path": "manuscript/revisions/revision.md", + "canonical_markdown_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "word_count": 42, + "created_by": "user", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "manuscript-revision.project_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "parent_revision_id": null, + "canonical_markdown_path": "manuscript/revisions/revision.md", + "canonical_markdown_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "word_count": 42, + "created_by": "user", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "manuscript-revision.parent_revision_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "project_id": "project_01J00000000000000000000001", + "canonical_markdown_path": "manuscript/revisions/revision.md", + "canonical_markdown_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "word_count": 42, + "created_by": "user", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "manuscript-revision.canonical_markdown_path: reject missing required property", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "project_id": "project_01J00000000000000000000001", + "parent_revision_id": null, + "canonical_markdown_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "word_count": 42, + "created_by": "user", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "manuscript-revision.canonical_markdown_sha256: reject missing required property", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "project_id": "project_01J00000000000000000000001", + "parent_revision_id": null, + "canonical_markdown_path": "manuscript/revisions/revision.md", + "word_count": 42, + "created_by": "user", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "manuscript-revision.word_count: reject missing required property", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "project_id": "project_01J00000000000000000000001", + "parent_revision_id": null, + "canonical_markdown_path": "manuscript/revisions/revision.md", + "canonical_markdown_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "created_by": "user", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "manuscript-revision.created_by: reject missing required property", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "project_id": "project_01J00000000000000000000001", + "parent_revision_id": null, + "canonical_markdown_path": "manuscript/revisions/revision.md", + "canonical_markdown_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "word_count": 42, + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "manuscript-revision.created_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "project_id": "project_01J00000000000000000000001", + "parent_revision_id": null, + "canonical_markdown_path": "manuscript/revisions/revision.md", + "canonical_markdown_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "word_count": 42, + "created_by": "user" + } + }, + { + "description": "manuscript-revision: reject unexpected property", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "project_id": "project_01J00000000000000000000001", + "parent_revision_id": null, + "canonical_markdown_path": "manuscript/revisions/revision.md", + "canonical_markdown_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "word_count": 42, + "created_by": "user", + "created_at": "2026-07-17T18:42:10.123Z", + "__unexpected": true + } + }, + { + "description": "manuscript-revision.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "revision_id": "revision_01J0000000000000000000000A", + "project_id": "project_01J00000000000000000000001", + "parent_revision_id": null, + "canonical_markdown_path": "manuscript/revisions/revision.md", + "canonical_markdown_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "word_count": 42, + "created_by": "user", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "manuscript-revision.revision_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "revision_id": "invalid-id", + "project_id": "project_01J00000000000000000000001", + "parent_revision_id": null, + "canonical_markdown_path": "manuscript/revisions/revision.md", + "canonical_markdown_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "word_count": 42, + "created_by": "user", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "manuscript-revision.project_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "project_id": "invalid-id", + "parent_revision_id": null, + "canonical_markdown_path": "manuscript/revisions/revision.md", + "canonical_markdown_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "word_count": 42, + "created_by": "user", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "manuscript-revision.canonical_markdown_path: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "project_id": "project_01J00000000000000000000001", + "parent_revision_id": null, + "canonical_markdown_path": "../outside-project", + "canonical_markdown_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "word_count": 42, + "created_by": "user", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "manuscript-revision.canonical_markdown_path: reject string below minLength", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "project_id": "project_01J00000000000000000000001", + "parent_revision_id": null, + "canonical_markdown_path": "", + "canonical_markdown_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "word_count": 42, + "created_by": "user", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "manuscript-revision.canonical_markdown_sha256: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "project_id": "project_01J00000000000000000000001", + "parent_revision_id": null, + "canonical_markdown_path": "manuscript/revisions/revision.md", + "canonical_markdown_sha256": "sha256:INVALID", + "word_count": 42, + "created_by": "user", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "manuscript-revision.word_count: reject value below minimum", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "project_id": "project_01J00000000000000000000001", + "parent_revision_id": null, + "canonical_markdown_path": "manuscript/revisions/revision.md", + "canonical_markdown_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "word_count": -1, + "created_by": "user", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "manuscript-revision.created_by: reject value outside enum", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "project_id": "project_01J00000000000000000000001", + "parent_revision_id": null, + "canonical_markdown_path": "manuscript/revisions/revision.md", + "canonical_markdown_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "word_count": 42, + "created_by": "__INVALID_ENUM__", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "manuscript-revision.created_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "project_id": "project_01J00000000000000000000001", + "parent_revision_id": null, + "canonical_markdown_path": "manuscript/revisions/revision.md", + "canonical_markdown_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "word_count": 42, + "created_by": "user", + "created_at": "not-a-timestamp" + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/model-capability-snapshot.invalid.json b/schemas/provenance/v1/fixtures/invalid/model-capability-snapshot.invalid.json new file mode 100644 index 0000000..c0ff594 --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/model-capability-snapshot.invalid.json @@ -0,0 +1,264 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/model-capability-snapshot.schema.json", + "cases": [ + { + "description": "model-capability-snapshot.schema_version: reject missing required property", + "instance": { + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "capabilities": { + "streaming": true, + "structured_output": false, + "tools": false, + "vision": false + }, + "observed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-capability-snapshot.snapshot_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "provider_id": "ollama", + "model_id": "llama3.2", + "capabilities": { + "streaming": true, + "structured_output": false, + "tools": false, + "vision": false + }, + "observed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-capability-snapshot.provider_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "model_id": "llama3.2", + "capabilities": { + "streaming": true, + "structured_output": false, + "tools": false, + "vision": false + }, + "observed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-capability-snapshot.model_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "capabilities": { + "streaming": true, + "structured_output": false, + "tools": false, + "vision": false + }, + "observed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-capability-snapshot.capabilities: reject missing required property", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "observed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-capability-snapshot.observed_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "capabilities": { + "streaming": true, + "structured_output": false, + "tools": false, + "vision": false + } + } + }, + { + "description": "model-capability-snapshot: reject unexpected property", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "capabilities": { + "streaming": true, + "structured_output": false, + "tools": false, + "vision": false + }, + "observed_at": "2026-07-17T18:42:10.123Z", + "__unexpected": true + } + }, + { + "description": "model-capability-snapshot.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "capabilities": { + "streaming": true, + "structured_output": false, + "tools": false, + "vision": false + }, + "observed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-capability-snapshot.snapshot_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "snapshot_id": "invalid-id", + "provider_id": "ollama", + "model_id": "llama3.2", + "capabilities": { + "streaming": true, + "structured_output": false, + "tools": false, + "vision": false + }, + "observed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-capability-snapshot.provider_id: reject string below minLength", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "", + "model_id": "llama3.2", + "capabilities": { + "streaming": true, + "structured_output": false, + "tools": false, + "vision": false + }, + "observed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-capability-snapshot.model_id: reject string below minLength", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "", + "capabilities": { + "streaming": true, + "structured_output": false, + "tools": false, + "vision": false + }, + "observed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-capability-snapshot.capabilities.streaming: reject missing required property", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "capabilities": { + "structured_output": false, + "tools": false, + "vision": false + }, + "observed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-capability-snapshot.capabilities.structured_output: reject missing required property", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "capabilities": { + "streaming": true, + "tools": false, + "vision": false + }, + "observed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-capability-snapshot.capabilities.tools: reject missing required property", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "capabilities": { + "streaming": true, + "structured_output": false, + "vision": false + }, + "observed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-capability-snapshot.capabilities.vision: reject missing required property", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "capabilities": { + "streaming": true, + "structured_output": false, + "tools": false + }, + "observed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-capability-snapshot.capabilities: reject unexpected property", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "capabilities": { + "streaming": true, + "structured_output": false, + "tools": false, + "vision": false, + "__unexpected": true + }, + "observed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-capability-snapshot.observed_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "capabilities": { + "streaming": true, + "structured_output": false, + "tools": false, + "vision": false + }, + "observed_at": "not-a-timestamp" + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/model-configuration-snapshot.invalid.json b/schemas/provenance/v1/fixtures/invalid/model-configuration-snapshot.invalid.json new file mode 100644 index 0000000..c3e8f31 --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/model-configuration-snapshot.invalid.json @@ -0,0 +1,479 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/model-configuration-snapshot.schema.json", + "cases": [ + { + "description": "model-configuration-snapshot.schema_version: reject missing required property", + "instance": { + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local", + "endpoint_classification": "loopback", + "temperature_milli": 700, + "context_limit": 8192, + "maximum_output": 800, + "structured_output_mode": "none", + "tool_configuration": [], + "capability_snapshot_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-configuration-snapshot.snapshot_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local", + "endpoint_classification": "loopback", + "temperature_milli": 700, + "context_limit": 8192, + "maximum_output": 800, + "structured_output_mode": "none", + "tool_configuration": [], + "capability_snapshot_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-configuration-snapshot.provider_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "model_id": "llama3.2", + "processing_mode": "local", + "endpoint_classification": "loopback", + "temperature_milli": 700, + "context_limit": 8192, + "maximum_output": 800, + "structured_output_mode": "none", + "tool_configuration": [], + "capability_snapshot_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-configuration-snapshot.model_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "processing_mode": "local", + "endpoint_classification": "loopback", + "temperature_milli": 700, + "context_limit": 8192, + "maximum_output": 800, + "structured_output_mode": "none", + "tool_configuration": [], + "capability_snapshot_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-configuration-snapshot.processing_mode: reject missing required property", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "endpoint_classification": "loopback", + "temperature_milli": 700, + "context_limit": 8192, + "maximum_output": 800, + "structured_output_mode": "none", + "tool_configuration": [], + "capability_snapshot_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-configuration-snapshot.endpoint_classification: reject missing required property", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local", + "temperature_milli": 700, + "context_limit": 8192, + "maximum_output": 800, + "structured_output_mode": "none", + "tool_configuration": [], + "capability_snapshot_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-configuration-snapshot.temperature_milli: reject missing required property", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local", + "endpoint_classification": "loopback", + "context_limit": 8192, + "maximum_output": 800, + "structured_output_mode": "none", + "tool_configuration": [], + "capability_snapshot_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-configuration-snapshot.context_limit: reject missing required property", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local", + "endpoint_classification": "loopback", + "temperature_milli": 700, + "maximum_output": 800, + "structured_output_mode": "none", + "tool_configuration": [], + "capability_snapshot_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-configuration-snapshot.maximum_output: reject missing required property", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local", + "endpoint_classification": "loopback", + "temperature_milli": 700, + "context_limit": 8192, + "structured_output_mode": "none", + "tool_configuration": [], + "capability_snapshot_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-configuration-snapshot.structured_output_mode: reject missing required property", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local", + "endpoint_classification": "loopback", + "temperature_milli": 700, + "context_limit": 8192, + "maximum_output": 800, + "tool_configuration": [], + "capability_snapshot_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-configuration-snapshot.tool_configuration: reject missing required property", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local", + "endpoint_classification": "loopback", + "temperature_milli": 700, + "context_limit": 8192, + "maximum_output": 800, + "structured_output_mode": "none", + "capability_snapshot_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-configuration-snapshot.capability_snapshot_sha256: reject missing required property", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local", + "endpoint_classification": "loopback", + "temperature_milli": 700, + "context_limit": 8192, + "maximum_output": 800, + "structured_output_mode": "none", + "tool_configuration": [], + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-configuration-snapshot.created_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local", + "endpoint_classification": "loopback", + "temperature_milli": 700, + "context_limit": 8192, + "maximum_output": 800, + "structured_output_mode": "none", + "tool_configuration": [], + "capability_snapshot_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888" + } + }, + { + "description": "model-configuration-snapshot: reject unexpected property", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local", + "endpoint_classification": "loopback", + "temperature_milli": 700, + "context_limit": 8192, + "maximum_output": 800, + "structured_output_mode": "none", + "tool_configuration": [], + "capability_snapshot_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "created_at": "2026-07-17T18:42:10.123Z", + "__unexpected": true + } + }, + { + "description": "model-configuration-snapshot.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local", + "endpoint_classification": "loopback", + "temperature_milli": 700, + "context_limit": 8192, + "maximum_output": 800, + "structured_output_mode": "none", + "tool_configuration": [], + "capability_snapshot_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-configuration-snapshot.snapshot_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "snapshot_id": "invalid-id", + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local", + "endpoint_classification": "loopback", + "temperature_milli": 700, + "context_limit": 8192, + "maximum_output": 800, + "structured_output_mode": "none", + "tool_configuration": [], + "capability_snapshot_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-configuration-snapshot.provider_id: reject string below minLength", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "", + "model_id": "llama3.2", + "processing_mode": "local", + "endpoint_classification": "loopback", + "temperature_milli": 700, + "context_limit": 8192, + "maximum_output": 800, + "structured_output_mode": "none", + "tool_configuration": [], + "capability_snapshot_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-configuration-snapshot.model_id: reject string below minLength", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "", + "processing_mode": "local", + "endpoint_classification": "loopback", + "temperature_milli": 700, + "context_limit": 8192, + "maximum_output": 800, + "structured_output_mode": "none", + "tool_configuration": [], + "capability_snapshot_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-configuration-snapshot.processing_mode: reject value outside enum", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "__INVALID_ENUM__", + "endpoint_classification": "loopback", + "temperature_milli": 700, + "context_limit": 8192, + "maximum_output": 800, + "structured_output_mode": "none", + "tool_configuration": [], + "capability_snapshot_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-configuration-snapshot.endpoint_classification: reject value outside enum", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local", + "endpoint_classification": "__INVALID_ENUM__", + "temperature_milli": 700, + "context_limit": 8192, + "maximum_output": 800, + "structured_output_mode": "none", + "tool_configuration": [], + "capability_snapshot_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-configuration-snapshot.temperature_milli: reject value below minimum", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local", + "endpoint_classification": "loopback", + "temperature_milli": -1, + "context_limit": 8192, + "maximum_output": 800, + "structured_output_mode": "none", + "tool_configuration": [], + "capability_snapshot_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-configuration-snapshot.temperature_milli: reject value above maximum", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local", + "endpoint_classification": "loopback", + "temperature_milli": 2001, + "context_limit": 8192, + "maximum_output": 800, + "structured_output_mode": "none", + "tool_configuration": [], + "capability_snapshot_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-configuration-snapshot.context_limit: reject value below minimum", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local", + "endpoint_classification": "loopback", + "temperature_milli": 700, + "context_limit": 0, + "maximum_output": 800, + "structured_output_mode": "none", + "tool_configuration": [], + "capability_snapshot_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-configuration-snapshot.maximum_output: reject value below minimum", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local", + "endpoint_classification": "loopback", + "temperature_milli": 700, + "context_limit": 8192, + "maximum_output": 0, + "structured_output_mode": "none", + "tool_configuration": [], + "capability_snapshot_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-configuration-snapshot.structured_output_mode: reject value outside enum", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local", + "endpoint_classification": "loopback", + "temperature_milli": 700, + "context_limit": 8192, + "maximum_output": 800, + "structured_output_mode": "__INVALID_ENUM__", + "tool_configuration": [], + "capability_snapshot_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-configuration-snapshot.capability_snapshot_sha256: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local", + "endpoint_classification": "loopback", + "temperature_milli": 700, + "context_limit": 8192, + "maximum_output": 800, + "structured_output_mode": "none", + "tool_configuration": [], + "capability_snapshot_sha256": "sha256:INVALID", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "model-configuration-snapshot.created_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local", + "endpoint_classification": "loopback", + "temperature_milli": 700, + "context_limit": 8192, + "maximum_output": 800, + "structured_output_mode": "none", + "tool_configuration": [], + "capability_snapshot_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "created_at": "not-a-timestamp" + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/project-key-manifest.invalid.json b/schemas/provenance/v1/fixtures/invalid/project-key-manifest.invalid.json new file mode 100644 index 0000000..fcf5fdd --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/project-key-manifest.invalid.json @@ -0,0 +1,245 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/project-key-manifest.schema.json", + "cases": [ + { + "description": "project-key-manifest.schema_version: reject missing required property", + "instance": { + "project_id": "project_01J00000000000000000000001", + "key_id": "key_01J0000000000000000000000G", + "algorithm": "xchacha20-poly1305", + "device_envelope_path": "provenance/keys/device-envelope.json", + "recovery_envelope_path": "provenance/keys/recovery-envelope.json", + "recovery_verified_at": "2026-07-17T18:42:10.123Z", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "project-key-manifest.project_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "key_id": "key_01J0000000000000000000000G", + "algorithm": "xchacha20-poly1305", + "device_envelope_path": "provenance/keys/device-envelope.json", + "recovery_envelope_path": "provenance/keys/recovery-envelope.json", + "recovery_verified_at": "2026-07-17T18:42:10.123Z", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "project-key-manifest.key_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "algorithm": "xchacha20-poly1305", + "device_envelope_path": "provenance/keys/device-envelope.json", + "recovery_envelope_path": "provenance/keys/recovery-envelope.json", + "recovery_verified_at": "2026-07-17T18:42:10.123Z", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "project-key-manifest.algorithm: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "key_id": "key_01J0000000000000000000000G", + "device_envelope_path": "provenance/keys/device-envelope.json", + "recovery_envelope_path": "provenance/keys/recovery-envelope.json", + "recovery_verified_at": "2026-07-17T18:42:10.123Z", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "project-key-manifest.device_envelope_path: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "key_id": "key_01J0000000000000000000000G", + "algorithm": "xchacha20-poly1305", + "recovery_envelope_path": "provenance/keys/recovery-envelope.json", + "recovery_verified_at": "2026-07-17T18:42:10.123Z", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "project-key-manifest.recovery_envelope_path: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "key_id": "key_01J0000000000000000000000G", + "algorithm": "xchacha20-poly1305", + "device_envelope_path": "provenance/keys/device-envelope.json", + "recovery_verified_at": "2026-07-17T18:42:10.123Z", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "project-key-manifest.recovery_verified_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "key_id": "key_01J0000000000000000000000G", + "algorithm": "xchacha20-poly1305", + "device_envelope_path": "provenance/keys/device-envelope.json", + "recovery_envelope_path": "provenance/keys/recovery-envelope.json", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "project-key-manifest.created_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "key_id": "key_01J0000000000000000000000G", + "algorithm": "xchacha20-poly1305", + "device_envelope_path": "provenance/keys/device-envelope.json", + "recovery_envelope_path": "provenance/keys/recovery-envelope.json", + "recovery_verified_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "project-key-manifest: reject unexpected property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "key_id": "key_01J0000000000000000000000G", + "algorithm": "xchacha20-poly1305", + "device_envelope_path": "provenance/keys/device-envelope.json", + "recovery_envelope_path": "provenance/keys/recovery-envelope.json", + "recovery_verified_at": "2026-07-17T18:42:10.123Z", + "created_at": "2026-07-17T18:42:10.123Z", + "__unexpected": true + } + }, + { + "description": "project-key-manifest.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "project_id": "project_01J00000000000000000000001", + "key_id": "key_01J0000000000000000000000G", + "algorithm": "xchacha20-poly1305", + "device_envelope_path": "provenance/keys/device-envelope.json", + "recovery_envelope_path": "provenance/keys/recovery-envelope.json", + "recovery_verified_at": "2026-07-17T18:42:10.123Z", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "project-key-manifest.project_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "project_id": "invalid-id", + "key_id": "key_01J0000000000000000000000G", + "algorithm": "xchacha20-poly1305", + "device_envelope_path": "provenance/keys/device-envelope.json", + "recovery_envelope_path": "provenance/keys/recovery-envelope.json", + "recovery_verified_at": "2026-07-17T18:42:10.123Z", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "project-key-manifest.key_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "key_id": "invalid-id", + "algorithm": "xchacha20-poly1305", + "device_envelope_path": "provenance/keys/device-envelope.json", + "recovery_envelope_path": "provenance/keys/recovery-envelope.json", + "recovery_verified_at": "2026-07-17T18:42:10.123Z", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "project-key-manifest.algorithm: reject value different from const", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "key_id": "key_01J0000000000000000000000G", + "algorithm": "__INVALID_CONST__", + "device_envelope_path": "provenance/keys/device-envelope.json", + "recovery_envelope_path": "provenance/keys/recovery-envelope.json", + "recovery_verified_at": "2026-07-17T18:42:10.123Z", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "project-key-manifest.device_envelope_path: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "key_id": "key_01J0000000000000000000000G", + "algorithm": "xchacha20-poly1305", + "device_envelope_path": "../outside-project", + "recovery_envelope_path": "provenance/keys/recovery-envelope.json", + "recovery_verified_at": "2026-07-17T18:42:10.123Z", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "project-key-manifest.device_envelope_path: reject string below minLength", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "key_id": "key_01J0000000000000000000000G", + "algorithm": "xchacha20-poly1305", + "device_envelope_path": "", + "recovery_envelope_path": "provenance/keys/recovery-envelope.json", + "recovery_verified_at": "2026-07-17T18:42:10.123Z", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "project-key-manifest.recovery_envelope_path: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "key_id": "key_01J0000000000000000000000G", + "algorithm": "xchacha20-poly1305", + "device_envelope_path": "provenance/keys/device-envelope.json", + "recovery_envelope_path": "../outside-project", + "recovery_verified_at": "2026-07-17T18:42:10.123Z", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "project-key-manifest.recovery_envelope_path: reject string below minLength", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "key_id": "key_01J0000000000000000000000G", + "algorithm": "xchacha20-poly1305", + "device_envelope_path": "provenance/keys/device-envelope.json", + "recovery_envelope_path": "", + "recovery_verified_at": "2026-07-17T18:42:10.123Z", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "project-key-manifest.recovery_verified_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "key_id": "key_01J0000000000000000000000G", + "algorithm": "xchacha20-poly1305", + "device_envelope_path": "provenance/keys/device-envelope.json", + "recovery_envelope_path": "provenance/keys/recovery-envelope.json", + "recovery_verified_at": "not-a-timestamp", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "project-key-manifest.created_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "key_id": "key_01J0000000000000000000000G", + "algorithm": "xchacha20-poly1305", + "device_envelope_path": "provenance/keys/device-envelope.json", + "recovery_envelope_path": "provenance/keys/recovery-envelope.json", + "recovery_verified_at": "2026-07-17T18:42:10.123Z", + "created_at": "not-a-timestamp" + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/project-manifest.invalid.json b/schemas/provenance/v1/fixtures/invalid/project-manifest.invalid.json new file mode 100644 index 0000000..0eba4db --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/project-manifest.invalid.json @@ -0,0 +1,311 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/project-manifest.schema.json", + "cases": [ + { + "description": "project-manifest.schema_version: reject missing required property", + "instance": { + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "title": "The Attention Commons", + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z", + "current_phase": "ideation", + "publication_status": "working", + "provenance_policy_id": "policy_01J0000000000000000000000H", + "audio_retained": false + } + }, + { + "description": "project-manifest.application_version: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "title": "The Attention Commons", + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z", + "current_phase": "ideation", + "publication_status": "working", + "provenance_policy_id": "policy_01J0000000000000000000000H", + "audio_retained": false + } + }, + { + "description": "project-manifest.project_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "title": "The Attention Commons", + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z", + "current_phase": "ideation", + "publication_status": "working", + "provenance_policy_id": "policy_01J0000000000000000000000H", + "audio_retained": false + } + }, + { + "description": "project-manifest.title: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z", + "current_phase": "ideation", + "publication_status": "working", + "provenance_policy_id": "policy_01J0000000000000000000000H", + "audio_retained": false + } + }, + { + "description": "project-manifest.created_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "title": "The Attention Commons", + "updated_at": "2026-07-17T18:43:11.456Z", + "current_phase": "ideation", + "publication_status": "working", + "provenance_policy_id": "policy_01J0000000000000000000000H", + "audio_retained": false + } + }, + { + "description": "project-manifest.updated_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "title": "The Attention Commons", + "created_at": "2026-07-17T18:42:10.123Z", + "current_phase": "ideation", + "publication_status": "working", + "provenance_policy_id": "policy_01J0000000000000000000000H", + "audio_retained": false + } + }, + { + "description": "project-manifest.current_phase: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "title": "The Attention Commons", + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z", + "publication_status": "working", + "provenance_policy_id": "policy_01J0000000000000000000000H", + "audio_retained": false + } + }, + { + "description": "project-manifest.publication_status: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "title": "The Attention Commons", + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z", + "current_phase": "ideation", + "provenance_policy_id": "policy_01J0000000000000000000000H", + "audio_retained": false + } + }, + { + "description": "project-manifest.provenance_policy_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "title": "The Attention Commons", + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z", + "current_phase": "ideation", + "publication_status": "working", + "audio_retained": false + } + }, + { + "description": "project-manifest.audio_retained: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "title": "The Attention Commons", + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z", + "current_phase": "ideation", + "publication_status": "working", + "provenance_policy_id": "policy_01J0000000000000000000000H" + } + }, + { + "description": "project-manifest: reject unexpected property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "title": "The Attention Commons", + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z", + "current_phase": "ideation", + "publication_status": "working", + "provenance_policy_id": "policy_01J0000000000000000000000H", + "audio_retained": false, + "__unexpected": true + } + }, + { + "description": "project-manifest.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "title": "The Attention Commons", + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z", + "current_phase": "ideation", + "publication_status": "working", + "provenance_policy_id": "policy_01J0000000000000000000000H", + "audio_retained": false + } + }, + { + "description": "project-manifest.application_version: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "application_version": " invalid!", + "project_id": "project_01J00000000000000000000001", + "title": "The Attention Commons", + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z", + "current_phase": "ideation", + "publication_status": "working", + "provenance_policy_id": "policy_01J0000000000000000000000H", + "audio_retained": false + } + }, + { + "description": "project-manifest.project_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "invalid-id", + "title": "The Attention Commons", + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z", + "current_phase": "ideation", + "publication_status": "working", + "provenance_policy_id": "policy_01J0000000000000000000000H", + "audio_retained": false + } + }, + { + "description": "project-manifest.title: reject string below minLength", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "title": "", + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z", + "current_phase": "ideation", + "publication_status": "working", + "provenance_policy_id": "policy_01J0000000000000000000000H", + "audio_retained": false + } + }, + { + "description": "project-manifest.created_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "title": "The Attention Commons", + "created_at": "not-a-timestamp", + "updated_at": "2026-07-17T18:43:11.456Z", + "current_phase": "ideation", + "publication_status": "working", + "provenance_policy_id": "policy_01J0000000000000000000000H", + "audio_retained": false + } + }, + { + "description": "project-manifest.updated_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "title": "The Attention Commons", + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "not-a-timestamp", + "current_phase": "ideation", + "publication_status": "working", + "provenance_policy_id": "policy_01J0000000000000000000000H", + "audio_retained": false + } + }, + { + "description": "project-manifest.current_phase: reject value outside enum", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "title": "The Attention Commons", + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z", + "current_phase": "__INVALID_ENUM__", + "publication_status": "working", + "provenance_policy_id": "policy_01J0000000000000000000000H", + "audio_retained": false + } + }, + { + "description": "project-manifest.publication_status: reject value outside enum", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "title": "The Attention Commons", + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z", + "current_phase": "ideation", + "publication_status": "__INVALID_ENUM__", + "provenance_policy_id": "policy_01J0000000000000000000000H", + "audio_retained": false + } + }, + { + "description": "project-manifest.provenance_policy_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "title": "The Attention Commons", + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z", + "current_phase": "ideation", + "publication_status": "working", + "provenance_policy_id": "invalid-id", + "audio_retained": false + } + }, + { + "description": "project-manifest.audio_retained: reject value different from const", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "title": "The Attention Commons", + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z", + "current_phase": "ideation", + "publication_status": "working", + "provenance_policy_id": "policy_01J0000000000000000000000H", + "audio_retained": true + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/prompt-template-reference.invalid.json b/schemas/provenance/v1/fixtures/invalid/prompt-template-reference.invalid.json new file mode 100644 index 0000000..f838c5d --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/prompt-template-reference.invalid.json @@ -0,0 +1,121 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/prompt-template-reference.schema.json", + "cases": [ + { + "description": "prompt-template-reference.schema_version: reject missing required property", + "instance": { + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + } + }, + { + "description": "prompt-template-reference.template_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + } + }, + { + "description": "prompt-template-reference.version: reject missing required property", + "instance": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + } + }, + { + "description": "prompt-template-reference.path: reject missing required property", + "instance": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + } + }, + { + "description": "prompt-template-reference.template_sha256: reject missing required property", + "instance": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json" + } + }, + { + "description": "prompt-template-reference: reject unexpected property", + "instance": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777", + "__unexpected": true + } + }, + { + "description": "prompt-template-reference.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + } + }, + { + "description": "prompt-template-reference.template_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "template_id": "invalid-id", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + } + }, + { + "description": "prompt-template-reference.version: reject value below minimum", + "instance": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 0, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + } + }, + { + "description": "prompt-template-reference.path: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "../outside-project", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + } + }, + { + "description": "prompt-template-reference.path: reject string below minLength", + "instance": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + } + }, + { + "description": "prompt-template-reference.template_sha256: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:INVALID" + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/prompt-template.invalid.json b/schemas/provenance/v1/fixtures/invalid/prompt-template.invalid.json new file mode 100644 index 0000000..8f8c219 --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/prompt-template.invalid.json @@ -0,0 +1,391 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/prompt-template.schema.json", + "cases": [ + { + "description": "prompt-template.schema_version: reject missing required property", + "instance": { + "template_id": "template_01J0000000000000000000000F", + "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": "sha256:7777777777777777777777777777777777777777777777777777777777777777", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "prompt-template.template_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "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": "sha256:7777777777777777777777777777777777777777777777777777777777777777", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "prompt-template.version: reject missing required property", + "instance": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "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": "sha256:7777777777777777777777777777777777777777777777777777777777777777", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "prompt-template.purpose: reject missing required property", + "instance": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "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": "sha256:7777777777777777777777777777777777777777777777777777777777777777", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "prompt-template.canonical_template_body: reject missing required property", + "instance": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "purpose": "draft_from_selected_ideas", + "variables": { + "context": { + "description": "Selected idea context", + "required": true + } + }, + "creation_application_version": "0.3.0", + "retention_classification": "project_record", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "prompt-template.variables: reject missing required property", + "instance": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "purpose": "draft_from_selected_ideas", + "canonical_template_body": "Use {{context}} to draft a passage.", + "creation_application_version": "0.3.0", + "retention_classification": "project_record", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "prompt-template.creation_application_version: reject missing required property", + "instance": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "purpose": "draft_from_selected_ideas", + "canonical_template_body": "Use {{context}} to draft a passage.", + "variables": { + "context": { + "description": "Selected idea context", + "required": true + } + }, + "retention_classification": "project_record", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "prompt-template.retention_classification: reject missing required property", + "instance": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "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", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "prompt-template.template_sha256: reject missing required property", + "instance": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "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", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "prompt-template.created_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "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": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + } + }, + { + "description": "prompt-template: reject unexpected property", + "instance": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "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": "sha256:7777777777777777777777777777777777777777777777777777777777777777", + "created_at": "2026-07-17T18:42:10.123Z", + "__unexpected": true + } + }, + { + "description": "prompt-template.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "template_id": "template_01J0000000000000000000000F", + "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": "sha256:7777777777777777777777777777777777777777777777777777777777777777", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "prompt-template.template_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "template_id": "invalid-id", + "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": "sha256:7777777777777777777777777777777777777777777777777777777777777777", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "prompt-template.version: reject value below minimum", + "instance": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 0, + "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": "sha256:7777777777777777777777777777777777777777777777777777777777777777", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "prompt-template.purpose: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "purpose": " invalid!", + "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": "sha256:7777777777777777777777777777777777777777777777777777777777777777", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "prompt-template.canonical_template_body: reject string below minLength", + "instance": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "purpose": "draft_from_selected_ideas", + "canonical_template_body": "", + "variables": { + "context": { + "description": "Selected idea context", + "required": true + } + }, + "creation_application_version": "0.3.0", + "retention_classification": "project_record", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "prompt-template.creation_application_version: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "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": " invalid!", + "retention_classification": "project_record", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "prompt-template.retention_classification: reject value outside enum", + "instance": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "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": "__INVALID_ENUM__", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "prompt-template.template_sha256: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "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": "sha256:INVALID", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "prompt-template.created_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "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": "sha256:7777777777777777777777777777777777777777777777777777777777777777", + "created_at": "not-a-timestamp" + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/provenance-event.invalid.json b/schemas/provenance/v1/fixtures/invalid/provenance-event.invalid.json new file mode 100644 index 0000000..8b33545 --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/provenance-event.invalid.json @@ -0,0 +1,2795 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/provenance-event.schema.json", + "cases": [ + { + "description": "provenance-event.schema_version: reject missing required property", + "instance": { + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.event_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.event_sequence: reject missing required property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.client_action_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.project_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.timestamp: reject missing required property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.event_type: reject missing required property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.actor: reject missing required property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.provider: reject missing required property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.inputs: reject missing required property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.outputs: reject missing required property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.relationships: reject missing required property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.metadata: reject missing required property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.previous_event_hash: reject missing required property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.event_hash: reject missing required property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null + } + }, + { + "description": "provenance-event: reject unexpected property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "__unexpected": true + } + }, + { + "description": "provenance-event.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.event_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "event_id": "invalid-id", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.event_sequence: reject value below minimum", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 0, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.client_action_id: reject string below minLength", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.client_action_id: reject string above maxLength", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.project_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "invalid-id", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.timestamp: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "not-a-timestamp", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.event_type: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": " invalid!", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.actor.type: reject missing required property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.actor.actor_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user" + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.actor: reject unexpected property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null, + "__unexpected": true + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.actor.type: reject value outside enum", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "__INVALID_ENUM__", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.outputs[0].schema_version: reject missing required property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.outputs[0].record_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.outputs[0].record_type: reject missing required property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.outputs[0].sha256: reject missing required property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.outputs[0].path: reject missing required property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.outputs[0].revision_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.outputs[0].range: reject missing required property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A" + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.outputs[0]: reject unexpected property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + }, + "__unexpected": true + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.outputs[0].schema_version: reject value different from const", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "__INVALID_CONST__", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.outputs[0].record_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "invalid-id", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.outputs[0].record_type: reject value outside enum", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "__INVALID_ENUM__", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.outputs[0].sha256: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:INVALID", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.outputs[0].path: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "../outside-project", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.outputs[0].path: reject string below minLength", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.outputs[0].revision_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "invalid-id", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.outputs[0].range.schema_version: reject missing required property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.outputs[0].range.document_revision_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.outputs[0].range.coordinate_system: reject missing required property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.outputs[0].range.start: reject missing required property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.outputs[0].range.end: reject missing required property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.outputs[0].range.preimage_sha256: reject missing required property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.outputs[0].range.text_fragment_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.outputs[0].range: reject unexpected property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C", + "__unexpected": true + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.outputs[0].range.schema_version: reject value different from const", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "__INVALID_CONST__", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.outputs[0].range.document_revision_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "invalid-id", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.outputs[0].range.coordinate_system: reject value outside enum", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "__INVALID_ENUM__", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.outputs[0].range.start: reject value below minimum", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": -1, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.outputs[0].range.end: reject value below minimum", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": -1, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.outputs[0].range.preimage_sha256: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:INVALID", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.outputs[0].range.text_fragment_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "invalid-id" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.relationships.parent_event_ids: reject missing required property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.relationships.invocation_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [] + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.relationships: reject unexpected property", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null, + "__unexpected": true + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + }, + { + "description": "provenance-event.event_hash: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:INVALID" + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/provenance-policy.invalid.json b/schemas/provenance/v1/fixtures/invalid/provenance-policy.invalid.json new file mode 100644 index 0000000..6c45d02 --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/provenance-policy.invalid.json @@ -0,0 +1,179 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/provenance-policy.schema.json", + "cases": [ + { + "description": "provenance-policy.schema_version: reject missing required property", + "instance": { + "policy_id": "policy_01J0000000000000000000000H", + "project_id": "project_01J00000000000000000000001", + "retention_mode": "minimal", + "encryption_mode": "none", + "default_export_profile": "sanitized", + "effective_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "provenance-policy.policy_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "retention_mode": "minimal", + "encryption_mode": "none", + "default_export_profile": "sanitized", + "effective_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "provenance-policy.project_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "policy_id": "policy_01J0000000000000000000000H", + "retention_mode": "minimal", + "encryption_mode": "none", + "default_export_profile": "sanitized", + "effective_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "provenance-policy.retention_mode: reject missing required property", + "instance": { + "schema_version": "1.0", + "policy_id": "policy_01J0000000000000000000000H", + "project_id": "project_01J00000000000000000000001", + "encryption_mode": "none", + "default_export_profile": "sanitized", + "effective_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "provenance-policy.encryption_mode: reject missing required property", + "instance": { + "schema_version": "1.0", + "policy_id": "policy_01J0000000000000000000000H", + "project_id": "project_01J00000000000000000000001", + "retention_mode": "minimal", + "default_export_profile": "sanitized", + "effective_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "provenance-policy.default_export_profile: reject missing required property", + "instance": { + "schema_version": "1.0", + "policy_id": "policy_01J0000000000000000000000H", + "project_id": "project_01J00000000000000000000001", + "retention_mode": "minimal", + "encryption_mode": "none", + "effective_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "provenance-policy.effective_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "policy_id": "policy_01J0000000000000000000000H", + "project_id": "project_01J00000000000000000000001", + "retention_mode": "minimal", + "encryption_mode": "none", + "default_export_profile": "sanitized" + } + }, + { + "description": "provenance-policy: reject unexpected property", + "instance": { + "schema_version": "1.0", + "policy_id": "policy_01J0000000000000000000000H", + "project_id": "project_01J00000000000000000000001", + "retention_mode": "minimal", + "encryption_mode": "none", + "default_export_profile": "sanitized", + "effective_at": "2026-07-17T18:42:10.123Z", + "__unexpected": true + } + }, + { + "description": "provenance-policy.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "policy_id": "policy_01J0000000000000000000000H", + "project_id": "project_01J00000000000000000000001", + "retention_mode": "minimal", + "encryption_mode": "none", + "default_export_profile": "sanitized", + "effective_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "provenance-policy.policy_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "policy_id": "invalid-id", + "project_id": "project_01J00000000000000000000001", + "retention_mode": "minimal", + "encryption_mode": "none", + "default_export_profile": "sanitized", + "effective_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "provenance-policy.project_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "policy_id": "policy_01J0000000000000000000000H", + "project_id": "invalid-id", + "retention_mode": "minimal", + "encryption_mode": "none", + "default_export_profile": "sanitized", + "effective_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "provenance-policy.retention_mode: reject value outside enum", + "instance": { + "schema_version": "1.0", + "policy_id": "policy_01J0000000000000000000000H", + "project_id": "project_01J00000000000000000000001", + "retention_mode": "__INVALID_ENUM__", + "encryption_mode": "none", + "default_export_profile": "sanitized", + "effective_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "provenance-policy.encryption_mode: reject value outside enum", + "instance": { + "schema_version": "1.0", + "policy_id": "policy_01J0000000000000000000000H", + "project_id": "project_01J00000000000000000000001", + "retention_mode": "minimal", + "encryption_mode": "__INVALID_ENUM__", + "default_export_profile": "sanitized", + "effective_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "provenance-policy.default_export_profile: reject value outside enum", + "instance": { + "schema_version": "1.0", + "policy_id": "policy_01J0000000000000000000000H", + "project_id": "project_01J00000000000000000000001", + "retention_mode": "minimal", + "encryption_mode": "none", + "default_export_profile": "__INVALID_ENUM__", + "effective_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "provenance-policy.effective_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "policy_id": "policy_01J0000000000000000000000H", + "project_id": "project_01J00000000000000000000001", + "retention_mode": "minimal", + "encryption_mode": "none", + "default_export_profile": "sanitized", + "effective_at": "not-a-timestamp" + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/purge-manifest.invalid.json b/schemas/provenance/v1/fixtures/invalid/purge-manifest.invalid.json new file mode 100644 index 0000000..a879f0c --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/purge-manifest.invalid.json @@ -0,0 +1,625 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/purge-manifest.schema.json", + "cases": [ + { + "description": "purge-manifest.schema_version: reject missing required property", + "instance": { + "purge_id": "purge_01J0000000000000000000000R", + "project_id": "project_01J00000000000000000000001", + "requested_at": "2026-07-17T18:42:10.123Z", + "completed_at": "2026-07-17T18:43:11.456Z", + "reason": "Remove accidentally retained credential", + "superseded_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "new_chain_root": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "affected_record_ids": [ + "record_01J00000000000000000000005" + ], + "affected_paths": [ + "records/invocations/request.json" + ], + "git_history_rewritten": true, + "prior_copies_revocable": false, + "confirmation_phrase_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + } + }, + { + "description": "purge-manifest.purge_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "requested_at": "2026-07-17T18:42:10.123Z", + "completed_at": "2026-07-17T18:43:11.456Z", + "reason": "Remove accidentally retained credential", + "superseded_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "new_chain_root": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "affected_record_ids": [ + "record_01J00000000000000000000005" + ], + "affected_paths": [ + "records/invocations/request.json" + ], + "git_history_rewritten": true, + "prior_copies_revocable": false, + "confirmation_phrase_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + } + }, + { + "description": "purge-manifest.project_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "purge_id": "purge_01J0000000000000000000000R", + "requested_at": "2026-07-17T18:42:10.123Z", + "completed_at": "2026-07-17T18:43:11.456Z", + "reason": "Remove accidentally retained credential", + "superseded_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "new_chain_root": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "affected_record_ids": [ + "record_01J00000000000000000000005" + ], + "affected_paths": [ + "records/invocations/request.json" + ], + "git_history_rewritten": true, + "prior_copies_revocable": false, + "confirmation_phrase_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + } + }, + { + "description": "purge-manifest.requested_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "purge_id": "purge_01J0000000000000000000000R", + "project_id": "project_01J00000000000000000000001", + "completed_at": "2026-07-17T18:43:11.456Z", + "reason": "Remove accidentally retained credential", + "superseded_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "new_chain_root": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "affected_record_ids": [ + "record_01J00000000000000000000005" + ], + "affected_paths": [ + "records/invocations/request.json" + ], + "git_history_rewritten": true, + "prior_copies_revocable": false, + "confirmation_phrase_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + } + }, + { + "description": "purge-manifest.completed_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "purge_id": "purge_01J0000000000000000000000R", + "project_id": "project_01J00000000000000000000001", + "requested_at": "2026-07-17T18:42:10.123Z", + "reason": "Remove accidentally retained credential", + "superseded_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "new_chain_root": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "affected_record_ids": [ + "record_01J00000000000000000000005" + ], + "affected_paths": [ + "records/invocations/request.json" + ], + "git_history_rewritten": true, + "prior_copies_revocable": false, + "confirmation_phrase_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + } + }, + { + "description": "purge-manifest.reason: reject missing required property", + "instance": { + "schema_version": "1.0", + "purge_id": "purge_01J0000000000000000000000R", + "project_id": "project_01J00000000000000000000001", + "requested_at": "2026-07-17T18:42:10.123Z", + "completed_at": "2026-07-17T18:43:11.456Z", + "superseded_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "new_chain_root": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "affected_record_ids": [ + "record_01J00000000000000000000005" + ], + "affected_paths": [ + "records/invocations/request.json" + ], + "git_history_rewritten": true, + "prior_copies_revocable": false, + "confirmation_phrase_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + } + }, + { + "description": "purge-manifest.superseded_chain_head: reject missing required property", + "instance": { + "schema_version": "1.0", + "purge_id": "purge_01J0000000000000000000000R", + "project_id": "project_01J00000000000000000000001", + "requested_at": "2026-07-17T18:42:10.123Z", + "completed_at": "2026-07-17T18:43:11.456Z", + "reason": "Remove accidentally retained credential", + "new_chain_root": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "affected_record_ids": [ + "record_01J00000000000000000000005" + ], + "affected_paths": [ + "records/invocations/request.json" + ], + "git_history_rewritten": true, + "prior_copies_revocable": false, + "confirmation_phrase_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + } + }, + { + "description": "purge-manifest.new_chain_root: reject missing required property", + "instance": { + "schema_version": "1.0", + "purge_id": "purge_01J0000000000000000000000R", + "project_id": "project_01J00000000000000000000001", + "requested_at": "2026-07-17T18:42:10.123Z", + "completed_at": "2026-07-17T18:43:11.456Z", + "reason": "Remove accidentally retained credential", + "superseded_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "affected_record_ids": [ + "record_01J00000000000000000000005" + ], + "affected_paths": [ + "records/invocations/request.json" + ], + "git_history_rewritten": true, + "prior_copies_revocable": false, + "confirmation_phrase_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + } + }, + { + "description": "purge-manifest.affected_record_ids: reject missing required property", + "instance": { + "schema_version": "1.0", + "purge_id": "purge_01J0000000000000000000000R", + "project_id": "project_01J00000000000000000000001", + "requested_at": "2026-07-17T18:42:10.123Z", + "completed_at": "2026-07-17T18:43:11.456Z", + "reason": "Remove accidentally retained credential", + "superseded_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "new_chain_root": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "affected_paths": [ + "records/invocations/request.json" + ], + "git_history_rewritten": true, + "prior_copies_revocable": false, + "confirmation_phrase_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + } + }, + { + "description": "purge-manifest.affected_paths: reject missing required property", + "instance": { + "schema_version": "1.0", + "purge_id": "purge_01J0000000000000000000000R", + "project_id": "project_01J00000000000000000000001", + "requested_at": "2026-07-17T18:42:10.123Z", + "completed_at": "2026-07-17T18:43:11.456Z", + "reason": "Remove accidentally retained credential", + "superseded_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "new_chain_root": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "affected_record_ids": [ + "record_01J00000000000000000000005" + ], + "git_history_rewritten": true, + "prior_copies_revocable": false, + "confirmation_phrase_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + } + }, + { + "description": "purge-manifest.git_history_rewritten: reject missing required property", + "instance": { + "schema_version": "1.0", + "purge_id": "purge_01J0000000000000000000000R", + "project_id": "project_01J00000000000000000000001", + "requested_at": "2026-07-17T18:42:10.123Z", + "completed_at": "2026-07-17T18:43:11.456Z", + "reason": "Remove accidentally retained credential", + "superseded_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "new_chain_root": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "affected_record_ids": [ + "record_01J00000000000000000000005" + ], + "affected_paths": [ + "records/invocations/request.json" + ], + "prior_copies_revocable": false, + "confirmation_phrase_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + } + }, + { + "description": "purge-manifest.prior_copies_revocable: reject missing required property", + "instance": { + "schema_version": "1.0", + "purge_id": "purge_01J0000000000000000000000R", + "project_id": "project_01J00000000000000000000001", + "requested_at": "2026-07-17T18:42:10.123Z", + "completed_at": "2026-07-17T18:43:11.456Z", + "reason": "Remove accidentally retained credential", + "superseded_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "new_chain_root": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "affected_record_ids": [ + "record_01J00000000000000000000005" + ], + "affected_paths": [ + "records/invocations/request.json" + ], + "git_history_rewritten": true, + "confirmation_phrase_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + } + }, + { + "description": "purge-manifest.confirmation_phrase_sha256: reject missing required property", + "instance": { + "schema_version": "1.0", + "purge_id": "purge_01J0000000000000000000000R", + "project_id": "project_01J00000000000000000000001", + "requested_at": "2026-07-17T18:42:10.123Z", + "completed_at": "2026-07-17T18:43:11.456Z", + "reason": "Remove accidentally retained credential", + "superseded_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "new_chain_root": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "affected_record_ids": [ + "record_01J00000000000000000000005" + ], + "affected_paths": [ + "records/invocations/request.json" + ], + "git_history_rewritten": true, + "prior_copies_revocable": false + } + }, + { + "description": "purge-manifest: reject unexpected property", + "instance": { + "schema_version": "1.0", + "purge_id": "purge_01J0000000000000000000000R", + "project_id": "project_01J00000000000000000000001", + "requested_at": "2026-07-17T18:42:10.123Z", + "completed_at": "2026-07-17T18:43:11.456Z", + "reason": "Remove accidentally retained credential", + "superseded_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "new_chain_root": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "affected_record_ids": [ + "record_01J00000000000000000000005" + ], + "affected_paths": [ + "records/invocations/request.json" + ], + "git_history_rewritten": true, + "prior_copies_revocable": false, + "confirmation_phrase_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "__unexpected": true + } + }, + { + "description": "purge-manifest.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "purge_id": "purge_01J0000000000000000000000R", + "project_id": "project_01J00000000000000000000001", + "requested_at": "2026-07-17T18:42:10.123Z", + "completed_at": "2026-07-17T18:43:11.456Z", + "reason": "Remove accidentally retained credential", + "superseded_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "new_chain_root": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "affected_record_ids": [ + "record_01J00000000000000000000005" + ], + "affected_paths": [ + "records/invocations/request.json" + ], + "git_history_rewritten": true, + "prior_copies_revocable": false, + "confirmation_phrase_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + } + }, + { + "description": "purge-manifest.purge_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "purge_id": "invalid-id", + "project_id": "project_01J00000000000000000000001", + "requested_at": "2026-07-17T18:42:10.123Z", + "completed_at": "2026-07-17T18:43:11.456Z", + "reason": "Remove accidentally retained credential", + "superseded_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "new_chain_root": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "affected_record_ids": [ + "record_01J00000000000000000000005" + ], + "affected_paths": [ + "records/invocations/request.json" + ], + "git_history_rewritten": true, + "prior_copies_revocable": false, + "confirmation_phrase_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + } + }, + { + "description": "purge-manifest.project_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "purge_id": "purge_01J0000000000000000000000R", + "project_id": "invalid-id", + "requested_at": "2026-07-17T18:42:10.123Z", + "completed_at": "2026-07-17T18:43:11.456Z", + "reason": "Remove accidentally retained credential", + "superseded_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "new_chain_root": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "affected_record_ids": [ + "record_01J00000000000000000000005" + ], + "affected_paths": [ + "records/invocations/request.json" + ], + "git_history_rewritten": true, + "prior_copies_revocable": false, + "confirmation_phrase_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + } + }, + { + "description": "purge-manifest.requested_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "purge_id": "purge_01J0000000000000000000000R", + "project_id": "project_01J00000000000000000000001", + "requested_at": "not-a-timestamp", + "completed_at": "2026-07-17T18:43:11.456Z", + "reason": "Remove accidentally retained credential", + "superseded_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "new_chain_root": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "affected_record_ids": [ + "record_01J00000000000000000000005" + ], + "affected_paths": [ + "records/invocations/request.json" + ], + "git_history_rewritten": true, + "prior_copies_revocable": false, + "confirmation_phrase_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + } + }, + { + "description": "purge-manifest.completed_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "purge_id": "purge_01J0000000000000000000000R", + "project_id": "project_01J00000000000000000000001", + "requested_at": "2026-07-17T18:42:10.123Z", + "completed_at": "not-a-timestamp", + "reason": "Remove accidentally retained credential", + "superseded_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "new_chain_root": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "affected_record_ids": [ + "record_01J00000000000000000000005" + ], + "affected_paths": [ + "records/invocations/request.json" + ], + "git_history_rewritten": true, + "prior_copies_revocable": false, + "confirmation_phrase_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + } + }, + { + "description": "purge-manifest.reason: reject string below minLength", + "instance": { + "schema_version": "1.0", + "purge_id": "purge_01J0000000000000000000000R", + "project_id": "project_01J00000000000000000000001", + "requested_at": "2026-07-17T18:42:10.123Z", + "completed_at": "2026-07-17T18:43:11.456Z", + "reason": "", + "superseded_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "new_chain_root": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "affected_record_ids": [ + "record_01J00000000000000000000005" + ], + "affected_paths": [ + "records/invocations/request.json" + ], + "git_history_rewritten": true, + "prior_copies_revocable": false, + "confirmation_phrase_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + } + }, + { + "description": "purge-manifest.superseded_chain_head: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "purge_id": "purge_01J0000000000000000000000R", + "project_id": "project_01J00000000000000000000001", + "requested_at": "2026-07-17T18:42:10.123Z", + "completed_at": "2026-07-17T18:43:11.456Z", + "reason": "Remove accidentally retained credential", + "superseded_chain_head": "sha256:INVALID", + "new_chain_root": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "affected_record_ids": [ + "record_01J00000000000000000000005" + ], + "affected_paths": [ + "records/invocations/request.json" + ], + "git_history_rewritten": true, + "prior_copies_revocable": false, + "confirmation_phrase_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + } + }, + { + "description": "purge-manifest.new_chain_root: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "purge_id": "purge_01J0000000000000000000000R", + "project_id": "project_01J00000000000000000000001", + "requested_at": "2026-07-17T18:42:10.123Z", + "completed_at": "2026-07-17T18:43:11.456Z", + "reason": "Remove accidentally retained credential", + "superseded_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "new_chain_root": "sha256:INVALID", + "affected_record_ids": [ + "record_01J00000000000000000000005" + ], + "affected_paths": [ + "records/invocations/request.json" + ], + "git_history_rewritten": true, + "prior_copies_revocable": false, + "confirmation_phrase_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + } + }, + { + "description": "purge-manifest.affected_record_ids: reject array below minItems", + "instance": { + "schema_version": "1.0", + "purge_id": "purge_01J0000000000000000000000R", + "project_id": "project_01J00000000000000000000001", + "requested_at": "2026-07-17T18:42:10.123Z", + "completed_at": "2026-07-17T18:43:11.456Z", + "reason": "Remove accidentally retained credential", + "superseded_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "new_chain_root": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "affected_record_ids": [], + "affected_paths": [ + "records/invocations/request.json" + ], + "git_history_rewritten": true, + "prior_copies_revocable": false, + "confirmation_phrase_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + } + }, + { + "description": "purge-manifest.affected_record_ids[0]: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "purge_id": "purge_01J0000000000000000000000R", + "project_id": "project_01J00000000000000000000001", + "requested_at": "2026-07-17T18:42:10.123Z", + "completed_at": "2026-07-17T18:43:11.456Z", + "reason": "Remove accidentally retained credential", + "superseded_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "new_chain_root": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "affected_record_ids": [ + "invalid-id" + ], + "affected_paths": [ + "records/invocations/request.json" + ], + "git_history_rewritten": true, + "prior_copies_revocable": false, + "confirmation_phrase_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + } + }, + { + "description": "purge-manifest.affected_paths[0]: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "purge_id": "purge_01J0000000000000000000000R", + "project_id": "project_01J00000000000000000000001", + "requested_at": "2026-07-17T18:42:10.123Z", + "completed_at": "2026-07-17T18:43:11.456Z", + "reason": "Remove accidentally retained credential", + "superseded_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "new_chain_root": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "affected_record_ids": [ + "record_01J00000000000000000000005" + ], + "affected_paths": [ + "../outside-project" + ], + "git_history_rewritten": true, + "prior_copies_revocable": false, + "confirmation_phrase_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + } + }, + { + "description": "purge-manifest.affected_paths[0]: reject string below minLength", + "instance": { + "schema_version": "1.0", + "purge_id": "purge_01J0000000000000000000000R", + "project_id": "project_01J00000000000000000000001", + "requested_at": "2026-07-17T18:42:10.123Z", + "completed_at": "2026-07-17T18:43:11.456Z", + "reason": "Remove accidentally retained credential", + "superseded_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "new_chain_root": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "affected_record_ids": [ + "record_01J00000000000000000000005" + ], + "affected_paths": [ + "" + ], + "git_history_rewritten": true, + "prior_copies_revocable": false, + "confirmation_phrase_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + } + }, + { + "description": "purge-manifest.git_history_rewritten: reject value different from const", + "instance": { + "schema_version": "1.0", + "purge_id": "purge_01J0000000000000000000000R", + "project_id": "project_01J00000000000000000000001", + "requested_at": "2026-07-17T18:42:10.123Z", + "completed_at": "2026-07-17T18:43:11.456Z", + "reason": "Remove accidentally retained credential", + "superseded_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "new_chain_root": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "affected_record_ids": [ + "record_01J00000000000000000000005" + ], + "affected_paths": [ + "records/invocations/request.json" + ], + "git_history_rewritten": false, + "prior_copies_revocable": false, + "confirmation_phrase_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + } + }, + { + "description": "purge-manifest.prior_copies_revocable: reject value different from const", + "instance": { + "schema_version": "1.0", + "purge_id": "purge_01J0000000000000000000000R", + "project_id": "project_01J00000000000000000000001", + "requested_at": "2026-07-17T18:42:10.123Z", + "completed_at": "2026-07-17T18:43:11.456Z", + "reason": "Remove accidentally retained credential", + "superseded_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "new_chain_root": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "affected_record_ids": [ + "record_01J00000000000000000000005" + ], + "affected_paths": [ + "records/invocations/request.json" + ], + "git_history_rewritten": true, + "prior_copies_revocable": true, + "confirmation_phrase_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + } + }, + { + "description": "purge-manifest.confirmation_phrase_sha256: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "purge_id": "purge_01J0000000000000000000000R", + "project_id": "project_01J00000000000000000000001", + "requested_at": "2026-07-17T18:42:10.123Z", + "completed_at": "2026-07-17T18:43:11.456Z", + "reason": "Remove accidentally retained credential", + "superseded_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "new_chain_root": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "affected_record_ids": [ + "record_01J00000000000000000000005" + ], + "affected_paths": [ + "records/invocations/request.json" + ], + "git_history_rewritten": true, + "prior_copies_revocable": false, + "confirmation_phrase_sha256": "sha256:INVALID" + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/record-envelope.invalid.json b/schemas/provenance/v1/fixtures/invalid/record-envelope.invalid.json new file mode 100644 index 0000000..2cfb7e6 --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/record-envelope.invalid.json @@ -0,0 +1,524 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/record-envelope.schema.json", + "cases": [ + { + "description": "record-envelope.schema_version: reject missing required property", + "instance": { + "project_id": "project_01J00000000000000000000001", + "record_id": "record_01J00000000000000000000005", + "record_type": "invocation_request", + "protection": "protected", + "plaintext_sha256": "sha256:97154eddff15ab6607181e55945547fdbbc5bde02b1e5123eade7a69509f00c5", + "payload": null, + "encryption": { + "algorithm": "xchacha20-poly1305", + "key_id": "key_01J0000000000000000000000G", + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "ciphertext": "ZW5jcnlwdGVkLXJlY29yZA==", + "ciphertext_sha256": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + } + } + }, + { + "description": "record-envelope.project_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "invocation_request", + "protection": "protected", + "plaintext_sha256": "sha256:97154eddff15ab6607181e55945547fdbbc5bde02b1e5123eade7a69509f00c5", + "payload": null, + "encryption": { + "algorithm": "xchacha20-poly1305", + "key_id": "key_01J0000000000000000000000G", + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "ciphertext": "ZW5jcnlwdGVkLXJlY29yZA==", + "ciphertext_sha256": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + } + } + }, + { + "description": "record-envelope.record_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "record_type": "invocation_request", + "protection": "protected", + "plaintext_sha256": "sha256:97154eddff15ab6607181e55945547fdbbc5bde02b1e5123eade7a69509f00c5", + "payload": null, + "encryption": { + "algorithm": "xchacha20-poly1305", + "key_id": "key_01J0000000000000000000000G", + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "ciphertext": "ZW5jcnlwdGVkLXJlY29yZA==", + "ciphertext_sha256": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + } + } + }, + { + "description": "record-envelope.record_type: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "record_id": "record_01J00000000000000000000005", + "protection": "protected", + "plaintext_sha256": "sha256:97154eddff15ab6607181e55945547fdbbc5bde02b1e5123eade7a69509f00c5", + "payload": null, + "encryption": { + "algorithm": "xchacha20-poly1305", + "key_id": "key_01J0000000000000000000000G", + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "ciphertext": "ZW5jcnlwdGVkLXJlY29yZA==", + "ciphertext_sha256": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + } + } + }, + { + "description": "record-envelope.protection: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "record_id": "record_01J00000000000000000000005", + "record_type": "invocation_request", + "plaintext_sha256": "sha256:97154eddff15ab6607181e55945547fdbbc5bde02b1e5123eade7a69509f00c5", + "payload": null, + "encryption": { + "algorithm": "xchacha20-poly1305", + "key_id": "key_01J0000000000000000000000G", + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "ciphertext": "ZW5jcnlwdGVkLXJlY29yZA==", + "ciphertext_sha256": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + } + } + }, + { + "description": "record-envelope.plaintext_sha256: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "record_id": "record_01J00000000000000000000005", + "record_type": "invocation_request", + "protection": "protected", + "payload": null, + "encryption": { + "algorithm": "xchacha20-poly1305", + "key_id": "key_01J0000000000000000000000G", + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "ciphertext": "ZW5jcnlwdGVkLXJlY29yZA==", + "ciphertext_sha256": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + } + } + }, + { + "description": "record-envelope.payload: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "record_id": "record_01J00000000000000000000005", + "record_type": "invocation_request", + "protection": "protected", + "plaintext_sha256": "sha256:97154eddff15ab6607181e55945547fdbbc5bde02b1e5123eade7a69509f00c5", + "encryption": { + "algorithm": "xchacha20-poly1305", + "key_id": "key_01J0000000000000000000000G", + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "ciphertext": "ZW5jcnlwdGVkLXJlY29yZA==", + "ciphertext_sha256": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + } + } + }, + { + "description": "record-envelope.encryption: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "record_id": "record_01J00000000000000000000005", + "record_type": "invocation_request", + "protection": "protected", + "plaintext_sha256": "sha256:97154eddff15ab6607181e55945547fdbbc5bde02b1e5123eade7a69509f00c5", + "payload": null + } + }, + { + "description": "record-envelope: reject unexpected property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "record_id": "record_01J00000000000000000000005", + "record_type": "invocation_request", + "protection": "protected", + "plaintext_sha256": "sha256:97154eddff15ab6607181e55945547fdbbc5bde02b1e5123eade7a69509f00c5", + "payload": null, + "encryption": { + "algorithm": "xchacha20-poly1305", + "key_id": "key_01J0000000000000000000000G", + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "ciphertext": "ZW5jcnlwdGVkLXJlY29yZA==", + "ciphertext_sha256": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + }, + "__unexpected": true + } + }, + { + "description": "record-envelope.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "project_id": "project_01J00000000000000000000001", + "record_id": "record_01J00000000000000000000005", + "record_type": "invocation_request", + "protection": "protected", + "plaintext_sha256": "sha256:97154eddff15ab6607181e55945547fdbbc5bde02b1e5123eade7a69509f00c5", + "payload": null, + "encryption": { + "algorithm": "xchacha20-poly1305", + "key_id": "key_01J0000000000000000000000G", + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "ciphertext": "ZW5jcnlwdGVkLXJlY29yZA==", + "ciphertext_sha256": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + } + } + }, + { + "description": "record-envelope.project_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "project_id": "invalid-id", + "record_id": "record_01J00000000000000000000005", + "record_type": "invocation_request", + "protection": "protected", + "plaintext_sha256": "sha256:97154eddff15ab6607181e55945547fdbbc5bde02b1e5123eade7a69509f00c5", + "payload": null, + "encryption": { + "algorithm": "xchacha20-poly1305", + "key_id": "key_01J0000000000000000000000G", + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "ciphertext": "ZW5jcnlwdGVkLXJlY29yZA==", + "ciphertext_sha256": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + } + } + }, + { + "description": "record-envelope.record_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "record_id": "invalid-id", + "record_type": "invocation_request", + "protection": "protected", + "plaintext_sha256": "sha256:97154eddff15ab6607181e55945547fdbbc5bde02b1e5123eade7a69509f00c5", + "payload": null, + "encryption": { + "algorithm": "xchacha20-poly1305", + "key_id": "key_01J0000000000000000000000G", + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "ciphertext": "ZW5jcnlwdGVkLXJlY29yZA==", + "ciphertext_sha256": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + } + } + }, + { + "description": "record-envelope.record_type: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "record_id": "record_01J00000000000000000000005", + "record_type": " invalid!", + "protection": "protected", + "plaintext_sha256": "sha256:97154eddff15ab6607181e55945547fdbbc5bde02b1e5123eade7a69509f00c5", + "payload": null, + "encryption": { + "algorithm": "xchacha20-poly1305", + "key_id": "key_01J0000000000000000000000G", + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "ciphertext": "ZW5jcnlwdGVkLXJlY29yZA==", + "ciphertext_sha256": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + } + } + }, + { + "description": "record-envelope.protection: reject value outside enum", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "record_id": "record_01J00000000000000000000005", + "record_type": "invocation_request", + "protection": "__INVALID_ENUM__", + "plaintext_sha256": "sha256:97154eddff15ab6607181e55945547fdbbc5bde02b1e5123eade7a69509f00c5", + "payload": null, + "encryption": { + "algorithm": "xchacha20-poly1305", + "key_id": "key_01J0000000000000000000000G", + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "ciphertext": "ZW5jcnlwdGVkLXJlY29yZA==", + "ciphertext_sha256": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + } + } + }, + { + "description": "record-envelope.plaintext_sha256: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "record_id": "record_01J00000000000000000000005", + "record_type": "invocation_request", + "protection": "protected", + "plaintext_sha256": "sha256:INVALID", + "payload": null, + "encryption": { + "algorithm": "xchacha20-poly1305", + "key_id": "key_01J0000000000000000000000G", + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "ciphertext": "ZW5jcnlwdGVkLXJlY29yZA==", + "ciphertext_sha256": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + } + } + }, + { + "description": "record-envelope.encryption.algorithm: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "record_id": "record_01J00000000000000000000005", + "record_type": "invocation_request", + "protection": "protected", + "plaintext_sha256": "sha256:97154eddff15ab6607181e55945547fdbbc5bde02b1e5123eade7a69509f00c5", + "payload": null, + "encryption": { + "key_id": "key_01J0000000000000000000000G", + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "ciphertext": "ZW5jcnlwdGVkLXJlY29yZA==", + "ciphertext_sha256": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + } + } + }, + { + "description": "record-envelope.encryption.key_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "record_id": "record_01J00000000000000000000005", + "record_type": "invocation_request", + "protection": "protected", + "plaintext_sha256": "sha256:97154eddff15ab6607181e55945547fdbbc5bde02b1e5123eade7a69509f00c5", + "payload": null, + "encryption": { + "algorithm": "xchacha20-poly1305", + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "ciphertext": "ZW5jcnlwdGVkLXJlY29yZA==", + "ciphertext_sha256": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + } + } + }, + { + "description": "record-envelope.encryption.nonce: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "record_id": "record_01J00000000000000000000005", + "record_type": "invocation_request", + "protection": "protected", + "plaintext_sha256": "sha256:97154eddff15ab6607181e55945547fdbbc5bde02b1e5123eade7a69509f00c5", + "payload": null, + "encryption": { + "algorithm": "xchacha20-poly1305", + "key_id": "key_01J0000000000000000000000G", + "ciphertext": "ZW5jcnlwdGVkLXJlY29yZA==", + "ciphertext_sha256": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + } + } + }, + { + "description": "record-envelope.encryption.ciphertext: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "record_id": "record_01J00000000000000000000005", + "record_type": "invocation_request", + "protection": "protected", + "plaintext_sha256": "sha256:97154eddff15ab6607181e55945547fdbbc5bde02b1e5123eade7a69509f00c5", + "payload": null, + "encryption": { + "algorithm": "xchacha20-poly1305", + "key_id": "key_01J0000000000000000000000G", + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "ciphertext_sha256": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + } + } + }, + { + "description": "record-envelope.encryption.ciphertext_sha256: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "record_id": "record_01J00000000000000000000005", + "record_type": "invocation_request", + "protection": "protected", + "plaintext_sha256": "sha256:97154eddff15ab6607181e55945547fdbbc5bde02b1e5123eade7a69509f00c5", + "payload": null, + "encryption": { + "algorithm": "xchacha20-poly1305", + "key_id": "key_01J0000000000000000000000G", + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "ciphertext": "ZW5jcnlwdGVkLXJlY29yZA==" + } + } + }, + { + "description": "record-envelope.encryption: reject unexpected property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "record_id": "record_01J00000000000000000000005", + "record_type": "invocation_request", + "protection": "protected", + "plaintext_sha256": "sha256:97154eddff15ab6607181e55945547fdbbc5bde02b1e5123eade7a69509f00c5", + "payload": null, + "encryption": { + "algorithm": "xchacha20-poly1305", + "key_id": "key_01J0000000000000000000000G", + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "ciphertext": "ZW5jcnlwdGVkLXJlY29yZA==", + "ciphertext_sha256": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "__unexpected": true + } + } + }, + { + "description": "record-envelope.encryption.algorithm: reject value different from const", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "record_id": "record_01J00000000000000000000005", + "record_type": "invocation_request", + "protection": "protected", + "plaintext_sha256": "sha256:97154eddff15ab6607181e55945547fdbbc5bde02b1e5123eade7a69509f00c5", + "payload": null, + "encryption": { + "algorithm": "__INVALID_CONST__", + "key_id": "key_01J0000000000000000000000G", + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "ciphertext": "ZW5jcnlwdGVkLXJlY29yZA==", + "ciphertext_sha256": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + } + } + }, + { + "description": "record-envelope.encryption.key_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "record_id": "record_01J00000000000000000000005", + "record_type": "invocation_request", + "protection": "protected", + "plaintext_sha256": "sha256:97154eddff15ab6607181e55945547fdbbc5bde02b1e5123eade7a69509f00c5", + "payload": null, + "encryption": { + "algorithm": "xchacha20-poly1305", + "key_id": "invalid-id", + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "ciphertext": "ZW5jcnlwdGVkLXJlY29yZA==", + "ciphertext_sha256": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + } + } + }, + { + "description": "record-envelope.encryption.nonce: reject string below minLength", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "record_id": "record_01J00000000000000000000005", + "record_type": "invocation_request", + "protection": "protected", + "plaintext_sha256": "sha256:97154eddff15ab6607181e55945547fdbbc5bde02b1e5123eade7a69509f00c5", + "payload": null, + "encryption": { + "algorithm": "xchacha20-poly1305", + "key_id": "key_01J0000000000000000000000G", + "nonce": "", + "ciphertext": "ZW5jcnlwdGVkLXJlY29yZA==", + "ciphertext_sha256": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + } + } + }, + { + "description": "record-envelope.encryption.ciphertext: reject string below minLength", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "record_id": "record_01J00000000000000000000005", + "record_type": "invocation_request", + "protection": "protected", + "plaintext_sha256": "sha256:97154eddff15ab6607181e55945547fdbbc5bde02b1e5123eade7a69509f00c5", + "payload": null, + "encryption": { + "algorithm": "xchacha20-poly1305", + "key_id": "key_01J0000000000000000000000G", + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "ciphertext": "", + "ciphertext_sha256": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + } + } + }, + { + "description": "record-envelope.encryption.ciphertext_sha256: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "record_id": "record_01J00000000000000000000005", + "record_type": "invocation_request", + "protection": "protected", + "plaintext_sha256": "sha256:97154eddff15ab6607181e55945547fdbbc5bde02b1e5123eade7a69509f00c5", + "payload": null, + "encryption": { + "algorithm": "xchacha20-poly1305", + "key_id": "key_01J0000000000000000000000G", + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "ciphertext": "ZW5jcnlwdGVkLXJlY29yZA==", + "ciphertext_sha256": "sha256:INVALID" + } + } + }, + { + "description": "record-envelope: protected payload must not remain plaintext", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "record_id": "record_01J00000000000000000000005", + "record_type": "invocation_request", + "protection": "protected", + "plaintext_sha256": "sha256:97154eddff15ab6607181e55945547fdbbc5bde02b1e5123eade7a69509f00c5", + "payload": { + "leaked": true + }, + "encryption": { + "algorithm": "xchacha20-poly1305", + "key_id": "key_01J0000000000000000000000G", + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "ciphertext": "ZW5jcnlwdGVkLXJlY29yZA==", + "ciphertext_sha256": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + } + } + }, + { + "description": "record-envelope: unprotected payload requires null encryption", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "record_id": "record_01J00000000000000000000005", + "record_type": "invocation_request", + "protection": "none", + "plaintext_sha256": "sha256:97154eddff15ab6607181e55945547fdbbc5bde02b1e5123eade7a69509f00c5", + "payload": { + "retained": true + }, + "encryption": { + "algorithm": "xchacha20-poly1305", + "key_id": "key_01J0000000000000000000000G", + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "ciphertext": "ZW5jcnlwdGVkLXJlY29yZA==", + "ciphertext_sha256": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + } + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/recovery-key-envelope.invalid.json b/schemas/provenance/v1/fixtures/invalid/recovery-key-envelope.invalid.json new file mode 100644 index 0000000..22cca63 --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/recovery-key-envelope.invalid.json @@ -0,0 +1,652 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/recovery-key-envelope.schema.json", + "cases": [ + { + "description": "recovery-key-envelope.schema_version: reject missing required property", + "instance": { + "envelope_id": "record_01J0000000000000000000000S", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "recovery", + "algorithm": "xchacha20-poly1305", + "key_derivation": { + "algorithm": "argon2id", + "memory_kib": 65536, + "iterations": 3, + "parallelism": 1, + "salt": "c2FsdC1mb3ItdGhpbmtsb29t" + }, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "recovery-key-envelope.envelope_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "recovery", + "algorithm": "xchacha20-poly1305", + "key_derivation": { + "algorithm": "argon2id", + "memory_kib": 65536, + "iterations": 3, + "parallelism": 1, + "salt": "c2FsdC1mb3ItdGhpbmtsb29t" + }, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "recovery-key-envelope.key_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J0000000000000000000000S", + "envelope_type": "recovery", + "algorithm": "xchacha20-poly1305", + "key_derivation": { + "algorithm": "argon2id", + "memory_kib": 65536, + "iterations": 3, + "parallelism": 1, + "salt": "c2FsdC1mb3ItdGhpbmtsb29t" + }, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "recovery-key-envelope.envelope_type: reject missing required property", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J0000000000000000000000S", + "key_id": "key_01J0000000000000000000000G", + "algorithm": "xchacha20-poly1305", + "key_derivation": { + "algorithm": "argon2id", + "memory_kib": 65536, + "iterations": 3, + "parallelism": 1, + "salt": "c2FsdC1mb3ItdGhpbmtsb29t" + }, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "recovery-key-envelope.algorithm: reject missing required property", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J0000000000000000000000S", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "recovery", + "key_derivation": { + "algorithm": "argon2id", + "memory_kib": 65536, + "iterations": 3, + "parallelism": 1, + "salt": "c2FsdC1mb3ItdGhpbmtsb29t" + }, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "recovery-key-envelope.key_derivation: reject missing required property", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J0000000000000000000000S", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "recovery", + "algorithm": "xchacha20-poly1305", + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "recovery-key-envelope.nonce: reject missing required property", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J0000000000000000000000S", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "recovery", + "algorithm": "xchacha20-poly1305", + "key_derivation": { + "algorithm": "argon2id", + "memory_kib": 65536, + "iterations": 3, + "parallelism": 1, + "salt": "c2FsdC1mb3ItdGhpbmtsb29t" + }, + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "recovery-key-envelope.wrapped_key: reject missing required property", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J0000000000000000000000S", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "recovery", + "algorithm": "xchacha20-poly1305", + "key_derivation": { + "algorithm": "argon2id", + "memory_kib": 65536, + "iterations": 3, + "parallelism": 1, + "salt": "c2FsdC1mb3ItdGhpbmtsb29t" + }, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "recovery-key-envelope.ciphertext_sha256: reject missing required property", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J0000000000000000000000S", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "recovery", + "algorithm": "xchacha20-poly1305", + "key_derivation": { + "algorithm": "argon2id", + "memory_kib": 65536, + "iterations": 3, + "parallelism": 1, + "salt": "c2FsdC1mb3ItdGhpbmtsb29t" + }, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "recovery-key-envelope.created_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J0000000000000000000000S", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "recovery", + "algorithm": "xchacha20-poly1305", + "key_derivation": { + "algorithm": "argon2id", + "memory_kib": 65536, + "iterations": 3, + "parallelism": 1, + "salt": "c2FsdC1mb3ItdGhpbmtsb29t" + }, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + } + }, + { + "description": "recovery-key-envelope: reject unexpected property", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J0000000000000000000000S", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "recovery", + "algorithm": "xchacha20-poly1305", + "key_derivation": { + "algorithm": "argon2id", + "memory_kib": 65536, + "iterations": 3, + "parallelism": 1, + "salt": "c2FsdC1mb3ItdGhpbmtsb29t" + }, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z", + "__unexpected": true + } + }, + { + "description": "recovery-key-envelope.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "envelope_id": "record_01J0000000000000000000000S", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "recovery", + "algorithm": "xchacha20-poly1305", + "key_derivation": { + "algorithm": "argon2id", + "memory_kib": 65536, + "iterations": 3, + "parallelism": 1, + "salt": "c2FsdC1mb3ItdGhpbmtsb29t" + }, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "recovery-key-envelope.envelope_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "envelope_id": "invalid-id", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "recovery", + "algorithm": "xchacha20-poly1305", + "key_derivation": { + "algorithm": "argon2id", + "memory_kib": 65536, + "iterations": 3, + "parallelism": 1, + "salt": "c2FsdC1mb3ItdGhpbmtsb29t" + }, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "recovery-key-envelope.key_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J0000000000000000000000S", + "key_id": "invalid-id", + "envelope_type": "recovery", + "algorithm": "xchacha20-poly1305", + "key_derivation": { + "algorithm": "argon2id", + "memory_kib": 65536, + "iterations": 3, + "parallelism": 1, + "salt": "c2FsdC1mb3ItdGhpbmtsb29t" + }, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "recovery-key-envelope.envelope_type: reject value different from const", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J0000000000000000000000S", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "__INVALID_CONST__", + "algorithm": "xchacha20-poly1305", + "key_derivation": { + "algorithm": "argon2id", + "memory_kib": 65536, + "iterations": 3, + "parallelism": 1, + "salt": "c2FsdC1mb3ItdGhpbmtsb29t" + }, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "recovery-key-envelope.algorithm: reject value outside enum", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J0000000000000000000000S", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "recovery", + "algorithm": "__INVALID_ENUM__", + "key_derivation": { + "algorithm": "argon2id", + "memory_kib": 65536, + "iterations": 3, + "parallelism": 1, + "salt": "c2FsdC1mb3ItdGhpbmtsb29t" + }, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "recovery-key-envelope.key_derivation.algorithm: reject missing required property", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J0000000000000000000000S", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "recovery", + "algorithm": "xchacha20-poly1305", + "key_derivation": { + "memory_kib": 65536, + "iterations": 3, + "parallelism": 1, + "salt": "c2FsdC1mb3ItdGhpbmtsb29t" + }, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "recovery-key-envelope.key_derivation.memory_kib: reject missing required property", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J0000000000000000000000S", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "recovery", + "algorithm": "xchacha20-poly1305", + "key_derivation": { + "algorithm": "argon2id", + "iterations": 3, + "parallelism": 1, + "salt": "c2FsdC1mb3ItdGhpbmtsb29t" + }, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "recovery-key-envelope.key_derivation.iterations: reject missing required property", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J0000000000000000000000S", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "recovery", + "algorithm": "xchacha20-poly1305", + "key_derivation": { + "algorithm": "argon2id", + "memory_kib": 65536, + "parallelism": 1, + "salt": "c2FsdC1mb3ItdGhpbmtsb29t" + }, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "recovery-key-envelope.key_derivation.parallelism: reject missing required property", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J0000000000000000000000S", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "recovery", + "algorithm": "xchacha20-poly1305", + "key_derivation": { + "algorithm": "argon2id", + "memory_kib": 65536, + "iterations": 3, + "salt": "c2FsdC1mb3ItdGhpbmtsb29t" + }, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "recovery-key-envelope.key_derivation.salt: reject missing required property", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J0000000000000000000000S", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "recovery", + "algorithm": "xchacha20-poly1305", + "key_derivation": { + "algorithm": "argon2id", + "memory_kib": 65536, + "iterations": 3, + "parallelism": 1 + }, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "recovery-key-envelope.key_derivation: reject unexpected property", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J0000000000000000000000S", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "recovery", + "algorithm": "xchacha20-poly1305", + "key_derivation": { + "algorithm": "argon2id", + "memory_kib": 65536, + "iterations": 3, + "parallelism": 1, + "salt": "c2FsdC1mb3ItdGhpbmtsb29t", + "__unexpected": true + }, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "recovery-key-envelope.key_derivation.algorithm: reject value different from const", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J0000000000000000000000S", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "recovery", + "algorithm": "xchacha20-poly1305", + "key_derivation": { + "algorithm": "__INVALID_CONST__", + "memory_kib": 65536, + "iterations": 3, + "parallelism": 1, + "salt": "c2FsdC1mb3ItdGhpbmtsb29t" + }, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "recovery-key-envelope.key_derivation.memory_kib: reject value below minimum", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J0000000000000000000000S", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "recovery", + "algorithm": "xchacha20-poly1305", + "key_derivation": { + "algorithm": "argon2id", + "memory_kib": 65535, + "iterations": 3, + "parallelism": 1, + "salt": "c2FsdC1mb3ItdGhpbmtsb29t" + }, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "recovery-key-envelope.key_derivation.iterations: reject value below minimum", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J0000000000000000000000S", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "recovery", + "algorithm": "xchacha20-poly1305", + "key_derivation": { + "algorithm": "argon2id", + "memory_kib": 65536, + "iterations": 0, + "parallelism": 1, + "salt": "c2FsdC1mb3ItdGhpbmtsb29t" + }, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "recovery-key-envelope.key_derivation.parallelism: reject value below minimum", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J0000000000000000000000S", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "recovery", + "algorithm": "xchacha20-poly1305", + "key_derivation": { + "algorithm": "argon2id", + "memory_kib": 65536, + "iterations": 3, + "parallelism": 0, + "salt": "c2FsdC1mb3ItdGhpbmtsb29t" + }, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "recovery-key-envelope.key_derivation.salt: reject string below minLength", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J0000000000000000000000S", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "recovery", + "algorithm": "xchacha20-poly1305", + "key_derivation": { + "algorithm": "argon2id", + "memory_kib": 65536, + "iterations": 3, + "parallelism": 1, + "salt": "" + }, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "recovery-key-envelope.nonce: reject string below minLength", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J0000000000000000000000S", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "recovery", + "algorithm": "xchacha20-poly1305", + "key_derivation": { + "algorithm": "argon2id", + "memory_kib": 65536, + "iterations": 3, + "parallelism": 1, + "salt": "c2FsdC1mb3ItdGhpbmtsb29t" + }, + "nonce": "", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "recovery-key-envelope.wrapped_key: reject string below minLength", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J0000000000000000000000S", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "recovery", + "algorithm": "xchacha20-poly1305", + "key_derivation": { + "algorithm": "argon2id", + "memory_kib": 65536, + "iterations": 3, + "parallelism": 1, + "salt": "c2FsdC1mb3ItdGhpbmtsb29t" + }, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "recovery-key-envelope.ciphertext_sha256: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J0000000000000000000000S", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "recovery", + "algorithm": "xchacha20-poly1305", + "key_derivation": { + "algorithm": "argon2id", + "memory_kib": 65536, + "iterations": 3, + "parallelism": 1, + "salt": "c2FsdC1mb3ItdGhpbmtsb29t" + }, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:INVALID", + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "recovery-key-envelope.created_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J0000000000000000000000S", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "recovery", + "algorithm": "xchacha20-poly1305", + "key_derivation": { + "algorithm": "argon2id", + "memory_kib": 65536, + "iterations": 3, + "parallelism": 1, + "salt": "c2FsdC1mb3ItdGhpbmtsb29t" + }, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "not-a-timestamp" + } + }, + { + "description": "recovery-key-envelope: recovery derivation is mandatory", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J0000000000000000000000S", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "recovery", + "algorithm": "xchacha20-poly1305", + "key_derivation": null, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/release-manifest.invalid.json b/schemas/provenance/v1/fixtures/invalid/release-manifest.invalid.json new file mode 100644 index 0000000..c68e342 --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/release-manifest.invalid.json @@ -0,0 +1,1213 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/release-manifest.schema.json", + "cases": [ + { + "description": "release-manifest.schema_version: reject missing required property", + "instance": { + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.application_version: reject missing required property", + "instance": { + "schema_version": "1.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.release_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.project_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.version: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.created_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.source_commit: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.source_chain_head: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.source_manuscript: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.sanitized: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.files: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.release_files_merkle_root: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.merkle_algorithm: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda" + } + }, + { + "description": "release-manifest: reject unexpected property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1", + "__unexpected": true + } + }, + { + "description": "release-manifest.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.application_version: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "application_version": " invalid!", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.release_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "invalid-id", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.project_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "invalid-id", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.version: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": " invalid!", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.created_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "not-a-timestamp", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.source_commit: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": " invalid!", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.source_chain_head: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:INVALID", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.source_manuscript.path: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.source_manuscript.sha256: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "manuscript/final-manuscript.md" + }, + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.source_manuscript: reject unexpected property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "__unexpected": true + }, + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.source_manuscript.path: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "../outside-project", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.source_manuscript.path: reject string below minLength", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.source_manuscript.sha256: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:INVALID" + }, + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.files: reject array below minItems", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.files[0].path: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [ + { + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.files[0].sha256: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.files[0].size: reject missing required property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.files[0]: reject unexpected property", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024, + "__unexpected": true + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.files[0].path: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [ + { + "path": "../outside-project", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.files[0].path: reject string below minLength", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [ + { + "path": "", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.files[0].sha256: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:INVALID", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.files[0].size: reject value below minimum", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": -1 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.release_files_merkle_root: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:INVALID", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + }, + { + "description": "release-manifest.merkle_algorithm: reject value different from const", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "__INVALID_CONST__" + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/release-state.invalid.json b/schemas/provenance/v1/fixtures/invalid/release-state.invalid.json new file mode 100644 index 0000000..06d9854 --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/release-state.invalid.json @@ -0,0 +1,249 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/release-state.schema.json", + "cases": [ + { + "description": "release-state.schema_version: reject missing required property", + "instance": { + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "state": "RELEASE_STAGED", + "state_sequence": 5, + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "updated_at": "2026-07-17T18:43:11.456Z", + "failure": null + } + }, + { + "description": "release-state.release_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "state": "RELEASE_STAGED", + "state_sequence": 5, + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "updated_at": "2026-07-17T18:43:11.456Z", + "failure": null + } + }, + { + "description": "release-state.project_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "release_id": "release_01J0000000000000000000000E", + "state": "RELEASE_STAGED", + "state_sequence": 5, + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "updated_at": "2026-07-17T18:43:11.456Z", + "failure": null + } + }, + { + "description": "release-state.state: reject missing required property", + "instance": { + "schema_version": "1.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "state_sequence": 5, + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "updated_at": "2026-07-17T18:43:11.456Z", + "failure": null + } + }, + { + "description": "release-state.state_sequence: reject missing required property", + "instance": { + "schema_version": "1.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "state": "RELEASE_STAGED", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "updated_at": "2026-07-17T18:43:11.456Z", + "failure": null + } + }, + { + "description": "release-state.source_commit: reject missing required property", + "instance": { + "schema_version": "1.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "state": "RELEASE_STAGED", + "state_sequence": 5, + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "updated_at": "2026-07-17T18:43:11.456Z", + "failure": null + } + }, + { + "description": "release-state.source_chain_head: reject missing required property", + "instance": { + "schema_version": "1.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "state": "RELEASE_STAGED", + "state_sequence": 5, + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "updated_at": "2026-07-17T18:43:11.456Z", + "failure": null + } + }, + { + "description": "release-state.updated_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "state": "RELEASE_STAGED", + "state_sequence": 5, + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "failure": null + } + }, + { + "description": "release-state.failure: reject missing required property", + "instance": { + "schema_version": "1.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "state": "RELEASE_STAGED", + "state_sequence": 5, + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "updated_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "release-state: reject unexpected property", + "instance": { + "schema_version": "1.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "state": "RELEASE_STAGED", + "state_sequence": 5, + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "updated_at": "2026-07-17T18:43:11.456Z", + "failure": null, + "__unexpected": true + } + }, + { + "description": "release-state.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "state": "RELEASE_STAGED", + "state_sequence": 5, + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "updated_at": "2026-07-17T18:43:11.456Z", + "failure": null + } + }, + { + "description": "release-state.release_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "release_id": "invalid-id", + "project_id": "project_01J00000000000000000000001", + "state": "RELEASE_STAGED", + "state_sequence": 5, + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "updated_at": "2026-07-17T18:43:11.456Z", + "failure": null + } + }, + { + "description": "release-state.project_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "invalid-id", + "state": "RELEASE_STAGED", + "state_sequence": 5, + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "updated_at": "2026-07-17T18:43:11.456Z", + "failure": null + } + }, + { + "description": "release-state.state: reject value outside enum", + "instance": { + "schema_version": "1.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "state": "__INVALID_ENUM__", + "state_sequence": 5, + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "updated_at": "2026-07-17T18:43:11.456Z", + "failure": null + } + }, + { + "description": "release-state.state_sequence: reject value below minimum", + "instance": { + "schema_version": "1.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "state": "RELEASE_STAGED", + "state_sequence": 0, + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "updated_at": "2026-07-17T18:43:11.456Z", + "failure": null + } + }, + { + "description": "release-state.source_commit: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "state": "RELEASE_STAGED", + "state_sequence": 5, + "source_commit": " invalid!", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "updated_at": "2026-07-17T18:43:11.456Z", + "failure": null + } + }, + { + "description": "release-state.source_chain_head: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "state": "RELEASE_STAGED", + "state_sequence": 5, + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:INVALID", + "updated_at": "2026-07-17T18:43:11.456Z", + "failure": null + } + }, + { + "description": "release-state.updated_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "state": "RELEASE_STAGED", + "state_sequence": 5, + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "updated_at": "not-a-timestamp", + "failure": null + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/sanitized-export-manifest.invalid.json b/schemas/provenance/v1/fixtures/invalid/sanitized-export-manifest.invalid.json new file mode 100644 index 0000000..a47d41d --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/sanitized-export-manifest.invalid.json @@ -0,0 +1,833 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/sanitized-export-manifest.schema.json", + "cases": [ + { + "description": "sanitized-export-manifest.schema_version: reject missing required property", + "instance": { + "export_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "profile": "sanitized", + "omission_rules": [ + { + "category": "private_conversation", + "action": "exclude", + "count": 2 + } + ], + "rules_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "files": [ + { + "path": "final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + } + ], + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "sanitized-export-manifest.export_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "profile": "sanitized", + "omission_rules": [ + { + "category": "private_conversation", + "action": "exclude", + "count": 2 + } + ], + "rules_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "files": [ + { + "path": "final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + } + ], + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "sanitized-export-manifest.project_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "export_id": "record_01J00000000000000000000005", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "profile": "sanitized", + "omission_rules": [ + { + "category": "private_conversation", + "action": "exclude", + "count": 2 + } + ], + "rules_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "files": [ + { + "path": "final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + } + ], + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "sanitized-export-manifest.source_chain_head: reject missing required property", + "instance": { + "schema_version": "1.0", + "export_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "profile": "sanitized", + "omission_rules": [ + { + "category": "private_conversation", + "action": "exclude", + "count": 2 + } + ], + "rules_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "files": [ + { + "path": "final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + } + ], + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "sanitized-export-manifest.profile: reject missing required property", + "instance": { + "schema_version": "1.0", + "export_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "omission_rules": [ + { + "category": "private_conversation", + "action": "exclude", + "count": 2 + } + ], + "rules_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "files": [ + { + "path": "final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + } + ], + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "sanitized-export-manifest.omission_rules: reject missing required property", + "instance": { + "schema_version": "1.0", + "export_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "profile": "sanitized", + "rules_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "files": [ + { + "path": "final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + } + ], + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "sanitized-export-manifest.rules_sha256: reject missing required property", + "instance": { + "schema_version": "1.0", + "export_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "profile": "sanitized", + "omission_rules": [ + { + "category": "private_conversation", + "action": "exclude", + "count": 2 + } + ], + "files": [ + { + "path": "final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + } + ], + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "sanitized-export-manifest.files: reject missing required property", + "instance": { + "schema_version": "1.0", + "export_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "profile": "sanitized", + "omission_rules": [ + { + "category": "private_conversation", + "action": "exclude", + "count": 2 + } + ], + "rules_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "sanitized-export-manifest.created_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "export_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "profile": "sanitized", + "omission_rules": [ + { + "category": "private_conversation", + "action": "exclude", + "count": 2 + } + ], + "rules_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "files": [ + { + "path": "final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + } + ] + } + }, + { + "description": "sanitized-export-manifest: reject unexpected property", + "instance": { + "schema_version": "1.0", + "export_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "profile": "sanitized", + "omission_rules": [ + { + "category": "private_conversation", + "action": "exclude", + "count": 2 + } + ], + "rules_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "files": [ + { + "path": "final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + } + ], + "created_at": "2026-07-17T18:43:11.456Z", + "__unexpected": true + } + }, + { + "description": "sanitized-export-manifest.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "export_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "profile": "sanitized", + "omission_rules": [ + { + "category": "private_conversation", + "action": "exclude", + "count": 2 + } + ], + "rules_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "files": [ + { + "path": "final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + } + ], + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "sanitized-export-manifest.export_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "export_id": "invalid-id", + "project_id": "project_01J00000000000000000000001", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "profile": "sanitized", + "omission_rules": [ + { + "category": "private_conversation", + "action": "exclude", + "count": 2 + } + ], + "rules_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "files": [ + { + "path": "final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + } + ], + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "sanitized-export-manifest.project_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "export_id": "record_01J00000000000000000000005", + "project_id": "invalid-id", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "profile": "sanitized", + "omission_rules": [ + { + "category": "private_conversation", + "action": "exclude", + "count": 2 + } + ], + "rules_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "files": [ + { + "path": "final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + } + ], + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "sanitized-export-manifest.source_chain_head: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "export_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "source_chain_head": "sha256:INVALID", + "profile": "sanitized", + "omission_rules": [ + { + "category": "private_conversation", + "action": "exclude", + "count": 2 + } + ], + "rules_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "files": [ + { + "path": "final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + } + ], + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "sanitized-export-manifest.profile: reject value different from const", + "instance": { + "schema_version": "1.0", + "export_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "profile": "__INVALID_CONST__", + "omission_rules": [ + { + "category": "private_conversation", + "action": "exclude", + "count": 2 + } + ], + "rules_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "files": [ + { + "path": "final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + } + ], + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "sanitized-export-manifest.omission_rules[0].category: reject missing required property", + "instance": { + "schema_version": "1.0", + "export_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "profile": "sanitized", + "omission_rules": [ + { + "action": "exclude", + "count": 2 + } + ], + "rules_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "files": [ + { + "path": "final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + } + ], + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "sanitized-export-manifest.omission_rules[0].action: reject missing required property", + "instance": { + "schema_version": "1.0", + "export_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "profile": "sanitized", + "omission_rules": [ + { + "category": "private_conversation", + "count": 2 + } + ], + "rules_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "files": [ + { + "path": "final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + } + ], + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "sanitized-export-manifest.omission_rules[0].count: reject missing required property", + "instance": { + "schema_version": "1.0", + "export_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "profile": "sanitized", + "omission_rules": [ + { + "category": "private_conversation", + "action": "exclude" + } + ], + "rules_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "files": [ + { + "path": "final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + } + ], + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "sanitized-export-manifest.omission_rules[0]: reject unexpected property", + "instance": { + "schema_version": "1.0", + "export_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "profile": "sanitized", + "omission_rules": [ + { + "category": "private_conversation", + "action": "exclude", + "count": 2, + "__unexpected": true + } + ], + "rules_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "files": [ + { + "path": "final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + } + ], + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "sanitized-export-manifest.omission_rules[0].category: reject value outside enum", + "instance": { + "schema_version": "1.0", + "export_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "profile": "sanitized", + "omission_rules": [ + { + "category": "__INVALID_ENUM__", + "action": "exclude", + "count": 2 + } + ], + "rules_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "files": [ + { + "path": "final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + } + ], + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "sanitized-export-manifest.omission_rules[0].action: reject value outside enum", + "instance": { + "schema_version": "1.0", + "export_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "profile": "sanitized", + "omission_rules": [ + { + "category": "private_conversation", + "action": "__INVALID_ENUM__", + "count": 2 + } + ], + "rules_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "files": [ + { + "path": "final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + } + ], + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "sanitized-export-manifest.omission_rules[0].count: reject value below minimum", + "instance": { + "schema_version": "1.0", + "export_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "profile": "sanitized", + "omission_rules": [ + { + "category": "private_conversation", + "action": "exclude", + "count": -1 + } + ], + "rules_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "files": [ + { + "path": "final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + } + ], + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "sanitized-export-manifest.rules_sha256: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "export_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "profile": "sanitized", + "omission_rules": [ + { + "category": "private_conversation", + "action": "exclude", + "count": 2 + } + ], + "rules_sha256": "sha256:INVALID", + "files": [ + { + "path": "final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + } + ], + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "sanitized-export-manifest.files: reject array below minItems", + "instance": { + "schema_version": "1.0", + "export_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "profile": "sanitized", + "omission_rules": [ + { + "category": "private_conversation", + "action": "exclude", + "count": 2 + } + ], + "rules_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "files": [], + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "sanitized-export-manifest.files[0].path: reject missing required property", + "instance": { + "schema_version": "1.0", + "export_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "profile": "sanitized", + "omission_rules": [ + { + "category": "private_conversation", + "action": "exclude", + "count": 2 + } + ], + "rules_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "files": [ + { + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + } + ], + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "sanitized-export-manifest.files[0].sha256: reject missing required property", + "instance": { + "schema_version": "1.0", + "export_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "profile": "sanitized", + "omission_rules": [ + { + "category": "private_conversation", + "action": "exclude", + "count": 2 + } + ], + "rules_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "files": [ + { + "path": "final-manuscript.md", + "size": 1024 + } + ], + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "sanitized-export-manifest.files[0].size: reject missing required property", + "instance": { + "schema_version": "1.0", + "export_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "profile": "sanitized", + "omission_rules": [ + { + "category": "private_conversation", + "action": "exclude", + "count": 2 + } + ], + "rules_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "files": [ + { + "path": "final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + ], + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "sanitized-export-manifest.files[0]: reject unexpected property", + "instance": { + "schema_version": "1.0", + "export_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "profile": "sanitized", + "omission_rules": [ + { + "category": "private_conversation", + "action": "exclude", + "count": 2 + } + ], + "rules_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "files": [ + { + "path": "final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024, + "__unexpected": true + } + ], + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "sanitized-export-manifest.files[0].path: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "export_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "profile": "sanitized", + "omission_rules": [ + { + "category": "private_conversation", + "action": "exclude", + "count": 2 + } + ], + "rules_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "files": [ + { + "path": "../outside-project", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + } + ], + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "sanitized-export-manifest.files[0].path: reject string below minLength", + "instance": { + "schema_version": "1.0", + "export_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "profile": "sanitized", + "omission_rules": [ + { + "category": "private_conversation", + "action": "exclude", + "count": 2 + } + ], + "rules_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "files": [ + { + "path": "", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + } + ], + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "sanitized-export-manifest.files[0].sha256: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "export_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "profile": "sanitized", + "omission_rules": [ + { + "category": "private_conversation", + "action": "exclude", + "count": 2 + } + ], + "rules_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "files": [ + { + "path": "final-manuscript.md", + "sha256": "sha256:INVALID", + "size": 1024 + } + ], + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "sanitized-export-manifest.files[0].size: reject value below minimum", + "instance": { + "schema_version": "1.0", + "export_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "profile": "sanitized", + "omission_rules": [ + { + "category": "private_conversation", + "action": "exclude", + "count": 2 + } + ], + "rules_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "files": [ + { + "path": "final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": -1 + } + ], + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "sanitized-export-manifest.created_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "export_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "profile": "sanitized", + "omission_rules": [ + { + "category": "private_conversation", + "action": "exclude", + "count": 2 + } + ], + "rules_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "files": [ + { + "path": "final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + } + ], + "created_at": "not-a-timestamp" + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/text-fragment-reference.invalid.json b/schemas/provenance/v1/fixtures/invalid/text-fragment-reference.invalid.json new file mode 100644 index 0000000..6427157 --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/text-fragment-reference.invalid.json @@ -0,0 +1,179 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/text-fragment-reference.schema.json", + "cases": [ + { + "description": "text-fragment-reference.schema_version: reject missing required property", + "instance": { + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + }, + { + "description": "text-fragment-reference.document_revision_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + }, + { + "description": "text-fragment-reference.coordinate_system: reject missing required property", + "instance": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + }, + { + "description": "text-fragment-reference.start: reject missing required property", + "instance": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + }, + { + "description": "text-fragment-reference.end: reject missing required property", + "instance": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + }, + { + "description": "text-fragment-reference.preimage_sha256: reject missing required property", + "instance": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + }, + { + "description": "text-fragment-reference.text_fragment_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111" + } + }, + { + "description": "text-fragment-reference: reject unexpected property", + "instance": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C", + "__unexpected": true + } + }, + { + "description": "text-fragment-reference.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + }, + { + "description": "text-fragment-reference.document_revision_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "document_revision_id": "invalid-id", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + }, + { + "description": "text-fragment-reference.coordinate_system: reject value outside enum", + "instance": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "__INVALID_ENUM__", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + }, + { + "description": "text-fragment-reference.start: reject value below minimum", + "instance": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": -1, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + }, + { + "description": "text-fragment-reference.end: reject value below minimum", + "instance": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": -1, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + }, + { + "description": "text-fragment-reference.preimage_sha256: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:INVALID", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + }, + { + "description": "text-fragment-reference.text_fragment_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "invalid-id" + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/transcript-correction.invalid.json b/schemas/provenance/v1/fixtures/invalid/transcript-correction.invalid.json new file mode 100644 index 0000000..58082f2 --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/transcript-correction.invalid.json @@ -0,0 +1,219 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/transcript-correction.schema.json", + "cases": [ + { + "description": "transcript-correction.schema_version: reject missing required property", + "instance": { + "correction_id": "correction_01J0000000000000000000000J", + "turn_id": "turn_01J00000000000000000000007", + "revision_number": 1, + "corrected_text": "Attention shapes our public life.", + "reason": "user_correction", + "created_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "transcript-correction.correction_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "turn_id": "turn_01J00000000000000000000007", + "revision_number": 1, + "corrected_text": "Attention shapes our public life.", + "reason": "user_correction", + "created_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "transcript-correction.turn_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "correction_id": "correction_01J0000000000000000000000J", + "revision_number": 1, + "corrected_text": "Attention shapes our public life.", + "reason": "user_correction", + "created_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "transcript-correction.revision_number: reject missing required property", + "instance": { + "schema_version": "1.0", + "correction_id": "correction_01J0000000000000000000000J", + "turn_id": "turn_01J00000000000000000000007", + "corrected_text": "Attention shapes our public life.", + "reason": "user_correction", + "created_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "transcript-correction.corrected_text: reject missing required property", + "instance": { + "schema_version": "1.0", + "correction_id": "correction_01J0000000000000000000000J", + "turn_id": "turn_01J00000000000000000000007", + "revision_number": 1, + "reason": "user_correction", + "created_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "transcript-correction.reason: reject missing required property", + "instance": { + "schema_version": "1.0", + "correction_id": "correction_01J0000000000000000000000J", + "turn_id": "turn_01J00000000000000000000007", + "revision_number": 1, + "corrected_text": "Attention shapes our public life.", + "created_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "transcript-correction.created_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "correction_id": "correction_01J0000000000000000000000J", + "turn_id": "turn_01J00000000000000000000007", + "revision_number": 1, + "corrected_text": "Attention shapes our public life.", + "reason": "user_correction", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "transcript-correction.event_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "correction_id": "correction_01J0000000000000000000000J", + "turn_id": "turn_01J00000000000000000000007", + "revision_number": 1, + "corrected_text": "Attention shapes our public life.", + "reason": "user_correction", + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "transcript-correction: reject unexpected property", + "instance": { + "schema_version": "1.0", + "correction_id": "correction_01J0000000000000000000000J", + "turn_id": "turn_01J00000000000000000000007", + "revision_number": 1, + "corrected_text": "Attention shapes our public life.", + "reason": "user_correction", + "created_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004", + "__unexpected": true + } + }, + { + "description": "transcript-correction.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "correction_id": "correction_01J0000000000000000000000J", + "turn_id": "turn_01J00000000000000000000007", + "revision_number": 1, + "corrected_text": "Attention shapes our public life.", + "reason": "user_correction", + "created_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "transcript-correction.correction_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "correction_id": "invalid-id", + "turn_id": "turn_01J00000000000000000000007", + "revision_number": 1, + "corrected_text": "Attention shapes our public life.", + "reason": "user_correction", + "created_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "transcript-correction.turn_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "correction_id": "correction_01J0000000000000000000000J", + "turn_id": "invalid-id", + "revision_number": 1, + "corrected_text": "Attention shapes our public life.", + "reason": "user_correction", + "created_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "transcript-correction.revision_number: reject value below minimum", + "instance": { + "schema_version": "1.0", + "correction_id": "correction_01J0000000000000000000000J", + "turn_id": "turn_01J00000000000000000000007", + "revision_number": 0, + "corrected_text": "Attention shapes our public life.", + "reason": "user_correction", + "created_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "transcript-correction.corrected_text: reject string below minLength", + "instance": { + "schema_version": "1.0", + "correction_id": "correction_01J0000000000000000000000J", + "turn_id": "turn_01J00000000000000000000007", + "revision_number": 1, + "corrected_text": "", + "reason": "user_correction", + "created_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "transcript-correction.reason: reject value outside enum", + "instance": { + "schema_version": "1.0", + "correction_id": "correction_01J0000000000000000000000J", + "turn_id": "turn_01J00000000000000000000007", + "revision_number": 1, + "corrected_text": "Attention shapes our public life.", + "reason": "__INVALID_ENUM__", + "created_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "transcript-correction.created_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "correction_id": "correction_01J0000000000000000000000J", + "turn_id": "turn_01J00000000000000000000007", + "revision_number": 1, + "corrected_text": "Attention shapes our public life.", + "reason": "user_correction", + "created_at": "not-a-timestamp", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "transcript-correction.event_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "correction_id": "correction_01J0000000000000000000000J", + "turn_id": "turn_01J00000000000000000000007", + "revision_number": 1, + "corrected_text": "Attention shapes our public life.", + "reason": "user_correction", + "created_at": "2026-07-17T18:43:11.456Z", + "event_id": "invalid-id" + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/transcript-normalization.invalid.json b/schemas/provenance/v1/fixtures/invalid/transcript-normalization.invalid.json new file mode 100644 index 0000000..2837c3f --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/transcript-normalization.invalid.json @@ -0,0 +1,263 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/transcript-normalization.schema.json", + "cases": [ + { + "description": "transcript-normalization.schema_version: reject missing required property", + "instance": { + "normalization_id": "normalization_01J0000000000000000000000K", + "turn_id": "turn_01J00000000000000000000007", + "revision_number": 1, + "normalized_text": "Attention shapes public life.", + "method": "application", + "source_correction_id": "correction_01J0000000000000000000000J", + "created_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "transcript-normalization.normalization_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "turn_id": "turn_01J00000000000000000000007", + "revision_number": 1, + "normalized_text": "Attention shapes public life.", + "method": "application", + "source_correction_id": "correction_01J0000000000000000000000J", + "created_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "transcript-normalization.turn_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "normalization_id": "normalization_01J0000000000000000000000K", + "revision_number": 1, + "normalized_text": "Attention shapes public life.", + "method": "application", + "source_correction_id": "correction_01J0000000000000000000000J", + "created_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "transcript-normalization.revision_number: reject missing required property", + "instance": { + "schema_version": "1.0", + "normalization_id": "normalization_01J0000000000000000000000K", + "turn_id": "turn_01J00000000000000000000007", + "normalized_text": "Attention shapes public life.", + "method": "application", + "source_correction_id": "correction_01J0000000000000000000000J", + "created_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "transcript-normalization.normalized_text: reject missing required property", + "instance": { + "schema_version": "1.0", + "normalization_id": "normalization_01J0000000000000000000000K", + "turn_id": "turn_01J00000000000000000000007", + "revision_number": 1, + "method": "application", + "source_correction_id": "correction_01J0000000000000000000000J", + "created_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "transcript-normalization.method: reject missing required property", + "instance": { + "schema_version": "1.0", + "normalization_id": "normalization_01J0000000000000000000000K", + "turn_id": "turn_01J00000000000000000000007", + "revision_number": 1, + "normalized_text": "Attention shapes public life.", + "source_correction_id": "correction_01J0000000000000000000000J", + "created_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "transcript-normalization.source_correction_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "normalization_id": "normalization_01J0000000000000000000000K", + "turn_id": "turn_01J00000000000000000000007", + "revision_number": 1, + "normalized_text": "Attention shapes public life.", + "method": "application", + "created_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "transcript-normalization.created_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "normalization_id": "normalization_01J0000000000000000000000K", + "turn_id": "turn_01J00000000000000000000007", + "revision_number": 1, + "normalized_text": "Attention shapes public life.", + "method": "application", + "source_correction_id": "correction_01J0000000000000000000000J", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "transcript-normalization.event_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "normalization_id": "normalization_01J0000000000000000000000K", + "turn_id": "turn_01J00000000000000000000007", + "revision_number": 1, + "normalized_text": "Attention shapes public life.", + "method": "application", + "source_correction_id": "correction_01J0000000000000000000000J", + "created_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "transcript-normalization: reject unexpected property", + "instance": { + "schema_version": "1.0", + "normalization_id": "normalization_01J0000000000000000000000K", + "turn_id": "turn_01J00000000000000000000007", + "revision_number": 1, + "normalized_text": "Attention shapes public life.", + "method": "application", + "source_correction_id": "correction_01J0000000000000000000000J", + "created_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004", + "__unexpected": true + } + }, + { + "description": "transcript-normalization.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "normalization_id": "normalization_01J0000000000000000000000K", + "turn_id": "turn_01J00000000000000000000007", + "revision_number": 1, + "normalized_text": "Attention shapes public life.", + "method": "application", + "source_correction_id": "correction_01J0000000000000000000000J", + "created_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "transcript-normalization.normalization_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "normalization_id": "invalid-id", + "turn_id": "turn_01J00000000000000000000007", + "revision_number": 1, + "normalized_text": "Attention shapes public life.", + "method": "application", + "source_correction_id": "correction_01J0000000000000000000000J", + "created_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "transcript-normalization.turn_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "normalization_id": "normalization_01J0000000000000000000000K", + "turn_id": "invalid-id", + "revision_number": 1, + "normalized_text": "Attention shapes public life.", + "method": "application", + "source_correction_id": "correction_01J0000000000000000000000J", + "created_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "transcript-normalization.revision_number: reject value below minimum", + "instance": { + "schema_version": "1.0", + "normalization_id": "normalization_01J0000000000000000000000K", + "turn_id": "turn_01J00000000000000000000007", + "revision_number": 0, + "normalized_text": "Attention shapes public life.", + "method": "application", + "source_correction_id": "correction_01J0000000000000000000000J", + "created_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "transcript-normalization.normalized_text: reject string below minLength", + "instance": { + "schema_version": "1.0", + "normalization_id": "normalization_01J0000000000000000000000K", + "turn_id": "turn_01J00000000000000000000007", + "revision_number": 1, + "normalized_text": "", + "method": "application", + "source_correction_id": "correction_01J0000000000000000000000J", + "created_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "transcript-normalization.method: reject value outside enum", + "instance": { + "schema_version": "1.0", + "normalization_id": "normalization_01J0000000000000000000000K", + "turn_id": "turn_01J00000000000000000000007", + "revision_number": 1, + "normalized_text": "Attention shapes public life.", + "method": "__INVALID_ENUM__", + "source_correction_id": "correction_01J0000000000000000000000J", + "created_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "transcript-normalization.source_correction_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "normalization_id": "normalization_01J0000000000000000000000K", + "turn_id": "turn_01J00000000000000000000007", + "revision_number": 1, + "normalized_text": "Attention shapes public life.", + "method": "application", + "source_correction_id": "invalid-id", + "created_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "transcript-normalization.created_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "normalization_id": "normalization_01J0000000000000000000000K", + "turn_id": "turn_01J00000000000000000000007", + "revision_number": 1, + "normalized_text": "Attention shapes public life.", + "method": "application", + "source_correction_id": "correction_01J0000000000000000000000J", + "created_at": "not-a-timestamp", + "event_id": "event_01J00000000000000000000004" + } + }, + { + "description": "transcript-normalization.event_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "normalization_id": "normalization_01J0000000000000000000000K", + "turn_id": "turn_01J00000000000000000000007", + "revision_number": 1, + "normalized_text": "Attention shapes public life.", + "method": "application", + "source_correction_id": "correction_01J0000000000000000000000J", + "created_at": "2026-07-17T18:43:11.456Z", + "event_id": "invalid-id" + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/transcript-turn.invalid.json b/schemas/provenance/v1/fixtures/invalid/transcript-turn.invalid.json new file mode 100644 index 0000000..7561e27 --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/transcript-turn.invalid.json @@ -0,0 +1,385 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/transcript-turn.schema.json", + "cases": [ + { + "description": "transcript-turn.schema_version: reject missing required property", + "instance": { + "turn_id": "turn_01J00000000000000000000007", + "session_id": "session_01J00000000000000000000006", + "speaker": "user", + "input_mode": "typed", + "retained_text": "Attention shapes public life.", + "raw_transcript": null, + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "audio_retained": false, + "invocation_id": null, + "event_id": "event_01J00000000000000000000003" + } + }, + { + "description": "transcript-turn.turn_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "session_id": "session_01J00000000000000000000006", + "speaker": "user", + "input_mode": "typed", + "retained_text": "Attention shapes public life.", + "raw_transcript": null, + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "audio_retained": false, + "invocation_id": null, + "event_id": "event_01J00000000000000000000003" + } + }, + { + "description": "transcript-turn.session_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "turn_id": "turn_01J00000000000000000000007", + "speaker": "user", + "input_mode": "typed", + "retained_text": "Attention shapes public life.", + "raw_transcript": null, + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "audio_retained": false, + "invocation_id": null, + "event_id": "event_01J00000000000000000000003" + } + }, + { + "description": "transcript-turn.speaker: reject missing required property", + "instance": { + "schema_version": "1.0", + "turn_id": "turn_01J00000000000000000000007", + "session_id": "session_01J00000000000000000000006", + "input_mode": "typed", + "retained_text": "Attention shapes public life.", + "raw_transcript": null, + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "audio_retained": false, + "invocation_id": null, + "event_id": "event_01J00000000000000000000003" + } + }, + { + "description": "transcript-turn.input_mode: reject missing required property", + "instance": { + "schema_version": "1.0", + "turn_id": "turn_01J00000000000000000000007", + "session_id": "session_01J00000000000000000000006", + "speaker": "user", + "retained_text": "Attention shapes public life.", + "raw_transcript": null, + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "audio_retained": false, + "invocation_id": null, + "event_id": "event_01J00000000000000000000003" + } + }, + { + "description": "transcript-turn.retained_text: reject missing required property", + "instance": { + "schema_version": "1.0", + "turn_id": "turn_01J00000000000000000000007", + "session_id": "session_01J00000000000000000000006", + "speaker": "user", + "input_mode": "typed", + "raw_transcript": null, + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "audio_retained": false, + "invocation_id": null, + "event_id": "event_01J00000000000000000000003" + } + }, + { + "description": "transcript-turn.raw_transcript: reject missing required property", + "instance": { + "schema_version": "1.0", + "turn_id": "turn_01J00000000000000000000007", + "session_id": "session_01J00000000000000000000006", + "speaker": "user", + "input_mode": "typed", + "retained_text": "Attention shapes public life.", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "audio_retained": false, + "invocation_id": null, + "event_id": "event_01J00000000000000000000003" + } + }, + { + "description": "transcript-turn.started_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "turn_id": "turn_01J00000000000000000000007", + "session_id": "session_01J00000000000000000000006", + "speaker": "user", + "input_mode": "typed", + "retained_text": "Attention shapes public life.", + "raw_transcript": null, + "ended_at": "2026-07-17T18:43:11.456Z", + "audio_retained": false, + "invocation_id": null, + "event_id": "event_01J00000000000000000000003" + } + }, + { + "description": "transcript-turn.ended_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "turn_id": "turn_01J00000000000000000000007", + "session_id": "session_01J00000000000000000000006", + "speaker": "user", + "input_mode": "typed", + "retained_text": "Attention shapes public life.", + "raw_transcript": null, + "started_at": "2026-07-17T18:42:10.123Z", + "audio_retained": false, + "invocation_id": null, + "event_id": "event_01J00000000000000000000003" + } + }, + { + "description": "transcript-turn.audio_retained: reject missing required property", + "instance": { + "schema_version": "1.0", + "turn_id": "turn_01J00000000000000000000007", + "session_id": "session_01J00000000000000000000006", + "speaker": "user", + "input_mode": "typed", + "retained_text": "Attention shapes public life.", + "raw_transcript": null, + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "invocation_id": null, + "event_id": "event_01J00000000000000000000003" + } + }, + { + "description": "transcript-turn.invocation_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "turn_id": "turn_01J00000000000000000000007", + "session_id": "session_01J00000000000000000000006", + "speaker": "user", + "input_mode": "typed", + "retained_text": "Attention shapes public life.", + "raw_transcript": null, + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "audio_retained": false, + "event_id": "event_01J00000000000000000000003" + } + }, + { + "description": "transcript-turn.event_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "turn_id": "turn_01J00000000000000000000007", + "session_id": "session_01J00000000000000000000006", + "speaker": "user", + "input_mode": "typed", + "retained_text": "Attention shapes public life.", + "raw_transcript": null, + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "audio_retained": false, + "invocation_id": null + } + }, + { + "description": "transcript-turn: reject unexpected property", + "instance": { + "schema_version": "1.0", + "turn_id": "turn_01J00000000000000000000007", + "session_id": "session_01J00000000000000000000006", + "speaker": "user", + "input_mode": "typed", + "retained_text": "Attention shapes public life.", + "raw_transcript": null, + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "audio_retained": false, + "invocation_id": null, + "event_id": "event_01J00000000000000000000003", + "__unexpected": true + } + }, + { + "description": "transcript-turn.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "turn_id": "turn_01J00000000000000000000007", + "session_id": "session_01J00000000000000000000006", + "speaker": "user", + "input_mode": "typed", + "retained_text": "Attention shapes public life.", + "raw_transcript": null, + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "audio_retained": false, + "invocation_id": null, + "event_id": "event_01J00000000000000000000003" + } + }, + { + "description": "transcript-turn.turn_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "turn_id": "invalid-id", + "session_id": "session_01J00000000000000000000006", + "speaker": "user", + "input_mode": "typed", + "retained_text": "Attention shapes public life.", + "raw_transcript": null, + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "audio_retained": false, + "invocation_id": null, + "event_id": "event_01J00000000000000000000003" + } + }, + { + "description": "transcript-turn.session_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "turn_id": "turn_01J00000000000000000000007", + "session_id": "invalid-id", + "speaker": "user", + "input_mode": "typed", + "retained_text": "Attention shapes public life.", + "raw_transcript": null, + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "audio_retained": false, + "invocation_id": null, + "event_id": "event_01J00000000000000000000003" + } + }, + { + "description": "transcript-turn.speaker: reject value outside enum", + "instance": { + "schema_version": "1.0", + "turn_id": "turn_01J00000000000000000000007", + "session_id": "session_01J00000000000000000000006", + "speaker": "__INVALID_ENUM__", + "input_mode": "typed", + "retained_text": "Attention shapes public life.", + "raw_transcript": null, + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "audio_retained": false, + "invocation_id": null, + "event_id": "event_01J00000000000000000000003" + } + }, + { + "description": "transcript-turn.input_mode: reject value outside enum", + "instance": { + "schema_version": "1.0", + "turn_id": "turn_01J00000000000000000000007", + "session_id": "session_01J00000000000000000000006", + "speaker": "user", + "input_mode": "__INVALID_ENUM__", + "retained_text": "Attention shapes public life.", + "raw_transcript": null, + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "audio_retained": false, + "invocation_id": null, + "event_id": "event_01J00000000000000000000003" + } + }, + { + "description": "transcript-turn.retained_text: reject string below minLength", + "instance": { + "schema_version": "1.0", + "turn_id": "turn_01J00000000000000000000007", + "session_id": "session_01J00000000000000000000006", + "speaker": "user", + "input_mode": "typed", + "retained_text": "", + "raw_transcript": null, + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "audio_retained": false, + "invocation_id": null, + "event_id": "event_01J00000000000000000000003" + } + }, + { + "description": "transcript-turn.started_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "turn_id": "turn_01J00000000000000000000007", + "session_id": "session_01J00000000000000000000006", + "speaker": "user", + "input_mode": "typed", + "retained_text": "Attention shapes public life.", + "raw_transcript": null, + "started_at": "not-a-timestamp", + "ended_at": "2026-07-17T18:43:11.456Z", + "audio_retained": false, + "invocation_id": null, + "event_id": "event_01J00000000000000000000003" + } + }, + { + "description": "transcript-turn.ended_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "turn_id": "turn_01J00000000000000000000007", + "session_id": "session_01J00000000000000000000006", + "speaker": "user", + "input_mode": "typed", + "retained_text": "Attention shapes public life.", + "raw_transcript": null, + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "not-a-timestamp", + "audio_retained": false, + "invocation_id": null, + "event_id": "event_01J00000000000000000000003" + } + }, + { + "description": "transcript-turn.audio_retained: reject value different from const", + "instance": { + "schema_version": "1.0", + "turn_id": "turn_01J00000000000000000000007", + "session_id": "session_01J00000000000000000000006", + "speaker": "user", + "input_mode": "typed", + "retained_text": "Attention shapes public life.", + "raw_transcript": null, + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "audio_retained": true, + "invocation_id": null, + "event_id": "event_01J00000000000000000000003" + } + }, + { + "description": "transcript-turn.event_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "turn_id": "turn_01J00000000000000000000007", + "session_id": "session_01J00000000000000000000006", + "speaker": "user", + "input_mode": "typed", + "retained_text": "Attention shapes public life.", + "raw_transcript": null, + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "audio_retained": false, + "invocation_id": null, + "event_id": "invalid-id" + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/verification-report.invalid.json b/schemas/provenance/v1/fixtures/invalid/verification-report.invalid.json new file mode 100644 index 0000000..07fae27 --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/verification-report.invalid.json @@ -0,0 +1,916 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/verification-report.schema.json", + "cases": [ + { + "description": "verification-report.schema_version: reject missing required property", + "instance": { + "verification_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "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": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "verification-report.verification_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "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": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "verification-report.project_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "verification_id": "record_01J00000000000000000000005", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "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": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "verification-report.status: reject missing required property", + "instance": { + "schema_version": "1.0", + "verification_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "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": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "verification-report.verified_through_event_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "verification_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED_WITH_WARNINGS", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "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": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "verification-report.verified_chain_head: reject missing required property", + "instance": { + "schema_version": "1.0", + "verification_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "event_01J00000000000000000000003", + "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": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "verification-report.checked_segments: reject missing required property", + "instance": { + "schema_version": "1.0", + "verification_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "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": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "verification-report.checked_events: reject missing required property", + "instance": { + "schema_version": "1.0", + "verification_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "checked_segments": 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": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "verification-report.checked_records: reject missing required property", + "instance": { + "schema_version": "1.0", + "verification_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "checked_segments": 1, + "checked_events": 1, + "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": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "verification-report.findings: reject missing required property", + "instance": { + "schema_version": "1.0", + "verification_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "checked_segments": 1, + "checked_events": 1, + "checked_records": 4, + "verifier_version": "1.0.0", + "completed_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "verification-report.verifier_version: reject missing required property", + "instance": { + "schema_version": "1.0", + "verification_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "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 + } + ], + "completed_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "verification-report.completed_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "verification_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "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" + } + }, + { + "description": "verification-report: reject unexpected property", + "instance": { + "schema_version": "1.0", + "verification_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "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": "2026-07-17T18:43:11.456Z", + "__unexpected": true + } + }, + { + "description": "verification-report.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "verification_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "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": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "verification-report.verification_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "verification_id": "invalid-id", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "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": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "verification-report.project_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "verification_id": "record_01J00000000000000000000005", + "project_id": "invalid-id", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "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": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "verification-report.status: reject value outside enum", + "instance": { + "schema_version": "1.0", + "verification_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "status": "__INVALID_ENUM__", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "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": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "verification-report.verified_through_event_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "verification_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "invalid-id", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "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": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "verification-report.verified_chain_head: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "verification_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:INVALID", + "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": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "verification-report.checked_segments: reject value below minimum", + "instance": { + "schema_version": "1.0", + "verification_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "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": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "verification-report.checked_events: reject value below minimum", + "instance": { + "schema_version": "1.0", + "verification_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "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": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "verification-report.checked_records: reject value below minimum", + "instance": { + "schema_version": "1.0", + "verification_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "checked_segments": 1, + "checked_events": 1, + "checked_records": -1, + "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": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "verification-report.findings[0].severity: reject missing required property", + "instance": { + "schema_version": "1.0", + "verification_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "checked_segments": 1, + "checked_events": 1, + "checked_records": 4, + "findings": [ + { + "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": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "verification-report.findings[0].code: reject missing required property", + "instance": { + "schema_version": "1.0", + "verification_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "checked_segments": 1, + "checked_events": 1, + "checked_records": 4, + "findings": [ + { + "severity": "WARNING", + "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": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "verification-report.findings[0].message: reject missing required property", + "instance": { + "schema_version": "1.0", + "verification_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "checked_segments": 1, + "checked_events": 1, + "checked_records": 4, + "findings": [ + { + "severity": "WARNING", + "code": "INDEX_STALE", + "authoritative_evidence_affected": false, + "path": "provenance/indexes/contribution-graph.json", + "event_id": null + } + ], + "verifier_version": "1.0.0", + "completed_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "verification-report.findings[0].authoritative_evidence_affected: reject missing required property", + "instance": { + "schema_version": "1.0", + "verification_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "checked_segments": 1, + "checked_events": 1, + "checked_records": 4, + "findings": [ + { + "severity": "WARNING", + "code": "INDEX_STALE", + "message": "Contribution index is stale.", + "path": "provenance/indexes/contribution-graph.json", + "event_id": null + } + ], + "verifier_version": "1.0.0", + "completed_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "verification-report.findings[0].path: reject missing required property", + "instance": { + "schema_version": "1.0", + "verification_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "checked_segments": 1, + "checked_events": 1, + "checked_records": 4, + "findings": [ + { + "severity": "WARNING", + "code": "INDEX_STALE", + "message": "Contribution index is stale.", + "authoritative_evidence_affected": false, + "event_id": null + } + ], + "verifier_version": "1.0.0", + "completed_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "verification-report.findings[0].event_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "verification_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "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" + } + ], + "verifier_version": "1.0.0", + "completed_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "verification-report.findings[0]: reject unexpected property", + "instance": { + "schema_version": "1.0", + "verification_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "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, + "__unexpected": true + } + ], + "verifier_version": "1.0.0", + "completed_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "verification-report.findings[0].severity: reject value outside enum", + "instance": { + "schema_version": "1.0", + "verification_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "checked_segments": 1, + "checked_events": 1, + "checked_records": 4, + "findings": [ + { + "severity": "__INVALID_ENUM__", + "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": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "verification-report.findings[0].code: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "verification_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "checked_segments": 1, + "checked_events": 1, + "checked_records": 4, + "findings": [ + { + "severity": "WARNING", + "code": " invalid!", + "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": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "verification-report.findings[0].message: reject string below minLength", + "instance": { + "schema_version": "1.0", + "verification_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "checked_segments": 1, + "checked_events": 1, + "checked_records": 4, + "findings": [ + { + "severity": "WARNING", + "code": "INDEX_STALE", + "message": "", + "authoritative_evidence_affected": false, + "path": "provenance/indexes/contribution-graph.json", + "event_id": null + } + ], + "verifier_version": "1.0.0", + "completed_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "verification-report.findings[0].path: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "verification_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "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": "../outside-project", + "event_id": null + } + ], + "verifier_version": "1.0.0", + "completed_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "verification-report.findings[0].path: reject string below minLength", + "instance": { + "schema_version": "1.0", + "verification_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "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": "", + "event_id": null + } + ], + "verifier_version": "1.0.0", + "completed_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "verification-report.verifier_version: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "verification_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "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": " invalid!", + "completed_at": "2026-07-17T18:43:11.456Z" + } + }, + { + "description": "verification-report.completed_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "verification_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "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": "not-a-timestamp" + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/invalid/write-intent.invalid.json b/schemas/provenance/v1/fixtures/invalid/write-intent.invalid.json new file mode 100644 index 0000000..2f61461 --- /dev/null +++ b/schemas/provenance/v1/fixtures/invalid/write-intent.invalid.json @@ -0,0 +1,461 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/write-intent.schema.json", + "cases": [ + { + "description": "write-intent.schema_version: reject missing required property", + "instance": { + "intent_id": "intent_01J00000000000000000000002", + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "operation_type": "IDEA_ACCEPTED", + "phase": "PREPARED", + "event_id": null, + "event_sequence": null, + "staged_path": ".app/temp/intents/intent.json", + "command_sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "result": null, + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "write-intent.intent_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "operation_type": "IDEA_ACCEPTED", + "phase": "PREPARED", + "event_id": null, + "event_sequence": null, + "staged_path": ".app/temp/intents/intent.json", + "command_sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "result": null, + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "write-intent.client_action_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "intent_id": "intent_01J00000000000000000000002", + "project_id": "project_01J00000000000000000000001", + "operation_type": "IDEA_ACCEPTED", + "phase": "PREPARED", + "event_id": null, + "event_sequence": null, + "staged_path": ".app/temp/intents/intent.json", + "command_sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "result": null, + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "write-intent.project_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "intent_id": "intent_01J00000000000000000000002", + "client_action_id": "client-action-0001", + "operation_type": "IDEA_ACCEPTED", + "phase": "PREPARED", + "event_id": null, + "event_sequence": null, + "staged_path": ".app/temp/intents/intent.json", + "command_sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "result": null, + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "write-intent.operation_type: reject missing required property", + "instance": { + "schema_version": "1.0", + "intent_id": "intent_01J00000000000000000000002", + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "phase": "PREPARED", + "event_id": null, + "event_sequence": null, + "staged_path": ".app/temp/intents/intent.json", + "command_sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "result": null, + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "write-intent.phase: reject missing required property", + "instance": { + "schema_version": "1.0", + "intent_id": "intent_01J00000000000000000000002", + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "operation_type": "IDEA_ACCEPTED", + "event_id": null, + "event_sequence": null, + "staged_path": ".app/temp/intents/intent.json", + "command_sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "result": null, + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "write-intent.event_id: reject missing required property", + "instance": { + "schema_version": "1.0", + "intent_id": "intent_01J00000000000000000000002", + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "operation_type": "IDEA_ACCEPTED", + "phase": "PREPARED", + "event_sequence": null, + "staged_path": ".app/temp/intents/intent.json", + "command_sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "result": null, + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "write-intent.event_sequence: reject missing required property", + "instance": { + "schema_version": "1.0", + "intent_id": "intent_01J00000000000000000000002", + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "operation_type": "IDEA_ACCEPTED", + "phase": "PREPARED", + "event_id": null, + "staged_path": ".app/temp/intents/intent.json", + "command_sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "result": null, + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "write-intent.staged_path: reject missing required property", + "instance": { + "schema_version": "1.0", + "intent_id": "intent_01J00000000000000000000002", + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "operation_type": "IDEA_ACCEPTED", + "phase": "PREPARED", + "event_id": null, + "event_sequence": null, + "command_sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "result": null, + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "write-intent.command_sha256: reject missing required property", + "instance": { + "schema_version": "1.0", + "intent_id": "intent_01J00000000000000000000002", + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "operation_type": "IDEA_ACCEPTED", + "phase": "PREPARED", + "event_id": null, + "event_sequence": null, + "staged_path": ".app/temp/intents/intent.json", + "result": null, + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "write-intent.result: reject missing required property", + "instance": { + "schema_version": "1.0", + "intent_id": "intent_01J00000000000000000000002", + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "operation_type": "IDEA_ACCEPTED", + "phase": "PREPARED", + "event_id": null, + "event_sequence": null, + "staged_path": ".app/temp/intents/intent.json", + "command_sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "write-intent.created_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "intent_id": "intent_01J00000000000000000000002", + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "operation_type": "IDEA_ACCEPTED", + "phase": "PREPARED", + "event_id": null, + "event_sequence": null, + "staged_path": ".app/temp/intents/intent.json", + "command_sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "result": null, + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "write-intent.updated_at: reject missing required property", + "instance": { + "schema_version": "1.0", + "intent_id": "intent_01J00000000000000000000002", + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "operation_type": "IDEA_ACCEPTED", + "phase": "PREPARED", + "event_id": null, + "event_sequence": null, + "staged_path": ".app/temp/intents/intent.json", + "command_sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "result": null, + "created_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "write-intent: reject unexpected property", + "instance": { + "schema_version": "1.0", + "intent_id": "intent_01J00000000000000000000002", + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "operation_type": "IDEA_ACCEPTED", + "phase": "PREPARED", + "event_id": null, + "event_sequence": null, + "staged_path": ".app/temp/intents/intent.json", + "command_sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "result": null, + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:42:10.123Z", + "__unexpected": true + } + }, + { + "description": "write-intent.schema_version: reject value different from const", + "instance": { + "schema_version": "__INVALID_CONST__", + "intent_id": "intent_01J00000000000000000000002", + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "operation_type": "IDEA_ACCEPTED", + "phase": "PREPARED", + "event_id": null, + "event_sequence": null, + "staged_path": ".app/temp/intents/intent.json", + "command_sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "result": null, + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "write-intent.intent_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "intent_id": "invalid-id", + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "operation_type": "IDEA_ACCEPTED", + "phase": "PREPARED", + "event_id": null, + "event_sequence": null, + "staged_path": ".app/temp/intents/intent.json", + "command_sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "result": null, + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "write-intent.client_action_id: reject string below minLength", + "instance": { + "schema_version": "1.0", + "intent_id": "intent_01J00000000000000000000002", + "client_action_id": "", + "project_id": "project_01J00000000000000000000001", + "operation_type": "IDEA_ACCEPTED", + "phase": "PREPARED", + "event_id": null, + "event_sequence": null, + "staged_path": ".app/temp/intents/intent.json", + "command_sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "result": null, + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "write-intent.client_action_id: reject string above maxLength", + "instance": { + "schema_version": "1.0", + "intent_id": "intent_01J00000000000000000000002", + "client_action_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "project_id": "project_01J00000000000000000000001", + "operation_type": "IDEA_ACCEPTED", + "phase": "PREPARED", + "event_id": null, + "event_sequence": null, + "staged_path": ".app/temp/intents/intent.json", + "command_sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "result": null, + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "write-intent.project_id: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "intent_id": "intent_01J00000000000000000000002", + "client_action_id": "client-action-0001", + "project_id": "invalid-id", + "operation_type": "IDEA_ACCEPTED", + "phase": "PREPARED", + "event_id": null, + "event_sequence": null, + "staged_path": ".app/temp/intents/intent.json", + "command_sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "result": null, + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "write-intent.operation_type: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "intent_id": "intent_01J00000000000000000000002", + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "operation_type": " invalid!", + "phase": "PREPARED", + "event_id": null, + "event_sequence": null, + "staged_path": ".app/temp/intents/intent.json", + "command_sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "result": null, + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "write-intent.phase: reject value outside enum", + "instance": { + "schema_version": "1.0", + "intent_id": "intent_01J00000000000000000000002", + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "operation_type": "IDEA_ACCEPTED", + "phase": "__INVALID_ENUM__", + "event_id": null, + "event_sequence": null, + "staged_path": ".app/temp/intents/intent.json", + "command_sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "result": null, + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "write-intent.staged_path: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "intent_id": "intent_01J00000000000000000000002", + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "operation_type": "IDEA_ACCEPTED", + "phase": "PREPARED", + "event_id": null, + "event_sequence": null, + "staged_path": "../outside-project", + "command_sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "result": null, + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "write-intent.staged_path: reject string below minLength", + "instance": { + "schema_version": "1.0", + "intent_id": "intent_01J00000000000000000000002", + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "operation_type": "IDEA_ACCEPTED", + "phase": "PREPARED", + "event_id": null, + "event_sequence": null, + "staged_path": "", + "command_sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "result": null, + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "write-intent.command_sha256: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "intent_id": "intent_01J00000000000000000000002", + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "operation_type": "IDEA_ACCEPTED", + "phase": "PREPARED", + "event_id": null, + "event_sequence": null, + "staged_path": ".app/temp/intents/intent.json", + "command_sha256": "sha256:INVALID", + "result": null, + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "write-intent.created_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "intent_id": "intent_01J00000000000000000000002", + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "operation_type": "IDEA_ACCEPTED", + "phase": "PREPARED", + "event_id": null, + "event_sequence": null, + "staged_path": ".app/temp/intents/intent.json", + "command_sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "result": null, + "created_at": "not-a-timestamp", + "updated_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "description": "write-intent.updated_at: reject pattern mismatch", + "instance": { + "schema_version": "1.0", + "intent_id": "intent_01J00000000000000000000002", + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "operation_type": "IDEA_ACCEPTED", + "phase": "PREPARED", + "event_id": null, + "event_sequence": null, + "staged_path": ".app/temp/intents/intent.json", + "command_sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "result": null, + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "not-a-timestamp" + } + } + ] +} diff --git a/schemas/provenance/v1/fixtures/valid/backup-manifest.valid.json b/schemas/provenance/v1/fixtures/valid/backup-manifest.valid.json new file mode 100644 index 0000000..31302d8 --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/backup-manifest.valid.json @@ -0,0 +1,28 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/backup-manifest.schema.json", + "description": "Valid Project backup manifest example.", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "sqlite_version": "3.46.0", + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [ + { + "path": "project.json", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": 256 + } + ], + "protected": false, + "recovery_key_envelope_path": null + } +} diff --git a/schemas/provenance/v1/fixtures/valid/chain-head.valid.json b/schemas/provenance/v1/fixtures/valid/chain-head.valid.json new file mode 100644 index 0000000..d18724e --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/chain-head.valid.json @@ -0,0 +1,13 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/chain-head.schema.json", + "description": "Valid Chain head example.", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "active_segment_number": 1, + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "updated_at": "2026-07-17T18:42:10.123Z" + } +} diff --git a/schemas/provenance/v1/fixtures/valid/content-reference.valid.json b/schemas/provenance/v1/fixtures/valid/content-reference.valid.json new file mode 100644 index 0000000..f63350d --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/content-reference.valid.json @@ -0,0 +1,21 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/content-reference.schema.json", + "description": "Valid Content reference example.", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } +} diff --git a/schemas/provenance/v1/fixtures/valid/conversation-session.valid.json b/schemas/provenance/v1/fixtures/valid/conversation-session.valid.json new file mode 100644 index 0000000..5ac379d --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/conversation-session.valid.json @@ -0,0 +1,16 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/conversation-session.schema.json", + "description": "Valid Conversation session example.", + "instance": { + "schema_version": "1.0", + "session_id": "session_01J00000000000000000000006", + "project_id": "project_01J00000000000000000000001", + "title": "Opening discussion", + "mode": "typed", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "turn_count": 2, + "audio_retained": false, + "retention_mode": "minimal" + } +} diff --git a/schemas/provenance/v1/fixtures/valid/derived-index-manifest.valid.json b/schemas/provenance/v1/fixtures/valid/derived-index-manifest.valid.json new file mode 100644 index 0000000..0396425 --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/derived-index-manifest.valid.json @@ -0,0 +1,17 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/derived-index-manifest.schema.json", + "description": "Valid Derived index manifest example.", + "instance": { + "schema_version": "1.0", + "index_type": "contribution_graph", + "source_chain_head": "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "source_event_count": 42, + "generator": { + "name": "thinkloom-indexer", + "version": "1.0.0", + "configuration_sha256": "sha256:0000000000000000000000000000000000000000000000000000000000000000" + }, + "content_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "generated_at": "2026-07-17T18:42:10.123Z" + } +} diff --git a/schemas/provenance/v1/fixtures/valid/disposition-revision.valid.json b/schemas/provenance/v1/fixtures/valid/disposition-revision.valid.json new file mode 100644 index 0000000..783cdc8 --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/disposition-revision.valid.json @@ -0,0 +1,32 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/disposition-revision.schema.json", + "description": "Valid Invocation disposition revision example.", + "instance": { + "schema_version": "1.0", + "disposition_id": "disposition_01J0000000000000000000000M", + "invocation_id": "invocation_01J00000000000000000000008", + "revision_number": 1, + "status": "partially_accepted", + "accepted_ranges": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "rejected_ranges": [], + "destination": { + "revision_id": "revision_01J0000000000000000000000B", + "path": "manuscript/revisions/revision.md", + "operation": "insert", + "position": 0 + }, + "stale_context_resolution": "revalidated", + "decided_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } +} diff --git a/schemas/provenance/v1/fixtures/valid/edit-transaction.valid.json b/schemas/provenance/v1/fixtures/valid/edit-transaction.valid.json new file mode 100644 index 0000000..913713e --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/edit-transaction.valid.json @@ -0,0 +1,24 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/edit-transaction.schema.json", + "description": "Valid Manuscript edit transaction example.", + "instance": { + "schema_version": "1.0", + "transaction_id": "transaction_01J0000000000000000000000N", + "project_id": "project_01J00000000000000000000001", + "base_revision_id": "revision_01J0000000000000000000000A", + "result_revision_id": "revision_01J0000000000000000000000B", + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "operations": [ + { + "operation_type": "insert", + "source_range": null, + "destination_position": 0, + "inserted_text_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "result_fragment_id": "fragment_01J0000000000000000000000C" + } + ], + "preimage_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "result_sha256": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + } +} diff --git a/schemas/provenance/v1/fixtures/valid/encrypted-key-envelope.valid.json b/schemas/provenance/v1/fixtures/valid/encrypted-key-envelope.valid.json new file mode 100644 index 0000000..fce7aaa --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/encrypted-key-envelope.valid.json @@ -0,0 +1,16 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/encrypted-key-envelope.schema.json", + "description": "Valid Encrypted key envelope example.", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J00000000000000000000005", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "device", + "algorithm": "xchacha20-poly1305", + "key_derivation": null, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } +} diff --git a/schemas/provenance/v1/fixtures/valid/idea-revision.valid.json b/schemas/provenance/v1/fixtures/valid/idea-revision.valid.json new file mode 100644 index 0000000..446fdf9 --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/idea-revision.valid.json @@ -0,0 +1,23 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/idea-revision.schema.json", + "description": "Valid Idea revision example.", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "idea_id": "idea_01J00000000000000000000009", + "revision_number": 1, + "title": "Attention as civic infrastructure", + "summary": "Institutions influence shared attention.", + "detail": "Treat attention as a public condition.", + "tags": [ + "thesis" + ], + "source_turn_ids": [ + "turn_01J00000000000000000000007" + ], + "parent_idea_ids": [], + "created_by": "mixed", + "created_at": "2026-07-17T18:42:10.123Z", + "content_sha256": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + } +} diff --git a/schemas/provenance/v1/fixtures/valid/idea.valid.json b/schemas/provenance/v1/fixtures/valid/idea.valid.json new file mode 100644 index 0000000..6f15d22 --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/idea.valid.json @@ -0,0 +1,13 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/idea.schema.json", + "description": "Valid Idea identity example.", + "instance": { + "schema_version": "1.0", + "idea_id": "idea_01J00000000000000000000009", + "project_id": "project_01J00000000000000000000001", + "current_revision_id": "revision_01J0000000000000000000000A", + "status": "accepted", + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z" + } +} diff --git a/schemas/provenance/v1/fixtures/valid/invocation-failure.valid.json b/schemas/provenance/v1/fixtures/valid/invocation-failure.valid.json new file mode 100644 index 0000000..085665d --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/invocation-failure.valid.json @@ -0,0 +1,15 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/invocation-failure.schema.json", + "description": "Valid Invocation failure example.", + "instance": { + "schema_version": "1.0", + "failure_id": "failure_01J0000000000000000000000P", + "invocation_id": "invocation_01J00000000000000000000008", + "code": "PROVIDER_TIMEOUT", + "category": "provider", + "recoverable": true, + "bounded_summary": "The provider did not respond within the configured timeout.", + "partial_output_preserved": false, + "occurred_at": "2026-07-17T18:43:11.456Z" + } +} diff --git a/schemas/provenance/v1/fixtures/valid/invocation-request.valid.json b/schemas/provenance/v1/fixtures/valid/invocation-request.valid.json new file mode 100644 index 0000000..c73dcb1 --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/invocation-request.valid.json @@ -0,0 +1,62 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/invocation-request.schema.json", + "description": "Valid Invocation request example.", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } +} diff --git a/schemas/provenance/v1/fixtures/valid/invocation-response.valid.json b/schemas/provenance/v1/fixtures/valid/invocation-response.valid.json new file mode 100644 index 0000000..a929523 --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/invocation-response.valid.json @@ -0,0 +1,27 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/invocation-response.schema.json", + "description": "Valid Invocation response example.", + "instance": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "invocation_id": "invocation_01J00000000000000000000008", + "retention_mode": "full_private", + "content_type": "draft_preview", + "retained_text": "Attention is personal in experience and public in consequence.", + "finish_reason": "stop", + "usage": { + "input_tokens": 120, + "output_tokens": 14 + }, + "provider_metadata": { + "request_id": "local-0001", + "load_duration_milliseconds": 120 + }, + "validation": { + "schema_valid": true, + "repair_attempted": false + }, + "content_sha256": "sha256:9999999999999999999999999999999999999999999999999999999999999999", + "created_at": "2026-07-17T18:43:11.456Z" + } +} diff --git a/schemas/provenance/v1/fixtures/valid/invocation-state.valid.json b/schemas/provenance/v1/fixtures/valid/invocation-state.valid.json new file mode 100644 index 0000000..11d2088 --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/invocation-state.valid.json @@ -0,0 +1,12 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/invocation-state.schema.json", + "description": "Valid Invocation state example.", + "instance": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "state": "REQUEST_RECORDED", + "state_sequence": 2, + "updated_at": "2026-07-17T18:42:10.123Z", + "failure_id": null + } +} diff --git a/schemas/provenance/v1/fixtures/valid/invocation-stream-state.valid.json b/schemas/provenance/v1/fixtures/valid/invocation-stream-state.valid.json new file mode 100644 index 0000000..dc0591b --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/invocation-stream-state.valid.json @@ -0,0 +1,13 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/invocation-stream-state.schema.json", + "description": "Valid Invocation stream state example.", + "instance": { + "schema_version": "1.0", + "stream_id": "stream_01J0000000000000000000000Q", + "invocation_id": "invocation_01J00000000000000000000008", + "state": "STREAMING", + "bytes_received": 512, + "started_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z" + } +} diff --git a/schemas/provenance/v1/fixtures/valid/invocation-stream-summary.valid.json b/schemas/provenance/v1/fixtures/valid/invocation-stream-summary.valid.json new file mode 100644 index 0000000..499f528 --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/invocation-stream-summary.valid.json @@ -0,0 +1,15 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/invocation-stream-summary.schema.json", + "description": "Valid Invocation stream summary example.", + "instance": { + "schema_version": "1.0", + "stream_id": "stream_01J0000000000000000000000Q", + "invocation_id": "invocation_01J00000000000000000000008", + "terminal_state": "COMPLETED", + "bytes_received": 512, + "chunks_received": 4, + "duration_milliseconds": 2400, + "partial_output_preserved": false, + "completed_at": "2026-07-17T18:43:11.456Z" + } +} diff --git a/schemas/provenance/v1/fixtures/valid/ledger-segment-manifest.valid.json b/schemas/provenance/v1/fixtures/valid/ledger-segment-manifest.valid.json new file mode 100644 index 0000000..4af97cc --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/ledger-segment-manifest.valid.json @@ -0,0 +1,18 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/ledger-segment-manifest.schema.json", + "description": "Valid Ledger segment manifest example.", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "segment_number": 1, + "previous_segment_file_hash": null, + "first_event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "final_event_hash": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "first_event_sequence": 1, + "final_event_sequence": 2, + "event_count": 2, + "byte_length": 1024, + "segment_file_hash": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "sealed_at": "2026-07-17T18:42:10.123Z" + } +} diff --git a/schemas/provenance/v1/fixtures/valid/manuscript-revision.valid.json b/schemas/provenance/v1/fixtures/valid/manuscript-revision.valid.json new file mode 100644 index 0000000..0686c30 --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/manuscript-revision.valid.json @@ -0,0 +1,15 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/manuscript-revision.schema.json", + "description": "Valid Manuscript revision example.", + "instance": { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "project_id": "project_01J00000000000000000000001", + "parent_revision_id": null, + "canonical_markdown_path": "manuscript/revisions/revision.md", + "canonical_markdown_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "word_count": 42, + "created_by": "user", + "created_at": "2026-07-17T18:42:10.123Z" + } +} diff --git a/schemas/provenance/v1/fixtures/valid/model-capability-snapshot.valid.json b/schemas/provenance/v1/fixtures/valid/model-capability-snapshot.valid.json new file mode 100644 index 0000000..ddddbf3 --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/model-capability-snapshot.valid.json @@ -0,0 +1,17 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/model-capability-snapshot.schema.json", + "description": "Valid Model capability snapshot example.", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "capabilities": { + "streaming": true, + "structured_output": false, + "tools": false, + "vision": false + }, + "observed_at": "2026-07-17T18:42:10.123Z" + } +} diff --git a/schemas/provenance/v1/fixtures/valid/model-configuration-snapshot.valid.json b/schemas/provenance/v1/fixtures/valid/model-configuration-snapshot.valid.json new file mode 100644 index 0000000..b7e16a5 --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/model-configuration-snapshot.valid.json @@ -0,0 +1,19 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/model-configuration-snapshot.schema.json", + "description": "Valid Model configuration snapshot example.", + "instance": { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local", + "endpoint_classification": "loopback", + "temperature_milli": 700, + "context_limit": 8192, + "maximum_output": 800, + "structured_output_mode": "none", + "tool_configuration": [], + "capability_snapshot_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "created_at": "2026-07-17T18:42:10.123Z" + } +} diff --git a/schemas/provenance/v1/fixtures/valid/project-key-manifest.valid.json b/schemas/provenance/v1/fixtures/valid/project-key-manifest.valid.json new file mode 100644 index 0000000..148ba0b --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/project-key-manifest.valid.json @@ -0,0 +1,14 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/project-key-manifest.schema.json", + "description": "Valid Project key manifest example.", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "key_id": "key_01J0000000000000000000000G", + "algorithm": "xchacha20-poly1305", + "device_envelope_path": "provenance/keys/device-envelope.json", + "recovery_envelope_path": "provenance/keys/recovery-envelope.json", + "recovery_verified_at": "2026-07-17T18:42:10.123Z", + "created_at": "2026-07-17T18:42:10.123Z" + } +} diff --git a/schemas/provenance/v1/fixtures/valid/project-manifest.valid.json b/schemas/provenance/v1/fixtures/valid/project-manifest.valid.json new file mode 100644 index 0000000..50fc212 --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/project-manifest.valid.json @@ -0,0 +1,16 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/project-manifest.schema.json", + "description": "Valid Project manifest example.", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "title": "The Attention Commons", + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z", + "current_phase": "ideation", + "publication_status": "working", + "provenance_policy_id": "policy_01J0000000000000000000000H", + "audio_retained": false + } +} diff --git a/schemas/provenance/v1/fixtures/valid/prompt-template-reference.valid.json b/schemas/provenance/v1/fixtures/valid/prompt-template-reference.valid.json new file mode 100644 index 0000000..cc63aef --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/prompt-template-reference.valid.json @@ -0,0 +1,11 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/prompt-template-reference.schema.json", + "description": "Valid Prompt template reference example.", + "instance": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + } +} diff --git a/schemas/provenance/v1/fixtures/valid/prompt-template.valid.json b/schemas/provenance/v1/fixtures/valid/prompt-template.valid.json new file mode 100644 index 0000000..afea2c0 --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/prompt-template.valid.json @@ -0,0 +1,21 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/prompt-template.schema.json", + "description": "Valid Prompt template example.", + "instance": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "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": "sha256:7777777777777777777777777777777777777777777777777777777777777777", + "created_at": "2026-07-17T18:42:10.123Z" + } +} diff --git a/schemas/provenance/v1/fixtures/valid/provenance-event.valid.json b/schemas/provenance/v1/fixtures/valid/provenance-event.valid.json new file mode 100644 index 0000000..3a170fa --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/provenance-event.valid.json @@ -0,0 +1,47 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/provenance-event.schema.json", + "description": "Valid Provenance event example.", + "instance": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } +} diff --git a/schemas/provenance/v1/fixtures/valid/provenance-policy.valid.json b/schemas/provenance/v1/fixtures/valid/provenance-policy.valid.json new file mode 100644 index 0000000..4a1c1a6 --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/provenance-policy.valid.json @@ -0,0 +1,13 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/provenance-policy.schema.json", + "description": "Valid Provenance policy example.", + "instance": { + "schema_version": "1.0", + "policy_id": "policy_01J0000000000000000000000H", + "project_id": "project_01J00000000000000000000001", + "retention_mode": "minimal", + "encryption_mode": "none", + "default_export_profile": "sanitized", + "effective_at": "2026-07-17T18:42:10.123Z" + } +} diff --git a/schemas/provenance/v1/fixtures/valid/purge-manifest.valid.json b/schemas/provenance/v1/fixtures/valid/purge-manifest.valid.json new file mode 100644 index 0000000..84d41da --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/purge-manifest.valid.json @@ -0,0 +1,23 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/purge-manifest.schema.json", + "description": "Valid Emergency purge manifest example.", + "instance": { + "schema_version": "1.0", + "purge_id": "purge_01J0000000000000000000000R", + "project_id": "project_01J00000000000000000000001", + "requested_at": "2026-07-17T18:42:10.123Z", + "completed_at": "2026-07-17T18:43:11.456Z", + "reason": "Remove accidentally retained credential", + "superseded_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "new_chain_root": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "affected_record_ids": [ + "record_01J00000000000000000000005" + ], + "affected_paths": [ + "records/invocations/request.json" + ], + "git_history_rewritten": true, + "prior_copies_revocable": false, + "confirmation_phrase_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + } +} diff --git a/schemas/provenance/v1/fixtures/valid/record-envelope.valid.json b/schemas/provenance/v1/fixtures/valid/record-envelope.valid.json new file mode 100644 index 0000000..6f5489a --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/record-envelope.valid.json @@ -0,0 +1,20 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/record-envelope.schema.json", + "description": "Valid Authoritative record envelope example.", + "instance": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "record_id": "record_01J00000000000000000000005", + "record_type": "invocation_request", + "protection": "protected", + "plaintext_sha256": "sha256:97154eddff15ab6607181e55945547fdbbc5bde02b1e5123eade7a69509f00c5", + "payload": null, + "encryption": { + "algorithm": "xchacha20-poly1305", + "key_id": "key_01J0000000000000000000000G", + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "ciphertext": "ZW5jcnlwdGVkLXJlY29yZA==", + "ciphertext_sha256": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + } + } +} diff --git a/schemas/provenance/v1/fixtures/valid/recovery-key-envelope.valid.json b/schemas/provenance/v1/fixtures/valid/recovery-key-envelope.valid.json new file mode 100644 index 0000000..4cb2623 --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/recovery-key-envelope.valid.json @@ -0,0 +1,22 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/recovery-key-envelope.schema.json", + "description": "Valid Recovery key envelope example.", + "instance": { + "schema_version": "1.0", + "envelope_id": "record_01J0000000000000000000000S", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "recovery", + "algorithm": "xchacha20-poly1305", + "key_derivation": { + "algorithm": "argon2id", + "memory_kib": 65536, + "iterations": 3, + "parallelism": 1, + "salt": "c2FsdC1mb3ItdGhpbmtsb29t" + }, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } +} diff --git a/schemas/provenance/v1/fixtures/valid/release-manifest.valid.json b/schemas/provenance/v1/fixtures/valid/release-manifest.valid.json new file mode 100644 index 0000000..f2ba254 --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/release-manifest.valid.json @@ -0,0 +1,33 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/release-manifest.schema.json", + "description": "Valid Release manifest example.", + "instance": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } +} diff --git a/schemas/provenance/v1/fixtures/valid/release-state.valid.json b/schemas/provenance/v1/fixtures/valid/release-state.valid.json new file mode 100644 index 0000000..e7b3bf8 --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/release-state.valid.json @@ -0,0 +1,15 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/release-state.schema.json", + "description": "Valid Release state example.", + "instance": { + "schema_version": "1.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "state": "RELEASE_STAGED", + "state_sequence": 5, + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "updated_at": "2026-07-17T18:43:11.456Z", + "failure": null + } +} diff --git a/schemas/provenance/v1/fixtures/valid/sanitized-export-manifest.valid.json b/schemas/provenance/v1/fixtures/valid/sanitized-export-manifest.valid.json new file mode 100644 index 0000000..dcec593 --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/sanitized-export-manifest.valid.json @@ -0,0 +1,27 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/sanitized-export-manifest.schema.json", + "description": "Valid Sanitized export manifest example.", + "instance": { + "schema_version": "1.0", + "export_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "profile": "sanitized", + "omission_rules": [ + { + "category": "private_conversation", + "action": "exclude", + "count": 2 + } + ], + "rules_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "files": [ + { + "path": "final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + } + ], + "created_at": "2026-07-17T18:43:11.456Z" + } +} diff --git a/schemas/provenance/v1/fixtures/valid/text-fragment-reference.valid.json b/schemas/provenance/v1/fixtures/valid/text-fragment-reference.valid.json new file mode 100644 index 0000000..135f616 --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/text-fragment-reference.valid.json @@ -0,0 +1,13 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/text-fragment-reference.schema.json", + "description": "Valid Text fragment reference example.", + "instance": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } +} diff --git a/schemas/provenance/v1/fixtures/valid/transcript-correction.valid.json b/schemas/provenance/v1/fixtures/valid/transcript-correction.valid.json new file mode 100644 index 0000000..cb22600 --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/transcript-correction.valid.json @@ -0,0 +1,14 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/transcript-correction.schema.json", + "description": "Valid Transcript correction example.", + "instance": { + "schema_version": "1.0", + "correction_id": "correction_01J0000000000000000000000J", + "turn_id": "turn_01J00000000000000000000007", + "revision_number": 1, + "corrected_text": "Attention shapes our public life.", + "reason": "user_correction", + "created_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } +} diff --git a/schemas/provenance/v1/fixtures/valid/transcript-normalization.valid.json b/schemas/provenance/v1/fixtures/valid/transcript-normalization.valid.json new file mode 100644 index 0000000..57461d9 --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/transcript-normalization.valid.json @@ -0,0 +1,15 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/transcript-normalization.schema.json", + "description": "Valid Transcript normalization example.", + "instance": { + "schema_version": "1.0", + "normalization_id": "normalization_01J0000000000000000000000K", + "turn_id": "turn_01J00000000000000000000007", + "revision_number": 1, + "normalized_text": "Attention shapes public life.", + "method": "application", + "source_correction_id": "correction_01J0000000000000000000000J", + "created_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } +} diff --git a/schemas/provenance/v1/fixtures/valid/transcript-turn.valid.json b/schemas/provenance/v1/fixtures/valid/transcript-turn.valid.json new file mode 100644 index 0000000..7e8b64b --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/transcript-turn.valid.json @@ -0,0 +1,18 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/transcript-turn.schema.json", + "description": "Valid Transcript turn example.", + "instance": { + "schema_version": "1.0", + "turn_id": "turn_01J00000000000000000000007", + "session_id": "session_01J00000000000000000000006", + "speaker": "user", + "input_mode": "typed", + "retained_text": "Attention shapes public life.", + "raw_transcript": null, + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "audio_retained": false, + "invocation_id": null, + "event_id": "event_01J00000000000000000000003" + } +} diff --git a/schemas/provenance/v1/fixtures/valid/verification-report.valid.json b/schemas/provenance/v1/fixtures/valid/verification-report.valid.json new file mode 100644 index 0000000..0869a98 --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/verification-report.valid.json @@ -0,0 +1,27 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/verification-report.schema.json", + "description": "Valid Verification report example.", + "instance": { + "schema_version": "1.0", + "verification_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "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": "2026-07-17T18:43:11.456Z" + } +} diff --git a/schemas/provenance/v1/fixtures/valid/write-intent.valid.json b/schemas/provenance/v1/fixtures/valid/write-intent.valid.json new file mode 100644 index 0000000..65444d7 --- /dev/null +++ b/schemas/provenance/v1/fixtures/valid/write-intent.valid.json @@ -0,0 +1,19 @@ +{ + "schema": "https://thinkloom.app/schemas/provenance/1.0/write-intent.schema.json", + "description": "Valid Cross-store write intent example.", + "instance": { + "schema_version": "1.0", + "intent_id": "intent_01J00000000000000000000002", + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "operation_type": "IDEA_ACCEPTED", + "phase": "PREPARED", + "event_id": null, + "event_sequence": null, + "staged_path": ".app/temp/intents/intent.json", + "command_sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "result": null, + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:42:10.123Z" + } +} diff --git a/schemas/provenance/v1/idea-revision.schema.json b/schemas/provenance/v1/idea-revision.schema.json new file mode 100644 index 0000000..2918bb2 --- /dev/null +++ b/schemas/provenance/v1/idea-revision.schema.json @@ -0,0 +1,112 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/idea-revision.schema.json", + "title": "Idea revision", + "description": "Immutable content revision for one idea.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "revision_id": { + "type": "string", + "pattern": "^revision_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "idea_id": { + "type": "string", + "pattern": "^idea_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "revision_number": { + "type": "integer", + "minimum": 1 + }, + "title": { + "type": "string", + "minLength": 1 + }, + "summary": { + "type": "string", + "minLength": 1 + }, + "detail": { + "type": "string" + }, + "tags": { + "type": "array", + "items": { + "type": "string", + "minLength": 1 + }, + "uniqueItems": true + }, + "source_turn_ids": { + "type": "array", + "items": { + "type": "string", + "pattern": "^turn_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "uniqueItems": true + }, + "parent_idea_ids": { + "type": "array", + "items": { + "type": "string", + "pattern": "^idea_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "uniqueItems": true + }, + "created_by": { + "enum": [ + "user", + "assistant", + "mixed" + ] + }, + "created_at": { + "type": "string", + "format": "date-time", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$" + }, + "content_sha256": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + } + }, + "required": [ + "schema_version", + "revision_id", + "idea_id", + "revision_number", + "title", + "summary", + "detail", + "tags", + "source_turn_ids", + "parent_idea_ids", + "created_by", + "created_at", + "content_sha256" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "idea_id": "idea_01J00000000000000000000009", + "revision_number": 1, + "title": "Attention as civic infrastructure", + "summary": "Institutions influence shared attention.", + "detail": "Treat attention as a public condition.", + "tags": [ + "thesis" + ], + "source_turn_ids": [ + "turn_01J00000000000000000000007" + ], + "parent_idea_ids": [], + "created_by": "mixed", + "created_at": "2026-07-17T18:42:10.123Z", + "content_sha256": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + } + ] +} diff --git a/schemas/provenance/v1/idea.schema.json b/schemas/provenance/v1/idea.schema.json new file mode 100644 index 0000000..331c42d --- /dev/null +++ b/schemas/provenance/v1/idea.schema.json @@ -0,0 +1,63 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/idea.schema.json", + "title": "Idea identity", + "description": "Stable idea identity and current derived status.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "idea_id": { + "type": "string", + "pattern": "^idea_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "project_id": { + "type": "string", + "pattern": "^project_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "current_revision_id": { + "type": "string", + "pattern": "^revision_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "status": { + "enum": [ + "suggested", + "accepted", + "rejected", + "archived" + ] + }, + "created_at": { + "type": "string", + "format": "date-time", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$" + }, + "updated_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", + "idea_id", + "project_id", + "current_revision_id", + "status", + "created_at", + "updated_at" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "idea_id": "idea_01J00000000000000000000009", + "project_id": "project_01J00000000000000000000001", + "current_revision_id": "revision_01J0000000000000000000000A", + "status": "accepted", + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z" + } + ] +} diff --git a/schemas/provenance/v1/invocation-failure.schema.json b/schemas/provenance/v1/invocation-failure.schema.json new file mode 100644 index 0000000..4b80231 --- /dev/null +++ b/schemas/provenance/v1/invocation-failure.schema.json @@ -0,0 +1,75 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/invocation-failure.schema.json", + "title": "Invocation failure", + "description": "Immutable bounded record of an invocation failure.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "failure_id": { + "type": "string", + "pattern": "^failure_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "invocation_id": { + "type": "string", + "pattern": "^invocation_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "code": { + "type": "string", + "pattern": "^[A-Z][A-Z0-9_]+$" + }, + "category": { + "enum": [ + "provider", + "validation", + "cancellation", + "output_limit", + "application", + "privacy" + ] + }, + "recoverable": { + "type": "boolean" + }, + "bounded_summary": { + "type": "string", + "minLength": 1, + "maxLength": 2000 + }, + "partial_output_preserved": { + "type": "boolean" + }, + "occurred_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", + "failure_id", + "invocation_id", + "code", + "category", + "recoverable", + "bounded_summary", + "partial_output_preserved", + "occurred_at" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "failure_id": "failure_01J0000000000000000000000P", + "invocation_id": "invocation_01J00000000000000000000008", + "code": "PROVIDER_TIMEOUT", + "category": "provider", + "recoverable": true, + "bounded_summary": "The provider did not respond within the configured timeout.", + "partial_output_preserved": false, + "occurred_at": "2026-07-17T18:43:11.456Z" + } + ] +} diff --git a/schemas/provenance/v1/invocation-request.schema.json b/schemas/provenance/v1/invocation-request.schema.json new file mode 100644 index 0000000..ea209af --- /dev/null +++ b/schemas/provenance/v1/invocation-request.schema.json @@ -0,0 +1,237 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/invocation-request.schema.json", + "title": "Invocation request", + "description": "Credential-free immutable provider request evidence; minimal mode may omit messages.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "invocation_id": { + "type": "string", + "pattern": "^invocation_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "project_id": { + "type": "string", + "pattern": "^project_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "purpose": { + "type": "string", + "pattern": "^[a-z][a-z0-9_]+$" + }, + "initiated_by_event_id": { + "type": "string", + "pattern": "^event_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "retention_mode": { + "enum": [ + "minimal", + "full_private" + ] + }, + "provider": { + "type": "object", + "properties": { + "provider_id": { + "type": "string", + "minLength": 1 + }, + "model_id": { + "type": "string", + "minLength": 1 + }, + "processing_mode": { + "enum": [ + "local", + "cloud" + ] + } + }, + "required": [ + "provider_id", + "model_id", + "processing_mode" + ], + "additionalProperties": false + }, + "model_configuration_sha256": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + }, + "prompt_template": { + "$ref": "https://thinkloom.app/schemas/provenance/1.0/prompt-template-reference.schema.json" + }, + "messages": { + "type": "array", + "items": { + "type": "object", + "properties": { + "role": { + "enum": [ + "system", + "user", + "assistant", + "tool" + ] + }, + "content": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "role", + "content" + ], + "additionalProperties": false + } + }, + "context_references": { + "type": "array", + "items": { + "$ref": "https://thinkloom.app/schemas/provenance/1.0/content-reference.schema.json" + } + }, + "manuscript_revision_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^revision_[0-9A-HJKMNP-TV-Z]{26}$" + }, + { + "type": "null" + } + ] + }, + "idea_revision_ids": { + "type": "array", + "items": { + "type": "string", + "pattern": "^revision_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "uniqueItems": true + }, + "conversation_head": { + "anyOf": [ + { + "type": "string", + "pattern": "^turn_[0-9A-HJKMNP-TV-Z]{26}$" + }, + { + "type": "null" + } + ] + }, + "submitted_at": { + "type": "string", + "format": "date-time", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$" + }, + "redactions": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "enum": [ + "credential", + "personal_identifier", + "signed_url", + "policy_omission", + "other" + ] + }, + "replacement": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "category", + "replacement" + ], + "additionalProperties": false + } + } + }, + "required": [ + "schema_version", + "invocation_id", + "project_id", + "purpose", + "initiated_by_event_id", + "retention_mode", + "provider", + "model_configuration_sha256", + "prompt_template", + "messages", + "context_references", + "manuscript_revision_id", + "idea_revision_ids", + "conversation_head", + "submitted_at", + "redactions" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + } + ] +} diff --git a/schemas/provenance/v1/invocation-response.schema.json b/schemas/provenance/v1/invocation-response.schema.json new file mode 100644 index 0000000..5aa931c --- /dev/null +++ b/schemas/provenance/v1/invocation-response.schema.json @@ -0,0 +1,171 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/invocation-response.schema.json", + "title": "Invocation response", + "description": "Immutable response evidence filtered according to retention policy.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "record_id": { + "type": "string", + "pattern": "^record_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "invocation_id": { + "type": "string", + "pattern": "^invocation_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "retention_mode": { + "enum": [ + "minimal", + "full_private" + ] + }, + "content_type": { + "enum": [ + "conversation_reply", + "idea_suggestion", + "draft_preview", + "editorial_preview", + "structured_result", + "other" + ] + }, + "retained_text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "finish_reason": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "null" + } + ] + }, + "usage": { + "anyOf": [ + { + "type": "object", + "properties": { + "input_tokens": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "null" + } + ] + }, + "output_tokens": { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "input_tokens", + "output_tokens" + ], + "additionalProperties": false + }, + { + "type": "null" + } + ] + }, + "provider_metadata": { + "anyOf": [ + { + "type": "object" + }, + { + "type": "null" + } + ] + }, + "validation": { + "type": "object", + "properties": { + "schema_valid": { + "type": "boolean" + }, + "repair_attempted": { + "type": "boolean" + } + }, + "required": [ + "schema_valid", + "repair_attempted" + ], + "additionalProperties": false + }, + "content_sha256": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + }, + "created_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", + "record_id", + "invocation_id", + "retention_mode", + "content_type", + "retained_text", + "finish_reason", + "usage", + "provider_metadata", + "validation", + "content_sha256", + "created_at" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "invocation_id": "invocation_01J00000000000000000000008", + "retention_mode": "full_private", + "content_type": "draft_preview", + "retained_text": "Attention is personal in experience and public in consequence.", + "finish_reason": "stop", + "usage": { + "input_tokens": 120, + "output_tokens": 14 + }, + "provider_metadata": { + "request_id": "local-0001", + "load_duration_milliseconds": 120 + }, + "validation": { + "schema_valid": true, + "repair_attempted": false + }, + "content_sha256": "sha256:9999999999999999999999999999999999999999999999999999999999999999", + "created_at": "2026-07-17T18:43:11.456Z" + } + ] +} diff --git a/schemas/provenance/v1/invocation-state.schema.json b/schemas/provenance/v1/invocation-state.schema.json new file mode 100644 index 0000000..61d44ec --- /dev/null +++ b/schemas/provenance/v1/invocation-state.schema.json @@ -0,0 +1,68 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/invocation-state.schema.json", + "title": "Invocation state", + "description": "Operational invocation lifecycle projection.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "invocation_id": { + "type": "string", + "pattern": "^invocation_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "state": { + "enum": [ + "REQUEST_PREPARED", + "REQUEST_RECORDED", + "MODEL_RUNNING", + "RESPONSE_RECEIVED", + "RESPONSE_RECORDED", + "STAGED_PREVIEW", + "FAILED", + "CANCELLED", + "ABANDONED" + ] + }, + "state_sequence": { + "type": "integer", + "minimum": 1 + }, + "updated_at": { + "type": "string", + "format": "date-time", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$" + }, + "failure_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^failure_[0-9A-HJKMNP-TV-Z]{26}$" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "schema_version", + "invocation_id", + "state", + "state_sequence", + "updated_at", + "failure_id" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "state": "REQUEST_RECORDED", + "state_sequence": 2, + "updated_at": "2026-07-17T18:42:10.123Z", + "failure_id": null + } + ] +} diff --git a/schemas/provenance/v1/invocation-stream-state.schema.json b/schemas/provenance/v1/invocation-stream-state.schema.json new file mode 100644 index 0000000..3891a81 --- /dev/null +++ b/schemas/provenance/v1/invocation-stream-state.schema.json @@ -0,0 +1,68 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/invocation-stream-state.schema.json", + "title": "Invocation stream state", + "description": "Non-authoritative operational streaming state.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "stream_id": { + "type": "string", + "pattern": "^stream_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "invocation_id": { + "type": "string", + "pattern": "^invocation_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "state": { + "enum": [ + "CREATED", + "CONNECTING", + "STREAMING", + "COMPLETED", + "FAILED", + "CANCELLED", + "ABANDONED", + "RECOVERING" + ] + }, + "bytes_received": { + "type": "integer", + "minimum": 0, + "maximum": 67108864 + }, + "started_at": { + "type": "string", + "format": "date-time", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$" + }, + "updated_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", + "stream_id", + "invocation_id", + "state", + "bytes_received", + "started_at", + "updated_at" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "stream_id": "stream_01J0000000000000000000000Q", + "invocation_id": "invocation_01J00000000000000000000008", + "state": "STREAMING", + "bytes_received": 512, + "started_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z" + } + ] +} diff --git a/schemas/provenance/v1/invocation-stream-summary.schema.json b/schemas/provenance/v1/invocation-stream-summary.schema.json new file mode 100644 index 0000000..92923d6 --- /dev/null +++ b/schemas/provenance/v1/invocation-stream-summary.schema.json @@ -0,0 +1,75 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/invocation-stream-summary.schema.json", + "title": "Invocation stream summary", + "description": "Bounded immutable summary of a completed or interrupted stream.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "stream_id": { + "type": "string", + "pattern": "^stream_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "invocation_id": { + "type": "string", + "pattern": "^invocation_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "terminal_state": { + "enum": [ + "COMPLETED", + "FAILED", + "CANCELLED", + "ABANDONED" + ] + }, + "bytes_received": { + "type": "integer", + "minimum": 0, + "maximum": 67108864 + }, + "chunks_received": { + "type": "integer", + "minimum": 0 + }, + "duration_milliseconds": { + "type": "integer", + "minimum": 0, + "maximum": 1800000 + }, + "partial_output_preserved": { + "type": "boolean" + }, + "completed_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", + "stream_id", + "invocation_id", + "terminal_state", + "bytes_received", + "chunks_received", + "duration_milliseconds", + "partial_output_preserved", + "completed_at" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "stream_id": "stream_01J0000000000000000000000Q", + "invocation_id": "invocation_01J00000000000000000000008", + "terminal_state": "COMPLETED", + "bytes_received": 512, + "chunks_received": 4, + "duration_milliseconds": 2400, + "partial_output_preserved": false, + "completed_at": "2026-07-17T18:43:11.456Z" + } + ] +} diff --git a/schemas/provenance/v1/ledger-segment-manifest.schema.json b/schemas/provenance/v1/ledger-segment-manifest.schema.json new file mode 100644 index 0000000..cac108d --- /dev/null +++ b/schemas/provenance/v1/ledger-segment-manifest.schema.json @@ -0,0 +1,95 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/ledger-segment-manifest.schema.json", + "title": "Ledger segment manifest", + "description": "Immutable seal for one ledger segment.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "project_id": { + "type": "string", + "pattern": "^project_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "segment_number": { + "type": "integer", + "minimum": 1 + }, + "previous_segment_file_hash": { + "anyOf": [ + { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + }, + { + "type": "null" + } + ] + }, + "first_event_hash": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + }, + "final_event_hash": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + }, + "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": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + }, + "sealed_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", + "project_id", + "segment_number", + "previous_segment_file_hash", + "first_event_hash", + "final_event_hash", + "first_event_sequence", + "final_event_sequence", + "event_count", + "byte_length", + "segment_file_hash", + "sealed_at" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "segment_number": 1, + "previous_segment_file_hash": null, + "first_event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "final_event_hash": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "first_event_sequence": 1, + "final_event_sequence": 2, + "event_count": 2, + "byte_length": 1024, + "segment_file_hash": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "sealed_at": "2026-07-17T18:42:10.123Z" + } + ] +} diff --git a/schemas/provenance/v1/manuscript-revision.schema.json b/schemas/provenance/v1/manuscript-revision.schema.json new file mode 100644 index 0000000..424f5d4 --- /dev/null +++ b/schemas/provenance/v1/manuscript-revision.schema.json @@ -0,0 +1,81 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/manuscript-revision.schema.json", + "title": "Manuscript revision", + "description": "Immutable canonical manuscript revision.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "revision_id": { + "type": "string", + "pattern": "^revision_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "project_id": { + "type": "string", + "pattern": "^project_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "parent_revision_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^revision_[0-9A-HJKMNP-TV-Z]{26}$" + }, + { + "type": "null" + } + ] + }, + "canonical_markdown_path": { + "type": "string", + "minLength": 1, + "pattern": "^(?!/)(?![A-Za-z]:)(?!.*\\\\)(?!.*(?:^|/)\\.\\.?(?:/|$))[^\\u0000-\\u001f]+$" + }, + "canonical_markdown_sha256": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + }, + "word_count": { + "type": "integer", + "minimum": 0 + }, + "created_by": { + "enum": [ + "user", + "assistant_acceptance", + "system_restore" + ] + }, + "created_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", + "revision_id", + "project_id", + "parent_revision_id", + "canonical_markdown_path", + "canonical_markdown_sha256", + "word_count", + "created_by", + "created_at" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "revision_id": "revision_01J0000000000000000000000A", + "project_id": "project_01J00000000000000000000001", + "parent_revision_id": null, + "canonical_markdown_path": "manuscript/revisions/revision.md", + "canonical_markdown_sha256": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "word_count": 42, + "created_by": "user", + "created_at": "2026-07-17T18:42:10.123Z" + } + ] +} diff --git a/schemas/provenance/v1/model-capability-snapshot.schema.json b/schemas/provenance/v1/model-capability-snapshot.schema.json new file mode 100644 index 0000000..24fe7f1 --- /dev/null +++ b/schemas/provenance/v1/model-capability-snapshot.schema.json @@ -0,0 +1,77 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/model-capability-snapshot.schema.json", + "title": "Model capability snapshot", + "description": "Immutable observed capability set for an invoked model.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "snapshot_id": { + "type": "string", + "pattern": "^record_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "provider_id": { + "type": "string", + "minLength": 1 + }, + "model_id": { + "type": "string", + "minLength": 1 + }, + "capabilities": { + "type": "object", + "properties": { + "streaming": { + "type": "boolean" + }, + "structured_output": { + "type": "boolean" + }, + "tools": { + "type": "boolean" + }, + "vision": { + "type": "boolean" + } + }, + "required": [ + "streaming", + "structured_output", + "tools", + "vision" + ], + "additionalProperties": false + }, + "observed_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", + "snapshot_id", + "provider_id", + "model_id", + "capabilities", + "observed_at" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "capabilities": { + "streaming": true, + "structured_output": false, + "tools": false, + "vision": false + }, + "observed_at": "2026-07-17T18:42:10.123Z" + } + ] +} diff --git a/schemas/provenance/v1/model-configuration-snapshot.schema.json b/schemas/provenance/v1/model-configuration-snapshot.schema.json new file mode 100644 index 0000000..2a1c4ac --- /dev/null +++ b/schemas/provenance/v1/model-configuration-snapshot.schema.json @@ -0,0 +1,130 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/model-configuration-snapshot.schema.json", + "title": "Model configuration snapshot", + "description": "Effective credential-free model settings used by one invocation.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "snapshot_id": { + "type": "string", + "pattern": "^record_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "provider_id": { + "type": "string", + "minLength": 1 + }, + "model_id": { + "type": "string", + "minLength": 1 + }, + "processing_mode": { + "enum": [ + "local", + "cloud" + ] + }, + "endpoint_classification": { + "enum": [ + "loopback", + "private_network", + "public_cloud", + "custom" + ] + }, + "temperature_milli": { + "anyOf": [ + { + "type": "integer", + "minimum": 0, + "maximum": 2000 + }, + { + "type": "null" + } + ] + }, + "context_limit": { + "anyOf": [ + { + "type": "integer", + "minimum": 1 + }, + { + "type": "null" + } + ] + }, + "maximum_output": { + "anyOf": [ + { + "type": "integer", + "minimum": 1 + }, + { + "type": "null" + } + ] + }, + "structured_output_mode": { + "enum": [ + "none", + "json", + "json_schema", + "provider_native" + ] + }, + "tool_configuration": { + "type": "array", + "items": { + "type": "string", + "minLength": 1 + }, + "uniqueItems": true + }, + "capability_snapshot_sha256": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + }, + "created_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", + "snapshot_id", + "provider_id", + "model_id", + "processing_mode", + "endpoint_classification", + "temperature_milli", + "context_limit", + "maximum_output", + "structured_output_mode", + "tool_configuration", + "capability_snapshot_sha256", + "created_at" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "snapshot_id": "record_01J00000000000000000000005", + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local", + "endpoint_classification": "loopback", + "temperature_milli": 700, + "context_limit": 8192, + "maximum_output": 800, + "structured_output_mode": "none", + "tool_configuration": [], + "capability_snapshot_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "created_at": "2026-07-17T18:42:10.123Z" + } + ] +} diff --git a/schemas/provenance/v1/project-key-manifest.schema.json b/schemas/provenance/v1/project-key-manifest.schema.json new file mode 100644 index 0000000..3205572 --- /dev/null +++ b/schemas/provenance/v1/project-key-manifest.schema.json @@ -0,0 +1,66 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/project-key-manifest.schema.json", + "title": "Project key manifest", + "description": "Stable key hierarchy references for protected project portability.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "project_id": { + "type": "string", + "pattern": "^project_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "key_id": { + "type": "string", + "pattern": "^key_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "algorithm": { + "const": "xchacha20-poly1305" + }, + "device_envelope_path": { + "type": "string", + "minLength": 1, + "pattern": "^(?!/)(?![A-Za-z]:)(?!.*\\\\)(?!.*(?:^|/)\\.\\.?(?:/|$))[^\\u0000-\\u001f]+$" + }, + "recovery_envelope_path": { + "type": "string", + "minLength": 1, + "pattern": "^(?!/)(?![A-Za-z]:)(?!.*\\\\)(?!.*(?:^|/)\\.\\.?(?:/|$))[^\\u0000-\\u001f]+$" + }, + "recovery_verified_at": { + "type": "string", + "format": "date-time", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$" + }, + "created_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", + "project_id", + "key_id", + "algorithm", + "device_envelope_path", + "recovery_envelope_path", + "recovery_verified_at", + "created_at" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "key_id": "key_01J0000000000000000000000G", + "algorithm": "xchacha20-poly1305", + "device_envelope_path": "provenance/keys/device-envelope.json", + "recovery_envelope_path": "provenance/keys/recovery-envelope.json", + "recovery_verified_at": "2026-07-17T18:42:10.123Z", + "created_at": "2026-07-17T18:42:10.123Z" + } + ] +} diff --git a/schemas/provenance/v1/project-manifest.schema.json b/schemas/provenance/v1/project-manifest.schema.json new file mode 100644 index 0000000..397b9dc --- /dev/null +++ b/schemas/provenance/v1/project-manifest.schema.json @@ -0,0 +1,85 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/project-manifest.schema.json", + "title": "Project manifest", + "description": "Canonical identity and lifecycle metadata for a 1.0 project.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "application_version": { + "type": "string", + "pattern": "^\\d+\\.\\d+\\.\\d+$" + }, + "project_id": { + "type": "string", + "pattern": "^project_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "title": { + "type": "string", + "minLength": 1 + }, + "description": { + "type": "string" + }, + "created_at": { + "type": "string", + "format": "date-time", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$" + }, + "current_phase": { + "enum": [ + "ideation", + "drafting", + "finalization" + ] + }, + "publication_status": { + "enum": [ + "working", + "finalized", + "published" + ] + }, + "provenance_policy_id": { + "type": "string", + "pattern": "^policy_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "audio_retained": { + "const": false + } + }, + "required": [ + "schema_version", + "application_version", + "project_id", + "title", + "created_at", + "updated_at", + "current_phase", + "publication_status", + "provenance_policy_id", + "audio_retained" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "title": "The Attention Commons", + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:43:11.456Z", + "current_phase": "ideation", + "publication_status": "working", + "provenance_policy_id": "policy_01J0000000000000000000000H", + "audio_retained": false + } + ] +} diff --git a/schemas/provenance/v1/prompt-template-reference.schema.json b/schemas/provenance/v1/prompt-template-reference.schema.json new file mode 100644 index 0000000..b5aee52 --- /dev/null +++ b/schemas/provenance/v1/prompt-template-reference.schema.json @@ -0,0 +1,46 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/prompt-template-reference.schema.json", + "title": "Prompt template reference", + "description": "Reference to an immutable prompt-template version.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "template_id": { + "type": "string", + "pattern": "^template_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "version": { + "type": "integer", + "minimum": 1 + }, + "path": { + "type": "string", + "minLength": 1, + "pattern": "^(?!/)(?![A-Za-z]:)(?!.*\\\\)(?!.*(?:^|/)\\.\\.?(?:/|$))[^\\u0000-\\u001f]+$" + }, + "template_sha256": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + } + }, + "required": [ + "schema_version", + "template_id", + "version", + "path", + "template_sha256" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + } + ] +} diff --git a/schemas/provenance/v1/prompt-template.schema.json b/schemas/provenance/v1/prompt-template.schema.json new file mode 100644 index 0000000..aa217b7 --- /dev/null +++ b/schemas/provenance/v1/prompt-template.schema.json @@ -0,0 +1,100 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/prompt-template.schema.json", + "title": "Prompt template", + "description": "Immutable versioned prompt template. Its digest identity excludes template_sha256.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "template_id": { + "type": "string", + "pattern": "^template_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "version": { + "type": "integer", + "minimum": 1 + }, + "purpose": { + "type": "string", + "pattern": "^[a-z][a-z0-9_]+$" + }, + "canonical_template_body": { + "type": "string", + "minLength": 1 + }, + "variables": { + "type": "object", + "additionalProperties": { + "type": "object", + "properties": { + "description": { + "type": "string", + "minLength": 1 + }, + "required": { + "type": "boolean" + } + }, + "required": [ + "description", + "required" + ], + "additionalProperties": false + } + }, + "creation_application_version": { + "type": "string", + "pattern": "^\\d+\\.\\d+\\.\\d+$" + }, + "retention_classification": { + "enum": [ + "application_default", + "project_record", + "protected_project_record" + ] + }, + "template_sha256": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + }, + "created_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", + "template_id", + "version", + "purpose", + "canonical_template_body", + "variables", + "creation_application_version", + "retention_classification", + "template_sha256", + "created_at" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "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": "sha256:7777777777777777777777777777777777777777777777777777777777777777", + "created_at": "2026-07-17T18:42:10.123Z" + } + ] +} diff --git a/schemas/provenance/v1/provenance-event.schema.json b/schemas/provenance/v1/provenance-event.schema.json new file mode 100644 index 0000000..f28a4f5 --- /dev/null +++ b/schemas/provenance/v1/provenance-event.schema.json @@ -0,0 +1,220 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/provenance-event.schema.json", + "title": "Provenance event", + "description": "Canonical chronological action with content references and SHA-256 chain linkage.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "event_id": { + "type": "string", + "pattern": "^event_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "event_sequence": { + "type": "integer", + "minimum": 1 + }, + "client_action_id": { + "type": "string", + "minLength": 8, + "maxLength": 200 + }, + "project_id": { + "type": "string", + "pattern": "^project_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "timestamp": { + "type": "string", + "format": "date-time", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$" + }, + "event_type": { + "type": "string", + "pattern": "^[A-Z][A-Z0-9_]+$" + }, + "actor": { + "type": "object", + "properties": { + "type": { + "enum": [ + "user", + "assistant", + "system" + ] + }, + "actor_id": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "type", + "actor_id" + ], + "additionalProperties": false + }, + "provider": { + "anyOf": [ + { + "type": "object", + "properties": { + "provider_id": { + "type": "string", + "minLength": 1 + }, + "model_id": { + "type": "string", + "minLength": 1 + }, + "processing_mode": { + "enum": [ + "local", + "cloud" + ] + } + }, + "required": [ + "provider_id", + "model_id", + "processing_mode" + ], + "additionalProperties": false + }, + { + "type": "null" + } + ] + }, + "inputs": { + "type": "array", + "items": { + "$ref": "https://thinkloom.app/schemas/provenance/1.0/content-reference.schema.json" + } + }, + "outputs": { + "type": "array", + "items": { + "$ref": "https://thinkloom.app/schemas/provenance/1.0/content-reference.schema.json" + } + }, + "relationships": { + "type": "object", + "properties": { + "parent_event_ids": { + "type": "array", + "items": { + "type": "string", + "pattern": "^event_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "uniqueItems": true + }, + "invocation_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^invocation_[0-9A-HJKMNP-TV-Z]{26}$" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "parent_event_ids", + "invocation_id" + ], + "additionalProperties": false + }, + "metadata": { + "type": "object" + }, + "previous_event_hash": { + "anyOf": [ + { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + }, + { + "type": "null" + } + ] + }, + "event_hash": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + } + }, + "required": [ + "schema_version", + "event_id", + "event_sequence", + "client_action_id", + "project_id", + "timestamp", + "event_type", + "actor", + "provider", + "inputs", + "outputs", + "relationships", + "metadata", + "previous_event_hash", + "event_hash" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + ] +} diff --git a/schemas/provenance/v1/provenance-policy.schema.json b/schemas/provenance/v1/provenance-policy.schema.json new file mode 100644 index 0000000..18ff426 --- /dev/null +++ b/schemas/provenance/v1/provenance-policy.schema.json @@ -0,0 +1,64 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/provenance-policy.schema.json", + "title": "Provenance policy", + "description": "Prospective project retention, protection, and export defaults.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "policy_id": { + "type": "string", + "pattern": "^policy_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "project_id": { + "type": "string", + "pattern": "^project_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "retention_mode": { + "enum": [ + "minimal", + "full_private" + ] + }, + "encryption_mode": { + "enum": [ + "none", + "protected" + ] + }, + "default_export_profile": { + "enum": [ + "full", + "sanitized" + ] + }, + "effective_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", + "policy_id", + "project_id", + "retention_mode", + "encryption_mode", + "default_export_profile", + "effective_at" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "policy_id": "policy_01J0000000000000000000000H", + "project_id": "project_01J00000000000000000000001", + "retention_mode": "minimal", + "encryption_mode": "none", + "default_export_profile": "sanitized", + "effective_at": "2026-07-17T18:42:10.123Z" + } + ] +} diff --git a/schemas/provenance/v1/purge-manifest.schema.json b/schemas/provenance/v1/purge-manifest.schema.json new file mode 100644 index 0000000..23a1899 --- /dev/null +++ b/schemas/provenance/v1/purge-manifest.schema.json @@ -0,0 +1,107 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/purge-manifest.schema.json", + "title": "Emergency purge manifest", + "description": "Explicit disclosure of a destructive provenance and Git reconstitution.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "purge_id": { + "type": "string", + "pattern": "^purge_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "project_id": { + "type": "string", + "pattern": "^project_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "requested_at": { + "type": "string", + "format": "date-time", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$" + }, + "completed_at": { + "type": "string", + "format": "date-time", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$" + }, + "reason": { + "type": "string", + "minLength": 1 + }, + "superseded_chain_head": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + }, + "new_chain_root": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + }, + "affected_record_ids": { + "type": "array", + "items": { + "type": "string", + "pattern": "^record_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "minItems": 1, + "uniqueItems": true + }, + "affected_paths": { + "type": "array", + "items": { + "type": "string", + "minLength": 1, + "pattern": "^(?!/)(?![A-Za-z]:)(?!.*\\\\)(?!.*(?:^|/)\\.\\.?(?:/|$))[^\\u0000-\\u001f]+$" + }, + "uniqueItems": true + }, + "git_history_rewritten": { + "const": true + }, + "prior_copies_revocable": { + "const": false + }, + "confirmation_phrase_sha256": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + } + }, + "required": [ + "schema_version", + "purge_id", + "project_id", + "requested_at", + "completed_at", + "reason", + "superseded_chain_head", + "new_chain_root", + "affected_record_ids", + "affected_paths", + "git_history_rewritten", + "prior_copies_revocable", + "confirmation_phrase_sha256" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "purge_id": "purge_01J0000000000000000000000R", + "project_id": "project_01J00000000000000000000001", + "requested_at": "2026-07-17T18:42:10.123Z", + "completed_at": "2026-07-17T18:43:11.456Z", + "reason": "Remove accidentally retained credential", + "superseded_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "new_chain_root": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "affected_record_ids": [ + "record_01J00000000000000000000005" + ], + "affected_paths": [ + "records/invocations/request.json" + ], + "git_history_rewritten": true, + "prior_copies_revocable": false, + "confirmation_phrase_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + } + ] +} diff --git a/schemas/provenance/v1/record-envelope.schema.json b/schemas/provenance/v1/record-envelope.schema.json new file mode 100644 index 0000000..ae57243 --- /dev/null +++ b/schemas/provenance/v1/record-envelope.schema.json @@ -0,0 +1,160 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/record-envelope.schema.json", + "title": "Authoritative record envelope", + "description": "Stable logical record identity with plaintext or authenticated protected payload.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "project_id": { + "type": "string", + "pattern": "^project_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "record_id": { + "type": "string", + "pattern": "^record_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "record_type": { + "type": "string", + "pattern": "^[a-z][a-z0-9_]+$" + }, + "protection": { + "enum": [ + "none", + "protected" + ] + }, + "plaintext_sha256": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + }, + "payload": { + "anyOf": [ + {}, + { + "type": "null" + } + ] + }, + "encryption": { + "anyOf": [ + { + "type": "object", + "properties": { + "algorithm": { + "const": "xchacha20-poly1305" + }, + "key_id": { + "type": "string", + "pattern": "^key_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "nonce": { + "type": "string", + "minLength": 32 + }, + "ciphertext": { + "type": "string", + "minLength": 16 + }, + "ciphertext_sha256": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + } + }, + "required": [ + "algorithm", + "key_id", + "nonce", + "ciphertext", + "ciphertext_sha256" + ], + "additionalProperties": false + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "schema_version", + "project_id", + "record_id", + "record_type", + "protection", + "plaintext_sha256", + "payload", + "encryption" + ], + "additionalProperties": false, + "allOf": [ + { + "if": { + "properties": { + "protection": { + "const": "none" + } + }, + "required": [ + "protection" + ] + }, + "then": { + "properties": { + "payload": { + "not": { + "type": "null" + } + }, + "encryption": { + "type": "null" + } + } + } + }, + { + "if": { + "properties": { + "protection": { + "const": "protected" + } + }, + "required": [ + "protection" + ] + }, + "then": { + "properties": { + "payload": { + "type": "null" + }, + "encryption": { + "not": { + "type": "null" + } + } + } + } + } + ], + "examples": [ + { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "record_id": "record_01J00000000000000000000005", + "record_type": "invocation_request", + "protection": "protected", + "plaintext_sha256": "sha256:97154eddff15ab6607181e55945547fdbbc5bde02b1e5123eade7a69509f00c5", + "payload": null, + "encryption": { + "algorithm": "xchacha20-poly1305", + "key_id": "key_01J0000000000000000000000G", + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "ciphertext": "ZW5jcnlwdGVkLXJlY29yZA==", + "ciphertext_sha256": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + } + } + ] +} diff --git a/schemas/provenance/v1/recovery-key-envelope.schema.json b/schemas/provenance/v1/recovery-key-envelope.schema.json new file mode 100644 index 0000000..2a3b340 --- /dev/null +++ b/schemas/provenance/v1/recovery-key-envelope.schema.json @@ -0,0 +1,110 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/recovery-key-envelope.schema.json", + "title": "Recovery key envelope", + "description": "Portable recovery envelope for a protected project key.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "envelope_id": { + "type": "string", + "pattern": "^record_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "key_id": { + "type": "string", + "pattern": "^key_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "envelope_type": { + "const": "recovery" + }, + "algorithm": { + "enum": [ + "xchacha20-poly1305" + ] + }, + "key_derivation": { + "type": "object", + "properties": { + "algorithm": { + "const": "argon2id" + }, + "memory_kib": { + "type": "integer", + "minimum": 65536 + }, + "iterations": { + "type": "integer", + "minimum": 1 + }, + "parallelism": { + "type": "integer", + "minimum": 1 + }, + "salt": { + "type": "string", + "minLength": 16 + } + }, + "required": [ + "algorithm", + "memory_kib", + "iterations", + "parallelism", + "salt" + ], + "additionalProperties": false + }, + "nonce": { + "type": "string", + "minLength": 32 + }, + "wrapped_key": { + "type": "string", + "minLength": 16 + }, + "ciphertext_sha256": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + }, + "created_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", + "envelope_id", + "key_id", + "envelope_type", + "algorithm", + "key_derivation", + "nonce", + "wrapped_key", + "ciphertext_sha256", + "created_at" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "envelope_id": "record_01J0000000000000000000000S", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "recovery", + "algorithm": "xchacha20-poly1305", + "key_derivation": { + "algorithm": "argon2id", + "memory_kib": 65536, + "iterations": 3, + "parallelism": 1, + "salt": "c2FsdC1mb3ItdGhpbmtsb29t" + }, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + } + ] +} diff --git a/schemas/provenance/v1/release-manifest.schema.json b/schemas/provenance/v1/release-manifest.schema.json new file mode 100644 index 0000000..68461f7 --- /dev/null +++ b/schemas/provenance/v1/release-manifest.schema.json @@ -0,0 +1,145 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/release-manifest.schema.json", + "title": "Release manifest", + "description": "Non-self-referential binding of a frozen source to verified release files.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "application_version": { + "type": "string", + "pattern": "^\\d+\\.\\d+\\.\\d+$" + }, + "release_id": { + "type": "string", + "pattern": "^release_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "project_id": { + "type": "string", + "pattern": "^project_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "version": { + "type": "string", + "pattern": "^\\d+\\.\\d+\\.\\d+$" + }, + "created_at": { + "type": "string", + "format": "date-time", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$" + }, + "source_commit": { + "type": "string", + "pattern": "^[a-f0-9]{40,64}$" + }, + "source_chain_head": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + }, + "source_manuscript": { + "type": "object", + "properties": { + "path": { + "type": "string", + "minLength": 1, + "pattern": "^(?!/)(?![A-Za-z]:)(?!.*\\\\)(?!.*(?:^|/)\\.\\.?(?:/|$))[^\\u0000-\\u001f]+$" + }, + "sha256": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + } + }, + "required": [ + "path", + "sha256" + ], + "additionalProperties": false + }, + "sanitized": { + "type": "boolean" + }, + "files": { + "type": "array", + "items": { + "type": "object", + "properties": { + "path": { + "type": "string", + "minLength": 1, + "pattern": "^(?!/)(?![A-Za-z]:)(?!.*\\\\)(?!.*(?:^|/)\\.\\.?(?:/|$))[^\\u0000-\\u001f]+$" + }, + "sha256": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + }, + "size": { + "type": "integer", + "minimum": 0 + } + }, + "required": [ + "path", + "sha256", + "size" + ], + "additionalProperties": false + }, + "minItems": 1 + }, + "release_files_merkle_root": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + }, + "merkle_algorithm": { + "const": "thinkloom-release-merkle-v1" + } + }, + "required": [ + "schema_version", + "application_version", + "release_id", + "project_id", + "version", + "created_at", + "source_commit", + "source_chain_head", + "source_manuscript", + "sanitized", + "files", + "release_files_merkle_root", + "merkle_algorithm" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + } + ] +} diff --git a/schemas/provenance/v1/release-state.schema.json b/schemas/provenance/v1/release-state.schema.json new file mode 100644 index 0000000..a2a4297 --- /dev/null +++ b/schemas/provenance/v1/release-state.schema.json @@ -0,0 +1,102 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/release-state.schema.json", + "title": "Release state", + "description": "Durable idempotent release-finalization state.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "release_id": { + "type": "string", + "pattern": "^release_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "project_id": { + "type": "string", + "pattern": "^project_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "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": { + "anyOf": [ + { + "type": "string", + "pattern": "^[a-f0-9]{40,64}$" + }, + { + "type": "null" + } + ] + }, + "source_chain_head": { + "anyOf": [ + { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + }, + { + "type": "null" + } + ] + }, + "updated_at": { + "type": "string", + "format": "date-time", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$" + }, + "failure": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "schema_version", + "release_id", + "project_id", + "state", + "state_sequence", + "source_commit", + "source_chain_head", + "updated_at", + "failure" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "state": "RELEASE_STAGED", + "state_sequence": 5, + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "updated_at": "2026-07-17T18:43:11.456Z", + "failure": null + } + ] +} diff --git a/schemas/provenance/v1/sanitized-export-manifest.schema.json b/schemas/provenance/v1/sanitized-export-manifest.schema.json new file mode 100644 index 0000000..ef7136b --- /dev/null +++ b/schemas/provenance/v1/sanitized-export-manifest.schema.json @@ -0,0 +1,137 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/sanitized-export-manifest.schema.json", + "title": "Sanitized export manifest", + "description": "Disclosure and file inventory for a non-mutating sanitized evidence export.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "export_id": { + "type": "string", + "pattern": "^record_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "project_id": { + "type": "string", + "pattern": "^project_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "source_chain_head": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + }, + "profile": { + "const": "sanitized" + }, + "omission_rules": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "enum": [ + "private_conversation", + "rejected_output", + "provider_detail", + "personal_identifier", + "internal_path", + "source_body", + "other" + ] + }, + "action": { + "enum": [ + "exclude", + "redact", + "summarize" + ] + }, + "count": { + "type": "integer", + "minimum": 0 + } + }, + "required": [ + "category", + "action", + "count" + ], + "additionalProperties": false + } + }, + "rules_sha256": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + }, + "files": { + "type": "array", + "items": { + "type": "object", + "properties": { + "path": { + "type": "string", + "minLength": 1, + "pattern": "^(?!/)(?![A-Za-z]:)(?!.*\\\\)(?!.*(?:^|/)\\.\\.?(?:/|$))[^\\u0000-\\u001f]+$" + }, + "sha256": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + }, + "size": { + "type": "integer", + "minimum": 0 + } + }, + "required": [ + "path", + "sha256", + "size" + ], + "additionalProperties": false + }, + "minItems": 1 + }, + "created_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", + "export_id", + "project_id", + "source_chain_head", + "profile", + "omission_rules", + "rules_sha256", + "files", + "created_at" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "export_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "profile": "sanitized", + "omission_rules": [ + { + "category": "private_conversation", + "action": "exclude", + "count": 2 + } + ], + "rules_sha256": "sha256:6666666666666666666666666666666666666666666666666666666666666666", + "files": [ + { + "path": "final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + } + ], + "created_at": "2026-07-17T18:43:11.456Z" + } + ] +} diff --git a/schemas/provenance/v1/text-fragment-reference.schema.json b/schemas/provenance/v1/text-fragment-reference.schema.json new file mode 100644 index 0000000..bdab832 --- /dev/null +++ b/schemas/provenance/v1/text-fragment-reference.schema.json @@ -0,0 +1,68 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/text-fragment-reference.schema.json", + "title": "Text fragment reference", + "description": "Stable revision-bound text range with an explicit coordinate system.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "document_revision_id": { + "type": "string", + "pattern": "^revision_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "coordinate_system": { + "enum": [ + "utf8_byte", + "unicode_scalar", + "utf16_code_unit", + "editor_position" + ] + }, + "start": { + "type": "integer", + "minimum": 0 + }, + "end": { + "type": "integer", + "minimum": 0 + }, + "preimage_sha256": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + }, + "text_fragment_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^fragment_[0-9A-HJKMNP-TV-Z]{26}$" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "schema_version", + "document_revision_id", + "coordinate_system", + "start", + "end", + "preimage_sha256", + "text_fragment_id" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + ] +} diff --git a/schemas/provenance/v1/transcript-correction.schema.json b/schemas/provenance/v1/transcript-correction.schema.json new file mode 100644 index 0000000..de79a23 --- /dev/null +++ b/schemas/provenance/v1/transcript-correction.schema.json @@ -0,0 +1,68 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/transcript-correction.schema.json", + "title": "Transcript correction", + "description": "Immutable ordered correction to a retained transcript turn.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "correction_id": { + "type": "string", + "pattern": "^correction_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "turn_id": { + "type": "string", + "pattern": "^turn_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "revision_number": { + "type": "integer", + "minimum": 1 + }, + "corrected_text": { + "type": "string", + "minLength": 1 + }, + "reason": { + "enum": [ + "user_correction", + "transcription_error", + "clarification", + "other" + ] + }, + "created_at": { + "type": "string", + "format": "date-time", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$" + }, + "event_id": { + "type": "string", + "pattern": "^event_[0-9A-HJKMNP-TV-Z]{26}$" + } + }, + "required": [ + "schema_version", + "correction_id", + "turn_id", + "revision_number", + "corrected_text", + "reason", + "created_at", + "event_id" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "correction_id": "correction_01J0000000000000000000000J", + "turn_id": "turn_01J00000000000000000000007", + "revision_number": 1, + "corrected_text": "Attention shapes our public life.", + "reason": "user_correction", + "created_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + ] +} diff --git a/schemas/provenance/v1/transcript-normalization.schema.json b/schemas/provenance/v1/transcript-normalization.schema.json new file mode 100644 index 0000000..5a6dd19 --- /dev/null +++ b/schemas/provenance/v1/transcript-normalization.schema.json @@ -0,0 +1,80 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/transcript-normalization.schema.json", + "title": "Transcript normalization", + "description": "Immutable normalized representation derived from a transcript revision.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "normalization_id": { + "type": "string", + "pattern": "^normalization_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "turn_id": { + "type": "string", + "pattern": "^turn_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "revision_number": { + "type": "integer", + "minimum": 1 + }, + "normalized_text": { + "type": "string", + "minLength": 1 + }, + "method": { + "enum": [ + "application", + "user_approved", + "provider" + ] + }, + "source_correction_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^correction_[0-9A-HJKMNP-TV-Z]{26}$" + }, + { + "type": "null" + } + ] + }, + "created_at": { + "type": "string", + "format": "date-time", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$" + }, + "event_id": { + "type": "string", + "pattern": "^event_[0-9A-HJKMNP-TV-Z]{26}$" + } + }, + "required": [ + "schema_version", + "normalization_id", + "turn_id", + "revision_number", + "normalized_text", + "method", + "source_correction_id", + "created_at", + "event_id" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "normalization_id": "normalization_01J0000000000000000000000K", + "turn_id": "turn_01J00000000000000000000007", + "revision_number": 1, + "normalized_text": "Attention shapes public life.", + "method": "application", + "source_correction_id": "correction_01J0000000000000000000000J", + "created_at": "2026-07-17T18:43:11.456Z", + "event_id": "event_01J00000000000000000000004" + } + ] +} diff --git a/schemas/provenance/v1/transcript-turn.schema.json b/schemas/provenance/v1/transcript-turn.schema.json new file mode 100644 index 0000000..4d7d57a --- /dev/null +++ b/schemas/provenance/v1/transcript-turn.schema.json @@ -0,0 +1,105 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/transcript-turn.schema.json", + "title": "Transcript turn", + "description": "Immutable retained conversation turn permitted by project policy.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "turn_id": { + "type": "string", + "pattern": "^turn_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "session_id": { + "type": "string", + "pattern": "^session_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "speaker": { + "enum": [ + "user", + "assistant" + ] + }, + "input_mode": { + "enum": [ + "typed", + "voice" + ] + }, + "retained_text": { + "type": "string", + "minLength": 1 + }, + "raw_transcript": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "started_at": { + "type": "string", + "format": "date-time", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$" + }, + "ended_at": { + "type": "string", + "format": "date-time", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$" + }, + "audio_retained": { + "const": false + }, + "invocation_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^invocation_[0-9A-HJKMNP-TV-Z]{26}$" + }, + { + "type": "null" + } + ] + }, + "event_id": { + "type": "string", + "pattern": "^event_[0-9A-HJKMNP-TV-Z]{26}$" + } + }, + "required": [ + "schema_version", + "turn_id", + "session_id", + "speaker", + "input_mode", + "retained_text", + "raw_transcript", + "started_at", + "ended_at", + "audio_retained", + "invocation_id", + "event_id" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "turn_id": "turn_01J00000000000000000000007", + "session_id": "session_01J00000000000000000000006", + "speaker": "user", + "input_mode": "typed", + "retained_text": "Attention shapes public life.", + "raw_transcript": null, + "started_at": "2026-07-17T18:42:10.123Z", + "ended_at": "2026-07-17T18:43:11.456Z", + "audio_retained": false, + "invocation_id": null, + "event_id": "event_01J00000000000000000000003" + } + ] +} diff --git a/schemas/provenance/v1/vectors/backup-and-release-manifests.json b/schemas/provenance/v1/vectors/backup-and-release-manifests.json new file mode 100644 index 0000000..7ff9596 --- /dev/null +++ b/schemas/provenance/v1/vectors/backup-and-release-manifests.json @@ -0,0 +1,57 @@ +{ + "vector_version": "1.0", + "backup_manifest": { + "schema_version": "1.0", + "application_version": "0.3.0", + "project_id": "project_01J00000000000000000000001", + "created_at": "2026-07-17T18:42:10.123Z", + "source_chain_head": "sha256:51935af27a4c989a014d975eab929f41fccafadedfbf1baafa15e3ce2a27a66d", + "sqlite_snapshot": { + "path": "database-snapshot/state.sqlite", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "size": 4096, + "sqlite_version": "3.46.0", + "database_schema_version": 1, + "completed_at": "2026-07-17T18:42:10.123Z" + }, + "files": [ + { + "path": "project.json", + "sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "size": 256 + } + ], + "protected": false, + "recovery_key_envelope_path": null + }, + "release_manifest": { + "schema_version": "1.0", + "application_version": "0.3.0", + "release_id": "release_01J0000000000000000000000E", + "project_id": "project_01J00000000000000000000001", + "version": "1.0.0", + "created_at": "2026-07-17T18:43:11.456Z", + "source_commit": "0123456789abcdef0123456789abcdef01234567", + "source_chain_head": "sha256:51935af27a4c989a014d975eab929f41fccafadedfbf1baafa15e3ce2a27a66d", + "source_manuscript": { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "sanitized": false, + "files": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "release_files_merkle_root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "merkle_algorithm": "thinkloom-release-merkle-v1" + }, + "binding_rule": "Backup and release inventories bind the same frozen authoritative chain head while remaining distinct artifact classes." +} diff --git a/schemas/provenance/v1/vectors/canonicalization.json b/schemas/provenance/v1/vectors/canonicalization.json new file mode 100644 index 0000000..dc7816f --- /dev/null +++ b/schemas/provenance/v1/vectors/canonicalization.json @@ -0,0 +1,73 @@ +{ + "vector_version": "1.0", + "algorithm": "Unicode NFC followed by RFC 8785 JSON Canonicalization Scheme and SHA-256 over UTF-8 bytes", + "cases": [ + { + "id": "rfc8785-key-order", + "input": { + "z": 1, + "a": 2, + "nested": { + "beta": true, + "alpha": false + } + }, + "canonical_json": "{\"a\":2,\"nested\":{\"alpha\":false,\"beta\":true},\"z\":1}", + "utf8_sha256": "sha256:f0d2d7ce87541c9b5d9c16a557f162a766ce865ae322a1ce512f89835e344479" + }, + { + "id": "thinkloom-nfc", + "input": { + "text": "Café", + "é": "normalize keys and values" + }, + "canonical_json": "{\"text\":\"Café\",\"é\":\"normalize keys and values\"}", + "utf8_sha256": "sha256:7c5f79c29886fc66ff5a0529755d07fe905f178131f264a95b4ff44d91214e4c" + }, + { + "id": "rfc8785-numbers", + "input": { + "numbers": [ + 333333333.3333333, + 1e+30, + 4.5, + 0.002, + 1e-27 + ] + }, + "canonical_json": "{\"numbers\":[333333333.3333333,1e+30,4.5,0.002,1e-27]}", + "utf8_sha256": "sha256:7c892d3452ad85ad65857a43e8dcac93b79475d2334fc3e85bac5c599142c158" + }, + { + "id": "thinkloom-timestamp-and-path", + "input": { + "timestamp": "2026-07-17T18:42:10.123Z", + "path": "records/invocations/request.json" + }, + "canonical_json": "{\"path\":\"records/invocations/request.json\",\"timestamp\":\"2026-07-17T18:42:10.123Z\"}", + "utf8_sha256": "sha256:97f1f02f62ecbbe8b80ede4e48655f5d8774fd6022bba1f6d2c421eca9975068" + } + ], + "rejected_inputs": [ + { + "id": "non-finite-number", + "description": "NaN and infinity are not JSON and MUST be rejected before canonicalization." + }, + { + "id": "undefined-value", + "description": "Undefined values MUST be rejected rather than silently omitted." + }, + { + "id": "nfc-key-collision", + "description": "Distinct source keys that normalize to the same NFC key MUST be rejected." + }, + { + "id": "unpaired-surrogate", + "description": "I-JSON prohibits unpaired Unicode surrogate code units." + }, + { + "id": "non-json-runtime-types", + "description": "BigInt, symbols, functions, sparse arrays, and non-plain objects MUST be rejected." + } + ] +} diff --git a/schemas/provenance/v1/vectors/cross-segment-chain.json b/schemas/provenance/v1/vectors/cross-segment-chain.json new file mode 100644 index 0000000..29f56a8 --- /dev/null +++ b/schemas/provenance/v1/vectors/cross-segment-chain.json @@ -0,0 +1,49 @@ +{ + "vector_version": "1.0", + "segments": [ + { + "jsonl": "{\"actor\":{\"actor_id\":null,\"type\":\"user\"},\"client_action_id\":\"client-action-0001\",\"event_hash\":\"sha256:3a087877f4878483805f517ef0ebd108476e31ed68162504da4fad12d6d9eff4\",\"event_id\":\"event_01J00000000000000000000003\",\"event_sequence\":1,\"event_type\":\"PROJECT_CREATED\",\"inputs\":[],\"metadata\":{\"summary\":\"Created project\"},\"outputs\":[{\"path\":\"manuscript/revisions/revision.json\",\"range\":{\"coordinate_system\":\"utf8_byte\",\"document_revision_id\":\"revision_01J0000000000000000000000A\",\"end\":12,\"preimage_sha256\":\"sha256:1111111111111111111111111111111111111111111111111111111111111111\",\"schema_version\":\"1.0\",\"start\":0,\"text_fragment_id\":\"fragment_01J0000000000000000000000C\"},\"record_id\":\"record_01J00000000000000000000005\",\"record_type\":\"manuscript_revision\",\"revision_id\":\"revision_01J0000000000000000000000A\",\"schema_version\":\"1.0\",\"sha256\":\"sha256:2222222222222222222222222222222222222222222222222222222222222222\"}],\"previous_event_hash\":null,\"project_id\":\"project_01J00000000000000000000001\",\"provider\":null,\"relationships\":{\"invocation_id\":null,\"parent_event_ids\":[]},\"schema_version\":\"1.0\",\"timestamp\":\"2026-07-17T18:42:10.123Z\"}\n{\"actor\":{\"actor_id\":null,\"type\":\"user\"},\"client_action_id\":\"client-action-0001\",\"event_hash\":\"sha256:eb03e514fa6fcfcd291357668559b24387a84256fc39d6fb0621529003d0988e\",\"event_id\":\"event_01J00000000000000000000004\",\"event_sequence\":2,\"event_type\":\"IDEA_ACCEPTED\",\"inputs\":[],\"metadata\":{\"summary\":\"Created project\"},\"outputs\":[{\"path\":\"manuscript/revisions/revision.json\",\"range\":{\"coordinate_system\":\"utf8_byte\",\"document_revision_id\":\"revision_01J0000000000000000000000A\",\"end\":12,\"preimage_sha256\":\"sha256:1111111111111111111111111111111111111111111111111111111111111111\",\"schema_version\":\"1.0\",\"start\":0,\"text_fragment_id\":\"fragment_01J0000000000000000000000C\"},\"record_id\":\"record_01J00000000000000000000005\",\"record_type\":\"manuscript_revision\",\"revision_id\":\"revision_01J0000000000000000000000A\",\"schema_version\":\"1.0\",\"sha256\":\"sha256:2222222222222222222222222222222222222222222222222222222222222222\"}],\"previous_event_hash\":\"sha256:3a087877f4878483805f517ef0ebd108476e31ed68162504da4fad12d6d9eff4\",\"project_id\":\"project_01J00000000000000000000001\",\"provider\":null,\"relationships\":{\"invocation_id\":null,\"parent_event_ids\":[]},\"schema_version\":\"1.0\",\"timestamp\":\"2026-07-17T18:43:11.456Z\"}\n", + "manifest": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "segment_number": 1, + "previous_segment_file_hash": null, + "first_event_hash": "sha256:3a087877f4878483805f517ef0ebd108476e31ed68162504da4fad12d6d9eff4", + "final_event_hash": "sha256:eb03e514fa6fcfcd291357668559b24387a84256fc39d6fb0621529003d0988e", + "first_event_sequence": 1, + "final_event_sequence": 2, + "event_count": 2, + "byte_length": 2323, + "segment_file_hash": "sha256:b37546669da485b3f5c8dad3c26b36ee8992ac8127e8f99d6a5ee8cdb1fa2d81", + "sealed_at": "2026-07-17T18:42:10.123Z" + } + }, + { + "jsonl": "{\"actor\":{\"actor_id\":null,\"type\":\"user\"},\"client_action_id\":\"client-action-0001\",\"event_hash\":\"sha256:51935af27a4c989a014d975eab929f41fccafadedfbf1baafa15e3ce2a27a66d\",\"event_id\":\"event_01J0000000000000000000000T\",\"event_sequence\":3,\"event_type\":\"MANUSCRIPT_EDITED\",\"inputs\":[],\"metadata\":{\"summary\":\"Created project\"},\"outputs\":[{\"path\":\"manuscript/revisions/revision.json\",\"range\":{\"coordinate_system\":\"utf8_byte\",\"document_revision_id\":\"revision_01J0000000000000000000000A\",\"end\":12,\"preimage_sha256\":\"sha256:1111111111111111111111111111111111111111111111111111111111111111\",\"schema_version\":\"1.0\",\"start\":0,\"text_fragment_id\":\"fragment_01J0000000000000000000000C\"},\"record_id\":\"record_01J00000000000000000000005\",\"record_type\":\"manuscript_revision\",\"revision_id\":\"revision_01J0000000000000000000000A\",\"schema_version\":\"1.0\",\"sha256\":\"sha256:2222222222222222222222222222222222222222222222222222222222222222\"}],\"previous_event_hash\":\"sha256:eb03e514fa6fcfcd291357668559b24387a84256fc39d6fb0621529003d0988e\",\"project_id\":\"project_01J00000000000000000000001\",\"provider\":null,\"relationships\":{\"invocation_id\":null,\"parent_event_ids\":[]},\"schema_version\":\"1.0\",\"timestamp\":\"2026-07-17T18:44:12.789Z\"}\n", + "manifest": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "segment_number": 2, + "previous_segment_file_hash": "sha256:b37546669da485b3f5c8dad3c26b36ee8992ac8127e8f99d6a5ee8cdb1fa2d81", + "first_event_hash": "sha256:51935af27a4c989a014d975eab929f41fccafadedfbf1baafa15e3ce2a27a66d", + "final_event_hash": "sha256:51935af27a4c989a014d975eab929f41fccafadedfbf1baafa15e3ce2a27a66d", + "first_event_sequence": 3, + "final_event_sequence": 3, + "event_count": 1, + "byte_length": 1199, + "segment_file_hash": "sha256:194195fb37a089af86334695f45de5efce45eccc651c6257d63a9f3cc6a81b51", + "sealed_at": "2026-07-17T18:45:13.012Z" + } + } + ], + "chain_head": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "active_segment_number": 2, + "event_id": "event_01J0000000000000000000000T", + "event_sequence": 3, + "event_hash": "sha256:51935af27a4c989a014d975eab929f41fccafadedfbf1baafa15e3ce2a27a66d", + "updated_at": "2026-07-17T18:45:13.012Z" + }, + "cross_segment_rule": "A sealed segment names the prior segment file digest, and event hash linkage remains contiguous across the boundary." +} diff --git a/schemas/provenance/v1/vectors/deterministic-derived-index.json b/schemas/provenance/v1/vectors/deterministic-derived-index.json new file mode 100644 index 0000000..ba81d2f --- /dev/null +++ b/schemas/provenance/v1/vectors/deterministic-derived-index.json @@ -0,0 +1,59 @@ +{ + "vector_version": "1.0", + "input_orders": [ + [ + { + "from": "idea_01J00000000000000000000009", + "to": "revision_01J0000000000000000000000B", + "relation": "influenced" + }, + { + "from": "turn_01J00000000000000000000007", + "to": "idea_01J00000000000000000000009", + "relation": "suggested" + } + ], + [ + { + "from": "turn_01J00000000000000000000007", + "to": "idea_01J00000000000000000000009", + "relation": "suggested" + }, + { + "from": "idea_01J00000000000000000000009", + "to": "revision_01J0000000000000000000000B", + "relation": "influenced" + } + ] + ], + "deterministic_content": [ + { + "from": "idea_01J00000000000000000000009", + "to": "revision_01J0000000000000000000000B", + "relation": "influenced" + }, + { + "from": "turn_01J00000000000000000000007", + "to": "idea_01J00000000000000000000009", + "relation": "suggested" + } + ], + "configuration": { + "sort": "canonical-json-code-unit", + "graph_version": 1 + }, + "manifest": { + "schema_version": "1.0", + "index_type": "contribution_graph", + "source_chain_head": "sha256:51935af27a4c989a014d975eab929f41fccafadedfbf1baafa15e3ce2a27a66d", + "source_event_count": 3, + "generator": { + "name": "thinkloom-indexer", + "version": "1.0.0", + "configuration_sha256": "sha256:730664bcc17657f08ea3a55a96513b183fe957d598f8b00cea3ff981a099890d" + }, + "content_sha256": "sha256:70ce92437e823653cb88cdc3ed8adaeb7bc48172ad526758720238149d6dcb79", + "generated_at": "2026-07-17T18:42:10.123Z" + }, + "determinism_rule": "Input order does not affect canonical derived content; volatile generation metadata is outside content_sha256." +} diff --git a/schemas/provenance/v1/vectors/event-chain.json b/schemas/provenance/v1/vectors/event-chain.json new file mode 100644 index 0000000..2ec00f2 --- /dev/null +++ b/schemas/provenance/v1/vectors/event-chain.json @@ -0,0 +1,145 @@ +{ + "vector_version": "1.0", + "event_hash_identity": "Canonical event object excluding only event_hash; previous_event_hash remains included.", + "sequence_rule": "Committed event_sequence values begin at 1 and are contiguous with no reuse.", + "jsonl_rule": "Each canonical event is UTF-8 without BOM followed by exactly one LF byte (0x0A).", + "events": [ + { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null, + "event_hash": "sha256:3a087877f4878483805f517ef0ebd108476e31ed68162504da4fad12d6d9eff4" + }, + { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000004", + "event_sequence": 2, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:43:11.456Z", + "event_type": "IDEA_ACCEPTED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": "sha256:3a087877f4878483805f517ef0ebd108476e31ed68162504da4fad12d6d9eff4", + "event_hash": "sha256:eb03e514fa6fcfcd291357668559b24387a84256fc39d6fb0621529003d0988e" + }, + { + "schema_version": "1.0", + "event_id": "event_01J0000000000000000000000T", + "event_sequence": 3, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:44:12.789Z", + "event_type": "MANUSCRIPT_EDITED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": "sha256:eb03e514fa6fcfcd291357668559b24387a84256fc39d6fb0621529003d0988e", + "event_hash": "sha256:51935af27a4c989a014d975eab929f41fccafadedfbf1baafa15e3ce2a27a66d" + } + ], + "canonical_jsonl": "{\"actor\":{\"actor_id\":null,\"type\":\"user\"},\"client_action_id\":\"client-action-0001\",\"event_hash\":\"sha256:3a087877f4878483805f517ef0ebd108476e31ed68162504da4fad12d6d9eff4\",\"event_id\":\"event_01J00000000000000000000003\",\"event_sequence\":1,\"event_type\":\"PROJECT_CREATED\",\"inputs\":[],\"metadata\":{\"summary\":\"Created project\"},\"outputs\":[{\"path\":\"manuscript/revisions/revision.json\",\"range\":{\"coordinate_system\":\"utf8_byte\",\"document_revision_id\":\"revision_01J0000000000000000000000A\",\"end\":12,\"preimage_sha256\":\"sha256:1111111111111111111111111111111111111111111111111111111111111111\",\"schema_version\":\"1.0\",\"start\":0,\"text_fragment_id\":\"fragment_01J0000000000000000000000C\"},\"record_id\":\"record_01J00000000000000000000005\",\"record_type\":\"manuscript_revision\",\"revision_id\":\"revision_01J0000000000000000000000A\",\"schema_version\":\"1.0\",\"sha256\":\"sha256:2222222222222222222222222222222222222222222222222222222222222222\"}],\"previous_event_hash\":null,\"project_id\":\"project_01J00000000000000000000001\",\"provider\":null,\"relationships\":{\"invocation_id\":null,\"parent_event_ids\":[]},\"schema_version\":\"1.0\",\"timestamp\":\"2026-07-17T18:42:10.123Z\"}\n{\"actor\":{\"actor_id\":null,\"type\":\"user\"},\"client_action_id\":\"client-action-0001\",\"event_hash\":\"sha256:eb03e514fa6fcfcd291357668559b24387a84256fc39d6fb0621529003d0988e\",\"event_id\":\"event_01J00000000000000000000004\",\"event_sequence\":2,\"event_type\":\"IDEA_ACCEPTED\",\"inputs\":[],\"metadata\":{\"summary\":\"Created project\"},\"outputs\":[{\"path\":\"manuscript/revisions/revision.json\",\"range\":{\"coordinate_system\":\"utf8_byte\",\"document_revision_id\":\"revision_01J0000000000000000000000A\",\"end\":12,\"preimage_sha256\":\"sha256:1111111111111111111111111111111111111111111111111111111111111111\",\"schema_version\":\"1.0\",\"start\":0,\"text_fragment_id\":\"fragment_01J0000000000000000000000C\"},\"record_id\":\"record_01J00000000000000000000005\",\"record_type\":\"manuscript_revision\",\"revision_id\":\"revision_01J0000000000000000000000A\",\"schema_version\":\"1.0\",\"sha256\":\"sha256:2222222222222222222222222222222222222222222222222222222222222222\"}],\"previous_event_hash\":\"sha256:3a087877f4878483805f517ef0ebd108476e31ed68162504da4fad12d6d9eff4\",\"project_id\":\"project_01J00000000000000000000001\",\"provider\":null,\"relationships\":{\"invocation_id\":null,\"parent_event_ids\":[]},\"schema_version\":\"1.0\",\"timestamp\":\"2026-07-17T18:43:11.456Z\"}\n{\"actor\":{\"actor_id\":null,\"type\":\"user\"},\"client_action_id\":\"client-action-0001\",\"event_hash\":\"sha256:51935af27a4c989a014d975eab929f41fccafadedfbf1baafa15e3ce2a27a66d\",\"event_id\":\"event_01J0000000000000000000000T\",\"event_sequence\":3,\"event_type\":\"MANUSCRIPT_EDITED\",\"inputs\":[],\"metadata\":{\"summary\":\"Created project\"},\"outputs\":[{\"path\":\"manuscript/revisions/revision.json\",\"range\":{\"coordinate_system\":\"utf8_byte\",\"document_revision_id\":\"revision_01J0000000000000000000000A\",\"end\":12,\"preimage_sha256\":\"sha256:1111111111111111111111111111111111111111111111111111111111111111\",\"schema_version\":\"1.0\",\"start\":0,\"text_fragment_id\":\"fragment_01J0000000000000000000000C\"},\"record_id\":\"record_01J00000000000000000000005\",\"record_type\":\"manuscript_revision\",\"revision_id\":\"revision_01J0000000000000000000000A\",\"schema_version\":\"1.0\",\"sha256\":\"sha256:2222222222222222222222222222222222222222222222222222222222222222\"}],\"previous_event_hash\":\"sha256:eb03e514fa6fcfcd291357668559b24387a84256fc39d6fb0621529003d0988e\",\"project_id\":\"project_01J00000000000000000000001\",\"provider\":null,\"relationships\":{\"invocation_id\":null,\"parent_event_ids\":[]},\"schema_version\":\"1.0\",\"timestamp\":\"2026-07-17T18:44:12.789Z\"}\n", + "canonical_jsonl_sha256": "sha256:1ac3e55684b2a501777c01d9338bf8de10853d320ddfa0c0a030b846317888a2", + "rejected_boundary_variants": [ + "CRLF line endings", + "missing final LF", + "blank records", + "UTF-8 BOM" + ] +} diff --git a/schemas/provenance/v1/vectors/protected-record-and-key-rotation.json b/schemas/provenance/v1/vectors/protected-record-and-key-rotation.json new file mode 100644 index 0000000..8858299 --- /dev/null +++ b/schemas/provenance/v1/vectors/protected-record-and-key-rotation.json @@ -0,0 +1,101 @@ +{ + "vector_version": "1.0", + "plaintext_identity_fields": [ + "schema_version", + "record_id", + "record_type", + "payload" + ], + "plaintext_identity": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "invocation_request", + "payload": { + "purpose": "draft_from_selected_ideas" + } + }, + "canonical_plaintext_identity": "{\"payload\":{\"purpose\":\"draft_from_selected_ideas\"},\"record_id\":\"record_01J00000000000000000000005\",\"record_type\":\"invocation_request\",\"schema_version\":\"1.0\"}", + "plaintext_sha256": "sha256:97154eddff15ab6607181e55945547fdbbc5bde02b1e5123eade7a69509f00c5", + "device_key_envelope": { + "schema_version": "1.0", + "envelope_id": "record_01J00000000000000000000005", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "device", + "algorithm": "xchacha20-poly1305", + "key_derivation": null, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + }, + "recovery_key_envelope": { + "schema_version": "1.0", + "envelope_id": "record_01J0000000000000000000000S", + "key_id": "key_01J0000000000000000000000G", + "envelope_type": "recovery", + "algorithm": "xchacha20-poly1305", + "key_derivation": { + "algorithm": "argon2id", + "memory_kib": 65536, + "iterations": 3, + "parallelism": 1, + "salt": "c2FsdC1mb3ItdGhpbmtsb29t" + }, + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "wrapped_key": "d3JhcHBlZC1wcm9qZWN0LWtleQ==", + "ciphertext_sha256": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "created_at": "2026-07-17T18:42:10.123Z" + }, + "project_key_manifest": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "key_id": "key_01J0000000000000000000000G", + "algorithm": "xchacha20-poly1305", + "device_envelope_path": "provenance/keys/device-envelope.json", + "recovery_envelope_path": "provenance/keys/recovery-envelope.json", + "recovery_verified_at": "2026-07-17T18:42:10.123Z", + "created_at": "2026-07-17T18:42:10.123Z" + }, + "initial_envelope": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "record_id": "record_01J00000000000000000000005", + "record_type": "invocation_request", + "protection": "protected", + "plaintext_sha256": "sha256:97154eddff15ab6607181e55945547fdbbc5bde02b1e5123eade7a69509f00c5", + "payload": null, + "encryption": { + "algorithm": "xchacha20-poly1305", + "key_id": "key_01J0000000000000000000000G", + "nonce": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "ciphertext": "ZW5jcnlwdGVkLXJlY29yZA==", + "ciphertext_sha256": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + } + }, + "rotated_envelope": { + "schema_version": "1.0", + "project_id": "project_01J00000000000000000000001", + "record_id": "record_01J00000000000000000000005", + "record_type": "invocation_request", + "protection": "protected", + "plaintext_sha256": "sha256:97154eddff15ab6607181e55945547fdbbc5bde02b1e5123eade7a69509f00c5", + "payload": null, + "encryption": { + "algorithm": "xchacha20-poly1305", + "key_id": "key_01J0000000000000000000000V", + "nonce": "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB", + "ciphertext": "cm90YXRlZC1jaXBoZXJ0ZXh0", + "ciphertext_sha256": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + } + }, + "invariant": "Key rotation changes encryption metadata and ciphertext but preserves record_id and plaintext_sha256.", + "excluded_from_plaintext_identity": [ + "project_id", + "protection", + "plaintext_sha256", + "encryption", + "path", + "nonce", + "ciphertext" + ] +} diff --git a/schemas/provenance/v1/vectors/release-merkle.json b/schemas/provenance/v1/vectors/release-merkle.json new file mode 100644 index 0000000..2aa9c1a --- /dev/null +++ b/schemas/provenance/v1/vectors/release-merkle.json @@ -0,0 +1,26 @@ +{ + "vector_version": "1.0", + "algorithm_id": "thinkloom-release-merkle-v1", + "ordering": "Sort entries by raw UTF-8 path bytes in ascending order.", + "leaf": "SHA-256(UTF8('thinkloom-release-leaf-v1\\0') || UTF8(path) || 0x00 || UTF8(decimal size) || 0x00 || raw 32-byte file SHA-256 digest)", + "node": "SHA-256(UTF8('thinkloom-release-node-v1\\0') || raw left digest || raw right digest); duplicate the final node when a level has odd cardinality.", + "empty": "SHA-256(UTF8('thinkloom-release-empty-v1\\0'))", + "entries": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "root": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "excluded_paths": [ + "release-manifest.json", + "release-files.sha256" + ], + "self_reference_rule": "The manifest and any flat digest file that contains the root MUST NOT be Merkle leaves." +} diff --git a/schemas/provenance/v1/vectors/retention-policy-modes.json b/schemas/provenance/v1/vectors/retention-policy-modes.json new file mode 100644 index 0000000..e063499 --- /dev/null +++ b/schemas/provenance/v1/vectors/retention-policy-modes.json @@ -0,0 +1,188 @@ +{ + "vector_version": "1.0", + "default_mode": "minimal", + "minimal": { + "policy": { + "schema_version": "1.0", + "policy_id": "policy_01J0000000000000000000000H", + "project_id": "project_01J00000000000000000000001", + "retention_mode": "minimal", + "encryption_mode": "none", + "default_export_profile": "sanitized", + "effective_at": "2026-07-17T18:42:10.123Z" + }, + "invocation_request": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "minimal", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [] + }, + "invocation_response": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "invocation_id": "invocation_01J00000000000000000000008", + "retention_mode": "minimal", + "content_type": "draft_preview", + "retained_text": null, + "finish_reason": "stop", + "usage": { + "input_tokens": 120, + "output_tokens": 14 + }, + "provider_metadata": null, + "validation": { + "schema_valid": true, + "repair_attempted": false + }, + "content_sha256": "sha256:9999999999999999999999999999999999999999999999999999999999999999", + "created_at": "2026-07-17T18:43:11.456Z" + }, + "prohibited_durable_fields": [ + "complete provider-facing prompt", + "complete supplied context", + "unaccepted raw response", + "provider transport metadata", + "audio bytes or references" + ] + }, + "full_private": { + "policy": { + "schema_version": "1.0", + "policy_id": "policy_01J0000000000000000000000H", + "project_id": "project_01J00000000000000000000001", + "retention_mode": "full_private", + "encryption_mode": "protected", + "default_export_profile": "sanitized", + "effective_at": "2026-07-17T18:42:10.123Z" + }, + "invocation_request": { + "schema_version": "1.0", + "invocation_id": "invocation_01J00000000000000000000008", + "project_id": "project_01J00000000000000000000001", + "purpose": "draft_from_selected_ideas", + "initiated_by_event_id": "event_01J00000000000000000000003", + "retention_mode": "full_private", + "provider": { + "provider_id": "ollama", + "model_id": "llama3.2", + "processing_mode": "local" + }, + "model_configuration_sha256": "sha256:8888888888888888888888888888888888888888888888888888888888888888", + "prompt_template": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "version": 1, + "path": "records/prompt-templates/drafting/template.json", + "template_sha256": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + "messages": [ + { + "role": "user", + "content": "Use the selected ideas to draft a passage." + } + ], + "context_references": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "manuscript_revision_id": "revision_01J0000000000000000000000A", + "idea_revision_ids": [ + "revision_01J0000000000000000000000B" + ], + "conversation_head": "turn_01J00000000000000000000007", + "submitted_at": "2026-07-17T18:42:10.123Z", + "redactions": [ + { + "category": "personal_identifier", + "replacement": "[redacted]" + } + ] + }, + "invocation_response": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "invocation_id": "invocation_01J00000000000000000000008", + "retention_mode": "full_private", + "content_type": "draft_preview", + "retained_text": "Attention is personal in experience and public in consequence.", + "finish_reason": "stop", + "usage": { + "input_tokens": 120, + "output_tokens": 14 + }, + "provider_metadata": { + "request_id": "local-0001", + "load_duration_milliseconds": 120 + }, + "validation": { + "schema_valid": true, + "repair_attempted": false + }, + "content_sha256": "sha256:9999999999999999999999999999999999999999999999999999999999999999", + "created_at": "2026-07-17T18:43:11.456Z" + }, + "requirements": [ + "protected records", + "verified recovery envelope", + "authorized verification for plaintext evidence" + ] + }, + "policy_change_rule": "Changes are prospective. Reducing retention does not delete prior records; deletion requires emergency purge." +} diff --git a/schemas/provenance/v1/vectors/sanitized-export.json b/schemas/provenance/v1/vectors/sanitized-export.json new file mode 100644 index 0000000..ee5de8b --- /dev/null +++ b/schemas/provenance/v1/vectors/sanitized-export.json @@ -0,0 +1,41 @@ +{ + "vector_version": "1.0", + "source_chain_head_before": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_chain_head_after": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "source_record_count": 7, + "exported_record_count": 3, + "manifest": { + "schema_version": "1.0", + "export_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "source_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "profile": "sanitized", + "omission_rules": [ + { + "category": "private_conversation", + "action": "exclude", + "count": 2 + }, + { + "category": "personal_identifier", + "action": "redact", + "count": 1 + }, + { + "category": "provider_detail", + "action": "summarize", + "count": 1 + } + ], + "rules_sha256": "sha256:352ccc3dde25000a1d6dd006a4c0376f73b7805736232b09458696928d3036f6", + "files": [ + { + "path": "final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + } + ], + "created_at": "2026-07-17T18:43:11.456Z" + }, + "non_mutation_rule": "Sanitization creates a disclosure-bearing export and never rewrites the project or source chain." +} diff --git a/schemas/provenance/v1/vectors/self-digest-identities.json b/schemas/provenance/v1/vectors/self-digest-identities.json new file mode 100644 index 0000000..d443726 --- /dev/null +++ b/schemas/provenance/v1/vectors/self-digest-identities.json @@ -0,0 +1,129 @@ +{ + "vector_version": "1.0", + "prompt_template": { + "identity": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "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", + "created_at": "2026-07-17T18:42:10.123Z" + }, + "digest": "sha256:73055322741f5a248ae79ca2c38f699e40da7b5b5576f83a615a9816ddab8ba3", + "complete_record": { + "schema_version": "1.0", + "template_id": "template_01J0000000000000000000000F", + "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", + "created_at": "2026-07-17T18:42:10.123Z", + "template_sha256": "sha256:73055322741f5a248ae79ca2c38f699e40da7b5b5576f83a615a9816ddab8ba3" + }, + "excluded_fields": [ + "template_sha256" + ] + }, + "provenance_event": { + "identity": { + "schema_version": "1.0", + "event_id": "event_01J00000000000000000000003", + "event_sequence": 1, + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "timestamp": "2026-07-17T18:42:10.123Z", + "event_type": "PROJECT_CREATED", + "actor": { + "type": "user", + "actor_id": null + }, + "provider": null, + "inputs": [], + "outputs": [ + { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "manuscript_revision", + "sha256": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "path": "manuscript/revisions/revision.json", + "revision_id": "revision_01J0000000000000000000000A", + "range": { + "schema_version": "1.0", + "document_revision_id": "revision_01J0000000000000000000000A", + "coordinate_system": "utf8_byte", + "start": 0, + "end": 12, + "preimage_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111", + "text_fragment_id": "fragment_01J0000000000000000000000C" + } + } + ], + "relationships": { + "parent_event_ids": [], + "invocation_id": null + }, + "metadata": { + "summary": "Created project" + }, + "previous_event_hash": null + }, + "digest": "sha256:3a087877f4878483805f517ef0ebd108476e31ed68162504da4fad12d6d9eff4", + "excluded_fields": [ + "event_hash" + ] + }, + "protected_record": { + "identity": { + "schema_version": "1.0", + "record_id": "record_01J00000000000000000000005", + "record_type": "invocation_request", + "payload": { + "purpose": "draft_from_selected_ideas" + } + }, + "digest": "sha256:97154eddff15ab6607181e55945547fdbbc5bde02b1e5123eade7a69509f00c5", + "excluded_fields": [ + "project_id", + "protection", + "plaintext_sha256", + "encryption", + "path", + "nonce", + "ciphertext" + ] + }, + "release_manifest": { + "merkle_identity": [ + { + "path": "manuscript/final-manuscript.md", + "sha256": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "size": 1024 + }, + { + "path": "evidence/creative-process-report.md", + "sha256": "sha256:5555555555555555555555555555555555555555555555555555555555555555", + "size": 512 + } + ], + "digest": "sha256:b773ac929d720839a617ec0f9d6e39ad5401fa7795e21f799302658de8db9cda", + "excluded_paths": [ + "release-manifest.json", + "release-files.sha256" + ] + } +} diff --git a/schemas/provenance/v1/vectors/timestamp-and-path.json b/schemas/provenance/v1/vectors/timestamp-and-path.json new file mode 100644 index 0000000..b44fdf9 --- /dev/null +++ b/schemas/provenance/v1/vectors/timestamp-and-path.json @@ -0,0 +1,35 @@ +{ + "vector_version": "1.0", + "timestamps": { + "accepted": [ + "2026-07-17T18:42:10.123Z", + "2026-07-17T18:43:11.456Z", + "2000-01-01T00:00:00.000Z" + ], + "rejected": [ + "2026-07-17T18:42:10Z", + "2026-07-17T18:42:10.12Z", + "2026-07-17T18:42:10.1234Z", + "2026-07-17T11:42:10.123-07:00", + "not-a-timestamp" + ] + }, + "repository_paths": { + "accepted": [ + "project.json", + "records/invocations/request.json", + "manuscript/Café.md" + ], + "rejected": [ + "", + "/absolute/path", + "C:/absolute/path", + "records\\request.json", + ".", + "..", + "records/../outside.json", + "records/./alias.json" + ] + }, + "normalization_rule": "Paths use NFC, forward slashes, repository-relative spelling, and no dot segments." +} diff --git a/schemas/provenance/v1/vectors/verification-statuses.json b/schemas/provenance/v1/vectors/verification-statuses.json new file mode 100644 index 0000000..fec6ae6 --- /dev/null +++ b/schemas/provenance/v1/vectors/verification-statuses.json @@ -0,0 +1,124 @@ +{ + "vector_version": "1.0", + "reports": [ + { + "schema_version": "1.0", + "verification_id": "record_01J0000000000000000000000W", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "checked_segments": 1, + "checked_events": 1, + "checked_records": 4, + "findings": [], + "verifier_version": "1.0.0", + "completed_at": "2026-07-17T18:43:11.456Z" + }, + { + "schema_version": "1.0", + "verification_id": "record_01J0000000000000000000000X", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "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": "2026-07-17T18:43:11.456Z" + }, + { + "schema_version": "1.0", + "verification_id": "record_01J0000000000000000000000Y", + "project_id": "project_01J00000000000000000000001", + "status": "INCOMPLETE", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "checked_segments": 1, + "checked_events": 1, + "checked_records": 4, + "findings": [ + { + "severity": "INFO", + "code": "OPTIONAL_BINARY_MISSING", + "message": "An optional release binary is unavailable.", + "authoritative_evidence_affected": false, + "path": "provenance/indexes/contribution-graph.json", + "event_id": null + } + ], + "verifier_version": "1.0.0", + "completed_at": "2026-07-17T18:43:11.456Z" + }, + { + "schema_version": "1.0", + "verification_id": "record_01J0000000000000000000000Z", + "project_id": "project_01J00000000000000000000001", + "status": "FAILED", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "checked_segments": 1, + "checked_events": 1, + "checked_records": 4, + "findings": [ + { + "severity": "ERROR", + "code": "EVENT_HASH_MISMATCH", + "message": "An event digest does not match canonical content.", + "authoritative_evidence_affected": true, + "path": "provenance/indexes/contribution-graph.json", + "event_id": null + } + ], + "verifier_version": "1.0.0", + "completed_at": "2026-07-17T18:43:11.456Z" + }, + { + "schema_version": "1.0", + "verification_id": "record_01J00000000000000000000000", + "project_id": "project_01J00000000000000000000001", + "status": "UNSAFE", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "checked_segments": 1, + "checked_events": 1, + "checked_records": 4, + "findings": [ + { + "severity": "CRITICAL", + "code": "CHAIN_RECONSTITUTED", + "message": "The chain cannot establish ordinary continuity.", + "authoritative_evidence_affected": true, + "path": "provenance/indexes/contribution-graph.json", + "event_id": null + } + ], + "verifier_version": "1.0.0", + "completed_at": "2026-07-17T18:43:11.456Z" + } + ], + "required_statuses": [ + "VERIFIED", + "VERIFIED_WITH_WARNINGS", + "INCOMPLETE", + "FAILED", + "UNSAFE" + ], + "required_severities": [ + "INFO", + "WARNING", + "ERROR", + "CRITICAL" + ] +} diff --git a/schemas/provenance/v1/verification-report.schema.json b/schemas/provenance/v1/verification-report.schema.json new file mode 100644 index 0000000..71f2a04 --- /dev/null +++ b/schemas/provenance/v1/verification-report.schema.json @@ -0,0 +1,171 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/verification-report.schema.json", + "title": "Verification report", + "description": "Authoritative native verification result rendered by the UI.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "verification_id": { + "type": "string", + "pattern": "^record_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "project_id": { + "type": "string", + "pattern": "^project_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "status": { + "enum": [ + "VERIFIED", + "VERIFIED_WITH_WARNINGS", + "INCOMPLETE", + "FAILED", + "UNSAFE" + ] + }, + "verified_through_event_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^event_[0-9A-HJKMNP-TV-Z]{26}$" + }, + { + "type": "null" + } + ] + }, + "verified_chain_head": { + "anyOf": [ + { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + }, + { + "type": "null" + } + ] + }, + "checked_segments": { + "type": "integer", + "minimum": 0 + }, + "checked_events": { + "type": "integer", + "minimum": 0 + }, + "checked_records": { + "type": "integer", + "minimum": 0 + }, + "findings": { + "type": "array", + "items": { + "type": "object", + "properties": { + "severity": { + "enum": [ + "INFO", + "WARNING", + "ERROR", + "CRITICAL" + ] + }, + "code": { + "type": "string", + "pattern": "^[A-Z][A-Z0-9_]+$" + }, + "message": { + "type": "string", + "minLength": 1 + }, + "authoritative_evidence_affected": { + "type": "boolean" + }, + "path": { + "anyOf": [ + { + "type": "string", + "minLength": 1, + "pattern": "^(?!/)(?![A-Za-z]:)(?!.*\\\\)(?!.*(?:^|/)\\.\\.?(?:/|$))[^\\u0000-\\u001f]+$" + }, + { + "type": "null" + } + ] + }, + "event_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^event_[0-9A-HJKMNP-TV-Z]{26}$" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "severity", + "code", + "message", + "authoritative_evidence_affected", + "path", + "event_id" + ], + "additionalProperties": false + } + }, + "verifier_version": { + "type": "string", + "pattern": "^\\d+\\.\\d+\\.\\d+$" + }, + "completed_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", + "verification_id", + "project_id", + "status", + "verified_through_event_id", + "verified_chain_head", + "checked_segments", + "checked_events", + "checked_records", + "findings", + "verifier_version", + "completed_at" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "verification_id": "record_01J00000000000000000000005", + "project_id": "project_01J00000000000000000000001", + "status": "VERIFIED_WITH_WARNINGS", + "verified_through_event_id": "event_01J00000000000000000000003", + "verified_chain_head": "sha256:4444444444444444444444444444444444444444444444444444444444444444", + "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": "2026-07-17T18:43:11.456Z" + } + ] +} diff --git a/schemas/provenance/v1/write-intent.schema.json b/schemas/provenance/v1/write-intent.schema.json new file mode 100644 index 0000000..95b23cc --- /dev/null +++ b/schemas/provenance/v1/write-intent.schema.json @@ -0,0 +1,130 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://thinkloom.app/schemas/provenance/1.0/write-intent.schema.json", + "title": "Cross-store write intent", + "description": "Rebuildable SQLite coordination record for a cross-store mutation.", + "type": "object", + "properties": { + "schema_version": { + "const": "1.0" + }, + "intent_id": { + "type": "string", + "pattern": "^intent_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "client_action_id": { + "type": "string", + "minLength": 8, + "maxLength": 200 + }, + "project_id": { + "type": "string", + "pattern": "^project_[0-9A-HJKMNP-TV-Z]{26}$" + }, + "operation_type": { + "type": "string", + "pattern": "^[A-Z][A-Z0-9_]+$" + }, + "phase": { + "enum": [ + "PREPARED", + "RECORDS_DURABLE", + "LEDGER_APPENDED", + "CHAIN_HEAD_ADVANCED", + "SQLITE_APPLIED", + "COMPLETE", + "QUARANTINED", + "FAILED" + ] + }, + "event_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^event_[0-9A-HJKMNP-TV-Z]{26}$" + }, + { + "type": "null" + } + ] + }, + "event_sequence": { + "anyOf": [ + { + "type": "integer", + "minimum": 1 + }, + { + "type": "null" + } + ] + }, + "staged_path": { + "anyOf": [ + { + "type": "string", + "minLength": 1, + "pattern": "^(?!/)(?![A-Za-z]:)(?!.*\\\\)(?!.*(?:^|/)\\.\\.?(?:/|$))[^\\u0000-\\u001f]+$" + }, + { + "type": "null" + } + ] + }, + "command_sha256": { + "type": "string", + "pattern": "^sha256:[a-f0-9]{64}$" + }, + "result": { + "anyOf": [ + {}, + { + "type": "null" + } + ] + }, + "created_at": { + "type": "string", + "format": "date-time", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$" + }, + "updated_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", + "intent_id", + "client_action_id", + "project_id", + "operation_type", + "phase", + "event_id", + "event_sequence", + "staged_path", + "command_sha256", + "result", + "created_at", + "updated_at" + ], + "additionalProperties": false, + "examples": [ + { + "schema_version": "1.0", + "intent_id": "intent_01J00000000000000000000002", + "client_action_id": "client-action-0001", + "project_id": "project_01J00000000000000000000001", + "operation_type": "IDEA_ACCEPTED", + "phase": "PREPARED", + "event_id": null, + "event_sequence": null, + "staged_path": ".app/temp/intents/intent.json", + "command_sha256": "sha256:3333333333333333333333333333333333333333333333333333333333333333", + "result": null, + "created_at": "2026-07-17T18:42:10.123Z", + "updated_at": "2026-07-17T18:42:10.123Z" + } + ] +} diff --git a/scripts/generate-provenance-stage2.mjs b/scripts/generate-provenance-stage2.mjs new file mode 100644 index 0000000..b7de9a3 --- /dev/null +++ b/scripts/generate-provenance-stage2.mjs @@ -0,0 +1,701 @@ +import { mkdir, rm, writeFile } from "node:fs/promises"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import { canonicalize, hashEvent, releaseMerkleRoot, sha256 } from "./provenance-stage2-lib.mjs"; + +const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); +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 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"; +const laterTimestamp = "2026-07-17T18:43:11.456Z"; +const digest = (character = "a") => `sha256:${character.repeat(64)}`; +const ulid = (suffix = "0") => `01J${"0".repeat(22)}${suffix}`; +const typedId = (type, suffix = "0") => `${type}_${ulid(suffix)}`; +const ids = { + project: typedId("project", "1"), intent: typedId("intent", "2"), event: typedId("event", "3"), event2: typedId("event", "4"), + record: typedId("record", "5"), session: typedId("session", "6"), turn: typedId("turn", "7"), invocation: typedId("invocation", "8"), + idea: typedId("idea", "9"), revision: typedId("revision", "A"), revision2: typedId("revision", "B"), fragment: typedId("fragment", "C"), + 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"), +}; + +if (!Object.values(ids).every((value) => /^[a-z]+_[0-9A-HJKMNP-TV-Z]{26}$/.test(value))) throw new Error("Generated fixture identifier is invalid."); + +const schemaVersion = { const: "1.0" }; +const timestamp = { type: "string", format: "date-time", pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$" }; +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 repositoryPath = { type: "string", minLength: 1, pattern: "^(?!/)(?![A-Za-z]:)(?!.*\\\\)(?!.*(?:^|/)\\.\\.?(?:/|$))[^\\u0000-\\u001f]+$" }; +const nonEmptyString = { type: "string", minLength: 1 }; +const jsonValue = {}; +const nullable = (schema) => ({ anyOf: [schema, { type: "null" }] }); +const ref = (name) => ({ $ref: `${baseId}/${name}.schema.json` }); +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 schemas = new Map(); +function add(name, title, body, example, description) { + const schema = { $schema: draft, $id: `${baseId}/${name}.schema.json`, title, description, ...body, examples: [example] }; + schemas.set(name, schema); + return schema; +} + +const actor = closed({ type: { enum: ["user", "assistant", "system"] }, actor_id: nullable(nonEmptyString) }); +const provider = closed({ provider_id: nonEmptyString, model_id: nonEmptyString, processing_mode: { enum: ["local", "cloud"] } }); +const fileEntry = closed({ path: repositoryPath, sha256: sha, size: { type: "integer", minimum: 0 } }); +const finding = closed({ severity: { enum: ["INFO", "WARNING", "ERROR", "CRITICAL"] }, code: { type: "string", pattern: "^[A-Z][A-Z0-9_]+$" }, message: nonEmptyString, authoritative_evidence_affected: { type: "boolean" }, path: nullable(repositoryPath), event_id: nullable(identifier("event")) }); + +const textRangeExample = { + schema_version: "1.0", + document_revision_id: ids.revision, + coordinate_system: "utf8_byte", + start: 0, + end: 12, + preimage_sha256: digest("1"), + text_fragment_id: ids.fragment, +}; + +add("text-fragment-reference", "Text fragment reference", closed({ + schema_version: schemaVersion, + document_revision_id: identifier("revision"), + coordinate_system: { enum: ["utf8_byte", "unicode_scalar", "utf16_code_unit", "editor_position"] }, + start: { type: "integer", minimum: 0 }, + end: { type: "integer", minimum: 0 }, + preimage_sha256: sha, + text_fragment_id: nullable(identifier("fragment")), +}), textRangeExample, "Stable revision-bound text range with an explicit coordinate system."); + +const contentReferenceExample = { + schema_version: "1.0", + record_id: ids.record, + record_type: "manuscript_revision", + sha256: digest("2"), + path: "manuscript/revisions/revision.json", + revision_id: ids.revision, + range: textRangeExample, +}; +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"] }, + sha256: sha, + path: nullable(repositoryPath), + revision_id: nullable(identifier("revision")), + range: nullable(ref("text-fragment-reference")), +}, ["schema_version", "record_id", "record_type", "sha256", "path", "revision_id", "range"]), contentReferenceExample, "Content-addressed link to an authoritative record or revision."); + +const policyExample = { + schema_version: "1.0", policy_id: ids.policy, project_id: ids.project, retention_mode: "minimal", encryption_mode: "none", default_export_profile: "sanitized", effective_at: timestampValue, +}; +add("provenance-policy", "Provenance policy", closed({ + schema_version: schemaVersion, policy_id: identifier("policy"), project_id: identifier("project"), retention_mode: { enum: ["minimal", "full_private"] }, encryption_mode: { enum: ["none", "protected"] }, default_export_profile: { enum: ["full", "sanitized"] }, effective_at: timestamp, +}), 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, +}; +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 }, +}, ["schema_version", "application_version", "project_id", "title", "created_at", "updated_at", "current_phase", "publication_status", "provenance_policy_id", "audio_retained"]), projectExample, "Canonical identity and lifecycle metadata for a 1.0 project."); + +const writeIntentExample = { + schema_version: "1.0", intent_id: ids.intent, client_action_id: "client-action-0001", project_id: ids.project, operation_type: "IDEA_ACCEPTED", phase: "PREPARED", event_id: null, event_sequence: null, staged_path: ".app/temp/intents/intent.json", command_sha256: digest("3"), result: null, created_at: timestampValue, updated_at: timestampValue, +}; +add("write-intent", "Cross-store write intent", closed({ + schema_version: schemaVersion, intent_id: identifier("intent"), client_action_id: { type: "string", minLength: 8, maxLength: 200 }, project_id: identifier("project"), operation_type: { type: "string", pattern: "^[A-Z][A-Z0-9_]+$" }, phase: { enum: ["PREPARED", "RECORDS_DURABLE", "LEDGER_APPENDED", "CHAIN_HEAD_ADVANCED", "SQLITE_APPLIED", "COMPLETE", "QUARANTINED", "FAILED"] }, event_id: nullable(identifier("event")), event_sequence: nullable({ type: "integer", minimum: 1 }), staged_path: nullable(repositoryPath), command_sha256: sha, result: nullable(jsonValue), created_at: timestamp, updated_at: timestamp, +}), writeIntentExample, "Rebuildable SQLite coordination record for a cross-store mutation."); + +const eventExample = { + schema_version: "1.0", event_id: ids.event, event_sequence: 1, client_action_id: "client-action-0001", project_id: ids.project, timestamp: timestampValue, event_type: "PROJECT_CREATED", actor: { type: "user", actor_id: null }, provider: null, inputs: [], outputs: [contentReferenceExample], relationships: { parent_event_ids: [], invocation_id: null }, metadata: { summary: "Created project" }, previous_event_hash: null, event_hash: digest("4"), +}; +add("provenance-event", "Provenance event", closed({ + schema_version: schemaVersion, event_id: identifier("event"), event_sequence: { type: "integer", minimum: 1 }, client_action_id: { type: "string", minLength: 8, maxLength: 200 }, project_id: identifier("project"), timestamp, event_type: { type: "string", pattern: "^[A-Z][A-Z0-9_]+$" }, actor, provider: nullable(provider), inputs: arrayOf(ref("content-reference")), outputs: arrayOf(ref("content-reference")), relationships: closed({ parent_event_ids: arrayOf(identifier("event"), { uniqueItems: true }), invocation_id: nullable(identifier("invocation")) }), metadata: { type: "object" }, previous_event_hash: nullable(sha), event_hash: sha, +}), eventExample, "Canonical chronological action with content references and SHA-256 chain linkage."); + +const chainHeadExample = { schema_version: "1.0", project_id: ids.project, active_segment_number: 1, event_id: ids.event, event_sequence: 1, event_hash: digest("4"), updated_at: timestampValue }; +add("chain-head", "Chain head", closed({ schema_version: schemaVersion, project_id: identifier("project"), active_segment_number: { type: "integer", minimum: 1 }, event_id: identifier("event"), event_sequence: { type: "integer", minimum: 1 }, event_hash: sha, updated_at: timestamp }), chainHeadExample, "Durable pointer to the last committed provenance event."); + +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 }; +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") }; +add("prompt-template-reference", "Prompt template reference", closed({ schema_version: schemaVersion, template_id: identifier("template"), version: { type: "integer", minimum: 1 }, path: repositoryPath, template_sha256: sha }), promptRefExample, "Reference to an immutable prompt-template version."); + +const capabilityExample = { schema_version: "1.0", snapshot_id: ids.record, provider_id: "ollama", model_id: "llama3.2", capabilities: { streaming: true, structured_output: false, tools: false, vision: false }, observed_at: timestampValue }; +add("model-capability-snapshot", "Model capability snapshot", closed({ schema_version: schemaVersion, snapshot_id: identifier("record"), provider_id: nonEmptyString, model_id: nonEmptyString, capabilities: closed({ streaming: { type: "boolean" }, structured_output: { type: "boolean" }, tools: { type: "boolean" }, vision: { type: "boolean" } }), observed_at: timestamp }), capabilityExample, "Immutable observed capability set for an invoked model."); + +const modelConfigExample = { schema_version: "1.0", snapshot_id: ids.record, provider_id: "ollama", model_id: "llama3.2", processing_mode: "local", endpoint_classification: "loopback", temperature_milli: 700, context_limit: 8192, maximum_output: 800, structured_output_mode: "none", tool_configuration: [], capability_snapshot_sha256: digest("8"), created_at: timestampValue }; +add("model-configuration-snapshot", "Model configuration snapshot", closed({ schema_version: schemaVersion, snapshot_id: identifier("record"), provider_id: nonEmptyString, model_id: nonEmptyString, processing_mode: { enum: ["local", "cloud"] }, endpoint_classification: { enum: ["loopback", "private_network", "public_cloud", "custom"] }, temperature_milli: nullable({ type: "integer", minimum: 0, maximum: 2000 }), context_limit: nullable({ type: "integer", minimum: 1 }), maximum_output: nullable({ type: "integer", minimum: 1 }), structured_output_mode: { enum: ["none", "json", "json_schema", "provider_native"] }, tool_configuration: arrayOf(nonEmptyString, { uniqueItems: true }), capability_snapshot_sha256: sha, created_at: timestamp }), modelConfigExample, "Effective credential-free model settings used by one invocation."); + +const invocationStateExample = { schema_version: "1.0", invocation_id: ids.invocation, state: "REQUEST_RECORDED", state_sequence: 2, updated_at: timestampValue, failure_id: null }; +add("invocation-state", "Invocation state", closed({ schema_version: schemaVersion, invocation_id: identifier("invocation"), state: { enum: ["REQUEST_PREPARED", "REQUEST_RECORDED", "MODEL_RUNNING", "RESPONSE_RECEIVED", "RESPONSE_RECORDED", "STAGED_PREVIEW", "FAILED", "CANCELLED", "ABANDONED"] }, state_sequence: { type: "integer", minimum: 1 }, updated_at: timestamp, failure_id: nullable(identifier("failure")) }), invocationStateExample, "Operational invocation lifecycle projection."); + +const streamStateExample = { schema_version: "1.0", stream_id: ids.stream, invocation_id: ids.invocation, state: "STREAMING", bytes_received: 512, started_at: timestampValue, updated_at: laterTimestamp }; +add("invocation-stream-state", "Invocation stream state", closed({ schema_version: schemaVersion, stream_id: identifier("stream"), invocation_id: identifier("invocation"), state: { enum: ["CREATED", "CONNECTING", "STREAMING", "COMPLETED", "FAILED", "CANCELLED", "ABANDONED", "RECOVERING"] }, bytes_received: { type: "integer", minimum: 0, maximum: 67108864 }, started_at: timestamp, updated_at: timestamp }), streamStateExample, "Non-authoritative operational streaming state."); + +const streamSummaryExample = { schema_version: "1.0", stream_id: ids.stream, invocation_id: ids.invocation, terminal_state: "COMPLETED", bytes_received: 512, chunks_received: 4, duration_milliseconds: 2400, partial_output_preserved: false, completed_at: laterTimestamp }; +add("invocation-stream-summary", "Invocation stream summary", closed({ schema_version: schemaVersion, stream_id: identifier("stream"), invocation_id: identifier("invocation"), terminal_state: { enum: ["COMPLETED", "FAILED", "CANCELLED", "ABANDONED"] }, bytes_received: { type: "integer", minimum: 0, maximum: 67108864 }, chunks_received: { type: "integer", minimum: 0 }, duration_milliseconds: { type: "integer", minimum: 0, maximum: 1800000 }, partial_output_preserved: { type: "boolean" }, completed_at: timestamp }), streamSummaryExample, "Bounded immutable summary of a completed or interrupted stream."); + +const requestExample = { schema_version: "1.0", invocation_id: ids.invocation, project_id: ids.project, purpose: "draft_from_selected_ideas", initiated_by_event_id: ids.event, retention_mode: "full_private", provider: { provider_id: "ollama", model_id: "llama3.2", processing_mode: "local" }, model_configuration_sha256: digest("8"), prompt_template: promptRefExample, messages: [{ role: "user", content: "Use the selected ideas to draft a passage." }], context_references: [contentReferenceExample], manuscript_revision_id: ids.revision, idea_revision_ids: [ids.revision2], conversation_head: ids.turn, submitted_at: timestampValue, redactions: [{ category: "personal_identifier", replacement: "[redacted]" }] }; +add("invocation-request", "Invocation request", closed({ schema_version: schemaVersion, invocation_id: identifier("invocation"), project_id: identifier("project"), purpose: { type: "string", pattern: "^[a-z][a-z0-9_]+$" }, initiated_by_event_id: identifier("event"), retention_mode: { enum: ["minimal", "full_private"] }, provider, model_configuration_sha256: sha, prompt_template: ref("prompt-template-reference"), messages: arrayOf(closed({ role: { enum: ["system", "user", "assistant", "tool"] }, content: nonEmptyString })), context_references: arrayOf(ref("content-reference")), manuscript_revision_id: nullable(identifier("revision")), idea_revision_ids: arrayOf(identifier("revision"), { uniqueItems: true }), conversation_head: nullable(identifier("turn")), submitted_at: timestamp, redactions: arrayOf(closed({ category: { enum: ["credential", "personal_identifier", "signed_url", "policy_omission", "other"] }, replacement: nonEmptyString })) }), requestExample, "Credential-free immutable provider request evidence; minimal mode may omit messages."); + +const responseExample = { schema_version: "1.0", record_id: ids.record, invocation_id: ids.invocation, retention_mode: "full_private", content_type: "draft_preview", retained_text: "Attention is personal in experience and public in consequence.", finish_reason: "stop", usage: { input_tokens: 120, output_tokens: 14 }, provider_metadata: { request_id: "local-0001", load_duration_milliseconds: 120 }, validation: { schema_valid: true, repair_attempted: false }, content_sha256: digest("9"), created_at: laterTimestamp }; +add("invocation-response", "Invocation response", closed({ schema_version: schemaVersion, record_id: identifier("record"), invocation_id: identifier("invocation"), retention_mode: { enum: ["minimal", "full_private"] }, content_type: { enum: ["conversation_reply", "idea_suggestion", "draft_preview", "editorial_preview", "structured_result", "other"] }, retained_text: nullable({ type: "string" }), finish_reason: nullable(nonEmptyString), usage: nullable(closed({ input_tokens: nullable({ type: "integer", minimum: 0 }), output_tokens: nullable({ type: "integer", minimum: 0 }) })), provider_metadata: nullable({ type: "object" }), validation: closed({ schema_valid: { type: "boolean" }, repair_attempted: { type: "boolean" } }), content_sha256: sha, created_at: timestamp }), responseExample, "Immutable response evidence filtered according to retention policy."); + +const failureExample = { schema_version: "1.0", failure_id: ids.failure, invocation_id: ids.invocation, code: "PROVIDER_TIMEOUT", category: "provider", recoverable: true, bounded_summary: "The provider did not respond within the configured timeout.", partial_output_preserved: false, occurred_at: laterTimestamp }; +add("invocation-failure", "Invocation failure", closed({ schema_version: schemaVersion, failure_id: identifier("failure"), invocation_id: identifier("invocation"), code: { type: "string", pattern: "^[A-Z][A-Z0-9_]+$" }, category: { enum: ["provider", "validation", "cancellation", "output_limit", "application", "privacy"] }, recoverable: { type: "boolean" }, bounded_summary: { type: "string", minLength: 1, maxLength: 2000 }, partial_output_preserved: { type: "boolean" }, occurred_at: timestamp }), failureExample, "Immutable bounded record of an invocation failure."); + +const sessionExample = { schema_version: "1.0", session_id: ids.session, project_id: ids.project, title: "Opening discussion", mode: "typed", started_at: timestampValue, ended_at: laterTimestamp, turn_count: 2, audio_retained: false, retention_mode: "minimal" }; +add("conversation-session", "Conversation session", closed({ schema_version: schemaVersion, session_id: identifier("session"), project_id: identifier("project"), title: { type: "string" }, mode: { enum: ["typed", "voice", "mixed"] }, started_at: timestamp, ended_at: nullable(timestamp), turn_count: { type: "integer", minimum: 0 }, audio_retained: { const: false }, retention_mode: { enum: ["minimal", "full_private"] } }), sessionExample, "Canonical conversation-session metadata without audio retention."); + +const turnExample = { schema_version: "1.0", turn_id: ids.turn, session_id: ids.session, speaker: "user", input_mode: "typed", retained_text: "Attention shapes public life.", raw_transcript: null, started_at: timestampValue, ended_at: laterTimestamp, audio_retained: false, invocation_id: null, event_id: ids.event }; +add("transcript-turn", "Transcript turn", closed({ schema_version: schemaVersion, turn_id: identifier("turn"), session_id: identifier("session"), speaker: { enum: ["user", "assistant"] }, input_mode: { enum: ["typed", "voice"] }, retained_text: nonEmptyString, raw_transcript: nullable({ type: "string" }), started_at: timestamp, ended_at: timestamp, audio_retained: { const: false }, invocation_id: nullable(identifier("invocation")), event_id: identifier("event") }), turnExample, "Immutable retained conversation turn permitted by project policy."); + +const correctionExample = { schema_version: "1.0", correction_id: ids.correction, turn_id: ids.turn, revision_number: 1, corrected_text: "Attention shapes our public life.", reason: "user_correction", created_at: laterTimestamp, event_id: ids.event2 }; +add("transcript-correction", "Transcript correction", closed({ schema_version: schemaVersion, correction_id: identifier("correction"), turn_id: identifier("turn"), revision_number: { type: "integer", minimum: 1 }, corrected_text: nonEmptyString, reason: { enum: ["user_correction", "transcription_error", "clarification", "other"] }, created_at: timestamp, event_id: identifier("event") }), correctionExample, "Immutable ordered correction to a retained transcript turn."); + +const normalizationExample = { schema_version: "1.0", normalization_id: ids.normalization, turn_id: ids.turn, revision_number: 1, normalized_text: "Attention shapes public life.", method: "application", source_correction_id: ids.correction, created_at: laterTimestamp, event_id: ids.event2 }; +add("transcript-normalization", "Transcript normalization", closed({ schema_version: schemaVersion, normalization_id: identifier("normalization"), turn_id: identifier("turn"), revision_number: { type: "integer", minimum: 1 }, normalized_text: nonEmptyString, method: { enum: ["application", "user_approved", "provider"] }, source_correction_id: nullable(identifier("correction")), created_at: timestamp, event_id: identifier("event") }), normalizationExample, "Immutable normalized representation derived from a transcript revision."); + +const keyEnvelopeExample = { schema_version: "1.0", envelope_id: ids.record, key_id: ids.key, envelope_type: "device", algorithm: "xchacha20-poly1305", key_derivation: null, nonce: "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", wrapped_key: "d3JhcHBlZC1wcm9qZWN0LWtleQ==", ciphertext_sha256: digest("a"), created_at: timestampValue }; +add("encrypted-key-envelope", "Encrypted key envelope", closed({ schema_version: schemaVersion, envelope_id: identifier("record"), key_id: identifier("key"), envelope_type: { enum: ["device", "recovery"] }, algorithm: { enum: ["xchacha20-poly1305"] }, key_derivation: nullable(closed({ algorithm: { const: "argon2id" }, memory_kib: { type: "integer", minimum: 65536 }, iterations: { type: "integer", minimum: 1 }, parallelism: { type: "integer", minimum: 1 }, salt: { type: "string", minLength: 16 } })), nonce: { type: "string", minLength: 32 }, wrapped_key: { type: "string", minLength: 16 }, ciphertext_sha256: sha, created_at: timestamp }), keyEnvelopeExample, "Authenticated envelope wrapping a project data-encryption key."); + +const recoveryEnvelopeExample = { ...keyEnvelopeExample, envelope_id: typedId("record", "S"), envelope_type: "recovery", key_derivation: { algorithm: "argon2id", memory_kib: 65536, iterations: 3, parallelism: 1, salt: "c2FsdC1mb3ItdGhpbmtsb29t" } }; +add("recovery-key-envelope", "Recovery key envelope", closed({ ...schemas.get("encrypted-key-envelope").properties, envelope_type: { const: "recovery" }, key_derivation: closed({ algorithm: { const: "argon2id" }, memory_kib: { type: "integer", minimum: 65536 }, iterations: { type: "integer", minimum: 1 }, parallelism: { type: "integer", minimum: 1 }, salt: { type: "string", minLength: 16 } }) }), recoveryEnvelopeExample, "Portable recovery envelope for a protected project key."); + +const keyManifestExample = { schema_version: "1.0", project_id: ids.project, key_id: ids.key, algorithm: "xchacha20-poly1305", device_envelope_path: "provenance/keys/device-envelope.json", recovery_envelope_path: "provenance/keys/recovery-envelope.json", recovery_verified_at: timestampValue, created_at: timestampValue }; +add("project-key-manifest", "Project key manifest", closed({ schema_version: schemaVersion, project_id: identifier("project"), key_id: identifier("key"), algorithm: { const: "xchacha20-poly1305" }, device_envelope_path: repositoryPath, recovery_envelope_path: repositoryPath, recovery_verified_at: timestamp, created_at: timestamp }), keyManifestExample, "Stable key hierarchy references for protected project portability."); + +const plaintextIdentity = { schema_version: "1.0", record_id: ids.record, record_type: "invocation_request", payload: { purpose: "draft_from_selected_ideas" } }; +const recordEnvelopeExample = { schema_version: "1.0", project_id: ids.project, record_id: ids.record, record_type: "invocation_request", protection: "protected", plaintext_sha256: sha256(plaintextIdentity), payload: null, encryption: { algorithm: "xchacha20-poly1305", key_id: ids.key, nonce: "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", ciphertext: "ZW5jcnlwdGVkLXJlY29yZA==", ciphertext_sha256: digest("b") } }; +const recordEnvelopeProperties = { + schema_version: schemaVersion, + project_id: identifier("project"), + record_id: identifier("record"), + record_type: { type: "string", pattern: "^[a-z][a-z0-9_]+$" }, + protection: { enum: ["none", "protected"] }, + plaintext_sha256: sha, + payload: nullable(jsonValue), + encryption: nullable(closed({ + algorithm: { const: "xchacha20-poly1305" }, + key_id: identifier("key"), + nonce: { type: "string", minLength: 32 }, + ciphertext: { type: "string", minLength: 16 }, + ciphertext_sha256: sha, + })), +}; +const recordEnvelopeRules = { + allOf: [ + { + if: { properties: { protection: { const: "none" } }, required: ["protection"] }, + then: { + properties: { + payload: { not: { type: "null" } }, + encryption: { type: "null" }, + }, + }, + }, + { + if: { properties: { protection: { const: "protected" } }, required: ["protection"] }, + then: { + properties: { + payload: { type: "null" }, + encryption: { not: { type: "null" } }, + }, + }, + }, + ], +}; +add("record-envelope", "Authoritative record envelope", closed(recordEnvelopeProperties, undefined, recordEnvelopeRules), recordEnvelopeExample, "Stable logical record identity with plaintext or authenticated protected payload."); + +const ideaExample = { schema_version: "1.0", idea_id: ids.idea, project_id: ids.project, current_revision_id: ids.revision, status: "accepted", created_at: timestampValue, updated_at: laterTimestamp }; +add("idea", "Idea identity", closed({ schema_version: schemaVersion, idea_id: identifier("idea"), project_id: identifier("project"), current_revision_id: identifier("revision"), status: { enum: ["suggested", "accepted", "rejected", "archived"] }, created_at: timestamp, updated_at: timestamp }), ideaExample, "Stable idea identity and current derived status."); + +const ideaRevisionExample = { schema_version: "1.0", revision_id: ids.revision, idea_id: ids.idea, revision_number: 1, title: "Attention as civic infrastructure", summary: "Institutions influence shared attention.", detail: "Treat attention as a public condition.", tags: ["thesis"], source_turn_ids: [ids.turn], parent_idea_ids: [], created_by: "mixed", created_at: timestampValue, content_sha256: digest("c") }; +add("idea-revision", "Idea revision", closed({ schema_version: schemaVersion, revision_id: identifier("revision"), idea_id: identifier("idea"), revision_number: { type: "integer", minimum: 1 }, title: nonEmptyString, summary: nonEmptyString, detail: { type: "string" }, tags: arrayOf(nonEmptyString, { uniqueItems: true }), source_turn_ids: arrayOf(identifier("turn"), { uniqueItems: true }), parent_idea_ids: arrayOf(identifier("idea"), { uniqueItems: true }), created_by: { enum: ["user", "assistant", "mixed"] }, created_at: timestamp, content_sha256: sha }), ideaRevisionExample, "Immutable content revision for one idea."); + +const manuscriptRevisionExample = { schema_version: "1.0", revision_id: ids.revision, project_id: ids.project, parent_revision_id: null, canonical_markdown_path: "manuscript/revisions/revision.md", canonical_markdown_sha256: digest("d"), word_count: 42, created_by: "user", created_at: timestampValue }; +add("manuscript-revision", "Manuscript revision", closed({ schema_version: schemaVersion, revision_id: identifier("revision"), project_id: identifier("project"), parent_revision_id: nullable(identifier("revision")), canonical_markdown_path: repositoryPath, canonical_markdown_sha256: sha, word_count: { type: "integer", minimum: 0 }, created_by: { enum: ["user", "assistant_acceptance", "system_restore"] }, created_at: timestamp }), manuscriptRevisionExample, "Immutable canonical manuscript revision."); + +const operation = closed({ operation_type: { enum: ["insert", "delete", "replace", "move", "format"] }, source_range: nullable(ref("text-fragment-reference")), destination_position: nullable({ type: "integer", minimum: 0 }), inserted_text_sha256: nullable(sha), result_fragment_id: nullable(identifier("fragment")) }); +const editExample = { schema_version: "1.0", transaction_id: ids.transaction, project_id: ids.project, base_revision_id: ids.revision, result_revision_id: ids.revision2, started_at: timestampValue, ended_at: laterTimestamp, operations: [{ operation_type: "insert", source_range: null, destination_position: 0, inserted_text_sha256: digest("e"), result_fragment_id: ids.fragment }], preimage_sha256: digest("d"), result_sha256: digest("e") }; +add("edit-transaction", "Manuscript edit transaction", closed({ schema_version: schemaVersion, transaction_id: identifier("transaction"), project_id: identifier("project"), base_revision_id: identifier("revision"), result_revision_id: identifier("revision"), started_at: timestamp, ended_at: timestamp, operations: arrayOf(operation, { minItems: 1 }), preimage_sha256: sha, result_sha256: sha }), editExample, "Meaningful coalesced manual or acceptance-driven edit transaction."); +const dispositionExample = { schema_version: "1.0", disposition_id: ids.disposition, invocation_id: ids.invocation, revision_number: 1, status: "partially_accepted", accepted_ranges: [textRangeExample], rejected_ranges: [], destination: { revision_id: ids.revision2, path: "manuscript/revisions/revision.md", operation: "insert", position: 0 }, stale_context_resolution: "revalidated", decided_at: laterTimestamp, event_id: ids.event2 }; +add("disposition-revision", "Invocation disposition revision", closed({ schema_version: schemaVersion, disposition_id: identifier("disposition"), invocation_id: identifier("invocation"), revision_number: { type: "integer", minimum: 1 }, status: { enum: ["staged", "accepted", "partially_accepted", "rejected", "discarded"] }, accepted_ranges: arrayOf(ref("text-fragment-reference")), rejected_ranges: arrayOf(ref("text-fragment-reference")), destination: nullable(closed({ revision_id: identifier("revision"), path: repositoryPath, operation: { enum: ["insert", "replace", "append", "new_section"] }, position: nullable({ type: "integer", minimum: 0 }) })), stale_context_resolution: { enum: ["not_stale", "revalidated", "rebased", "explicitly_confirmed", "rejected"] }, decided_at: timestamp, event_id: identifier("event") }), dispositionExample, "Immutable ordered record of user action on one model result."); + +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 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 }; +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" }; +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 }; +add("sanitized-export-manifest", "Sanitized export manifest", closed({ schema_version: schemaVersion, export_id: identifier("record"), project_id: identifier("project"), source_chain_head: sha, profile: { const: "sanitized" }, omission_rules: arrayOf(closed({ category: { enum: ["private_conversation", "rejected_output", "provider_detail", "personal_identifier", "internal_path", "source_body", "other"] }, action: { enum: ["exclude", "redact", "summarize"] }, count: { type: "integer", minimum: 0 } })), rules_sha256: sha, files: arrayOf(fileEntry, { minItems: 1 }), created_at: timestamp }), sanitizedExample, "Disclosure and file inventory for a non-mutating sanitized evidence export."); + +const purgeExample = { schema_version: "1.0", purge_id: ids.purge, project_id: ids.project, requested_at: timestampValue, completed_at: laterTimestamp, reason: "Remove accidentally retained credential", superseded_chain_head: digest("4"), new_chain_root: digest("5"), affected_record_ids: [ids.record], affected_paths: ["records/invocations/request.json"], git_history_rewritten: true, prior_copies_revocable: false, confirmation_phrase_sha256: digest("6") }; +add("purge-manifest", "Emergency purge manifest", closed({ schema_version: schemaVersion, purge_id: identifier("purge"), project_id: identifier("project"), requested_at: timestamp, completed_at: timestamp, reason: nonEmptyString, superseded_chain_head: sha, new_chain_root: sha, affected_record_ids: arrayOf(identifier("record"), { minItems: 1, uniqueItems: true }), affected_paths: arrayOf(repositoryPath, { uniqueItems: true }), git_history_rewritten: { const: true }, prior_copies_revocable: { const: false }, confirmation_phrase_sha256: sha }), purgeExample, "Explicit disclosure of a destructive provenance and Git reconstitution."); +const schemaNames = [...schemas.keys()].sort(); + +function clone(value) { + return structuredClone(value); +} + +function valueAt(instance, valuePath) { + return valuePath.reduce((value, segment) => value?.[segment], instance); +} + +function invalidPatternValue(pattern) { + if (pattern.includes("sha256")) return "sha256:INVALID"; + if (pattern.includes("\\d{4}")) return "not-a-timestamp"; + if (pattern.includes("A-HJKMNP")) return "invalid-id"; + if (pattern.includes("A-Za-z]:")) return "../outside-project"; + return " invalid!"; +} + +function resolvedNode(node) { + if (!node?.$ref) return node; + const match = /\/([^/]+)\.schema\.json$/.exec(node.$ref); + return match ? schemas.get(match[1]) ?? node : node; +} + +function invalidCases(name, schema, example) { + const cases = []; + const labels = new Set(); + const push = (description, mutation) => { + if (labels.has(description)) return; + const instance = clone(example); + mutation(instance); + labels.add(description); + cases.push({ description, instance }); + }; + + const walk = (rawNode, instancePath, labelPath, seenRefs = new Set()) => { + let node = rawNode; + if (node?.$ref) { + if (seenRefs.has(node.$ref)) return; + seenRefs = new Set(seenRefs).add(node.$ref); + node = resolvedNode(node); + } + const sample = valueAt(example, instancePath); + if (!node || sample === undefined) return; + + if (Array.isArray(node.anyOf)) { + const candidate = node.anyOf.find((entry) => sample === null ? entry.type === "null" : entry.type !== "null"); + if (candidate) walk(candidate, instancePath, labelPath, seenRefs); + return; + } + + if (Array.isArray(node.enum) && node.enum.length) { + push(`${labelPath}: reject value outside enum`, (instance) => { + const parent = valueAt(instance, instancePath.slice(0, -1)); + parent[instancePath.at(-1)] = "__INVALID_ENUM__"; + }); + } + if (Object.hasOwn(node, "const")) { + push(`${labelPath}: reject value different from const`, (instance) => { + const parent = valueAt(instance, instancePath.slice(0, -1)); + parent[instancePath.at(-1)] = typeof node.const === "boolean" ? !node.const : "__INVALID_CONST__"; + }); + } + if (node.pattern && typeof sample === "string") { + push(`${labelPath}: reject pattern mismatch`, (instance) => { + const parent = valueAt(instance, instancePath.slice(0, -1)); + parent[instancePath.at(-1)] = invalidPatternValue(node.pattern); + }); + } + if (Number.isFinite(node.minimum) && typeof sample === "number") { + push(`${labelPath}: reject value below minimum`, (instance) => { + const parent = valueAt(instance, instancePath.slice(0, -1)); + parent[instancePath.at(-1)] = node.minimum - 1; + }); + } + if (Number.isFinite(node.maximum) && typeof sample === "number") { + push(`${labelPath}: reject value above maximum`, (instance) => { + const parent = valueAt(instance, instancePath.slice(0, -1)); + parent[instancePath.at(-1)] = node.maximum + 1; + }); + } + if (Number.isFinite(node.minLength) && node.minLength > 0 && typeof sample === "string") { + push(`${labelPath}: reject string below minLength`, (instance) => { + const parent = valueAt(instance, instancePath.slice(0, -1)); + parent[instancePath.at(-1)] = ""; + }); + } + if (Number.isFinite(node.maxLength) && typeof sample === "string") { + push(`${labelPath}: reject string above maxLength`, (instance) => { + const parent = valueAt(instance, instancePath.slice(0, -1)); + parent[instancePath.at(-1)] = "x".repeat(node.maxLength + 1); + }); + } + if (Number.isFinite(node.minItems) && node.minItems > 0 && Array.isArray(sample)) { + push(`${labelPath}: reject array below minItems`, (instance) => { + const parent = valueAt(instance, instancePath.slice(0, -1)); + parent[instancePath.at(-1)] = []; + }); + } + + if (node.type === "object" && sample && typeof sample === "object" && !Array.isArray(sample)) { + for (const requiredName of node.required ?? []) { + if (!Object.hasOwn(sample, requiredName)) continue; + push(`${labelPath}.${requiredName}: reject missing required property`, (instance) => { + delete valueAt(instance, instancePath)[requiredName]; + }); + } + if (node.additionalProperties === false) { + push(`${labelPath}: reject unexpected property`, (instance) => { + valueAt(instance, instancePath).__unexpected = true; + }); + } + for (const [propertyName, propertySchema] of Object.entries(node.properties ?? {})) { + if (Object.hasOwn(sample, propertyName)) walk(propertySchema, [...instancePath, propertyName], `${labelPath}.${propertyName}`, seenRefs); + } + } + + if (node.type === "array" && Array.isArray(sample) && sample.length && node.items) { + walk(node.items, [...instancePath, 0], `${labelPath}[0]`, seenRefs); + } + }; + + walk(schema, [], name); + if (name === "record-envelope") { + push("record-envelope: protected payload must not remain plaintext", (instance) => { + instance.payload = { leaked: true }; + }); + push("record-envelope: unprotected payload requires null encryption", (instance) => { + instance.protection = "none"; + instance.payload = { retained: true }; + }); + } + if (name === "recovery-key-envelope") { + push("recovery-key-envelope: recovery derivation is mandatory", (instance) => { + instance.key_derivation = null; + }); + } + if (!cases.length) throw new Error(`No invalid fixture cases generated for ${name}.`); + return cases; +} + +async function writeJson(filePath, value) { + await writeFile(filePath, `${JSON.stringify(value, null, 2)}\n`, "utf8"); +} + +await rm(output, { recursive: true, force: true }); +await Promise.all([validDir, invalidDir, vectorDir].map((directory) => mkdir(directory, { recursive: true }))); + +for (const name of schemaNames) { + const schema = schemas.get(name); + await writeJson(path.join(output, `${name}.schema.json`), schema); + await writeJson(path.join(validDir, `${name}.valid.json`), { + schema: schema.$id, + description: `Valid ${schema.title} example.`, + instance: schema.examples[0], + }); + await writeJson(path.join(invalidDir, `${name}.invalid.json`), { + schema: schema.$id, + cases: invalidCases(name, schema, schema.examples[0]), + }); +} + +const catalog = { + catalog_version: "1.0", + dialect: draft, + provenance_schema_version: "1.0", + application_version: "0.3.0", + compatible_application_versions: ["0.3.0"], + native_writer_conformance: false, + normative_specification: "../../../docs/provenance/STAGE-1-NORMATIVE-SPECIFICATION.md", + generated_by: "scripts/generate-provenance-stage2.mjs", + schemas: schemaNames.map((name) => ({ + name, + id: schemas.get(name).$id, + file: `${name}.schema.json`, + valid_fixture: `fixtures/valid/${name}.valid.json`, + invalid_fixture: `fixtures/invalid/${name}.invalid.json`, + })), +}; +await writeJson(path.join(output, "catalog.json"), catalog); + +const canonicalInputs = [ + { id: "rfc8785-key-order", input: { z: 1, a: 2, nested: { beta: true, alpha: false } } }, + { id: "thinkloom-nfc", input: { text: "Cafe\u0301", "e\u0301": "normalize keys and values" } }, + { id: "rfc8785-numbers", input: { numbers: [333333333.3333333, 1e30, 4.5, 0.002, 1e-27] } }, + { id: "thinkloom-timestamp-and-path", input: { timestamp: timestampValue, path: "records/invocations/request.json" } }, +]; +const canonicalizationVector = { + vector_version: "1.0", + algorithm: "Unicode NFC followed by RFC 8785 JSON Canonicalization Scheme and SHA-256 over UTF-8 bytes", + cases: canonicalInputs.map(({ id, input }) => { + const canonical_json = canonicalize(input); + return { id, input, canonical_json, utf8_sha256: sha256(canonical_json) }; + }), + rejected_inputs: [ + { id: "non-finite-number", description: "NaN and infinity are not JSON and MUST be rejected before canonicalization." }, + { id: "undefined-value", description: "Undefined values MUST be rejected rather than silently omitted." }, + { id: "nfc-key-collision", description: "Distinct source keys that normalize to the same NFC key MUST be rejected." }, + { id: "unpaired-surrogate", description: "I-JSON prohibits unpaired Unicode surrogate code units." }, + { id: "non-json-runtime-types", description: "BigInt, symbols, functions, sparse arrays, and non-plain objects MUST be rejected." }, + ], +}; +await writeJson(path.join(vectorDir, "canonicalization.json"), canonicalizationVector); + +const baseEvents = [ + { ...eventExample, event_id: ids.event, event_sequence: 1, event_type: "PROJECT_CREATED", previous_event_hash: null, event_hash: "" }, + { ...eventExample, event_id: ids.event2, event_sequence: 2, event_type: "IDEA_ACCEPTED", previous_event_hash: "", event_hash: "", timestamp: laterTimestamp }, + { ...eventExample, event_id: typedId("event", "T"), event_sequence: 3, event_type: "MANUSCRIPT_EDITED", previous_event_hash: "", event_hash: "", timestamp: "2026-07-17T18:44:12.789Z" }, +]; +for (let index = 0; index < baseEvents.length; index += 1) { + baseEvents[index].previous_event_hash = index ? baseEvents[index - 1].event_hash : null; + baseEvents[index].event_hash = hashEvent(baseEvents[index]); +} +const canonicalEventLines = baseEvents.map((event) => canonicalize(event)); +await writeJson(path.join(vectorDir, "event-chain.json"), { + vector_version: "1.0", + event_hash_identity: "Canonical event object excluding only event_hash; previous_event_hash remains included.", + sequence_rule: "Committed event_sequence values begin at 1 and are contiguous with no reuse.", + jsonl_rule: "Each canonical event is UTF-8 without BOM followed by exactly one LF byte (0x0A).", + events: baseEvents, + canonical_jsonl: `${canonicalEventLines.join("\n")}\n`, + canonical_jsonl_sha256: sha256(`${canonicalEventLines.join("\n")}\n`), + rejected_boundary_variants: ["CRLF line endings", "missing final LF", "blank records", "UTF-8 BOM"], +}); + +const protectedPlaintextIdentity = { + schema_version: "1.0", + record_id: ids.record, + record_type: "invocation_request", + payload: { purpose: "draft_from_selected_ideas" }, +}; +await writeJson(path.join(vectorDir, "protected-record-and-key-rotation.json"), { + vector_version: "1.0", + plaintext_identity_fields: ["schema_version", "record_id", "record_type", "payload"], + plaintext_identity: protectedPlaintextIdentity, + canonical_plaintext_identity: canonicalize(protectedPlaintextIdentity), + plaintext_sha256: sha256(protectedPlaintextIdentity), + device_key_envelope: keyEnvelopeExample, + recovery_key_envelope: recoveryEnvelopeExample, + project_key_manifest: keyManifestExample, + initial_envelope: recordEnvelopeExample, + rotated_envelope: { + ...recordEnvelopeExample, + encryption: { ...recordEnvelopeExample.encryption, key_id: typedId("key", "V"), nonce: "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB", ciphertext: "cm90YXRlZC1jaXBoZXJ0ZXh0", ciphertext_sha256: digest("c") }, + }, + invariant: "Key rotation changes encryption metadata and ciphertext but preserves record_id and plaintext_sha256.", + excluded_from_plaintext_identity: ["project_id", "protection", "plaintext_sha256", "encryption", "path", "nonce", "ciphertext"], +}); + +await writeJson(path.join(vectorDir, "release-merkle.json"), { + vector_version: "1.0", + algorithm_id: "thinkloom-release-merkle-v1", + ordering: "Sort entries by raw UTF-8 path bytes in ascending order.", + leaf: "SHA-256(UTF8('thinkloom-release-leaf-v1\\0') || UTF8(path) || 0x00 || UTF8(decimal size) || 0x00 || raw 32-byte file SHA-256 digest)", + node: "SHA-256(UTF8('thinkloom-release-node-v1\\0') || raw left digest || raw right digest); duplicate the final node when a level has odd cardinality.", + empty: "SHA-256(UTF8('thinkloom-release-empty-v1\\0'))", + entries: releaseFiles, + root: releaseMerkleRoot(releaseFiles), + excluded_paths: ["release-manifest.json", "release-files.sha256"], + self_reference_rule: "The manifest and any flat digest file that contains the root MUST NOT be Merkle leaves.", +}); + +const minimalRequest = { + ...requestExample, + retention_mode: "minimal", + messages: [], + redactions: [], +}; +const minimalResponse = { + ...responseExample, + retention_mode: "minimal", + retained_text: null, + provider_metadata: null, +}; +await writeJson(path.join(vectorDir, "retention-policy-modes.json"), { + vector_version: "1.0", + default_mode: "minimal", + minimal: { + policy: policyExample, + invocation_request: minimalRequest, + invocation_response: minimalResponse, + prohibited_durable_fields: ["complete provider-facing prompt", "complete supplied context", "unaccepted raw response", "provider transport metadata", "audio bytes or references"], + }, + full_private: { + policy: { ...policyExample, retention_mode: "full_private", encryption_mode: "protected" }, + invocation_request: requestExample, + invocation_response: responseExample, + requirements: ["protected records", "verified recovery envelope", "authorized verification for plaintext evidence"], + }, + policy_change_rule: "Changes are prospective. Reducing retention does not delete prior records; deletion requires emergency purge.", +}); + +await writeJson(path.join(vectorDir, "timestamp-and-path.json"), { + vector_version: "1.0", + timestamps: { + accepted: [timestampValue, laterTimestamp, "2000-01-01T00:00:00.000Z"], + rejected: ["2026-07-17T18:42:10Z", "2026-07-17T18:42:10.12Z", "2026-07-17T18:42:10.1234Z", "2026-07-17T11:42:10.123-07:00", "not-a-timestamp"], + }, + repository_paths: { + accepted: ["project.json", "records/invocations/request.json", "manuscript/Café.md"], + rejected: ["", "/absolute/path", "C:/absolute/path", "records\\request.json", ".", "..", "records/../outside.json", "records/./alias.json"], + }, + normalization_rule: "Paths use NFC, forward slashes, repository-relative spelling, and no dot segments.", +}); + +const segmentOneJsonl = `${canonicalEventLines.slice(0, 2).join("\n")}\n`; +const segmentTwoJsonl = `${canonicalEventLines.slice(2).join("\n")}\n`; +const segmentOneHash = sha256(segmentOneJsonl); +const segmentTwoHash = sha256(segmentTwoJsonl); +const segmentOneManifest = { + ...segmentExample, + previous_segment_file_hash: null, + first_event_hash: baseEvents[0].event_hash, + final_event_hash: baseEvents[1].event_hash, + first_event_sequence: 1, + final_event_sequence: 2, + event_count: 2, + byte_length: Buffer.byteLength(segmentOneJsonl), + segment_file_hash: segmentOneHash, +}; +const segmentTwoManifest = { + ...segmentExample, + segment_number: 2, + previous_segment_file_hash: segmentOneHash, + first_event_hash: baseEvents[2].event_hash, + final_event_hash: baseEvents[2].event_hash, + first_event_sequence: 3, + final_event_sequence: 3, + event_count: 1, + byte_length: Buffer.byteLength(segmentTwoJsonl), + segment_file_hash: segmentTwoHash, + sealed_at: "2026-07-17T18:45:13.012Z", +}; +await writeJson(path.join(vectorDir, "cross-segment-chain.json"), { + vector_version: "1.0", + segments: [ + { jsonl: segmentOneJsonl, manifest: segmentOneManifest }, + { jsonl: segmentTwoJsonl, manifest: segmentTwoManifest }, + ], + chain_head: { + ...chainHeadExample, + active_segment_number: 2, + event_id: baseEvents[2].event_id, + event_sequence: 3, + event_hash: baseEvents[2].event_hash, + updated_at: segmentTwoManifest.sealed_at, + }, + cross_segment_rule: "A sealed segment names the prior segment file digest, and event hash linkage remains contiguous across the boundary.", +}); + +const promptIdentity = { ...promptExample }; +delete promptIdentity.template_sha256; +const promptWithDigest = { ...promptIdentity, template_sha256: sha256(promptIdentity) }; +await writeJson(path.join(vectorDir, "self-digest-identities.json"), { + vector_version: "1.0", + prompt_template: { + identity: promptIdentity, + digest: promptWithDigest.template_sha256, + complete_record: promptWithDigest, + excluded_fields: ["template_sha256"], + }, + provenance_event: { + identity: { ...baseEvents[0], event_hash: undefined }, + digest: baseEvents[0].event_hash, + excluded_fields: ["event_hash"], + }, + protected_record: { + identity: protectedPlaintextIdentity, + digest: sha256(protectedPlaintextIdentity), + excluded_fields: ["project_id", "protection", "plaintext_sha256", "encryption", "path", "nonce", "ciphertext"], + }, + release_manifest: { + merkle_identity: releaseFiles, + digest: releaseMerkleRoot(releaseFiles), + excluded_paths: ["release-manifest.json", "release-files.sha256"], + }, +}); + +const sanitizationRules = [ + { category: "private_conversation", action: "exclude", count: 2 }, + { category: "personal_identifier", action: "redact", count: 1 }, + { category: "provider_detail", action: "summarize", count: 1 }, +]; +const sanitizedManifestVector = { + ...sanitizedExample, + omission_rules: sanitizationRules, + rules_sha256: sha256(sanitizationRules), +}; +await writeJson(path.join(vectorDir, "sanitized-export.json"), { + vector_version: "1.0", + source_chain_head_before: sanitizedManifestVector.source_chain_head, + source_chain_head_after: sanitizedManifestVector.source_chain_head, + source_record_count: 7, + exported_record_count: 3, + manifest: sanitizedManifestVector, + non_mutation_rule: "Sanitization creates a disclosure-bearing export and never rewrites the project or source chain.", +}); + +const derivedInputsA = [ + { from: ids.idea, to: ids.revision2, relation: "influenced" }, + { from: ids.turn, to: ids.idea, relation: "suggested" }, +]; +const derivedInputsB = [...derivedInputsA].reverse(); +const deterministicIndexContent = [...derivedInputsA].sort((left, right) => { const leftKey = canonicalize(left); const rightKey = canonicalize(right); return leftKey < rightKey ? -1 : leftKey > rightKey ? 1 : 0; }); +const derivedConfiguration = { sort: "canonical-json-code-unit", graph_version: 1 }; +const derivedManifestVector = { + ...indexManifestExample, + source_chain_head: baseEvents.at(-1).event_hash, + source_event_count: baseEvents.length, + generator: { ...indexManifestExample.generator, configuration_sha256: sha256(derivedConfiguration) }, + content_sha256: sha256(deterministicIndexContent), +}; +await writeJson(path.join(vectorDir, "deterministic-derived-index.json"), { + vector_version: "1.0", + input_orders: [derivedInputsA, derivedInputsB], + deterministic_content: deterministicIndexContent, + configuration: derivedConfiguration, + manifest: derivedManifestVector, + determinism_rule: "Input order does not affect canonical derived content; volatile generation metadata is outside content_sha256.", +}); + +const verificationReports = [ + { ...verificationExample, verification_id: typedId("record", "W"), status: "VERIFIED", findings: [] }, + { ...verificationExample, verification_id: typedId("record", "X"), status: "VERIFIED_WITH_WARNINGS", findings: [{ ...verificationExample.findings[0], severity: "WARNING" }] }, + { ...verificationExample, verification_id: typedId("record", "Y"), status: "INCOMPLETE", findings: [{ ...verificationExample.findings[0], severity: "INFO", code: "OPTIONAL_BINARY_MISSING", message: "An optional release binary is unavailable." }] }, + { ...verificationExample, verification_id: typedId("record", "Z"), status: "FAILED", findings: [{ ...verificationExample.findings[0], severity: "ERROR", code: "EVENT_HASH_MISMATCH", message: "An event digest does not match canonical content.", authoritative_evidence_affected: true }] }, + { ...verificationExample, verification_id: typedId("record", "0"), status: "UNSAFE", findings: [{ ...verificationExample.findings[0], severity: "CRITICAL", code: "CHAIN_RECONSTITUTED", message: "The chain cannot establish ordinary continuity.", authoritative_evidence_affected: true }] }, +]; +await writeJson(path.join(vectorDir, "verification-statuses.json"), { + vector_version: "1.0", + reports: verificationReports, + required_statuses: ["VERIFIED", "VERIFIED_WITH_WARNINGS", "INCOMPLETE", "FAILED", "UNSAFE"], + required_severities: ["INFO", "WARNING", "ERROR", "CRITICAL"], +}); + +await writeJson(path.join(vectorDir, "backup-and-release-manifests.json"), { + vector_version: "1.0", + backup_manifest: { ...backupExample, source_chain_head: baseEvents.at(-1).event_hash }, + 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`; +await writeFile(path.join(output, "README.md"), readme, "utf8"); + +console.log(`Generated ${schemaNames.length} provenance schemas and fixtures in ${path.relative(root, output)}.`); \ No newline at end of file diff --git a/scripts/provenance-stage2-lib.mjs b/scripts/provenance-stage2-lib.mjs new file mode 100644 index 0000000..5f4ba29 --- /dev/null +++ b/scripts/provenance-stage2-lib.mjs @@ -0,0 +1,108 @@ +import { createHash } from "node:crypto"; + +function normalizedString(value) { + for (let index = 0; index < value.length; index += 1) { + const code = value.charCodeAt(index); + if (code >= 0xd800 && code <= 0xdbff) { + const next = value.charCodeAt(index + 1); + if (!(next >= 0xdc00 && next <= 0xdfff)) throw new TypeError("Canonical JSON prohibits unpaired Unicode surrogates."); + index += 1; + } else if (code >= 0xdc00 && code <= 0xdfff) { + throw new TypeError("Canonical JSON prohibits unpaired Unicode surrogates."); + } + } + return value.normalize("NFC"); +} + +function normalize(value) { + if (typeof value === "string") return normalizedString(value); + if (typeof value === "number") { + if (!Number.isFinite(value)) throw new TypeError("Canonical JSON prohibits non-finite numbers."); + return value; + } + if (value === null || typeof value === "boolean") return value; + if (["undefined", "bigint", "symbol", "function"].includes(typeof value)) { + throw new TypeError(`Canonical JSON prohibits ${typeof value} values.`); + } + if (Array.isArray(value)) { + const enumerableKeys = Object.keys(value); + if (enumerableKeys.length !== value.length || enumerableKeys.some((key, index) => key !== String(index))) { + throw new TypeError("Canonical JSON prohibits sparse arrays and non-index array properties."); + } + return value.map(normalize); + } + if (value && typeof value === "object") { + const prototype = Object.getPrototypeOf(value); + if (prototype !== Object.prototype && prototype !== null) throw new TypeError("Canonical JSON accepts only plain objects."); + if (Reflect.ownKeys(value).length !== Object.keys(value).length) throw new TypeError("Canonical JSON prohibits symbol and non-enumerable object keys."); + const normalized = Object.create(null); + for (const [key, item] of Object.entries(value)) { + const normalizedKey = normalizedString(key); + if (Object.prototype.hasOwnProperty.call(normalized, normalizedKey)) { + throw new TypeError(`Canonical JSON key collision after NFC normalization: ${normalizedKey}`); + } + normalized[normalizedKey] = normalize(item); + } + return normalized; + } + throw new TypeError(`Canonical JSON prohibits ${typeof value} values.`); +} + +function serialize(value) { + if (value === null || typeof value === "boolean" || typeof value === "number" || typeof value === "string") return JSON.stringify(value); + if (Array.isArray(value)) return `[${value.map(serialize).join(",")}]`; + const keys = Object.keys(value).sort(); + return `{${keys.map((key) => `${JSON.stringify(key)}:${serialize(value[key])}`).join(",")}}`; +} + +export function canonicalize(value) { + return serialize(normalize(value)); +} + +export function sha256Bytes(value) { + return createHash("sha256").update(value).digest(); +} + +export function sha256(value) { + const input = typeof value === "string" || Buffer.isBuffer(value) ? value : canonicalize(value); + return `sha256:${sha256Bytes(input).toString("hex")}`; +} + +export function eventIdentity(event) { + const identity = { ...event }; + delete identity.event_hash; + return identity; +} + +export function hashEvent(event) { + return sha256(eventIdentity(event)); +} + +function digestBytes(value) { + const match = /^sha256:([a-f0-9]{64})$/.exec(value); + if (!match) throw new TypeError(`Invalid SHA-256 digest: ${value}`); + return Buffer.from(match[1], "hex"); +} + +function releaseLeaf(entry) { + const domain = Buffer.from("thinkloom-release-leaf-v1\0", "utf8"); + const fields = Buffer.from(`${entry.path}\0${entry.size}\0`, "utf8"); + return sha256Bytes(Buffer.concat([domain, fields, digestBytes(entry.sha256)])); +} + +export function releaseMerkleRoot(entries) { + const ordered = [...entries].sort((left, right) => Buffer.from(left.path, "utf8").compare(Buffer.from(right.path, "utf8"))); + if (!ordered.length) return `sha256:${sha256Bytes("thinkloom-release-empty-v1\0").toString("hex")}`; + let level = ordered.map(releaseLeaf); + const domain = Buffer.from("thinkloom-release-node-v1\0", "utf8"); + while (level.length > 1) { + const next = []; + for (let index = 0; index < level.length; index += 2) { + const left = level[index]; + const right = level[index + 1] ?? left; + next.push(sha256Bytes(Buffer.concat([domain, left, right]))); + } + level = next; + } + return `sha256:${level[0].toString("hex")}`; +} diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 8ba75ca..273c86c 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -3980,7 +3980,7 @@ dependencies = [ [[package]] name = "thinkloom" -version = "0.2.0" +version = "0.3.0" dependencies = [ "chrono", "hex", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 09598cb..dfb5286 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "thinkloom" -version = "0.2.0" +version = "0.3.0" description = "Local-first writing studio with creative provenance" authors = ["Christopher Chambers"] license = "AGPL-3.0-only" diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index c0e529e..c0149a1 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "Thinkloom", - "version": "0.2.0", + "version": "0.3.0", "identifier": "com.thinkloom.desktop", "build": { "beforeDevCommand": "npm run dev", diff --git a/src/Thinkloom.tsx b/src/Thinkloom.tsx index b6b5640..615a13e 100644 --- a/src/Thinkloom.tsx +++ b/src/Thinkloom.tsx @@ -220,6 +220,6 @@ export default function Thinkloom() {
04

Prompt configuration

Technical users can tune every instruction sent to the model.

conversation.json affects Ideation replies. drafting.json affects passage and editorial previews. Files reload before every model request, so no restart is needed.

{promptPath || "Preparing prompt files…"}
README.md in this folder documents every field, variable, effect, validation rule, and reset procedure.
} - + ; } diff --git a/tests/native-app.test.mjs b/tests/native-app.test.mjs index 38263e1..207f2f7 100644 --- a/tests/native-app.test.mjs +++ b/tests/native-app.test.mjs @@ -95,13 +95,14 @@ test("never ships retained audio assets", async () => { }); test("externalizes and documents every model prompt", async () => { - const [conversationRaw, draftingRaw, source, rust, guide, packageRaw, tauriRaw, cargoRaw] = await Promise.all([ + const [conversationRaw, draftingRaw, source, rust, guide, packageRaw, packageLockRaw, tauriRaw, cargoRaw] = await Promise.all([ readFile(new URL("../src-tauri/prompts/conversation.json", import.meta.url), "utf8"), readFile(new URL("../src-tauri/prompts/drafting.json", import.meta.url), "utf8"), readFile(new URL("../src/Thinkloom.tsx", import.meta.url), "utf8"), readFile(new URL("../src-tauri/src/lib.rs", import.meta.url), "utf8"), readFile(new URL("../PROMPTS.md", import.meta.url), "utf8"), readFile(new URL("../package.json", import.meta.url), "utf8"), + readFile(new URL("../package-lock.json", import.meta.url), "utf8"), readFile(new URL("../src-tauri/tauri.conf.json", import.meta.url), "utf8"), readFile(new URL("../src-tauri/Cargo.toml", import.meta.url), "utf8"), ]); @@ -132,7 +133,10 @@ test("externalizes and documents every model prompt", async () => { } const version = JSON.parse(packageRaw).version; - assert.equal(version, "0.2.0"); + assert.equal(version, "0.3.0"); + const packageLock = JSON.parse(packageLockRaw); + assert.equal(packageLock.version, version); + assert.equal(packageLock.packages[""].version, version); assert.equal(JSON.parse(tauriRaw).version, version); const escapedVersion = version.replaceAll(".", "\\."); assert.match(cargoRaw, new RegExp("^version = \"" + escapedVersion + "\"$", "m")); diff --git a/tests/provenance-schema.test.mjs b/tests/provenance-schema.test.mjs new file mode 100644 index 0000000..d0e1c0e --- /dev/null +++ b/tests/provenance-schema.test.mjs @@ -0,0 +1,242 @@ +import assert from "node:assert/strict"; +import { readFile } from "node:fs/promises"; +import path from "node:path"; +import test from "node:test"; +import { fileURLToPath } from "node:url"; +import Ajv2020 from "ajv/dist/2020.js"; +import addFormats from "ajv-formats"; +import { canonicalize, hashEvent, releaseMerkleRoot, sha256 } from "../scripts/provenance-stage2-lib.mjs"; + +const repositoryRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); +const schemaRoot = path.join(repositoryRoot, "schemas", "provenance", "v1"); +const readJson = async (...segments) => JSON.parse(await readFile(path.join(schemaRoot, ...segments), "utf8")); +const catalog = await readJson("catalog.json"); +const schemaEntries = await Promise.all(catalog.schemas.map(async (entry) => ({ ...entry, schema: await readJson(entry.file) }))); + +function validator() { + const ajv = new Ajv2020({ allErrors: true, strict: true, validateFormats: true }); + addFormats(ajv); + for (const entry of schemaEntries) { + assert.equal(ajv.validateSchema(entry.schema), true, `${entry.name} is not a valid Draft 2020-12 schema: ${ajv.errorsText(ajv.errors)}`); + ajv.addSchema(entry.schema); + } + return ajv; +} + +const requiredSchemas = [ + "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", + "recovery-key-envelope", "release-manifest", "release-state", "sanitized-export-manifest", "text-fragment-reference", + "transcript-correction", "transcript-normalization", "transcript-turn", "verification-report", "write-intent", +]; + +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.native_writer_conformance, false); + assert.equal(catalog.dialect, "https://json-schema.org/draft/2020-12/schema"); + assert.deepEqual(catalog.schemas.map(({ name }) => name), requiredSchemas); + assert.equal(new Set(catalog.schemas.map(({ id }) => id)).size, requiredSchemas.length); + for (const { schema } of schemaEntries) { + assert.equal(schema.additionalProperties, false, `${schema.$id} must be closed at its top level`); + } +}); + +test("accepts every valid fixture", async () => { + const ajv = validator(); + for (const entry of schemaEntries) { + const fixture = await readJson(entry.valid_fixture); + const validate = ajv.getSchema(entry.id); + assert.equal(validate(fixture.instance), true, `${entry.name}: ${ajv.errorsText(validate.errors)}`); + } +}); + +test("rejects every invalid fixture case", async () => { + const ajv = validator(); + for (const entry of schemaEntries) { + const fixture = await readJson(entry.invalid_fixture); + assert.ok(fixture.cases.length >= 2, `${entry.name} needs multiple invalid cases`); + for (const requiredProperty of entry.schema.required ?? []) { + assert.ok(fixture.cases.some(({ description }) => description === `${entry.name}.${requiredProperty}: reject missing required property`), `${entry.name} lacks a missing-${requiredProperty} fixture`); + } + assert.ok(fixture.cases.some(({ description }) => description === `${entry.name}: reject unexpected property`), `${entry.name} lacks an additional-property fixture`); + const validate = ajv.getSchema(entry.id); + for (const invalidCase of fixture.cases) { + assert.equal(validate(invalidCase.instance), false, `${entry.name} unexpectedly accepted: ${invalidCase.description}`); + } + } +}); + +test("reproduces canonical JSON and rejects prohibited values", async () => { + const vectors = await readJson("vectors", "canonicalization.json"); + for (const vector of vectors.cases) { + assert.equal(canonicalize(vector.input), vector.canonical_json, vector.id); + assert.equal(sha256(vector.canonical_json), vector.utf8_sha256, vector.id); + } + assert.throws(() => canonicalize({ value: Number.NaN }), /non-finite/); + assert.throws(() => canonicalize({ value: undefined }), /undefined/); + assert.throws(() => canonicalize({ "é": 1, "e\u0301": 2 }), /key collision/); + assert.throws(() => canonicalize({ value: 1n }), /bigint/); + const sparse = []; + sparse.length = 2; + sparse[1] = "value"; + assert.throws(() => canonicalize(sparse), /sparse arrays/); + assert.throws(() => canonicalize(new Date()), /plain objects/); + assert.throws(() => canonicalize({ value: "\ud800" }), /unpaired Unicode surrogate/); + assert.equal(canonicalize(JSON.parse('{"__proto__":{"safe":true}}')), '{"__proto__":{"safe":true}}'); +}); + +test("reproduces contiguous event hashes and canonical LF-only JSONL", async () => { + const vector = await readJson("vectors", "event-chain.json"); + for (const [index, event] of vector.events.entries()) { + assert.equal(event.event_sequence, index + 1); + assert.equal(event.previous_event_hash, index ? vector.events[index - 1].event_hash : null); + assert.equal(hashEvent(event), event.event_hash); + } + assert.equal(vector.canonical_jsonl, `${vector.events.map(canonicalize).join("\n")}\n`); + assert.equal(sha256(vector.canonical_jsonl), vector.canonical_jsonl_sha256); + assert.equal(vector.canonical_jsonl.includes("\r"), false); + assert.equal(vector.canonical_jsonl.charCodeAt(0) === 0xfeff, false); +}); + +test("preserves protected-record identity across key rotation", async () => { + const vector = await readJson("vectors", "protected-record-and-key-rotation.json"); + assert.equal(canonicalize(vector.plaintext_identity), vector.canonical_plaintext_identity); + assert.equal(sha256(vector.plaintext_identity), vector.plaintext_sha256); + assert.equal(vector.initial_envelope.record_id, vector.rotated_envelope.record_id); + assert.equal(vector.initial_envelope.plaintext_sha256, vector.rotated_envelope.plaintext_sha256); + assert.notEqual(vector.initial_envelope.encryption.key_id, vector.rotated_envelope.encryption.key_id); + assert.notEqual(vector.initial_envelope.encryption.ciphertext_sha256, vector.rotated_envelope.encryption.ciphertext_sha256); +}); + +test("reproduces the release-files Merkle root without self-reference", async () => { + const vector = await readJson("vectors", "release-merkle.json"); + assert.equal(vector.algorithm_id, "thinkloom-release-merkle-v1"); + assert.equal(releaseMerkleRoot(vector.entries), vector.root); + assert.equal(vector.entries.some(({ path: entryPath }) => vector.excluded_paths.includes(entryPath)), false); + assert.match(vector.self_reference_rule, /MUST NOT/); +}); + +test("validates both retention policy vectors and keeps minimal as default", async () => { + const ajv = validator(); + const vector = await readJson("vectors", "retention-policy-modes.json"); + assert.equal(vector.default_mode, "minimal"); + for (const mode of [vector.minimal, vector.full_private]) { + for (const [schemaName, field] of [["provenance-policy", "policy"], ["invocation-request", "invocation_request"], ["invocation-response", "invocation_response"]]) { + const validate = ajv.getSchema(`https://thinkloom.app/schemas/provenance/1.0/${schemaName}.schema.json`); + assert.equal(validate(mode[field]), true, `${schemaName}: ${ajv.errorsText(validate.errors)}`); + } + } + assert.deepEqual(vector.minimal.invocation_request.messages, []); + assert.equal(vector.minimal.invocation_response.provider_metadata, null); + assert.equal(vector.full_private.policy.encryption_mode, "protected"); + assert.ok(vector.full_private.invocation_request.messages.length > 0); +}); +test("enforces canonical timestamps and repository-relative paths", async () => { + const ajv = validator(); + const vector = await readJson("vectors", "timestamp-and-path.json"); + const timestampSchema = schemaEntries.find(({ name }) => name === "project-manifest").schema.properties.created_at; + const pathSchema = schemaEntries.find(({ name }) => name === "prompt-template-reference").schema.properties.path; + const validateTimestamp = ajv.compile(timestampSchema); + const validatePath = ajv.compile(pathSchema); + for (const value of vector.timestamps.accepted) assert.equal(validateTimestamp(value), true, value); + for (const value of vector.timestamps.rejected) assert.equal(validateTimestamp(value), false, value); + for (const value of vector.repository_paths.accepted) assert.equal(validatePath(value), true, value); + for (const value of vector.repository_paths.rejected) assert.equal(validatePath(value), false, value); + assert.equal(vector.repository_paths.accepted.at(-1), vector.repository_paths.accepted.at(-1).normalize("NFC")); +}); + +test("verifies sealed segments and event linkage across a segment boundary", async () => { + const ajv = validator(); + const vector = await readJson("vectors", "cross-segment-chain.json"); + const segmentValidator = ajv.getSchema("https://thinkloom.app/schemas/provenance/1.0/ledger-segment-manifest.schema.json"); + const chainHeadValidator = ajv.getSchema("https://thinkloom.app/schemas/provenance/1.0/chain-head.schema.json"); + const allEvents = []; + for (const [index, segment] of vector.segments.entries()) { + assert.equal(segmentValidator(segment.manifest), true, ajv.errorsText(segmentValidator.errors)); + assert.equal(Buffer.byteLength(segment.jsonl), segment.manifest.byte_length); + assert.equal(sha256(segment.jsonl), segment.manifest.segment_file_hash); + assert.equal(segment.manifest.previous_segment_file_hash, index ? vector.segments[index - 1].manifest.segment_file_hash : null); + const events = segment.jsonl.trimEnd().split("\n").map(JSON.parse); + assert.equal(events.length, segment.manifest.event_count); + assert.equal(events[0].event_hash, segment.manifest.first_event_hash); + assert.equal(events.at(-1).event_hash, segment.manifest.final_event_hash); + allEvents.push(...events); + } + for (const [index, event] of allEvents.entries()) { + assert.equal(event.event_sequence, index + 1); + assert.equal(event.previous_event_hash, index ? allEvents[index - 1].event_hash : null); + } + assert.equal(chainHeadValidator(vector.chain_head), true, ajv.errorsText(chainHeadValidator.errors)); + assert.equal(vector.chain_head.event_hash, allEvents.at(-1).event_hash); +}); + +test("reproduces every defined self-digest identity", async () => { + const ajv = validator(); + const vector = await readJson("vectors", "self-digest-identities.json"); + assert.equal(sha256(vector.prompt_template.identity), vector.prompt_template.digest); + const promptValidator = ajv.getSchema("https://thinkloom.app/schemas/provenance/1.0/prompt-template.schema.json"); + assert.equal(promptValidator(vector.prompt_template.complete_record), true, ajv.errorsText(promptValidator.errors)); + assert.equal(hashEvent({ ...vector.provenance_event.identity, event_hash: vector.provenance_event.digest }), vector.provenance_event.digest); + assert.equal(sha256(vector.protected_record.identity), vector.protected_record.digest); + assert.equal(releaseMerkleRoot(vector.release_manifest.merkle_identity), vector.release_manifest.digest); + assert.ok(vector.release_manifest.excluded_paths.includes("release-manifest.json")); +}); + +test("validates key recovery materials and sanitized non-mutating export disclosure", async () => { + const ajv = validator(); + const protectedVector = await readJson("vectors", "protected-record-and-key-rotation.json"); + for (const [schemaName, field] of [["encrypted-key-envelope", "device_key_envelope"], ["recovery-key-envelope", "recovery_key_envelope"], ["project-key-manifest", "project_key_manifest"], ["record-envelope", "initial_envelope"], ["record-envelope", "rotated_envelope"]]) { + const validate = ajv.getSchema(`https://thinkloom.app/schemas/provenance/1.0/${schemaName}.schema.json`); + assert.equal(validate(protectedVector[field]), true, `${schemaName}: ${ajv.errorsText(validate.errors)}`); + } + assert.equal(protectedVector.recovery_key_envelope.key_derivation.algorithm, "argon2id"); + + const sanitizedVector = await readJson("vectors", "sanitized-export.json"); + const validateSanitized = ajv.getSchema("https://thinkloom.app/schemas/provenance/1.0/sanitized-export-manifest.schema.json"); + assert.equal(validateSanitized(sanitizedVector.manifest), true, ajv.errorsText(validateSanitized.errors)); + assert.equal(sha256(sanitizedVector.manifest.omission_rules), sanitizedVector.manifest.rules_sha256); + assert.equal(sanitizedVector.source_chain_head_before, sanitizedVector.source_chain_head_after); + assert.ok(sanitizedVector.exported_record_count < sanitizedVector.source_record_count); +}); + +test("rebuilds deterministic derived-index evidence independent of input order", async () => { + const ajv = validator(); + const vector = await readJson("vectors", "deterministic-derived-index.json"); + const sortContent = (items) => [...items].sort((left, right) => { + const leftKey = canonicalize(left); + const rightKey = canonicalize(right); + return leftKey < rightKey ? -1 : leftKey > rightKey ? 1 : 0; + }); + for (const order of vector.input_orders) assert.deepEqual(sortContent(order), vector.deterministic_content); + assert.equal(sha256(vector.deterministic_content), vector.manifest.content_sha256); + assert.equal(sha256(vector.configuration), vector.manifest.generator.configuration_sha256); + const validate = ajv.getSchema("https://thinkloom.app/schemas/provenance/1.0/derived-index-manifest.schema.json"); + assert.equal(validate(vector.manifest), true, ajv.errorsText(validate.errors)); +}); + +test("covers every verification status and finding severity", async () => { + const ajv = validator(); + const vector = await readJson("vectors", "verification-statuses.json"); + const validate = ajv.getSchema("https://thinkloom.app/schemas/provenance/1.0/verification-report.schema.json"); + for (const report of vector.reports) assert.equal(validate(report), true, ajv.errorsText(validate.errors)); + assert.deepEqual([...new Set(vector.reports.map(({ status }) => status))].sort(), [...vector.required_statuses].sort()); + assert.deepEqual([...new Set(vector.reports.flatMap(({ findings }) => findings.map(({ severity }) => severity)))].sort(), [...vector.required_severities].sort()); +}); + +test("validates backup and release manifests bound to one chain head", async () => { + const ajv = validator(); + const vector = await readJson("vectors", "backup-and-release-manifests.json"); + const validateBackup = ajv.getSchema("https://thinkloom.app/schemas/provenance/1.0/backup-manifest.schema.json"); + const validateRelease = ajv.getSchema("https://thinkloom.app/schemas/provenance/1.0/release-manifest.schema.json"); + assert.equal(validateBackup(vector.backup_manifest), true, ajv.errorsText(validateBackup.errors)); + 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); +}); \ No newline at end of file