From 0433a8a90906339c0ad656b139fc61c2fc03ad2c Mon Sep 17 00:00:00 2001 From: Jeremi Joslin Date: Sat, 1 Aug 2026 16:12:29 +0700 Subject: [PATCH 1/3] fix(registryctl): unify structured-output nullability on the type union A structured output now declares nullability the same way at every type. Object and array outputs use `type: [object, "null"]` and `type: ["array", "null"]`, which is what scalar outputs already used, and the separate `nullable:` key they carried is removed. That key shipped on composites only and never applied to scalars, so one grammar had two ways to say the same thing depending on the type in hand. The key is a released surface: it went out in 0.16.0, so removing it is a break and carries a `BREAKING:` entry with migration steps in the crate changelog, per the pre-1.0 rule in the API stability reference. Delete `nullable: true` and pair the declared form with `"null"` in the `type` union; delete `nullable: false` outright, since a form without `"null"` is already non-nullable. An authored project that still carries the key is rejected by `registryctl.authoring.yaml.unknown_field`, naming the offending pointer and the union syntax that replaces it, rather than by a generic whole-document schema error. Malformed recursive declarations now address their own nested location. The output validators compile each `$defs` branch standalone and select the branch the `type` discriminator names, so a failure inside `outputs.parents.items.fields.identifier.schema` reports that pointer instead of collapsing to the whole document. When no authored path can be recovered the diagnostic degrades to the previous whole-document form. Boundary-parity tests cover the authored declaration through Relay and Notary: escaped control characters and non-ASCII strings and keys, exact bounded integers, nullable and required nested values, byte caps at N and N-1, and the platform depth, field, item, and expanded-node limits. Two things the ticket raises are deliberately not changed. The aggregate composite byte budget stays explicit and required rather than gaining a derived default, because a silent default would weaken a safety control that the ticket also asks to keep independent. The `nullable` field on the compiled Relay and Notary contracts is a different, internal wire surface and is untouched. The `docs/site` files are regenerated configuration reference data, produced by `node scripts/generate-authoring-reference.mjs`, not hand-edited. Closes #573 Signed-off-by: Jeremi Joslin --- crates/registryctl/CHANGELOG.md | 16 + .../documentation-intent.json | 22 +- .../dto-shape-contract.v1.json | 60 +- .../project-authoring/integration.schema.json | 46 +- .../project_authoring/authoring_contract.rs | 180 +- .../src/project_authoring/diagnostics.rs | 165 +- .../src/project_authoring/documentation.rs | 2 +- .../src/project_authoring/project.rs | 2 +- .../project_authoring/promotion_projection.rs | 2 +- .../src/project_authoring/schema_authority.rs | 193 +- .../src/project_authoring/tests.rs | 207 +- .../birth-record/integration.yaml | 2 - .../opencrvs/registry-stack.yaml | 2 +- crates/registryctl/tests/project_authoring.rs | 2 +- .../tests/project_authoring_schema_parity.rs | 1002 ++++- .../tests/project_documentation_reference.rs | 20 +- .../configuration-reference-coverage.v1.json | 28 +- .../generated/configuration-reference.v1.json | 3964 ++++++++++------- .../configuration-reference-coverage.json | 28 +- .../generated/configuration-reference.json | 3964 ++++++++++------- 20 files changed, 6277 insertions(+), 3630 deletions(-) diff --git a/crates/registryctl/CHANGELOG.md b/crates/registryctl/CHANGELOG.md index de9aae445..72ea20f60 100644 --- a/crates/registryctl/CHANGELOG.md +++ b/crates/registryctl/CHANGELOG.md @@ -6,6 +6,22 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] +### Changed + +- BREAKING: a structured output declares nullability the same way at every + type. Object and array outputs use `type: [object, "null"]` and + `type: ["array", "null"]`, which is what scalar outputs already used, and the + separate `nullable:` key they carried is removed. It shipped on composites + only, in 0.16.0, and never applied to scalars, so one grammar had two ways to + say the same thing depending on the type in hand. Migration: delete + `nullable: true` and pair the declared form with `"null"` in the `type` union; + delete `nullable: false` outright, since a form without `"null"` is already + non-nullable. An authored project that still carries the key is rejected by + `registryctl.authoring.yaml.unknown_field` with the offending pointer and the + union syntax to replace it. The `nullable` field on the compiled Registry + Relay and Registry Notary contracts is a different, internal wire surface and + is unchanged. + ## [0.16.0] - 2026-08-01 ### Removed diff --git a/crates/registryctl/schemas/project-authoring/documentation-intent.json b/crates/registryctl/schemas/project-authoring/documentation-intent.json index 91b5a2ccf..e7d05d82b 100644 --- a/crates/registryctl/schemas/project-authoring/documentation-intent.json +++ b/crates/registryctl/schemas/project-authoring/documentation-intent.json @@ -180,6 +180,14 @@ { "schema": "integration", "pointer": "/$defs/scalarType/oneOf/1", "path_kind": "branch" }, { "schema": "integration", "pointer": "/$defs/scalarType/oneOf/1/prefixItems/0", "path_kind": "array_item" }, { "schema": "integration", "pointer": "/$defs/scalarType/oneOf/1/prefixItems/1", "path_kind": "array_item" }, + { "schema": "integration", "pointer": "/$defs/objectType/oneOf/0", "path_kind": "branch" }, + { "schema": "integration", "pointer": "/$defs/objectType/oneOf/1", "path_kind": "branch" }, + { "schema": "integration", "pointer": "/$defs/objectType/oneOf/1/prefixItems/0", "path_kind": "array_item" }, + { "schema": "integration", "pointer": "/$defs/objectType/oneOf/1/prefixItems/1", "path_kind": "array_item" }, + { "schema": "integration", "pointer": "/$defs/arrayType/oneOf/0", "path_kind": "branch" }, + { "schema": "integration", "pointer": "/$defs/arrayType/oneOf/1", "path_kind": "branch" }, + { "schema": "integration", "pointer": "/$defs/arrayType/oneOf/1/prefixItems/0", "path_kind": "array_item" }, + { "schema": "integration", "pointer": "/$defs/arrayType/oneOf/1/prefixItems/1", "path_kind": "array_item" }, { "schema": "integration", "pointer": "/$defs/versions/anyOf/0", "path_kind": "branch" }, { "schema": "integration", "pointer": "/$defs/versions/anyOf/1", "path_kind": "branch" }, { "schema": "integration", "pointer": "/$defs/versionList/items", "path_kind": "array_item" }, @@ -1475,12 +1483,7 @@ { "schema": "integration", "pointer": "/$defs/outputObject/properties/type", - "purpose": "Selects the closed object form for a structured integration output." - }, - { - "schema": "integration", - "pointer": "/$defs/outputObject/properties/nullable", - "purpose": "Declares whether the complete structured output object may be null." + "purpose": "Selects the closed object form for a structured integration output, and declares the object nullable by pairing it with null." }, { "schema": "integration", @@ -1495,12 +1498,7 @@ { "schema": "integration", "pointer": "/$defs/outputArray/properties/type", - "purpose": "Selects the array form for a structured integration output." - }, - { - "schema": "integration", - "pointer": "/$defs/outputArray/properties/nullable", - "purpose": "Declares whether the complete structured output array may be null." + "purpose": "Selects the array form for a structured integration output, and declares the array nullable by pairing it with null." }, { "schema": "integration", diff --git a/crates/registryctl/schemas/project-authoring/dto-shape-contract.v1.json b/crates/registryctl/schemas/project-authoring/dto-shape-contract.v1.json index fe8ccb96d..d600ec0d5 100644 --- a/crates/registryctl/schemas/project-authoring/dto-shape-contract.v1.json +++ b/crates/registryctl/schemas/project-authoring/dto-shape-contract.v1.json @@ -2529,6 +2529,26 @@ "rust_type": "AuthoredIntegrationDocument", "schema": { "$defs": { + "AuthoredArraySchemaType": { + "anyOf": [ + { + "$ref": "#/$defs/AuthoredOutputArrayType" + }, + { + "maxItems": 2, + "minItems": 2, + "prefixItems": [ + { + "$ref": "#/$defs/AuthoredOutputArrayType" + }, + { + "$ref": "#/$defs/AuthoredNullType" + } + ], + "type": "array" + } + ] + }, "AuthoredByteSize": { "anyOf": [ { @@ -2899,6 +2919,34 @@ ], "type": "object" }, + "AuthoredNullType": { + "description": "The `\"null\"` member of an authored composite `type` union.", + "enum": [ + "null" + ], + "type": "string" + }, + "AuthoredObjectSchemaType": { + "anyOf": [ + { + "$ref": "#/$defs/AuthoredOutputObjectType" + }, + { + "maxItems": 2, + "minItems": 2, + "prefixItems": [ + { + "$ref": "#/$defs/AuthoredOutputObjectType" + }, + { + "$ref": "#/$defs/AuthoredNullType" + } + ], + "type": "array" + } + ], + "description": "The one authored nullability idiom, shared with `AuthoredSchemaType`.\n\nScalar, object, and array declarations all express nullability as the\nJSON-Schema-native `type` union `[
, \"null\"]`. The tuple arm makes the\ntwo-member scalar/null order part of the type rather than a runtime rule." + }, "AuthoredOutputArrayDeclaration": { "additionalProperties": false, "properties": { @@ -2916,16 +2964,12 @@ "minimum": 0, "type": "integer" }, - "nullable": { - "type": "boolean" - }, "type": { - "$ref": "#/$defs/AuthoredOutputArrayType" + "$ref": "#/$defs/AuthoredArraySchemaType" } }, "required": [ "type", - "nullable", "max_bytes", "max_items", "items" @@ -2965,16 +3009,12 @@ "minimum": 0, "type": "integer" }, - "nullable": { - "type": "boolean" - }, "type": { - "$ref": "#/$defs/AuthoredOutputObjectType" + "$ref": "#/$defs/AuthoredObjectSchemaType" } }, "required": [ "type", - "nullable", "max_bytes", "fields" ], diff --git a/crates/registryctl/schemas/project-authoring/integration.schema.json b/crates/registryctl/schemas/project-authoring/integration.schema.json index 32a8669fa..8730fe003 100644 --- a/crates/registryctl/schemas/project-authoring/integration.schema.json +++ b/crates/registryctl/schemas/project-authoring/integration.schema.json @@ -67,13 +67,11 @@ "outputs": { "active": { "type": "boolean" }, "parents": { - "type": "array", - "nullable": false, + "type": ["array", "null"], "max_bytes": 4096, "max_items": 2, "items": { "type": "object", - "nullable": false, "max_bytes": 2048, "fields": { "name": { @@ -577,14 +575,45 @@ "schema": {"x-registry-field": "property", "$ref": "#/$defs/outputSchema" } } }, + "objectType": { + "description": "The object form, optionally paired with null for a nullable structured output object.", + "oneOf": [ + {"x-registry-field": "branch", "const": "object" }, + { + "x-registry-field": "branch", + "type": "array", + "prefixItems": [ + {"x-registry-field": "array_item", "const": "object" }, + {"x-registry-field": "array_item", "const": "null" } + ], + "minItems": 2, + "maxItems": 2 + } + ] + }, + "arrayType": { + "description": "The array form, optionally paired with null for a nullable structured output array.", + "oneOf": [ + {"x-registry-field": "branch", "const": "array" }, + { + "x-registry-field": "branch", + "type": "array", + "prefixItems": [ + {"x-registry-field": "array_item", "const": "array" }, + {"x-registry-field": "array_item", "const": "null" } + ], + "minItems": 2, + "maxItems": 2 + } + ] + }, "outputObject": { "description": "A recursively typed object output with a canonical byte ceiling and an always-closed field map.", "type": "object", "additionalProperties": false, - "required": ["type", "nullable", "max_bytes", "fields"], + "required": ["type", "max_bytes", "fields"], "properties": { - "type": {"x-registry-field": "property", "const": "object" }, - "nullable": {"x-registry-field": "property", "type": "boolean" }, + "type": {"x-registry-field": "property", "$ref": "#/$defs/objectType" }, "max_bytes": {"x-registry-field": "property", "type": "integer", "minimum": 1, "maximum": 65536 }, "fields": { "x-registry-field": "property", @@ -600,10 +629,9 @@ "description": "A recursively typed array output with canonical byte and item-count ceilings.", "type": "object", "additionalProperties": false, - "required": ["type", "nullable", "max_bytes", "max_items", "items"], + "required": ["type", "max_bytes", "max_items", "items"], "properties": { - "type": {"x-registry-field": "property", "const": "array" }, - "nullable": {"x-registry-field": "property", "type": "boolean" }, + "type": {"x-registry-field": "property", "$ref": "#/$defs/arrayType" }, "max_bytes": {"x-registry-field": "property", "type": "integer", "minimum": 1, "maximum": 65536 }, "max_items": {"x-registry-field": "property", "type": "integer", "minimum": 1, "maximum": 256 }, "items": {"x-registry-field": "property", "$ref": "#/$defs/outputSchema" } diff --git a/crates/registryctl/src/project_authoring/authoring_contract.rs b/crates/registryctl/src/project_authoring/authoring_contract.rs index 2ebb2ef34..08dfe188e 100644 --- a/crates/registryctl/src/project_authoring/authoring_contract.rs +++ b/crates/registryctl/src/project_authoring/authoring_contract.rs @@ -401,38 +401,93 @@ struct AuthoredOutputObjectField { #[serde(deny_unknown_fields)] struct AuthoredOutputObjectDeclaration { #[serde(rename = "type")] - output_type: AuthoredOutputObjectType, - nullable: bool, + output_type: AuthoredObjectSchemaType, max_bytes: u32, fields: BTreeMap, } +impl AuthoredOutputObjectDeclaration { + const fn nullable(&self) -> bool { + self.output_type.nullable() + } +} + #[cfg_attr(test, derive(schemars::JsonSchema))] -#[derive(Debug, Clone, Copy, Deserialize, Serialize)] +#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq)] #[serde(rename_all = "snake_case")] enum AuthoredOutputObjectType { Object, } +/// The one authored nullability idiom, shared with `AuthoredSchemaType`. +/// +/// Scalar, object, and array declarations all express nullability as the +/// JSON-Schema-native `type` union `[, "null"]`. The tuple arm makes the +/// two-member scalar/null order part of the type rather than a runtime rule. +#[cfg_attr(test, derive(schemars::JsonSchema))] +#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq)] +#[serde(untagged)] +enum AuthoredObjectSchemaType { + Single(AuthoredOutputObjectType), + Nullable((AuthoredOutputObjectType, AuthoredNullType)), +} + +impl AuthoredObjectSchemaType { + const fn nullable(&self) -> bool { + matches!(self, Self::Nullable(_)) + } +} + #[cfg_attr(test, derive(schemars::JsonSchema))] #[derive(Debug, Deserialize, Serialize)] #[serde(deny_unknown_fields)] struct AuthoredOutputArrayDeclaration { #[serde(rename = "type")] - output_type: AuthoredOutputArrayType, - nullable: bool, + output_type: AuthoredArraySchemaType, max_bytes: u32, max_items: u16, items: Box, } +impl AuthoredOutputArrayDeclaration { + const fn nullable(&self) -> bool { + self.output_type.nullable() + } +} + #[cfg_attr(test, derive(schemars::JsonSchema))] -#[derive(Debug, Clone, Copy, Deserialize, Serialize)] +#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq)] #[serde(rename_all = "snake_case")] enum AuthoredOutputArrayType { Array, } +#[cfg_attr(test, derive(schemars::JsonSchema))] +#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq)] +#[serde(untagged)] +enum AuthoredArraySchemaType { + Single(AuthoredOutputArrayType), + Nullable((AuthoredOutputArrayType, AuthoredNullType)), +} + +impl AuthoredArraySchemaType { + const fn nullable(&self) -> bool { + matches!(self, Self::Nullable(_)) + } +} + +/// The `"null"` member of an authored composite `type` union. +#[cfg_attr(test, derive(schemars::JsonSchema))] +#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq)] +#[serde(rename_all = "snake_case")] +enum AuthoredNullType { + Null, +} + +const STRUCTURED_OUTPUT_NULLABLE_UNION_SUGGESTION: &str = "type: [object, \"null\"] for an object output, or type: [array, \"null\"] for an array output"; + +const STRUCTURED_OUTPUT_NULLABLE_UNION_REMEDIATION: &str = "Remove the `nullable` field and pair the declared form with null in the `type` union, exactly as scalar outputs already do."; + #[cfg_attr(test, derive(schemars::JsonSchema))] #[derive(Debug, Deserialize, Serialize)] #[serde(deny_unknown_fields)] @@ -1059,11 +1114,12 @@ fn validate_authored_output( output: &AuthoredOutputDeclaration, nodes: &mut usize, ) -> Result { + let path = format!("outputs.{name}"); match output { AuthoredOutputDeclaration::Scalar(output) => { - record_output_schema_node(name, OUTPUT_SCHEMA_ROOT_DEPTH_V1, nodes)?; + record_output_schema_node(&path, OUTPUT_SCHEMA_ROOT_DEPTH_V1, nodes)?; validate_authored_scalar_output( - name, + &path, &output.output_type, output.format, output.max_length, @@ -1073,28 +1129,16 @@ fn validate_authored_output( Ok(1) } AuthoredOutputDeclaration::Object(output) => { - validate_authored_output_object( - name, - &format!("outputs.{name}"), - output, - OUTPUT_SCHEMA_ROOT_DEPTH_V1, - nodes, - ) + validate_authored_output_object(&path, output, OUTPUT_SCHEMA_ROOT_DEPTH_V1, nodes) } AuthoredOutputDeclaration::Array(output) => { - validate_authored_output_array( - name, - &format!("outputs.{name}"), - output, - OUTPUT_SCHEMA_ROOT_DEPTH_V1, - nodes, - ) + validate_authored_output_array(&path, output, OUTPUT_SCHEMA_ROOT_DEPTH_V1, nodes) } } } fn validate_authored_scalar_output( - name: &str, + path: &str, output_type: &AuthoredSchemaType, format: Option, max_length: Option, @@ -1104,16 +1148,16 @@ fn validate_authored_scalar_output( let (scalar, _) = schema_type_parts(output_type)?; match scalar { AuthoredScalarType::String => { - let max = max_length - .ok_or_else(|| anyhow!("outputs.{name}.maxLength is required for String"))?; + let max = + max_length.ok_or_else(|| anyhow!("{path}.maxLength is required for String"))?; if max == 0 || max > 16_384 { - bail!("outputs.{name}.maxLength is outside the v1 bounds"); + bail!("{path}.maxLength is outside the v1 bounds"); } if minimum.is_some() || maximum.is_some() { - bail!("outputs.{name} String schemas cannot declare minimum or maximum"); + bail!("{path} String schemas cannot declare minimum or maximum"); } if format == Some(AuthoredStringFormat::Date) && max != 10 { - bail!("outputs.{name} date format requires maxLength: 10"); + bail!("{path} date format requires maxLength: 10"); } } AuthoredScalarType::Boolean => { @@ -1122,34 +1166,34 @@ fn validate_authored_scalar_output( || minimum.is_some() || maximum.is_some() { - bail!("outputs.{name} Boolean schema has incompatible constraints"); + bail!("{path} Boolean schema has incompatible constraints"); } } AuthoredScalarType::Integer => { - let minimum = minimum - .ok_or_else(|| anyhow!("outputs.{name}.minimum is required for Integer"))?; - let maximum = maximum - .ok_or_else(|| anyhow!("outputs.{name}.maximum is required for Integer"))?; + let minimum = + minimum.ok_or_else(|| anyhow!("{path}.minimum is required for Integer"))?; + let maximum = + maximum.ok_or_else(|| anyhow!("{path}.maximum is required for Integer"))?; if minimum > maximum || minimum < -MAX_JSON_SAFE_INTEGER_V1 || maximum > MAX_JSON_SAFE_INTEGER_V1 || format.is_some() || max_length.is_some() { - bail!("outputs.{name} Integer schema has invalid constraints"); + bail!("{path} Integer schema has invalid constraints"); } } - AuthoredScalarType::Null => bail!("outputs.{name} cannot have only null type"), + AuthoredScalarType::Null => bail!("{path} cannot have only null type"), } Ok(()) } -fn record_output_schema_node(name: &str, depth: usize, nodes: &mut usize) -> Result<()> { +fn record_output_schema_node(path: &str, depth: usize, nodes: &mut usize) -> Result<()> { *nodes = nodes .checked_add(1) - .ok_or_else(|| anyhow!("outputs.{name} schema node count overflows"))?; + .ok_or_else(|| anyhow!("{path} schema node count overflows"))?; if depth > MAX_OUTPUT_SCHEMA_DEPTH_V1 { - bail!("outputs.{name} schema exceeds the maximum depth of {MAX_OUTPUT_SCHEMA_DEPTH_V1}"); + bail!("{path} schema exceeds the maximum depth of {MAX_OUTPUT_SCHEMA_DEPTH_V1}"); } if *nodes > MAX_OUTPUT_SCHEMA_NODES_V1 { bail!("outputs schema contains more than {MAX_OUTPUT_SCHEMA_NODES_V1} nodes"); @@ -1158,7 +1202,6 @@ fn record_output_schema_node(name: &str, depth: usize, nodes: &mut usize) -> Res } fn validate_authored_output_schema( - name: &str, path: &str, schema: &AuthoredOutputSchema, depth: usize, @@ -1166,9 +1209,9 @@ fn validate_authored_output_schema( ) -> Result { match schema { AuthoredOutputSchema::Scalar(schema) => { - record_output_schema_node(name, depth, nodes)?; + record_output_schema_node(path, depth, nodes)?; validate_authored_scalar_output( - name, + path, &schema.output_type, schema.format, schema.max_length, @@ -1178,22 +1221,21 @@ fn validate_authored_output_schema( Ok(1) } AuthoredOutputSchema::Object(schema) => { - validate_authored_output_object(name, path, schema, depth, nodes) + validate_authored_output_object(path, schema, depth, nodes) } AuthoredOutputSchema::Array(schema) => { - validate_authored_output_array(name, path, schema, depth, nodes) + validate_authored_output_array(path, schema, depth, nodes) } } } fn validate_authored_output_object( - name: &str, path: &str, object: &AuthoredOutputObjectDeclaration, depth: usize, nodes: &mut usize, ) -> Result { - record_output_schema_node(name, depth, nodes)?; + record_output_schema_node(path, depth, nodes)?; if !(1..=registry_notary_core::MAX_RELAY_OUTPUT_VALUE_BYTES_V1) .contains(&object.max_bytes) { @@ -1215,16 +1257,10 @@ fn validate_authored_output_object( validate_input_name(field_name) .with_context(|| format!("{path}.fields.{field_name}"))?; let child_path = format!("{path}.fields.{field_name}.schema"); - let child = validate_authored_output_schema( - name, - &child_path, - &field.schema, - depth + 1, - nodes, - )?; + let child = validate_authored_output_schema(&child_path, &field.schema, depth + 1, nodes)?; expanded = expanded .checked_add(child) - .ok_or_else(|| anyhow!("outputs.{name} recursive expansion overflows"))?; + .ok_or_else(|| anyhow!("{path} recursive expansion overflows"))?; } let minimum_bytes = minimum_authored_output_object_json_bytes(path, object)?; if u64::from(object.max_bytes) < minimum_bytes { @@ -1236,13 +1272,12 @@ fn validate_authored_output_object( } fn validate_authored_output_array( - name: &str, path: &str, array: &AuthoredOutputArrayDeclaration, depth: usize, nodes: &mut usize, ) -> Result { - record_output_schema_node(name, depth, nodes)?; + record_output_schema_node(path, depth, nodes)?; if !(1..=registry_notary_core::MAX_RELAY_OUTPUT_VALUE_BYTES_V1) .contains(&array.max_bytes) { @@ -1257,13 +1292,8 @@ fn validate_authored_output_array( registry_notary_core::MAX_RELAY_OUTPUT_ARRAY_ITEMS_V1 ); } - let child = validate_authored_output_schema( - name, - &format!("{path}.items"), - &array.items, - depth + 1, - nodes, - )?; + let child = + validate_authored_output_schema(&format!("{path}.items"), &array.items, depth + 1, nodes)?; let minimum_bytes = minimum_authored_output_array_json_bytes(); if u64::from(array.max_bytes) < minimum_bytes { bail!( @@ -1273,7 +1303,7 @@ fn validate_authored_output_array( usize::from(array.max_items) .checked_mul(child) .and_then(|expanded| expanded.checked_add(1)) - .ok_or_else(|| anyhow!("outputs.{name} recursive expansion overflows")) + .ok_or_else(|| anyhow!("{path} recursive expansion overflows")) } fn minimum_authored_output_schema_json_bytes( @@ -1310,10 +1340,10 @@ fn minimum_authored_output_schema_json_bytes( } AuthoredOutputSchema::Object(object) => ( minimum_authored_output_object_json_bytes(path, object)?, - object.nullable, + object.nullable(), ), AuthoredOutputSchema::Array(array) => { - (minimum_authored_output_array_json_bytes(), array.nullable) + (minimum_authored_output_array_json_bytes(), array.nullable()) } }; Ok(if nullable { @@ -1945,16 +1975,13 @@ fn lower_output_map( ) } AuthoredOutputDeclaration::Object(declaration) => { - match declaration.output_type { - AuthoredOutputObjectType::Object => {} - } if require_source { bail!("outputs.{name}: structured outputs require capability.script"); } let schema = lower_authored_output_object(name, declaration)?; ( OutputType::Object, - declaration.nullable, + declaration.nullable(), Some(declaration.max_bytes), None, None, @@ -1963,16 +1990,13 @@ fn lower_output_map( ) } AuthoredOutputDeclaration::Array(declaration) => { - match declaration.output_type { - AuthoredOutputArrayType::Array => {} - } if require_source { bail!("outputs.{name}: structured outputs require capability.script"); } let schema = lower_authored_output_array(name, declaration)?; ( OutputType::Array, - declaration.nullable, + declaration.nullable(), Some(declaration.max_bytes), None, None, @@ -2100,11 +2124,8 @@ fn lower_authored_output_object( name: &str, object: &AuthoredOutputObjectDeclaration, ) -> Result { - match object.output_type { - AuthoredOutputObjectType::Object => {} - } Ok(StructuredOutputSchema::Object { - nullable: object.nullable, + nullable: object.nullable(), max_bytes: object.max_bytes, fields: object .fields @@ -2126,11 +2147,8 @@ fn lower_authored_output_array( name: &str, array: &AuthoredOutputArrayDeclaration, ) -> Result { - match array.output_type { - AuthoredOutputArrayType::Array => {} - } Ok(StructuredOutputSchema::Array { - nullable: array.nullable, + nullable: array.nullable(), max_bytes: array.max_bytes, max_items: array.max_items, items: Box::new(lower_authored_output_schema(name, &array.items)?), diff --git a/crates/registryctl/src/project_authoring/diagnostics.rs b/crates/registryctl/src/project_authoring/diagnostics.rs index 544972cd1..aeba2826d 100644 --- a/crates/registryctl/src/project_authoring/diagnostics.rs +++ b/crates/registryctl/src/project_authoring/diagnostics.rs @@ -364,26 +364,28 @@ fn collect_project_authoring_diagnostics( } let document = match lower_project_integration(&authored, &entities) { Ok(document) => document, - Err(_) => { - diagnostics.push(invalid_diagnostic( + Err(error) => { + diagnostics.push(cross_file_diagnostic( "registryctl.authoring.integration.invalid", &file, None, "The integration declaration is invalid.", "Correct the integration declaration using the authoring schema.", Some(INTEGRATION_SCHEMA_HINT), + authored_output_addresses(&file, &error), )); continue; } }; - if validate_integration(alias, &document).is_err() { - diagnostics.push(invalid_diagnostic( + if let Err(error) = validate_integration(alias, &document) { + diagnostics.push(cross_file_diagnostic( "registryctl.authoring.integration.invalid", &file, None, "The integration declaration is invalid.", "Correct the integration declaration using the authoring schema.", Some(INTEGRATION_SCHEMA_HINT), + authored_output_addresses(&file, &error), )); continue; } @@ -2250,6 +2252,7 @@ fn diagnostic_parse_yaml( return Box::new(path_unsafe(file, None)); } let reserved_fixture_body = error.is_reserved_fixture_body(); + let retired_nullable_key = error.is_retired_nullable_key(); let unknown_field = error.keyword() == Some("additionalProperties"); let syntax = error.is_syntax(); let schema_code = match T::KIND { @@ -2268,7 +2271,7 @@ fn diagnostic_parse_yaml( let mut diagnostic = make_diagnostic( if reserved_fixture_body { "registryctl.authoring.fixture.reserved_body_field" - } else if unknown_field { + } else if retired_nullable_key || unknown_field { "registryctl.authoring.yaml.unknown_field" } else if syntax { "registryctl.authoring.yaml.invalid_syntax" @@ -2280,9 +2283,11 @@ fn diagnostic_parse_yaml( line, column, Some(schema_hint), - None, + retired_nullable_key.then_some(STRUCTURED_OUTPUT_NULLABLE_UNION_SUGGESTION), if reserved_fixture_body { "A fixture body object uses the reserved top-level `file` field without matching the closed file-reference shape." + } else if retired_nullable_key { + "A structured output declares nullability with the removed `nullable` field." } else if unknown_field { "The YAML document contains an unknown field." } else if syntax { @@ -2292,6 +2297,8 @@ fn diagnostic_parse_yaml( }, if reserved_fixture_body { FIXTURE_BODY_FILE_REFERENCE_REMEDIATION + } else if retired_nullable_key { + STRUCTURED_OUTPUT_NULLABLE_UNION_REMEDIATION } else { match kind { "project" => "Correct the project YAML using the project authoring schema. If this project passed with a pre-1.0 Registryctl, create a separate 1.0 project with the `spreadsheet` or `http` template that matches the source, then copy only reviewed authored intent. Registryctl does not migrate or approve the source project.", @@ -2502,6 +2509,40 @@ fn cross_file_diagnostic( diagnostic } +/// Recovers the authored output path that a lowering or semantic failure names. +/// +/// The recursive output validators thread the authored path through their own +/// messages (`outputs.parents.items.fields.identifier.schema`), so a malformed +/// recursive declaration can address its own nested location instead of the +/// whole document. Only a leading token whose every segment matches the +/// authored path grammar is recovered, so no other error text reaches an +/// address, and the rendered diagnostic text stays static either way. +fn authored_output_addresses( + file: &str, + error: &anyhow::Error, +) -> Vec { + for cause in error.chain() { + let message = cause.to_string(); + let Some(candidate) = message.split_whitespace().next() else { + continue; + }; + let segments = candidate.split('.').collect::>(); + if segments.len() < 2 || segments[0] != "outputs" { + continue; + } + if segments.iter().all(|segment| { + let mut characters = segment.chars(); + characters + .next() + .is_some_and(|first| first.is_ascii_alphabetic()) + && characters.all(|rest| rest.is_ascii_alphanumeric() || rest == '_') + }) { + return vec![diagnostic_address(file, &segments)]; + } + } + Vec::new() +} + fn diagnostic_address(file: &str, segments: &[&str]) -> ProjectAuthoringDiagnosticAddress { let mut pointer = String::new(); for segment in segments { @@ -2722,6 +2763,118 @@ services: {} } } + #[test] + fn retired_composite_nullable_key_names_its_path_and_the_union_syntax() { + let document = br#" +version: 1 +id: example-integration +revision: 1 +source: + product: custom + versions: { unverified: [v1] } + auth: { type: none } + allow: [{ method: GET, path: /records, semantics: read_only }] + response: { format: json, max_bytes: 256KiB } +capability: + script: { file: adapter.rhai } +input: + uin: { role: selector, type: string, maxLength: 16 } +outputs: + parents: + type: array + max_bytes: 1024 + max_items: 2 + items: + type: object + nullable: true + max_bytes: 384 + fields: + name: { required: true, schema: { type: string, maxLength: 160 } } +limits: { calls: 1, source_bytes: 512KiB, request_bytes: 32KiB, deadline: 20s } +"#; + let diagnostic = diagnostic_parse_yaml::( + document, + "integrations/example/integration.yaml", + "integration", + INTEGRATION_SCHEMA_HINT, + ) + .expect_err("the retired composite nullable key is rejected"); + + assert_eq!(diagnostic.code, "registryctl.authoring.yaml.unknown_field"); + assert_eq!( + diagnostic.cause, + "A structured output declares nullability with the removed `nullable` field." + ); + assert_eq!( + diagnostic.suggestion, + Some("type: [object, \"null\"] for an object output, or type: [array, \"null\"] for an array output") + ); + assert_eq!( + diagnostic.remediation, + "Remove the `nullable` field and pair the declared form with null in the `type` union, exactly as scalar outputs already do." + ); + assert_eq!( + diagnostic + .addresses + .iter() + .map(|address| address.pointer.as_str()) + .collect::>(), + vec!["/outputs/parents/items/nullable"] + ); + } + + #[test] + fn malformed_recursive_output_reports_its_nested_authored_path() { + let document = br#" +version: 1 +id: example-integration +revision: 1 +source: + product: custom + versions: { unverified: [v1] } + auth: { type: none } + allow: [{ method: GET, path: /records, semantics: read_only }] + response: { format: json, max_bytes: 256KiB } +capability: + script: { file: adapter.rhai } +input: + uin: { role: selector, type: string, maxLength: 16 } +outputs: + parents: + type: array + max_bytes: 1024 + max_items: 2 + items: + type: object + max_bytes: 384 + fields: + identifier: + required: false + schema: { type: string, maxLength: "sixty-four" } +limits: { calls: 1, source_bytes: 512KiB, request_bytes: 32KiB, deadline: 20s } +"#; + let diagnostic = diagnostic_parse_yaml::( + document, + "integrations/example/integration.yaml", + "integration", + INTEGRATION_SCHEMA_HINT, + ) + .expect_err("a malformed nested output schema is rejected"); + + assert_eq!( + diagnostic.code, + "registryctl.authoring.integration.invalid" + ); + assert_eq!( + diagnostic + .addresses + .iter() + .map(|address| address.pointer.as_str()) + .collect::>(), + vec!["/outputs/parents/items/fields/identifier/schema/maxLength"] + ); + } + #[test] fn dynamic_relationship_address_escapes_each_rfc6901_segment() { assert_eq!( diff --git a/crates/registryctl/src/project_authoring/documentation.rs b/crates/registryctl/src/project_authoring/documentation.rs index e9b46c8f8..a88a91093 100644 --- a/crates/registryctl/src/project_authoring/documentation.rs +++ b/crates/registryctl/src/project_authoring/documentation.rs @@ -2855,7 +2855,7 @@ mod tests { .expect("embedded reference coverage is readable"); assert!(!coverage.source_contract.reads_country_workspaces); assert!(!coverage.source_contract.reads_runtime_configuration); - assert_eq!(coverage.coverage.path_count, 702); + assert_eq!(coverage.coverage.path_count, 708); } #[test] diff --git a/crates/registryctl/src/project_authoring/project.rs b/crates/registryctl/src/project_authoring/project.rs index 3f3082b5e..092e3fda5 100644 --- a/crates/registryctl/src/project_authoring/project.rs +++ b/crates/registryctl/src/project_authoring/project.rs @@ -889,7 +889,7 @@ fn semantic_digests( // A schema or knowledge change must therefore be reviewed for promotion // semantics before a new projection can be emitted. const PROMOTION_FIELD_KNOWLEDGE_REVISION: &str = - "sha256:537dde0f120d9874e74cae1d899d7e4d86ad013a5d1b918021a73e1045f951b1"; + "sha256:48143e77caf603c743f0f80e4a2215dff5f4e7e17053a38de401d9f438ccdbd4"; fn project_promotion_projection( loaded: &LoadedRegistryProject, diff --git a/crates/registryctl/src/project_authoring/promotion_projection.rs b/crates/registryctl/src/project_authoring/promotion_projection.rs index 8d71dad58..82afe158d 100644 --- a/crates/registryctl/src/project_authoring/promotion_projection.rs +++ b/crates/registryctl/src/project_authoring/promotion_projection.rs @@ -321,7 +321,7 @@ mod tests { assert_eq!(revision, PROMOTION_FIELD_KNOWLEDGE_REVISION); let index = knowledge::published_field_knowledge_index().expect("knowledge indexes"); - assert_eq!(index.by_path().len(), 702); + assert_eq!(index.by_path().len(), 708); let mapped = index .by_path() .keys() diff --git a/crates/registryctl/src/project_authoring/schema_authority.rs b/crates/registryctl/src/project_authoring/schema_authority.rs index f7ee8f65b..5fa7a9bd2 100644 --- a/crates/registryctl/src/project_authoring/schema_authority.rs +++ b/crates/registryctl/src/project_authoring/schema_authority.rs @@ -22,6 +22,7 @@ enum AuthoringDocumentError { schema_path: String, keyword: &'static str, reserved_fixture_body: bool, + retired_nullable_key: bool, unsafe_authored_path: bool, line: Option, column: Option, @@ -82,6 +83,16 @@ impl AuthoringDocumentError { ) } + const fn is_retired_nullable_key(&self) -> bool { + matches!( + self, + Self::Schema { + retired_nullable_key: true, + .. + } + ) + } + const fn is_unsafe_authored_path(&self) -> bool { matches!( self, @@ -113,6 +124,17 @@ impl fmt::Display for AuthoringDocumentError { )?; write_safe_location(formatter, self) } + Self::Schema { + retired_nullable_key: true, + .. + } => { + write!( + formatter, + "structured output nullability must use the type union instead of the \ + removed `nullable` field" + )?; + write_safe_location(formatter, self) + } Self::Schema { schema_path, keyword: "additionalProperties", @@ -351,6 +373,7 @@ fn schema_validation_error( document: &Value, error: jsonschema::ValidationError<'_>, instance_path: String, + retired_nullable_key: bool, ) -> AuthoringDocumentError { let schema_path = error.schema_path.to_string(); let unsafe_authored_path = is_unsafe_authored_path_constraint(kind, &schema_path); @@ -361,6 +384,7 @@ fn schema_validation_error( schema_path, keyword: validation_keyword(&error.kind), reserved_fixture_body, + retired_nullable_key, unsafe_authored_path, line: None, column: None, @@ -482,6 +506,140 @@ fn project_service_validation_instance_path(document: &Value) -> Option None } +/// Where a structured integration output failed, recovered from the collapsed +/// `#/$defs/output` union. +struct OutputValidationLocation { + instance_path: String, + retired_nullable_key: bool, +} + +/// Compiles one `$defs` branch of a published schema as a standalone validator. +fn definition_branch_validator( + definitions: &Value, + branch: &str, +) -> Option { + let mut branch_schema = definitions.get(branch)?.clone(); + let branch_object = branch_schema.as_object_mut()?; + branch_object.insert( + "$schema".to_string(), + Value::String("https://json-schema.org/draft/2020-12/schema".to_string()), + ); + branch_object.insert("$defs".to_string(), definitions.clone()); + jsonschema::JSONSchema::options() + .with_draft(jsonschema::Draft::Draft202012) + .compile(&branch_schema) + .ok() +} + +/// Selects the output branch an author intended from the `type` discriminator. +/// +/// Both the single form and the `[, "null"]` union select the same +/// branch, so a malformed nullable declaration is still reported against the +/// structured branch rather than collapsing to the scalar one. +fn output_declaration_branch<'a>(declaration: &Value, scalar_branch: &'a str) -> &'a str { + let discriminator = match declaration.get("type") { + Some(Value::String(name)) => Some(name.as_str()), + Some(Value::Array(members)) => members.first().and_then(Value::as_str), + _ => None, + }; + match discriminator { + Some("object") => "outputObject", + Some("array") => "outputArray", + _ => scalar_branch, + } +} + +/// Returns the deepest failing location inside one authored output declaration, +/// relative to that declaration, or `None` when the declaration is valid. +fn output_declaration_location( + declaration: &Value, + definitions: &Value, + scalar_branch: &str, +) -> Option { + let branch = output_declaration_branch(declaration, scalar_branch); + let validator = definition_branch_validator(definitions, branch)?; + if validator.is_valid(declaration) { + return None; + } + if let Some(nested) = nested_output_declaration_location(declaration, definitions) { + return Some(nested); + } + if branch != scalar_branch && declaration.get("nullable").is_some() { + return Some(OutputValidationLocation { + instance_path: "/nullable".to_string(), + retired_nullable_key: true, + }); + } + Some(OutputValidationLocation { + instance_path: most_specific_validation_instance_path(&validator, declaration) + .unwrap_or_default(), + retired_nullable_key: false, + }) +} + +/// Descends one level into the recursive object-field and array-item schemas. +fn nested_output_declaration_location( + declaration: &Value, + definitions: &Value, +) -> Option { + if let Some(fields) = declaration.get("fields").and_then(Value::as_object) { + for (field_name, field) in fields { + let Some(schema) = field.get("schema") else { + continue; + }; + if let Some(nested) = + output_declaration_location(schema, definitions, "scalarOutputSchema") + { + return Some(OutputValidationLocation { + instance_path: format!( + "/fields/{}/schema{}", + escape_json_pointer_segment(field_name), + nested.instance_path + ), + retired_nullable_key: nested.retired_nullable_key, + }); + } + } + } + let items = declaration.get("items")?; + let nested = output_declaration_location(items, definitions, "scalarOutputSchema")?; + Some(OutputValidationLocation { + instance_path: format!("/items{}", nested.instance_path), + retired_nullable_key: nested.retired_nullable_key, + }) +} + +/// Recovers the authored path a collapsed `outputs` union hides. +/// +/// The published `outputs` map and every nested structured schema are closed +/// unions, so `jsonschema` reports only the outermost `oneOf` failure. This +/// re-validates against the branch the author's own `type` discriminator +/// selects, which restores a path such as +/// `/outputs/parents/items/fields/identifier/schema`. +fn integration_output_validation_instance_path( + document: &Value, +) -> Option { + let outputs = document.get("outputs")?.as_object()?; + let root_schema: Value = + serde_json::from_str(ProjectSchemaKind::Integration.document()).ok()?; + let definitions = root_schema.get("$defs")?.clone(); + for (name, declaration) in outputs { + let Some(location) = output_declaration_location(declaration, &definitions, "scalarOutput") + else { + continue; + }; + return Some(OutputValidationLocation { + instance_path: format!( + "/outputs/{}{}", + escape_json_pointer_segment(name), + location.instance_path + ), + retired_nullable_key: location.retired_nullable_key, + }); + } + None +} + fn parse_authoring_value( bytes: &[u8], kind: ProjectSchemaKind, @@ -503,21 +661,39 @@ fn parse_authoring_value( schema_path: String::new(), keyword: "schema", reserved_fixture_body: false, + retired_nullable_key: false, unsafe_authored_path: false, line: None, column: None, })?; if let Err(mut errors) = validator.validate(&value) { let error = errors.next().expect("schema validation returned an error"); - let collapsed_project_union = kind == ProjectSchemaKind::Project - && matches!(&error.kind, ValidationErrorKind::OneOfNotValid); - let instance_path = if collapsed_project_union { + let collapsed_union = matches!(&error.kind, ValidationErrorKind::OneOfNotValid); + let reported_path = error.instance_path.to_string(); + let collapsed_output_union = kind == ProjectSchemaKind::Integration + && collapsed_union + && (reported_path == "/outputs" || reported_path.starts_with("/outputs/")); + let output_location = + collapsed_output_union.then(|| integration_output_validation_instance_path(&value)); + let retired_nullable_key = output_location + .as_ref() + .and_then(Option::as_ref) + .is_some_and(|location| location.retired_nullable_key); + let instance_path = if kind == ProjectSchemaKind::Project && collapsed_union { project_service_validation_instance_path(&value) } else { - None - } - .unwrap_or_else(|| error.instance_path.to_string()); - return Err(schema_validation_error(kind, &value, error, instance_path)); + output_location + .flatten() + .map(|location| location.instance_path) + } + .unwrap_or(reported_path); + return Err(schema_validation_error( + kind, + &value, + error, + instance_path, + retired_nullable_key, + )); } Ok(value) } @@ -578,6 +754,7 @@ fn assert_current_authoring_value_reaches_typed_model( schema_path: String::new(), keyword: "schema", reserved_fixture_body: false, + retired_nullable_key: false, unsafe_authored_path: false, line: None, column: None, @@ -586,7 +763,7 @@ fn assert_current_authoring_value_reaches_typed_model( .map_err(|mut errors| { let error = errors.next().expect("schema validation returned an error"); let instance_path = error.instance_path.to_string(); - schema_validation_error(kind, &value, error, instance_path) + schema_validation_error(kind, &value, error, instance_path, false) })?; match kind { ProjectSchemaKind::Project => { diff --git a/crates/registryctl/src/project_authoring/tests.rs b/crates/registryctl/src/project_authoring/tests.rs index 647e7afd5..feeb5fb86 100644 --- a/crates/registryctl/src/project_authoring/tests.rs +++ b/crates/registryctl/src/project_authoring/tests.rs @@ -289,7 +289,6 @@ maximum: 9007199254740991 fn integer_integration_outputs_enforce_json_safe_bounds_recursively() { let safe: AuthoredOutputDeclaration = serde_norway::from_str( r#"type: object -nullable: false max_bytes: 1024 fields: direct: @@ -302,7 +301,6 @@ fields: required: true schema: type: array - nullable: false max_bytes: 512 max_items: 2 items: @@ -320,7 +318,6 @@ fields: ( "nested object lower bound", r#"type: object -nullable: false max_bytes: 256 fields: sequence: @@ -334,7 +331,6 @@ fields: ( "nested array upper bound", r#"type: array -nullable: false max_bytes: 256 max_items: 2 items: @@ -360,12 +356,10 @@ items: #[test] fn structured_script_output_lowers_recursively_with_closed_bounded_fields() { let authored = r#"type: array -nullable: false max_bytes: 1024 max_items: 2 items: type: object - nullable: false max_bytes: 384 fields: type: @@ -437,6 +431,172 @@ items: .contains("require capability.script")); } + #[test] + fn structured_output_nullability_uses_the_one_scalar_type_union_idiom() { + fn parse(source: &str) -> AuthoredOutputDeclaration { + serde_norway::from_str(source).expect("structured output parses") + } + + fn lower(name: &str, output: AuthoredOutputDeclaration) -> OutputDeclaration { + let mut nodes = OUTPUT_SCHEMA_ENVELOPE_NODES_V1; + validate_authored_output(name, &output, &mut nodes) + .expect("union-typed structured output validates"); + lower_output_map( + &BTreeMap::from([(name.to_string(), output)]), + "birth", + false, + ) + .expect("union-typed structured output lowers") + .remove(name) + .expect("the lowered output is present") + } + + let nullable_object = lower( + "record", + parse( + r#"type: [object, "null"] +max_bytes: 64 +fields: + active: + required: true + schema: { type: boolean } +"#, + ), + ); + assert_eq!(nullable_object.output_type, OutputType::Object); + assert!(nullable_object.nullable); + assert!(matches!( + nullable_object.structured_schema, + Some(StructuredOutputSchema::Object { + nullable: true, + .. + }) + )); + + let required_object = lower( + "record", + parse( + r#"type: object +max_bytes: 64 +fields: + active: + required: true + schema: { type: boolean } +"#, + ), + ); + assert!(!required_object.nullable); + assert!(matches!( + required_object.structured_schema, + Some(StructuredOutputSchema::Object { + nullable: false, + .. + }) + )); + + let nullable_array = lower( + "records", + parse( + r#"type: [array, "null"] +max_bytes: 64 +max_items: 2 +items: { type: boolean } +"#, + ), + ); + assert_eq!(nullable_array.output_type, OutputType::Array); + assert!(nullable_array.nullable); + assert!(matches!( + nullable_array.structured_schema, + Some(StructuredOutputSchema::Array { + nullable: true, + .. + }) + )); + + let required_array = lower( + "records", + parse( + r#"type: array +max_bytes: 64 +max_items: 2 +items: { type: boolean } +"#, + ), + ); + assert!(!required_array.nullable); + + let nested = parse( + r#"type: [array, "null"] +max_bytes: 512 +max_items: 2 +items: + type: [object, "null"] + max_bytes: 128 + fields: + identifier: + required: false + schema: { type: [string, "null"], maxLength: 16 } +"#, + ); + let mut nodes = OUTPUT_SCHEMA_ENVELOPE_NODES_V1; + validate_authored_output("parents", &nested, &mut nodes) + .expect("a nested union-typed structured output validates"); + + for retired in [ + concat!( + "type: object\n", + "nullable: true\n", + "max_bytes: 64\n", + "fields:\n", + " active:\n", + " required: true\n", + " schema: { type: boolean }\n" + ), + concat!( + "type: array\n", + "nullable: false\n", + "max_bytes: 64\n", + "max_items: 2\n", + "items: { type: boolean }\n" + ), + ] { + assert!( + serde_norway::from_str::(retired).is_err(), + "the retired composite `nullable` key must not parse: {retired}" + ); + } + + for null_only in [ + r#"type: ["null"] +max_bytes: 64 +fields: + active: + required: true + schema: { type: boolean } +"#, + r#"type: ["null", object] +max_bytes: 64 +fields: + active: + required: true + schema: { type: boolean } +"#, + r#"type: [array, "null"] +max_bytes: 64 +fields: + active: + required: true + schema: { type: boolean } +"#, + ] { + assert!( + serde_norway::from_str::(null_only).is_err(), + "only `[, \"null\"]` is an authored union: {null_only}" + ); + } + } + #[test] fn authored_output_count_preserves_the_generic_non_notary_limit() { fn boolean_output() -> AuthoredOutputDeclaration { @@ -533,7 +693,6 @@ items: let required_boolean = |max_bytes| { format!( r#"type: object -nullable: false max_bytes: {max_bytes} fields: active: @@ -552,7 +711,6 @@ fields: let array = |max_bytes| { format!( r#"type: array -nullable: false max_bytes: {max_bytes} max_items: 1 items: {{ type: boolean }} @@ -566,14 +724,12 @@ items: {{ type: boolean }} validate(&array(2)).expect("the empty-array encoding bound validates"); let nested = r#"type: object -nullable: false max_bytes: 64 fields: child: required: true schema: type: object - nullable: false max_bytes: 1 fields: active: @@ -611,8 +767,9 @@ fields: fn object_declaration(field_count: usize) -> AuthoredOutputObjectDeclaration { AuthoredOutputObjectDeclaration { - output_type: AuthoredOutputObjectType::Object, - nullable: false, + output_type: AuthoredObjectSchemaType::Single( + AuthoredOutputObjectType::Object, + ), max_bytes: 65_536, fields: (0..field_count) .map(|index| { @@ -637,16 +794,18 @@ fields: let mut items = boolean_schema(); for _ in 1..array_nodes { items = AuthoredOutputSchema::Array(AuthoredOutputArrayDeclaration { - output_type: AuthoredOutputArrayType::Array, - nullable: false, + output_type: AuthoredArraySchemaType::Single( + AuthoredOutputArrayType::Array, + ), max_bytes: 65_536, max_items: 1, items: Box::new(items), }); } AuthoredOutputDeclaration::Array(AuthoredOutputArrayDeclaration { - output_type: AuthoredOutputArrayType::Array, - nullable: false, + output_type: AuthoredArraySchemaType::Single( + AuthoredOutputArrayType::Array, + ), max_bytes: 65_536, max_items: 1, items: Box::new(items), @@ -657,10 +816,13 @@ fields: validate_authored_outputs(&maximum_depth) .expect("five array nodes plus one leaf fit downstream depth eight"); let excessive_depth = BTreeMap::from([("nested".to_string(), array_output(6))]); - assert!(validate_authored_outputs(&excessive_depth) - .expect_err("one more nested node exceeds downstream depth eight") - .to_string() - .contains("maximum depth of 8")); + assert_eq!( + validate_authored_outputs(&excessive_depth) + .expect_err("one more nested node exceeds downstream depth eight") + .to_string(), + "outputs.nested.items.items.items.items.items.items schema exceeds the maximum depth of 8", + "a recursive depth rejection must name the nested authored path, not just the output" + ); let node_budget = |extra_scalars| { let mut outputs = (0..7) @@ -682,8 +844,9 @@ fields: BTreeMap::from([( "expanded".to_string(), AuthoredOutputDeclaration::Array(AuthoredOutputArrayDeclaration { - output_type: AuthoredOutputArrayType::Array, - nullable: false, + output_type: AuthoredArraySchemaType::Single( + AuthoredOutputArrayType::Array, + ), max_bytes: 65_536, max_items: 255, items: Box::new(AuthoredOutputSchema::Object(object_declaration(field_count))), diff --git a/crates/registryctl/tests/fixtures/project-authoring/opencrvs/integrations/birth-record/integration.yaml b/crates/registryctl/tests/fixtures/project-authoring/opencrvs/integrations/birth-record/integration.yaml index 4332904e3..5a4762b63 100644 --- a/crates/registryctl/tests/fixtures/project-authoring/opencrvs/integrations/birth-record/integration.yaml +++ b/crates/registryctl/tests/fixtures/project-authoring/opencrvs/integrations/birth-record/integration.yaml @@ -48,12 +48,10 @@ outputs: place_of_birth: { type: [string, "null"], maxLength: 120 } parents: type: array - nullable: false max_bytes: 1024 max_items: 2 items: type: object - nullable: false max_bytes: 384 fields: type: diff --git a/crates/registryctl/tests/fixtures/project-authoring/opencrvs/registry-stack.yaml b/crates/registryctl/tests/fixtures/project-authoring/opencrvs/registry-stack.yaml index 6128f2ce6..6f3fecdf1 100644 --- a/crates/registryctl/tests/fixtures/project-authoring/opencrvs/registry-stack.yaml +++ b/crates/registryctl/tests/fixtures/project-authoring/opencrvs/registry-stack.yaml @@ -2,7 +2,7 @@ version: 1 starter: id: opencrvs-dci release: 0.16.0 - content_digest: sha256:20d38c1e44624cde34740619246b7c1d198f3aba156ffbdfdc64cae9949f914b + content_digest: sha256:47f7df25e50880fdff3e6a848ae4d4f061de0be6e6d0a3d3d4da808df13d342c registry: { id: fictional-civil-registry } integrations: birth-record: { file: integrations/birth-record/integration.yaml } diff --git a/crates/registryctl/tests/project_authoring.rs b/crates/registryctl/tests/project_authoring.rs index ef7496925..448f193ce 100644 --- a/crates/registryctl/tests/project_authoring.rs +++ b/crates/registryctl/tests/project_authoring.rs @@ -6181,7 +6181,7 @@ fn check_and_build_produce_deterministic_product_inputs() { assert_eq!(first_closure, directory_closure(&output)); assert_eq!( closure_digest(&first_closure), - "5db7283ed355add4e3942cccfc279d9f2cb16324d7c40455d5445b8a2ef75f2d", + "c77952eb0c76fbda06254690ee4ebcc7597b8f881a8d5c62a32cbac7dc938b6f", "project output, including its deterministic manifest, must match the cross-machine golden digest" ); } diff --git a/crates/registryctl/tests/project_authoring_schema_parity.rs b/crates/registryctl/tests/project_authoring_schema_parity.rs index 4b72b1a53..771073d54 100644 --- a/crates/registryctl/tests/project_authoring_schema_parity.rs +++ b/crates/registryctl/tests/project_authoring_schema_parity.rs @@ -3,13 +3,21 @@ use std::collections::{BTreeMap, BTreeSet}; use std::path::{Path, PathBuf}; +use registry_notary_core::{ + ClaimEvidenceMode, RelayOutputContract, StandaloneRegistryNotaryConfig, + MAX_RELAY_OUTPUT_EXPANDED_NODES_V1, +}; +use registry_relay::rhai_worker::{ + OutputSchema, TypedValue, WorkerError, WorkerLimits, WorkerOutcome, WorkerOutput, + WorkerProcess, WorkerRequest, +}; use registryctl::ProjectSchemaKind; use registryctl::{ - check_registry_project_with_context, ProjectAuthoringDiagnostics, ProjectCheckOptions, - ProjectExecutionContext, + build_registry_project_with_context, check_registry_project_with_context, + ProjectAuthoringDiagnostics, ProjectBuildOptions, ProjectCheckOptions, ProjectExecutionContext, }; use serde::Deserialize; -use serde_json::Value; +use serde_json::{json, Value}; #[path = "../src/project_authoring/knowledge.rs"] mod field_knowledge; @@ -249,7 +257,7 @@ fn published_field_knowledge_is_complete_typed_reachable_and_editor_exact() { [ (SchemaKind::Project, 220), (SchemaKind::Environment, 213), - (SchemaKind::Integration, 171), + (SchemaKind::Integration, 177), (SchemaKind::Fixture, 63), (SchemaKind::Entity, 35), ] @@ -261,11 +269,11 @@ fn published_field_knowledge_is_complete_typed_reachable_and_editor_exact() { index.coverage_by_path_kind(), [ (FieldPathKind::Root, 5), - (FieldPathKind::Property, 492), + (FieldPathKind::Property, 490), (FieldPathKind::MapKey, 26), (FieldPathKind::MapValue, 33), - (FieldPathKind::ArrayItem, 34), - (FieldPathKind::Branch, 112), + (FieldPathKind::ArrayItem, 38), + (FieldPathKind::Branch, 116), ] .into_iter() .collect(), @@ -275,11 +283,11 @@ fn published_field_knowledge_is_complete_typed_reachable_and_editor_exact() { index.coverage_by_sensitivity(), [ (Sensitivity::Public, 6), - (Sensitivity::Internal, 445), + (Sensitivity::Internal, 447), (Sensitivity::Sensitive, 69), (Sensitivity::SecretReference, 14), (Sensitivity::RedactedFixture, 51), - (Sensitivity::Structural, 117), + (Sensitivity::Structural, 121), ] .into_iter() .collect(), @@ -287,12 +295,12 @@ fn published_field_knowledge_is_complete_typed_reachable_and_editor_exact() { ); assert_eq!( index.by_path().len(), - 702, + 708, "the field-knowledge gate covers every published schema path" ); assert_eq!( index.references().len(), - 279, + 281, "every published local reference remains resolved in the deterministic reference index" ); assert_eq!( @@ -817,28 +825,28 @@ fn exact_published_structural_contract_inventory_is_release_gated() { ( "integration", PublishedStructuralInventory { - nodes: 200, - local_refs: 46, - union_nodes: 12, - union_branches: 29, + nodes: 208, + local_refs: 48, + union_nodes: 14, + union_branches: 33, conditionals: 1, objects: 38, closed_objects: 31, typed_maps: 7, open_maps: 0, - arrays: 9, - scalar_types: 59, + arrays: 11, + scalar_types: 57, nullable_nodes: 0, integer_lower_bounds: 22, integer_upper_bounds: 22, string_length_bounds: 14, string_patterns: 20, - array_size_bounds: 9, + array_size_bounds: 11, unique_arrays: 8, object_size_bounds: 9, property_name_constraints: 4, enums: 11, - consts: 17, + consts: 21, defaults: 3, deprecations: 0, }, @@ -1540,3 +1548,959 @@ fn representative_mutations_fail_schema_and_runtime() { "each maintained mutation must name the exact schema keywords observed to fail" ); } + +// --------------------------------------------------------------------------- +// Boundary parity: one authored structured output, three product boundaries. +// +// Registryctl compiles an authored `outputs` declaration into the public Relay +// consultation contract and into the Notary evidence configuration. The two +// runtime products then read that declaration through independent Rust types +// (`registry_relay::rhai_worker::OutputSchema` and +// `registry_notary_core::RelayOutputContract`). The tests below pin the shared +// wire shape, the shared value verdicts, and the exact places where the two +// platform bounds deliberately differ. +// --------------------------------------------------------------------------- + +const OPENCRVS_FIXTURE: &str = "crates/registryctl/tests/fixtures/project-authoring/opencrvs"; +const OPENCRVS_INTEGRATION: &str = "integrations/birth-record/integration.yaml"; +const RELAY_CONSULTATION_CONTRACT: &str = "private/relay-consultation/config/artifacts/consultation-contracts/birth-verification-birth.json"; +const NOTARY_CONFIG: &str = "private/notary/config/notary.yaml"; +/// The claim whose authored output is the structured array of objects. +const STRUCTURED_OUTPUT: &str = "parents"; +/// The synthesized output name used to drive both product boundaries. +const PROBE_OUTPUT: &str = "probe"; + +/// Reviewed echo program: whatever the host supplies as `probe` is returned as +/// the `probe` output, so the worker validates a real value against the +/// compiler-produced declaration instead of against a literal. +const ECHO_PROGRAM: &str = "fn consult(ctx) { result.match(#{ probe: ctx.input.probe }) }"; + +/// Reviewed program that produces no outputs, so a worker verdict reports only +/// whether the declared output schema itself was accepted. +const NO_OUTPUT_PROGRAM: &str = "fn consult(ctx) { result.no_match() }"; + +/// The two product views of one authored `outputs` block. +struct BoundaryOutputs { + /// `spec.output` from the generated Relay consultation contract. + relay: BTreeMap, + /// The generated Notary consultation outputs, re-serialized from the + /// production `RelayOutputContract` model rather than from raw YAML. + notary: BTreeMap, + /// The generated Notary configuration as plain data, so a parity case can + /// splice one probe declaration into it and revalidate. + notary_document: Value, +} + +fn build_opencrvs_outputs(edit: impl FnOnce(&mut Value)) -> BoundaryOutputs { + let temporary = tempfile::tempdir().expect("temporary directory creates"); + let project = temporary.path().join("project"); + copy_tree(&repository_root().join(OPENCRVS_FIXTURE), &project); + let integration_path = project.join(OPENCRVS_INTEGRATION); + let mut integration = read_yaml_json(&integration_path); + edit(&mut integration); + std::fs::write( + &integration_path, + serde_norway::to_string(&integration).expect("integration document serializes as YAML"), + ) + .expect("integration document writes"); + + let context = ProjectExecutionContext::new(env!("CARGO_BIN_EXE_registryctl")) + .expect("Cargo provides the real registryctl executable"); + let report = build_registry_project_with_context( + &ProjectBuildOptions { + project_directory: project.clone(), + environment: "local".to_string(), + against: None, + anchor: None, + }, + &context, + ) + .expect("the opencrvs project builds"); + let output = project.join(report.output.expect("build reports an output directory")); + + let contract: Value = serde_json::from_slice( + &std::fs::read(output.join(RELAY_CONSULTATION_CONTRACT)) + .expect("Relay consultation contract reads"), + ) + .expect("Relay consultation contract parses"); + let relay = contract["spec"]["output"] + .as_object() + .expect("the Relay contract declares an output map") + .iter() + .map(|(name, declaration)| (name.clone(), declaration.clone())) + .collect::>(); + + let notary_path = output.join(NOTARY_CONFIG); + let notary_config: StandaloneRegistryNotaryConfig = + serde_norway::from_slice(&std::fs::read(¬ary_path).expect("Notary config reads")) + .expect("the generated Notary config parses through its production model"); + notary_config + .validate() + .expect("the generated Notary config passes its own platform validation"); + let notary = structured_consultation_outputs(¬ary_config) + .iter() + .map(|(name, contract)| { + ( + name.clone(), + serde_json::to_value(contract).expect("a Notary output contract serializes"), + ) + }) + .collect::>(); + + BoundaryOutputs { + relay, + notary, + notary_document: read_yaml_json(¬ary_path), + } +} + +fn structured_consultation_outputs( + config: &StandaloneRegistryNotaryConfig, +) -> &BTreeMap { + let claim = config + .evidence + .claims + .iter() + .find(|claim| claim.id == STRUCTURED_OUTPUT) + .expect("the structured-output claim is generated"); + let ClaimEvidenceMode::RegistryBacked { consultations } = &claim.evidence_mode else { + panic!("the structured-output claim remains registry backed"); + }; + &consultations + .values() + .next() + .expect("the structured-output claim has one consultation") + .outputs +} + +/// Aligns the worker string ceiling with the Notary platform ceiling so a +/// rejection can only come from the declaration, never from a narrower +/// per-deployment budget. +fn boundary_worker_limits() -> WorkerLimits { + WorkerLimits { + max_string_bytes: 64 * 1024, + max_call_levels: 16, + max_expr_depth: 16, + ..WorkerLimits::default() + } +} + +fn relay_verdict(request: &WorkerRequest) -> bool { + let worker = WorkerProcess::with_program(env!("CARGO_BIN_EXE_registryctl")); + let runtime = tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .expect("test runtime builds"); + match runtime.block_on(worker.evaluate(request)) { + Ok(WorkerOutput::Success { outcome, .. }) => { + assert_ne!( + outcome, + WorkerOutcome::Ambiguous, + "the reviewed parity program is never ambiguous" + ); + true + } + Ok(WorkerOutput::Failure { failure }) => { + panic!("the reviewed parity program never fails: {failure:?}") + } + Err(WorkerError::ContractViolation) => false, + Err(error) => panic!("the Relay worker did not reach a contract verdict: {error}"), + } +} + +/// Wraps a probe value in the worker's typed input envelope using the declared +/// output type, so a null probe still crosses the boundary with its type. +fn typed_probe(declaration: &Value, value: &Value) -> TypedValue { + match declaration["type"] + .as_str() + .expect("every output declaration names one type") + { + "string" => TypedValue::String { + value: value.as_str().map(str::to_owned), + }, + "date" => TypedValue::Date { + value: value.as_str().map(str::to_owned), + }, + "boolean" => TypedValue::Boolean { + value: value.as_bool(), + }, + "integer" => TypedValue::Integer { + value: value.as_i64(), + }, + "object" => TypedValue::Object { + value: (!value.is_null()).then(|| value.clone()), + }, + "array" => TypedValue::Array { + value: (!value.is_null()).then(|| value.clone()), + }, + other => panic!("unknown declared output type: {other}"), + } +} + +fn relay_accepts_value(declaration: &Value, value: &Value) -> bool { + let schema: OutputSchema = serde_json::from_value(declaration.clone()) + .expect("the declaration decodes into the Relay worker output contract"); + let mut request = WorkerRequest::v1(ECHO_PROGRAM, "consult", boundary_worker_limits()); + request.input = BTreeMap::from([(PROBE_OUTPUT.to_string(), typed_probe(declaration, value))]); + request.output_schema = BTreeMap::from([(PROBE_OUTPUT.to_string(), schema)]); + relay_verdict(&request) +} + +fn notary_accepts_value(declaration: &Value, value: &Value) -> bool { + let contract: RelayOutputContract = serde_json::from_value(declaration.clone()) + .expect("the declaration decodes into the Notary Relay output contract"); + contract.validates_value(value) +} + +fn relay_accepts_declaration(declaration: &Value) -> bool { + let Ok(schema) = serde_json::from_value::(declaration.clone()) else { + return false; + }; + let mut request = WorkerRequest::v1(NO_OUTPUT_PROGRAM, "consult", boundary_worker_limits()); + request.output_schema = BTreeMap::from([(PROBE_OUTPUT.to_string(), schema)]); + relay_verdict(&request) +} + +/// Splices one probe output into every generated consultation and revalidates +/// the whole Notary configuration, which is the only public path to the +/// platform output-schema bounds. +fn notary_accepts_declaration(document: &Value, declaration: &Value) -> bool { + let mut document = document.clone(); + for claim in document["evidence"]["claims"] + .as_array_mut() + .expect("the generated Notary config declares claims") + { + for consultation in claim["evidence_mode"]["consultations"] + .as_object_mut() + .expect("every generated claim is registry backed") + .values_mut() + { + consultation["outputs"] + .as_object_mut() + .expect("every generated consultation declares outputs") + .insert(PROBE_OUTPUT.to_string(), declaration.clone()); + } + } + let yaml = serde_norway::to_string(&document).expect("the Notary config serializes as YAML"); + serde_norway::from_str::(&yaml) + .is_ok_and(|config| config.validate().is_ok()) +} + +/// Reports whether the Registryctl authoring stage rejects an authored output. +/// +/// The maintained adapter script never produces an extra output, so a project +/// carrying one always fails somewhere; the authoring verdict is which stage +/// fails. An accepted declaration reaches fixture execution, and a rejected one +/// stops at authoring with a diagnostic that names the offending output path. +fn authoring_rejects_output(name: &str, declaration: &Value) -> bool { + let error = check_authored_output(name, declaration) + .expect_err("an extra authored output never reaches a clean check"); + if let Some(report) = error.downcast_ref::() { + let pointer = format!("/outputs/{name}"); + assert!( + report.diagnostics.iter().any(|diagnostic| { + diagnostic.code == "registryctl.authoring.integration.invalid" + && diagnostic + .addresses + .iter() + .any(|address| address.pointer.starts_with(&pointer)) + }), + "an authoring rejection must name the offending output path: {error:#} PROBE {:?}", + report + .diagnostics + .iter() + .flat_map(|diagnostic| diagnostic.addresses.iter()) + .map(|address| address.pointer.clone()) + .collect::>() + ); + return true; + } + assert!( + format!("{error:#}").contains("project integration fixtures failed"), + "an authoring acceptance must reach fixture execution: {error:#}" + ); + false +} + +/// Runs the production check path over an authored project that declares one +/// extra structured output. +fn check_authored_output(name: &str, declaration: &Value) -> anyhow::Result<()> { + let temporary = tempfile::tempdir().expect("temporary directory creates"); + let project = temporary.path().join("project"); + copy_tree(&repository_root().join(OPENCRVS_FIXTURE), &project); + let integration_path = project.join(OPENCRVS_INTEGRATION); + let mut integration = read_yaml_json(&integration_path); + integration["outputs"] + .as_object_mut() + .expect("the maintained integration declares outputs") + .insert(name.to_string(), declaration.clone()); + std::fs::write( + &integration_path, + serde_norway::to_string(&integration).expect("integration document serializes as YAML"), + ) + .expect("integration document writes"); + check_registry_project(&ProjectCheckOptions { + project_directory: project, + environment: "local".to_string(), + explain: false, + against: None, + anchor: None, + }) + .map(|_| ()) +} + +/// A chain of `nodes` schema nodes: `nodes - 1` nested arrays around a boolean. +fn array_layers(nodes: usize) -> Value { + assert!(nodes > 0); + let mut schema = json!({ "type": "boolean", "nullable": false }); + for _ in 1..nodes { + schema = json!({ + "type": "array", + "nullable": false, + "max_bytes": 65_536, + "max_items": 1, + "items": schema, + }); + } + schema +} + +/// The fixed nodes the Notary decoder reserves for the Relay result envelope +/// before it reads any consultation output. +const RELAY_RESULT_ENVELOPE_NODES: usize = 20; + +/// The shared expansion formula both products implement: a scalar expands to +/// itself, an object to itself plus its fields, and an array to its item +/// expansion repeated `max_items` times plus itself. +fn expanded_nodes(declaration: &Value) -> usize { + match declaration["type"] + .as_str() + .expect("every declaration names one type") + { + "object" => declaration["fields"] + .as_object() + .expect("an object declaration carries fields") + .values() + .map(|field| expanded_nodes(&field["schema"])) + .sum::() + .checked_add(1) + .expect("the expansion fits"), + "array" => expanded_nodes(&declaration["items"]) + .checked_mul( + declaration["max_items"] + .as_u64() + .expect("an array declaration carries max_items") as usize, + ) + .and_then(|expanded| expanded.checked_add(1)) + .expect("the expansion fits"), + _ => 1, + } +} + +/// Builds an object declaration that expands to exactly `target` nodes, using +/// bounded arrays of booleans as the adjustable field weights. +fn expanded_object(target: usize) -> Value { + let mut remaining = target + .checked_sub(1) + .expect("an object expands to at least one node"); + let mut fields = serde_json::Map::new(); + while remaining > 0 { + let weight = remaining.min(257); + let schema = if weight == 1 { + json!({ "type": "boolean", "nullable": false }) + } else { + json!({ + "type": "array", + "nullable": false, + "max_bytes": 65_536, + "max_items": weight - 1, + "items": { "type": "boolean", "nullable": false }, + }) + }; + fields.insert( + format!("field_{}", fields.len()), + json!({ "required": true, "schema": schema }), + ); + remaining -= weight; + } + json!({ + "type": "object", + "nullable": false, + "max_bytes": 65_536, + "fields": fields, + }) +} + +fn boolean_object(fields: usize) -> Value { + json!({ + "type": "object", + "nullable": false, + "max_bytes": 65_536, + "fields": (0..fields) + .map(|index| { + ( + format!("field_{index}"), + json!({ "required": true, "schema": { "type": "boolean", "nullable": false } }), + ) + }) + .collect::>(), + }) +} + +#[test] +fn authored_structured_output_reaches_relay_and_notary_as_one_declaration() { + let baseline = build_opencrvs_outputs(|_| {}); + let structured = baseline + .relay + .get(STRUCTURED_OUTPUT) + .expect("the Relay contract carries the structured output"); + assert_eq!( + Some(structured), + baseline.notary.get(STRUCTURED_OUTPUT), + "one authored structured declaration must reach Relay and Notary as the same declaration" + ); + assert_eq!( + serde_json::to_value( + serde_json::from_value::(structured.clone()) + .expect("the structured declaration decodes into the Relay worker contract") + ) + .expect("the Relay worker contract re-serializes"), + *structured, + "the Relay worker type must round-trip the compiler-produced declaration exactly" + ); + assert_eq!( + serde_json::to_value( + serde_json::from_value::(structured.clone()) + .expect("the structured declaration decodes into the Notary output contract") + ) + .expect("the Notary output contract re-serializes"), + *structured, + "the Notary type must round-trip the compiler-produced declaration exactly" + ); + + // The public Relay contract keeps the authored `maxLength` on a date so the + // published surface stays self-describing; neither runtime type carries it. + // Every other output must be identical on both sides. + let divergent = baseline + .relay + .iter() + .filter(|(name, declaration)| baseline.notary.get(*name) != Some(*declaration)) + .map(|(name, declaration)| { + let mut relay_only = declaration.clone(); + let notary = baseline + .notary + .get(name) + .expect("Relay and Notary declare the same output names"); + relay_only + .as_object_mut() + .expect("an output declaration is an object") + .retain(|key, value| notary.get(key) != Some(value)); + (name.clone(), relay_only) + }) + .collect::>(); + assert_eq!( + divergent, + BTreeMap::from([("date_of_birth".to_string(), json!({ "max_bytes": 10 }))]), + "only the documented date byte hint may differ between the two product views" + ); + assert_eq!( + baseline.relay.keys().collect::>(), + baseline.notary.keys().collect::>(), + "both products must receive the same output names" + ); + + // The one authored nullability idiom must lower to `nullable: true` at both + // boundaries and at every level of a recursive declaration. + assert_eq!(structured["nullable"], json!(false)); + assert_eq!(structured["items"]["nullable"], json!(false)); + let nullable = build_opencrvs_outputs(|integration| { + integration["outputs"][STRUCTURED_OUTPUT]["type"] = json!(["array", "null"]); + integration["outputs"][STRUCTURED_OUTPUT]["items"]["type"] = json!(["object", "null"]); + }); + let nullable_structured = nullable + .relay + .get(STRUCTURED_OUTPUT) + .expect("the nullable Relay contract carries the structured output"); + assert_eq!( + Some(nullable_structured), + nullable.notary.get(STRUCTURED_OUTPUT), + "the nullable union idiom must reach Relay and Notary as the same declaration" + ); + assert_eq!(nullable_structured["nullable"], json!(true)); + assert_eq!(nullable_structured["items"]["nullable"], json!(true)); + assert_eq!( + nullable_structured["items"]["fields"], structured["items"]["fields"], + "declaring the composite nullable must not change any nested field" + ); +} + +#[test] +fn structured_output_values_agree_at_the_relay_and_notary_boundaries() { + let built = build_opencrvs_outputs(|_| {}); + let parents = built + .relay + .get(STRUCTURED_OUTPUT) + .expect("the Relay contract carries the structured output") + .clone(); + let item = parents["items"].clone(); + // Authored `maxLength: 16` on the item's `type` field lowers to 64 bytes. + let type_field_bytes = item["fields"]["type"]["schema"]["max_bytes"] + .as_u64() + .expect("the item type field declares a byte ceiling") as usize; + let item_bytes = item["max_bytes"] + .as_u64() + .expect("the item declares a byte ceiling") as usize; + + // A UTF-8 byte ceiling is measured in bytes, not characters. + let at_scalar_cap = "é".repeat(type_field_bytes / 2); + let over_scalar_cap = "é".repeat(type_field_bytes / 2 + 1); + assert_eq!(at_scalar_cap.len(), type_field_bytes); + assert_eq!(over_scalar_cap.len(), type_field_bytes + 2); + let ascii_under_cap = "a".repeat(type_field_bytes - 1); + let ascii_at_cap = "a".repeat(type_field_bytes); + let ascii_over_cap = "a".repeat(type_field_bytes + 1); + + // Pad the item's `name` so the serialized item lands exactly on its cap. + let padding = |extra: isize| { + let empty = json!({ "type": "mother", "name": "", "identifier": "P-1" }); + let base = serde_json::to_vec(&empty) + .expect("the probe item serializes") + .len(); + let width = usize::try_from(item_bytes as isize - base as isize + extra) + .expect("the padded item stays positive"); + json!({ "type": "mother", "name": "n".repeat(width), "identifier": "P-1" }) + }; + assert_eq!( + serde_json::to_vec(&padding(0)) + .expect("the padded item serializes") + .len(), + item_bytes + ); + + // A synthesized array reaches its own byte ceiling, which the authored + // declaration cannot: two items of at most 384 bytes never reach 1024. + let capped_array = json!({ + "type": "array", + "nullable": false, + "max_bytes": 64, + "max_items": 8, + "items": { "type": "string", "nullable": false, "max_bytes": 64 }, + }); + let array_at_cap = json!(["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]); + assert_eq!( + serde_json::to_vec(&array_at_cap) + .expect("the capped array serializes") + .len(), + 64 + ); + let array_over_cap = json!(["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]); + let array_under_cap = json!(["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]); + + let json_safe_integer = json!({ + "type": "integer", + "nullable": false, + "minimum": -9_007_199_254_740_991_i64, + "maximum": 9_007_199_254_740_991_i64, + }); + let nullable_integer = json!({ + "type": "integer", + "nullable": true, + "minimum": 0, + "maximum": 10, + }); + + for (case, declaration, value, accepted) in [ + ( + "two conforming items", + &parents, + json!([ + { "type": "mother", "name": "Mira Example", "identifier": "PARENT-0001" }, + { "type": "father", "name": "Noah Example", "identifier": "PARENT-0002" }, + ]), + true, + ), + ( + "more items than the declared maximum", + &parents, + json!([ + { "type": "mother", "name": "Mira Example" }, + { "type": "father", "name": "Noah Example" }, + { "type": "guardian", "name": "Ada Example" }, + ]), + false, + ), + ( + "absent optional nested field", + &parents, + json!([{ "type": "mother", "name": "Mira Example" }]), + true, + ), + ( + "null optional nested field", + &parents, + json!([{ "type": "mother", "name": "Mira Example", "identifier": null }]), + true, + ), + ( + "absent required nested field", + &parents, + json!([{ "type": "mother", "identifier": "PARENT-0001" }]), + false, + ), + ( + "null required nested field", + &parents, + json!([{ "type": "mother", "name": null }]), + false, + ), + ( + "null value for a non-nullable composite", + &parents, + Value::Null, + false, + ), + ( + "unknown ASCII nested key", + &parents, + json!([{ "type": "mother", "name": "Mira Example", "age": "41" }]), + false, + ), + ( + "unknown non-ASCII nested key", + &parents, + json!([{ "type": "mother", "name": "Mira Example", "prénom": "Mira" }]), + false, + ), + ( + "non-ASCII string value", + &parents, + json!([{ "type": "mother", "name": "José Mará Ñuñez" }]), + true, + ), + ( + "escaped control characters in a string value", + &parents, + json!([{ "type": "mother", "name": "Mira\u{0001}\u{0007}\nExample" }]), + true, + ), + ( + "string one byte below the scalar byte ceiling", + &parents, + json!([{ "type": ascii_under_cap, "name": "Mira Example" }]), + true, + ), + ( + "string exactly on the scalar byte ceiling", + &parents, + json!([{ "type": ascii_at_cap, "name": "Mira Example" }]), + true, + ), + ( + "string one byte past the scalar byte ceiling", + &parents, + json!([{ "type": ascii_over_cap, "name": "Mira Example" }]), + false, + ), + ( + "non-ASCII string exactly on the scalar byte ceiling", + &parents, + json!([{ "type": at_scalar_cap, "name": "Mira Example" }]), + true, + ), + ( + "non-ASCII string one byte pair past the scalar byte ceiling", + &parents, + json!([{ "type": over_scalar_cap, "name": "Mira Example" }]), + false, + ), + ( + "serialized item one byte below its ceiling", + &parents, + json!([padding(-1)]), + true, + ), + ( + "serialized item exactly on its ceiling", + &parents, + json!([padding(0)]), + true, + ), + ( + "serialized item one byte past its ceiling", + &parents, + json!([padding(1)]), + false, + ), + ( + "serialized array one byte below its ceiling", + &capped_array, + array_under_cap, + true, + ), + ( + "serialized array exactly on its ceiling", + &capped_array, + array_at_cap, + true, + ), + ( + "serialized array one byte past its ceiling", + &capped_array, + array_over_cap, + false, + ), + ( + "exact JSON-safe maximum integer", + &json_safe_integer, + json!(9_007_199_254_740_991_i64), + true, + ), + ( + "one past the JSON-safe maximum integer", + &json_safe_integer, + json!(9_007_199_254_740_992_i64), + false, + ), + ( + "exact JSON-safe minimum integer", + &json_safe_integer, + json!(-9_007_199_254_740_991_i64), + true, + ), + ( + "one past the JSON-safe minimum integer", + &json_safe_integer, + json!(-9_007_199_254_740_992_i64), + false, + ), + ( + "integer exactly on a narrow declared maximum", + &nullable_integer, + json!(10), + true, + ), + ( + "integer one past a narrow declared maximum", + &nullable_integer, + json!(11), + false, + ), + ( + "null value for a nullable scalar", + &nullable_integer, + Value::Null, + true, + ), + ] { + let relay = relay_accepts_value(declaration, &value); + let notary = notary_accepts_value(declaration, &value); + assert_eq!( + relay, notary, + "Relay and Notary must reach the same verdict for {case}" + ); + assert_eq!(relay, accepted, "unexpected boundary verdict for {case}"); + } +} + +#[test] +fn platform_output_schema_bounds_agree_across_registryctl_relay_and_notary() { + let built = build_opencrvs_outputs(|_| {}); + + // The Notary decoder wraps consultation outputs in the Relay result root + // (three levels) and reserves the twenty fixed envelope nodes. Registryctl + // reserves the same envelope when it validates an authored declaration, so + // Notary is the binding bound and Relay, which validates only the bare + // output map, is deliberately more permissive. + assert!( + relay_accepts_declaration(&array_layers(6)), + "six schema levels fit inside the Relay worker depth bound" + ); + assert!( + notary_accepts_declaration(&built.notary_document, &array_layers(6)), + "six schema levels fit beneath the reserved Notary result envelope" + ); + assert!( + !authoring_rejects_output("nested", &authored_array_layers(6)), + "six schema levels are authorable" + ); + assert!( + relay_accepts_declaration(&array_layers(7)), + "seven schema levels still fit the Relay worker depth bound" + ); + assert!( + !notary_accepts_declaration(&built.notary_document, &array_layers(7)), + "seven schema levels exceed the reserved Notary result envelope" + ); + assert!( + authoring_rejects_output("nested", &authored_array_layers(7)), + "Registryctl reserves the same result envelope as the Notary platform" + ); + assert!( + !relay_accepts_declaration(&array_layers(9)), + "nine schema levels exceed the Relay worker depth bound" + ); + assert!( + !notary_accepts_declaration(&built.notary_document, &array_layers(9)), + "nine schema levels exceed the Notary depth bound" + ); + + for (case, declaration, accepted) in [ + ("thirty-two object fields", boolean_object(32), true), + ("thirty-three object fields", boolean_object(33), false), + ( + "two hundred and fifty-six array items", + json!({ + "type": "array", + "nullable": false, + "max_bytes": 65_536, + "max_items": 256, + "items": { "type": "boolean", "nullable": false }, + }), + true, + ), + ( + "two hundred and fifty-seven array items", + json!({ + "type": "array", + "nullable": false, + "max_bytes": 65_536, + "max_items": 257, + "items": { "type": "boolean", "nullable": false }, + }), + false, + ), + ( + "declared field name carrying a control character", + json!({ + "type": "object", + "nullable": false, + "max_bytes": 65_536, + "fields": { + "wrapped\u{0001}name": { + "required": true, + "schema": { "type": "boolean", "nullable": false }, + }, + }, + }), + false, + ), + ( + "declared non-ASCII field name", + json!({ + "type": "object", + "nullable": false, + "max_bytes": 65_536, + "fields": { + "prénom": { + "required": true, + "schema": { "type": "boolean", "nullable": false }, + }, + }, + }), + true, + ), + ( + "string byte ceiling exactly on the platform bound", + json!({ "type": "string", "nullable": false, "max_bytes": 65_536 }), + true, + ), + ( + "string byte ceiling one byte past the platform bound", + json!({ "type": "string", "nullable": false, "max_bytes": 65_537 }), + false, + ), + ] { + let relay = relay_accepts_declaration(&declaration); + let notary = notary_accepts_declaration(&built.notary_document, &declaration); + assert_eq!( + relay, notary, + "Relay and Notary must reach the same declaration verdict for {case}" + ); + assert_eq!(relay, accepted, "unexpected declaration verdict for {case}"); + } + + // The expanded-node budget is a whole-consultation budget, and the Notary + // decoder spends the reserved result envelope inside it before reading any + // output. A worker request that carries one output therefore admits a + // larger single declaration than the same declaration inside a generated + // consultation. Both products expand a declaration identically; only the + // reserve differs. + let reserved = + RELAY_RESULT_ENVELOPE_NODES + built.notary.values().map(expanded_nodes).sum::(); + let notary_budget = MAX_RELAY_OUTPUT_EXPANDED_NODES_V1 - reserved; + for (case, target, relay_accepts, notary_accepts) in [ + ( + "the generated consultation budget", + notary_budget, + true, + true, + ), + ( + "one node past the generated consultation budget", + notary_budget + 1, + true, + false, + ), + ( + "the bare platform expanded-node bound", + MAX_RELAY_OUTPUT_EXPANDED_NODES_V1, + true, + false, + ), + ( + "one node past the platform expanded-node bound", + MAX_RELAY_OUTPUT_EXPANDED_NODES_V1 + 1, + false, + false, + ), + ] { + let declaration = expanded_object(target); + assert_eq!( + expanded_nodes(&declaration), + target, + "the parity builder must expand to exactly {target} nodes for {case}" + ); + assert_eq!( + relay_accepts_declaration(&declaration), + relay_accepts, + "unexpected Relay expanded-node verdict for {case}" + ); + assert_eq!( + notary_accepts_declaration(&built.notary_document, &declaration), + notary_accepts, + "unexpected Notary expanded-node verdict for {case}" + ); + } + + // Registryctl is the strictest of the three gates: the published authoring + // grammar rejects declared field names that both runtime products accept. + assert!( + authoring_rejects_output( + "named", + &json!({ + "type": "object", + "max_bytes": 1_024, + "fields": { + "prénom": { "required": true, "schema": { "type": "boolean" } }, + }, + }), + ), + "a non-ASCII declared field name is outside the published authoring grammar" + ); +} + +/// The authored form of [`array_layers`]: the authoring surface omits the +/// lowered `nullable` flag and expresses the leaf as a scalar declaration. +fn authored_array_layers(nodes: usize) -> Value { + assert!(nodes > 0); + let mut schema = json!({ "type": "boolean" }); + for _ in 1..nodes { + schema = json!({ + "type": "array", + "max_bytes": 65_536, + "max_items": 1, + "items": schema, + }); + } + schema +} diff --git a/crates/registryctl/tests/project_documentation_reference.rs b/crates/registryctl/tests/project_documentation_reference.rs index 41eef4be8..2b0b6c792 100644 --- a/crates/registryctl/tests/project_documentation_reference.rs +++ b/crates/registryctl/tests/project_documentation_reference.rs @@ -312,7 +312,7 @@ fn human_intent_sidecar_and_documentation_contracts_are_strict_schemas() { let intent_schema = compile_schema(&intent_schema_document); let intent = read_json(schema_root.join("project-authoring/documentation-intent.json")); assert_valid(&intent_schema, &intent, "documentation intent sidecar"); - assert_eq!(intent["structural_reviews"].as_array().unwrap().len(), 205); + assert_eq!(intent["structural_reviews"].as_array().unwrap().len(), 213); for file in [ "registry.project.configuration_reference.v1.schema.json", @@ -437,13 +437,13 @@ fn embedded_coverage_is_complete_and_generates_the_canonical_reference() { CONFIGURATION_REFERENCE_COVERAGE_SCHEMA_ID ); assert_eq!(coverage.coverage.schema_count, 7); - assert_eq!(coverage.coverage.path_count, 1829); + assert_eq!(coverage.coverage.path_count, 1835); assert_eq!( coverage.coverage.by_schema, [ (ConfigurationSchemaKind::Project, 220), (ConfigurationSchemaKind::Environment, 213), - (ConfigurationSchemaKind::Integration, 171), + (ConfigurationSchemaKind::Integration, 177), (ConfigurationSchemaKind::Fixture, 63), (ConfigurationSchemaKind::Entity, 35), (ConfigurationSchemaKind::Relay, 593), @@ -456,22 +456,22 @@ fn embedded_coverage_is_complete_and_generates_the_canonical_reference() { coverage.coverage.by_path_kind, [ (FieldPathKind::Root, 7), - (FieldPathKind::Property, 1_458), + (FieldPathKind::Property, 1_456), (FieldPathKind::MapKey, 26), (FieldPathKind::MapValue, 48), - (FieldPathKind::ArrayItem, 178), - (FieldPathKind::Branch, 112), + (FieldPathKind::ArrayItem, 182), + (FieldPathKind::Branch, 116), ] .into_iter() .collect(), "the exact reviewed structural taxonomy remains release-gated" ); - assert_eq!(coverage.reviewed_intent_assignment_required_count, 1829); + assert_eq!(coverage.reviewed_intent_assignment_required_count, 1835); assert_eq!( coverage.reviewed_intent_assignment_covered_count + coverage.missing_intent.len(), coverage.reviewed_intent_assignment_required_count ); - assert_eq!(coverage.reviewed_intent_assignment_covered_count, 1829); + assert_eq!(coverage.reviewed_intent_assignment_covered_count, 1835); assert!( coverage.distinct_reviewed_intent_count < coverage.reviewed_intent_assignment_covered_count, "assignment coverage must not imply one unique explanation per path" @@ -488,7 +488,7 @@ fn embedded_coverage_is_complete_and_generates_the_canonical_reference() { coverage.distinct_reviewed_intents_reused_count, coverage.reviewed_intent_assignments_using_reused_intent_count, ), - (629, 86, 1_286), + (627, 86, 1_294), "the exact intent-text reuse baseline must change intentionally with reviewed documentation" ); assert_eq!( @@ -636,7 +636,7 @@ fn embedded_coverage_is_complete_and_generates_the_canonical_reference() { }) .count(), ), - (528, 315, 0, 986), + (528, 315, 0, 992), "the exact empty-string semantic coverage prevents constrained strings from regressing to allowed" ); assert_eq!( diff --git a/docs/site/public/generated/configuration-reference-coverage.v1.json b/docs/site/public/generated/configuration-reference-coverage.v1.json index 5293f4f1b..d9ac9b7fd 100644 --- a/docs/site/public/generated/configuration-reference-coverage.v1.json +++ b/docs/site/public/generated/configuration-reference-coverage.v1.json @@ -39,12 +39,12 @@ }, "coverage": { "schema_count": 7, - "path_count": 1829, - "reference_count": 506, + "path_count": 1835, + "reference_count": 508, "by_schema": { "project": 220, "environment": 213, - "integration": 171, + "integration": 177, "fixture": 63, "entity": 35, "relay": 593, @@ -52,24 +52,24 @@ }, "by_path_kind": { "root": 7, - "property": 1458, + "property": 1456, "map_key": 26, "map_value": 48, - "array_item": 178, - "branch": 112 + "array_item": 182, + "branch": 116 }, "by_sensitivity": { "public": 16, - "internal": 1179, + "internal": 1181, "sensitive": 408, "secret_reference": 44, "redacted_fixture": 51, - "structural": 131 + "structural": 135 }, "by_intent_source": { "schema_description": 530, - "reviewed_override": 266, - "structural_taxonomy": 131, + "reviewed_override": 264, + "structural_taxonomy": 139, "reviewed_profile": 902 }, "by_intent_profile": { @@ -148,10 +148,10 @@ "relay_vocabularies_open_map": 1 } }, - "reviewed_intent_assignment_required_count": 1829, - "reviewed_intent_assignment_covered_count": 1829, - "distinct_reviewed_intent_count": 629, + "reviewed_intent_assignment_required_count": 1835, + "reviewed_intent_assignment_covered_count": 1835, + "distinct_reviewed_intent_count": 627, "distinct_reviewed_intents_reused_count": 86, - "reviewed_intent_assignments_using_reused_intent_count": 1286, + "reviewed_intent_assignments_using_reused_intent_count": 1294, "missing_intent": [] } diff --git a/docs/site/public/generated/configuration-reference.v1.json b/docs/site/public/generated/configuration-reference.v1.json index 85e52bb36..93ee13ccd 100644 --- a/docs/site/public/generated/configuration-reference.v1.json +++ b/docs/site/public/generated/configuration-reference.v1.json @@ -38,12 +38,12 @@ }, "coverage": { "schema_count": 7, - "path_count": 1829, - "reference_count": 506, + "path_count": 1835, + "reference_count": 508, "by_schema": { "project": 220, "environment": 213, - "integration": 171, + "integration": 177, "fixture": 63, "entity": 35, "relay": 593, @@ -51,24 +51,24 @@ }, "by_path_kind": { "root": 7, - "property": 1458, + "property": 1456, "map_key": 26, "map_value": 48, - "array_item": 178, - "branch": 112 + "array_item": 182, + "branch": 116 }, "by_sensitivity": { "public": 16, - "internal": 1179, + "internal": 1181, "sensitive": 408, "secret_reference": 44, "redacted_fixture": 51, - "structural": 131 + "structural": 135 }, "by_intent_source": { "schema_description": 530, - "reviewed_override": 266, - "structural_taxonomy": 131, + "reviewed_override": 264, + "structural_taxonomy": 139, "reviewed_profile": 902 }, "by_intent_profile": { @@ -41370,7 +41370,7 @@ { "address": { "schema": "integration", - "pointer": "/$defs/capability/oneOf/0", + "pointer": "/$defs/arrayType/oneOf/0", "path_kind": "branch" }, "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", @@ -41379,9 +41379,7 @@ "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [ - "object" - ], + "schema_types": [], "composed": false }, "requiredness": "conditional", @@ -41452,42 +41450,36 @@ ], "constraints": [ { - "keyword": "required", - "value": [ - "http" - ] - }, - { - "keyword": "type", - "value": "object" + "keyword": "const", + "value": "array" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/capability/oneOf/0/properties/http", - "path_kind": "property" + "pointer": "/$defs/arrayType/oneOf/1", + "path_kind": "branch" }, - "purpose": "Selects the single-request declarative HTTP capability and its expected response semantics.", - "purpose_source": "reviewed_override", + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "object" + "array" ], "composed": false }, - "requiredness": "required", - "null_behavior": "rejected", + "requiredness": "conditional", + "null_behavior": "not_applicable", "empty_behavior": "not_applicable", "default": { - "behavior": "no_schema_default" + "behavior": "not_applicable" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "structural", "state": "authored", "products": [ "registryctl", @@ -41543,40 +41535,40 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" ], "constraints": [ { - "keyword": "required", - "value": [ - "request" - ] + "keyword": "maxItems", + "value": 2 + }, + { + "keyword": "minItems", + "value": 2 }, { "keyword": "type", - "value": "object" + "value": "array" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/capability/oneOf/0/properties/http/properties/request", - "path_kind": "property" + "pointer": "/$defs/arrayType/oneOf/1/prefixItems/0", + "path_kind": "array_item" }, - "purpose": "Bounded read-only HTTP request template.", - "purpose_source": "schema_description", + "purpose": "Defines the contract shared by each ordered item in the enclosing authored list.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [ - "object" - ], - "local_reference": "#/$defs/httpRequest", + "schema_types": [], "composed": false }, - "requiredness": "required", + "requiredness": "not_applicable", "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { @@ -41639,45 +41631,32 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "array_items_share_element_contract" ], "constraints": [ { - "keyword": "required", - "value": [ - "method", - "path" - ] - }, - { - "keyword": "type", - "value": "object" + "keyword": "const", + "value": "array" } - ], - "local_reference": { - "schema": "integration", - "pointer": "/$defs/httpRequest" - } + ] }, { "address": { "schema": "integration", - "pointer": "/$defs/capability/oneOf/0/properties/http/properties/response", - "path_kind": "property" + "pointer": "/$defs/arrayType/oneOf/1/prefixItems/1", + "path_kind": "array_item" }, - "purpose": "Rules for translating upstream status and body cardinality into normalized outcomes.", - "purpose_source": "schema_description", + "purpose": "Defines the contract shared by each ordered item in the enclosing authored list.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [ - "object" - ], - "local_reference": "#/$defs/httpResponse", + "schema_types": [], "composed": false }, - "requiredness": "optional", + "requiredness": "not_applicable", "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { @@ -41740,23 +41719,20 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "array_items_share_element_contract" ], "constraints": [ { - "keyword": "type", - "value": "object" + "keyword": "const", + "value": "null" } - ], - "local_reference": { - "schema": "integration", - "pointer": "/$defs/httpResponse" - } + ] }, { "address": { "schema": "integration", - "pointer": "/$defs/capability/oneOf/1", + "pointer": "/$defs/capability/oneOf/0", "path_kind": "branch" }, "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", @@ -41840,7 +41816,7 @@ { "keyword": "required", "value": [ - "script" + "http" ] }, { @@ -41852,10 +41828,10 @@ { "address": { "schema": "integration", - "pointer": "/$defs/capability/oneOf/1/properties/script", + "pointer": "/$defs/capability/oneOf/0/properties/http", "path_kind": "property" }, - "purpose": "Selects the reviewed project-relative script capability and its optional modules.", + "purpose": "Selects the single-request declarative HTTP capability and its expected response semantics.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", @@ -41935,7 +41911,7 @@ { "keyword": "required", "value": [ - "file" + "request" ] }, { @@ -41947,29 +41923,29 @@ { "address": { "schema": "integration", - "pointer": "/$defs/capability/oneOf/1/properties/script/properties/file", + "pointer": "/$defs/capability/oneOf/0/properties/http/properties/request", "path_kind": "property" }, - "purpose": "Project-relative path without traversal or duplicate separators.", + "purpose": "Bounded read-only HTTP request template.", "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "string" + "object" ], - "local_reference": "#/$defs/relativePath", + "local_reference": "#/$defs/httpRequest", "composed": false }, "requiredness": "required", "null_behavior": "rejected", - "empty_behavior": "rejected", + "empty_behavior": "not_applicable", "default": { "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "sensitive", + "sensitivity": "internal", "state": "authored", "products": [ "registryctl", @@ -42025,47 +42001,42 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "sensitive_operational_metadata" + "generated_docs_never_load_country_values" ], "constraints": [ { - "keyword": "maxLength", - "value": 4096 - }, - { - "keyword": "minLength", - "value": 1 - }, - { - "keyword": "pattern", - "value": "^(?!/)(?!.*(?:^|/)\\.\\.?/)(?!.*//).+$" + "keyword": "required", + "value": [ + "method", + "path" + ] }, { "keyword": "type", - "value": "string" + "value": "object" } ], "local_reference": { "schema": "integration", - "pointer": "/$defs/relativePath" + "pointer": "/$defs/httpRequest" } }, { "address": { "schema": "integration", - "pointer": "/$defs/capability/oneOf/1/properties/script/properties/modules", + "pointer": "/$defs/capability/oneOf/0/properties/http/properties/response", "path_kind": "property" }, - "purpose": "Lists the reviewed project-relative modules available to the integration script.", - "purpose_source": "reviewed_override", + "purpose": "Rules for translating upstream status and body cardinality into normalized outcomes.", + "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "array" + "object" ], + "local_reference": "#/$defs/httpResponse", "composed": false }, "requiredness": "optional", @@ -42075,105 +42046,6 @@ "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "sensitive", - "state": "authored", - "products": [ - "registryctl", - "relay", - "notary", - "editor", - "docs" - ], - "availability": "published", - "stability": "experimental", - "validation_stages": [ - "json_schema", - "rust_deserialization", - "cross_file_semantic", - "fixture_execution", - "product_build" - ], - "diagnostic": "registryctl.authoring.integration.invalid", - "history_status": "not_verified", - "introduced_in": null, - "version_history": [], - "example": { - "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", - "schema_examples_available": false, - "contains_country_values": false - }, - "migration": "rebuild_project", - "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", - "consumers": [ - "registryctl_authoring", - "registry_relay", - "registry_notary", - "editor_tooling", - "docs_generator" - ], - "generated_artifacts": [ - "editor_schemas", - "project_build", - "relay_config", - "notary_config", - "fixture_report", - "field_reference" - ], - "review_classes": [ - "contract", - "security", - "privacy", - "relay", - "notary", - "compatibility", - "documentation", - "testing" - ], - "semantic_rules": [ - "knowledge_only", - "generated_docs_never_load_country_values", - "sensitive_operational_metadata" - ], - "constraints": [ - { - "keyword": "maxItems", - "value": 32 - }, - { - "keyword": "type", - "value": "array" - }, - { - "keyword": "uniqueItems", - "value": true - } - ] - }, - { - "address": { - "schema": "integration", - "pointer": "/$defs/capability/oneOf/1/properties/script/properties/modules/items", - "path_kind": "array_item" - }, - "purpose": "Project-relative path without traversal or duplicate separators.", - "purpose_source": "schema_description", - "semantic_owner": "integration_contract", - "human_owner": "integration_maintainers", - "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", - "field_type": { - "schema_types": [ - "string" - ], - "local_reference": "#/$defs/relativePath", - "composed": false - }, - "requiredness": "not_applicable", - "null_behavior": "rejected", - "empty_behavior": "rejected", - "default": { - "behavior": "no_schema_default" - }, - "environment_behavior": "narrows_reviewed_authority", "sensitivity": "internal", "state": "authored", "products": [ @@ -42230,36 +42102,23 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "array_items_share_element_contract" + "generated_docs_never_load_country_values" ], "constraints": [ - { - "keyword": "maxLength", - "value": 4096 - }, - { - "keyword": "minLength", - "value": 1 - }, - { - "keyword": "pattern", - "value": "^(?!/)(?!.*(?:^|/)\\.\\.?/)(?!.*//).+$" - }, { "keyword": "type", - "value": "string" + "value": "object" } ], "local_reference": { "schema": "integration", - "pointer": "/$defs/relativePath" + "pointer": "/$defs/httpResponse" } }, { "address": { "schema": "integration", - "pointer": "/$defs/capability/oneOf/2", + "pointer": "/$defs/capability/oneOf/1", "path_kind": "branch" }, "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", @@ -42343,7 +42202,7 @@ { "keyword": "required", "value": [ - "snapshot" + "script" ] }, { @@ -42355,10 +42214,10 @@ { "address": { "schema": "integration", - "pointer": "/$defs/capability/oneOf/2/properties/snapshot", + "pointer": "/$defs/capability/oneOf/1/properties/script", "path_kind": "property" }, - "purpose": "Selects an offline entity snapshot capability with exact input matching and freshness control.", + "purpose": "Selects the reviewed project-relative script capability and its optional modules.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", @@ -42438,9 +42297,7 @@ { "keyword": "required", "value": [ - "entity", - "exact", - "freshness" + "file" ] }, { @@ -42452,10 +42309,10 @@ { "address": { "schema": "integration", - "pointer": "/$defs/capability/oneOf/2/properties/snapshot/properties/entity", + "pointer": "/$defs/capability/oneOf/1/properties/script/properties/file", "path_kind": "property" }, - "purpose": "Lowercase stable identifier used in project references.", + "purpose": "Project-relative path without traversal or duplicate separators.", "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", @@ -42464,7 +42321,7 @@ "schema_types": [ "string" ], - "local_reference": "#/$defs/stableId", + "local_reference": "#/$defs/relativePath", "composed": false }, "requiredness": "required", @@ -42474,7 +42331,7 @@ "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "sensitive", "state": "authored", "products": [ "registryctl", @@ -42530,12 +42387,21 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "sensitive_operational_metadata" ], "constraints": [ + { + "keyword": "maxLength", + "value": 4096 + }, + { + "keyword": "minLength", + "value": 1 + }, { "keyword": "pattern", - "value": "^[a-z][a-z0-9._-]{0,95}$" + "value": "^(?!/)(?!.*(?:^|/)\\.\\.?/)(?!.*//).+$" }, { "keyword": "type", @@ -42544,34 +42410,34 @@ ], "local_reference": { "schema": "integration", - "pointer": "/$defs/stableId" + "pointer": "/$defs/relativePath" } }, { "address": { "schema": "integration", - "pointer": "/$defs/capability/oneOf/2/properties/snapshot/properties/exact", + "pointer": "/$defs/capability/oneOf/1/properties/script/properties/modules", "path_kind": "property" }, - "purpose": "Maps entity fields to integration inputs that must match exactly in the snapshot lookup.", + "purpose": "Lists the reviewed project-relative modules available to the integration script.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "object" + "array" ], "composed": false }, - "requiredness": "required", + "requiredness": "optional", "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "sensitive", "state": "authored", "products": [ "registryctl", @@ -42627,44 +42493,45 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "sensitive_operational_metadata" ], "constraints": [ { - "keyword": "maxProperties", - "value": 8 + "keyword": "maxItems", + "value": 32 }, { - "keyword": "minProperties", - "value": 1 + "keyword": "type", + "value": "array" }, { - "keyword": "type", - "value": "object" + "keyword": "uniqueItems", + "value": true } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/capability/oneOf/2/properties/snapshot/properties/exact/additionalProperties", - "path_kind": "map_value" + "pointer": "/$defs/capability/oneOf/1/properties/script/properties/modules/items", + "path_kind": "array_item" }, - "purpose": "Reference to a declared integration input.", + "purpose": "Project-relative path without traversal or duplicate separators.", "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "object" + "string" ], - "local_reference": "#/$defs/inputReference", + "local_reference": "#/$defs/relativePath", "composed": false }, "requiredness": "not_applicable", "null_behavior": "rejected", - "empty_behavior": "not_applicable", + "empty_behavior": "rejected", "default": { "behavior": "no_schema_default" }, @@ -42726,50 +42593,56 @@ "semantic_rules": [ "knowledge_only", "generated_docs_never_load_country_values", - "arbitrary_map_keys_not_fixed_properties" + "array_items_share_element_contract" ], "constraints": [ { - "keyword": "required", - "value": [ - "input" - ] + "keyword": "maxLength", + "value": 4096 + }, + { + "keyword": "minLength", + "value": 1 + }, + { + "keyword": "pattern", + "value": "^(?!/)(?!.*(?:^|/)\\.\\.?/)(?!.*//).+$" }, { "keyword": "type", - "value": "object" + "value": "string" } ], "local_reference": { "schema": "integration", - "pointer": "/$defs/inputReference" + "pointer": "/$defs/relativePath" } }, { "address": { "schema": "integration", - "pointer": "/$defs/capability/oneOf/2/properties/snapshot/properties/freshness", - "path_kind": "property" + "pointer": "/$defs/capability/oneOf/2", + "path_kind": "branch" }, - "purpose": "Sets the maximum accepted age of the materialized entity snapshot within the product-owned 31-day ceiling.", - "purpose_source": "reviewed_override", + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "string" + "object" ], "composed": false }, - "requiredness": "required", - "null_behavior": "rejected", - "empty_behavior": "rejected", + "requiredness": "conditional", + "null_behavior": "not_applicable", + "empty_behavior": "not_applicable", "default": { - "behavior": "no_schema_default" + "behavior": "not_applicable" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "structural", "state": "authored", "products": [ "registryctl", @@ -42825,27 +42698,30 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" ], "constraints": [ { - "keyword": "pattern", - "value": "^(?:(?:[1-9][0-9]{0,8}|1[0-9]{9}|2[0-5][0-9]{8}|26[0-6][0-9]{7}|267[0-7][0-9]{6}|2678[0-3][0-9]{5}|2678400000)ms|(?:[1-9][0-9]{0,5}|1[0-9]{6}|2[0-5][0-9]{5}|26[0-6][0-9]{4}|267[0-7][0-9]{3}|2678[0-3][0-9]{2}|2678400)s|(?:[1-9][0-9]{0,3}|[1-3][0-9]{4}|4[0-3][0-9]{3}|44[0-5][0-9]{2}|446[0-3][0-9]{1}|44640)m|(?:[1-9][0-9]{0,1}|[1-6][0-9]{2}|7[0-3][0-9]{1}|74[0-3]|744)h|(?:[1-9][0-9]{0,0}|[1-2][0-9]{1}|30|31)d)$" + "keyword": "required", + "value": [ + "snapshot" + ] }, { "keyword": "type", - "value": "string" + "value": "object" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/0", - "path_kind": "branch" + "pointer": "/$defs/capability/oneOf/2/properties/snapshot", + "path_kind": "property" }, - "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", - "purpose_source": "structural_taxonomy", + "purpose": "Selects an offline entity snapshot capability with exact input matching and freshness control.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", @@ -42855,14 +42731,14 @@ ], "composed": false }, - "requiredness": "conditional", - "null_behavior": "not_applicable", + "requiredness": "required", + "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { - "behavior": "not_applicable" + "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "structural", + "sensitivity": "internal", "state": "authored", "products": [ "registryctl", @@ -42918,14 +42794,15 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "branch_has_no_authored_value" + "generated_docs_never_load_country_values" ], "constraints": [ { "keyword": "required", "value": [ - "type" + "entity", + "exact", + "freshness" ] }, { @@ -42937,21 +42814,24 @@ { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/0/properties/type", + "pointer": "/$defs/capability/oneOf/2/properties/snapshot/properties/entity", "path_kind": "property" }, - "purpose": "Selects an unauthenticated, basic-authentication, or static-bearer credential interface.", - "purpose_source": "reviewed_override", + "purpose": "Lowercase stable identifier used in project references.", + "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [], + "schema_types": [ + "string" + ], + "local_reference": "#/$defs/stableId", "composed": false }, "requiredness": "required", "null_behavior": "rejected", - "empty_behavior": "not_applicable", + "empty_behavior": "rejected", "default": { "behavior": "no_schema_default" }, @@ -43016,23 +42896,27 @@ ], "constraints": [ { - "keyword": "enum", - "value": [ - "none", - "basic", - "static_bearer" - ] + "keyword": "pattern", + "value": "^[a-z][a-z0-9._-]{0,95}$" + }, + { + "keyword": "type", + "value": "string" } - ] + ], + "local_reference": { + "schema": "integration", + "pointer": "/$defs/stableId" + } }, { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/1", - "path_kind": "branch" + "pointer": "/$defs/capability/oneOf/2/properties/snapshot/properties/exact", + "path_kind": "property" }, - "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", - "purpose_source": "structural_taxonomy", + "purpose": "Maps entity fields to integration inputs that must match exactly in the snapshot lookup.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", @@ -43042,14 +42926,14 @@ ], "composed": false }, - "requiredness": "conditional", - "null_behavior": "not_applicable", + "requiredness": "required", + "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { - "behavior": "not_applicable" + "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "structural", + "sensitivity": "internal", "state": "authored", "products": [ "registryctl", @@ -43105,17 +42989,16 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "branch_has_no_authored_value" + "generated_docs_never_load_country_values" ], "constraints": [ { - "keyword": "required", - "value": [ - "type", - "name", - "max_value_bytes" - ] + "keyword": "maxProperties", + "value": 8 + }, + { + "keyword": "minProperties", + "value": 1 }, { "keyword": "type", @@ -43126,21 +43009,22 @@ { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/1/properties/max_value_bytes", - "path_kind": "property" + "pointer": "/$defs/capability/oneOf/2/properties/snapshot/properties/exact/additionalProperties", + "path_kind": "map_value" }, - "purpose": "Caps the credential value size accepted by the fixed-header API-key interface.", - "purpose_source": "reviewed_override", + "purpose": "Reference to a declared integration input.", + "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "integer" + "object" ], + "local_reference": "#/$defs/inputReference", "composed": false }, - "requiredness": "required", + "requiredness": "not_applicable", "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { @@ -43203,30 +43087,33 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "arbitrary_map_keys_not_fixed_properties" ], "constraints": [ { - "keyword": "maximum", - "value": 4096 - }, - { - "keyword": "minimum", - "value": 1 + "keyword": "required", + "value": [ + "input" + ] }, { "keyword": "type", - "value": "integer" + "value": "object" } - ] + ], + "local_reference": { + "schema": "integration", + "pointer": "/$defs/inputReference" + } }, { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/1/properties/name", + "pointer": "/$defs/capability/oneOf/2/properties/snapshot/properties/freshness", "path_kind": "property" }, - "purpose": "Declares the fixed HTTP header name used by the API-key credential interface.", + "purpose": "Sets the maximum accepted age of the materialized entity snapshot within the product-owned 31-day ceiling.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", @@ -43305,7 +43192,7 @@ "constraints": [ { "keyword": "pattern", - "value": "^[A-Za-z][A-Za-z0-9_-]{0,63}$" + "value": "^(?:(?:[1-9][0-9]{0,8}|1[0-9]{9}|2[0-5][0-9]{8}|26[0-6][0-9]{7}|267[0-7][0-9]{6}|2678[0-3][0-9]{5}|2678400000)ms|(?:[1-9][0-9]{0,5}|1[0-9]{6}|2[0-5][0-9]{5}|26[0-6][0-9]{4}|267[0-7][0-9]{3}|2678[0-3][0-9]{2}|2678400)s|(?:[1-9][0-9]{0,3}|[1-3][0-9]{4}|4[0-3][0-9]{3}|44[0-5][0-9]{2}|446[0-3][0-9]{1}|44640)m|(?:[1-9][0-9]{0,1}|[1-6][0-9]{2}|7[0-3][0-9]{1}|74[0-3]|744)h|(?:[1-9][0-9]{0,0}|[1-2][0-9]{1}|30|31)d)$" }, { "keyword": "type", @@ -43316,94 +43203,7 @@ { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/1/properties/type", - "path_kind": "property" - }, - "purpose": "Selects the fixed-header API-key credential interface for this source contract.", - "purpose_source": "reviewed_override", - "semantic_owner": "integration_contract", - "human_owner": "integration_maintainers", - "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", - "field_type": { - "schema_types": [], - "composed": false - }, - "requiredness": "required", - "null_behavior": "rejected", - "empty_behavior": "not_applicable", - "default": { - "behavior": "no_schema_default" - }, - "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", - "state": "authored", - "products": [ - "registryctl", - "relay", - "notary", - "editor", - "docs" - ], - "availability": "published", - "stability": "experimental", - "validation_stages": [ - "json_schema", - "rust_deserialization", - "cross_file_semantic", - "fixture_execution", - "product_build" - ], - "diagnostic": "registryctl.authoring.integration.invalid", - "history_status": "not_verified", - "introduced_in": null, - "version_history": [], - "example": { - "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", - "schema_examples_available": false, - "contains_country_values": false - }, - "migration": "rebuild_project", - "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", - "consumers": [ - "registryctl_authoring", - "registry_relay", - "registry_notary", - "editor_tooling", - "docs_generator" - ], - "generated_artifacts": [ - "editor_schemas", - "project_build", - "relay_config", - "notary_config", - "fixture_report", - "field_reference" - ], - "review_classes": [ - "contract", - "security", - "privacy", - "relay", - "notary", - "compatibility", - "documentation", - "testing" - ], - "semantic_rules": [ - "knowledge_only", - "generated_docs_never_load_country_values" - ], - "constraints": [ - { - "keyword": "const", - "value": "api_key_header" - } - ] - }, - { - "address": { - "schema": "integration", - "pointer": "/$defs/credential/oneOf/2", + "pointer": "/$defs/credential/oneOf/0", "path_kind": "branch" }, "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", @@ -43487,9 +43287,7 @@ { "keyword": "required", "value": [ - "type", - "name", - "max_value_bytes" + "type" ] }, { @@ -43501,18 +43299,16 @@ { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/2/properties/max_value_bytes", + "pointer": "/$defs/credential/oneOf/0/properties/type", "path_kind": "property" }, - "purpose": "Caps the credential value size accepted by the fixed-query API-key interface.", + "purpose": "Selects an unauthenticated, basic-authentication, or static-bearer credential interface.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [ - "integer" - ], + "schema_types": [], "composed": false }, "requiredness": "required", @@ -43582,44 +43378,40 @@ ], "constraints": [ { - "keyword": "maximum", - "value": 4096 - }, - { - "keyword": "minimum", - "value": 1 - }, - { - "keyword": "type", - "value": "integer" + "keyword": "enum", + "value": [ + "none", + "basic", + "static_bearer" + ] } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/2/properties/name", - "path_kind": "property" + "pointer": "/$defs/credential/oneOf/1", + "path_kind": "branch" }, - "purpose": "Declares the fixed query parameter name used by the API-key credential interface.", - "purpose_source": "reviewed_override", + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "string" + "object" ], "composed": false }, - "requiredness": "required", - "null_behavior": "rejected", - "empty_behavior": "rejected", + "requiredness": "conditional", + "null_behavior": "not_applicable", + "empty_behavior": "not_applicable", "default": { - "behavior": "no_schema_default" + "behavior": "not_applicable" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "structural", "state": "authored", "products": [ "registryctl", @@ -43675,32 +43467,39 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" ], "constraints": [ { - "keyword": "pattern", - "value": "^[A-Za-z_][A-Za-z0-9._:~-]{0,95}$" + "keyword": "required", + "value": [ + "type", + "name", + "max_value_bytes" + ] }, { "keyword": "type", - "value": "string" + "value": "object" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/2/properties/type", + "pointer": "/$defs/credential/oneOf/1/properties/max_value_bytes", "path_kind": "property" }, - "purpose": "Selects the fixed-query-parameter API-key credential interface for this source contract.", + "purpose": "Caps the credential value size accepted by the fixed-header API-key interface.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [], + "schema_types": [ + "integer" + ], "composed": false }, "requiredness": "required", @@ -43770,36 +43569,44 @@ ], "constraints": [ { - "keyword": "const", - "value": "api_key_query" + "keyword": "maximum", + "value": 4096 + }, + { + "keyword": "minimum", + "value": 1 + }, + { + "keyword": "type", + "value": "integer" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/3", - "path_kind": "branch" + "pointer": "/$defs/credential/oneOf/1/properties/name", + "path_kind": "property" }, - "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", - "purpose_source": "structural_taxonomy", + "purpose": "Declares the fixed HTTP header name used by the API-key credential interface.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "object" + "string" ], - "composed": true + "composed": false }, - "requiredness": "conditional", - "null_behavior": "not_applicable", - "empty_behavior": "not_applicable", + "requiredness": "required", + "null_behavior": "rejected", + "empty_behavior": "rejected", "default": { - "behavior": "not_applicable" + "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "structural", + "sensitivity": "internal", "state": "authored", "products": [ "registryctl", @@ -43855,32 +43662,27 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "branch_has_no_authored_value" + "generated_docs_never_load_country_values" ], "constraints": [ { - "keyword": "required", - "value": [ - "type", - "request", - "response_profile" - ] + "keyword": "pattern", + "value": "^[A-Za-z][A-Za-z0-9_-]{0,63}$" }, { "keyword": "type", - "value": "object" + "value": "string" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/3/allOf/0", - "path_kind": "branch" + "pointer": "/$defs/credential/oneOf/1/properties/type", + "path_kind": "property" }, - "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", - "purpose_source": "structural_taxonomy", + "purpose": "Selects the fixed-header API-key credential interface for this source contract.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", @@ -43888,14 +43690,14 @@ "schema_types": [], "composed": false }, - "requiredness": "conditional", - "null_behavior": "not_applicable", + "requiredness": "required", + "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { - "behavior": "not_applicable" + "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "structural", + "sensitivity": "internal", "state": "authored", "products": [ "registryctl", @@ -43951,15 +43753,19 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "branch_has_no_authored_value" + "generated_docs_never_load_country_values" ], - "constraints": [] + "constraints": [ + { + "keyword": "const", + "value": "api_key_header" + } + ] }, { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/3/allOf/0/if", + "pointer": "/$defs/credential/oneOf/2", "path_kind": "branch" }, "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", @@ -43968,7 +43774,9 @@ "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [], + "schema_types": [ + "object" + ], "composed": false }, "requiredness": "conditional", @@ -44041,24 +43849,32 @@ { "keyword": "required", "value": [ - "response_profile" + "type", + "name", + "max_value_bytes" ] + }, + { + "keyword": "type", + "value": "object" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/3/allOf/0/if/properties/response_profile", + "pointer": "/$defs/credential/oneOf/2/properties/max_value_bytes", "path_kind": "property" }, - "purpose": "Matches the strict no-expiry bearer profile before applying its refresh-control constraint.", - "purpose_source": "schema_description", + "purpose": "Caps the credential value size accepted by the fixed-query API-key interface.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [], + "schema_types": [ + "integer" + ], "composed": false }, "requiredness": "required", @@ -44128,34 +43944,44 @@ ], "constraints": [ { - "keyword": "const", - "value": "oauth2_bearer_no_expiry" + "keyword": "maximum", + "value": 4096 + }, + { + "keyword": "minimum", + "value": 1 + }, + { + "keyword": "type", + "value": "integer" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/3/allOf/0/then", - "path_kind": "branch" + "pointer": "/$defs/credential/oneOf/2/properties/name", + "path_kind": "property" }, - "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", - "purpose_source": "structural_taxonomy", + "purpose": "Declares the fixed query parameter name used by the API-key credential interface.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [], + "schema_types": [ + "string" + ], "composed": false }, - "requiredness": "conditional", - "null_behavior": "not_applicable", - "empty_behavior": "not_applicable", + "requiredness": "required", + "null_behavior": "rejected", + "empty_behavior": "rejected", "default": { - "behavior": "not_applicable" + "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "structural", + "sensitivity": "internal", "state": "authored", "products": [ "registryctl", @@ -44211,19 +44037,27 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "branch_has_no_authored_value" + "generated_docs_never_load_country_values" ], - "constraints": [] + "constraints": [ + { + "keyword": "pattern", + "value": "^[A-Za-z_][A-Za-z0-9._:~-]{0,95}$" + }, + { + "keyword": "type", + "value": "string" + } + ] }, { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/3/allOf/0/then/not", - "path_kind": "branch" + "pointer": "/$defs/credential/oneOf/2/properties/type", + "path_kind": "property" }, - "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", - "purpose_source": "structural_taxonomy", + "purpose": "Selects the fixed-query-parameter API-key credential interface for this source contract.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", @@ -44231,14 +44065,14 @@ "schema_types": [], "composed": false }, - "requiredness": "conditional", - "null_behavior": "not_applicable", + "requiredness": "required", + "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { - "behavior": "not_applicable" + "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "structural", + "sensitivity": "internal", "state": "authored", "products": [ "registryctl", @@ -44294,43 +44128,40 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "branch_has_no_authored_value" + "generated_docs_never_load_country_values" ], "constraints": [ { - "keyword": "required", - "value": [ - "refresh_skew" - ] + "keyword": "const", + "value": "api_key_query" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/3/properties/audience", - "path_kind": "property" + "pointer": "/$defs/credential/oneOf/3", + "path_kind": "branch" }, - "purpose": "Constrains OAuth token acquisition to the reviewed source audience and is treated as sensitive operational metadata.", - "purpose_source": "reviewed_override", + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "string" + "object" ], - "composed": false + "composed": true }, - "requiredness": "optional", - "null_behavior": "rejected", - "empty_behavior": "rejected", + "requiredness": "conditional", + "null_behavior": "not_applicable", + "empty_behavior": "not_applicable", "default": { - "behavior": "no_schema_default" + "behavior": "not_applicable" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "sensitive", + "sensitivity": "structural", "state": "authored", "products": [ "registryctl", @@ -44387,48 +44218,46 @@ "semantic_rules": [ "knowledge_only", "generated_docs_never_load_country_values", - "sensitive_operational_metadata" + "branch_has_no_authored_value" ], "constraints": [ { - "keyword": "maxLength", - "value": 2048 - }, - { - "keyword": "minLength", - "value": 1 + "keyword": "required", + "value": [ + "type", + "request", + "response_profile" + ] }, { "keyword": "type", - "value": "string" + "value": "object" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/3/properties/refresh_skew", - "path_kind": "property" + "pointer": "/$defs/credential/oneOf/3/allOf/0", + "path_kind": "branch" }, - "purpose": "With oauth2_bearer, sets a positive refresh interval below sixty seconds so a cached OAuth credential retains usable lifetime. The no-expiry profile rejects this field because caching is disabled.", - "purpose_source": "reviewed_override", + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [ - "string" - ], + "schema_types": [], "composed": false }, - "requiredness": "optional", - "null_behavior": "rejected", - "empty_behavior": "rejected", + "requiredness": "conditional", + "null_behavior": "not_applicable", + "empty_behavior": "not_applicable", "default": { - "behavior": "no_schema_default" + "behavior": "not_applicable" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "structural", "state": "authored", "products": [ "registryctl", @@ -44484,27 +44313,19 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" ], - "constraints": [ - { - "keyword": "pattern", - "value": "^(?:(?:[1-9][0-9]{0,3}|[1-5][0-9]{4})ms|(?:[1-9]|[1-5][0-9])s)$" - }, - { - "keyword": "type", - "value": "string" - } - ] + "constraints": [] }, { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/3/properties/request", - "path_kind": "property" + "pointer": "/$defs/credential/oneOf/3/allOf/0/if", + "path_kind": "branch" }, - "purpose": "Selects form-encoded or JSON token requests for the OAuth client-credentials interface.", - "purpose_source": "reviewed_override", + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", @@ -44512,14 +44333,14 @@ "schema_types": [], "composed": false }, - "requiredness": "required", - "null_behavior": "rejected", + "requiredness": "conditional", + "null_behavior": "not_applicable", "empty_behavior": "not_applicable", "default": { - "behavior": "no_schema_default" + "behavior": "not_applicable" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "structural", "state": "authored", "products": [ "registryctl", @@ -44575,14 +44396,14 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" ], "constraints": [ { - "keyword": "enum", + "keyword": "required", "value": [ - "form", - "json" + "response_profile" ] } ] @@ -44590,11 +44411,11 @@ { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/3/properties/response_profile", + "pointer": "/$defs/credential/oneOf/3/allOf/0/if/properties/response_profile", "path_kind": "property" }, - "purpose": "Selects an exact OAuth bearer-token response shape. oauth2_bearer requires access_token, token_type Bearer, and a bounded expires_in value and permits expiry-bound caching. oauth2_bearer_no_expiry requires only access_token and token_type Bearer, rejects expiry and extra fields, and disables token caching.", - "purpose_source": "reviewed_override", + "purpose": "Matches the strict no-expiry bearer profile before applying its refresh-control constraint.", + "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", @@ -44669,39 +44490,34 @@ ], "constraints": [ { - "keyword": "enum", - "value": [ - "oauth2_bearer", - "oauth2_bearer_no_expiry" - ] + "keyword": "const", + "value": "oauth2_bearer_no_expiry" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/3/properties/scope", - "path_kind": "property" + "pointer": "/$defs/credential/oneOf/3/allOf/0/then", + "path_kind": "branch" }, - "purpose": "Declares the bounded OAuth scope string requested for this source credential.", - "purpose_source": "reviewed_override", + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [ - "string" - ], + "schema_types": [], "composed": false }, - "requiredness": "optional", - "null_behavior": "rejected", - "empty_behavior": "rejected", + "requiredness": "conditional", + "null_behavior": "not_applicable", + "empty_behavior": "not_applicable", "default": { - "behavior": "no_schema_default" + "behavior": "not_applicable" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "structural", "state": "authored", "products": [ "registryctl", @@ -44757,31 +44573,19 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" ], - "constraints": [ - { - "keyword": "maxLength", - "value": 1024 - }, - { - "keyword": "minLength", - "value": 1 - }, - { - "keyword": "type", - "value": "string" - } - ] + "constraints": [] }, { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/3/properties/type", - "path_kind": "property" + "pointer": "/$defs/credential/oneOf/3/allOf/0/then/not", + "path_kind": "branch" }, - "purpose": "Selects the OAuth 2.0 client-credentials interface for source authentication.", - "purpose_source": "reviewed_override", + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", @@ -44789,14 +44593,14 @@ "schema_types": [], "composed": false }, - "requiredness": "required", - "null_behavior": "rejected", + "requiredness": "conditional", + "null_behavior": "not_applicable", "empty_behavior": "not_applicable", "default": { - "behavior": "no_schema_default" + "behavior": "not_applicable" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "structural", "state": "authored", "products": [ "registryctl", @@ -44852,38 +44656,43 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" ], "constraints": [ { - "keyword": "const", - "value": "oauth2_client_credentials" + "keyword": "required", + "value": [ + "refresh_skew" + ] } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/httpRequest/properties/body", + "pointer": "/$defs/credential/oneOf/3/properties/audience", "path_kind": "property" }, - "purpose": "Defines the optional authored body template sent by the declarative HTTP request.", + "purpose": "Constrains OAuth token acquisition to the reviewed source audience and is treated as sensitive operational metadata.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [], + "schema_types": [ + "string" + ], "composed": false }, "requiredness": "optional", "null_behavior": "rejected", - "empty_behavior": "not_applicable", + "empty_behavior": "rejected", "default": { "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "sensitive", "state": "authored", "products": [ "registryctl", @@ -44939,30 +44748,44 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "sensitive_operational_metadata" ], - "constraints": [] + "constraints": [ + { + "keyword": "maxLength", + "value": 2048 + }, + { + "keyword": "minLength", + "value": 1 + }, + { + "keyword": "type", + "value": "string" + } + ] }, { "address": { "schema": "integration", - "pointer": "/$defs/httpRequest/properties/headers", + "pointer": "/$defs/credential/oneOf/3/properties/refresh_skew", "path_kind": "property" }, - "purpose": "Maps reviewed request header names to authored values and input substitutions.", + "purpose": "With oauth2_bearer, sets a positive refresh interval below sixty seconds so a cached OAuth credential retains usable lifetime. The no-expiry profile rejects this field because caching is disabled.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "object" + "string" ], "composed": false }, "requiredness": "optional", "null_behavior": "rejected", - "empty_behavior": "not_applicable", + "empty_behavior": "rejected", "default": { "behavior": "no_schema_default" }, @@ -45027,38 +44850,33 @@ ], "constraints": [ { - "keyword": "maxProperties", - "value": 32 + "keyword": "pattern", + "value": "^(?:(?:[1-9][0-9]{0,3}|[1-5][0-9]{4})ms|(?:[1-9]|[1-5][0-9])s)$" }, { "keyword": "type", - "value": "object" + "value": "string" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/httpRequest/properties/headers/additionalProperties", - "path_kind": "map_value" + "pointer": "/$defs/credential/oneOf/3/properties/request", + "path_kind": "property" }, - "purpose": "Request value supplied from a declared input or an authored scalar literal.", - "purpose_source": "schema_description", + "purpose": "Selects form-encoded or JSON token requests for the OAuth client-credentials interface.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [ - "boolean", - "integer", - "string" - ], - "local_reference": "#/$defs/inputOrLiteral", + "schema_types": [], "composed": false }, - "requiredness": "not_applicable", + "requiredness": "required", "null_behavior": "rejected", - "empty_behavior": "allowed", + "empty_behavior": "not_applicable", "default": { "behavior": "no_schema_default" }, @@ -45119,22 +44937,25 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "arbitrary_map_keys_not_fixed_properties" + "generated_docs_never_load_country_values" ], - "constraints": [], - "local_reference": { - "schema": "integration", - "pointer": "/$defs/inputOrLiteral" - } + "constraints": [ + { + "keyword": "enum", + "value": [ + "form", + "json" + ] + } + ] }, { "address": { "schema": "integration", - "pointer": "/$defs/httpRequest/properties/method", + "pointer": "/$defs/credential/oneOf/3/properties/response_profile", "path_kind": "property" }, - "purpose": "Selects the single GET or POST request performed by a declarative HTTP capability.", + "purpose": "Selects an exact OAuth bearer-token response shape. oauth2_bearer requires access_token, token_type Bearer, and a bounded expires_in value and permits expiry-bound caching. oauth2_bearer_no_expiry requires only access_token and token_type Bearer, rejects expiry and extra fields, and disables token caching.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", @@ -45212,8 +45033,8 @@ { "keyword": "enum", "value": [ - "GET", - "POST" + "oauth2_bearer", + "oauth2_bearer_no_expiry" ] } ] @@ -45221,10 +45042,10 @@ { "address": { "schema": "integration", - "pointer": "/$defs/httpRequest/properties/path", + "pointer": "/$defs/credential/oneOf/3/properties/scope", "path_kind": "property" }, - "purpose": "Defines the reviewed source path template used by the declarative HTTP request.", + "purpose": "Declares the bounded OAuth scope string requested for this source credential.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", @@ -45235,14 +45056,14 @@ ], "composed": false }, - "requiredness": "required", + "requiredness": "optional", "null_behavior": "rejected", "empty_behavior": "rejected", "default": { "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "sensitive", + "sensitivity": "internal", "state": "authored", "products": [ "registryctl", @@ -45298,22 +45119,17 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "sensitive_operational_metadata" + "generated_docs_never_load_country_values" ], "constraints": [ { "keyword": "maxLength", - "value": 4096 + "value": 1024 }, { "keyword": "minLength", "value": 1 }, - { - "keyword": "pattern", - "value": "^/[^?#]*$" - }, { "keyword": "type", "value": "string" @@ -45323,21 +45139,19 @@ { "address": { "schema": "integration", - "pointer": "/$defs/httpRequest/properties/query", + "pointer": "/$defs/credential/oneOf/3/properties/type", "path_kind": "property" }, - "purpose": "Maps reviewed query parameter names to authored request values and input substitutions.", + "purpose": "Selects the OAuth 2.0 client-credentials interface for source authentication.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [ - "object" - ], + "schema_types": [], "composed": false }, - "requiredness": "optional", + "requiredness": "required", "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { @@ -45404,38 +45218,29 @@ ], "constraints": [ { - "keyword": "maxProperties", - "value": 64 - }, - { - "keyword": "type", - "value": "object" + "keyword": "const", + "value": "oauth2_client_credentials" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/httpRequest/properties/query/additionalProperties", - "path_kind": "map_value" + "pointer": "/$defs/httpRequest/properties/body", + "path_kind": "property" }, - "purpose": "Request value supplied from a declared input or an authored scalar literal.", - "purpose_source": "schema_description", + "purpose": "Defines the optional authored body template sent by the declarative HTTP request.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [ - "boolean", - "integer", - "string" - ], - "local_reference": "#/$defs/inputOrLiteral", + "schema_types": [], "composed": false }, - "requiredness": "not_applicable", + "requiredness": "optional", "null_behavior": "rejected", - "empty_behavior": "allowed", + "empty_behavior": "not_applicable", "default": { "behavior": "no_schema_default" }, @@ -45496,28 +45301,25 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "arbitrary_map_keys_not_fixed_properties" + "generated_docs_never_load_country_values" ], - "constraints": [], - "local_reference": { - "schema": "integration", - "pointer": "/$defs/inputOrLiteral" - } + "constraints": [] }, { "address": { "schema": "integration", - "pointer": "/$defs/httpRequest/properties/semantics", + "pointer": "/$defs/httpRequest/properties/headers", "path_kind": "property" }, - "purpose": "Declares that the declarative HTTP request has read-only source semantics.", + "purpose": "Maps reviewed request header names to authored values and input substitutions.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [], + "schema_types": [ + "object" + ], "composed": false }, "requiredness": "optional", @@ -45587,29 +45389,123 @@ ], "constraints": [ { - "keyword": "const", - "value": "read_only" + "keyword": "maxProperties", + "value": 32 + }, + { + "keyword": "type", + "value": "object" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/httpResponse/properties/ambiguous", - "path_kind": "property" + "pointer": "/$defs/httpRequest/properties/headers/additionalProperties", + "path_kind": "map_value" }, - "purpose": "Lists HTTP response statuses that produce the integration's ambiguous outcome.", - "purpose_source": "reviewed_override", + "purpose": "Request value supplied from a declared input or an authored scalar literal.", + "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "array" + "boolean", + "integer", + "string" ], + "local_reference": "#/$defs/inputOrLiteral", "composed": false }, - "requiredness": "optional", + "requiredness": "not_applicable", + "null_behavior": "rejected", + "empty_behavior": "allowed", + "default": { + "behavior": "no_schema_default" + }, + "environment_behavior": "narrows_reviewed_authority", + "sensitivity": "internal", + "state": "authored", + "products": [ + "registryctl", + "relay", + "notary", + "editor", + "docs" + ], + "availability": "published", + "stability": "experimental", + "validation_stages": [ + "json_schema", + "rust_deserialization", + "cross_file_semantic", + "fixture_execution", + "product_build" + ], + "diagnostic": "registryctl.authoring.integration.invalid", + "history_status": "not_verified", + "introduced_in": null, + "version_history": [], + "example": { + "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", + "schema_examples_available": false, + "contains_country_values": false + }, + "migration": "rebuild_project", + "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", + "consumers": [ + "registryctl_authoring", + "registry_relay", + "registry_notary", + "editor_tooling", + "docs_generator" + ], + "generated_artifacts": [ + "editor_schemas", + "project_build", + "relay_config", + "notary_config", + "fixture_report", + "field_reference" + ], + "review_classes": [ + "contract", + "security", + "privacy", + "relay", + "notary", + "compatibility", + "documentation", + "testing" + ], + "semantic_rules": [ + "knowledge_only", + "generated_docs_never_load_country_values", + "arbitrary_map_keys_not_fixed_properties" + ], + "constraints": [], + "local_reference": { + "schema": "integration", + "pointer": "/$defs/inputOrLiteral" + } + }, + { + "address": { + "schema": "integration", + "pointer": "/$defs/httpRequest/properties/method", + "path_kind": "property" + }, + "purpose": "Selects the single GET or POST request performed by a declarative HTTP capability.", + "purpose_source": "reviewed_override", + "semantic_owner": "integration_contract", + "human_owner": "integration_maintainers", + "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", + "field_type": { + "schema_types": [], + "composed": false + }, + "requiredness": "required", "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { @@ -45676,40 +45572,39 @@ ], "constraints": [ { - "keyword": "type", - "value": "array" - }, - { - "keyword": "uniqueItems", - "value": true + "keyword": "enum", + "value": [ + "GET", + "POST" + ] } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/httpResponse/properties/ambiguous/items", - "path_kind": "array_item" + "pointer": "/$defs/httpRequest/properties/path", + "path_kind": "property" }, - "purpose": "Defines the contract shared by each ordered item in the enclosing authored list.", - "purpose_source": "structural_taxonomy", + "purpose": "Defines the reviewed source path template used by the declarative HTTP request.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "integer" + "string" ], "composed": false }, - "requiredness": "not_applicable", + "requiredness": "required", "null_behavior": "rejected", - "empty_behavior": "not_applicable", + "empty_behavior": "rejected", "default": { "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "sensitive", "state": "authored", "products": [ "registryctl", @@ -45766,37 +45661,41 @@ "semantic_rules": [ "knowledge_only", "generated_docs_never_load_country_values", - "array_items_share_element_contract" + "sensitive_operational_metadata" ], "constraints": [ { - "keyword": "maximum", - "value": 599 + "keyword": "maxLength", + "value": 4096 }, { - "keyword": "minimum", - "value": 100 + "keyword": "minLength", + "value": 1 + }, + { + "keyword": "pattern", + "value": "^/[^?#]*$" }, { "keyword": "type", - "value": "integer" + "value": "string" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/httpResponse/properties/no_match", + "pointer": "/$defs/httpRequest/properties/query", "path_kind": "property" }, - "purpose": "Lists HTTP response statuses that produce the integration's no-match outcome.", + "purpose": "Maps reviewed query parameter names to authored request values and input substitutions.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "array" + "object" ], "composed": false }, @@ -45867,35 +45766,38 @@ ], "constraints": [ { - "keyword": "type", - "value": "array" + "keyword": "maxProperties", + "value": 64 }, { - "keyword": "uniqueItems", - "value": true + "keyword": "type", + "value": "object" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/httpResponse/properties/no_match/items", - "path_kind": "array_item" + "pointer": "/$defs/httpRequest/properties/query/additionalProperties", + "path_kind": "map_value" }, - "purpose": "Defines the contract shared by each ordered item in the enclosing authored list.", - "purpose_source": "structural_taxonomy", + "purpose": "Request value supplied from a declared input or an authored scalar literal.", + "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "integer" + "boolean", + "integer", + "string" ], + "local_reference": "#/$defs/inputOrLiteral", "composed": false }, "requiredness": "not_applicable", "null_behavior": "rejected", - "empty_behavior": "not_applicable", + "empty_behavior": "allowed", "default": { "behavior": "no_schema_default" }, @@ -45957,39 +45859,28 @@ "semantic_rules": [ "knowledge_only", "generated_docs_never_load_country_values", - "array_items_share_element_contract" + "arbitrary_map_keys_not_fixed_properties" ], - "constraints": [ - { - "keyword": "maximum", - "value": 599 - }, - { - "keyword": "minimum", - "value": 100 - }, - { - "keyword": "type", - "value": "integer" - } - ] + "constraints": [], + "local_reference": { + "schema": "integration", + "pointer": "/$defs/inputOrLiteral" + } }, { "address": { "schema": "integration", - "pointer": "/$defs/httpResponse/properties/shape", + "pointer": "/$defs/httpRequest/properties/semantics", "path_kind": "property" }, - "purpose": "Declares whether a successful response is a singleton or a bounded collection.", + "purpose": "Declares that the declarative HTTP request has read-only source semantics.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [ - "object" - ], - "composed": true + "schema_types": [], + "composed": false }, "requiredness": "optional", "null_behavior": "rejected", @@ -46056,121 +45947,38 @@ "knowledge_only", "generated_docs_never_load_country_values" ], - "constraints": [] - }, - { - "address": { - "schema": "integration", - "pointer": "/$defs/httpResponse/properties/shape/oneOf/0", - "path_kind": "branch" - }, - "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", - "purpose_source": "structural_taxonomy", - "semantic_owner": "integration_contract", - "human_owner": "integration_maintainers", - "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", - "field_type": { - "schema_types": [], - "composed": false - }, - "requiredness": "conditional", - "null_behavior": "not_applicable", - "empty_behavior": "not_applicable", - "default": { - "behavior": "not_applicable" - }, - "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "structural", - "state": "authored", - "products": [ - "registryctl", - "relay", - "notary", - "editor", - "docs" - ], - "availability": "published", - "stability": "experimental", - "validation_stages": [ - "json_schema", - "rust_deserialization", - "cross_file_semantic", - "fixture_execution", - "product_build" - ], - "diagnostic": "registryctl.authoring.integration.invalid", - "history_status": "not_verified", - "introduced_in": null, - "version_history": [], - "example": { - "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", - "schema_examples_available": false, - "contains_country_values": false - }, - "migration": "rebuild_project", - "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", - "consumers": [ - "registryctl_authoring", - "registry_relay", - "registry_notary", - "editor_tooling", - "docs_generator" - ], - "generated_artifacts": [ - "editor_schemas", - "project_build", - "relay_config", - "notary_config", - "fixture_report", - "field_reference" - ], - "review_classes": [ - "contract", - "security", - "privacy", - "relay", - "notary", - "compatibility", - "documentation", - "testing" - ], - "semantic_rules": [ - "knowledge_only", - "generated_docs_never_load_country_values", - "branch_has_no_authored_value" - ], "constraints": [ { "keyword": "const", - "value": "singleton" + "value": "read_only" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/httpResponse/properties/shape/oneOf/1", - "path_kind": "branch" + "pointer": "/$defs/httpResponse/properties/ambiguous", + "path_kind": "property" }, - "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", - "purpose_source": "structural_taxonomy", + "purpose": "Lists HTTP response statuses that produce the integration's ambiguous outcome.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "object" + "array" ], "composed": false }, - "requiredness": "conditional", - "null_behavior": "not_applicable", + "requiredness": "optional", + "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { - "behavior": "not_applicable" + "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "structural", + "sensitivity": "internal", "state": "authored", "products": [ "registryctl", @@ -46226,39 +46034,37 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "branch_has_no_authored_value" + "generated_docs_never_load_country_values" ], "constraints": [ { - "keyword": "required", - "value": [ - "records", - "cardinality" - ] + "keyword": "type", + "value": "array" }, { - "keyword": "type", - "value": "object" + "keyword": "uniqueItems", + "value": true } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/httpResponse/properties/shape/oneOf/1/properties/cardinality", - "path_kind": "property" + "pointer": "/$defs/httpResponse/properties/ambiguous/items", + "path_kind": "array_item" }, - "purpose": "Requires two-record probing so collection results distinguish one match from ambiguity.", - "purpose_source": "reviewed_override", + "purpose": "Defines the contract shared by each ordered item in the enclosing authored list.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [], + "schema_types": [ + "integer" + ], "composed": false }, - "requiredness": "required", + "requiredness": "not_applicable", "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { @@ -46321,35 +46127,44 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "array_items_share_element_contract" ], "constraints": [ { - "keyword": "const", - "value": "probe_two" + "keyword": "maximum", + "value": 599 + }, + { + "keyword": "minimum", + "value": 100 + }, + { + "keyword": "type", + "value": "integer" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/httpResponse/properties/shape/oneOf/1/properties/records", + "pointer": "/$defs/httpResponse/properties/no_match", "path_kind": "property" }, - "purpose": "Selects the canonical response location containing collection records.", + "purpose": "Lists HTTP response statuses that produce the integration's no-match outcome.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "string" + "array" ], "composed": false }, - "requiredness": "required", + "requiredness": "optional", "null_behavior": "rejected", - "empty_behavior": "rejected", + "empty_behavior": "not_applicable", "default": { "behavior": "no_schema_default" }, @@ -46414,31 +46229,33 @@ ], "constraints": [ { - "keyword": "pattern", - "value": "^/(?:[^/~]|~[01])+(?:/(?:[^/~]|~[01])+)*$" + "keyword": "type", + "value": "array" }, { - "keyword": "type", - "value": "string" + "keyword": "uniqueItems", + "value": true } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/input/properties/canonicalization", - "path_kind": "property" + "pointer": "/$defs/httpResponse/properties/no_match/items", + "path_kind": "array_item" }, - "purpose": "Selects the reviewed normalization rule applied before an input is compared, interpolated, or sent to a source.", - "purpose_source": "reviewed_override", + "purpose": "Defines the contract shared by each ordered item in the enclosing authored list.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [], + "schema_types": [ + "integer" + ], "composed": false }, - "requiredness": "optional", + "requiredness": "not_applicable", "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { @@ -46501,121 +46318,40 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "array_items_share_element_contract" ], "constraints": [ { - "keyword": "enum", - "value": [ - "identity", - "ascii_lowercase" - ] - } - ] - }, - { - "address": { - "schema": "integration", - "pointer": "/$defs/input/properties/format", - "path_kind": "property" - }, - "purpose": "Applies the full-date semantic format to a string-valued integration input.", - "purpose_source": "reviewed_override", - "semantic_owner": "integration_contract", - "human_owner": "integration_maintainers", - "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", - "field_type": { - "schema_types": [], - "composed": false - }, - "requiredness": "optional", - "null_behavior": "rejected", - "empty_behavior": "not_applicable", - "default": { - "behavior": "no_schema_default" - }, - "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", - "state": "authored", - "products": [ - "registryctl", - "relay", - "notary", - "editor", - "docs" - ], - "availability": "published", - "stability": "experimental", - "validation_stages": [ - "json_schema", - "rust_deserialization", - "cross_file_semantic", - "fixture_execution", - "product_build" - ], - "diagnostic": "registryctl.authoring.integration.invalid", - "history_status": "not_verified", - "introduced_in": null, - "version_history": [], - "example": { - "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", - "schema_examples_available": false, - "contains_country_values": false - }, - "migration": "rebuild_project", - "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", - "consumers": [ - "registryctl_authoring", - "registry_relay", - "registry_notary", - "editor_tooling", - "docs_generator" - ], - "generated_artifacts": [ - "editor_schemas", - "project_build", - "relay_config", - "notary_config", - "fixture_report", - "field_reference" - ], - "review_classes": [ - "contract", - "security", - "privacy", - "relay", - "notary", - "compatibility", - "documentation", - "testing" - ], - "semantic_rules": [ - "knowledge_only", - "generated_docs_never_load_country_values" - ], - "constraints": [ + "keyword": "maximum", + "value": 599 + }, { - "keyword": "const", - "value": "date" + "keyword": "minimum", + "value": 100 + }, + { + "keyword": "type", + "value": "integer" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/input/properties/maxLength", + "pointer": "/$defs/httpResponse/properties/shape", "path_kind": "property" }, - "purpose": "Caps a string-valued integration input at 1,024 Unicode scalar values, deriving its conservative 4,096-byte UTF-8 ceiling.", + "purpose": "Declares whether a successful response is a singleton or a bounded collection.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "integer" + "object" ], - "composed": false + "composed": true }, "requiredness": "optional", "null_behavior": "rejected", @@ -46682,46 +46418,31 @@ "knowledge_only", "generated_docs_never_load_country_values" ], - "constraints": [ - { - "keyword": "maximum", - "value": 1024 - }, - { - "keyword": "minimum", - "value": 1 - }, - { - "keyword": "type", - "value": "integer" - } - ] + "constraints": [] }, { "address": { "schema": "integration", - "pointer": "/$defs/input/properties/maximum", - "path_kind": "property" + "pointer": "/$defs/httpResponse/properties/shape/oneOf/0", + "path_kind": "branch" }, - "purpose": "Sets the inclusive upper bound accepted for an integer-valued integration input.", - "purpose_source": "reviewed_override", + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [ - "integer" - ], + "schema_types": [], "composed": false }, - "requiredness": "optional", - "null_behavior": "rejected", + "requiredness": "conditional", + "null_behavior": "not_applicable", "empty_behavior": "not_applicable", "default": { - "behavior": "no_schema_default" + "behavior": "not_applicable" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "structural", "state": "authored", "products": [ "registryctl", @@ -46777,48 +46498,41 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" ], "constraints": [ { - "keyword": "maximum", - "value": 9007199254740991 - }, - { - "keyword": "minimum", - "value": -9007199254740991 - }, - { - "keyword": "type", - "value": "integer" + "keyword": "const", + "value": "singleton" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/input/properties/minLength", - "path_kind": "property" + "pointer": "/$defs/httpResponse/properties/shape/oneOf/1", + "path_kind": "branch" }, - "purpose": "Sets the minimum character length accepted for a string-valued integration input.", - "purpose_source": "reviewed_override", + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "integer" + "object" ], "composed": false }, - "requiredness": "optional", - "null_behavior": "rejected", + "requiredness": "conditional", + "null_behavior": "not_applicable", "empty_behavior": "not_applicable", "default": { - "behavior": "no_schema_default" + "behavior": "not_applicable" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "structural", "state": "authored", "products": [ "registryctl", @@ -46874,41 +46588,39 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" ], "constraints": [ { - "keyword": "maximum", - "value": 16384 - }, - { - "keyword": "minimum", - "value": 0 + "keyword": "required", + "value": [ + "records", + "cardinality" + ] }, { "keyword": "type", - "value": "integer" + "value": "object" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/input/properties/minimum", + "pointer": "/$defs/httpResponse/properties/shape/oneOf/1/properties/cardinality", "path_kind": "property" }, - "purpose": "Sets the inclusive lower bound accepted for an integer-valued integration input.", + "purpose": "Requires two-record probing so collection results distinguish one match from ambiguity.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [ - "integer" - ], + "schema_types": [], "composed": false }, - "requiredness": "optional", + "requiredness": "required", "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { @@ -46975,26 +46687,18 @@ ], "constraints": [ { - "keyword": "maximum", - "value": 9007199254740991 - }, - { - "keyword": "minimum", - "value": -9007199254740991 - }, - { - "keyword": "type", - "value": "integer" + "keyword": "const", + "value": "probe_two" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/input/properties/pattern", + "pointer": "/$defs/httpResponse/properties/shape/oneOf/1/properties/records", "path_kind": "property" }, - "purpose": "Constrains a string-valued integration input with the authored regular expression.", + "purpose": "Selects the canonical response location containing collection records.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", @@ -47005,7 +46709,7 @@ ], "composed": false }, - "requiredness": "optional", + "requiredness": "required", "null_behavior": "rejected", "empty_behavior": "rejected", "default": { @@ -47072,12 +46776,8 @@ ], "constraints": [ { - "keyword": "maxLength", - "value": 16384 - }, - { - "keyword": "minLength", - "value": 1 + "keyword": "pattern", + "value": "^/(?:[^/~]|~[01])+(?:/(?:[^/~]|~[01])+)*$" }, { "keyword": "type", @@ -47088,10 +46788,10 @@ { "address": { "schema": "integration", - "pointer": "/$defs/input/properties/role", + "pointer": "/$defs/input/properties/canonicalization", "path_kind": "property" }, - "purpose": "Declares how one typed authoring input participates in source lookup, selection, or result shaping.", + "purpose": "Selects the reviewed normalization rule applied before an input is compared, interpolated, or sent to a source.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", @@ -47100,7 +46800,7 @@ "schema_types": [], "composed": false }, - "requiredness": "required", + "requiredness": "optional", "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { @@ -47169,8 +46869,8 @@ { "keyword": "enum", "value": [ - "selector", - "parameter" + "identity", + "ascii_lowercase" ] } ] @@ -47178,22 +46878,19 @@ { "address": { "schema": "integration", - "pointer": "/$defs/input/properties/type", + "pointer": "/$defs/input/properties/format", "path_kind": "property" }, - "purpose": "Declares the closed scalar or array type accepted for one integration input.", + "purpose": "Applies the full-date semantic format to a string-valued integration input.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [ - "array" - ], - "local_reference": "#/$defs/scalarType", + "schema_types": [], "composed": false }, - "requiredness": "required", + "requiredness": "optional", "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { @@ -47258,140 +46955,38 @@ "knowledge_only", "generated_docs_never_load_country_values" ], - "constraints": [], - "local_reference": { - "schema": "integration", - "pointer": "/$defs/scalarType" - } - }, - { - "address": { - "schema": "integration", - "pointer": "/$defs/inputOrLiteral/oneOf/0", - "path_kind": "branch" - }, - "purpose": "Reference to a declared integration input.", - "purpose_source": "schema_description", - "semantic_owner": "integration_contract", - "human_owner": "integration_maintainers", - "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", - "field_type": { - "schema_types": [ - "object" - ], - "local_reference": "#/$defs/inputReference", - "composed": false - }, - "requiredness": "conditional", - "null_behavior": "not_applicable", - "empty_behavior": "not_applicable", - "default": { - "behavior": "not_applicable" - }, - "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "structural", - "state": "authored", - "products": [ - "registryctl", - "relay", - "notary", - "editor", - "docs" - ], - "availability": "published", - "stability": "experimental", - "validation_stages": [ - "json_schema", - "rust_deserialization", - "cross_file_semantic", - "fixture_execution", - "product_build" - ], - "diagnostic": "registryctl.authoring.integration.invalid", - "history_status": "not_verified", - "introduced_in": null, - "version_history": [], - "example": { - "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", - "schema_examples_available": false, - "contains_country_values": false - }, - "migration": "rebuild_project", - "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", - "consumers": [ - "registryctl_authoring", - "registry_relay", - "registry_notary", - "editor_tooling", - "docs_generator" - ], - "generated_artifacts": [ - "editor_schemas", - "project_build", - "relay_config", - "notary_config", - "fixture_report", - "field_reference" - ], - "review_classes": [ - "contract", - "security", - "privacy", - "relay", - "notary", - "compatibility", - "documentation", - "testing" - ], - "semantic_rules": [ - "knowledge_only", - "generated_docs_never_load_country_values", - "branch_has_no_authored_value" - ], "constraints": [ { - "keyword": "required", - "value": [ - "input" - ] - }, - { - "keyword": "type", - "value": "object" + "keyword": "const", + "value": "date" } - ], - "local_reference": { - "schema": "integration", - "pointer": "/$defs/inputReference" - } + ] }, { "address": { "schema": "integration", - "pointer": "/$defs/inputOrLiteral/oneOf/1", - "path_kind": "branch" + "pointer": "/$defs/input/properties/maxLength", + "path_kind": "property" }, - "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", - "purpose_source": "structural_taxonomy", + "purpose": "Caps a string-valued integration input at 1,024 Unicode scalar values, deriving its conservative 4,096-byte UTF-8 ceiling.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "boolean", - "integer", - "string" + "integer" ], "composed": false }, - "requiredness": "conditional", - "null_behavior": "not_applicable", + "requiredness": "optional", + "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { - "behavior": "not_applicable" + "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "structural", + "sensitivity": "internal", "state": "authored", "products": [ "registryctl", @@ -47447,41 +47042,43 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "branch_has_no_authored_value" + "generated_docs_never_load_country_values" ], "constraints": [ + { + "keyword": "maximum", + "value": 1024 + }, + { + "keyword": "minimum", + "value": 1 + }, { "keyword": "type", - "value": [ - "string", - "boolean", - "integer" - ] + "value": "integer" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/inputReference/properties/input", + "pointer": "/$defs/input/properties/maximum", "path_kind": "property" }, - "purpose": "Portable lowercase name for an integration input or output.", - "purpose_source": "schema_description", + "purpose": "Sets the inclusive upper bound accepted for an integer-valued integration input.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "string" + "integer" ], - "local_reference": "#/$defs/inputName", "composed": false }, - "requiredness": "required", + "requiredness": "optional", "null_behavior": "rejected", - "empty_behavior": "rejected", + "empty_behavior": "not_applicable", "default": { "behavior": "no_schema_default" }, @@ -47546,27 +47143,27 @@ ], "constraints": [ { - "keyword": "pattern", - "value": "^[a-z][a-z0-9_]{0,63}$" + "keyword": "maximum", + "value": 9007199254740991 + }, + { + "keyword": "minimum", + "value": -9007199254740991 }, { "keyword": "type", - "value": "string" + "value": "integer" } - ], - "local_reference": { - "schema": "integration", - "pointer": "/$defs/inputName" - } + ] }, { "address": { "schema": "integration", - "pointer": "/$defs/integrationRequestByteSize/oneOf/0", - "path_kind": "branch" + "pointer": "/$defs/input/properties/minLength", + "path_kind": "property" }, - "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", - "purpose_source": "structural_taxonomy", + "purpose": "Sets the minimum character length accepted for a string-valued integration input.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", @@ -47576,14 +47173,14 @@ ], "composed": false }, - "requiredness": "conditional", - "null_behavior": "not_applicable", + "requiredness": "optional", + "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { - "behavior": "not_applicable" + "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "structural", + "sensitivity": "internal", "state": "authored", "products": [ "registryctl", @@ -47639,17 +47236,16 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "branch_has_no_authored_value" + "generated_docs_never_load_country_values" ], "constraints": [ { "keyword": "maximum", - "value": 1048576 + "value": 16384 }, { "keyword": "minimum", - "value": 1 + "value": 0 }, { "keyword": "type", @@ -47660,28 +47256,28 @@ { "address": { "schema": "integration", - "pointer": "/$defs/integrationRequestByteSize/oneOf/1", - "path_kind": "branch" + "pointer": "/$defs/input/properties/minimum", + "path_kind": "property" }, - "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", - "purpose_source": "structural_taxonomy", + "purpose": "Sets the inclusive lower bound accepted for an integer-valued integration input.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "string" + "integer" ], "composed": false }, - "requiredness": "conditional", - "null_behavior": "not_applicable", + "requiredness": "optional", + "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { - "behavior": "not_applicable" + "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "structural", + "sensitivity": "internal", "state": "authored", "products": [ "registryctl", @@ -47737,45 +47333,48 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "branch_has_no_authored_value" + "generated_docs_never_load_country_values" ], "constraints": [ { - "keyword": "pattern", - "value": "^(?:(?:[1-9][0-9]{0,2}|10[0-1][0-9]|102[0-4])KiB|1MiB)$" + "keyword": "maximum", + "value": 9007199254740991 + }, + { + "keyword": "minimum", + "value": -9007199254740991 }, { "keyword": "type", - "value": "string" + "value": "integer" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/integrationResponseByteSize/oneOf/0", - "path_kind": "branch" + "pointer": "/$defs/input/properties/pattern", + "path_kind": "property" }, - "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", - "purpose_source": "structural_taxonomy", + "purpose": "Constrains a string-valued integration input with the authored regular expression.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "integer" + "string" ], "composed": false }, - "requiredness": "conditional", - "null_behavior": "not_applicable", - "empty_behavior": "not_applicable", + "requiredness": "optional", + "null_behavior": "rejected", + "empty_behavior": "rejected", "default": { - "behavior": "not_applicable" + "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "structural", + "sensitivity": "internal", "state": "authored", "products": [ "registryctl", @@ -47831,49 +47430,46 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "branch_has_no_authored_value" + "generated_docs_never_load_country_values" ], "constraints": [ { - "keyword": "maximum", - "value": 8388608 + "keyword": "maxLength", + "value": 16384 }, { - "keyword": "minimum", + "keyword": "minLength", "value": 1 }, { "keyword": "type", - "value": "integer" + "value": "string" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/integrationResponseByteSize/oneOf/1", - "path_kind": "branch" + "pointer": "/$defs/input/properties/role", + "path_kind": "property" }, - "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", - "purpose_source": "structural_taxonomy", + "purpose": "Declares how one typed authoring input participates in source lookup, selection, or result shaping.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [ - "string" - ], + "schema_types": [], "composed": false }, - "requiredness": "conditional", - "null_behavior": "not_applicable", + "requiredness": "required", + "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { - "behavior": "not_applicable" + "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "structural", + "sensitivity": "internal", "state": "authored", "products": [ "registryctl", @@ -47929,35 +47525,123 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "branch_has_no_authored_value" + "generated_docs_never_load_country_values" ], "constraints": [ { - "keyword": "pattern", - "value": "^(?:(?:[1-9][0-9]{0,2}|[1-7][0-9]{3}|80[0-9]{2}|81[0-8][0-9]|819[0-2])KiB|[1-8]MiB)$" - }, - { - "keyword": "type", - "value": "string" + "keyword": "enum", + "value": [ + "selector", + "parameter" + ] } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/integrationSourceByteSize/oneOf/0", + "pointer": "/$defs/input/properties/type", + "path_kind": "property" + }, + "purpose": "Declares the closed scalar or array type accepted for one integration input.", + "purpose_source": "reviewed_override", + "semantic_owner": "integration_contract", + "human_owner": "integration_maintainers", + "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", + "field_type": { + "schema_types": [ + "array" + ], + "local_reference": "#/$defs/scalarType", + "composed": false + }, + "requiredness": "required", + "null_behavior": "rejected", + "empty_behavior": "not_applicable", + "default": { + "behavior": "no_schema_default" + }, + "environment_behavior": "narrows_reviewed_authority", + "sensitivity": "internal", + "state": "authored", + "products": [ + "registryctl", + "relay", + "notary", + "editor", + "docs" + ], + "availability": "published", + "stability": "experimental", + "validation_stages": [ + "json_schema", + "rust_deserialization", + "cross_file_semantic", + "fixture_execution", + "product_build" + ], + "diagnostic": "registryctl.authoring.integration.invalid", + "history_status": "not_verified", + "introduced_in": null, + "version_history": [], + "example": { + "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", + "schema_examples_available": false, + "contains_country_values": false + }, + "migration": "rebuild_project", + "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", + "consumers": [ + "registryctl_authoring", + "registry_relay", + "registry_notary", + "editor_tooling", + "docs_generator" + ], + "generated_artifacts": [ + "editor_schemas", + "project_build", + "relay_config", + "notary_config", + "fixture_report", + "field_reference" + ], + "review_classes": [ + "contract", + "security", + "privacy", + "relay", + "notary", + "compatibility", + "documentation", + "testing" + ], + "semantic_rules": [ + "knowledge_only", + "generated_docs_never_load_country_values" + ], + "constraints": [], + "local_reference": { + "schema": "integration", + "pointer": "/$defs/scalarType" + } + }, + { + "address": { + "schema": "integration", + "pointer": "/$defs/inputOrLiteral/oneOf/0", "path_kind": "branch" }, - "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", - "purpose_source": "structural_taxonomy", + "purpose": "Reference to a declared integration input.", + "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "integer" + "object" ], + "local_reference": "#/$defs/inputReference", "composed": false }, "requiredness": "conditional", @@ -48028,23 +47712,25 @@ ], "constraints": [ { - "keyword": "maximum", - "value": 16777216 - }, - { - "keyword": "minimum", - "value": 1 + "keyword": "required", + "value": [ + "input" + ] }, { "keyword": "type", - "value": "integer" + "value": "object" } - ] + ], + "local_reference": { + "schema": "integration", + "pointer": "/$defs/inputReference" + } }, { "address": { "schema": "integration", - "pointer": "/$defs/integrationSourceByteSize/oneOf/1", + "pointer": "/$defs/inputOrLiteral/oneOf/1", "path_kind": "branch" }, "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", @@ -48054,6 +47740,8 @@ "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ + "boolean", + "integer", "string" ], "composed": false @@ -48125,36 +47813,37 @@ "branch_has_no_authored_value" ], "constraints": [ - { - "keyword": "pattern", - "value": "^(?:(?:[1-9][0-9]{0,3}|1[0-5][0-9]{3}|16[0-2][0-9]{2}|163[0-7][0-9]|1638[0-4])KiB|(?:[1-9]|1[0-6])MiB)$" - }, { "keyword": "type", - "value": "string" + "value": [ + "string", + "boolean", + "integer" + ] } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/limits/properties/calls", + "pointer": "/$defs/inputReference/properties/input", "path_kind": "property" }, - "purpose": "Caps the number of high-level source calls available to a script integration.", - "purpose_source": "reviewed_override", + "purpose": "Portable lowercase name for an integration input or output.", + "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "integer" + "string" ], + "local_reference": "#/$defs/inputName", "composed": false }, - "requiredness": "optional", + "requiredness": "required", "null_behavior": "rejected", - "empty_behavior": "not_applicable", + "empty_behavior": "rejected", "default": { "behavior": "no_schema_default" }, @@ -48219,44 +47908,44 @@ ], "constraints": [ { - "keyword": "maximum", - "value": 16 - }, - { - "keyword": "minimum", - "value": 1 + "keyword": "pattern", + "value": "^[a-z][a-z0-9_]{0,63}$" }, { "keyword": "type", - "value": "integer" + "value": "string" } - ] + ], + "local_reference": { + "schema": "integration", + "pointer": "/$defs/inputName" + } }, { "address": { "schema": "integration", - "pointer": "/$defs/limits/properties/deadline", - "path_kind": "property" + "pointer": "/$defs/integrationRequestByteSize/oneOf/0", + "path_kind": "branch" }, - "purpose": "Caps total integration execution time with a positive duration no greater than twenty seconds.", - "purpose_source": "reviewed_override", + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "string" + "integer" ], "composed": false }, - "requiredness": "optional", - "null_behavior": "rejected", - "empty_behavior": "rejected", + "requiredness": "conditional", + "null_behavior": "not_applicable", + "empty_behavior": "not_applicable", "default": { - "behavior": "no_schema_default" + "behavior": "not_applicable" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "structural", "state": "authored", "products": [ "registryctl", @@ -48312,47 +48001,49 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" ], "constraints": [ { - "keyword": "pattern", - "value": "^(?:(?:[1-9][0-9]{0,3}|1[0-9]{4}|20000)ms|(?:[1-9]|1[0-9]|20)s)$" + "keyword": "maximum", + "value": 1048576 + }, + { + "keyword": "minimum", + "value": 1 }, { "keyword": "type", - "value": "string" + "value": "integer" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/limits/properties/request_bytes", - "path_kind": "property" + "pointer": "/$defs/integrationRequestByteSize/oneOf/1", + "path_kind": "branch" }, - "purpose": "Maximum aggregate author-controlled request bytes for one execution, defaulting to 64 KiB and capped at 1 MiB. Use a positive byte integer or canonical KiB/MiB value.", - "purpose_source": "schema_description", + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "integer", "string" ], - "local_reference": "#/$defs/integrationRequestByteSize", "composed": false }, - "requiredness": "optional", - "null_behavior": "rejected", - "empty_behavior": "rejected", + "requiredness": "conditional", + "null_behavior": "not_applicable", + "empty_behavior": "not_applicable", "default": { - "behavior": "schema_default", - "schema_value": "64KiB" + "behavior": "not_applicable" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "structural", "state": "authored", "products": [ "registryctl", @@ -48408,42 +48099,45 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" ], - "constraints": [], - "local_reference": { - "schema": "integration", - "pointer": "/$defs/integrationRequestByteSize" - } + "constraints": [ + { + "keyword": "pattern", + "value": "^(?:(?:[1-9][0-9]{0,2}|10[0-1][0-9]|102[0-4])KiB|1MiB)$" + }, + { + "keyword": "type", + "value": "string" + } + ] }, { "address": { "schema": "integration", - "pointer": "/$defs/limits/properties/source_bytes", - "path_kind": "property" + "pointer": "/$defs/integrationResponseByteSize/oneOf/0", + "path_kind": "branch" }, - "purpose": "Maximum aggregate source-response bytes for one execution, defaulting to 2 MiB and capped at 16 MiB. Use a positive byte integer or canonical KiB/MiB value.", - "purpose_source": "schema_description", + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "integer", - "string" + "integer" ], - "local_reference": "#/$defs/integrationSourceByteSize", "composed": false }, - "requiredness": "optional", - "null_behavior": "rejected", - "empty_behavior": "rejected", + "requiredness": "conditional", + "null_behavior": "not_applicable", + "empty_behavior": "not_applicable", "default": { - "behavior": "schema_default", - "schema_value": "2MiB" + "behavior": "not_applicable" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "structural", "state": "authored", "products": [ "registryctl", @@ -48499,40 +48193,49 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" ], - "constraints": [], - "local_reference": { - "schema": "integration", - "pointer": "/$defs/integrationSourceByteSize" - } + "constraints": [ + { + "keyword": "maximum", + "value": 8388608 + }, + { + "keyword": "minimum", + "value": 1 + }, + { + "keyword": "type", + "value": "integer" + } + ] }, { "address": { "schema": "integration", - "pointer": "/$defs/notApplicable/properties/ambiguity", - "path_kind": "property" + "pointer": "/$defs/integrationResponseByteSize/oneOf/1", + "path_kind": "branch" }, - "purpose": "Why the reviewed source contract cannot produce more than one matching record.", - "purpose_source": "schema_description", + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "object" + "string" ], - "local_reference": "#/$defs/notApplicableReason", "composed": false }, - "requiredness": "optional", - "null_behavior": "rejected", + "requiredness": "conditional", + "null_behavior": "not_applicable", "empty_behavior": "not_applicable", "default": { - "behavior": "no_schema_default" + "behavior": "not_applicable" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "structural", "state": "authored", "products": [ "registryctl", @@ -48588,52 +48291,45 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" ], "constraints": [ { - "keyword": "required", - "value": [ - "rationale", - "request_fixture" - ] + "keyword": "pattern", + "value": "^(?:(?:[1-9][0-9]{0,2}|[1-7][0-9]{3}|80[0-9]{2}|81[0-8][0-9]|819[0-2])KiB|[1-8]MiB)$" }, { "keyword": "type", - "value": "object" + "value": "string" } - ], - "local_reference": { - "schema": "integration", - "pointer": "/$defs/notApplicableReason" - } + ] }, { "address": { "schema": "integration", - "pointer": "/$defs/notApplicable/properties/subject_mismatch", - "path_kind": "property" + "pointer": "/$defs/integrationSourceByteSize/oneOf/0", + "path_kind": "branch" }, - "purpose": "Why the reviewed response contract contains no identifier comparable with a requested selector.", - "purpose_source": "schema_description", + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "object" + "integer" ], - "local_reference": "#/$defs/notApplicableReason", "composed": false }, - "requiredness": "optional", - "null_behavior": "rejected", + "requiredness": "conditional", + "null_behavior": "not_applicable", "empty_behavior": "not_applicable", "default": { - "behavior": "no_schema_default" + "behavior": "not_applicable" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "structural", "state": "authored", "products": [ "registryctl", @@ -48689,34 +48385,32 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" ], "constraints": [ { - "keyword": "required", - "value": [ - "rationale", - "request_fixture" - ] + "keyword": "maximum", + "value": 16777216 + }, + { + "keyword": "minimum", + "value": 1 }, { "keyword": "type", - "value": "object" + "value": "integer" } - ], - "local_reference": { - "schema": "integration", - "pointer": "/$defs/notApplicableReason" - } + ] }, { "address": { "schema": "integration", - "pointer": "/$defs/notApplicableReason/properties/rationale", - "path_kind": "property" + "pointer": "/$defs/integrationSourceByteSize/oneOf/1", + "path_kind": "branch" }, - "purpose": "Why the named normally required outcome cannot occur for this source contract.", - "purpose_source": "schema_description", + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", @@ -48726,14 +48420,14 @@ ], "composed": false }, - "requiredness": "required", - "null_behavior": "rejected", - "empty_behavior": "rejected", + "requiredness": "conditional", + "null_behavior": "not_applicable", + "empty_behavior": "not_applicable", "default": { - "behavior": "no_schema_default" + "behavior": "not_applicable" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "structural", "state": "authored", "products": [ "registryctl", @@ -48789,16 +48483,13 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" ], "constraints": [ { - "keyword": "maxLength", - "value": 512 - }, - { - "keyword": "minLength", - "value": 24 + "keyword": "pattern", + "value": "^(?:(?:[1-9][0-9]{0,3}|1[0-5][0-9]{3}|16[0-2][0-9]{2}|163[0-7][0-9]|1638[0-4])KiB|(?:[1-9]|1[0-6])MiB)$" }, { "keyword": "type", @@ -48809,24 +48500,23 @@ { "address": { "schema": "integration", - "pointer": "/$defs/notApplicableReason/properties/request_fixture", + "pointer": "/$defs/limits/properties/calls", "path_kind": "property" }, - "purpose": "Fixture name containing the supporting bounded source request.", - "purpose_source": "schema_description", + "purpose": "Caps the number of high-level source calls available to a script integration.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "string" + "integer" ], - "local_reference": "#/$defs/stableId", "composed": false }, - "requiredness": "required", + "requiredness": "optional", "null_behavior": "rejected", - "empty_behavior": "rejected", + "empty_behavior": "not_applicable", "default": { "behavior": "no_schema_default" }, @@ -48891,45 +48581,44 @@ ], "constraints": [ { - "keyword": "pattern", - "value": "^[a-z][a-z0-9._-]{0,95}$" + "keyword": "maximum", + "value": 16 + }, + { + "keyword": "minimum", + "value": 1 }, { "keyword": "type", - "value": "string" + "value": "integer" } - ], - "local_reference": { - "schema": "integration", - "pointer": "/$defs/stableId" - } + ] }, { "address": { "schema": "integration", - "pointer": "/$defs/output/oneOf/0", - "path_kind": "branch" + "pointer": "/$defs/limits/properties/deadline", + "path_kind": "property" }, - "purpose": "Type, scalar bounds, and optional source pointer for one normalized scalar integration output.", - "purpose_source": "schema_description", + "purpose": "Caps total integration execution time with a positive duration no greater than twenty seconds.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "object" + "string" ], - "local_reference": "#/$defs/scalarOutput", "composed": false }, - "requiredness": "conditional", - "null_behavior": "not_applicable", - "empty_behavior": "not_applicable", + "requiredness": "optional", + "null_behavior": "rejected", + "empty_behavior": "rejected", "default": { - "behavior": "not_applicable" + "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "structural", + "sensitivity": "internal", "state": "authored", "products": [ "registryctl", @@ -48985,52 +48674,47 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "branch_has_no_authored_value" + "generated_docs_never_load_country_values" ], "constraints": [ { - "keyword": "required", - "value": [ - "type" - ] + "keyword": "pattern", + "value": "^(?:(?:[1-9][0-9]{0,3}|1[0-9]{4}|20000)ms|(?:[1-9]|1[0-9]|20)s)$" }, { "keyword": "type", - "value": "object" + "value": "string" } - ], - "local_reference": { - "schema": "integration", - "pointer": "/$defs/scalarOutput" - } + ] }, { "address": { "schema": "integration", - "pointer": "/$defs/output/oneOf/1", - "path_kind": "branch" + "pointer": "/$defs/limits/properties/request_bytes", + "path_kind": "property" }, - "purpose": "A recursively typed object output with a canonical byte ceiling and an always-closed field map.", + "purpose": "Maximum aggregate author-controlled request bytes for one execution, defaulting to 64 KiB and capped at 1 MiB. Use a positive byte integer or canonical KiB/MiB value.", "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "object" + "integer", + "string" ], - "local_reference": "#/$defs/outputObject", + "local_reference": "#/$defs/integrationRequestByteSize", "composed": false }, - "requiredness": "conditional", - "null_behavior": "not_applicable", - "empty_behavior": "not_applicable", + "requiredness": "optional", + "null_behavior": "rejected", + "empty_behavior": "rejected", "default": { - "behavior": "not_applicable" + "behavior": "schema_default", + "schema_value": "64KiB" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "structural", + "sensitivity": "internal", "state": "authored", "products": [ "registryctl", @@ -49086,155 +48770,39 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "branch_has_no_authored_value" - ], - "constraints": [ - { - "keyword": "required", - "value": [ - "type", - "nullable", - "max_bytes", - "fields" - ] - }, - { - "keyword": "type", - "value": "object" - } + "generated_docs_never_load_country_values" ], + "constraints": [], "local_reference": { "schema": "integration", - "pointer": "/$defs/outputObject" + "pointer": "/$defs/integrationRequestByteSize" } }, { "address": { "schema": "integration", - "pointer": "/$defs/output/oneOf/2", - "path_kind": "branch" + "pointer": "/$defs/limits/properties/source_bytes", + "path_kind": "property" }, - "purpose": "A recursively typed array output with canonical byte and item-count ceilings.", + "purpose": "Maximum aggregate source-response bytes for one execution, defaulting to 2 MiB and capped at 16 MiB. Use a positive byte integer or canonical KiB/MiB value.", "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "object" + "integer", + "string" ], - "local_reference": "#/$defs/outputArray", - "composed": false - }, - "requiredness": "conditional", - "null_behavior": "not_applicable", - "empty_behavior": "not_applicable", - "default": { - "behavior": "not_applicable" - }, - "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "structural", - "state": "authored", - "products": [ - "registryctl", - "relay", - "notary", - "editor", - "docs" - ], - "availability": "published", - "stability": "experimental", - "validation_stages": [ - "json_schema", - "rust_deserialization", - "cross_file_semantic", - "fixture_execution", - "product_build" - ], - "diagnostic": "registryctl.authoring.integration.invalid", - "history_status": "not_verified", - "introduced_in": null, - "version_history": [], - "example": { - "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", - "schema_examples_available": false, - "contains_country_values": false - }, - "migration": "rebuild_project", - "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", - "consumers": [ - "registryctl_authoring", - "registry_relay", - "registry_notary", - "editor_tooling", - "docs_generator" - ], - "generated_artifacts": [ - "editor_schemas", - "project_build", - "relay_config", - "notary_config", - "fixture_report", - "field_reference" - ], - "review_classes": [ - "contract", - "security", - "privacy", - "relay", - "notary", - "compatibility", - "documentation", - "testing" - ], - "semantic_rules": [ - "knowledge_only", - "generated_docs_never_load_country_values", - "branch_has_no_authored_value" - ], - "constraints": [ - { - "keyword": "required", - "value": [ - "type", - "nullable", - "max_bytes", - "max_items", - "items" - ] - }, - { - "keyword": "type", - "value": "object" - } - ], - "local_reference": { - "schema": "integration", - "pointer": "/$defs/outputArray" - } - }, - { - "address": { - "schema": "integration", - "pointer": "/$defs/outputArray/properties/items", - "path_kind": "property" - }, - "purpose": "A recursively closed structured output schema without a source pointer.", - "purpose_source": "schema_description", - "semantic_owner": "integration_contract", - "human_owner": "integration_maintainers", - "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", - "field_type": { - "schema_types": [], - "local_reference": "#/$defs/outputSchema", + "local_reference": "#/$defs/integrationSourceByteSize", "composed": false }, - "requiredness": "required", + "requiredness": "optional", "null_behavior": "rejected", - "empty_behavior": "not_applicable", + "empty_behavior": "rejected", "default": { - "behavior": "no_schema_default" + "behavior": "schema_default", + "schema_value": "2MiB" }, "environment_behavior": "narrows_reviewed_authority", "sensitivity": "internal", @@ -49298,27 +48866,28 @@ "constraints": [], "local_reference": { "schema": "integration", - "pointer": "/$defs/outputSchema" + "pointer": "/$defs/integrationSourceByteSize" } }, { "address": { "schema": "integration", - "pointer": "/$defs/outputArray/properties/max_bytes", + "pointer": "/$defs/notApplicable/properties/ambiguity", "path_kind": "property" }, - "purpose": "Caps the canonical serialized size of one structured output array.", - "purpose_source": "reviewed_override", + "purpose": "Why the reviewed source contract cannot produce more than one matching record.", + "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "integer" + "object" ], + "local_reference": "#/$defs/notApplicableReason", "composed": false }, - "requiredness": "required", + "requiredness": "optional", "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { @@ -49385,37 +48954,41 @@ ], "constraints": [ { - "keyword": "maximum", - "value": 65536 - }, - { - "keyword": "minimum", - "value": 1 + "keyword": "required", + "value": [ + "rationale", + "request_fixture" + ] }, { "keyword": "type", - "value": "integer" + "value": "object" } - ] + ], + "local_reference": { + "schema": "integration", + "pointer": "/$defs/notApplicableReason" + } }, { "address": { "schema": "integration", - "pointer": "/$defs/outputArray/properties/max_items", + "pointer": "/$defs/notApplicable/properties/subject_mismatch", "path_kind": "property" }, - "purpose": "Caps the number of values released in one structured output array.", - "purpose_source": "reviewed_override", + "purpose": "Why the reviewed response contract contains no identifier comparable with a requested selector.", + "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "integer" + "object" ], + "local_reference": "#/$defs/notApplicableReason", "composed": false }, - "requiredness": "required", + "requiredness": "optional", "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { @@ -49482,39 +49055,42 @@ ], "constraints": [ { - "keyword": "maximum", - "value": 256 - }, - { - "keyword": "minimum", - "value": 1 + "keyword": "required", + "value": [ + "rationale", + "request_fixture" + ] }, { "keyword": "type", - "value": "integer" + "value": "object" } - ] + ], + "local_reference": { + "schema": "integration", + "pointer": "/$defs/notApplicableReason" + } }, { "address": { "schema": "integration", - "pointer": "/$defs/outputArray/properties/nullable", + "pointer": "/$defs/notApplicableReason/properties/rationale", "path_kind": "property" }, - "purpose": "Declares whether the complete structured output array may be null.", - "purpose_source": "reviewed_override", + "purpose": "Why the named normally required outcome cannot occur for this source contract.", + "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "boolean" + "string" ], "composed": false }, "requiredness": "required", "null_behavior": "rejected", - "empty_behavior": "not_applicable", + "empty_behavior": "rejected", "default": { "behavior": "no_schema_default" }, @@ -49578,30 +49154,41 @@ "generated_docs_never_load_country_values" ], "constraints": [ + { + "keyword": "maxLength", + "value": 512 + }, + { + "keyword": "minLength", + "value": 24 + }, { "keyword": "type", - "value": "boolean" + "value": "string" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/outputArray/properties/type", + "pointer": "/$defs/notApplicableReason/properties/request_fixture", "path_kind": "property" }, - "purpose": "Selects the array form for a structured integration output.", - "purpose_source": "reviewed_override", + "purpose": "Fixture name containing the supporting bounded source request.", + "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [], + "schema_types": [ + "string" + ], + "local_reference": "#/$defs/stableId", "composed": false }, "requiredness": "required", "null_behavior": "rejected", - "empty_behavior": "not_applicable", + "empty_behavior": "rejected", "default": { "behavior": "no_schema_default" }, @@ -49666,36 +49253,801 @@ ], "constraints": [ { - "keyword": "const", - "value": "array" + "keyword": "pattern", + "value": "^[a-z][a-z0-9._-]{0,95}$" + }, + { + "keyword": "type", + "value": "string" } - ] + ], + "local_reference": { + "schema": "integration", + "pointer": "/$defs/stableId" + } }, { "address": { "schema": "integration", - "pointer": "/$defs/outputObject/properties/fields", - "path_kind": "property" + "pointer": "/$defs/objectType/oneOf/0", + "path_kind": "branch" }, - "purpose": "Declares the bounded closed map of fields released in one structured output object.", - "purpose_source": "reviewed_override", + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [ - "object" - ], + "schema_types": [], "composed": false }, - "requiredness": "required", - "null_behavior": "rejected", + "requiredness": "conditional", + "null_behavior": "not_applicable", "empty_behavior": "not_applicable", "default": { - "behavior": "no_schema_default" + "behavior": "not_applicable" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "structural", + "state": "authored", + "products": [ + "registryctl", + "relay", + "notary", + "editor", + "docs" + ], + "availability": "published", + "stability": "experimental", + "validation_stages": [ + "json_schema", + "rust_deserialization", + "cross_file_semantic", + "fixture_execution", + "product_build" + ], + "diagnostic": "registryctl.authoring.integration.invalid", + "history_status": "not_verified", + "introduced_in": null, + "version_history": [], + "example": { + "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", + "schema_examples_available": false, + "contains_country_values": false + }, + "migration": "rebuild_project", + "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", + "consumers": [ + "registryctl_authoring", + "registry_relay", + "registry_notary", + "editor_tooling", + "docs_generator" + ], + "generated_artifacts": [ + "editor_schemas", + "project_build", + "relay_config", + "notary_config", + "fixture_report", + "field_reference" + ], + "review_classes": [ + "contract", + "security", + "privacy", + "relay", + "notary", + "compatibility", + "documentation", + "testing" + ], + "semantic_rules": [ + "knowledge_only", + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" + ], + "constraints": [ + { + "keyword": "const", + "value": "object" + } + ] + }, + { + "address": { + "schema": "integration", + "pointer": "/$defs/objectType/oneOf/1", + "path_kind": "branch" + }, + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", + "semantic_owner": "integration_contract", + "human_owner": "integration_maintainers", + "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", + "field_type": { + "schema_types": [ + "array" + ], + "composed": false + }, + "requiredness": "conditional", + "null_behavior": "not_applicable", + "empty_behavior": "not_applicable", + "default": { + "behavior": "not_applicable" + }, + "environment_behavior": "narrows_reviewed_authority", + "sensitivity": "structural", + "state": "authored", + "products": [ + "registryctl", + "relay", + "notary", + "editor", + "docs" + ], + "availability": "published", + "stability": "experimental", + "validation_stages": [ + "json_schema", + "rust_deserialization", + "cross_file_semantic", + "fixture_execution", + "product_build" + ], + "diagnostic": "registryctl.authoring.integration.invalid", + "history_status": "not_verified", + "introduced_in": null, + "version_history": [], + "example": { + "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", + "schema_examples_available": false, + "contains_country_values": false + }, + "migration": "rebuild_project", + "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", + "consumers": [ + "registryctl_authoring", + "registry_relay", + "registry_notary", + "editor_tooling", + "docs_generator" + ], + "generated_artifacts": [ + "editor_schemas", + "project_build", + "relay_config", + "notary_config", + "fixture_report", + "field_reference" + ], + "review_classes": [ + "contract", + "security", + "privacy", + "relay", + "notary", + "compatibility", + "documentation", + "testing" + ], + "semantic_rules": [ + "knowledge_only", + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" + ], + "constraints": [ + { + "keyword": "maxItems", + "value": 2 + }, + { + "keyword": "minItems", + "value": 2 + }, + { + "keyword": "type", + "value": "array" + } + ] + }, + { + "address": { + "schema": "integration", + "pointer": "/$defs/objectType/oneOf/1/prefixItems/0", + "path_kind": "array_item" + }, + "purpose": "Defines the contract shared by each ordered item in the enclosing authored list.", + "purpose_source": "structural_taxonomy", + "semantic_owner": "integration_contract", + "human_owner": "integration_maintainers", + "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", + "field_type": { + "schema_types": [], + "composed": false + }, + "requiredness": "not_applicable", + "null_behavior": "rejected", + "empty_behavior": "not_applicable", + "default": { + "behavior": "no_schema_default" + }, + "environment_behavior": "narrows_reviewed_authority", + "sensitivity": "internal", + "state": "authored", + "products": [ + "registryctl", + "relay", + "notary", + "editor", + "docs" + ], + "availability": "published", + "stability": "experimental", + "validation_stages": [ + "json_schema", + "rust_deserialization", + "cross_file_semantic", + "fixture_execution", + "product_build" + ], + "diagnostic": "registryctl.authoring.integration.invalid", + "history_status": "not_verified", + "introduced_in": null, + "version_history": [], + "example": { + "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", + "schema_examples_available": false, + "contains_country_values": false + }, + "migration": "rebuild_project", + "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", + "consumers": [ + "registryctl_authoring", + "registry_relay", + "registry_notary", + "editor_tooling", + "docs_generator" + ], + "generated_artifacts": [ + "editor_schemas", + "project_build", + "relay_config", + "notary_config", + "fixture_report", + "field_reference" + ], + "review_classes": [ + "contract", + "security", + "privacy", + "relay", + "notary", + "compatibility", + "documentation", + "testing" + ], + "semantic_rules": [ + "knowledge_only", + "generated_docs_never_load_country_values", + "array_items_share_element_contract" + ], + "constraints": [ + { + "keyword": "const", + "value": "object" + } + ] + }, + { + "address": { + "schema": "integration", + "pointer": "/$defs/objectType/oneOf/1/prefixItems/1", + "path_kind": "array_item" + }, + "purpose": "Defines the contract shared by each ordered item in the enclosing authored list.", + "purpose_source": "structural_taxonomy", + "semantic_owner": "integration_contract", + "human_owner": "integration_maintainers", + "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", + "field_type": { + "schema_types": [], + "composed": false + }, + "requiredness": "not_applicable", + "null_behavior": "rejected", + "empty_behavior": "not_applicable", + "default": { + "behavior": "no_schema_default" + }, + "environment_behavior": "narrows_reviewed_authority", + "sensitivity": "internal", + "state": "authored", + "products": [ + "registryctl", + "relay", + "notary", + "editor", + "docs" + ], + "availability": "published", + "stability": "experimental", + "validation_stages": [ + "json_schema", + "rust_deserialization", + "cross_file_semantic", + "fixture_execution", + "product_build" + ], + "diagnostic": "registryctl.authoring.integration.invalid", + "history_status": "not_verified", + "introduced_in": null, + "version_history": [], + "example": { + "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", + "schema_examples_available": false, + "contains_country_values": false + }, + "migration": "rebuild_project", + "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", + "consumers": [ + "registryctl_authoring", + "registry_relay", + "registry_notary", + "editor_tooling", + "docs_generator" + ], + "generated_artifacts": [ + "editor_schemas", + "project_build", + "relay_config", + "notary_config", + "fixture_report", + "field_reference" + ], + "review_classes": [ + "contract", + "security", + "privacy", + "relay", + "notary", + "compatibility", + "documentation", + "testing" + ], + "semantic_rules": [ + "knowledge_only", + "generated_docs_never_load_country_values", + "array_items_share_element_contract" + ], + "constraints": [ + { + "keyword": "const", + "value": "null" + } + ] + }, + { + "address": { + "schema": "integration", + "pointer": "/$defs/output/oneOf/0", + "path_kind": "branch" + }, + "purpose": "Type, scalar bounds, and optional source pointer for one normalized scalar integration output.", + "purpose_source": "schema_description", + "semantic_owner": "integration_contract", + "human_owner": "integration_maintainers", + "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", + "field_type": { + "schema_types": [ + "object" + ], + "local_reference": "#/$defs/scalarOutput", + "composed": false + }, + "requiredness": "conditional", + "null_behavior": "not_applicable", + "empty_behavior": "not_applicable", + "default": { + "behavior": "not_applicable" + }, + "environment_behavior": "narrows_reviewed_authority", + "sensitivity": "structural", + "state": "authored", + "products": [ + "registryctl", + "relay", + "notary", + "editor", + "docs" + ], + "availability": "published", + "stability": "experimental", + "validation_stages": [ + "json_schema", + "rust_deserialization", + "cross_file_semantic", + "fixture_execution", + "product_build" + ], + "diagnostic": "registryctl.authoring.integration.invalid", + "history_status": "not_verified", + "introduced_in": null, + "version_history": [], + "example": { + "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", + "schema_examples_available": false, + "contains_country_values": false + }, + "migration": "rebuild_project", + "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", + "consumers": [ + "registryctl_authoring", + "registry_relay", + "registry_notary", + "editor_tooling", + "docs_generator" + ], + "generated_artifacts": [ + "editor_schemas", + "project_build", + "relay_config", + "notary_config", + "fixture_report", + "field_reference" + ], + "review_classes": [ + "contract", + "security", + "privacy", + "relay", + "notary", + "compatibility", + "documentation", + "testing" + ], + "semantic_rules": [ + "knowledge_only", + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" + ], + "constraints": [ + { + "keyword": "required", + "value": [ + "type" + ] + }, + { + "keyword": "type", + "value": "object" + } + ], + "local_reference": { + "schema": "integration", + "pointer": "/$defs/scalarOutput" + } + }, + { + "address": { + "schema": "integration", + "pointer": "/$defs/output/oneOf/1", + "path_kind": "branch" + }, + "purpose": "A recursively typed object output with a canonical byte ceiling and an always-closed field map.", + "purpose_source": "schema_description", + "semantic_owner": "integration_contract", + "human_owner": "integration_maintainers", + "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", + "field_type": { + "schema_types": [ + "object" + ], + "local_reference": "#/$defs/outputObject", + "composed": false + }, + "requiredness": "conditional", + "null_behavior": "not_applicable", + "empty_behavior": "not_applicable", + "default": { + "behavior": "not_applicable" + }, + "environment_behavior": "narrows_reviewed_authority", + "sensitivity": "structural", + "state": "authored", + "products": [ + "registryctl", + "relay", + "notary", + "editor", + "docs" + ], + "availability": "published", + "stability": "experimental", + "validation_stages": [ + "json_schema", + "rust_deserialization", + "cross_file_semantic", + "fixture_execution", + "product_build" + ], + "diagnostic": "registryctl.authoring.integration.invalid", + "history_status": "not_verified", + "introduced_in": null, + "version_history": [], + "example": { + "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", + "schema_examples_available": false, + "contains_country_values": false + }, + "migration": "rebuild_project", + "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", + "consumers": [ + "registryctl_authoring", + "registry_relay", + "registry_notary", + "editor_tooling", + "docs_generator" + ], + "generated_artifacts": [ + "editor_schemas", + "project_build", + "relay_config", + "notary_config", + "fixture_report", + "field_reference" + ], + "review_classes": [ + "contract", + "security", + "privacy", + "relay", + "notary", + "compatibility", + "documentation", + "testing" + ], + "semantic_rules": [ + "knowledge_only", + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" + ], + "constraints": [ + { + "keyword": "required", + "value": [ + "type", + "max_bytes", + "fields" + ] + }, + { + "keyword": "type", + "value": "object" + } + ], + "local_reference": { + "schema": "integration", + "pointer": "/$defs/outputObject" + } + }, + { + "address": { + "schema": "integration", + "pointer": "/$defs/output/oneOf/2", + "path_kind": "branch" + }, + "purpose": "A recursively typed array output with canonical byte and item-count ceilings.", + "purpose_source": "schema_description", + "semantic_owner": "integration_contract", + "human_owner": "integration_maintainers", + "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", + "field_type": { + "schema_types": [ + "object" + ], + "local_reference": "#/$defs/outputArray", + "composed": false + }, + "requiredness": "conditional", + "null_behavior": "not_applicable", + "empty_behavior": "not_applicable", + "default": { + "behavior": "not_applicable" + }, + "environment_behavior": "narrows_reviewed_authority", + "sensitivity": "structural", + "state": "authored", + "products": [ + "registryctl", + "relay", + "notary", + "editor", + "docs" + ], + "availability": "published", + "stability": "experimental", + "validation_stages": [ + "json_schema", + "rust_deserialization", + "cross_file_semantic", + "fixture_execution", + "product_build" + ], + "diagnostic": "registryctl.authoring.integration.invalid", + "history_status": "not_verified", + "introduced_in": null, + "version_history": [], + "example": { + "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", + "schema_examples_available": false, + "contains_country_values": false + }, + "migration": "rebuild_project", + "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", + "consumers": [ + "registryctl_authoring", + "registry_relay", + "registry_notary", + "editor_tooling", + "docs_generator" + ], + "generated_artifacts": [ + "editor_schemas", + "project_build", + "relay_config", + "notary_config", + "fixture_report", + "field_reference" + ], + "review_classes": [ + "contract", + "security", + "privacy", + "relay", + "notary", + "compatibility", + "documentation", + "testing" + ], + "semantic_rules": [ + "knowledge_only", + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" + ], + "constraints": [ + { + "keyword": "required", + "value": [ + "type", + "max_bytes", + "max_items", + "items" + ] + }, + { + "keyword": "type", + "value": "object" + } + ], + "local_reference": { + "schema": "integration", + "pointer": "/$defs/outputArray" + } + }, + { + "address": { + "schema": "integration", + "pointer": "/$defs/outputArray/properties/items", + "path_kind": "property" + }, + "purpose": "A recursively closed structured output schema without a source pointer.", + "purpose_source": "schema_description", + "semantic_owner": "integration_contract", + "human_owner": "integration_maintainers", + "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", + "field_type": { + "schema_types": [], + "local_reference": "#/$defs/outputSchema", + "composed": false + }, + "requiredness": "required", + "null_behavior": "rejected", + "empty_behavior": "not_applicable", + "default": { + "behavior": "no_schema_default" + }, + "environment_behavior": "narrows_reviewed_authority", + "sensitivity": "internal", + "state": "authored", + "products": [ + "registryctl", + "relay", + "notary", + "editor", + "docs" + ], + "availability": "published", + "stability": "experimental", + "validation_stages": [ + "json_schema", + "rust_deserialization", + "cross_file_semantic", + "fixture_execution", + "product_build" + ], + "diagnostic": "registryctl.authoring.integration.invalid", + "history_status": "not_verified", + "introduced_in": null, + "version_history": [], + "example": { + "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", + "schema_examples_available": false, + "contains_country_values": false + }, + "migration": "rebuild_project", + "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", + "consumers": [ + "registryctl_authoring", + "registry_relay", + "registry_notary", + "editor_tooling", + "docs_generator" + ], + "generated_artifacts": [ + "editor_schemas", + "project_build", + "relay_config", + "notary_config", + "fixture_report", + "field_reference" + ], + "review_classes": [ + "contract", + "security", + "privacy", + "relay", + "notary", + "compatibility", + "documentation", + "testing" + ], + "semantic_rules": [ + "knowledge_only", + "generated_docs_never_load_country_values" + ], + "constraints": [], + "local_reference": { + "schema": "integration", + "pointer": "/$defs/outputSchema" + } + }, + { + "address": { + "schema": "integration", + "pointer": "/$defs/outputArray/properties/max_bytes", + "path_kind": "property" + }, + "purpose": "Caps the canonical serialized size of one structured output array.", + "purpose_source": "reviewed_override", + "semantic_owner": "integration_contract", + "human_owner": "integration_maintainers", + "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", + "field_type": { + "schema_types": [ + "integer" + ], + "composed": false + }, + "requiredness": "required", + "null_behavior": "rejected", + "empty_behavior": "not_applicable", + "default": { + "behavior": "no_schema_default" + }, + "environment_behavior": "narrows_reviewed_authority", + "sensitivity": "internal", "state": "authored", "products": [ "registryctl", @@ -49755,38 +50107,37 @@ ], "constraints": [ { - "keyword": "maxProperties", - "value": 32 + "keyword": "maximum", + "value": 65536 }, { - "keyword": "minProperties", + "keyword": "minimum", "value": 1 }, { "keyword": "type", - "value": "object" + "value": "integer" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/outputObject/properties/fields/additionalProperties", - "path_kind": "map_value" + "pointer": "/$defs/outputArray/properties/max_items", + "path_kind": "property" }, - "purpose": "Requiredness and recursive schema for one named field of a closed structured output object.", - "purpose_source": "schema_description", + "purpose": "Caps the number of values released in one structured output array.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "object" + "integer" ], - "local_reference": "#/$defs/outputObjectField", "composed": false }, - "requiredness": "not_applicable", + "requiredness": "required", "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { @@ -49849,48 +50200,230 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "arbitrary_map_keys_not_fixed_properties" + "generated_docs_never_load_country_values" ], "constraints": [ { - "keyword": "required", - "value": [ - "required", - "schema" - ] + "keyword": "maximum", + "value": 256 + }, + { + "keyword": "minimum", + "value": 1 }, { "keyword": "type", - "value": "object" + "value": "integer" } + ] + }, + { + "address": { + "schema": "integration", + "pointer": "/$defs/outputArray/properties/type", + "path_kind": "property" + }, + "purpose": "Selects the array form for a structured integration output, and declares the array nullable by pairing it with null.", + "purpose_source": "reviewed_override", + "semantic_owner": "integration_contract", + "human_owner": "integration_maintainers", + "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", + "field_type": { + "schema_types": [ + "array" + ], + "local_reference": "#/$defs/arrayType", + "composed": false + }, + "requiredness": "required", + "null_behavior": "rejected", + "empty_behavior": "not_applicable", + "default": { + "behavior": "no_schema_default" + }, + "environment_behavior": "narrows_reviewed_authority", + "sensitivity": "internal", + "state": "authored", + "products": [ + "registryctl", + "relay", + "notary", + "editor", + "docs" + ], + "availability": "published", + "stability": "experimental", + "validation_stages": [ + "json_schema", + "rust_deserialization", + "cross_file_semantic", + "fixture_execution", + "product_build" + ], + "diagnostic": "registryctl.authoring.integration.invalid", + "history_status": "not_verified", + "introduced_in": null, + "version_history": [], + "example": { + "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", + "schema_examples_available": false, + "contains_country_values": false + }, + "migration": "rebuild_project", + "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", + "consumers": [ + "registryctl_authoring", + "registry_relay", + "registry_notary", + "editor_tooling", + "docs_generator" + ], + "generated_artifacts": [ + "editor_schemas", + "project_build", + "relay_config", + "notary_config", + "fixture_report", + "field_reference" + ], + "review_classes": [ + "contract", + "security", + "privacy", + "relay", + "notary", + "compatibility", + "documentation", + "testing" + ], + "semantic_rules": [ + "knowledge_only", + "generated_docs_never_load_country_values" ], + "constraints": [], "local_reference": { "schema": "integration", - "pointer": "/$defs/outputObjectField" + "pointer": "/$defs/arrayType" } }, { "address": { "schema": "integration", - "pointer": "/$defs/outputObject/properties/fields/propertyNames", - "path_kind": "map_key" + "pointer": "/$defs/outputObject/properties/fields", + "path_kind": "property" }, - "purpose": "Portable lowercase name for an integration input or output.", + "purpose": "Declares the bounded closed map of fields released in one structured output object.", + "purpose_source": "reviewed_override", + "semantic_owner": "integration_contract", + "human_owner": "integration_maintainers", + "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", + "field_type": { + "schema_types": [ + "object" + ], + "composed": false + }, + "requiredness": "required", + "null_behavior": "rejected", + "empty_behavior": "not_applicable", + "default": { + "behavior": "no_schema_default" + }, + "environment_behavior": "narrows_reviewed_authority", + "sensitivity": "internal", + "state": "authored", + "products": [ + "registryctl", + "relay", + "notary", + "editor", + "docs" + ], + "availability": "published", + "stability": "experimental", + "validation_stages": [ + "json_schema", + "rust_deserialization", + "cross_file_semantic", + "fixture_execution", + "product_build" + ], + "diagnostic": "registryctl.authoring.integration.invalid", + "history_status": "not_verified", + "introduced_in": null, + "version_history": [], + "example": { + "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", + "schema_examples_available": false, + "contains_country_values": false + }, + "migration": "rebuild_project", + "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", + "consumers": [ + "registryctl_authoring", + "registry_relay", + "registry_notary", + "editor_tooling", + "docs_generator" + ], + "generated_artifacts": [ + "editor_schemas", + "project_build", + "relay_config", + "notary_config", + "fixture_report", + "field_reference" + ], + "review_classes": [ + "contract", + "security", + "privacy", + "relay", + "notary", + "compatibility", + "documentation", + "testing" + ], + "semantic_rules": [ + "knowledge_only", + "generated_docs_never_load_country_values" + ], + "constraints": [ + { + "keyword": "maxProperties", + "value": 32 + }, + { + "keyword": "minProperties", + "value": 1 + }, + { + "keyword": "type", + "value": "object" + } + ] + }, + { + "address": { + "schema": "integration", + "pointer": "/$defs/outputObject/properties/fields/additionalProperties", + "path_kind": "map_value" + }, + "purpose": "Requiredness and recursive schema for one named field of a closed structured output object.", "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "string" + "object" ], - "local_reference": "#/$defs/inputName", + "local_reference": "#/$defs/outputObjectField", "composed": false }, "requiredness": "not_applicable", "null_behavior": "rejected", - "empty_behavior": "rejected", + "empty_behavior": "not_applicable", "default": { "behavior": "no_schema_default" }, @@ -49956,39 +50489,43 @@ ], "constraints": [ { - "keyword": "pattern", - "value": "^[a-z][a-z0-9_]{0,63}$" + "keyword": "required", + "value": [ + "required", + "schema" + ] }, { "keyword": "type", - "value": "string" + "value": "object" } ], "local_reference": { "schema": "integration", - "pointer": "/$defs/inputName" + "pointer": "/$defs/outputObjectField" } }, { "address": { "schema": "integration", - "pointer": "/$defs/outputObject/properties/max_bytes", - "path_kind": "property" + "pointer": "/$defs/outputObject/properties/fields/propertyNames", + "path_kind": "map_key" }, - "purpose": "Caps the canonical serialized size of one structured output object.", - "purpose_source": "reviewed_override", + "purpose": "Portable lowercase name for an integration input or output.", + "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "integer" + "string" ], + "local_reference": "#/$defs/inputName", "composed": false }, - "requiredness": "required", + "requiredness": "not_applicable", "null_behavior": "rejected", - "empty_behavior": "not_applicable", + "empty_behavior": "rejected", "default": { "behavior": "no_schema_default" }, @@ -50049,37 +50586,38 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "arbitrary_map_keys_not_fixed_properties" ], "constraints": [ { - "keyword": "maximum", - "value": 65536 - }, - { - "keyword": "minimum", - "value": 1 + "keyword": "pattern", + "value": "^[a-z][a-z0-9_]{0,63}$" }, { "keyword": "type", - "value": "integer" + "value": "string" } - ] + ], + "local_reference": { + "schema": "integration", + "pointer": "/$defs/inputName" + } }, { "address": { "schema": "integration", - "pointer": "/$defs/outputObject/properties/nullable", + "pointer": "/$defs/outputObject/properties/max_bytes", "path_kind": "property" }, - "purpose": "Declares whether the complete structured output object may be null.", + "purpose": "Caps the canonical serialized size of one structured output object.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "boolean" + "integer" ], "composed": false }, @@ -50149,9 +50687,17 @@ "generated_docs_never_load_country_values" ], "constraints": [ + { + "keyword": "maximum", + "value": 65536 + }, + { + "keyword": "minimum", + "value": 1 + }, { "keyword": "type", - "value": "boolean" + "value": "integer" } ] }, @@ -50161,13 +50707,16 @@ "pointer": "/$defs/outputObject/properties/type", "path_kind": "property" }, - "purpose": "Selects the closed object form for a structured integration output.", + "purpose": "Selects the closed object form for a structured integration output, and declares the object nullable by pairing it with null.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [], + "schema_types": [ + "array" + ], + "local_reference": "#/$defs/objectType", "composed": false }, "requiredness": "required", @@ -50235,12 +50784,11 @@ "knowledge_only", "generated_docs_never_load_country_values" ], - "constraints": [ - { - "keyword": "const", - "value": "object" - } - ] + "constraints": [], + "local_reference": { + "schema": "integration", + "pointer": "/$defs/objectType" + } }, { "address": { @@ -50608,7 +51156,6 @@ "keyword": "required", "value": [ "type", - "nullable", "max_bytes", "fields" ] @@ -50712,7 +51259,6 @@ "keyword": "required", "value": [ "type", - "nullable", "max_bytes", "max_items", "items" diff --git a/docs/site/src/data/generated/configuration-reference-coverage.json b/docs/site/src/data/generated/configuration-reference-coverage.json index 5293f4f1b..d9ac9b7fd 100644 --- a/docs/site/src/data/generated/configuration-reference-coverage.json +++ b/docs/site/src/data/generated/configuration-reference-coverage.json @@ -39,12 +39,12 @@ }, "coverage": { "schema_count": 7, - "path_count": 1829, - "reference_count": 506, + "path_count": 1835, + "reference_count": 508, "by_schema": { "project": 220, "environment": 213, - "integration": 171, + "integration": 177, "fixture": 63, "entity": 35, "relay": 593, @@ -52,24 +52,24 @@ }, "by_path_kind": { "root": 7, - "property": 1458, + "property": 1456, "map_key": 26, "map_value": 48, - "array_item": 178, - "branch": 112 + "array_item": 182, + "branch": 116 }, "by_sensitivity": { "public": 16, - "internal": 1179, + "internal": 1181, "sensitive": 408, "secret_reference": 44, "redacted_fixture": 51, - "structural": 131 + "structural": 135 }, "by_intent_source": { "schema_description": 530, - "reviewed_override": 266, - "structural_taxonomy": 131, + "reviewed_override": 264, + "structural_taxonomy": 139, "reviewed_profile": 902 }, "by_intent_profile": { @@ -148,10 +148,10 @@ "relay_vocabularies_open_map": 1 } }, - "reviewed_intent_assignment_required_count": 1829, - "reviewed_intent_assignment_covered_count": 1829, - "distinct_reviewed_intent_count": 629, + "reviewed_intent_assignment_required_count": 1835, + "reviewed_intent_assignment_covered_count": 1835, + "distinct_reviewed_intent_count": 627, "distinct_reviewed_intents_reused_count": 86, - "reviewed_intent_assignments_using_reused_intent_count": 1286, + "reviewed_intent_assignments_using_reused_intent_count": 1294, "missing_intent": [] } diff --git a/docs/site/src/data/generated/configuration-reference.json b/docs/site/src/data/generated/configuration-reference.json index 85e52bb36..93ee13ccd 100644 --- a/docs/site/src/data/generated/configuration-reference.json +++ b/docs/site/src/data/generated/configuration-reference.json @@ -38,12 +38,12 @@ }, "coverage": { "schema_count": 7, - "path_count": 1829, - "reference_count": 506, + "path_count": 1835, + "reference_count": 508, "by_schema": { "project": 220, "environment": 213, - "integration": 171, + "integration": 177, "fixture": 63, "entity": 35, "relay": 593, @@ -51,24 +51,24 @@ }, "by_path_kind": { "root": 7, - "property": 1458, + "property": 1456, "map_key": 26, "map_value": 48, - "array_item": 178, - "branch": 112 + "array_item": 182, + "branch": 116 }, "by_sensitivity": { "public": 16, - "internal": 1179, + "internal": 1181, "sensitive": 408, "secret_reference": 44, "redacted_fixture": 51, - "structural": 131 + "structural": 135 }, "by_intent_source": { "schema_description": 530, - "reviewed_override": 266, - "structural_taxonomy": 131, + "reviewed_override": 264, + "structural_taxonomy": 139, "reviewed_profile": 902 }, "by_intent_profile": { @@ -41370,7 +41370,7 @@ { "address": { "schema": "integration", - "pointer": "/$defs/capability/oneOf/0", + "pointer": "/$defs/arrayType/oneOf/0", "path_kind": "branch" }, "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", @@ -41379,9 +41379,7 @@ "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [ - "object" - ], + "schema_types": [], "composed": false }, "requiredness": "conditional", @@ -41452,42 +41450,36 @@ ], "constraints": [ { - "keyword": "required", - "value": [ - "http" - ] - }, - { - "keyword": "type", - "value": "object" + "keyword": "const", + "value": "array" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/capability/oneOf/0/properties/http", - "path_kind": "property" + "pointer": "/$defs/arrayType/oneOf/1", + "path_kind": "branch" }, - "purpose": "Selects the single-request declarative HTTP capability and its expected response semantics.", - "purpose_source": "reviewed_override", + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "object" + "array" ], "composed": false }, - "requiredness": "required", - "null_behavior": "rejected", + "requiredness": "conditional", + "null_behavior": "not_applicable", "empty_behavior": "not_applicable", "default": { - "behavior": "no_schema_default" + "behavior": "not_applicable" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "structural", "state": "authored", "products": [ "registryctl", @@ -41543,40 +41535,40 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" ], "constraints": [ { - "keyword": "required", - "value": [ - "request" - ] + "keyword": "maxItems", + "value": 2 + }, + { + "keyword": "minItems", + "value": 2 }, { "keyword": "type", - "value": "object" + "value": "array" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/capability/oneOf/0/properties/http/properties/request", - "path_kind": "property" + "pointer": "/$defs/arrayType/oneOf/1/prefixItems/0", + "path_kind": "array_item" }, - "purpose": "Bounded read-only HTTP request template.", - "purpose_source": "schema_description", + "purpose": "Defines the contract shared by each ordered item in the enclosing authored list.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [ - "object" - ], - "local_reference": "#/$defs/httpRequest", + "schema_types": [], "composed": false }, - "requiredness": "required", + "requiredness": "not_applicable", "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { @@ -41639,45 +41631,32 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "array_items_share_element_contract" ], "constraints": [ { - "keyword": "required", - "value": [ - "method", - "path" - ] - }, - { - "keyword": "type", - "value": "object" + "keyword": "const", + "value": "array" } - ], - "local_reference": { - "schema": "integration", - "pointer": "/$defs/httpRequest" - } + ] }, { "address": { "schema": "integration", - "pointer": "/$defs/capability/oneOf/0/properties/http/properties/response", - "path_kind": "property" + "pointer": "/$defs/arrayType/oneOf/1/prefixItems/1", + "path_kind": "array_item" }, - "purpose": "Rules for translating upstream status and body cardinality into normalized outcomes.", - "purpose_source": "schema_description", + "purpose": "Defines the contract shared by each ordered item in the enclosing authored list.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [ - "object" - ], - "local_reference": "#/$defs/httpResponse", + "schema_types": [], "composed": false }, - "requiredness": "optional", + "requiredness": "not_applicable", "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { @@ -41740,23 +41719,20 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "array_items_share_element_contract" ], "constraints": [ { - "keyword": "type", - "value": "object" + "keyword": "const", + "value": "null" } - ], - "local_reference": { - "schema": "integration", - "pointer": "/$defs/httpResponse" - } + ] }, { "address": { "schema": "integration", - "pointer": "/$defs/capability/oneOf/1", + "pointer": "/$defs/capability/oneOf/0", "path_kind": "branch" }, "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", @@ -41840,7 +41816,7 @@ { "keyword": "required", "value": [ - "script" + "http" ] }, { @@ -41852,10 +41828,10 @@ { "address": { "schema": "integration", - "pointer": "/$defs/capability/oneOf/1/properties/script", + "pointer": "/$defs/capability/oneOf/0/properties/http", "path_kind": "property" }, - "purpose": "Selects the reviewed project-relative script capability and its optional modules.", + "purpose": "Selects the single-request declarative HTTP capability and its expected response semantics.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", @@ -41935,7 +41911,7 @@ { "keyword": "required", "value": [ - "file" + "request" ] }, { @@ -41947,29 +41923,29 @@ { "address": { "schema": "integration", - "pointer": "/$defs/capability/oneOf/1/properties/script/properties/file", + "pointer": "/$defs/capability/oneOf/0/properties/http/properties/request", "path_kind": "property" }, - "purpose": "Project-relative path without traversal or duplicate separators.", + "purpose": "Bounded read-only HTTP request template.", "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "string" + "object" ], - "local_reference": "#/$defs/relativePath", + "local_reference": "#/$defs/httpRequest", "composed": false }, "requiredness": "required", "null_behavior": "rejected", - "empty_behavior": "rejected", + "empty_behavior": "not_applicable", "default": { "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "sensitive", + "sensitivity": "internal", "state": "authored", "products": [ "registryctl", @@ -42025,47 +42001,42 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "sensitive_operational_metadata" + "generated_docs_never_load_country_values" ], "constraints": [ { - "keyword": "maxLength", - "value": 4096 - }, - { - "keyword": "minLength", - "value": 1 - }, - { - "keyword": "pattern", - "value": "^(?!/)(?!.*(?:^|/)\\.\\.?/)(?!.*//).+$" + "keyword": "required", + "value": [ + "method", + "path" + ] }, { "keyword": "type", - "value": "string" + "value": "object" } ], "local_reference": { "schema": "integration", - "pointer": "/$defs/relativePath" + "pointer": "/$defs/httpRequest" } }, { "address": { "schema": "integration", - "pointer": "/$defs/capability/oneOf/1/properties/script/properties/modules", + "pointer": "/$defs/capability/oneOf/0/properties/http/properties/response", "path_kind": "property" }, - "purpose": "Lists the reviewed project-relative modules available to the integration script.", - "purpose_source": "reviewed_override", + "purpose": "Rules for translating upstream status and body cardinality into normalized outcomes.", + "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "array" + "object" ], + "local_reference": "#/$defs/httpResponse", "composed": false }, "requiredness": "optional", @@ -42075,105 +42046,6 @@ "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "sensitive", - "state": "authored", - "products": [ - "registryctl", - "relay", - "notary", - "editor", - "docs" - ], - "availability": "published", - "stability": "experimental", - "validation_stages": [ - "json_schema", - "rust_deserialization", - "cross_file_semantic", - "fixture_execution", - "product_build" - ], - "diagnostic": "registryctl.authoring.integration.invalid", - "history_status": "not_verified", - "introduced_in": null, - "version_history": [], - "example": { - "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", - "schema_examples_available": false, - "contains_country_values": false - }, - "migration": "rebuild_project", - "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", - "consumers": [ - "registryctl_authoring", - "registry_relay", - "registry_notary", - "editor_tooling", - "docs_generator" - ], - "generated_artifacts": [ - "editor_schemas", - "project_build", - "relay_config", - "notary_config", - "fixture_report", - "field_reference" - ], - "review_classes": [ - "contract", - "security", - "privacy", - "relay", - "notary", - "compatibility", - "documentation", - "testing" - ], - "semantic_rules": [ - "knowledge_only", - "generated_docs_never_load_country_values", - "sensitive_operational_metadata" - ], - "constraints": [ - { - "keyword": "maxItems", - "value": 32 - }, - { - "keyword": "type", - "value": "array" - }, - { - "keyword": "uniqueItems", - "value": true - } - ] - }, - { - "address": { - "schema": "integration", - "pointer": "/$defs/capability/oneOf/1/properties/script/properties/modules/items", - "path_kind": "array_item" - }, - "purpose": "Project-relative path without traversal or duplicate separators.", - "purpose_source": "schema_description", - "semantic_owner": "integration_contract", - "human_owner": "integration_maintainers", - "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", - "field_type": { - "schema_types": [ - "string" - ], - "local_reference": "#/$defs/relativePath", - "composed": false - }, - "requiredness": "not_applicable", - "null_behavior": "rejected", - "empty_behavior": "rejected", - "default": { - "behavior": "no_schema_default" - }, - "environment_behavior": "narrows_reviewed_authority", "sensitivity": "internal", "state": "authored", "products": [ @@ -42230,36 +42102,23 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "array_items_share_element_contract" + "generated_docs_never_load_country_values" ], "constraints": [ - { - "keyword": "maxLength", - "value": 4096 - }, - { - "keyword": "minLength", - "value": 1 - }, - { - "keyword": "pattern", - "value": "^(?!/)(?!.*(?:^|/)\\.\\.?/)(?!.*//).+$" - }, { "keyword": "type", - "value": "string" + "value": "object" } ], "local_reference": { "schema": "integration", - "pointer": "/$defs/relativePath" + "pointer": "/$defs/httpResponse" } }, { "address": { "schema": "integration", - "pointer": "/$defs/capability/oneOf/2", + "pointer": "/$defs/capability/oneOf/1", "path_kind": "branch" }, "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", @@ -42343,7 +42202,7 @@ { "keyword": "required", "value": [ - "snapshot" + "script" ] }, { @@ -42355,10 +42214,10 @@ { "address": { "schema": "integration", - "pointer": "/$defs/capability/oneOf/2/properties/snapshot", + "pointer": "/$defs/capability/oneOf/1/properties/script", "path_kind": "property" }, - "purpose": "Selects an offline entity snapshot capability with exact input matching and freshness control.", + "purpose": "Selects the reviewed project-relative script capability and its optional modules.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", @@ -42438,9 +42297,7 @@ { "keyword": "required", "value": [ - "entity", - "exact", - "freshness" + "file" ] }, { @@ -42452,10 +42309,10 @@ { "address": { "schema": "integration", - "pointer": "/$defs/capability/oneOf/2/properties/snapshot/properties/entity", + "pointer": "/$defs/capability/oneOf/1/properties/script/properties/file", "path_kind": "property" }, - "purpose": "Lowercase stable identifier used in project references.", + "purpose": "Project-relative path without traversal or duplicate separators.", "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", @@ -42464,7 +42321,7 @@ "schema_types": [ "string" ], - "local_reference": "#/$defs/stableId", + "local_reference": "#/$defs/relativePath", "composed": false }, "requiredness": "required", @@ -42474,7 +42331,7 @@ "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "sensitive", "state": "authored", "products": [ "registryctl", @@ -42530,12 +42387,21 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "sensitive_operational_metadata" ], "constraints": [ + { + "keyword": "maxLength", + "value": 4096 + }, + { + "keyword": "minLength", + "value": 1 + }, { "keyword": "pattern", - "value": "^[a-z][a-z0-9._-]{0,95}$" + "value": "^(?!/)(?!.*(?:^|/)\\.\\.?/)(?!.*//).+$" }, { "keyword": "type", @@ -42544,34 +42410,34 @@ ], "local_reference": { "schema": "integration", - "pointer": "/$defs/stableId" + "pointer": "/$defs/relativePath" } }, { "address": { "schema": "integration", - "pointer": "/$defs/capability/oneOf/2/properties/snapshot/properties/exact", + "pointer": "/$defs/capability/oneOf/1/properties/script/properties/modules", "path_kind": "property" }, - "purpose": "Maps entity fields to integration inputs that must match exactly in the snapshot lookup.", + "purpose": "Lists the reviewed project-relative modules available to the integration script.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "object" + "array" ], "composed": false }, - "requiredness": "required", + "requiredness": "optional", "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "sensitive", "state": "authored", "products": [ "registryctl", @@ -42627,44 +42493,45 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "sensitive_operational_metadata" ], "constraints": [ { - "keyword": "maxProperties", - "value": 8 + "keyword": "maxItems", + "value": 32 }, { - "keyword": "minProperties", - "value": 1 + "keyword": "type", + "value": "array" }, { - "keyword": "type", - "value": "object" + "keyword": "uniqueItems", + "value": true } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/capability/oneOf/2/properties/snapshot/properties/exact/additionalProperties", - "path_kind": "map_value" + "pointer": "/$defs/capability/oneOf/1/properties/script/properties/modules/items", + "path_kind": "array_item" }, - "purpose": "Reference to a declared integration input.", + "purpose": "Project-relative path without traversal or duplicate separators.", "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "object" + "string" ], - "local_reference": "#/$defs/inputReference", + "local_reference": "#/$defs/relativePath", "composed": false }, "requiredness": "not_applicable", "null_behavior": "rejected", - "empty_behavior": "not_applicable", + "empty_behavior": "rejected", "default": { "behavior": "no_schema_default" }, @@ -42726,50 +42593,56 @@ "semantic_rules": [ "knowledge_only", "generated_docs_never_load_country_values", - "arbitrary_map_keys_not_fixed_properties" + "array_items_share_element_contract" ], "constraints": [ { - "keyword": "required", - "value": [ - "input" - ] + "keyword": "maxLength", + "value": 4096 + }, + { + "keyword": "minLength", + "value": 1 + }, + { + "keyword": "pattern", + "value": "^(?!/)(?!.*(?:^|/)\\.\\.?/)(?!.*//).+$" }, { "keyword": "type", - "value": "object" + "value": "string" } ], "local_reference": { "schema": "integration", - "pointer": "/$defs/inputReference" + "pointer": "/$defs/relativePath" } }, { "address": { "schema": "integration", - "pointer": "/$defs/capability/oneOf/2/properties/snapshot/properties/freshness", - "path_kind": "property" + "pointer": "/$defs/capability/oneOf/2", + "path_kind": "branch" }, - "purpose": "Sets the maximum accepted age of the materialized entity snapshot within the product-owned 31-day ceiling.", - "purpose_source": "reviewed_override", + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "string" + "object" ], "composed": false }, - "requiredness": "required", - "null_behavior": "rejected", - "empty_behavior": "rejected", + "requiredness": "conditional", + "null_behavior": "not_applicable", + "empty_behavior": "not_applicable", "default": { - "behavior": "no_schema_default" + "behavior": "not_applicable" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "structural", "state": "authored", "products": [ "registryctl", @@ -42825,27 +42698,30 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" ], "constraints": [ { - "keyword": "pattern", - "value": "^(?:(?:[1-9][0-9]{0,8}|1[0-9]{9}|2[0-5][0-9]{8}|26[0-6][0-9]{7}|267[0-7][0-9]{6}|2678[0-3][0-9]{5}|2678400000)ms|(?:[1-9][0-9]{0,5}|1[0-9]{6}|2[0-5][0-9]{5}|26[0-6][0-9]{4}|267[0-7][0-9]{3}|2678[0-3][0-9]{2}|2678400)s|(?:[1-9][0-9]{0,3}|[1-3][0-9]{4}|4[0-3][0-9]{3}|44[0-5][0-9]{2}|446[0-3][0-9]{1}|44640)m|(?:[1-9][0-9]{0,1}|[1-6][0-9]{2}|7[0-3][0-9]{1}|74[0-3]|744)h|(?:[1-9][0-9]{0,0}|[1-2][0-9]{1}|30|31)d)$" + "keyword": "required", + "value": [ + "snapshot" + ] }, { "keyword": "type", - "value": "string" + "value": "object" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/0", - "path_kind": "branch" + "pointer": "/$defs/capability/oneOf/2/properties/snapshot", + "path_kind": "property" }, - "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", - "purpose_source": "structural_taxonomy", + "purpose": "Selects an offline entity snapshot capability with exact input matching and freshness control.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", @@ -42855,14 +42731,14 @@ ], "composed": false }, - "requiredness": "conditional", - "null_behavior": "not_applicable", + "requiredness": "required", + "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { - "behavior": "not_applicable" + "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "structural", + "sensitivity": "internal", "state": "authored", "products": [ "registryctl", @@ -42918,14 +42794,15 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "branch_has_no_authored_value" + "generated_docs_never_load_country_values" ], "constraints": [ { "keyword": "required", "value": [ - "type" + "entity", + "exact", + "freshness" ] }, { @@ -42937,21 +42814,24 @@ { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/0/properties/type", + "pointer": "/$defs/capability/oneOf/2/properties/snapshot/properties/entity", "path_kind": "property" }, - "purpose": "Selects an unauthenticated, basic-authentication, or static-bearer credential interface.", - "purpose_source": "reviewed_override", + "purpose": "Lowercase stable identifier used in project references.", + "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [], + "schema_types": [ + "string" + ], + "local_reference": "#/$defs/stableId", "composed": false }, "requiredness": "required", "null_behavior": "rejected", - "empty_behavior": "not_applicable", + "empty_behavior": "rejected", "default": { "behavior": "no_schema_default" }, @@ -43016,23 +42896,27 @@ ], "constraints": [ { - "keyword": "enum", - "value": [ - "none", - "basic", - "static_bearer" - ] + "keyword": "pattern", + "value": "^[a-z][a-z0-9._-]{0,95}$" + }, + { + "keyword": "type", + "value": "string" } - ] + ], + "local_reference": { + "schema": "integration", + "pointer": "/$defs/stableId" + } }, { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/1", - "path_kind": "branch" + "pointer": "/$defs/capability/oneOf/2/properties/snapshot/properties/exact", + "path_kind": "property" }, - "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", - "purpose_source": "structural_taxonomy", + "purpose": "Maps entity fields to integration inputs that must match exactly in the snapshot lookup.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", @@ -43042,14 +42926,14 @@ ], "composed": false }, - "requiredness": "conditional", - "null_behavior": "not_applicable", + "requiredness": "required", + "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { - "behavior": "not_applicable" + "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "structural", + "sensitivity": "internal", "state": "authored", "products": [ "registryctl", @@ -43105,17 +42989,16 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "branch_has_no_authored_value" + "generated_docs_never_load_country_values" ], "constraints": [ { - "keyword": "required", - "value": [ - "type", - "name", - "max_value_bytes" - ] + "keyword": "maxProperties", + "value": 8 + }, + { + "keyword": "minProperties", + "value": 1 }, { "keyword": "type", @@ -43126,21 +43009,22 @@ { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/1/properties/max_value_bytes", - "path_kind": "property" + "pointer": "/$defs/capability/oneOf/2/properties/snapshot/properties/exact/additionalProperties", + "path_kind": "map_value" }, - "purpose": "Caps the credential value size accepted by the fixed-header API-key interface.", - "purpose_source": "reviewed_override", + "purpose": "Reference to a declared integration input.", + "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "integer" + "object" ], + "local_reference": "#/$defs/inputReference", "composed": false }, - "requiredness": "required", + "requiredness": "not_applicable", "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { @@ -43203,30 +43087,33 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "arbitrary_map_keys_not_fixed_properties" ], "constraints": [ { - "keyword": "maximum", - "value": 4096 - }, - { - "keyword": "minimum", - "value": 1 + "keyword": "required", + "value": [ + "input" + ] }, { "keyword": "type", - "value": "integer" + "value": "object" } - ] + ], + "local_reference": { + "schema": "integration", + "pointer": "/$defs/inputReference" + } }, { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/1/properties/name", + "pointer": "/$defs/capability/oneOf/2/properties/snapshot/properties/freshness", "path_kind": "property" }, - "purpose": "Declares the fixed HTTP header name used by the API-key credential interface.", + "purpose": "Sets the maximum accepted age of the materialized entity snapshot within the product-owned 31-day ceiling.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", @@ -43305,7 +43192,7 @@ "constraints": [ { "keyword": "pattern", - "value": "^[A-Za-z][A-Za-z0-9_-]{0,63}$" + "value": "^(?:(?:[1-9][0-9]{0,8}|1[0-9]{9}|2[0-5][0-9]{8}|26[0-6][0-9]{7}|267[0-7][0-9]{6}|2678[0-3][0-9]{5}|2678400000)ms|(?:[1-9][0-9]{0,5}|1[0-9]{6}|2[0-5][0-9]{5}|26[0-6][0-9]{4}|267[0-7][0-9]{3}|2678[0-3][0-9]{2}|2678400)s|(?:[1-9][0-9]{0,3}|[1-3][0-9]{4}|4[0-3][0-9]{3}|44[0-5][0-9]{2}|446[0-3][0-9]{1}|44640)m|(?:[1-9][0-9]{0,1}|[1-6][0-9]{2}|7[0-3][0-9]{1}|74[0-3]|744)h|(?:[1-9][0-9]{0,0}|[1-2][0-9]{1}|30|31)d)$" }, { "keyword": "type", @@ -43316,94 +43203,7 @@ { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/1/properties/type", - "path_kind": "property" - }, - "purpose": "Selects the fixed-header API-key credential interface for this source contract.", - "purpose_source": "reviewed_override", - "semantic_owner": "integration_contract", - "human_owner": "integration_maintainers", - "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", - "field_type": { - "schema_types": [], - "composed": false - }, - "requiredness": "required", - "null_behavior": "rejected", - "empty_behavior": "not_applicable", - "default": { - "behavior": "no_schema_default" - }, - "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", - "state": "authored", - "products": [ - "registryctl", - "relay", - "notary", - "editor", - "docs" - ], - "availability": "published", - "stability": "experimental", - "validation_stages": [ - "json_schema", - "rust_deserialization", - "cross_file_semantic", - "fixture_execution", - "product_build" - ], - "diagnostic": "registryctl.authoring.integration.invalid", - "history_status": "not_verified", - "introduced_in": null, - "version_history": [], - "example": { - "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", - "schema_examples_available": false, - "contains_country_values": false - }, - "migration": "rebuild_project", - "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", - "consumers": [ - "registryctl_authoring", - "registry_relay", - "registry_notary", - "editor_tooling", - "docs_generator" - ], - "generated_artifacts": [ - "editor_schemas", - "project_build", - "relay_config", - "notary_config", - "fixture_report", - "field_reference" - ], - "review_classes": [ - "contract", - "security", - "privacy", - "relay", - "notary", - "compatibility", - "documentation", - "testing" - ], - "semantic_rules": [ - "knowledge_only", - "generated_docs_never_load_country_values" - ], - "constraints": [ - { - "keyword": "const", - "value": "api_key_header" - } - ] - }, - { - "address": { - "schema": "integration", - "pointer": "/$defs/credential/oneOf/2", + "pointer": "/$defs/credential/oneOf/0", "path_kind": "branch" }, "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", @@ -43487,9 +43287,7 @@ { "keyword": "required", "value": [ - "type", - "name", - "max_value_bytes" + "type" ] }, { @@ -43501,18 +43299,16 @@ { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/2/properties/max_value_bytes", + "pointer": "/$defs/credential/oneOf/0/properties/type", "path_kind": "property" }, - "purpose": "Caps the credential value size accepted by the fixed-query API-key interface.", + "purpose": "Selects an unauthenticated, basic-authentication, or static-bearer credential interface.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [ - "integer" - ], + "schema_types": [], "composed": false }, "requiredness": "required", @@ -43582,44 +43378,40 @@ ], "constraints": [ { - "keyword": "maximum", - "value": 4096 - }, - { - "keyword": "minimum", - "value": 1 - }, - { - "keyword": "type", - "value": "integer" + "keyword": "enum", + "value": [ + "none", + "basic", + "static_bearer" + ] } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/2/properties/name", - "path_kind": "property" + "pointer": "/$defs/credential/oneOf/1", + "path_kind": "branch" }, - "purpose": "Declares the fixed query parameter name used by the API-key credential interface.", - "purpose_source": "reviewed_override", + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "string" + "object" ], "composed": false }, - "requiredness": "required", - "null_behavior": "rejected", - "empty_behavior": "rejected", + "requiredness": "conditional", + "null_behavior": "not_applicable", + "empty_behavior": "not_applicable", "default": { - "behavior": "no_schema_default" + "behavior": "not_applicable" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "structural", "state": "authored", "products": [ "registryctl", @@ -43675,32 +43467,39 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" ], "constraints": [ { - "keyword": "pattern", - "value": "^[A-Za-z_][A-Za-z0-9._:~-]{0,95}$" + "keyword": "required", + "value": [ + "type", + "name", + "max_value_bytes" + ] }, { "keyword": "type", - "value": "string" + "value": "object" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/2/properties/type", + "pointer": "/$defs/credential/oneOf/1/properties/max_value_bytes", "path_kind": "property" }, - "purpose": "Selects the fixed-query-parameter API-key credential interface for this source contract.", + "purpose": "Caps the credential value size accepted by the fixed-header API-key interface.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [], + "schema_types": [ + "integer" + ], "composed": false }, "requiredness": "required", @@ -43770,36 +43569,44 @@ ], "constraints": [ { - "keyword": "const", - "value": "api_key_query" + "keyword": "maximum", + "value": 4096 + }, + { + "keyword": "minimum", + "value": 1 + }, + { + "keyword": "type", + "value": "integer" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/3", - "path_kind": "branch" + "pointer": "/$defs/credential/oneOf/1/properties/name", + "path_kind": "property" }, - "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", - "purpose_source": "structural_taxonomy", + "purpose": "Declares the fixed HTTP header name used by the API-key credential interface.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "object" + "string" ], - "composed": true + "composed": false }, - "requiredness": "conditional", - "null_behavior": "not_applicable", - "empty_behavior": "not_applicable", + "requiredness": "required", + "null_behavior": "rejected", + "empty_behavior": "rejected", "default": { - "behavior": "not_applicable" + "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "structural", + "sensitivity": "internal", "state": "authored", "products": [ "registryctl", @@ -43855,32 +43662,27 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "branch_has_no_authored_value" + "generated_docs_never_load_country_values" ], "constraints": [ { - "keyword": "required", - "value": [ - "type", - "request", - "response_profile" - ] + "keyword": "pattern", + "value": "^[A-Za-z][A-Za-z0-9_-]{0,63}$" }, { "keyword": "type", - "value": "object" + "value": "string" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/3/allOf/0", - "path_kind": "branch" + "pointer": "/$defs/credential/oneOf/1/properties/type", + "path_kind": "property" }, - "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", - "purpose_source": "structural_taxonomy", + "purpose": "Selects the fixed-header API-key credential interface for this source contract.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", @@ -43888,14 +43690,14 @@ "schema_types": [], "composed": false }, - "requiredness": "conditional", - "null_behavior": "not_applicable", + "requiredness": "required", + "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { - "behavior": "not_applicable" + "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "structural", + "sensitivity": "internal", "state": "authored", "products": [ "registryctl", @@ -43951,15 +43753,19 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "branch_has_no_authored_value" + "generated_docs_never_load_country_values" ], - "constraints": [] + "constraints": [ + { + "keyword": "const", + "value": "api_key_header" + } + ] }, { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/3/allOf/0/if", + "pointer": "/$defs/credential/oneOf/2", "path_kind": "branch" }, "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", @@ -43968,7 +43774,9 @@ "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [], + "schema_types": [ + "object" + ], "composed": false }, "requiredness": "conditional", @@ -44041,24 +43849,32 @@ { "keyword": "required", "value": [ - "response_profile" + "type", + "name", + "max_value_bytes" ] + }, + { + "keyword": "type", + "value": "object" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/3/allOf/0/if/properties/response_profile", + "pointer": "/$defs/credential/oneOf/2/properties/max_value_bytes", "path_kind": "property" }, - "purpose": "Matches the strict no-expiry bearer profile before applying its refresh-control constraint.", - "purpose_source": "schema_description", + "purpose": "Caps the credential value size accepted by the fixed-query API-key interface.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [], + "schema_types": [ + "integer" + ], "composed": false }, "requiredness": "required", @@ -44128,34 +43944,44 @@ ], "constraints": [ { - "keyword": "const", - "value": "oauth2_bearer_no_expiry" + "keyword": "maximum", + "value": 4096 + }, + { + "keyword": "minimum", + "value": 1 + }, + { + "keyword": "type", + "value": "integer" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/3/allOf/0/then", - "path_kind": "branch" + "pointer": "/$defs/credential/oneOf/2/properties/name", + "path_kind": "property" }, - "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", - "purpose_source": "structural_taxonomy", + "purpose": "Declares the fixed query parameter name used by the API-key credential interface.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [], + "schema_types": [ + "string" + ], "composed": false }, - "requiredness": "conditional", - "null_behavior": "not_applicable", - "empty_behavior": "not_applicable", + "requiredness": "required", + "null_behavior": "rejected", + "empty_behavior": "rejected", "default": { - "behavior": "not_applicable" + "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "structural", + "sensitivity": "internal", "state": "authored", "products": [ "registryctl", @@ -44211,19 +44037,27 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "branch_has_no_authored_value" + "generated_docs_never_load_country_values" ], - "constraints": [] + "constraints": [ + { + "keyword": "pattern", + "value": "^[A-Za-z_][A-Za-z0-9._:~-]{0,95}$" + }, + { + "keyword": "type", + "value": "string" + } + ] }, { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/3/allOf/0/then/not", - "path_kind": "branch" + "pointer": "/$defs/credential/oneOf/2/properties/type", + "path_kind": "property" }, - "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", - "purpose_source": "structural_taxonomy", + "purpose": "Selects the fixed-query-parameter API-key credential interface for this source contract.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", @@ -44231,14 +44065,14 @@ "schema_types": [], "composed": false }, - "requiredness": "conditional", - "null_behavior": "not_applicable", + "requiredness": "required", + "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { - "behavior": "not_applicable" + "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "structural", + "sensitivity": "internal", "state": "authored", "products": [ "registryctl", @@ -44294,43 +44128,40 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "branch_has_no_authored_value" + "generated_docs_never_load_country_values" ], "constraints": [ { - "keyword": "required", - "value": [ - "refresh_skew" - ] + "keyword": "const", + "value": "api_key_query" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/3/properties/audience", - "path_kind": "property" + "pointer": "/$defs/credential/oneOf/3", + "path_kind": "branch" }, - "purpose": "Constrains OAuth token acquisition to the reviewed source audience and is treated as sensitive operational metadata.", - "purpose_source": "reviewed_override", + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "string" + "object" ], - "composed": false + "composed": true }, - "requiredness": "optional", - "null_behavior": "rejected", - "empty_behavior": "rejected", + "requiredness": "conditional", + "null_behavior": "not_applicable", + "empty_behavior": "not_applicable", "default": { - "behavior": "no_schema_default" + "behavior": "not_applicable" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "sensitive", + "sensitivity": "structural", "state": "authored", "products": [ "registryctl", @@ -44387,48 +44218,46 @@ "semantic_rules": [ "knowledge_only", "generated_docs_never_load_country_values", - "sensitive_operational_metadata" + "branch_has_no_authored_value" ], "constraints": [ { - "keyword": "maxLength", - "value": 2048 - }, - { - "keyword": "minLength", - "value": 1 + "keyword": "required", + "value": [ + "type", + "request", + "response_profile" + ] }, { "keyword": "type", - "value": "string" + "value": "object" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/3/properties/refresh_skew", - "path_kind": "property" + "pointer": "/$defs/credential/oneOf/3/allOf/0", + "path_kind": "branch" }, - "purpose": "With oauth2_bearer, sets a positive refresh interval below sixty seconds so a cached OAuth credential retains usable lifetime. The no-expiry profile rejects this field because caching is disabled.", - "purpose_source": "reviewed_override", + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [ - "string" - ], + "schema_types": [], "composed": false }, - "requiredness": "optional", - "null_behavior": "rejected", - "empty_behavior": "rejected", + "requiredness": "conditional", + "null_behavior": "not_applicable", + "empty_behavior": "not_applicable", "default": { - "behavior": "no_schema_default" + "behavior": "not_applicable" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "structural", "state": "authored", "products": [ "registryctl", @@ -44484,27 +44313,19 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" ], - "constraints": [ - { - "keyword": "pattern", - "value": "^(?:(?:[1-9][0-9]{0,3}|[1-5][0-9]{4})ms|(?:[1-9]|[1-5][0-9])s)$" - }, - { - "keyword": "type", - "value": "string" - } - ] + "constraints": [] }, { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/3/properties/request", - "path_kind": "property" + "pointer": "/$defs/credential/oneOf/3/allOf/0/if", + "path_kind": "branch" }, - "purpose": "Selects form-encoded or JSON token requests for the OAuth client-credentials interface.", - "purpose_source": "reviewed_override", + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", @@ -44512,14 +44333,14 @@ "schema_types": [], "composed": false }, - "requiredness": "required", - "null_behavior": "rejected", + "requiredness": "conditional", + "null_behavior": "not_applicable", "empty_behavior": "not_applicable", "default": { - "behavior": "no_schema_default" + "behavior": "not_applicable" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "structural", "state": "authored", "products": [ "registryctl", @@ -44575,14 +44396,14 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" ], "constraints": [ { - "keyword": "enum", + "keyword": "required", "value": [ - "form", - "json" + "response_profile" ] } ] @@ -44590,11 +44411,11 @@ { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/3/properties/response_profile", + "pointer": "/$defs/credential/oneOf/3/allOf/0/if/properties/response_profile", "path_kind": "property" }, - "purpose": "Selects an exact OAuth bearer-token response shape. oauth2_bearer requires access_token, token_type Bearer, and a bounded expires_in value and permits expiry-bound caching. oauth2_bearer_no_expiry requires only access_token and token_type Bearer, rejects expiry and extra fields, and disables token caching.", - "purpose_source": "reviewed_override", + "purpose": "Matches the strict no-expiry bearer profile before applying its refresh-control constraint.", + "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", @@ -44669,39 +44490,34 @@ ], "constraints": [ { - "keyword": "enum", - "value": [ - "oauth2_bearer", - "oauth2_bearer_no_expiry" - ] + "keyword": "const", + "value": "oauth2_bearer_no_expiry" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/3/properties/scope", - "path_kind": "property" + "pointer": "/$defs/credential/oneOf/3/allOf/0/then", + "path_kind": "branch" }, - "purpose": "Declares the bounded OAuth scope string requested for this source credential.", - "purpose_source": "reviewed_override", + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [ - "string" - ], + "schema_types": [], "composed": false }, - "requiredness": "optional", - "null_behavior": "rejected", - "empty_behavior": "rejected", + "requiredness": "conditional", + "null_behavior": "not_applicable", + "empty_behavior": "not_applicable", "default": { - "behavior": "no_schema_default" + "behavior": "not_applicable" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "structural", "state": "authored", "products": [ "registryctl", @@ -44757,31 +44573,19 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" ], - "constraints": [ - { - "keyword": "maxLength", - "value": 1024 - }, - { - "keyword": "minLength", - "value": 1 - }, - { - "keyword": "type", - "value": "string" - } - ] + "constraints": [] }, { "address": { "schema": "integration", - "pointer": "/$defs/credential/oneOf/3/properties/type", - "path_kind": "property" + "pointer": "/$defs/credential/oneOf/3/allOf/0/then/not", + "path_kind": "branch" }, - "purpose": "Selects the OAuth 2.0 client-credentials interface for source authentication.", - "purpose_source": "reviewed_override", + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", @@ -44789,14 +44593,14 @@ "schema_types": [], "composed": false }, - "requiredness": "required", - "null_behavior": "rejected", + "requiredness": "conditional", + "null_behavior": "not_applicable", "empty_behavior": "not_applicable", "default": { - "behavior": "no_schema_default" + "behavior": "not_applicable" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "structural", "state": "authored", "products": [ "registryctl", @@ -44852,38 +44656,43 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" ], "constraints": [ { - "keyword": "const", - "value": "oauth2_client_credentials" + "keyword": "required", + "value": [ + "refresh_skew" + ] } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/httpRequest/properties/body", + "pointer": "/$defs/credential/oneOf/3/properties/audience", "path_kind": "property" }, - "purpose": "Defines the optional authored body template sent by the declarative HTTP request.", + "purpose": "Constrains OAuth token acquisition to the reviewed source audience and is treated as sensitive operational metadata.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [], + "schema_types": [ + "string" + ], "composed": false }, "requiredness": "optional", "null_behavior": "rejected", - "empty_behavior": "not_applicable", + "empty_behavior": "rejected", "default": { "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "sensitive", "state": "authored", "products": [ "registryctl", @@ -44939,30 +44748,44 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "sensitive_operational_metadata" ], - "constraints": [] + "constraints": [ + { + "keyword": "maxLength", + "value": 2048 + }, + { + "keyword": "minLength", + "value": 1 + }, + { + "keyword": "type", + "value": "string" + } + ] }, { "address": { "schema": "integration", - "pointer": "/$defs/httpRequest/properties/headers", + "pointer": "/$defs/credential/oneOf/3/properties/refresh_skew", "path_kind": "property" }, - "purpose": "Maps reviewed request header names to authored values and input substitutions.", + "purpose": "With oauth2_bearer, sets a positive refresh interval below sixty seconds so a cached OAuth credential retains usable lifetime. The no-expiry profile rejects this field because caching is disabled.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "object" + "string" ], "composed": false }, "requiredness": "optional", "null_behavior": "rejected", - "empty_behavior": "not_applicable", + "empty_behavior": "rejected", "default": { "behavior": "no_schema_default" }, @@ -45027,38 +44850,33 @@ ], "constraints": [ { - "keyword": "maxProperties", - "value": 32 + "keyword": "pattern", + "value": "^(?:(?:[1-9][0-9]{0,3}|[1-5][0-9]{4})ms|(?:[1-9]|[1-5][0-9])s)$" }, { "keyword": "type", - "value": "object" + "value": "string" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/httpRequest/properties/headers/additionalProperties", - "path_kind": "map_value" + "pointer": "/$defs/credential/oneOf/3/properties/request", + "path_kind": "property" }, - "purpose": "Request value supplied from a declared input or an authored scalar literal.", - "purpose_source": "schema_description", + "purpose": "Selects form-encoded or JSON token requests for the OAuth client-credentials interface.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [ - "boolean", - "integer", - "string" - ], - "local_reference": "#/$defs/inputOrLiteral", + "schema_types": [], "composed": false }, - "requiredness": "not_applicable", + "requiredness": "required", "null_behavior": "rejected", - "empty_behavior": "allowed", + "empty_behavior": "not_applicable", "default": { "behavior": "no_schema_default" }, @@ -45119,22 +44937,25 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "arbitrary_map_keys_not_fixed_properties" + "generated_docs_never_load_country_values" ], - "constraints": [], - "local_reference": { - "schema": "integration", - "pointer": "/$defs/inputOrLiteral" - } + "constraints": [ + { + "keyword": "enum", + "value": [ + "form", + "json" + ] + } + ] }, { "address": { "schema": "integration", - "pointer": "/$defs/httpRequest/properties/method", + "pointer": "/$defs/credential/oneOf/3/properties/response_profile", "path_kind": "property" }, - "purpose": "Selects the single GET or POST request performed by a declarative HTTP capability.", + "purpose": "Selects an exact OAuth bearer-token response shape. oauth2_bearer requires access_token, token_type Bearer, and a bounded expires_in value and permits expiry-bound caching. oauth2_bearer_no_expiry requires only access_token and token_type Bearer, rejects expiry and extra fields, and disables token caching.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", @@ -45212,8 +45033,8 @@ { "keyword": "enum", "value": [ - "GET", - "POST" + "oauth2_bearer", + "oauth2_bearer_no_expiry" ] } ] @@ -45221,10 +45042,10 @@ { "address": { "schema": "integration", - "pointer": "/$defs/httpRequest/properties/path", + "pointer": "/$defs/credential/oneOf/3/properties/scope", "path_kind": "property" }, - "purpose": "Defines the reviewed source path template used by the declarative HTTP request.", + "purpose": "Declares the bounded OAuth scope string requested for this source credential.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", @@ -45235,14 +45056,14 @@ ], "composed": false }, - "requiredness": "required", + "requiredness": "optional", "null_behavior": "rejected", "empty_behavior": "rejected", "default": { "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "sensitive", + "sensitivity": "internal", "state": "authored", "products": [ "registryctl", @@ -45298,22 +45119,17 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "sensitive_operational_metadata" + "generated_docs_never_load_country_values" ], "constraints": [ { "keyword": "maxLength", - "value": 4096 + "value": 1024 }, { "keyword": "minLength", "value": 1 }, - { - "keyword": "pattern", - "value": "^/[^?#]*$" - }, { "keyword": "type", "value": "string" @@ -45323,21 +45139,19 @@ { "address": { "schema": "integration", - "pointer": "/$defs/httpRequest/properties/query", + "pointer": "/$defs/credential/oneOf/3/properties/type", "path_kind": "property" }, - "purpose": "Maps reviewed query parameter names to authored request values and input substitutions.", + "purpose": "Selects the OAuth 2.0 client-credentials interface for source authentication.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [ - "object" - ], + "schema_types": [], "composed": false }, - "requiredness": "optional", + "requiredness": "required", "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { @@ -45404,38 +45218,29 @@ ], "constraints": [ { - "keyword": "maxProperties", - "value": 64 - }, - { - "keyword": "type", - "value": "object" + "keyword": "const", + "value": "oauth2_client_credentials" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/httpRequest/properties/query/additionalProperties", - "path_kind": "map_value" + "pointer": "/$defs/httpRequest/properties/body", + "path_kind": "property" }, - "purpose": "Request value supplied from a declared input or an authored scalar literal.", - "purpose_source": "schema_description", + "purpose": "Defines the optional authored body template sent by the declarative HTTP request.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [ - "boolean", - "integer", - "string" - ], - "local_reference": "#/$defs/inputOrLiteral", + "schema_types": [], "composed": false }, - "requiredness": "not_applicable", + "requiredness": "optional", "null_behavior": "rejected", - "empty_behavior": "allowed", + "empty_behavior": "not_applicable", "default": { "behavior": "no_schema_default" }, @@ -45496,28 +45301,25 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "arbitrary_map_keys_not_fixed_properties" + "generated_docs_never_load_country_values" ], - "constraints": [], - "local_reference": { - "schema": "integration", - "pointer": "/$defs/inputOrLiteral" - } + "constraints": [] }, { "address": { "schema": "integration", - "pointer": "/$defs/httpRequest/properties/semantics", + "pointer": "/$defs/httpRequest/properties/headers", "path_kind": "property" }, - "purpose": "Declares that the declarative HTTP request has read-only source semantics.", + "purpose": "Maps reviewed request header names to authored values and input substitutions.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [], + "schema_types": [ + "object" + ], "composed": false }, "requiredness": "optional", @@ -45587,29 +45389,123 @@ ], "constraints": [ { - "keyword": "const", - "value": "read_only" + "keyword": "maxProperties", + "value": 32 + }, + { + "keyword": "type", + "value": "object" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/httpResponse/properties/ambiguous", - "path_kind": "property" + "pointer": "/$defs/httpRequest/properties/headers/additionalProperties", + "path_kind": "map_value" }, - "purpose": "Lists HTTP response statuses that produce the integration's ambiguous outcome.", - "purpose_source": "reviewed_override", + "purpose": "Request value supplied from a declared input or an authored scalar literal.", + "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "array" + "boolean", + "integer", + "string" ], + "local_reference": "#/$defs/inputOrLiteral", "composed": false }, - "requiredness": "optional", + "requiredness": "not_applicable", + "null_behavior": "rejected", + "empty_behavior": "allowed", + "default": { + "behavior": "no_schema_default" + }, + "environment_behavior": "narrows_reviewed_authority", + "sensitivity": "internal", + "state": "authored", + "products": [ + "registryctl", + "relay", + "notary", + "editor", + "docs" + ], + "availability": "published", + "stability": "experimental", + "validation_stages": [ + "json_schema", + "rust_deserialization", + "cross_file_semantic", + "fixture_execution", + "product_build" + ], + "diagnostic": "registryctl.authoring.integration.invalid", + "history_status": "not_verified", + "introduced_in": null, + "version_history": [], + "example": { + "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", + "schema_examples_available": false, + "contains_country_values": false + }, + "migration": "rebuild_project", + "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", + "consumers": [ + "registryctl_authoring", + "registry_relay", + "registry_notary", + "editor_tooling", + "docs_generator" + ], + "generated_artifacts": [ + "editor_schemas", + "project_build", + "relay_config", + "notary_config", + "fixture_report", + "field_reference" + ], + "review_classes": [ + "contract", + "security", + "privacy", + "relay", + "notary", + "compatibility", + "documentation", + "testing" + ], + "semantic_rules": [ + "knowledge_only", + "generated_docs_never_load_country_values", + "arbitrary_map_keys_not_fixed_properties" + ], + "constraints": [], + "local_reference": { + "schema": "integration", + "pointer": "/$defs/inputOrLiteral" + } + }, + { + "address": { + "schema": "integration", + "pointer": "/$defs/httpRequest/properties/method", + "path_kind": "property" + }, + "purpose": "Selects the single GET or POST request performed by a declarative HTTP capability.", + "purpose_source": "reviewed_override", + "semantic_owner": "integration_contract", + "human_owner": "integration_maintainers", + "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", + "field_type": { + "schema_types": [], + "composed": false + }, + "requiredness": "required", "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { @@ -45676,40 +45572,39 @@ ], "constraints": [ { - "keyword": "type", - "value": "array" - }, - { - "keyword": "uniqueItems", - "value": true + "keyword": "enum", + "value": [ + "GET", + "POST" + ] } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/httpResponse/properties/ambiguous/items", - "path_kind": "array_item" + "pointer": "/$defs/httpRequest/properties/path", + "path_kind": "property" }, - "purpose": "Defines the contract shared by each ordered item in the enclosing authored list.", - "purpose_source": "structural_taxonomy", + "purpose": "Defines the reviewed source path template used by the declarative HTTP request.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "integer" + "string" ], "composed": false }, - "requiredness": "not_applicable", + "requiredness": "required", "null_behavior": "rejected", - "empty_behavior": "not_applicable", + "empty_behavior": "rejected", "default": { "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "sensitive", "state": "authored", "products": [ "registryctl", @@ -45766,37 +45661,41 @@ "semantic_rules": [ "knowledge_only", "generated_docs_never_load_country_values", - "array_items_share_element_contract" + "sensitive_operational_metadata" ], "constraints": [ { - "keyword": "maximum", - "value": 599 + "keyword": "maxLength", + "value": 4096 }, { - "keyword": "minimum", - "value": 100 + "keyword": "minLength", + "value": 1 + }, + { + "keyword": "pattern", + "value": "^/[^?#]*$" }, { "keyword": "type", - "value": "integer" + "value": "string" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/httpResponse/properties/no_match", + "pointer": "/$defs/httpRequest/properties/query", "path_kind": "property" }, - "purpose": "Lists HTTP response statuses that produce the integration's no-match outcome.", + "purpose": "Maps reviewed query parameter names to authored request values and input substitutions.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "array" + "object" ], "composed": false }, @@ -45867,35 +45766,38 @@ ], "constraints": [ { - "keyword": "type", - "value": "array" + "keyword": "maxProperties", + "value": 64 }, { - "keyword": "uniqueItems", - "value": true + "keyword": "type", + "value": "object" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/httpResponse/properties/no_match/items", - "path_kind": "array_item" + "pointer": "/$defs/httpRequest/properties/query/additionalProperties", + "path_kind": "map_value" }, - "purpose": "Defines the contract shared by each ordered item in the enclosing authored list.", - "purpose_source": "structural_taxonomy", + "purpose": "Request value supplied from a declared input or an authored scalar literal.", + "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "integer" + "boolean", + "integer", + "string" ], + "local_reference": "#/$defs/inputOrLiteral", "composed": false }, "requiredness": "not_applicable", "null_behavior": "rejected", - "empty_behavior": "not_applicable", + "empty_behavior": "allowed", "default": { "behavior": "no_schema_default" }, @@ -45957,39 +45859,28 @@ "semantic_rules": [ "knowledge_only", "generated_docs_never_load_country_values", - "array_items_share_element_contract" + "arbitrary_map_keys_not_fixed_properties" ], - "constraints": [ - { - "keyword": "maximum", - "value": 599 - }, - { - "keyword": "minimum", - "value": 100 - }, - { - "keyword": "type", - "value": "integer" - } - ] + "constraints": [], + "local_reference": { + "schema": "integration", + "pointer": "/$defs/inputOrLiteral" + } }, { "address": { "schema": "integration", - "pointer": "/$defs/httpResponse/properties/shape", + "pointer": "/$defs/httpRequest/properties/semantics", "path_kind": "property" }, - "purpose": "Declares whether a successful response is a singleton or a bounded collection.", + "purpose": "Declares that the declarative HTTP request has read-only source semantics.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [ - "object" - ], - "composed": true + "schema_types": [], + "composed": false }, "requiredness": "optional", "null_behavior": "rejected", @@ -46056,121 +45947,38 @@ "knowledge_only", "generated_docs_never_load_country_values" ], - "constraints": [] - }, - { - "address": { - "schema": "integration", - "pointer": "/$defs/httpResponse/properties/shape/oneOf/0", - "path_kind": "branch" - }, - "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", - "purpose_source": "structural_taxonomy", - "semantic_owner": "integration_contract", - "human_owner": "integration_maintainers", - "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", - "field_type": { - "schema_types": [], - "composed": false - }, - "requiredness": "conditional", - "null_behavior": "not_applicable", - "empty_behavior": "not_applicable", - "default": { - "behavior": "not_applicable" - }, - "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "structural", - "state": "authored", - "products": [ - "registryctl", - "relay", - "notary", - "editor", - "docs" - ], - "availability": "published", - "stability": "experimental", - "validation_stages": [ - "json_schema", - "rust_deserialization", - "cross_file_semantic", - "fixture_execution", - "product_build" - ], - "diagnostic": "registryctl.authoring.integration.invalid", - "history_status": "not_verified", - "introduced_in": null, - "version_history": [], - "example": { - "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", - "schema_examples_available": false, - "contains_country_values": false - }, - "migration": "rebuild_project", - "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", - "consumers": [ - "registryctl_authoring", - "registry_relay", - "registry_notary", - "editor_tooling", - "docs_generator" - ], - "generated_artifacts": [ - "editor_schemas", - "project_build", - "relay_config", - "notary_config", - "fixture_report", - "field_reference" - ], - "review_classes": [ - "contract", - "security", - "privacy", - "relay", - "notary", - "compatibility", - "documentation", - "testing" - ], - "semantic_rules": [ - "knowledge_only", - "generated_docs_never_load_country_values", - "branch_has_no_authored_value" - ], "constraints": [ { "keyword": "const", - "value": "singleton" + "value": "read_only" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/httpResponse/properties/shape/oneOf/1", - "path_kind": "branch" + "pointer": "/$defs/httpResponse/properties/ambiguous", + "path_kind": "property" }, - "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", - "purpose_source": "structural_taxonomy", + "purpose": "Lists HTTP response statuses that produce the integration's ambiguous outcome.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "object" + "array" ], "composed": false }, - "requiredness": "conditional", - "null_behavior": "not_applicable", + "requiredness": "optional", + "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { - "behavior": "not_applicable" + "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "structural", + "sensitivity": "internal", "state": "authored", "products": [ "registryctl", @@ -46226,39 +46034,37 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "branch_has_no_authored_value" + "generated_docs_never_load_country_values" ], "constraints": [ { - "keyword": "required", - "value": [ - "records", - "cardinality" - ] + "keyword": "type", + "value": "array" }, { - "keyword": "type", - "value": "object" + "keyword": "uniqueItems", + "value": true } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/httpResponse/properties/shape/oneOf/1/properties/cardinality", - "path_kind": "property" + "pointer": "/$defs/httpResponse/properties/ambiguous/items", + "path_kind": "array_item" }, - "purpose": "Requires two-record probing so collection results distinguish one match from ambiguity.", - "purpose_source": "reviewed_override", + "purpose": "Defines the contract shared by each ordered item in the enclosing authored list.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [], + "schema_types": [ + "integer" + ], "composed": false }, - "requiredness": "required", + "requiredness": "not_applicable", "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { @@ -46321,35 +46127,44 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "array_items_share_element_contract" ], "constraints": [ { - "keyword": "const", - "value": "probe_two" + "keyword": "maximum", + "value": 599 + }, + { + "keyword": "minimum", + "value": 100 + }, + { + "keyword": "type", + "value": "integer" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/httpResponse/properties/shape/oneOf/1/properties/records", + "pointer": "/$defs/httpResponse/properties/no_match", "path_kind": "property" }, - "purpose": "Selects the canonical response location containing collection records.", + "purpose": "Lists HTTP response statuses that produce the integration's no-match outcome.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "string" + "array" ], "composed": false }, - "requiredness": "required", + "requiredness": "optional", "null_behavior": "rejected", - "empty_behavior": "rejected", + "empty_behavior": "not_applicable", "default": { "behavior": "no_schema_default" }, @@ -46414,31 +46229,33 @@ ], "constraints": [ { - "keyword": "pattern", - "value": "^/(?:[^/~]|~[01])+(?:/(?:[^/~]|~[01])+)*$" + "keyword": "type", + "value": "array" }, { - "keyword": "type", - "value": "string" + "keyword": "uniqueItems", + "value": true } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/input/properties/canonicalization", - "path_kind": "property" + "pointer": "/$defs/httpResponse/properties/no_match/items", + "path_kind": "array_item" }, - "purpose": "Selects the reviewed normalization rule applied before an input is compared, interpolated, or sent to a source.", - "purpose_source": "reviewed_override", + "purpose": "Defines the contract shared by each ordered item in the enclosing authored list.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [], + "schema_types": [ + "integer" + ], "composed": false }, - "requiredness": "optional", + "requiredness": "not_applicable", "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { @@ -46501,121 +46318,40 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "array_items_share_element_contract" ], "constraints": [ { - "keyword": "enum", - "value": [ - "identity", - "ascii_lowercase" - ] - } - ] - }, - { - "address": { - "schema": "integration", - "pointer": "/$defs/input/properties/format", - "path_kind": "property" - }, - "purpose": "Applies the full-date semantic format to a string-valued integration input.", - "purpose_source": "reviewed_override", - "semantic_owner": "integration_contract", - "human_owner": "integration_maintainers", - "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", - "field_type": { - "schema_types": [], - "composed": false - }, - "requiredness": "optional", - "null_behavior": "rejected", - "empty_behavior": "not_applicable", - "default": { - "behavior": "no_schema_default" - }, - "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", - "state": "authored", - "products": [ - "registryctl", - "relay", - "notary", - "editor", - "docs" - ], - "availability": "published", - "stability": "experimental", - "validation_stages": [ - "json_schema", - "rust_deserialization", - "cross_file_semantic", - "fixture_execution", - "product_build" - ], - "diagnostic": "registryctl.authoring.integration.invalid", - "history_status": "not_verified", - "introduced_in": null, - "version_history": [], - "example": { - "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", - "schema_examples_available": false, - "contains_country_values": false - }, - "migration": "rebuild_project", - "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", - "consumers": [ - "registryctl_authoring", - "registry_relay", - "registry_notary", - "editor_tooling", - "docs_generator" - ], - "generated_artifacts": [ - "editor_schemas", - "project_build", - "relay_config", - "notary_config", - "fixture_report", - "field_reference" - ], - "review_classes": [ - "contract", - "security", - "privacy", - "relay", - "notary", - "compatibility", - "documentation", - "testing" - ], - "semantic_rules": [ - "knowledge_only", - "generated_docs_never_load_country_values" - ], - "constraints": [ + "keyword": "maximum", + "value": 599 + }, { - "keyword": "const", - "value": "date" + "keyword": "minimum", + "value": 100 + }, + { + "keyword": "type", + "value": "integer" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/input/properties/maxLength", + "pointer": "/$defs/httpResponse/properties/shape", "path_kind": "property" }, - "purpose": "Caps a string-valued integration input at 1,024 Unicode scalar values, deriving its conservative 4,096-byte UTF-8 ceiling.", + "purpose": "Declares whether a successful response is a singleton or a bounded collection.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "integer" + "object" ], - "composed": false + "composed": true }, "requiredness": "optional", "null_behavior": "rejected", @@ -46682,46 +46418,31 @@ "knowledge_only", "generated_docs_never_load_country_values" ], - "constraints": [ - { - "keyword": "maximum", - "value": 1024 - }, - { - "keyword": "minimum", - "value": 1 - }, - { - "keyword": "type", - "value": "integer" - } - ] + "constraints": [] }, { "address": { "schema": "integration", - "pointer": "/$defs/input/properties/maximum", - "path_kind": "property" + "pointer": "/$defs/httpResponse/properties/shape/oneOf/0", + "path_kind": "branch" }, - "purpose": "Sets the inclusive upper bound accepted for an integer-valued integration input.", - "purpose_source": "reviewed_override", + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [ - "integer" - ], + "schema_types": [], "composed": false }, - "requiredness": "optional", - "null_behavior": "rejected", + "requiredness": "conditional", + "null_behavior": "not_applicable", "empty_behavior": "not_applicable", "default": { - "behavior": "no_schema_default" + "behavior": "not_applicable" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "structural", "state": "authored", "products": [ "registryctl", @@ -46777,48 +46498,41 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" ], "constraints": [ { - "keyword": "maximum", - "value": 9007199254740991 - }, - { - "keyword": "minimum", - "value": -9007199254740991 - }, - { - "keyword": "type", - "value": "integer" + "keyword": "const", + "value": "singleton" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/input/properties/minLength", - "path_kind": "property" + "pointer": "/$defs/httpResponse/properties/shape/oneOf/1", + "path_kind": "branch" }, - "purpose": "Sets the minimum character length accepted for a string-valued integration input.", - "purpose_source": "reviewed_override", + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "integer" + "object" ], "composed": false }, - "requiredness": "optional", - "null_behavior": "rejected", + "requiredness": "conditional", + "null_behavior": "not_applicable", "empty_behavior": "not_applicable", "default": { - "behavior": "no_schema_default" + "behavior": "not_applicable" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "structural", "state": "authored", "products": [ "registryctl", @@ -46874,41 +46588,39 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" ], "constraints": [ { - "keyword": "maximum", - "value": 16384 - }, - { - "keyword": "minimum", - "value": 0 + "keyword": "required", + "value": [ + "records", + "cardinality" + ] }, { "keyword": "type", - "value": "integer" + "value": "object" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/input/properties/minimum", + "pointer": "/$defs/httpResponse/properties/shape/oneOf/1/properties/cardinality", "path_kind": "property" }, - "purpose": "Sets the inclusive lower bound accepted for an integer-valued integration input.", + "purpose": "Requires two-record probing so collection results distinguish one match from ambiguity.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [ - "integer" - ], + "schema_types": [], "composed": false }, - "requiredness": "optional", + "requiredness": "required", "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { @@ -46975,26 +46687,18 @@ ], "constraints": [ { - "keyword": "maximum", - "value": 9007199254740991 - }, - { - "keyword": "minimum", - "value": -9007199254740991 - }, - { - "keyword": "type", - "value": "integer" + "keyword": "const", + "value": "probe_two" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/input/properties/pattern", + "pointer": "/$defs/httpResponse/properties/shape/oneOf/1/properties/records", "path_kind": "property" }, - "purpose": "Constrains a string-valued integration input with the authored regular expression.", + "purpose": "Selects the canonical response location containing collection records.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", @@ -47005,7 +46709,7 @@ ], "composed": false }, - "requiredness": "optional", + "requiredness": "required", "null_behavior": "rejected", "empty_behavior": "rejected", "default": { @@ -47072,12 +46776,8 @@ ], "constraints": [ { - "keyword": "maxLength", - "value": 16384 - }, - { - "keyword": "minLength", - "value": 1 + "keyword": "pattern", + "value": "^/(?:[^/~]|~[01])+(?:/(?:[^/~]|~[01])+)*$" }, { "keyword": "type", @@ -47088,10 +46788,10 @@ { "address": { "schema": "integration", - "pointer": "/$defs/input/properties/role", + "pointer": "/$defs/input/properties/canonicalization", "path_kind": "property" }, - "purpose": "Declares how one typed authoring input participates in source lookup, selection, or result shaping.", + "purpose": "Selects the reviewed normalization rule applied before an input is compared, interpolated, or sent to a source.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", @@ -47100,7 +46800,7 @@ "schema_types": [], "composed": false }, - "requiredness": "required", + "requiredness": "optional", "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { @@ -47169,8 +46869,8 @@ { "keyword": "enum", "value": [ - "selector", - "parameter" + "identity", + "ascii_lowercase" ] } ] @@ -47178,22 +46878,19 @@ { "address": { "schema": "integration", - "pointer": "/$defs/input/properties/type", + "pointer": "/$defs/input/properties/format", "path_kind": "property" }, - "purpose": "Declares the closed scalar or array type accepted for one integration input.", + "purpose": "Applies the full-date semantic format to a string-valued integration input.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [ - "array" - ], - "local_reference": "#/$defs/scalarType", + "schema_types": [], "composed": false }, - "requiredness": "required", + "requiredness": "optional", "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { @@ -47258,140 +46955,38 @@ "knowledge_only", "generated_docs_never_load_country_values" ], - "constraints": [], - "local_reference": { - "schema": "integration", - "pointer": "/$defs/scalarType" - } - }, - { - "address": { - "schema": "integration", - "pointer": "/$defs/inputOrLiteral/oneOf/0", - "path_kind": "branch" - }, - "purpose": "Reference to a declared integration input.", - "purpose_source": "schema_description", - "semantic_owner": "integration_contract", - "human_owner": "integration_maintainers", - "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", - "field_type": { - "schema_types": [ - "object" - ], - "local_reference": "#/$defs/inputReference", - "composed": false - }, - "requiredness": "conditional", - "null_behavior": "not_applicable", - "empty_behavior": "not_applicable", - "default": { - "behavior": "not_applicable" - }, - "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "structural", - "state": "authored", - "products": [ - "registryctl", - "relay", - "notary", - "editor", - "docs" - ], - "availability": "published", - "stability": "experimental", - "validation_stages": [ - "json_schema", - "rust_deserialization", - "cross_file_semantic", - "fixture_execution", - "product_build" - ], - "diagnostic": "registryctl.authoring.integration.invalid", - "history_status": "not_verified", - "introduced_in": null, - "version_history": [], - "example": { - "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", - "schema_examples_available": false, - "contains_country_values": false - }, - "migration": "rebuild_project", - "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", - "consumers": [ - "registryctl_authoring", - "registry_relay", - "registry_notary", - "editor_tooling", - "docs_generator" - ], - "generated_artifacts": [ - "editor_schemas", - "project_build", - "relay_config", - "notary_config", - "fixture_report", - "field_reference" - ], - "review_classes": [ - "contract", - "security", - "privacy", - "relay", - "notary", - "compatibility", - "documentation", - "testing" - ], - "semantic_rules": [ - "knowledge_only", - "generated_docs_never_load_country_values", - "branch_has_no_authored_value" - ], "constraints": [ { - "keyword": "required", - "value": [ - "input" - ] - }, - { - "keyword": "type", - "value": "object" + "keyword": "const", + "value": "date" } - ], - "local_reference": { - "schema": "integration", - "pointer": "/$defs/inputReference" - } + ] }, { "address": { "schema": "integration", - "pointer": "/$defs/inputOrLiteral/oneOf/1", - "path_kind": "branch" + "pointer": "/$defs/input/properties/maxLength", + "path_kind": "property" }, - "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", - "purpose_source": "structural_taxonomy", + "purpose": "Caps a string-valued integration input at 1,024 Unicode scalar values, deriving its conservative 4,096-byte UTF-8 ceiling.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "boolean", - "integer", - "string" + "integer" ], "composed": false }, - "requiredness": "conditional", - "null_behavior": "not_applicable", + "requiredness": "optional", + "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { - "behavior": "not_applicable" + "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "structural", + "sensitivity": "internal", "state": "authored", "products": [ "registryctl", @@ -47447,41 +47042,43 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "branch_has_no_authored_value" + "generated_docs_never_load_country_values" ], "constraints": [ + { + "keyword": "maximum", + "value": 1024 + }, + { + "keyword": "minimum", + "value": 1 + }, { "keyword": "type", - "value": [ - "string", - "boolean", - "integer" - ] + "value": "integer" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/inputReference/properties/input", + "pointer": "/$defs/input/properties/maximum", "path_kind": "property" }, - "purpose": "Portable lowercase name for an integration input or output.", - "purpose_source": "schema_description", + "purpose": "Sets the inclusive upper bound accepted for an integer-valued integration input.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "string" + "integer" ], - "local_reference": "#/$defs/inputName", "composed": false }, - "requiredness": "required", + "requiredness": "optional", "null_behavior": "rejected", - "empty_behavior": "rejected", + "empty_behavior": "not_applicable", "default": { "behavior": "no_schema_default" }, @@ -47546,27 +47143,27 @@ ], "constraints": [ { - "keyword": "pattern", - "value": "^[a-z][a-z0-9_]{0,63}$" + "keyword": "maximum", + "value": 9007199254740991 + }, + { + "keyword": "minimum", + "value": -9007199254740991 }, { "keyword": "type", - "value": "string" + "value": "integer" } - ], - "local_reference": { - "schema": "integration", - "pointer": "/$defs/inputName" - } + ] }, { "address": { "schema": "integration", - "pointer": "/$defs/integrationRequestByteSize/oneOf/0", - "path_kind": "branch" + "pointer": "/$defs/input/properties/minLength", + "path_kind": "property" }, - "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", - "purpose_source": "structural_taxonomy", + "purpose": "Sets the minimum character length accepted for a string-valued integration input.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", @@ -47576,14 +47173,14 @@ ], "composed": false }, - "requiredness": "conditional", - "null_behavior": "not_applicable", + "requiredness": "optional", + "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { - "behavior": "not_applicable" + "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "structural", + "sensitivity": "internal", "state": "authored", "products": [ "registryctl", @@ -47639,17 +47236,16 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "branch_has_no_authored_value" + "generated_docs_never_load_country_values" ], "constraints": [ { "keyword": "maximum", - "value": 1048576 + "value": 16384 }, { "keyword": "minimum", - "value": 1 + "value": 0 }, { "keyword": "type", @@ -47660,28 +47256,28 @@ { "address": { "schema": "integration", - "pointer": "/$defs/integrationRequestByteSize/oneOf/1", - "path_kind": "branch" + "pointer": "/$defs/input/properties/minimum", + "path_kind": "property" }, - "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", - "purpose_source": "structural_taxonomy", + "purpose": "Sets the inclusive lower bound accepted for an integer-valued integration input.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "string" + "integer" ], "composed": false }, - "requiredness": "conditional", - "null_behavior": "not_applicable", + "requiredness": "optional", + "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { - "behavior": "not_applicable" + "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "structural", + "sensitivity": "internal", "state": "authored", "products": [ "registryctl", @@ -47737,45 +47333,48 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "branch_has_no_authored_value" + "generated_docs_never_load_country_values" ], "constraints": [ { - "keyword": "pattern", - "value": "^(?:(?:[1-9][0-9]{0,2}|10[0-1][0-9]|102[0-4])KiB|1MiB)$" + "keyword": "maximum", + "value": 9007199254740991 + }, + { + "keyword": "minimum", + "value": -9007199254740991 }, { "keyword": "type", - "value": "string" + "value": "integer" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/integrationResponseByteSize/oneOf/0", - "path_kind": "branch" + "pointer": "/$defs/input/properties/pattern", + "path_kind": "property" }, - "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", - "purpose_source": "structural_taxonomy", + "purpose": "Constrains a string-valued integration input with the authored regular expression.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "integer" + "string" ], "composed": false }, - "requiredness": "conditional", - "null_behavior": "not_applicable", - "empty_behavior": "not_applicable", + "requiredness": "optional", + "null_behavior": "rejected", + "empty_behavior": "rejected", "default": { - "behavior": "not_applicable" + "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "structural", + "sensitivity": "internal", "state": "authored", "products": [ "registryctl", @@ -47831,49 +47430,46 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "branch_has_no_authored_value" + "generated_docs_never_load_country_values" ], "constraints": [ { - "keyword": "maximum", - "value": 8388608 + "keyword": "maxLength", + "value": 16384 }, { - "keyword": "minimum", + "keyword": "minLength", "value": 1 }, { "keyword": "type", - "value": "integer" + "value": "string" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/integrationResponseByteSize/oneOf/1", - "path_kind": "branch" + "pointer": "/$defs/input/properties/role", + "path_kind": "property" }, - "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", - "purpose_source": "structural_taxonomy", + "purpose": "Declares how one typed authoring input participates in source lookup, selection, or result shaping.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [ - "string" - ], + "schema_types": [], "composed": false }, - "requiredness": "conditional", - "null_behavior": "not_applicable", + "requiredness": "required", + "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { - "behavior": "not_applicable" + "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "structural", + "sensitivity": "internal", "state": "authored", "products": [ "registryctl", @@ -47929,35 +47525,123 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "branch_has_no_authored_value" + "generated_docs_never_load_country_values" ], "constraints": [ { - "keyword": "pattern", - "value": "^(?:(?:[1-9][0-9]{0,2}|[1-7][0-9]{3}|80[0-9]{2}|81[0-8][0-9]|819[0-2])KiB|[1-8]MiB)$" - }, - { - "keyword": "type", - "value": "string" + "keyword": "enum", + "value": [ + "selector", + "parameter" + ] } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/integrationSourceByteSize/oneOf/0", + "pointer": "/$defs/input/properties/type", + "path_kind": "property" + }, + "purpose": "Declares the closed scalar or array type accepted for one integration input.", + "purpose_source": "reviewed_override", + "semantic_owner": "integration_contract", + "human_owner": "integration_maintainers", + "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", + "field_type": { + "schema_types": [ + "array" + ], + "local_reference": "#/$defs/scalarType", + "composed": false + }, + "requiredness": "required", + "null_behavior": "rejected", + "empty_behavior": "not_applicable", + "default": { + "behavior": "no_schema_default" + }, + "environment_behavior": "narrows_reviewed_authority", + "sensitivity": "internal", + "state": "authored", + "products": [ + "registryctl", + "relay", + "notary", + "editor", + "docs" + ], + "availability": "published", + "stability": "experimental", + "validation_stages": [ + "json_schema", + "rust_deserialization", + "cross_file_semantic", + "fixture_execution", + "product_build" + ], + "diagnostic": "registryctl.authoring.integration.invalid", + "history_status": "not_verified", + "introduced_in": null, + "version_history": [], + "example": { + "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", + "schema_examples_available": false, + "contains_country_values": false + }, + "migration": "rebuild_project", + "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", + "consumers": [ + "registryctl_authoring", + "registry_relay", + "registry_notary", + "editor_tooling", + "docs_generator" + ], + "generated_artifacts": [ + "editor_schemas", + "project_build", + "relay_config", + "notary_config", + "fixture_report", + "field_reference" + ], + "review_classes": [ + "contract", + "security", + "privacy", + "relay", + "notary", + "compatibility", + "documentation", + "testing" + ], + "semantic_rules": [ + "knowledge_only", + "generated_docs_never_load_country_values" + ], + "constraints": [], + "local_reference": { + "schema": "integration", + "pointer": "/$defs/scalarType" + } + }, + { + "address": { + "schema": "integration", + "pointer": "/$defs/inputOrLiteral/oneOf/0", "path_kind": "branch" }, - "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", - "purpose_source": "structural_taxonomy", + "purpose": "Reference to a declared integration input.", + "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "integer" + "object" ], + "local_reference": "#/$defs/inputReference", "composed": false }, "requiredness": "conditional", @@ -48028,23 +47712,25 @@ ], "constraints": [ { - "keyword": "maximum", - "value": 16777216 - }, - { - "keyword": "minimum", - "value": 1 + "keyword": "required", + "value": [ + "input" + ] }, { "keyword": "type", - "value": "integer" + "value": "object" } - ] + ], + "local_reference": { + "schema": "integration", + "pointer": "/$defs/inputReference" + } }, { "address": { "schema": "integration", - "pointer": "/$defs/integrationSourceByteSize/oneOf/1", + "pointer": "/$defs/inputOrLiteral/oneOf/1", "path_kind": "branch" }, "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", @@ -48054,6 +47740,8 @@ "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ + "boolean", + "integer", "string" ], "composed": false @@ -48125,36 +47813,37 @@ "branch_has_no_authored_value" ], "constraints": [ - { - "keyword": "pattern", - "value": "^(?:(?:[1-9][0-9]{0,3}|1[0-5][0-9]{3}|16[0-2][0-9]{2}|163[0-7][0-9]|1638[0-4])KiB|(?:[1-9]|1[0-6])MiB)$" - }, { "keyword": "type", - "value": "string" + "value": [ + "string", + "boolean", + "integer" + ] } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/limits/properties/calls", + "pointer": "/$defs/inputReference/properties/input", "path_kind": "property" }, - "purpose": "Caps the number of high-level source calls available to a script integration.", - "purpose_source": "reviewed_override", + "purpose": "Portable lowercase name for an integration input or output.", + "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "integer" + "string" ], + "local_reference": "#/$defs/inputName", "composed": false }, - "requiredness": "optional", + "requiredness": "required", "null_behavior": "rejected", - "empty_behavior": "not_applicable", + "empty_behavior": "rejected", "default": { "behavior": "no_schema_default" }, @@ -48219,44 +47908,44 @@ ], "constraints": [ { - "keyword": "maximum", - "value": 16 - }, - { - "keyword": "minimum", - "value": 1 + "keyword": "pattern", + "value": "^[a-z][a-z0-9_]{0,63}$" }, { "keyword": "type", - "value": "integer" + "value": "string" } - ] + ], + "local_reference": { + "schema": "integration", + "pointer": "/$defs/inputName" + } }, { "address": { "schema": "integration", - "pointer": "/$defs/limits/properties/deadline", - "path_kind": "property" + "pointer": "/$defs/integrationRequestByteSize/oneOf/0", + "path_kind": "branch" }, - "purpose": "Caps total integration execution time with a positive duration no greater than twenty seconds.", - "purpose_source": "reviewed_override", + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "string" + "integer" ], "composed": false }, - "requiredness": "optional", - "null_behavior": "rejected", - "empty_behavior": "rejected", + "requiredness": "conditional", + "null_behavior": "not_applicable", + "empty_behavior": "not_applicable", "default": { - "behavior": "no_schema_default" + "behavior": "not_applicable" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "structural", "state": "authored", "products": [ "registryctl", @@ -48312,47 +48001,49 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" ], "constraints": [ { - "keyword": "pattern", - "value": "^(?:(?:[1-9][0-9]{0,3}|1[0-9]{4}|20000)ms|(?:[1-9]|1[0-9]|20)s)$" + "keyword": "maximum", + "value": 1048576 + }, + { + "keyword": "minimum", + "value": 1 }, { "keyword": "type", - "value": "string" + "value": "integer" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/limits/properties/request_bytes", - "path_kind": "property" + "pointer": "/$defs/integrationRequestByteSize/oneOf/1", + "path_kind": "branch" }, - "purpose": "Maximum aggregate author-controlled request bytes for one execution, defaulting to 64 KiB and capped at 1 MiB. Use a positive byte integer or canonical KiB/MiB value.", - "purpose_source": "schema_description", + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "integer", "string" ], - "local_reference": "#/$defs/integrationRequestByteSize", "composed": false }, - "requiredness": "optional", - "null_behavior": "rejected", - "empty_behavior": "rejected", + "requiredness": "conditional", + "null_behavior": "not_applicable", + "empty_behavior": "not_applicable", "default": { - "behavior": "schema_default", - "schema_value": "64KiB" + "behavior": "not_applicable" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "structural", "state": "authored", "products": [ "registryctl", @@ -48408,42 +48099,45 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" ], - "constraints": [], - "local_reference": { - "schema": "integration", - "pointer": "/$defs/integrationRequestByteSize" - } + "constraints": [ + { + "keyword": "pattern", + "value": "^(?:(?:[1-9][0-9]{0,2}|10[0-1][0-9]|102[0-4])KiB|1MiB)$" + }, + { + "keyword": "type", + "value": "string" + } + ] }, { "address": { "schema": "integration", - "pointer": "/$defs/limits/properties/source_bytes", - "path_kind": "property" + "pointer": "/$defs/integrationResponseByteSize/oneOf/0", + "path_kind": "branch" }, - "purpose": "Maximum aggregate source-response bytes for one execution, defaulting to 2 MiB and capped at 16 MiB. Use a positive byte integer or canonical KiB/MiB value.", - "purpose_source": "schema_description", + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "integer", - "string" + "integer" ], - "local_reference": "#/$defs/integrationSourceByteSize", "composed": false }, - "requiredness": "optional", - "null_behavior": "rejected", - "empty_behavior": "rejected", + "requiredness": "conditional", + "null_behavior": "not_applicable", + "empty_behavior": "not_applicable", "default": { - "behavior": "schema_default", - "schema_value": "2MiB" + "behavior": "not_applicable" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "structural", "state": "authored", "products": [ "registryctl", @@ -48499,40 +48193,49 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" ], - "constraints": [], - "local_reference": { - "schema": "integration", - "pointer": "/$defs/integrationSourceByteSize" - } + "constraints": [ + { + "keyword": "maximum", + "value": 8388608 + }, + { + "keyword": "minimum", + "value": 1 + }, + { + "keyword": "type", + "value": "integer" + } + ] }, { "address": { "schema": "integration", - "pointer": "/$defs/notApplicable/properties/ambiguity", - "path_kind": "property" + "pointer": "/$defs/integrationResponseByteSize/oneOf/1", + "path_kind": "branch" }, - "purpose": "Why the reviewed source contract cannot produce more than one matching record.", - "purpose_source": "schema_description", + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "object" + "string" ], - "local_reference": "#/$defs/notApplicableReason", "composed": false }, - "requiredness": "optional", - "null_behavior": "rejected", + "requiredness": "conditional", + "null_behavior": "not_applicable", "empty_behavior": "not_applicable", "default": { - "behavior": "no_schema_default" + "behavior": "not_applicable" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "structural", "state": "authored", "products": [ "registryctl", @@ -48588,52 +48291,45 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" ], "constraints": [ { - "keyword": "required", - "value": [ - "rationale", - "request_fixture" - ] + "keyword": "pattern", + "value": "^(?:(?:[1-9][0-9]{0,2}|[1-7][0-9]{3}|80[0-9]{2}|81[0-8][0-9]|819[0-2])KiB|[1-8]MiB)$" }, { "keyword": "type", - "value": "object" + "value": "string" } - ], - "local_reference": { - "schema": "integration", - "pointer": "/$defs/notApplicableReason" - } + ] }, { "address": { "schema": "integration", - "pointer": "/$defs/notApplicable/properties/subject_mismatch", - "path_kind": "property" + "pointer": "/$defs/integrationSourceByteSize/oneOf/0", + "path_kind": "branch" }, - "purpose": "Why the reviewed response contract contains no identifier comparable with a requested selector.", - "purpose_source": "schema_description", + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "object" + "integer" ], - "local_reference": "#/$defs/notApplicableReason", "composed": false }, - "requiredness": "optional", - "null_behavior": "rejected", + "requiredness": "conditional", + "null_behavior": "not_applicable", "empty_behavior": "not_applicable", "default": { - "behavior": "no_schema_default" + "behavior": "not_applicable" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "structural", "state": "authored", "products": [ "registryctl", @@ -48689,34 +48385,32 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" ], "constraints": [ { - "keyword": "required", - "value": [ - "rationale", - "request_fixture" - ] + "keyword": "maximum", + "value": 16777216 + }, + { + "keyword": "minimum", + "value": 1 }, { "keyword": "type", - "value": "object" + "value": "integer" } - ], - "local_reference": { - "schema": "integration", - "pointer": "/$defs/notApplicableReason" - } + ] }, { "address": { "schema": "integration", - "pointer": "/$defs/notApplicableReason/properties/rationale", - "path_kind": "property" + "pointer": "/$defs/integrationSourceByteSize/oneOf/1", + "path_kind": "branch" }, - "purpose": "Why the named normally required outcome cannot occur for this source contract.", - "purpose_source": "schema_description", + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", @@ -48726,14 +48420,14 @@ ], "composed": false }, - "requiredness": "required", - "null_behavior": "rejected", - "empty_behavior": "rejected", + "requiredness": "conditional", + "null_behavior": "not_applicable", + "empty_behavior": "not_applicable", "default": { - "behavior": "no_schema_default" + "behavior": "not_applicable" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "structural", "state": "authored", "products": [ "registryctl", @@ -48789,16 +48483,13 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" ], "constraints": [ { - "keyword": "maxLength", - "value": 512 - }, - { - "keyword": "minLength", - "value": 24 + "keyword": "pattern", + "value": "^(?:(?:[1-9][0-9]{0,3}|1[0-5][0-9]{3}|16[0-2][0-9]{2}|163[0-7][0-9]|1638[0-4])KiB|(?:[1-9]|1[0-6])MiB)$" }, { "keyword": "type", @@ -48809,24 +48500,23 @@ { "address": { "schema": "integration", - "pointer": "/$defs/notApplicableReason/properties/request_fixture", + "pointer": "/$defs/limits/properties/calls", "path_kind": "property" }, - "purpose": "Fixture name containing the supporting bounded source request.", - "purpose_source": "schema_description", + "purpose": "Caps the number of high-level source calls available to a script integration.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "string" + "integer" ], - "local_reference": "#/$defs/stableId", "composed": false }, - "requiredness": "required", + "requiredness": "optional", "null_behavior": "rejected", - "empty_behavior": "rejected", + "empty_behavior": "not_applicable", "default": { "behavior": "no_schema_default" }, @@ -48891,45 +48581,44 @@ ], "constraints": [ { - "keyword": "pattern", - "value": "^[a-z][a-z0-9._-]{0,95}$" + "keyword": "maximum", + "value": 16 + }, + { + "keyword": "minimum", + "value": 1 }, { "keyword": "type", - "value": "string" + "value": "integer" } - ], - "local_reference": { - "schema": "integration", - "pointer": "/$defs/stableId" - } + ] }, { "address": { "schema": "integration", - "pointer": "/$defs/output/oneOf/0", - "path_kind": "branch" + "pointer": "/$defs/limits/properties/deadline", + "path_kind": "property" }, - "purpose": "Type, scalar bounds, and optional source pointer for one normalized scalar integration output.", - "purpose_source": "schema_description", + "purpose": "Caps total integration execution time with a positive duration no greater than twenty seconds.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "object" + "string" ], - "local_reference": "#/$defs/scalarOutput", "composed": false }, - "requiredness": "conditional", - "null_behavior": "not_applicable", - "empty_behavior": "not_applicable", + "requiredness": "optional", + "null_behavior": "rejected", + "empty_behavior": "rejected", "default": { - "behavior": "not_applicable" + "behavior": "no_schema_default" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "structural", + "sensitivity": "internal", "state": "authored", "products": [ "registryctl", @@ -48985,52 +48674,47 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "branch_has_no_authored_value" + "generated_docs_never_load_country_values" ], "constraints": [ { - "keyword": "required", - "value": [ - "type" - ] + "keyword": "pattern", + "value": "^(?:(?:[1-9][0-9]{0,3}|1[0-9]{4}|20000)ms|(?:[1-9]|1[0-9]|20)s)$" }, { "keyword": "type", - "value": "object" + "value": "string" } - ], - "local_reference": { - "schema": "integration", - "pointer": "/$defs/scalarOutput" - } + ] }, { "address": { "schema": "integration", - "pointer": "/$defs/output/oneOf/1", - "path_kind": "branch" + "pointer": "/$defs/limits/properties/request_bytes", + "path_kind": "property" }, - "purpose": "A recursively typed object output with a canonical byte ceiling and an always-closed field map.", + "purpose": "Maximum aggregate author-controlled request bytes for one execution, defaulting to 64 KiB and capped at 1 MiB. Use a positive byte integer or canonical KiB/MiB value.", "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "object" + "integer", + "string" ], - "local_reference": "#/$defs/outputObject", + "local_reference": "#/$defs/integrationRequestByteSize", "composed": false }, - "requiredness": "conditional", - "null_behavior": "not_applicable", - "empty_behavior": "not_applicable", + "requiredness": "optional", + "null_behavior": "rejected", + "empty_behavior": "rejected", "default": { - "behavior": "not_applicable" + "behavior": "schema_default", + "schema_value": "64KiB" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "structural", + "sensitivity": "internal", "state": "authored", "products": [ "registryctl", @@ -49086,155 +48770,39 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "branch_has_no_authored_value" - ], - "constraints": [ - { - "keyword": "required", - "value": [ - "type", - "nullable", - "max_bytes", - "fields" - ] - }, - { - "keyword": "type", - "value": "object" - } + "generated_docs_never_load_country_values" ], + "constraints": [], "local_reference": { "schema": "integration", - "pointer": "/$defs/outputObject" + "pointer": "/$defs/integrationRequestByteSize" } }, { "address": { "schema": "integration", - "pointer": "/$defs/output/oneOf/2", - "path_kind": "branch" + "pointer": "/$defs/limits/properties/source_bytes", + "path_kind": "property" }, - "purpose": "A recursively typed array output with canonical byte and item-count ceilings.", + "purpose": "Maximum aggregate source-response bytes for one execution, defaulting to 2 MiB and capped at 16 MiB. Use a positive byte integer or canonical KiB/MiB value.", "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "object" + "integer", + "string" ], - "local_reference": "#/$defs/outputArray", - "composed": false - }, - "requiredness": "conditional", - "null_behavior": "not_applicable", - "empty_behavior": "not_applicable", - "default": { - "behavior": "not_applicable" - }, - "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "structural", - "state": "authored", - "products": [ - "registryctl", - "relay", - "notary", - "editor", - "docs" - ], - "availability": "published", - "stability": "experimental", - "validation_stages": [ - "json_schema", - "rust_deserialization", - "cross_file_semantic", - "fixture_execution", - "product_build" - ], - "diagnostic": "registryctl.authoring.integration.invalid", - "history_status": "not_verified", - "introduced_in": null, - "version_history": [], - "example": { - "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", - "schema_examples_available": false, - "contains_country_values": false - }, - "migration": "rebuild_project", - "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", - "consumers": [ - "registryctl_authoring", - "registry_relay", - "registry_notary", - "editor_tooling", - "docs_generator" - ], - "generated_artifacts": [ - "editor_schemas", - "project_build", - "relay_config", - "notary_config", - "fixture_report", - "field_reference" - ], - "review_classes": [ - "contract", - "security", - "privacy", - "relay", - "notary", - "compatibility", - "documentation", - "testing" - ], - "semantic_rules": [ - "knowledge_only", - "generated_docs_never_load_country_values", - "branch_has_no_authored_value" - ], - "constraints": [ - { - "keyword": "required", - "value": [ - "type", - "nullable", - "max_bytes", - "max_items", - "items" - ] - }, - { - "keyword": "type", - "value": "object" - } - ], - "local_reference": { - "schema": "integration", - "pointer": "/$defs/outputArray" - } - }, - { - "address": { - "schema": "integration", - "pointer": "/$defs/outputArray/properties/items", - "path_kind": "property" - }, - "purpose": "A recursively closed structured output schema without a source pointer.", - "purpose_source": "schema_description", - "semantic_owner": "integration_contract", - "human_owner": "integration_maintainers", - "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", - "field_type": { - "schema_types": [], - "local_reference": "#/$defs/outputSchema", + "local_reference": "#/$defs/integrationSourceByteSize", "composed": false }, - "requiredness": "required", + "requiredness": "optional", "null_behavior": "rejected", - "empty_behavior": "not_applicable", + "empty_behavior": "rejected", "default": { - "behavior": "no_schema_default" + "behavior": "schema_default", + "schema_value": "2MiB" }, "environment_behavior": "narrows_reviewed_authority", "sensitivity": "internal", @@ -49298,27 +48866,28 @@ "constraints": [], "local_reference": { "schema": "integration", - "pointer": "/$defs/outputSchema" + "pointer": "/$defs/integrationSourceByteSize" } }, { "address": { "schema": "integration", - "pointer": "/$defs/outputArray/properties/max_bytes", + "pointer": "/$defs/notApplicable/properties/ambiguity", "path_kind": "property" }, - "purpose": "Caps the canonical serialized size of one structured output array.", - "purpose_source": "reviewed_override", + "purpose": "Why the reviewed source contract cannot produce more than one matching record.", + "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "integer" + "object" ], + "local_reference": "#/$defs/notApplicableReason", "composed": false }, - "requiredness": "required", + "requiredness": "optional", "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { @@ -49385,37 +48954,41 @@ ], "constraints": [ { - "keyword": "maximum", - "value": 65536 - }, - { - "keyword": "minimum", - "value": 1 + "keyword": "required", + "value": [ + "rationale", + "request_fixture" + ] }, { "keyword": "type", - "value": "integer" + "value": "object" } - ] + ], + "local_reference": { + "schema": "integration", + "pointer": "/$defs/notApplicableReason" + } }, { "address": { "schema": "integration", - "pointer": "/$defs/outputArray/properties/max_items", + "pointer": "/$defs/notApplicable/properties/subject_mismatch", "path_kind": "property" }, - "purpose": "Caps the number of values released in one structured output array.", - "purpose_source": "reviewed_override", + "purpose": "Why the reviewed response contract contains no identifier comparable with a requested selector.", + "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "integer" + "object" ], + "local_reference": "#/$defs/notApplicableReason", "composed": false }, - "requiredness": "required", + "requiredness": "optional", "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { @@ -49482,39 +49055,42 @@ ], "constraints": [ { - "keyword": "maximum", - "value": 256 - }, - { - "keyword": "minimum", - "value": 1 + "keyword": "required", + "value": [ + "rationale", + "request_fixture" + ] }, { "keyword": "type", - "value": "integer" + "value": "object" } - ] + ], + "local_reference": { + "schema": "integration", + "pointer": "/$defs/notApplicableReason" + } }, { "address": { "schema": "integration", - "pointer": "/$defs/outputArray/properties/nullable", + "pointer": "/$defs/notApplicableReason/properties/rationale", "path_kind": "property" }, - "purpose": "Declares whether the complete structured output array may be null.", - "purpose_source": "reviewed_override", + "purpose": "Why the named normally required outcome cannot occur for this source contract.", + "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "boolean" + "string" ], "composed": false }, "requiredness": "required", "null_behavior": "rejected", - "empty_behavior": "not_applicable", + "empty_behavior": "rejected", "default": { "behavior": "no_schema_default" }, @@ -49578,30 +49154,41 @@ "generated_docs_never_load_country_values" ], "constraints": [ + { + "keyword": "maxLength", + "value": 512 + }, + { + "keyword": "minLength", + "value": 24 + }, { "keyword": "type", - "value": "boolean" + "value": "string" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/outputArray/properties/type", + "pointer": "/$defs/notApplicableReason/properties/request_fixture", "path_kind": "property" }, - "purpose": "Selects the array form for a structured integration output.", - "purpose_source": "reviewed_override", + "purpose": "Fixture name containing the supporting bounded source request.", + "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [], + "schema_types": [ + "string" + ], + "local_reference": "#/$defs/stableId", "composed": false }, "requiredness": "required", "null_behavior": "rejected", - "empty_behavior": "not_applicable", + "empty_behavior": "rejected", "default": { "behavior": "no_schema_default" }, @@ -49666,36 +49253,801 @@ ], "constraints": [ { - "keyword": "const", - "value": "array" + "keyword": "pattern", + "value": "^[a-z][a-z0-9._-]{0,95}$" + }, + { + "keyword": "type", + "value": "string" } - ] + ], + "local_reference": { + "schema": "integration", + "pointer": "/$defs/stableId" + } }, { "address": { "schema": "integration", - "pointer": "/$defs/outputObject/properties/fields", - "path_kind": "property" + "pointer": "/$defs/objectType/oneOf/0", + "path_kind": "branch" }, - "purpose": "Declares the bounded closed map of fields released in one structured output object.", - "purpose_source": "reviewed_override", + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [ - "object" - ], + "schema_types": [], "composed": false }, - "requiredness": "required", - "null_behavior": "rejected", + "requiredness": "conditional", + "null_behavior": "not_applicable", "empty_behavior": "not_applicable", "default": { - "behavior": "no_schema_default" + "behavior": "not_applicable" }, "environment_behavior": "narrows_reviewed_authority", - "sensitivity": "internal", + "sensitivity": "structural", + "state": "authored", + "products": [ + "registryctl", + "relay", + "notary", + "editor", + "docs" + ], + "availability": "published", + "stability": "experimental", + "validation_stages": [ + "json_schema", + "rust_deserialization", + "cross_file_semantic", + "fixture_execution", + "product_build" + ], + "diagnostic": "registryctl.authoring.integration.invalid", + "history_status": "not_verified", + "introduced_in": null, + "version_history": [], + "example": { + "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", + "schema_examples_available": false, + "contains_country_values": false + }, + "migration": "rebuild_project", + "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", + "consumers": [ + "registryctl_authoring", + "registry_relay", + "registry_notary", + "editor_tooling", + "docs_generator" + ], + "generated_artifacts": [ + "editor_schemas", + "project_build", + "relay_config", + "notary_config", + "fixture_report", + "field_reference" + ], + "review_classes": [ + "contract", + "security", + "privacy", + "relay", + "notary", + "compatibility", + "documentation", + "testing" + ], + "semantic_rules": [ + "knowledge_only", + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" + ], + "constraints": [ + { + "keyword": "const", + "value": "object" + } + ] + }, + { + "address": { + "schema": "integration", + "pointer": "/$defs/objectType/oneOf/1", + "path_kind": "branch" + }, + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", + "semantic_owner": "integration_contract", + "human_owner": "integration_maintainers", + "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", + "field_type": { + "schema_types": [ + "array" + ], + "composed": false + }, + "requiredness": "conditional", + "null_behavior": "not_applicable", + "empty_behavior": "not_applicable", + "default": { + "behavior": "not_applicable" + }, + "environment_behavior": "narrows_reviewed_authority", + "sensitivity": "structural", + "state": "authored", + "products": [ + "registryctl", + "relay", + "notary", + "editor", + "docs" + ], + "availability": "published", + "stability": "experimental", + "validation_stages": [ + "json_schema", + "rust_deserialization", + "cross_file_semantic", + "fixture_execution", + "product_build" + ], + "diagnostic": "registryctl.authoring.integration.invalid", + "history_status": "not_verified", + "introduced_in": null, + "version_history": [], + "example": { + "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", + "schema_examples_available": false, + "contains_country_values": false + }, + "migration": "rebuild_project", + "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", + "consumers": [ + "registryctl_authoring", + "registry_relay", + "registry_notary", + "editor_tooling", + "docs_generator" + ], + "generated_artifacts": [ + "editor_schemas", + "project_build", + "relay_config", + "notary_config", + "fixture_report", + "field_reference" + ], + "review_classes": [ + "contract", + "security", + "privacy", + "relay", + "notary", + "compatibility", + "documentation", + "testing" + ], + "semantic_rules": [ + "knowledge_only", + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" + ], + "constraints": [ + { + "keyword": "maxItems", + "value": 2 + }, + { + "keyword": "minItems", + "value": 2 + }, + { + "keyword": "type", + "value": "array" + } + ] + }, + { + "address": { + "schema": "integration", + "pointer": "/$defs/objectType/oneOf/1/prefixItems/0", + "path_kind": "array_item" + }, + "purpose": "Defines the contract shared by each ordered item in the enclosing authored list.", + "purpose_source": "structural_taxonomy", + "semantic_owner": "integration_contract", + "human_owner": "integration_maintainers", + "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", + "field_type": { + "schema_types": [], + "composed": false + }, + "requiredness": "not_applicable", + "null_behavior": "rejected", + "empty_behavior": "not_applicable", + "default": { + "behavior": "no_schema_default" + }, + "environment_behavior": "narrows_reviewed_authority", + "sensitivity": "internal", + "state": "authored", + "products": [ + "registryctl", + "relay", + "notary", + "editor", + "docs" + ], + "availability": "published", + "stability": "experimental", + "validation_stages": [ + "json_schema", + "rust_deserialization", + "cross_file_semantic", + "fixture_execution", + "product_build" + ], + "diagnostic": "registryctl.authoring.integration.invalid", + "history_status": "not_verified", + "introduced_in": null, + "version_history": [], + "example": { + "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", + "schema_examples_available": false, + "contains_country_values": false + }, + "migration": "rebuild_project", + "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", + "consumers": [ + "registryctl_authoring", + "registry_relay", + "registry_notary", + "editor_tooling", + "docs_generator" + ], + "generated_artifacts": [ + "editor_schemas", + "project_build", + "relay_config", + "notary_config", + "fixture_report", + "field_reference" + ], + "review_classes": [ + "contract", + "security", + "privacy", + "relay", + "notary", + "compatibility", + "documentation", + "testing" + ], + "semantic_rules": [ + "knowledge_only", + "generated_docs_never_load_country_values", + "array_items_share_element_contract" + ], + "constraints": [ + { + "keyword": "const", + "value": "object" + } + ] + }, + { + "address": { + "schema": "integration", + "pointer": "/$defs/objectType/oneOf/1/prefixItems/1", + "path_kind": "array_item" + }, + "purpose": "Defines the contract shared by each ordered item in the enclosing authored list.", + "purpose_source": "structural_taxonomy", + "semantic_owner": "integration_contract", + "human_owner": "integration_maintainers", + "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", + "field_type": { + "schema_types": [], + "composed": false + }, + "requiredness": "not_applicable", + "null_behavior": "rejected", + "empty_behavior": "not_applicable", + "default": { + "behavior": "no_schema_default" + }, + "environment_behavior": "narrows_reviewed_authority", + "sensitivity": "internal", + "state": "authored", + "products": [ + "registryctl", + "relay", + "notary", + "editor", + "docs" + ], + "availability": "published", + "stability": "experimental", + "validation_stages": [ + "json_schema", + "rust_deserialization", + "cross_file_semantic", + "fixture_execution", + "product_build" + ], + "diagnostic": "registryctl.authoring.integration.invalid", + "history_status": "not_verified", + "introduced_in": null, + "version_history": [], + "example": { + "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", + "schema_examples_available": false, + "contains_country_values": false + }, + "migration": "rebuild_project", + "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", + "consumers": [ + "registryctl_authoring", + "registry_relay", + "registry_notary", + "editor_tooling", + "docs_generator" + ], + "generated_artifacts": [ + "editor_schemas", + "project_build", + "relay_config", + "notary_config", + "fixture_report", + "field_reference" + ], + "review_classes": [ + "contract", + "security", + "privacy", + "relay", + "notary", + "compatibility", + "documentation", + "testing" + ], + "semantic_rules": [ + "knowledge_only", + "generated_docs_never_load_country_values", + "array_items_share_element_contract" + ], + "constraints": [ + { + "keyword": "const", + "value": "null" + } + ] + }, + { + "address": { + "schema": "integration", + "pointer": "/$defs/output/oneOf/0", + "path_kind": "branch" + }, + "purpose": "Type, scalar bounds, and optional source pointer for one normalized scalar integration output.", + "purpose_source": "schema_description", + "semantic_owner": "integration_contract", + "human_owner": "integration_maintainers", + "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", + "field_type": { + "schema_types": [ + "object" + ], + "local_reference": "#/$defs/scalarOutput", + "composed": false + }, + "requiredness": "conditional", + "null_behavior": "not_applicable", + "empty_behavior": "not_applicable", + "default": { + "behavior": "not_applicable" + }, + "environment_behavior": "narrows_reviewed_authority", + "sensitivity": "structural", + "state": "authored", + "products": [ + "registryctl", + "relay", + "notary", + "editor", + "docs" + ], + "availability": "published", + "stability": "experimental", + "validation_stages": [ + "json_schema", + "rust_deserialization", + "cross_file_semantic", + "fixture_execution", + "product_build" + ], + "diagnostic": "registryctl.authoring.integration.invalid", + "history_status": "not_verified", + "introduced_in": null, + "version_history": [], + "example": { + "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", + "schema_examples_available": false, + "contains_country_values": false + }, + "migration": "rebuild_project", + "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", + "consumers": [ + "registryctl_authoring", + "registry_relay", + "registry_notary", + "editor_tooling", + "docs_generator" + ], + "generated_artifacts": [ + "editor_schemas", + "project_build", + "relay_config", + "notary_config", + "fixture_report", + "field_reference" + ], + "review_classes": [ + "contract", + "security", + "privacy", + "relay", + "notary", + "compatibility", + "documentation", + "testing" + ], + "semantic_rules": [ + "knowledge_only", + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" + ], + "constraints": [ + { + "keyword": "required", + "value": [ + "type" + ] + }, + { + "keyword": "type", + "value": "object" + } + ], + "local_reference": { + "schema": "integration", + "pointer": "/$defs/scalarOutput" + } + }, + { + "address": { + "schema": "integration", + "pointer": "/$defs/output/oneOf/1", + "path_kind": "branch" + }, + "purpose": "A recursively typed object output with a canonical byte ceiling and an always-closed field map.", + "purpose_source": "schema_description", + "semantic_owner": "integration_contract", + "human_owner": "integration_maintainers", + "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", + "field_type": { + "schema_types": [ + "object" + ], + "local_reference": "#/$defs/outputObject", + "composed": false + }, + "requiredness": "conditional", + "null_behavior": "not_applicable", + "empty_behavior": "not_applicable", + "default": { + "behavior": "not_applicable" + }, + "environment_behavior": "narrows_reviewed_authority", + "sensitivity": "structural", + "state": "authored", + "products": [ + "registryctl", + "relay", + "notary", + "editor", + "docs" + ], + "availability": "published", + "stability": "experimental", + "validation_stages": [ + "json_schema", + "rust_deserialization", + "cross_file_semantic", + "fixture_execution", + "product_build" + ], + "diagnostic": "registryctl.authoring.integration.invalid", + "history_status": "not_verified", + "introduced_in": null, + "version_history": [], + "example": { + "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", + "schema_examples_available": false, + "contains_country_values": false + }, + "migration": "rebuild_project", + "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", + "consumers": [ + "registryctl_authoring", + "registry_relay", + "registry_notary", + "editor_tooling", + "docs_generator" + ], + "generated_artifacts": [ + "editor_schemas", + "project_build", + "relay_config", + "notary_config", + "fixture_report", + "field_reference" + ], + "review_classes": [ + "contract", + "security", + "privacy", + "relay", + "notary", + "compatibility", + "documentation", + "testing" + ], + "semantic_rules": [ + "knowledge_only", + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" + ], + "constraints": [ + { + "keyword": "required", + "value": [ + "type", + "max_bytes", + "fields" + ] + }, + { + "keyword": "type", + "value": "object" + } + ], + "local_reference": { + "schema": "integration", + "pointer": "/$defs/outputObject" + } + }, + { + "address": { + "schema": "integration", + "pointer": "/$defs/output/oneOf/2", + "path_kind": "branch" + }, + "purpose": "A recursively typed array output with canonical byte and item-count ceilings.", + "purpose_source": "schema_description", + "semantic_owner": "integration_contract", + "human_owner": "integration_maintainers", + "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", + "field_type": { + "schema_types": [ + "object" + ], + "local_reference": "#/$defs/outputArray", + "composed": false + }, + "requiredness": "conditional", + "null_behavior": "not_applicable", + "empty_behavior": "not_applicable", + "default": { + "behavior": "not_applicable" + }, + "environment_behavior": "narrows_reviewed_authority", + "sensitivity": "structural", + "state": "authored", + "products": [ + "registryctl", + "relay", + "notary", + "editor", + "docs" + ], + "availability": "published", + "stability": "experimental", + "validation_stages": [ + "json_schema", + "rust_deserialization", + "cross_file_semantic", + "fixture_execution", + "product_build" + ], + "diagnostic": "registryctl.authoring.integration.invalid", + "history_status": "not_verified", + "introduced_in": null, + "version_history": [], + "example": { + "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", + "schema_examples_available": false, + "contains_country_values": false + }, + "migration": "rebuild_project", + "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", + "consumers": [ + "registryctl_authoring", + "registry_relay", + "registry_notary", + "editor_tooling", + "docs_generator" + ], + "generated_artifacts": [ + "editor_schemas", + "project_build", + "relay_config", + "notary_config", + "fixture_report", + "field_reference" + ], + "review_classes": [ + "contract", + "security", + "privacy", + "relay", + "notary", + "compatibility", + "documentation", + "testing" + ], + "semantic_rules": [ + "knowledge_only", + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" + ], + "constraints": [ + { + "keyword": "required", + "value": [ + "type", + "max_bytes", + "max_items", + "items" + ] + }, + { + "keyword": "type", + "value": "object" + } + ], + "local_reference": { + "schema": "integration", + "pointer": "/$defs/outputArray" + } + }, + { + "address": { + "schema": "integration", + "pointer": "/$defs/outputArray/properties/items", + "path_kind": "property" + }, + "purpose": "A recursively closed structured output schema without a source pointer.", + "purpose_source": "schema_description", + "semantic_owner": "integration_contract", + "human_owner": "integration_maintainers", + "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", + "field_type": { + "schema_types": [], + "local_reference": "#/$defs/outputSchema", + "composed": false + }, + "requiredness": "required", + "null_behavior": "rejected", + "empty_behavior": "not_applicable", + "default": { + "behavior": "no_schema_default" + }, + "environment_behavior": "narrows_reviewed_authority", + "sensitivity": "internal", + "state": "authored", + "products": [ + "registryctl", + "relay", + "notary", + "editor", + "docs" + ], + "availability": "published", + "stability": "experimental", + "validation_stages": [ + "json_schema", + "rust_deserialization", + "cross_file_semantic", + "fixture_execution", + "product_build" + ], + "diagnostic": "registryctl.authoring.integration.invalid", + "history_status": "not_verified", + "introduced_in": null, + "version_history": [], + "example": { + "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", + "schema_examples_available": false, + "contains_country_values": false + }, + "migration": "rebuild_project", + "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", + "consumers": [ + "registryctl_authoring", + "registry_relay", + "registry_notary", + "editor_tooling", + "docs_generator" + ], + "generated_artifacts": [ + "editor_schemas", + "project_build", + "relay_config", + "notary_config", + "fixture_report", + "field_reference" + ], + "review_classes": [ + "contract", + "security", + "privacy", + "relay", + "notary", + "compatibility", + "documentation", + "testing" + ], + "semantic_rules": [ + "knowledge_only", + "generated_docs_never_load_country_values" + ], + "constraints": [], + "local_reference": { + "schema": "integration", + "pointer": "/$defs/outputSchema" + } + }, + { + "address": { + "schema": "integration", + "pointer": "/$defs/outputArray/properties/max_bytes", + "path_kind": "property" + }, + "purpose": "Caps the canonical serialized size of one structured output array.", + "purpose_source": "reviewed_override", + "semantic_owner": "integration_contract", + "human_owner": "integration_maintainers", + "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", + "field_type": { + "schema_types": [ + "integer" + ], + "composed": false + }, + "requiredness": "required", + "null_behavior": "rejected", + "empty_behavior": "not_applicable", + "default": { + "behavior": "no_schema_default" + }, + "environment_behavior": "narrows_reviewed_authority", + "sensitivity": "internal", "state": "authored", "products": [ "registryctl", @@ -49755,38 +50107,37 @@ ], "constraints": [ { - "keyword": "maxProperties", - "value": 32 + "keyword": "maximum", + "value": 65536 }, { - "keyword": "minProperties", + "keyword": "minimum", "value": 1 }, { "keyword": "type", - "value": "object" + "value": "integer" } ] }, { "address": { "schema": "integration", - "pointer": "/$defs/outputObject/properties/fields/additionalProperties", - "path_kind": "map_value" + "pointer": "/$defs/outputArray/properties/max_items", + "path_kind": "property" }, - "purpose": "Requiredness and recursive schema for one named field of a closed structured output object.", - "purpose_source": "schema_description", + "purpose": "Caps the number of values released in one structured output array.", + "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "object" + "integer" ], - "local_reference": "#/$defs/outputObjectField", "composed": false }, - "requiredness": "not_applicable", + "requiredness": "required", "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { @@ -49849,48 +50200,230 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values", - "arbitrary_map_keys_not_fixed_properties" + "generated_docs_never_load_country_values" ], "constraints": [ { - "keyword": "required", - "value": [ - "required", - "schema" - ] + "keyword": "maximum", + "value": 256 + }, + { + "keyword": "minimum", + "value": 1 }, { "keyword": "type", - "value": "object" + "value": "integer" } + ] + }, + { + "address": { + "schema": "integration", + "pointer": "/$defs/outputArray/properties/type", + "path_kind": "property" + }, + "purpose": "Selects the array form for a structured integration output, and declares the array nullable by pairing it with null.", + "purpose_source": "reviewed_override", + "semantic_owner": "integration_contract", + "human_owner": "integration_maintainers", + "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", + "field_type": { + "schema_types": [ + "array" + ], + "local_reference": "#/$defs/arrayType", + "composed": false + }, + "requiredness": "required", + "null_behavior": "rejected", + "empty_behavior": "not_applicable", + "default": { + "behavior": "no_schema_default" + }, + "environment_behavior": "narrows_reviewed_authority", + "sensitivity": "internal", + "state": "authored", + "products": [ + "registryctl", + "relay", + "notary", + "editor", + "docs" + ], + "availability": "published", + "stability": "experimental", + "validation_stages": [ + "json_schema", + "rust_deserialization", + "cross_file_semantic", + "fixture_execution", + "product_build" + ], + "diagnostic": "registryctl.authoring.integration.invalid", + "history_status": "not_verified", + "introduced_in": null, + "version_history": [], + "example": { + "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", + "schema_examples_available": false, + "contains_country_values": false + }, + "migration": "rebuild_project", + "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", + "consumers": [ + "registryctl_authoring", + "registry_relay", + "registry_notary", + "editor_tooling", + "docs_generator" + ], + "generated_artifacts": [ + "editor_schemas", + "project_build", + "relay_config", + "notary_config", + "fixture_report", + "field_reference" + ], + "review_classes": [ + "contract", + "security", + "privacy", + "relay", + "notary", + "compatibility", + "documentation", + "testing" + ], + "semantic_rules": [ + "knowledge_only", + "generated_docs_never_load_country_values" ], + "constraints": [], "local_reference": { "schema": "integration", - "pointer": "/$defs/outputObjectField" + "pointer": "/$defs/arrayType" } }, { "address": { "schema": "integration", - "pointer": "/$defs/outputObject/properties/fields/propertyNames", - "path_kind": "map_key" + "pointer": "/$defs/outputObject/properties/fields", + "path_kind": "property" }, - "purpose": "Portable lowercase name for an integration input or output.", + "purpose": "Declares the bounded closed map of fields released in one structured output object.", + "purpose_source": "reviewed_override", + "semantic_owner": "integration_contract", + "human_owner": "integration_maintainers", + "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", + "field_type": { + "schema_types": [ + "object" + ], + "composed": false + }, + "requiredness": "required", + "null_behavior": "rejected", + "empty_behavior": "not_applicable", + "default": { + "behavior": "no_schema_default" + }, + "environment_behavior": "narrows_reviewed_authority", + "sensitivity": "internal", + "state": "authored", + "products": [ + "registryctl", + "relay", + "notary", + "editor", + "docs" + ], + "availability": "published", + "stability": "experimental", + "validation_stages": [ + "json_schema", + "rust_deserialization", + "cross_file_semantic", + "fixture_execution", + "product_build" + ], + "diagnostic": "registryctl.authoring.integration.invalid", + "history_status": "not_verified", + "introduced_in": null, + "version_history": [], + "example": { + "guidance": "Use a bounded synthetic source contract and fixture-safe values that demonstrate behavior without revealing a country endpoint or record.", + "schema_examples_available": false, + "contains_country_values": false + }, + "migration": "rebuild_project", + "migration_note": "Update affected fixtures and rebuild the project; re-review authority whenever source access, credentials, or bounds change.", + "consumers": [ + "registryctl_authoring", + "registry_relay", + "registry_notary", + "editor_tooling", + "docs_generator" + ], + "generated_artifacts": [ + "editor_schemas", + "project_build", + "relay_config", + "notary_config", + "fixture_report", + "field_reference" + ], + "review_classes": [ + "contract", + "security", + "privacy", + "relay", + "notary", + "compatibility", + "documentation", + "testing" + ], + "semantic_rules": [ + "knowledge_only", + "generated_docs_never_load_country_values" + ], + "constraints": [ + { + "keyword": "maxProperties", + "value": 32 + }, + { + "keyword": "minProperties", + "value": 1 + }, + { + "keyword": "type", + "value": "object" + } + ] + }, + { + "address": { + "schema": "integration", + "pointer": "/$defs/outputObject/properties/fields/additionalProperties", + "path_kind": "map_value" + }, + "purpose": "Requiredness and recursive schema for one named field of a closed structured output object.", "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "string" + "object" ], - "local_reference": "#/$defs/inputName", + "local_reference": "#/$defs/outputObjectField", "composed": false }, "requiredness": "not_applicable", "null_behavior": "rejected", - "empty_behavior": "rejected", + "empty_behavior": "not_applicable", "default": { "behavior": "no_schema_default" }, @@ -49956,39 +50489,43 @@ ], "constraints": [ { - "keyword": "pattern", - "value": "^[a-z][a-z0-9_]{0,63}$" + "keyword": "required", + "value": [ + "required", + "schema" + ] }, { "keyword": "type", - "value": "string" + "value": "object" } ], "local_reference": { "schema": "integration", - "pointer": "/$defs/inputName" + "pointer": "/$defs/outputObjectField" } }, { "address": { "schema": "integration", - "pointer": "/$defs/outputObject/properties/max_bytes", - "path_kind": "property" + "pointer": "/$defs/outputObject/properties/fields/propertyNames", + "path_kind": "map_key" }, - "purpose": "Caps the canonical serialized size of one structured output object.", - "purpose_source": "reviewed_override", + "purpose": "Portable lowercase name for an integration input or output.", + "purpose_source": "schema_description", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "integer" + "string" ], + "local_reference": "#/$defs/inputName", "composed": false }, - "requiredness": "required", + "requiredness": "not_applicable", "null_behavior": "rejected", - "empty_behavior": "not_applicable", + "empty_behavior": "rejected", "default": { "behavior": "no_schema_default" }, @@ -50049,37 +50586,38 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "arbitrary_map_keys_not_fixed_properties" ], "constraints": [ { - "keyword": "maximum", - "value": 65536 - }, - { - "keyword": "minimum", - "value": 1 + "keyword": "pattern", + "value": "^[a-z][a-z0-9_]{0,63}$" }, { "keyword": "type", - "value": "integer" + "value": "string" } - ] + ], + "local_reference": { + "schema": "integration", + "pointer": "/$defs/inputName" + } }, { "address": { "schema": "integration", - "pointer": "/$defs/outputObject/properties/nullable", + "pointer": "/$defs/outputObject/properties/max_bytes", "path_kind": "property" }, - "purpose": "Declares whether the complete structured output object may be null.", + "purpose": "Caps the canonical serialized size of one structured output object.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { "schema_types": [ - "boolean" + "integer" ], "composed": false }, @@ -50149,9 +50687,17 @@ "generated_docs_never_load_country_values" ], "constraints": [ + { + "keyword": "maximum", + "value": 65536 + }, + { + "keyword": "minimum", + "value": 1 + }, { "keyword": "type", - "value": "boolean" + "value": "integer" } ] }, @@ -50161,13 +50707,16 @@ "pointer": "/$defs/outputObject/properties/type", "path_kind": "property" }, - "purpose": "Selects the closed object form for a structured integration output.", + "purpose": "Selects the closed object form for a structured integration output, and declares the object nullable by pairing it with null.", "purpose_source": "reviewed_override", "semantic_owner": "integration_contract", "human_owner": "integration_maintainers", "scope": "A reviewed source contract, bounded adaptation capability, typed inputs and outputs, and offline verification requirements.", "field_type": { - "schema_types": [], + "schema_types": [ + "array" + ], + "local_reference": "#/$defs/objectType", "composed": false }, "requiredness": "required", @@ -50235,12 +50784,11 @@ "knowledge_only", "generated_docs_never_load_country_values" ], - "constraints": [ - { - "keyword": "const", - "value": "object" - } - ] + "constraints": [], + "local_reference": { + "schema": "integration", + "pointer": "/$defs/objectType" + } }, { "address": { @@ -50608,7 +51156,6 @@ "keyword": "required", "value": [ "type", - "nullable", "max_bytes", "fields" ] @@ -50712,7 +51259,6 @@ "keyword": "required", "value": [ "type", - "nullable", "max_bytes", "max_items", "items" From ce41d6bb041957400d89597d3a2e57853c06b4c1 Mon Sep 17 00:00:00 2001 From: Jeremi Joslin Date: Sat, 1 Aug 2026 16:28:54 +0700 Subject: [PATCH 2/3] fix(registryctl): recover colon-punctuated output paths and un-invert the example Two review findings, both correct. The authored-path recovery only fired for messages that end the path at a space, like `outputs.parents.maxLength is required`. The validators also punctuate with a colon, as in `outputs.parents: structured outputs require capability.script`, and the trailing colon failed the segment grammar check, so those errors silently fell back to a whole-document diagnostic. Nine such messages in `authoring_contract.rs` were affected, including both structured outputs on an HTTP capability. Trailing separators are now stripped before the check. The canonical `integration.schema.json` example migrated `nullable: false` to `type: ["array", "null"]`, which makes it nullable: the opposite of what it declared, and the opposite of the migration the changelog documents. The nested object in the same example was migrated correctly, so the example also disagreed with itself. It is now plain `type: "array"`. This is the example implementers copy first. Nothing validated those examples before; the documentation pipeline only recorded whether examples were present. Every published authoring schema's example is now checked against its own schema. That check would not have caught this inversion, since both spellings are schema-valid and only the intent differs, but it closes the wider hole. Signed-off-by: Jeremi Joslin --- .../project-authoring/integration.schema.json | 2 +- .../src/project_authoring/diagnostics.rs | 40 +++++++++++++++ .../tests/project_authoring_schema_parity.rs | 51 +++++++++++++++++++ 3 files changed, 92 insertions(+), 1 deletion(-) diff --git a/crates/registryctl/schemas/project-authoring/integration.schema.json b/crates/registryctl/schemas/project-authoring/integration.schema.json index 8730fe003..992cc4717 100644 --- a/crates/registryctl/schemas/project-authoring/integration.schema.json +++ b/crates/registryctl/schemas/project-authoring/integration.schema.json @@ -67,7 +67,7 @@ "outputs": { "active": { "type": "boolean" }, "parents": { - "type": ["array", "null"], + "type": "array", "max_bytes": 4096, "max_items": 2, "items": { diff --git a/crates/registryctl/src/project_authoring/diagnostics.rs b/crates/registryctl/src/project_authoring/diagnostics.rs index aeba2826d..257847349 100644 --- a/crates/registryctl/src/project_authoring/diagnostics.rs +++ b/crates/registryctl/src/project_authoring/diagnostics.rs @@ -2517,6 +2517,13 @@ fn cross_file_diagnostic( /// whole document. Only a leading token whose every segment matches the /// authored path grammar is recovered, so no other error text reaches an /// address, and the rendered diagnostic text stays static either way. +/// +/// The validators punctuate that leading token two ways: `outputs.parents. +/// maxLength is required` ends the path at a space, while `outputs.parents: +/// structured outputs require capability.script` ends it at a colon. The +/// trailing punctuation is stripped before the grammar check, because leaving +/// it on made every colon-punctuated message fail the check and fall back to a +/// whole-document diagnostic. fn authored_output_addresses( file: &str, error: &anyhow::Error, @@ -2526,6 +2533,7 @@ fn authored_output_addresses( let Some(candidate) = message.split_whitespace().next() else { continue; }; + let candidate = candidate.trim_end_matches([':', ',', '.']); let segments = candidate.split('.').collect::>(); if segments.len() < 2 || segments[0] != "outputs" { continue; @@ -2875,6 +2883,38 @@ limits: { calls: 1, source_bytes: 512KiB, request_bytes: 32KiB, deadline: 20s } ); } + fn recovered_pointers(message: &str) -> Vec { + authored_output_addresses( + "integrations/example/integration.yaml", + &anyhow::anyhow!("{message}"), + ) + .into_iter() + .map(|address| address.pointer) + .collect() + } + + #[test] + fn an_output_path_followed_by_a_colon_still_recovers_its_address() { + assert_eq!( + recovered_pointers("outputs.parents: structured outputs require capability.script"), + vec!["/outputs/parents".to_string()] + ); + } + + #[test] + fn an_output_path_followed_by_a_space_recovers_the_same_address() { + assert_eq!( + recovered_pointers("outputs.parents.maxLength is required"), + vec!["/outputs/parents/maxLength".to_string()] + ); + } + + #[test] + fn a_message_that_names_no_output_path_recovers_nothing() { + assert!(recovered_pointers("capability.script is required").is_empty()); + assert!(recovered_pointers("outputs: at least one output is required").is_empty()); + } + #[test] fn dynamic_relationship_address_escapes_each_rfc6901_segment() { assert_eq!( diff --git a/crates/registryctl/tests/project_authoring_schema_parity.rs b/crates/registryctl/tests/project_authoring_schema_parity.rs index 771073d54..1bd0ee891 100644 --- a/crates/registryctl/tests/project_authoring_schema_parity.rs +++ b/crates/registryctl/tests/project_authoring_schema_parity.rs @@ -2504,3 +2504,54 @@ fn authored_array_layers(nodes: usize) -> Value { } schema } + +/// The `examples` block of each authoring schema is what an implementer copies +/// first, so it has to satisfy the schema it illustrates. Nothing validated it +/// before: the documentation pipeline only records whether examples are +/// present. This does not judge what an example declares, only that the +/// declaration is well formed; an example that is valid but says the wrong +/// thing is still a reading problem. +#[test] +fn every_published_authoring_schema_example_validates_against_its_own_schema() { + let mut checked = 0_usize; + for entry in + std::fs::read_dir(schema_root()).expect("the authoring schema directory is readable") + { + let path = entry + .expect("each schema directory entry is readable") + .path(); + if path.extension().and_then(|extension| extension.to_str()) != Some("json") { + continue; + } + let name = path + .file_name() + .and_then(|name| name.to_str()) + .expect("each schema file has a UTF-8 name") + .to_string(); + let document: Value = serde_json::from_str( + &std::fs::read_to_string(&path).unwrap_or_else(|_| panic!("{name} is readable")), + ) + .unwrap_or_else(|error| panic!("{name} is valid JSON: {error}")); + let Some(examples) = document.get("examples").and_then(Value::as_array) else { + continue; + }; + let validator = jsonschema::JSONSchema::options() + .with_draft(jsonschema::Draft::Draft202012) + .compile(&document) + .unwrap_or_else(|error| panic!("{name} compiles as a schema: {error}")); + for (index, example) in examples.iter().enumerate() { + if let Err(errors) = validator.validate(example) { + let report = errors + .map(|error| format!(" {}: {error}", error.instance_path)) + .collect::>() + .join("\n"); + panic!("{name} example {index} does not satisfy {name}:\n{report}"); + } + checked += 1; + } + } + assert!( + checked >= 5, + "expected every published authoring schema to keep its example, found {checked}" + ); +} From b629dea55b6d857cdf3cef93acec06aa7b12cead Mon Sep 17 00:00:00 2001 From: Jeremi Joslin Date: Sat, 1 Aug 2026 17:21:22 +0700 Subject: [PATCH 3/3] fix(registryctl): declare claim value nullability with the type union A claim value now declares nullability the same way as every other authored declaration. Write `type: [string, "null"]` for a nullable claim value and `type: string` for a required one; the separate `nullable:` key it carried is removed. That key shipped with the project authoring workflow in 0.10.0 and was the last place on the authored surface that spelled nullability a second way, so scalar outputs, structured outputs, entity fields, and claim values now all read the same. The key is a released surface, so removing it is a break and carries a `BREAKING:` entry with migration steps in the crate changelog, per the pre-1.0 rule in the API stability reference. Delete `nullable: true` and pair the declared type with `"null"` in the `type` union; delete `nullable: false` outright, since a type without `"null"` is already non-nullable. An authored project that still carries the key is rejected by `registryctl.authoring.yaml.unknown_field`, naming the offending claim pointer and the union syntax that replaces it, rather than collapsing to a whole-service schema error. The union type is the existing tuple idiom, parameterized rather than copied. `AuthoredObjectSchemaType` and `AuthoredArraySchemaType` become aliases of one generic `AuthoredNullableType` that claim values reuse with their own type enum, so there is one nullability code path with three users instead of three near-identical enums. Claim values keep their own type enum because they admit `date`, which no output scalar does, and widening the output scalar enum would have loosened four unrelated typed surfaces past their published schemas. The retired-key diagnostic signal is likewise extended, not duplicated: `retired_nullable_key` carries which authored surface was found instead of a bare flag, and the recovered validation location is shared between the integration output union and the project service union. The removed claim-value `nullable` field had no readers. It never reached Relay or Notary compilation, and no authored fixture declares a claim value, so no generated product input changes. The build output digest moves only because the reviewed field-knowledge revision covers the published schema paths, which is the review gate working as designed. The `nullable` field on the compiled Relay and Notary contracts is a different, internal wire surface and is unchanged. The `docs/site` generated reference data is produced by `node scripts/generate-authoring-reference.mjs`, and `dto-shape-contract.v1.json` by the ignored `regenerate_dto_shape_contract_from_five_rust_roots` test; both are byte-identical on a second run. The `docs/site` reference test counters were stale from the preceding structured-output commit, which regenerated the data without moving them, and are corrected to the generated values here. Signed-off-by: Jeremi Joslin --- crates/registryctl/CHANGELOG.md | 13 + .../documentation-intent.json | 11 +- .../dto-shape-contract.v1.json | 93 +++-- .../project-authoring/project.schema.json | 19 +- .../project_authoring/authoring_contract.rs | 81 +++-- .../src/project_authoring/diagnostics.rs | 77 ++++- .../src/project_authoring/documentation.rs | 2 +- .../src/project_authoring/model.rs | 17 +- .../src/project_authoring/project.rs | 6 +- .../project_authoring/promotion_projection.rs | 2 +- .../src/project_authoring/schema_authority.rs | 154 ++++++--- .../src/project_authoring/tests.rs | 56 ++++ crates/registryctl/tests/project_authoring.rs | 2 +- .../tests/project_authoring_schema_parity.rs | 36 +- .../tests/project_documentation_reference.rs | 20 +- .../configuration-reference-coverage.v1.json | 28 +- .../generated/configuration-reference.v1.json | 317 ++++++++++++++++-- .../scripts/authoring-reference-docs.test.mjs | 22 +- .../configuration-reference-coverage.json | 28 +- .../generated/configuration-reference.json | 317 ++++++++++++++++-- 20 files changed, 1069 insertions(+), 232 deletions(-) diff --git a/crates/registryctl/CHANGELOG.md b/crates/registryctl/CHANGELOG.md index 72ea20f60..2280dbc1c 100644 --- a/crates/registryctl/CHANGELOG.md +++ b/crates/registryctl/CHANGELOG.md @@ -21,6 +21,19 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). union syntax to replace it. The `nullable` field on the compiled Registry Relay and Registry Notary contracts is a different, internal wire surface and is unchanged. +- BREAKING: a claim value declares nullability with its `type` union, the same + way scalar outputs, structured outputs, and entity fields already do. Write + `type: [string, "null"]` for a nullable claim value and `type: string` for a + required one, and the separate `nullable:` key is removed. It shipped with + the project authoring workflow in 0.10.0 and was the last place on the + authored surface that spelled nullability a second way. Migration: delete + `nullable: true` and pair the declared type with `"null"` in the `type` + union; delete `nullable: false` outright, since a type without `"null"` is + already non-nullable. An authored project that still carries the key is + rejected by `registryctl.authoring.yaml.unknown_field` with the offending + pointer and the union syntax to replace it. The `nullable` field on the + compiled Registry Relay and Registry Notary contracts is a different, + internal wire surface and is unchanged. ## [0.16.0] - 2026-08-01 diff --git a/crates/registryctl/schemas/project-authoring/documentation-intent.json b/crates/registryctl/schemas/project-authoring/documentation-intent.json index e7d05d82b..5d6d21117 100644 --- a/crates/registryctl/schemas/project-authoring/documentation-intent.json +++ b/crates/registryctl/schemas/project-authoring/documentation-intent.json @@ -96,6 +96,10 @@ { "schema": "project", "pointer": "/$defs/consultations/additionalProperties", "path_kind": "map_value" }, { "schema": "project", "pointer": "/$defs/consultations/additionalProperties/properties/input/propertyNames", "path_kind": "map_key" }, { "schema": "project", "pointer": "/$defs/consultations/additionalProperties/properties/input/additionalProperties", "path_kind": "map_value" }, + { "schema": "project", "pointer": "/$defs/claimValueType/oneOf/0", "path_kind": "branch" }, + { "schema": "project", "pointer": "/$defs/claimValueType/oneOf/1", "path_kind": "branch" }, + { "schema": "project", "pointer": "/$defs/claimValueType/oneOf/1/prefixItems/0", "path_kind": "array_item" }, + { "schema": "project", "pointer": "/$defs/claimValueType/oneOf/1/prefixItems/1", "path_kind": "array_item" }, { "schema": "environment", "pointer": "/properties/integrations/propertyNames", "path_kind": "map_key" }, { "schema": "environment", "pointer": "/properties/integrations/additionalProperties", "path_kind": "map_value" }, { "schema": "environment", "pointer": "/properties/entities/propertyNames", "path_kind": "map_key" }, @@ -893,12 +897,7 @@ { "schema": "project", "pointer": "/$defs/claimValue/properties/type", - "purpose": "Declares the boolean, integer, string, or date type of a claim value." - }, - { - "schema": "project", - "pointer": "/$defs/claimValue/properties/nullable", - "purpose": "States whether the claim value may be null." + "purpose": "Declares the boolean, integer, string, or date type of a claim value, paired with null when the claim value may be null." }, { "schema": "project", diff --git a/crates/registryctl/schemas/project-authoring/dto-shape-contract.v1.json b/crates/registryctl/schemas/project-authoring/dto-shape-contract.v1.json index d600ec0d5..df45ae998 100644 --- a/crates/registryctl/schemas/project-authoring/dto-shape-contract.v1.json +++ b/crates/registryctl/schemas/project-authoring/dto-shape-contract.v1.json @@ -24,6 +24,34 @@ }, "type": "object" }, + "AuthoredNullType": { + "description": "The `\"null\"` member of an authored composite `type` union.", + "enum": [ + "null" + ], + "type": "string" + }, + "AuthoredNullableType": { + "anyOf": [ + { + "$ref": "#/$defs/ClaimValueType" + }, + { + "maxItems": 2, + "minItems": 2, + "prefixItems": [ + { + "$ref": "#/$defs/ClaimValueType" + }, + { + "$ref": "#/$defs/AuthoredNullType" + } + ], + "type": "array" + } + ], + "description": "The one authored nullability idiom, shared with `AuthoredSchemaType`.\n\nScalar, object, array, and claim-value declarations all express nullability\nas the JSON-Schema-native `type` union `[, \"null\"]`. The tuple arm\nmakes the two-member form/null order part of the type rather than a runtime\nrule." + }, "ClaimDeclaration": { "additionalProperties": false, "properties": { @@ -73,12 +101,8 @@ "null" ] }, - "nullable": { - "default": false, - "type": "boolean" - }, "type": { - "$ref": "#/$defs/OutputType" + "$ref": "#/$defs/AuthoredNullableType" } }, "required": [ @@ -86,6 +110,16 @@ ], "type": "object" }, + "ClaimValueType": { + "description": "The types a claim value may take. Structured outputs are consulted through\nRelay but are never disclosed as a claim value, so `object`, `array`, and\n`presence` are absent by construction.", + "enum": [ + "boolean", + "integer", + "string", + "date" + ], + "type": "string" + }, "ConsentDeclaration": { "enum": [ "not_required", @@ -2529,26 +2563,6 @@ "rust_type": "AuthoredIntegrationDocument", "schema": { "$defs": { - "AuthoredArraySchemaType": { - "anyOf": [ - { - "$ref": "#/$defs/AuthoredOutputArrayType" - }, - { - "maxItems": 2, - "minItems": 2, - "prefixItems": [ - { - "$ref": "#/$defs/AuthoredOutputArrayType" - }, - { - "$ref": "#/$defs/AuthoredNullType" - } - ], - "type": "array" - } - ] - }, "AuthoredByteSize": { "anyOf": [ { @@ -2926,7 +2940,7 @@ ], "type": "string" }, - "AuthoredObjectSchemaType": { + "AuthoredNullableType": { "anyOf": [ { "$ref": "#/$defs/AuthoredOutputObjectType" @@ -2945,7 +2959,28 @@ "type": "array" } ], - "description": "The one authored nullability idiom, shared with `AuthoredSchemaType`.\n\nScalar, object, and array declarations all express nullability as the\nJSON-Schema-native `type` union `[, \"null\"]`. The tuple arm makes the\ntwo-member scalar/null order part of the type rather than a runtime rule." + "description": "The one authored nullability idiom, shared with `AuthoredSchemaType`.\n\nScalar, object, array, and claim-value declarations all express nullability\nas the JSON-Schema-native `type` union `[, \"null\"]`. The tuple arm\nmakes the two-member form/null order part of the type rather than a runtime\nrule." + }, + "AuthoredNullableType2": { + "anyOf": [ + { + "$ref": "#/$defs/AuthoredOutputArrayType" + }, + { + "maxItems": 2, + "minItems": 2, + "prefixItems": [ + { + "$ref": "#/$defs/AuthoredOutputArrayType" + }, + { + "$ref": "#/$defs/AuthoredNullType" + } + ], + "type": "array" + } + ], + "description": "The one authored nullability idiom, shared with `AuthoredSchemaType`.\n\nScalar, object, array, and claim-value declarations all express nullability\nas the JSON-Schema-native `type` union `[, \"null\"]`. The tuple arm\nmakes the two-member form/null order part of the type rather than a runtime\nrule." }, "AuthoredOutputArrayDeclaration": { "additionalProperties": false, @@ -2965,7 +3000,7 @@ "type": "integer" }, "type": { - "$ref": "#/$defs/AuthoredArraySchemaType" + "$ref": "#/$defs/AuthoredNullableType2" } }, "required": [ @@ -3010,7 +3045,7 @@ "type": "integer" }, "type": { - "$ref": "#/$defs/AuthoredObjectSchemaType" + "$ref": "#/$defs/AuthoredNullableType" } }, "required": [ diff --git a/crates/registryctl/schemas/project-authoring/project.schema.json b/crates/registryctl/schemas/project-authoring/project.schema.json index 0147c4f35..e06db6056 100644 --- a/crates/registryctl/schemas/project-authoring/project.schema.json +++ b/crates/registryctl/schemas/project-authoring/project.schema.json @@ -536,7 +536,24 @@ "claimValue": { "description": "Explicit claim value type, nullability, and encoded-size bound for a claim derived from declared Relay consultation outputs.", "type": "object", "additionalProperties": false, "required": ["type"], - "properties": { "type": {"x-registry-field": "property", "enum": ["boolean", "integer", "string", "date"] }, "nullable": {"x-registry-field": "property", "type": "boolean" }, "max_bytes": {"x-registry-field": "property", "type": "integer", "minimum": 1, "maximum": 65536 } } + "properties": { "type": {"x-registry-field": "property", "$ref": "#/$defs/claimValueType" }, "max_bytes": {"x-registry-field": "property", "type": "integer", "minimum": 1, "maximum": 65536 } } + }, + "claimValueType": { + "description": "Supported claim value type, optionally paired with null for a nullable claim value.", + "oneOf": [ + {"x-registry-field": "branch", "enum": ["boolean", "integer", "string", "date"] }, + { + "x-registry-field": "branch", + "type": "array", + "prefixItems": [ + {"x-registry-field": "array_item", "enum": ["boolean", "integer", "string", "date"] }, + {"x-registry-field": "array_item", "const": "null" } + ], + "minItems": 2, + "maxItems": 2, + "uniqueItems": true + } + ] } } } diff --git a/crates/registryctl/src/project_authoring/authoring_contract.rs b/crates/registryctl/src/project_authoring/authoring_contract.rs index 08dfe188e..08286ffa3 100644 --- a/crates/registryctl/src/project_authoring/authoring_contract.rs +++ b/crates/registryctl/src/project_authoring/authoring_contract.rs @@ -421,23 +421,32 @@ enum AuthoredOutputObjectType { /// The one authored nullability idiom, shared with `AuthoredSchemaType`. /// -/// Scalar, object, and array declarations all express nullability as the -/// JSON-Schema-native `type` union `[, "null"]`. The tuple arm makes the -/// two-member scalar/null order part of the type rather than a runtime rule. +/// Scalar, object, array, and claim-value declarations all express nullability +/// as the JSON-Schema-native `type` union `[, "null"]`. The tuple arm +/// makes the two-member form/null order part of the type rather than a runtime +/// rule. #[cfg_attr(test, derive(schemars::JsonSchema))] #[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq)] #[serde(untagged)] -enum AuthoredObjectSchemaType { - Single(AuthoredOutputObjectType), - Nullable((AuthoredOutputObjectType, AuthoredNullType)), +enum AuthoredNullableType { + Single(T), + Nullable((T, AuthoredNullType)), } -impl AuthoredObjectSchemaType { +impl AuthoredNullableType { const fn nullable(&self) -> bool { matches!(self, Self::Nullable(_)) } + + const fn form(&self) -> T { + match self { + Self::Single(form) | Self::Nullable((form, _)) => *form, + } + } } +type AuthoredObjectSchemaType = AuthoredNullableType; + #[cfg_attr(test, derive(schemars::JsonSchema))] #[derive(Debug, Deserialize, Serialize)] #[serde(deny_unknown_fields)] @@ -462,19 +471,7 @@ enum AuthoredOutputArrayType { Array, } -#[cfg_attr(test, derive(schemars::JsonSchema))] -#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq)] -#[serde(untagged)] -enum AuthoredArraySchemaType { - Single(AuthoredOutputArrayType), - Nullable((AuthoredOutputArrayType, AuthoredNullType)), -} - -impl AuthoredArraySchemaType { - const fn nullable(&self) -> bool { - matches!(self, Self::Nullable(_)) - } -} +type AuthoredArraySchemaType = AuthoredNullableType; /// The `"null"` member of an authored composite `type` union. #[cfg_attr(test, derive(schemars::JsonSchema))] @@ -484,10 +481,54 @@ enum AuthoredNullType { Null, } +/// The authored surface an unknown `nullable` key was found on. +/// +/// Both surfaces retired the key in favour of the `type` union, so a document +/// that still carries it is answered with the union syntax that replaces it +/// rather than with a generic whole-document schema failure. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum RetiredNullableSurface { + StructuredOutput, + ClaimValue, +} + +impl RetiredNullableSurface { + const fn suggestion(self) -> &'static str { + match self { + Self::StructuredOutput => STRUCTURED_OUTPUT_NULLABLE_UNION_SUGGESTION, + Self::ClaimValue => CLAIM_VALUE_NULLABLE_UNION_SUGGESTION, + } + } + + const fn cause(self) -> &'static str { + match self { + Self::StructuredOutput => STRUCTURED_OUTPUT_NULLABLE_UNION_CAUSE, + Self::ClaimValue => CLAIM_VALUE_NULLABLE_UNION_CAUSE, + } + } + + const fn remediation(self) -> &'static str { + match self { + Self::StructuredOutput => STRUCTURED_OUTPUT_NULLABLE_UNION_REMEDIATION, + Self::ClaimValue => CLAIM_VALUE_NULLABLE_UNION_REMEDIATION, + } + } +} + const STRUCTURED_OUTPUT_NULLABLE_UNION_SUGGESTION: &str = "type: [object, \"null\"] for an object output, or type: [array, \"null\"] for an array output"; +const STRUCTURED_OUTPUT_NULLABLE_UNION_CAUSE: &str = + "A structured output declares nullability with the removed `nullable` field."; + const STRUCTURED_OUTPUT_NULLABLE_UNION_REMEDIATION: &str = "Remove the `nullable` field and pair the declared form with null in the `type` union, exactly as scalar outputs already do."; +const CLAIM_VALUE_NULLABLE_UNION_SUGGESTION: &str = "type: [string, \"null\"] for a nullable claim value, or type: string for a non-nullable one"; + +const CLAIM_VALUE_NULLABLE_UNION_CAUSE: &str = + "A claim value declares nullability with the removed `nullable` field."; + +const CLAIM_VALUE_NULLABLE_UNION_REMEDIATION: &str = "Remove the `nullable` field and pair the declared type with null in the `type` union, exactly as scalar outputs already do."; + #[cfg_attr(test, derive(schemars::JsonSchema))] #[derive(Debug, Deserialize, Serialize)] #[serde(deny_unknown_fields)] diff --git a/crates/registryctl/src/project_authoring/diagnostics.rs b/crates/registryctl/src/project_authoring/diagnostics.rs index 257847349..4182ff5e8 100644 --- a/crates/registryctl/src/project_authoring/diagnostics.rs +++ b/crates/registryctl/src/project_authoring/diagnostics.rs @@ -2252,7 +2252,7 @@ fn diagnostic_parse_yaml( return Box::new(path_unsafe(file, None)); } let reserved_fixture_body = error.is_reserved_fixture_body(); - let retired_nullable_key = error.is_retired_nullable_key(); + let retired_nullable_key = error.retired_nullable_key(); let unknown_field = error.keyword() == Some("additionalProperties"); let syntax = error.is_syntax(); let schema_code = match T::KIND { @@ -2271,7 +2271,7 @@ fn diagnostic_parse_yaml( let mut diagnostic = make_diagnostic( if reserved_fixture_body { "registryctl.authoring.fixture.reserved_body_field" - } else if retired_nullable_key || unknown_field { + } else if retired_nullable_key.is_some() || unknown_field { "registryctl.authoring.yaml.unknown_field" } else if syntax { "registryctl.authoring.yaml.invalid_syntax" @@ -2283,11 +2283,11 @@ fn diagnostic_parse_yaml( line, column, Some(schema_hint), - retired_nullable_key.then_some(STRUCTURED_OUTPUT_NULLABLE_UNION_SUGGESTION), + retired_nullable_key.map(RetiredNullableSurface::suggestion), if reserved_fixture_body { "A fixture body object uses the reserved top-level `file` field without matching the closed file-reference shape." - } else if retired_nullable_key { - "A structured output declares nullability with the removed `nullable` field." + } else if let Some(surface) = retired_nullable_key { + surface.cause() } else if unknown_field { "The YAML document contains an unknown field." } else if syntax { @@ -2297,8 +2297,8 @@ fn diagnostic_parse_yaml( }, if reserved_fixture_body { FIXTURE_BODY_FILE_REFERENCE_REMEDIATION - } else if retired_nullable_key { - STRUCTURED_OUTPUT_NULLABLE_UNION_REMEDIATION + } else if let Some(surface) = retired_nullable_key { + surface.remediation() } else { match kind { "project" => "Correct the project YAML using the project authoring schema. If this project passed with a pre-1.0 Registryctl, create a separate 1.0 project with the `spreadsheet` or `http` template that matches the source, then copy only reviewed authored intent. Registryctl does not migrate or approve the source project.", @@ -2831,6 +2831,69 @@ limits: { calls: 1, source_bytes: 512KiB, request_bytes: 32KiB, deadline: 20s } ); } + #[test] + fn retired_claim_value_nullable_key_names_its_path_and_the_union_syntax() { + let document = br#" +version: 1 +registry: + id: fictional-household-authority +integrations: + eligibility: + file: integrations/eligibility/integration.yaml +services: + household-eligibility: + kind: evidence + version: 1 + purpose: household-support-screening + legal_basis: public-service-delivery + consent: not_required + access: + scopes: ["evidence:household:read"] + consultations: + household: + integration: eligibility + input: + household_reference: request.target.identifiers.household_reference + claims: + household-category: + output: household.category + value: + type: string + nullable: true + max_bytes: 64 + disclosure: value +"#; + let diagnostic = diagnostic_parse_yaml::( + document, + PROJECT_FILE, + "project", + PROJECT_SCHEMA_HINT, + ) + .expect_err("the retired claim value nullable key is rejected"); + + assert_eq!(diagnostic.code, "registryctl.authoring.yaml.unknown_field"); + assert_eq!( + diagnostic.cause, + "A claim value declares nullability with the removed `nullable` field." + ); + assert_eq!( + diagnostic.suggestion, + Some("type: [string, \"null\"] for a nullable claim value, or type: string for a non-nullable one") + ); + assert_eq!( + diagnostic.remediation, + "Remove the `nullable` field and pair the declared type with null in the `type` union, exactly as scalar outputs already do." + ); + assert_eq!( + diagnostic + .addresses + .iter() + .map(|address| address.pointer.as_str()) + .collect::>(), + vec!["/services/household-eligibility/claims/household-category/value/nullable"] + ); + } + #[test] fn malformed_recursive_output_reports_its_nested_authored_path() { let document = br#" diff --git a/crates/registryctl/src/project_authoring/documentation.rs b/crates/registryctl/src/project_authoring/documentation.rs index a88a91093..f15ff95ed 100644 --- a/crates/registryctl/src/project_authoring/documentation.rs +++ b/crates/registryctl/src/project_authoring/documentation.rs @@ -2855,7 +2855,7 @@ mod tests { .expect("embedded reference coverage is readable"); assert!(!coverage.source_contract.reads_country_workspaces); assert!(!coverage.source_contract.reads_runtime_configuration); - assert_eq!(coverage.coverage.path_count, 708); + assert_eq!(coverage.coverage.path_count, 711); } #[test] diff --git a/crates/registryctl/src/project_authoring/model.rs b/crates/registryctl/src/project_authoring/model.rs index c541d9dc7..43f0f0a5b 100644 --- a/crates/registryctl/src/project_authoring/model.rs +++ b/crates/registryctl/src/project_authoring/model.rs @@ -1043,13 +1043,24 @@ enum ClaimEvidence { #[serde(deny_unknown_fields)] struct ClaimValueDeclaration { #[serde(rename = "type")] - value_type: OutputType, - #[serde(default)] - nullable: bool, + value_type: AuthoredNullableType, #[serde(default)] max_bytes: Option, } +/// The types a claim value may take. Structured outputs are consulted through +/// Relay but are never disclosed as a claim value, so `object`, `array`, and +/// `presence` are absent by construction. +#[cfg_attr(test, derive(schemars::JsonSchema))] +#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq)] +#[serde(rename_all = "snake_case")] +enum ClaimValueType { + Boolean, + Integer, + String, + Date, +} + #[cfg_attr(test, derive(schemars::JsonSchema))] #[derive(Debug, Deserialize, Serialize)] #[serde(untagged)] diff --git a/crates/registryctl/src/project_authoring/project.rs b/crates/registryctl/src/project_authoring/project.rs index 092e3fda5..6156d3430 100644 --- a/crates/registryctl/src/project_authoring/project.rs +++ b/crates/registryctl/src/project_authoring/project.rs @@ -889,7 +889,7 @@ fn semantic_digests( // A schema or knowledge change must therefore be reviewed for promotion // semantics before a new projection can be emitted. const PROMOTION_FIELD_KNOWLEDGE_REVISION: &str = - "sha256:48143e77caf603c743f0f80e4a2215dff5f4e7e17053a38de401d9f438ccdbd4"; + "sha256:0a7311fdc93c81dae30d0f33cf0c4fa61dda65ddf9e7f26232e03856f75603da"; fn project_promotion_projection( loaded: &LoadedRegistryProject, @@ -1791,7 +1791,7 @@ fn validate_project_shape(project: &RegistryProject) -> Result<()> { } } if let Some(value) = &claim.value { - if value.value_type == OutputType::String { + if value.value_type.form() == ClaimValueType::String { let Some(max_bytes) = value.max_bytes else { bail!("string claim value contracts require max_bytes"); }; @@ -1804,7 +1804,7 @@ fn validate_project_shape(project: &RegistryProject) -> Result<()> { ); } } - if value.value_type != OutputType::String && value.max_bytes.is_some() { + if value.value_type.form() != ClaimValueType::String && value.max_bytes.is_some() { bail!("only string claim value contracts may declare max_bytes"); } } diff --git a/crates/registryctl/src/project_authoring/promotion_projection.rs b/crates/registryctl/src/project_authoring/promotion_projection.rs index 82afe158d..8c0eeb034 100644 --- a/crates/registryctl/src/project_authoring/promotion_projection.rs +++ b/crates/registryctl/src/project_authoring/promotion_projection.rs @@ -321,7 +321,7 @@ mod tests { assert_eq!(revision, PROMOTION_FIELD_KNOWLEDGE_REVISION); let index = knowledge::published_field_knowledge_index().expect("knowledge indexes"); - assert_eq!(index.by_path().len(), 708); + assert_eq!(index.by_path().len(), 711); let mapped = index .by_path() .keys() diff --git a/crates/registryctl/src/project_authoring/schema_authority.rs b/crates/registryctl/src/project_authoring/schema_authority.rs index 5fa7a9bd2..05a85eb22 100644 --- a/crates/registryctl/src/project_authoring/schema_authority.rs +++ b/crates/registryctl/src/project_authoring/schema_authority.rs @@ -22,7 +22,7 @@ enum AuthoringDocumentError { schema_path: String, keyword: &'static str, reserved_fixture_body: bool, - retired_nullable_key: bool, + retired_nullable_key: Option, unsafe_authored_path: bool, line: Option, column: Option, @@ -83,14 +83,14 @@ impl AuthoringDocumentError { ) } - const fn is_retired_nullable_key(&self) -> bool { - matches!( - self, + const fn retired_nullable_key(&self) -> Option { + match self { Self::Schema { - retired_nullable_key: true, + retired_nullable_key, .. - } - ) + } => *retired_nullable_key, + Self::Syntax { .. } | Self::TypedModel { .. } => None, + } } const fn is_unsafe_authored_path(&self) -> bool { @@ -125,13 +125,17 @@ impl fmt::Display for AuthoringDocumentError { write_safe_location(formatter, self) } Self::Schema { - retired_nullable_key: true, + retired_nullable_key: Some(surface), .. } => { write!( formatter, - "structured output nullability must use the type union instead of the \ - removed `nullable` field" + "{} nullability must use the type union instead of the removed `nullable` \ + field", + match surface { + RetiredNullableSurface::StructuredOutput => "structured output", + RetiredNullableSurface::ClaimValue => "claim value", + } )?; write_safe_location(formatter, self) } @@ -373,7 +377,7 @@ fn schema_validation_error( document: &Value, error: jsonschema::ValidationError<'_>, instance_path: String, - retired_nullable_key: bool, + retired_nullable_key: Option, ) -> AuthoringDocumentError { let schema_path = error.schema_path.to_string(); let unsafe_authored_path = is_unsafe_authored_path_constraint(kind, &schema_path); @@ -453,24 +457,69 @@ fn project_request_mapping_validation_instance_path( None } -fn project_service_validation_instance_path(document: &Value) -> Option { +/// Returns the claim value that still carries the removed `nullable` key. +/// +/// The published `claimValue` object is closed, so the key is always a +/// validation failure. Reporting it here keeps the answer specific instead of +/// letting the collapsed `services` union address the whole service. +fn project_claim_value_validation_location( + services: &serde_json::Map, + definitions: &Value, +) -> Option { + let validator = definition_branch_validator(definitions, "claimValue")?; + for (service_id, service) in services { + let Some(claims) = service.get("claims").and_then(Value::as_object) else { + continue; + }; + for (claim_id, claim) in claims { + let Some(value) = claim.get("value") else { + continue; + }; + if validator.is_valid(value) || value.get("nullable").is_none() { + continue; + } + return Some(AuthoredValidationLocation { + instance_path: format!( + "/services/{}/claims/{}/value/nullable", + escape_json_pointer_segment(service_id), + escape_json_pointer_segment(claim_id), + ), + retired_nullable_key: Some(RetiredNullableSurface::ClaimValue), + }); + } + } + None +} + +fn project_service_validation_instance_path( + document: &Value, +) -> Option { let services = document.get("services")?.as_object()?; let root_schema: Value = serde_json::from_str(ProjectSchemaKind::Project.document()).ok()?; let definitions = root_schema.get("$defs")?.clone(); if let Some(pointer) = project_request_mapping_validation_instance_path(services, &definitions) { - return Some(pointer); + return Some(AuthoredValidationLocation { + instance_path: pointer, + retired_nullable_key: None, + }); + } + if let Some(location) = project_claim_value_validation_location(services, &definitions) { + return Some(location); } for (service_id, service) in services { let branch = match service.get("kind").and_then(Value::as_str) { Some("evidence") => "evidenceService", Some("records_api") => "recordsService", Some(_) => { - return Some(format!( - "/services/{}/kind", - escape_json_pointer_segment(service_id) - )); + return Some(AuthoredValidationLocation { + instance_path: format!( + "/services/{}/kind", + escape_json_pointer_segment(service_id) + ), + retired_nullable_key: None, + }); } None => continue, }; @@ -497,20 +546,24 @@ fn project_service_validation_instance_path(document: &Value) -> Option .map(|error| error.instance_path.to_string()) }) .unwrap_or_default(); - return Some(format!( - "/services/{}{}", - escape_json_pointer_segment(service_id), - nested - )); + return Some(AuthoredValidationLocation { + instance_path: format!( + "/services/{}{}", + escape_json_pointer_segment(service_id), + nested + ), + retired_nullable_key: None, + }); } None } -/// Where a structured integration output failed, recovered from the collapsed -/// `#/$defs/output` union. -struct OutputValidationLocation { +/// Where an authored document failed inside a collapsed union, recovered from +/// the branch the author's own discriminator selects, and whether that failure +/// is the removed `nullable` key. +struct AuthoredValidationLocation { instance_path: String, - retired_nullable_key: bool, + retired_nullable_key: Option, } /// Compiles one `$defs` branch of a published schema as a standalone validator. @@ -555,7 +608,7 @@ fn output_declaration_location( declaration: &Value, definitions: &Value, scalar_branch: &str, -) -> Option { +) -> Option { let branch = output_declaration_branch(declaration, scalar_branch); let validator = definition_branch_validator(definitions, branch)?; if validator.is_valid(declaration) { @@ -565,15 +618,15 @@ fn output_declaration_location( return Some(nested); } if branch != scalar_branch && declaration.get("nullable").is_some() { - return Some(OutputValidationLocation { + return Some(AuthoredValidationLocation { instance_path: "/nullable".to_string(), - retired_nullable_key: true, + retired_nullable_key: Some(RetiredNullableSurface::StructuredOutput), }); } - Some(OutputValidationLocation { + Some(AuthoredValidationLocation { instance_path: most_specific_validation_instance_path(&validator, declaration) .unwrap_or_default(), - retired_nullable_key: false, + retired_nullable_key: None, }) } @@ -581,7 +634,7 @@ fn output_declaration_location( fn nested_output_declaration_location( declaration: &Value, definitions: &Value, -) -> Option { +) -> Option { if let Some(fields) = declaration.get("fields").and_then(Value::as_object) { for (field_name, field) in fields { let Some(schema) = field.get("schema") else { @@ -590,7 +643,7 @@ fn nested_output_declaration_location( if let Some(nested) = output_declaration_location(schema, definitions, "scalarOutputSchema") { - return Some(OutputValidationLocation { + return Some(AuthoredValidationLocation { instance_path: format!( "/fields/{}/schema{}", escape_json_pointer_segment(field_name), @@ -603,7 +656,7 @@ fn nested_output_declaration_location( } let items = declaration.get("items")?; let nested = output_declaration_location(items, definitions, "scalarOutputSchema")?; - Some(OutputValidationLocation { + Some(AuthoredValidationLocation { instance_path: format!("/items{}", nested.instance_path), retired_nullable_key: nested.retired_nullable_key, }) @@ -618,7 +671,7 @@ fn nested_output_declaration_location( /// `/outputs/parents/items/fields/identifier/schema`. fn integration_output_validation_instance_path( document: &Value, -) -> Option { +) -> Option { let outputs = document.get("outputs")?.as_object()?; let root_schema: Value = serde_json::from_str(ProjectSchemaKind::Integration.document()).ok()?; @@ -628,7 +681,7 @@ fn integration_output_validation_instance_path( else { continue; }; - return Some(OutputValidationLocation { + return Some(AuthoredValidationLocation { instance_path: format!( "/outputs/{}{}", escape_json_pointer_segment(name), @@ -661,7 +714,7 @@ fn parse_authoring_value( schema_path: String::new(), keyword: "schema", reserved_fixture_body: false, - retired_nullable_key: false, + retired_nullable_key: None, unsafe_authored_path: false, line: None, column: None, @@ -673,20 +726,19 @@ fn parse_authoring_value( let collapsed_output_union = kind == ProjectSchemaKind::Integration && collapsed_union && (reported_path == "/outputs" || reported_path.starts_with("/outputs/")); - let output_location = - collapsed_output_union.then(|| integration_output_validation_instance_path(&value)); - let retired_nullable_key = output_location - .as_ref() - .and_then(Option::as_ref) - .is_some_and(|location| location.retired_nullable_key); - let instance_path = if kind == ProjectSchemaKind::Project && collapsed_union { + let location = if kind == ProjectSchemaKind::Project && collapsed_union { project_service_validation_instance_path(&value) + } else if collapsed_output_union { + integration_output_validation_instance_path(&value) } else { - output_location - .flatten() - .map(|location| location.instance_path) - } - .unwrap_or(reported_path); + None + }; + let retired_nullable_key = location + .as_ref() + .and_then(|location| location.retired_nullable_key); + let instance_path = location + .map(|location| location.instance_path) + .unwrap_or(reported_path); return Err(schema_validation_error( kind, &value, @@ -754,7 +806,7 @@ fn assert_current_authoring_value_reaches_typed_model( schema_path: String::new(), keyword: "schema", reserved_fixture_body: false, - retired_nullable_key: false, + retired_nullable_key: None, unsafe_authored_path: false, line: None, column: None, @@ -763,7 +815,7 @@ fn assert_current_authoring_value_reaches_typed_model( .map_err(|mut errors| { let error = errors.next().expect("schema validation returned an error"); let instance_path = error.instance_path.to_string(); - schema_validation_error(kind, &value, error, instance_path, false) + schema_validation_error(kind, &value, error, instance_path, None) })?; match kind { ProjectSchemaKind::Project => { diff --git a/crates/registryctl/src/project_authoring/tests.rs b/crates/registryctl/src/project_authoring/tests.rs index feeb5fb86..99bff604b 100644 --- a/crates/registryctl/src/project_authoring/tests.rs +++ b/crates/registryctl/src/project_authoring/tests.rs @@ -597,6 +597,62 @@ fields: } } + #[test] + fn claim_value_nullability_uses_the_one_scalar_type_union_idiom() { + fn parse(source: &str) -> ClaimValueDeclaration { + serde_norway::from_str(source).expect("claim value parses") + } + + let nullable = parse(r#"{ type: [string, "null"], max_bytes: 64 }"#); + assert_eq!(nullable.value_type.form(), ClaimValueType::String); + assert!(nullable.value_type.nullable()); + assert_eq!( + serde_json::to_value(&nullable).expect("claim value serializes"), + json!({ "type": ["string", "null"], "max_bytes": 64 }) + ); + + let required = parse("{ type: string, max_bytes: 64 }"); + assert_eq!(required.value_type.form(), ClaimValueType::String); + assert!(!required.value_type.nullable()); + assert_eq!( + serde_json::to_value(&required).expect("claim value serializes"), + json!({ "type": "string", "max_bytes": 64 }) + ); + + let date = parse("{ type: date }"); + assert_eq!(date.value_type.form(), ClaimValueType::Date); + assert!(!date.value_type.nullable()); + + let nullable_date = parse(r#"{ type: [date, "null"] }"#); + assert_eq!(nullable_date.value_type.form(), ClaimValueType::Date); + assert!(nullable_date.value_type.nullable()); + + for retired in [ + "{ type: string, nullable: true, max_bytes: 64 }", + "{ type: string, nullable: false, max_bytes: 64 }", + ] { + assert!( + serde_norway::from_str::(retired).is_err(), + "the retired claim value `nullable` key must not parse: {retired}" + ); + } + + for rejected in [ + r#"{ type: ["null"] }"#, + "{ type: [string, string] }", + r#"{ type: ["null", string] }"#, + r#"{ type: [object, "null"] }"#, + "{ type: object }", + "{ type: array }", + "{ type: presence }", + ] { + assert!( + serde_norway::from_str::(rejected).is_err(), + "only a claim value type or `[, \"null\"]` is authored: {rejected}" + ); + } + } + #[test] fn authored_output_count_preserves_the_generic_non_notary_limit() { fn boolean_output() -> AuthoredOutputDeclaration { diff --git a/crates/registryctl/tests/project_authoring.rs b/crates/registryctl/tests/project_authoring.rs index 448f193ce..701bdf6c8 100644 --- a/crates/registryctl/tests/project_authoring.rs +++ b/crates/registryctl/tests/project_authoring.rs @@ -6181,7 +6181,7 @@ fn check_and_build_produce_deterministic_product_inputs() { assert_eq!(first_closure, directory_closure(&output)); assert_eq!( closure_digest(&first_closure), - "c77952eb0c76fbda06254690ee4ebcc7597b8f881a8d5c62a32cbac7dc938b6f", + "7e403329f1f8f4dcf95be932f82041d10146aaf957b99f92c89288eeec1c1e23", "project output, including its deterministic manifest, must match the cross-machine golden digest" ); } diff --git a/crates/registryctl/tests/project_authoring_schema_parity.rs b/crates/registryctl/tests/project_authoring_schema_parity.rs index 1bd0ee891..3b843436e 100644 --- a/crates/registryctl/tests/project_authoring_schema_parity.rs +++ b/crates/registryctl/tests/project_authoring_schema_parity.rs @@ -255,7 +255,7 @@ fn published_field_knowledge_is_complete_typed_reachable_and_editor_exact() { assert_eq!( index.coverage_by_schema(), [ - (SchemaKind::Project, 220), + (SchemaKind::Project, 223), (SchemaKind::Environment, 213), (SchemaKind::Integration, 177), (SchemaKind::Fixture, 63), @@ -269,11 +269,11 @@ fn published_field_knowledge_is_complete_typed_reachable_and_editor_exact() { index.coverage_by_path_kind(), [ (FieldPathKind::Root, 5), - (FieldPathKind::Property, 490), + (FieldPathKind::Property, 489), (FieldPathKind::MapKey, 26), (FieldPathKind::MapValue, 33), - (FieldPathKind::ArrayItem, 38), - (FieldPathKind::Branch, 116), + (FieldPathKind::ArrayItem, 40), + (FieldPathKind::Branch, 118), ] .into_iter() .collect(), @@ -283,11 +283,11 @@ fn published_field_knowledge_is_complete_typed_reachable_and_editor_exact() { index.coverage_by_sensitivity(), [ (Sensitivity::Public, 6), - (Sensitivity::Internal, 447), + (Sensitivity::Internal, 448), (Sensitivity::Sensitive, 69), (Sensitivity::SecretReference, 14), (Sensitivity::RedactedFixture, 51), - (Sensitivity::Structural, 121), + (Sensitivity::Structural, 123), ] .into_iter() .collect(), @@ -295,12 +295,12 @@ fn published_field_knowledge_is_complete_typed_reachable_and_editor_exact() { ); assert_eq!( index.by_path().len(), - 708, + 711, "the field-knowledge gate covers every published schema path" ); assert_eq!( index.references().len(), - 281, + 282, "every published local reference remains resolved in the deterministic reference index" ); assert_eq!( @@ -767,28 +767,28 @@ fn exact_published_structural_contract_inventory_is_release_gated() { ( "project", PublishedStructuralInventory { - nodes: 253, - local_refs: 123, - union_nodes: 9, - union_branches: 19, + nodes: 257, + local_refs: 124, + union_nodes: 10, + union_branches: 21, conditionals: 0, objects: 51, closed_objects: 36, typed_maps: 15, open_maps: 0, - arrays: 11, - scalar_types: 30, + arrays: 12, + scalar_types: 29, nullable_nodes: 0, integer_lower_bounds: 9, integer_upper_bounds: 9, string_length_bounds: 10, string_patterns: 12, - array_size_bounds: 9, - unique_arrays: 8, + array_size_bounds: 10, + unique_arrays: 9, object_size_bounds: 17, property_name_constraints: 14, - enums: 13, - consts: 8, + enums: 14, + consts: 9, defaults: 0, deprecations: 0, }, diff --git a/crates/registryctl/tests/project_documentation_reference.rs b/crates/registryctl/tests/project_documentation_reference.rs index 2b0b6c792..8317e3b43 100644 --- a/crates/registryctl/tests/project_documentation_reference.rs +++ b/crates/registryctl/tests/project_documentation_reference.rs @@ -312,7 +312,7 @@ fn human_intent_sidecar_and_documentation_contracts_are_strict_schemas() { let intent_schema = compile_schema(&intent_schema_document); let intent = read_json(schema_root.join("project-authoring/documentation-intent.json")); assert_valid(&intent_schema, &intent, "documentation intent sidecar"); - assert_eq!(intent["structural_reviews"].as_array().unwrap().len(), 213); + assert_eq!(intent["structural_reviews"].as_array().unwrap().len(), 217); for file in [ "registry.project.configuration_reference.v1.schema.json", @@ -437,11 +437,11 @@ fn embedded_coverage_is_complete_and_generates_the_canonical_reference() { CONFIGURATION_REFERENCE_COVERAGE_SCHEMA_ID ); assert_eq!(coverage.coverage.schema_count, 7); - assert_eq!(coverage.coverage.path_count, 1835); + assert_eq!(coverage.coverage.path_count, 1838); assert_eq!( coverage.coverage.by_schema, [ - (ConfigurationSchemaKind::Project, 220), + (ConfigurationSchemaKind::Project, 223), (ConfigurationSchemaKind::Environment, 213), (ConfigurationSchemaKind::Integration, 177), (ConfigurationSchemaKind::Fixture, 63), @@ -456,22 +456,22 @@ fn embedded_coverage_is_complete_and_generates_the_canonical_reference() { coverage.coverage.by_path_kind, [ (FieldPathKind::Root, 7), - (FieldPathKind::Property, 1_456), + (FieldPathKind::Property, 1_455), (FieldPathKind::MapKey, 26), (FieldPathKind::MapValue, 48), - (FieldPathKind::ArrayItem, 182), - (FieldPathKind::Branch, 116), + (FieldPathKind::ArrayItem, 184), + (FieldPathKind::Branch, 118), ] .into_iter() .collect(), "the exact reviewed structural taxonomy remains release-gated" ); - assert_eq!(coverage.reviewed_intent_assignment_required_count, 1835); + assert_eq!(coverage.reviewed_intent_assignment_required_count, 1838); assert_eq!( coverage.reviewed_intent_assignment_covered_count + coverage.missing_intent.len(), coverage.reviewed_intent_assignment_required_count ); - assert_eq!(coverage.reviewed_intent_assignment_covered_count, 1835); + assert_eq!(coverage.reviewed_intent_assignment_covered_count, 1838); assert!( coverage.distinct_reviewed_intent_count < coverage.reviewed_intent_assignment_covered_count, "assignment coverage must not imply one unique explanation per path" @@ -488,7 +488,7 @@ fn embedded_coverage_is_complete_and_generates_the_canonical_reference() { coverage.distinct_reviewed_intents_reused_count, coverage.reviewed_intent_assignments_using_reused_intent_count, ), - (627, 86, 1_294), + (626, 86, 1_298), "the exact intent-text reuse baseline must change intentionally with reviewed documentation" ); assert_eq!( @@ -636,7 +636,7 @@ fn embedded_coverage_is_complete_and_generates_the_canonical_reference() { }) .count(), ), - (528, 315, 0, 992), + (528, 315, 0, 995), "the exact empty-string semantic coverage prevents constrained strings from regressing to allowed" ); assert_eq!( diff --git a/docs/site/public/generated/configuration-reference-coverage.v1.json b/docs/site/public/generated/configuration-reference-coverage.v1.json index d9ac9b7fd..e5649fce3 100644 --- a/docs/site/public/generated/configuration-reference-coverage.v1.json +++ b/docs/site/public/generated/configuration-reference-coverage.v1.json @@ -39,10 +39,10 @@ }, "coverage": { "schema_count": 7, - "path_count": 1835, - "reference_count": 508, + "path_count": 1838, + "reference_count": 509, "by_schema": { - "project": 220, + "project": 223, "environment": 213, "integration": 177, "fixture": 63, @@ -52,24 +52,24 @@ }, "by_path_kind": { "root": 7, - "property": 1456, + "property": 1455, "map_key": 26, "map_value": 48, - "array_item": 182, - "branch": 116 + "array_item": 184, + "branch": 118 }, "by_sensitivity": { "public": 16, - "internal": 1181, + "internal": 1182, "sensitive": 408, "secret_reference": 44, "redacted_fixture": 51, - "structural": 135 + "structural": 137 }, "by_intent_source": { "schema_description": 530, - "reviewed_override": 264, - "structural_taxonomy": 139, + "reviewed_override": 263, + "structural_taxonomy": 143, "reviewed_profile": 902 }, "by_intent_profile": { @@ -148,10 +148,10 @@ "relay_vocabularies_open_map": 1 } }, - "reviewed_intent_assignment_required_count": 1835, - "reviewed_intent_assignment_covered_count": 1835, - "distinct_reviewed_intent_count": 627, + "reviewed_intent_assignment_required_count": 1838, + "reviewed_intent_assignment_covered_count": 1838, + "distinct_reviewed_intent_count": 626, "distinct_reviewed_intents_reused_count": 86, - "reviewed_intent_assignments_using_reused_intent_count": 1294, + "reviewed_intent_assignments_using_reused_intent_count": 1298, "missing_intent": [] } diff --git a/docs/site/public/generated/configuration-reference.v1.json b/docs/site/public/generated/configuration-reference.v1.json index 93ee13ccd..7c9c05566 100644 --- a/docs/site/public/generated/configuration-reference.v1.json +++ b/docs/site/public/generated/configuration-reference.v1.json @@ -38,10 +38,10 @@ }, "coverage": { "schema_count": 7, - "path_count": 1835, - "reference_count": 508, + "path_count": 1838, + "reference_count": 509, "by_schema": { - "project": 220, + "project": 223, "environment": 213, "integration": 177, "fixture": 63, @@ -51,24 +51,24 @@ }, "by_path_kind": { "root": 7, - "property": 1456, + "property": 1455, "map_key": 26, "map_value": 48, - "array_item": 182, - "branch": 116 + "array_item": 184, + "branch": 118 }, "by_sensitivity": { "public": 16, - "internal": 1181, + "internal": 1182, "sensitive": 408, "secret_reference": 44, "redacted_fixture": 51, - "structural": 135 + "structural": 137 }, "by_intent_source": { "schema_description": 530, - "reviewed_override": 264, - "structural_taxonomy": 139, + "reviewed_override": 263, + "structural_taxonomy": 143, "reviewed_profile": 902 }, "by_intent_profile": { @@ -541,21 +541,22 @@ { "address": { "schema": "project", - "pointer": "/$defs/claimValue/properties/nullable", + "pointer": "/$defs/claimValue/properties/type", "path_kind": "property" }, - "purpose": "States whether the claim value may be null.", + "purpose": "Declares the boolean, integer, string, or date type of a claim value, paired with null when the claim value may be null.", "purpose_source": "reviewed_override", "semantic_owner": "authoring_contract", "human_owner": "registry_maintainers", "scope": "The product-neutral project graph and the Relay or Notary services that consume its authored contracts.", "field_type": { "schema_types": [ - "boolean" + "array" ], + "local_reference": "#/$defs/claimValueType", "composed": false }, - "requiredness": "optional", + "requiredness": "required", "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { @@ -617,21 +618,209 @@ "knowledge_only", "generated_docs_never_load_country_values" ], + "constraints": [], + "local_reference": { + "schema": "project", + "pointer": "/$defs/claimValueType" + } + }, + { + "address": { + "schema": "project", + "pointer": "/$defs/claimValueType/oneOf/0", + "path_kind": "branch" + }, + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", + "semantic_owner": "authoring_contract", + "human_owner": "registry_maintainers", + "scope": "The product-neutral project graph and the Relay or Notary services that consume its authored contracts.", + "field_type": { + "schema_types": [], + "composed": false + }, + "requiredness": "conditional", + "null_behavior": "not_applicable", + "empty_behavior": "not_applicable", + "default": { + "behavior": "not_applicable" + }, + "environment_behavior": "narrows_reviewed_authority", + "sensitivity": "structural", + "state": "authored", + "products": [ + "registryctl", + "relay", + "notary", + "editor", + "docs" + ], + "availability": "published", + "stability": "experimental", + "validation_stages": [ + "json_schema", + "rust_deserialization", + "cross_file_semantic", + "product_build" + ], + "diagnostic": "registryctl.authoring.project.invalid", + "history_status": "not_verified", + "introduced_in": null, + "version_history": [], + "example": { + "guidance": "Use synthetic identifiers and values from a maintained golden workspace; never copy a private country contract into reference data.", + "schema_examples_available": false, + "contains_country_values": false + }, + "migration": "rebuild_project", + "migration_note": "Revalidate and rebuild the project after changing this field; coordinate a deployment when generated product inputs change.", + "consumers": [ + "registryctl_authoring", + "registry_relay", + "registry_notary", + "editor_tooling", + "docs_generator" + ], + "generated_artifacts": [ + "editor_schemas", + "project_build", + "relay_config", + "notary_config", + "field_reference" + ], + "review_classes": [ + "contract", + "security", + "privacy", + "relay", + "notary", + "compatibility", + "documentation" + ], + "semantic_rules": [ + "knowledge_only", + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" + ], "constraints": [ + { + "keyword": "enum", + "value": [ + "boolean", + "integer", + "string", + "date" + ] + } + ] + }, + { + "address": { + "schema": "project", + "pointer": "/$defs/claimValueType/oneOf/1", + "path_kind": "branch" + }, + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", + "semantic_owner": "authoring_contract", + "human_owner": "registry_maintainers", + "scope": "The product-neutral project graph and the Relay or Notary services that consume its authored contracts.", + "field_type": { + "schema_types": [ + "array" + ], + "composed": false + }, + "requiredness": "conditional", + "null_behavior": "not_applicable", + "empty_behavior": "not_applicable", + "default": { + "behavior": "not_applicable" + }, + "environment_behavior": "narrows_reviewed_authority", + "sensitivity": "structural", + "state": "authored", + "products": [ + "registryctl", + "relay", + "notary", + "editor", + "docs" + ], + "availability": "published", + "stability": "experimental", + "validation_stages": [ + "json_schema", + "rust_deserialization", + "cross_file_semantic", + "product_build" + ], + "diagnostic": "registryctl.authoring.project.invalid", + "history_status": "not_verified", + "introduced_in": null, + "version_history": [], + "example": { + "guidance": "Use synthetic identifiers and values from a maintained golden workspace; never copy a private country contract into reference data.", + "schema_examples_available": false, + "contains_country_values": false + }, + "migration": "rebuild_project", + "migration_note": "Revalidate and rebuild the project after changing this field; coordinate a deployment when generated product inputs change.", + "consumers": [ + "registryctl_authoring", + "registry_relay", + "registry_notary", + "editor_tooling", + "docs_generator" + ], + "generated_artifacts": [ + "editor_schemas", + "project_build", + "relay_config", + "notary_config", + "field_reference" + ], + "review_classes": [ + "contract", + "security", + "privacy", + "relay", + "notary", + "compatibility", + "documentation" + ], + "semantic_rules": [ + "knowledge_only", + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" + ], + "constraints": [ + { + "keyword": "maxItems", + "value": 2 + }, + { + "keyword": "minItems", + "value": 2 + }, { "keyword": "type", - "value": "boolean" + "value": "array" + }, + { + "keyword": "uniqueItems", + "value": true } ] }, { "address": { "schema": "project", - "pointer": "/$defs/claimValue/properties/type", - "path_kind": "property" + "pointer": "/$defs/claimValueType/oneOf/1/prefixItems/0", + "path_kind": "array_item" }, - "purpose": "Declares the boolean, integer, string, or date type of a claim value.", - "purpose_source": "reviewed_override", + "purpose": "Defines the contract shared by each ordered item in the enclosing authored list.", + "purpose_source": "structural_taxonomy", "semantic_owner": "authoring_contract", "human_owner": "registry_maintainers", "scope": "The product-neutral project graph and the Relay or Notary services that consume its authored contracts.", @@ -639,7 +828,7 @@ "schema_types": [], "composed": false }, - "requiredness": "required", + "requiredness": "not_applicable", "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { @@ -699,7 +888,8 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "array_items_share_element_contract" ], "constraints": [ { @@ -713,6 +903,91 @@ } ] }, + { + "address": { + "schema": "project", + "pointer": "/$defs/claimValueType/oneOf/1/prefixItems/1", + "path_kind": "array_item" + }, + "purpose": "Defines the contract shared by each ordered item in the enclosing authored list.", + "purpose_source": "structural_taxonomy", + "semantic_owner": "authoring_contract", + "human_owner": "registry_maintainers", + "scope": "The product-neutral project graph and the Relay or Notary services that consume its authored contracts.", + "field_type": { + "schema_types": [], + "composed": false + }, + "requiredness": "not_applicable", + "null_behavior": "rejected", + "empty_behavior": "not_applicable", + "default": { + "behavior": "no_schema_default" + }, + "environment_behavior": "narrows_reviewed_authority", + "sensitivity": "internal", + "state": "authored", + "products": [ + "registryctl", + "relay", + "notary", + "editor", + "docs" + ], + "availability": "published", + "stability": "experimental", + "validation_stages": [ + "json_schema", + "rust_deserialization", + "cross_file_semantic", + "product_build" + ], + "diagnostic": "registryctl.authoring.project.invalid", + "history_status": "not_verified", + "introduced_in": null, + "version_history": [], + "example": { + "guidance": "Use synthetic identifiers and values from a maintained golden workspace; never copy a private country contract into reference data.", + "schema_examples_available": false, + "contains_country_values": false + }, + "migration": "rebuild_project", + "migration_note": "Revalidate and rebuild the project after changing this field; coordinate a deployment when generated product inputs change.", + "consumers": [ + "registryctl_authoring", + "registry_relay", + "registry_notary", + "editor_tooling", + "docs_generator" + ], + "generated_artifacts": [ + "editor_schemas", + "project_build", + "relay_config", + "notary_config", + "field_reference" + ], + "review_classes": [ + "contract", + "security", + "privacy", + "relay", + "notary", + "compatibility", + "documentation" + ], + "semantic_rules": [ + "knowledge_only", + "generated_docs_never_load_country_values", + "array_items_share_element_contract" + ], + "constraints": [ + { + "keyword": "const", + "value": "null" + } + ] + }, { "address": { "schema": "project", diff --git a/docs/site/scripts/authoring-reference-docs.test.mjs b/docs/site/scripts/authoring-reference-docs.test.mjs index 1c0926bc5..7fa73e6a2 100644 --- a/docs/site/scripts/authoring-reference-docs.test.mjs +++ b/docs/site/scripts/authoring-reference-docs.test.mjs @@ -26,12 +26,12 @@ test('committed internal and public reference artifacts are exact and complete', validateAuthoringReference(reference, coverage); assert.deepEqual(publicReference, reference); assert.deepEqual(publicCoverage, coverage); - assert.equal(reference.fields.length, 1829); - assert.equal(coverage.reviewed_intent_assignment_required_count, 1829); - assert.equal(coverage.reviewed_intent_assignment_covered_count, 1829); - assert.equal(coverage.distinct_reviewed_intent_count, 629); + assert.equal(reference.fields.length, 1838); + assert.equal(coverage.reviewed_intent_assignment_required_count, 1838); + assert.equal(coverage.reviewed_intent_assignment_covered_count, 1838); + assert.equal(coverage.distinct_reviewed_intent_count, 626); assert.equal(coverage.distinct_reviewed_intents_reused_count, 86); - assert.equal(coverage.reviewed_intent_assignments_using_reused_intent_count, 1286); + assert.equal(coverage.reviewed_intent_assignments_using_reused_intent_count, 1298); assert.deepEqual(reference.reference_baseline, { generator_lifecycle: 'unreleased', published_release: null, @@ -50,9 +50,9 @@ test('committed internal and public reference artifacts are exact and complete', 'unverified release history must remain explicit and cannot contain a fabricated version', ); assert.deepEqual(reference.coverage.by_schema, { - project: 220, + project: 223, environment: 213, - integration: 171, + integration: 177, fixture: 63, entity: 35, relay: 593, @@ -60,11 +60,11 @@ test('committed internal and public reference artifacts are exact and complete', }); assert.deepEqual(reference.coverage.by_path_kind, { root: 7, - property: 1458, + property: 1455, map_key: 26, map_value: 48, - array_item: 178, - branch: 112, + array_item: 184, + branch: 118, }); assert.equal( Object.values(reference.coverage.by_intent_profile).reduce( @@ -77,7 +77,7 @@ test('committed internal and public reference artifacts are exact and complete', assert.equal(reference.fields.filter((field) => field.empty_behavior === 'rejected').length, 315); assert.equal( reference.fields.filter((field) => field.empty_behavior === 'not_applicable').length, - 986, + 995, ); }); diff --git a/docs/site/src/data/generated/configuration-reference-coverage.json b/docs/site/src/data/generated/configuration-reference-coverage.json index d9ac9b7fd..e5649fce3 100644 --- a/docs/site/src/data/generated/configuration-reference-coverage.json +++ b/docs/site/src/data/generated/configuration-reference-coverage.json @@ -39,10 +39,10 @@ }, "coverage": { "schema_count": 7, - "path_count": 1835, - "reference_count": 508, + "path_count": 1838, + "reference_count": 509, "by_schema": { - "project": 220, + "project": 223, "environment": 213, "integration": 177, "fixture": 63, @@ -52,24 +52,24 @@ }, "by_path_kind": { "root": 7, - "property": 1456, + "property": 1455, "map_key": 26, "map_value": 48, - "array_item": 182, - "branch": 116 + "array_item": 184, + "branch": 118 }, "by_sensitivity": { "public": 16, - "internal": 1181, + "internal": 1182, "sensitive": 408, "secret_reference": 44, "redacted_fixture": 51, - "structural": 135 + "structural": 137 }, "by_intent_source": { "schema_description": 530, - "reviewed_override": 264, - "structural_taxonomy": 139, + "reviewed_override": 263, + "structural_taxonomy": 143, "reviewed_profile": 902 }, "by_intent_profile": { @@ -148,10 +148,10 @@ "relay_vocabularies_open_map": 1 } }, - "reviewed_intent_assignment_required_count": 1835, - "reviewed_intent_assignment_covered_count": 1835, - "distinct_reviewed_intent_count": 627, + "reviewed_intent_assignment_required_count": 1838, + "reviewed_intent_assignment_covered_count": 1838, + "distinct_reviewed_intent_count": 626, "distinct_reviewed_intents_reused_count": 86, - "reviewed_intent_assignments_using_reused_intent_count": 1294, + "reviewed_intent_assignments_using_reused_intent_count": 1298, "missing_intent": [] } diff --git a/docs/site/src/data/generated/configuration-reference.json b/docs/site/src/data/generated/configuration-reference.json index 93ee13ccd..7c9c05566 100644 --- a/docs/site/src/data/generated/configuration-reference.json +++ b/docs/site/src/data/generated/configuration-reference.json @@ -38,10 +38,10 @@ }, "coverage": { "schema_count": 7, - "path_count": 1835, - "reference_count": 508, + "path_count": 1838, + "reference_count": 509, "by_schema": { - "project": 220, + "project": 223, "environment": 213, "integration": 177, "fixture": 63, @@ -51,24 +51,24 @@ }, "by_path_kind": { "root": 7, - "property": 1456, + "property": 1455, "map_key": 26, "map_value": 48, - "array_item": 182, - "branch": 116 + "array_item": 184, + "branch": 118 }, "by_sensitivity": { "public": 16, - "internal": 1181, + "internal": 1182, "sensitive": 408, "secret_reference": 44, "redacted_fixture": 51, - "structural": 135 + "structural": 137 }, "by_intent_source": { "schema_description": 530, - "reviewed_override": 264, - "structural_taxonomy": 139, + "reviewed_override": 263, + "structural_taxonomy": 143, "reviewed_profile": 902 }, "by_intent_profile": { @@ -541,21 +541,22 @@ { "address": { "schema": "project", - "pointer": "/$defs/claimValue/properties/nullable", + "pointer": "/$defs/claimValue/properties/type", "path_kind": "property" }, - "purpose": "States whether the claim value may be null.", + "purpose": "Declares the boolean, integer, string, or date type of a claim value, paired with null when the claim value may be null.", "purpose_source": "reviewed_override", "semantic_owner": "authoring_contract", "human_owner": "registry_maintainers", "scope": "The product-neutral project graph and the Relay or Notary services that consume its authored contracts.", "field_type": { "schema_types": [ - "boolean" + "array" ], + "local_reference": "#/$defs/claimValueType", "composed": false }, - "requiredness": "optional", + "requiredness": "required", "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { @@ -617,21 +618,209 @@ "knowledge_only", "generated_docs_never_load_country_values" ], + "constraints": [], + "local_reference": { + "schema": "project", + "pointer": "/$defs/claimValueType" + } + }, + { + "address": { + "schema": "project", + "pointer": "/$defs/claimValueType/oneOf/0", + "path_kind": "branch" + }, + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", + "semantic_owner": "authoring_contract", + "human_owner": "registry_maintainers", + "scope": "The product-neutral project graph and the Relay or Notary services that consume its authored contracts.", + "field_type": { + "schema_types": [], + "composed": false + }, + "requiredness": "conditional", + "null_behavior": "not_applicable", + "empty_behavior": "not_applicable", + "default": { + "behavior": "not_applicable" + }, + "environment_behavior": "narrows_reviewed_authority", + "sensitivity": "structural", + "state": "authored", + "products": [ + "registryctl", + "relay", + "notary", + "editor", + "docs" + ], + "availability": "published", + "stability": "experimental", + "validation_stages": [ + "json_schema", + "rust_deserialization", + "cross_file_semantic", + "product_build" + ], + "diagnostic": "registryctl.authoring.project.invalid", + "history_status": "not_verified", + "introduced_in": null, + "version_history": [], + "example": { + "guidance": "Use synthetic identifiers and values from a maintained golden workspace; never copy a private country contract into reference data.", + "schema_examples_available": false, + "contains_country_values": false + }, + "migration": "rebuild_project", + "migration_note": "Revalidate and rebuild the project after changing this field; coordinate a deployment when generated product inputs change.", + "consumers": [ + "registryctl_authoring", + "registry_relay", + "registry_notary", + "editor_tooling", + "docs_generator" + ], + "generated_artifacts": [ + "editor_schemas", + "project_build", + "relay_config", + "notary_config", + "field_reference" + ], + "review_classes": [ + "contract", + "security", + "privacy", + "relay", + "notary", + "compatibility", + "documentation" + ], + "semantic_rules": [ + "knowledge_only", + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" + ], "constraints": [ + { + "keyword": "enum", + "value": [ + "boolean", + "integer", + "string", + "date" + ] + } + ] + }, + { + "address": { + "schema": "project", + "pointer": "/$defs/claimValueType/oneOf/1", + "path_kind": "branch" + }, + "purpose": "Documents a validation alternative or condition and is not authored as a standalone configuration field.", + "purpose_source": "structural_taxonomy", + "semantic_owner": "authoring_contract", + "human_owner": "registry_maintainers", + "scope": "The product-neutral project graph and the Relay or Notary services that consume its authored contracts.", + "field_type": { + "schema_types": [ + "array" + ], + "composed": false + }, + "requiredness": "conditional", + "null_behavior": "not_applicable", + "empty_behavior": "not_applicable", + "default": { + "behavior": "not_applicable" + }, + "environment_behavior": "narrows_reviewed_authority", + "sensitivity": "structural", + "state": "authored", + "products": [ + "registryctl", + "relay", + "notary", + "editor", + "docs" + ], + "availability": "published", + "stability": "experimental", + "validation_stages": [ + "json_schema", + "rust_deserialization", + "cross_file_semantic", + "product_build" + ], + "diagnostic": "registryctl.authoring.project.invalid", + "history_status": "not_verified", + "introduced_in": null, + "version_history": [], + "example": { + "guidance": "Use synthetic identifiers and values from a maintained golden workspace; never copy a private country contract into reference data.", + "schema_examples_available": false, + "contains_country_values": false + }, + "migration": "rebuild_project", + "migration_note": "Revalidate and rebuild the project after changing this field; coordinate a deployment when generated product inputs change.", + "consumers": [ + "registryctl_authoring", + "registry_relay", + "registry_notary", + "editor_tooling", + "docs_generator" + ], + "generated_artifacts": [ + "editor_schemas", + "project_build", + "relay_config", + "notary_config", + "field_reference" + ], + "review_classes": [ + "contract", + "security", + "privacy", + "relay", + "notary", + "compatibility", + "documentation" + ], + "semantic_rules": [ + "knowledge_only", + "generated_docs_never_load_country_values", + "branch_has_no_authored_value" + ], + "constraints": [ + { + "keyword": "maxItems", + "value": 2 + }, + { + "keyword": "minItems", + "value": 2 + }, { "keyword": "type", - "value": "boolean" + "value": "array" + }, + { + "keyword": "uniqueItems", + "value": true } ] }, { "address": { "schema": "project", - "pointer": "/$defs/claimValue/properties/type", - "path_kind": "property" + "pointer": "/$defs/claimValueType/oneOf/1/prefixItems/0", + "path_kind": "array_item" }, - "purpose": "Declares the boolean, integer, string, or date type of a claim value.", - "purpose_source": "reviewed_override", + "purpose": "Defines the contract shared by each ordered item in the enclosing authored list.", + "purpose_source": "structural_taxonomy", "semantic_owner": "authoring_contract", "human_owner": "registry_maintainers", "scope": "The product-neutral project graph and the Relay or Notary services that consume its authored contracts.", @@ -639,7 +828,7 @@ "schema_types": [], "composed": false }, - "requiredness": "required", + "requiredness": "not_applicable", "null_behavior": "rejected", "empty_behavior": "not_applicable", "default": { @@ -699,7 +888,8 @@ ], "semantic_rules": [ "knowledge_only", - "generated_docs_never_load_country_values" + "generated_docs_never_load_country_values", + "array_items_share_element_contract" ], "constraints": [ { @@ -713,6 +903,91 @@ } ] }, + { + "address": { + "schema": "project", + "pointer": "/$defs/claimValueType/oneOf/1/prefixItems/1", + "path_kind": "array_item" + }, + "purpose": "Defines the contract shared by each ordered item in the enclosing authored list.", + "purpose_source": "structural_taxonomy", + "semantic_owner": "authoring_contract", + "human_owner": "registry_maintainers", + "scope": "The product-neutral project graph and the Relay or Notary services that consume its authored contracts.", + "field_type": { + "schema_types": [], + "composed": false + }, + "requiredness": "not_applicable", + "null_behavior": "rejected", + "empty_behavior": "not_applicable", + "default": { + "behavior": "no_schema_default" + }, + "environment_behavior": "narrows_reviewed_authority", + "sensitivity": "internal", + "state": "authored", + "products": [ + "registryctl", + "relay", + "notary", + "editor", + "docs" + ], + "availability": "published", + "stability": "experimental", + "validation_stages": [ + "json_schema", + "rust_deserialization", + "cross_file_semantic", + "product_build" + ], + "diagnostic": "registryctl.authoring.project.invalid", + "history_status": "not_verified", + "introduced_in": null, + "version_history": [], + "example": { + "guidance": "Use synthetic identifiers and values from a maintained golden workspace; never copy a private country contract into reference data.", + "schema_examples_available": false, + "contains_country_values": false + }, + "migration": "rebuild_project", + "migration_note": "Revalidate and rebuild the project after changing this field; coordinate a deployment when generated product inputs change.", + "consumers": [ + "registryctl_authoring", + "registry_relay", + "registry_notary", + "editor_tooling", + "docs_generator" + ], + "generated_artifacts": [ + "editor_schemas", + "project_build", + "relay_config", + "notary_config", + "field_reference" + ], + "review_classes": [ + "contract", + "security", + "privacy", + "relay", + "notary", + "compatibility", + "documentation" + ], + "semantic_rules": [ + "knowledge_only", + "generated_docs_never_load_country_values", + "array_items_share_element_contract" + ], + "constraints": [ + { + "keyword": "const", + "value": "null" + } + ] + }, { "address": { "schema": "project",