diff --git a/public/connect/schemas/catalog.json b/public/connect/schemas/catalog.json index bec7280..f5a1c9d 100644 --- a/public/connect/schemas/catalog.json +++ b/public/connect/schemas/catalog.json @@ -2,7 +2,7 @@ "manifest_version": 1, "schemas": { "app_manifest": "./mdbase-app.schema.json", - "contract_extension": "./contract-extension.v1.schema.json", + "data_contract": "./data-contract.schema.json", "connect_protocol": "./connect-protocol.v1.schema.json", "encrypted_relay": "./encrypted-relay.v1.schema.json", "notification_webhook": "./notification-webhook.v1.schema.json", diff --git a/public/connect/schemas/connect-protocol.v1.schema.json b/public/connect/schemas/connect-protocol.v1.schema.json index 14f9fdb..2adc64c 100644 --- a/public/connect/schemas/connect-protocol.v1.schema.json +++ b/public/connect/schemas/connect-protocol.v1.schema.json @@ -26,9 +26,26 @@ "required": ["id", "version"], "properties": { "id": { "type": "string", "minLength": 1, "maxLength": 100, "pattern": "^[a-z0-9]+(?:[._-][a-z0-9]+)*$" }, + "version": { "$ref": "#/$defs/semanticVersion" } + } + }, + "runtimeContractRequirement": { + "type": "object", + "additionalProperties": false, + "required": ["id", "version"], + "properties": { + "id": { "type": "string", "minLength": 1, "maxLength": 100 }, "version": { "type": "integer", "minimum": 1 } } }, + "semanticVersion": { + "type": "string", + "pattern": "^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$" + }, + "digest": { + "type": "string", + "pattern": "^sha256:[0-9a-f]{64}$" + }, "grantScope": { "type": "object", "additionalProperties": false, @@ -38,7 +55,7 @@ "contracts": { "type": "array", "maxItems": 20, - "items": { "$ref": "#/$defs/contractRequirement" } + "items": { "$ref": "#/$defs/collectionContract" } } } }, @@ -160,7 +177,7 @@ "contracts": { "type": "array", "maxItems": 100, - "items": { "$ref": "#/$defs/contractRequirement" } + "items": { "$ref": "#/$defs/collectionContract" } } } }, @@ -177,14 +194,18 @@ "access": { "enum": ["contract", "full_collection"] } } }, - "typeProvision": { + "typePackProvision": { "type": "object", "additionalProperties": false, - "required": ["name", "document", "provides"], + "required": ["manifest", "resources", "provides"], "properties": { - "name": { "type": "string", "minLength": 1, "maxLength": 100 }, - "path": { "type": "string", "minLength": 1, "maxLength": 500 }, - "document": { "type": "string", "minLength": 1, "maxLength": 262144 }, + "manifest": { "$ref": "#/$defs/typePackManifest" }, + "resources": { + "type": "array", + "minItems": 1, + "maxItems": 100, + "items": { "$ref": "#/$defs/typePackSourceResource" } + }, "provides": { "type": "array", "maxItems": 20, @@ -192,15 +213,53 @@ } } }, + "typePackManifest": { + "type": "object", + "required": ["kind", "id", "version", "resources"], + "properties": { + "kind": { "const": "mdbase.type-pack" }, + "id": { "type": "string", "minLength": 3 }, + "version": { "$ref": "#/$defs/semanticVersion" }, + "name": { "type": "string", "minLength": 1 }, + "description": { "type": "string" }, + "resources": { + "type": "array", + "minItems": 1, + "items": { "$ref": "#/$defs/typePackManifestResource" } + } + }, + "patternProperties": { "^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": true }, + "additionalProperties": false + }, + "typePackManifestResource": { + "type": "object", + "additionalProperties": false, + "required": ["kind", "source", "target", "digest"], + "properties": { + "kind": { "enum": ["contract", "type", "schema"] }, + "source": { "type": "string", "minLength": 1, "maxLength": 500 }, + "target": { "type": "string", "minLength": 1, "maxLength": 500 }, + "digest": { "$ref": "#/$defs/digest" } + } + }, + "typePackSourceResource": { + "type": "object", + "additionalProperties": false, + "required": ["source", "document"], + "properties": { + "source": { "type": "string", "minLength": 1, "maxLength": 500 }, + "document": { "type": "string", "maxLength": 262144 } + } + }, "applicationProvisions": { "type": "object", "additionalProperties": false, - "required": ["types"], + "required": ["type_packs"], "properties": { - "types": { + "type_packs": { "type": "array", "maxItems": 100, - "items": { "$ref": "#/$defs/typeProvision" } + "items": { "$ref": "#/$defs/typePackProvision" } } } }, @@ -258,7 +317,7 @@ "contracts": { "type": "array", "maxItems": 100, - "items": { "$ref": "#/$defs/contractRequirement" } + "items": { "$ref": "#/$defs/collectionContract" } }, "error": { "type": "object", @@ -289,7 +348,7 @@ "required": ["id", "event", "presentation"], "properties": { "id": { "type": "string", "minLength": 1, "maxLength": 100, "pattern": "^[a-z0-9]+(?:[._-][a-z0-9]+)*$" }, - "event": { "$ref": "#/$defs/contractRequirement" }, + "event": { "$ref": "#/$defs/runtimeContractRequirement" }, "if": { "type": "object", "additionalProperties": false, @@ -370,13 +429,34 @@ "collectionContract": { "type": "object", "additionalProperties": false, - "required": ["id", "version", "type_name", "extension", "configuration"], + "required": ["id", "version", "digest", "schema", "implementations"], "properties": { "id": { "type": "string", "minLength": 1 }, - "version": { "type": "integer", "minimum": 1 }, + "version": { "$ref": "#/$defs/semanticVersion" }, + "digest": { "$ref": "#/$defs/digest" }, + "schema": { "type": "object" }, + "binding_schema": { "type": "object" }, + "implementations": { + "type": "array", + "minItems": 1, + "items": { "$ref": "#/$defs/collectionContractImplementation" } + } + } + }, + "collectionContractImplementation": { + "type": "object", + "additionalProperties": false, + "required": ["type_name", "type_version", "digest", "fields"], + "properties": { "type_name": { "type": "string", "minLength": 1 }, - "extension": { "type": "string", "pattern": "^x-[a-z0-9]+(?:[._-][a-z0-9]+)*$" }, - "configuration": { "type": "object" } + "type_version": { "type": "integer", "minimum": 1 }, + "type_path": { "type": "string", "minLength": 1 }, + "digest": { "$ref": "#/$defs/digest" }, + "fields": { + "type": "object", + "additionalProperties": { "type": "string", "minLength": 1 } + }, + "binding": { "type": "object" } } }, "changesPage": { diff --git a/public/connect/schemas/data-contract.schema.json b/public/connect/schemas/data-contract.schema.json new file mode 100644 index 0000000..f8da60b --- /dev/null +++ b/public/connect/schemas/data-contract.schema.json @@ -0,0 +1,58 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://mdbase.dev/schemas/v0.3/data-contract.schema.json", + "title": "mdbase v0.3 data contract frontmatter", + "type": "object", + "required": ["kind", "id", "version", "schema"], + "properties": { + "kind": { "const": "mdbase.contract" }, + "id": { "$ref": "#/$defs/contractId" }, + "version": { "$ref": "#/$defs/semanticVersion" }, + "name": { "type": "string", "minLength": 1 }, + "description": { "type": "string" }, + "schema": { "$ref": "#/$defs/schemaWrapper" }, + "binding_schema": { "$ref": "#/$defs/schemaWrapper" } + }, + "patternProperties": { + "^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": true + }, + "additionalProperties": false, + "$defs": { + "contractId": { + "type": "string", + "minLength": 3, + "maxLength": 128, + "pattern": "^[a-z][a-z0-9]*(?:[._-][a-z0-9]+)+$" + }, + "semanticVersion": { + "type": "string", + "pattern": "^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$" + }, + "schemaWrapper": { + "type": "object", + "required": ["dialect"], + "properties": { + "dialect": { "const": "json-schema-2020-12" }, + "value": { "type": "object" }, + "ref": { "type": "string", "minLength": 1 } + }, + "oneOf": [ + { + "required": ["value"], + "properties": { + "value": true, + "ref": false + } + }, + { + "required": ["ref"], + "properties": { + "ref": true, + "value": false + } + } + ], + "additionalProperties": false + } + } +} diff --git a/public/connect/schemas/mdbase-app.schema.json b/public/connect/schemas/mdbase-app.schema.json index ae7df73..696b272 100644 --- a/public/connect/schemas/mdbase-app.schema.json +++ b/public/connect/schemas/mdbase-app.schema.json @@ -37,12 +37,12 @@ "provisions": { "type": "object", "additionalProperties": false, - "required": ["types"], + "required": ["type_packs"], "properties": { - "types": { + "type_packs": { "type": "array", "maxItems": 20, - "items": { "$ref": "#/$defs/typeProvision" } + "items": { "$ref": "#/$defs/typePackProvision" } } } }, @@ -91,6 +91,18 @@ "pattern": "^[0-9]+(ms|s|m|h|d)$" }, "contract": { + "type": "object", + "additionalProperties": false, + "required": ["id", "version"], + "properties": { + "id": { "$ref": "#/$defs/identifier" }, + "version": { + "type": "string", + "pattern": "^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$" + } + } + }, + "runtimeContract": { "type": "object", "additionalProperties": false, "required": ["id", "version"], @@ -120,14 +132,18 @@ } } }, - "typeProvision": { + "typePackProvision": { "type": "object", "additionalProperties": false, - "required": ["name", "document", "provides"], + "required": ["manifest", "resources", "provides"], "properties": { - "name": { "type": "string", "minLength": 1, "maxLength": 100 }, - "path": { "type": "string", "minLength": 1, "maxLength": 240 }, - "document": { "type": "string", "minLength": 1, "maxLength": 131072 }, + "manifest": { "$ref": "#/$defs/typePackManifest" }, + "resources": { + "type": "array", + "minItems": 1, + "maxItems": 100, + "items": { "$ref": "#/$defs/typePackSourceResource" } + }, "provides": { "type": "array", "maxItems": 20, @@ -136,13 +152,52 @@ } } }, + "typePackManifest": { + "type": "object", + "required": ["kind", "id", "version", "resources"], + "properties": { + "kind": { "const": "mdbase.type-pack" }, + "id": { "$ref": "#/$defs/identifier" }, + "version": { "$ref": "#/$defs/contract/properties/version" }, + "name": { "type": "string", "minLength": 1, "maxLength": 100 }, + "description": { "type": "string", "maxLength": 500 }, + "resources": { + "type": "array", + "minItems": 1, + "maxItems": 100, + "items": { "$ref": "#/$defs/typePackManifestResource" } + } + }, + "patternProperties": { "^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": true }, + "additionalProperties": false + }, + "typePackManifestResource": { + "type": "object", + "additionalProperties": false, + "required": ["kind", "source", "target", "digest"], + "properties": { + "kind": { "enum": ["contract", "type", "schema"] }, + "source": { "type": "string", "minLength": 1, "maxLength": 240 }, + "target": { "type": "string", "minLength": 1, "maxLength": 240 }, + "digest": { "type": "string", "pattern": "^sha256:[0-9a-f]{64}$" } + } + }, + "typePackSourceResource": { + "type": "object", + "additionalProperties": false, + "required": ["source", "document"], + "properties": { + "source": { "type": "string", "minLength": 1, "maxLength": 240 }, + "document": { "type": "string", "maxLength": 262144 } + } + }, "notificationCriterion": { "type": "object", "additionalProperties": false, "required": ["id", "event", "presentation"], "properties": { "id": { "$ref": "#/$defs/identifier" }, - "event": { "$ref": "#/$defs/contract" }, + "event": { "$ref": "#/$defs/runtimeContract" }, "if": { "type": "object", "additionalProperties": false, diff --git a/public/connect/schemas/mdbase-app.v1.json b/public/connect/schemas/mdbase-app.v1.json index ae7df73..696b272 100644 --- a/public/connect/schemas/mdbase-app.v1.json +++ b/public/connect/schemas/mdbase-app.v1.json @@ -37,12 +37,12 @@ "provisions": { "type": "object", "additionalProperties": false, - "required": ["types"], + "required": ["type_packs"], "properties": { - "types": { + "type_packs": { "type": "array", "maxItems": 20, - "items": { "$ref": "#/$defs/typeProvision" } + "items": { "$ref": "#/$defs/typePackProvision" } } } }, @@ -91,6 +91,18 @@ "pattern": "^[0-9]+(ms|s|m|h|d)$" }, "contract": { + "type": "object", + "additionalProperties": false, + "required": ["id", "version"], + "properties": { + "id": { "$ref": "#/$defs/identifier" }, + "version": { + "type": "string", + "pattern": "^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$" + } + } + }, + "runtimeContract": { "type": "object", "additionalProperties": false, "required": ["id", "version"], @@ -120,14 +132,18 @@ } } }, - "typeProvision": { + "typePackProvision": { "type": "object", "additionalProperties": false, - "required": ["name", "document", "provides"], + "required": ["manifest", "resources", "provides"], "properties": { - "name": { "type": "string", "minLength": 1, "maxLength": 100 }, - "path": { "type": "string", "minLength": 1, "maxLength": 240 }, - "document": { "type": "string", "minLength": 1, "maxLength": 131072 }, + "manifest": { "$ref": "#/$defs/typePackManifest" }, + "resources": { + "type": "array", + "minItems": 1, + "maxItems": 100, + "items": { "$ref": "#/$defs/typePackSourceResource" } + }, "provides": { "type": "array", "maxItems": 20, @@ -136,13 +152,52 @@ } } }, + "typePackManifest": { + "type": "object", + "required": ["kind", "id", "version", "resources"], + "properties": { + "kind": { "const": "mdbase.type-pack" }, + "id": { "$ref": "#/$defs/identifier" }, + "version": { "$ref": "#/$defs/contract/properties/version" }, + "name": { "type": "string", "minLength": 1, "maxLength": 100 }, + "description": { "type": "string", "maxLength": 500 }, + "resources": { + "type": "array", + "minItems": 1, + "maxItems": 100, + "items": { "$ref": "#/$defs/typePackManifestResource" } + } + }, + "patternProperties": { "^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": true }, + "additionalProperties": false + }, + "typePackManifestResource": { + "type": "object", + "additionalProperties": false, + "required": ["kind", "source", "target", "digest"], + "properties": { + "kind": { "enum": ["contract", "type", "schema"] }, + "source": { "type": "string", "minLength": 1, "maxLength": 240 }, + "target": { "type": "string", "minLength": 1, "maxLength": 240 }, + "digest": { "type": "string", "pattern": "^sha256:[0-9a-f]{64}$" } + } + }, + "typePackSourceResource": { + "type": "object", + "additionalProperties": false, + "required": ["source", "document"], + "properties": { + "source": { "type": "string", "minLength": 1, "maxLength": 240 }, + "document": { "type": "string", "maxLength": 262144 } + } + }, "notificationCriterion": { "type": "object", "additionalProperties": false, "required": ["id", "event", "presentation"], "properties": { "id": { "$ref": "#/$defs/identifier" }, - "event": { "$ref": "#/$defs/contract" }, + "event": { "$ref": "#/$defs/runtimeContract" }, "if": { "type": "object", "additionalProperties": false, diff --git a/public/connect/schemas/sync.v1.schema.json b/public/connect/schemas/sync.v1.schema.json index d1bf928..436b121 100644 --- a/public/connect/schemas/sync.v1.schema.json +++ b/public/connect/schemas/sync.v1.schema.json @@ -11,6 +11,14 @@ ], "$defs": { "uuid": { "type": "string", "format": "uuid" }, + "semanticVersion": { + "type": "string", + "pattern": "^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$" + }, + "digest": { + "type": "string", + "pattern": "^sha256:[0-9a-f]{64}$" + }, "collectionType": { "type": "object", "additionalProperties": false, @@ -28,13 +36,34 @@ "contract": { "type": "object", "additionalProperties": false, - "required": ["id", "version", "type_name", "extension", "configuration"], + "required": ["id", "version", "digest", "schema", "implementations"], "properties": { "id": { "type": "string", "minLength": 1 }, - "version": { "type": "integer", "minimum": 1 }, + "version": { "$ref": "#/$defs/semanticVersion" }, + "digest": { "$ref": "#/$defs/digest" }, + "schema": { "type": "object" }, + "binding_schema": { "type": "object" }, + "implementations": { + "type": "array", + "minItems": 1, + "items": { "$ref": "#/$defs/contractImplementation" } + } + } + }, + "contractImplementation": { + "type": "object", + "additionalProperties": false, + "required": ["type_name", "type_version", "digest", "fields"], + "properties": { "type_name": { "type": "string", "minLength": 1 }, - "extension": { "type": "string", "pattern": "^x-" }, - "configuration": { "type": "object" } + "type_version": { "type": "integer", "minimum": 1 }, + "type_path": { "type": "string", "minLength": 1 }, + "digest": { "$ref": "#/$defs/digest" }, + "fields": { + "type": "object", + "additionalProperties": { "type": "string", "minLength": 1 } + }, + "binding": { "type": "object" } } }, "resources": { @@ -55,7 +84,7 @@ "required": ["path", "kind", "revision", "document"], "properties": { "path": { "type": "string", "minLength": 1 }, - "kind": { "enum": ["configuration", "type"] }, + "kind": { "enum": ["configuration", "type", "contract", "schema", "view"] }, "revision": { "type": "string", "minLength": 1 }, "document": { "type": "string" } } diff --git a/site-sources.json b/site-sources.json index 77da7f2..c47afde 100644 --- a/site-sources.json +++ b/site-sources.json @@ -1,20 +1,20 @@ { "specification": { "repository": "mdbase-dev/mdbase-spec", - "ref": "2c5e1bbc8736d71b95fcaea1b593dc2eeaec739b" + "ref": "f0f6b5ab497f201a21723e137997b5d5d02358be" }, "connect": { "repository": "mdbase-dev/mdbase-connect", - "ref": "8e960317f0886f8c504023dad873cf8cec82fd99" + "ref": "fc94dffefb2408a756d7610f26730cac2b22a843" }, "implementations": [ { "repository": "callumalpass/mdbase-rs", - "ref": "fafea262cffbce1205563a580e4d5850e7e942b2" + "ref": "99d27a245523a6f6feea950a036bd796b89f99b4" }, { "repository": "callumalpass/mdbase", - "ref": "4f419e0f4454682d42e067749db1fd16d72d1eb9" + "ref": "893c7aee289794a353a71546a8c87e9902d684ce" } ] } diff --git a/src/data/conformance.json b/src/data/conformance.json index bbbb1f6..3da243d 100644 --- a/src/data/conformance.json +++ b/src/data/conformance.json @@ -1,5 +1,5 @@ { - "generated_at": "2026-07-27", + "generated_at": "2026-07-28", "spec_version": "0.3.0", "implementations": [ { diff --git a/src/pages/sdk/connect-quickstart/index.astro b/src/pages/sdk/connect-quickstart/index.astro index e7e7733..4be4db0 100644 --- a/src/pages/sdk/connect-quickstart/index.astro +++ b/src/pages/sdk/connect-quickstart/index.astro @@ -12,16 +12,43 @@ const manifest = `{ ], "requirements": { "contracts": [ - { "id": "workout.record", "version": 1 } + { "id": "workout.record", "version": "1.0.0" } ] }, "provisions": { - "types": [ + "type_packs": [ { - "name": "Workout", - "document": "---\\nkind: mdbase.type\\nname: workout\\nversion: 1\\nschema:\\n dialect: json-schema-2020-12\\n value:\\n type: object\\n required: [type, title]\\n additionalProperties: true\\n properties:\\n type: { const: workout }\\n title: { type: string }\\n completed: { type: boolean }\\nx-workout:\\n contract: workout.record\\n version: 1\\n field_roles:\\n title: title\\n---\\n", "provides": [ - { "id": "workout.record", "version": 1 } + { "id": "workout.record", "version": "1.0.0" } + ], + "manifest": { + "kind": "mdbase.type-pack", + "id": "example.workouts", + "version": "1.0.0", + "resources": [ + { + "kind": "contract", + "source": "contracts/workout.record.md", + "target": "_contracts/workout.record.md", + "digest": "sha256:e0c2f77dd7158ca7e6b52b13da8c306f0a7e1b97582a1024f00ec0cf7fe5f259" + }, + { + "kind": "type", + "source": "types/workout.md", + "target": "_types/workout.md", + "digest": "sha256:ff35309cd4598182d2021f698ee85cad4d320d965cd5f7c1bd608ee2eb16505b" + } + ] + }, + "resources": [ + { + "source": "contracts/workout.record.md", + "document": "---\\nkind: mdbase.contract\\nid: workout.record\\nversion: 1.0.0\\nschema:\\n dialect: json-schema-2020-12\\n value:\\n $schema: https://json-schema.org/draft/2020-12/schema\\n type: object\\n additionalProperties: false\\n properties:\\n title: { type: string }\\n completed: { type: boolean, default: false }\\n required: [title]\\n---\\n" + }, + { + "source": "types/workout.md", + "document": "---\\nkind: mdbase.type\\nname: workout\\nversion: 1\\nschema:\\n dialect: json-schema-2020-12\\n value:\\n type: object\\n additionalProperties: true\\n properties:\\n title: { type: string }\\n completed: { type: boolean }\\n required: [title]\\nimplements:\\n - contract: workout.record\\n version: 1.0.0\\n fields:\\n title: title\\n completed: completed\\n---\\n" + } ] } ] @@ -48,7 +75,6 @@ const client = `import { } from "@mdbase/connect"; export interface Workout extends JsonObject { - type: "workout"; title: string; completed?: boolean; } @@ -114,17 +140,26 @@ const collection = collectionLocation.activeConnection(); if (!collection) throw new Error("Choose a collection."); const page = unwrapOperation(await collection.query({ - types: ["workout"], - where: "completed != true", - order_by: [{ field: "title", direction: "asc" }], + contract: { + id: "workout.record", + version: "1.0.0" + }, limit: 50 })); -const first = page.results[0]; +const first = page.results + .filter((row) => row.completed !== true) + .sort((left, right) => + left.title.localeCompare(right.title) + )[0]; if (first) { unwrapOperation(await collection.update({ path: first.path, patch: { completed: true }, + contract: { + id: "workout.record", + version: "1.0.0" + }, if_revision: first.revision })); }`; @@ -164,9 +199,9 @@ if (first) {
  • a Connect SDK source build or beta artifact.
  • - The example manifest carries a complete workout type. Connect can install - that type during approval when the chosen collection does not yet provide - {" "}workout.record@1. + The example manifest carries a complete transactional contract/type pack. + Connect can install it during approval when the chosen collection does not + yet provide workout.record 1.0.0.

    1. Add a bundled application manifest

    @@ -178,9 +213,9 @@ if (first) {

    - The contract requirement limits compatible collections. The provision - makes a collection safely provisionable during approval and does not give - the application general type-management access. + The contract requirement limits compatible collections. The type pack makes + a collection safely provisionable during approval and does not give the + application general type-management access.

    2. Add the SDK and validator

    @@ -231,6 +266,11 @@ if (first) { {" "}if_revision prevents one application from silently overwriting a newer change.

    +

    + Contract-scoped queries expose normalized mapped fields only. They union + every approved implementation and deliberately leave filtering and sorting + those normalized values to the application. +

    What success looks like

      diff --git a/src/pages/sdk/contracts/index.astro b/src/pages/sdk/contracts/index.astro index 9061639..a4919f9 100644 --- a/src/pages/sdk/contracts/index.astro +++ b/src/pages/sdk/contracts/index.astro @@ -7,15 +7,19 @@ const generic = `const description = await connection.describe(); const workItemContract = description.contracts.find( (contract) => contract.id === "example.work-item" && - contract.version === 1 + contract.version === "1.0.0" ); if (!workItemContract) { - throw new Error("The approved collection lacks example.work-item@1"); + throw new Error("The approved collection lacks example.work-item 1.0.0"); } -const workItemType = workItemContract.type_name; -const fieldRoles = workItemContract.configuration.field_roles;`; +for (const implementation of workItemContract.implementations) { + console.log( + implementation.type_name, + implementation.fields + ); +}`; const domainFunction = `import type { MdbaseCollectionClient } from "@mdbase/connect"; @@ -27,7 +31,10 @@ export class WorklogCollection { list() { return this.client.queryAll({ - types: [this.contract.typeName] + contract: { + id: "example.work-item", + version: "1.0.0" + } }); } }`; @@ -45,19 +52,26 @@ export class WorklogCollection { ]} >

      - A type describes record shape. A domain contract identifies portable - behavior and maps semantic roles onto that type. Two collections can provide - the same contract while using different frontmatter property names or path - conventions. + A type describes how one collection stores records. A data contract is a + versioned JSON Schema for a stable, portable record view. A type opts into a + contract through{" "}implements, where it maps contract field names + to its own frontmatter fields. +

      +

      + This is intentionally many-to-many. Several types can implement one + contract, so reads union all of them. One type can implement contracts used + by several applications, so those applications can share the same records + without sharing implementation-specific conventions.

      Read the approved collection description

      - describe() returns portable type definitions, complete contract - descriptors, collection settings, JSON Schemas, and supported operations. - Use this data after authorization. The manifest requirement guarantees that - Connect only offers a ready or safely provisionable collection. + describe() returns each exact string version, contract schema, + digest, and complete{" "}implementations list. Each implementation + includes its concrete type, field mapping, binding metadata, and digest. Use + this data after authorization; do not look for semantic meaning in{" "} + x-* extensions.

      Keep your adapter on the transport-neutral client

      @@ -68,6 +82,12 @@ export class WorklogCollection { Connect, createSandbox(), offline transports, and conforming providers.

      +

      + A contract query returns normalized contract fields and unions every + approved implementation. If a record exposes several approved views, pass + the exact{" "}{"{ id, version, type }"} selector. Creates also need + an exact provider when more than one implementation is available. +

      Keep domain behavior with its application

      @@ -80,10 +100,11 @@ export class WorklogCollection {

      Contract scope and full collection access

      - Contract-scoped grants confine record paths and operations to types that - provide the required contracts. They cannot administer collection-wide - type definitions. Request full_collection only for genuine - collection-level behavior such as arbitrary saved views, schema editors, or - general-purpose collection tools. + Contract-scoped grants expose only normalized mapped fields. Markdown + bodies, unmapped frontmatter, unrelated types, and collection-wide features + stay private. Filtering and sorting normalized fields happens in the + application. Request{" "}full_collection only for genuine + whole-record or collection-level behavior such as body-aware task tools, + arbitrary saved views, schema editors, or general-purpose collection tools.

      diff --git a/src/pages/sdk/manifest/index.astro b/src/pages/sdk/manifest/index.astro index e16118d..0d40a4e 100644 --- a/src/pages/sdk/manifest/index.astro +++ b/src/pages/sdk/manifest/index.astro @@ -12,16 +12,44 @@ const contractManifest = `{ ], "requirements": { "contracts": [ - { "id": "example.work-item", "version": 1 } + { "id": "example.work-item", "version": "1.0.0" } ] }, "provisions": { - "types": [ + "type_packs": [ { - "name": "Work item", - "document": "---\\nkind: mdbase.type\\nname: work-item\\nversion: 1\\nschema:\\n dialect: json-schema-2020-12\\n value:\\n type: object\\nx-worklog:\\n contract: example.work-item\\n version: 1\\n---\\n", "provides": [ - { "id": "example.work-item", "version": 1 } + { "id": "example.work-item", "version": "1.0.0" } + ], + "manifest": { + "kind": "mdbase.type-pack", + "id": "example.work-items", + "version": "1.0.0", + "name": "Work items", + "resources": [ + { + "kind": "contract", + "source": "contracts/example.work-item.md", + "target": "_contracts/example.work-item.md", + "digest": "sha256:9cd7f8e4b23ba20aaeaec3f7e209c6ba8de3fa5cd224204f2baef4e14dd69936" + }, + { + "kind": "type", + "source": "types/work-item.md", + "target": "_types/work-item.md", + "digest": "sha256:2be7d8a5cd316fe2e4d31fa49b1d09f2d26a584846392b3ef21ff0219893230b" + } + ] + }, + "resources": [ + { + "source": "contracts/example.work-item.md", + "document": "---\\nkind: mdbase.contract\\nid: example.work-item\\nversion: 1.0.0\\nschema:\\n dialect: json-schema-2020-12\\n value:\\n $schema: https://json-schema.org/draft/2020-12/schema\\n type: object\\n additionalProperties: false\\n properties:\\n title: { type: string }\\n required: [title]\\n---\\n" + }, + { + "source": "types/work-item.md", + "document": "---\\nkind: mdbase.type\\nname: work-item\\nversion: 1\\nschema:\\n dialect: json-schema-2020-12\\n value:\\n type: object\\n additionalProperties: true\\n properties:\\n title: { type: string }\\n required: [title]\\nimplements:\\n - contract: example.work-item\\n version: 1.0.0\\n fields:\\n title: title\\n---\\n" + } ] } ] @@ -143,7 +171,7 @@ const portableManifest = `{ contracts - Exact domain contract IDs and major versions the app understands + Exact contract IDs and semantic versions the app understands access: "contract" @@ -169,17 +197,19 @@ const portableManifest = `{

      Provision a missing contract safely

      - A manifest may carry complete portable type documents. During approval, the - authority installs only the missing definitions, reopens the collection, - and verifies the declared contract before it creates the grant. + A manifest may carry a complete transactional type pack. During approval, + the authority validates every declared digest, preflights the contract, + types, and referenced schemas together, and writes all resources or none. + It then reopens the collection and pins the exact contract and + implementation digests before creating the grant. General type administration requires a separate{" "} create_type grant.

      - A provision may only claim contracts listed in{" "} - requirements.contracts. Auxiliary types installed with the - same approved set use an empty provides array. + A pack may only claim contracts listed in{" "} + requirements.contracts. A target with different bytes is a + conflict, not an implicit overwrite. Repeating the same pack is idempotent.

      Native application callbacks