Skip to main content
Glama

kb_upsert

Destructive

Create or update one knowledge-base entity and optional relationships; use dry-run validation first to catch schema and semantic conflicts before writing.

Instructions

Create or update one entity and optional relationships. Use for KB mutations after validating intent; prefer a dryRun:true call first because it validates without writing and returns semantic advisor receipts for prose-heavy requirements. Use kb_model (mode requirement) before hand-writing strict property facts from prose, and kb_model (mode predicates) before hand-writing ontology predicate facts. Use the relationships array for batch creation of multiple links in a single call (e.g., linking a requirement to multiple tests or facts). An update keeps the properties and relationships it leaves out: send the fields that change (with title and status) and only the links to add. Prefer modeling requirements as reusable fact links (constrains, requires_property, or requires_predicate) so consistency and contradiction checks remain queryable. Relationship endpoints must already exist in KB. For requirements, the write will be rejected if it contradicts existing current requirements that constrain the same subject with incompatible properties. To replace a conflicting requirement, include a supersedes relationship from the new requirement to the old one in the same request, then upsert the old requirement with status closed (kb_check blocks a superseded requirement that is not closed). Successful writes may return non-blocking semantic advisor warnings; inspect and repair those warnings before treating prose as contradiction-checkable. Pass a sectioned document.body when creating a requirement (the statement, then ## Context stating why it exists, who asked and the source, then ## Source with the verbatim excerpt) and a prose body for scenarios, tests, ADRs and observation facts; a result warning reports an entity whose body lacks context, and kb_check blocks it under entity-context-missing. Never invent a reason the requester did not give: write 'Reason not stated'. Do not use for read-only inspection. Side effects: writes KB, may refresh symbol coordinates; dryRun:true writes nothing.

Input Schema

NameRequiredDescriptionDefault
idYesUnique entity ID (string). Example: 'REQ-cli-gc'. Name entities by the behavior they govern (<TYPE>-<area>-<behavior>), never by the next free number. Existing ID updates the entity; new ID creates it.
typeYesEntity type to create/update. Allowed: req, scenario, test, adr, flag, event, symbol, fact. Example: 'req'.
dryRunNoValidate the payload and return schema/modeling errors, a normalized preview and the semantic advisor receipt without writing the KB or workspace. Use it as the preflight before the real write.
documentNoOptional source-first document write. Paths are workspace-relative; omit body when updating to preserve the existing body bytes (a requirement whose semantic_text changes gets the new statement in place of the old one, with its context sections kept). For a new requirement pass a sectioned body: statement, '## Context' (why, who asked, constraints), '## Source' (blockquoted excerpt and reference); context never changes the checked meaning, which stays in semantic_text.
propertiesYesEntity fields to persist. Must include title and status. If created_at, updated_at, or source are omitted, server fills defaults.
plannedFactsNodryRun only. Fact upsert payloads (type, id, properties, optional relationships) that will be written before this payload, typically the applyPlan entries kb_model returned. They are validated in order and staged with the payload, so a requires_predicate or requires_property target that does not exist yet resolves, its claim_key is read from the plan, and the contradiction preview runs against the KB as it would be after the whole batch (result: stagedFacts, whatIf). A conflict the batch would introduce, such as an allow and a deny permission_rule on the same key, is refused as the commit would refuse it. Rejected without dryRun: write the facts first.
relationshipsNoOptional relationship rows to create in the same call. For requirement encoding, prefer `constrains` + `requires_property` for strict property facts or `requires_predicate` for ontology predicate facts. Side effect: asserts edges in KB.
workspaceRootNoOptional absolute path of the workspace this call is about when it differs from the one the server started in, for example the git worktree you are working in. The server answers from that workspace's knowledge base when it is a worktree of the same repository or lies under the client's MCP roots; otherwise it answers from its own workspace and adds a workspace_mismatch diagnostic. Host hooks fill this in automatically where available.

Output Schema

NameRequiredDescriptionDefault
dataYesCommitted upsert payload, or the validation preview when dryRun:true wrote nothing.
errorNo
statusYes
effectsYes
operationYes
diagnosticsYes
nextActionsYes
kibiProtocolYes
resultVersionYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed9 schema fields changedv0.1.7
    • addedInput schema / properties / properties / properties / proof_contract / properties / domain_source / properties / arg
      Added value: +{
      +  "description": "A SWI-Prolog predicate's argument (1-based) whose solutions Kibi reads, when the predicate takes more than one argument (operator/2 with arg 1 lists each operator's name).",
      +  "maximum": 9007199254740991,
      +  "minimum": 1,
      +  "type": "integer"
      +}
    • addedInput schema / properties / properties / properties / proof_contract / properties / initial_source / properties / arg
      Added value: +{
      +  "description": "A SWI-Prolog predicate's argument (1-based) whose solutions Kibi reads, when the predicate takes more than one argument (operator/2 with arg 1 lists each operator's name).",
      +  "maximum": 9007199254740991,
      +  "minimum": 1,
      +  "type": "integer"
      +}
    • addedInput schema / properties / properties / properties / proof_contract / properties / pattern_source / properties / arg
      Added value: +{
      +  "description": "A SWI-Prolog predicate's argument (1-based) whose solutions Kibi reads, when the predicate takes more than one argument (operator/2 with arg 1 lists each operator's name).",
      +  "maximum": 9007199254740991,
      +  "minimum": 1,
      +  "type": "integer"
      +}
    • changedInput schema / properties / properties / properties / proof_contract / properties / source / description
      Previous value: -"source: the project source a source proof reads. A project source Kibi reads by itself. reader json or yaml: {file, path?, select?: keys|values|items}. glob: {pattern, capture?, ignore?} (capture true reads what each * matched). openapi: {file, select?: operations|unsecured_operations|security_schemes|responses}. references: {files, extract: env|imports|calls|string_args|thrown|property, callee?, key?, ignore?}. schema: {format: drizzle|prisma|sql, file (drizzle, prisma) or files (sql migrations), exports?, table?, select?: tables|columns|required_columns|nullable_columns|foreign_keys}. routes: {file, export, framework?: hono|express, path_prefix?, names_from?, select?: routes|middleware}. validator: {file, export, select?: fields|required_fields|optional_fields}. Paths are repository-relative. A member Kibi cannot read statically fails the read with its location."New value: +"source: the project source a source proof reads. A project source Kibi reads by itself. reader json or yaml: {file, path?, select?: keys|values|items}. glob: {pattern, capture?, ignore?} (capture true reads what each * matched). openapi: {file, select?: operations|unsecured_operations|security_schemes|responses}. references: {files, extract: env|imports|calls|string_args|thrown|property, callee?, key?, ignore?} over TypeScript, JavaScript, Python and SWI-Prolog files. schema: {format: drizzle|prisma|sql, file (drizzle, prisma) or files (sql migrations), exports?, table?, select?: tables|columns|required_columns|nullable_columns|foreign_keys}. routes: {file, export, framework?: hono|express, path_prefix?, names_from?, select?: routes|middleware}. validator: {file, export, select?: fields|required_fields|optional_fields}. prolog: {file, functor: Name/Arity, arg?} reads one argument of every fact with that functor in a SWI-Prolog file (requires/1 in pack.pl), without running it. Paths are repository-relative. A member Kibi cannot read statically fails the read with its location."
    • changedInput schema / properties / properties / properties / proof_contract / properties / source / properties / reader / anyOf
      Previous value: -[
      -  {
      -    "const": "json",
      -    "type": "string"
      -  },
      -  {
      -    "const": "yaml",
      -    "type": "string"
      -  },
      -  {
      -    "const": "glob",
      -    "type": "string"
      -  },
      -  {
      -    "const": "openapi",
      -    "type": "string"
      -  },
      -  {
      -    "const": "references",
      -    "type": "string"
      -  },
      -  {
      -    "const": "schema",
      -    "type": "string"
      -  },
      -  {
      -    "const": "routes",
      -    "type": "string"
      -  },
      -  {
      -    "const": "validator",
      -    "type": "string"
      -  }
      -]New value: +[
      +  {
      +    "const": "json",
      +    "type": "string"
      +  },
      +  {
      +    "const": "yaml",
      +    "type": "string"
      +  },
      +  {
      +    "const": "glob",
      +    "type": "string"
      +  },
      +  {
      +    "const": "openapi",
      +    "type": "string"
      +  },
      +  {
      +    "const": "references",
      +    "type": "string"
      +  },
      +  {
      +    "const": "schema",
      +    "type": "string"
      +  },
      +  {
      +    "const": "routes",
      +    "type": "string"
      +  },
      +  {
      +    "const": "validator",
      +    "type": "string"
      +  },
      +  {
      +    "const": "prolog",
      +    "type": "string"
      +  }
      +]
    • addedInput schema / properties / properties / properties / proof_contract / properties / value_source / items / properties / arg
      Added value: +{
      +  "description": "A SWI-Prolog predicate's argument (1-based) whose solutions Kibi reads, when the predicate takes more than one argument (operator/2 with arg 1 lists each operator's name).",
      +  "maximum": 9007199254740991,
      +  "minimum": 1,
      +  "type": "integer"
      +}
    • changedInput schema / properties / properties / properties / proof_contract / properties / value_source / items / properties / source / description
      Previous value: -"A project source Kibi reads by itself. reader json or yaml: {file, path?, select?: keys|values|items}. glob: {pattern, capture?, ignore?} (capture true reads what each * matched). openapi: {file, select?: operations|unsecured_operations|security_schemes|responses}. references: {files, extract: env|imports|calls|string_args|thrown|property, callee?, key?, ignore?}. schema: {format: drizzle|prisma|sql, file (drizzle, prisma) or files (sql migrations), exports?, table?, select?: tables|columns|required_columns|nullable_columns|foreign_keys}. routes: {file, export, framework?: hono|express, path_prefix?, names_from?, select?: routes|middleware}. validator: {file, export, select?: fields|required_fields|optional_fields}. Paths are repository-relative. A member Kibi cannot read statically fails the read with its location."New value: +"A project source Kibi reads by itself. reader json or yaml: {file, path?, select?: keys|values|items}. glob: {pattern, capture?, ignore?} (capture true reads what each * matched). openapi: {file, select?: operations|unsecured_operations|security_schemes|responses}. references: {files, extract: env|imports|calls|string_args|thrown|property, callee?, key?, ignore?} over TypeScript, JavaScript, Python and SWI-Prolog files. schema: {format: drizzle|prisma|sql, file (drizzle, prisma) or files (sql migrations), exports?, table?, select?: tables|columns|required_columns|nullable_columns|foreign_keys}. routes: {file, export, framework?: hono|express, path_prefix?, names_from?, select?: routes|middleware}. validator: {file, export, select?: fields|required_fields|optional_fields}. prolog: {file, functor: Name/Arity, arg?} reads one argument of every fact with that functor in a SWI-Prolog file (requires/1 in pack.pl), without running it. Paths are repository-relative. A member Kibi cannot read statically fails the read with its location."
    • changedInput schema / properties / properties / properties / proof_contract / properties / value_source / items / properties / source / properties / reader / anyOf
      Previous value: -[
      -  {
      -    "const": "json",
      -    "type": "string"
      -  },
      -  {
      -    "const": "yaml",
      -    "type": "string"
      -  },
      -  {
      -    "const": "glob",
      -    "type": "string"
      -  },
      -  {
      -    "const": "openapi",
      -    "type": "string"
      -  },
      -  {
      -    "const": "references",
      -    "type": "string"
      -  },
      -  {
      -    "const": "schema",
      -    "type": "string"
      -  },
      -  {
      -    "const": "routes",
      -    "type": "string"
      -  },
      -  {
      -    "const": "validator",
      -    "type": "string"
      -  }
      -]New value: +[
      +  {
      +    "const": "json",
      +    "type": "string"
      +  },
      +  {
      +    "const": "yaml",
      +    "type": "string"
      +  },
      +  {
      +    "const": "glob",
      +    "type": "string"
      +  },
      +  {
      +    "const": "openapi",
      +    "type": "string"
      +  },
      +  {
      +    "const": "references",
      +    "type": "string"
      +  },
      +  {
      +    "const": "schema",
      +    "type": "string"
      +  },
      +  {
      +    "const": "routes",
      +    "type": "string"
      +  },
      +  {
      +    "const": "validator",
      +    "type": "string"
      +  },
      +  {
      +    "const": "prolog",
      +    "type": "string"
      +  }
      +]
    • changedOutput schema / properties / data / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "claimKey": {
      -        "description": "For a fact with claim_text: the stored claim_key, derived from claim_text when the payload did not supply it.",
      -        "type": "string"
      -      },
      -      "contradictionCheck": {
      -        "additionalProperties": {},
      -        "properties": {},
      -        "type": "object"
      -      },
      -      "created": {
      -        "maximum": 9007199254740991,
      -        "minimum": -9007199254740991,
      -        "type": "integer"
      -      },
      -      "effectFailures": {
      -        "items": {
      -          "additionalProperties": {},
      -          "properties": {},
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "nextActions": {
      -        "items": {
      -          "additionalProperties": {},
      -          "properties": {},
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "relationships_created": {
      -        "maximum": 9007199254740991,
      -        "minimum": -9007199254740991,
      -        "type": "integer"
      -      },
      -      "semanticAdvisor": {
      -        "additionalProperties": {},
      -        "properties": {},
      -        "type": "object"
      -      },
      -      "sourceWrites": {
      -        "items": {
      -          "additionalProperties": {},
      -          "properties": {},
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "status": {
      -        "type": "string"
      -      },
      -      "updated": {
      -        "maximum": 9007199254740991,
      -        "minimum": -9007199254740991,
      -        "type": "integer"
      -      },
      -      "warnings": {
      -        "items": {},
      -        "type": "array"
      -      }
      -    },
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "dryRun": {
      -        "const": true,
      -        "type": "boolean"
      -      },
      -      "errorCode": {
      -        "type": "string"
      -      },
      -      "errors": {
      -        "items": {},
      -        "type": "array"
      -      },
      -      "normalizedPreview": {
      -        "anyOf": [
      -          {
      -            "additionalProperties": {},
      -            "properties": {},
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "semanticAdvisor": {
      -        "anyOf": [
      -          {
      -            "additionalProperties": {},
      -            "properties": {},
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "skippedEffects": {
      -        "items": {
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "stagedFacts": {
      -        "items": {
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "valid": {
      -        "type": "boolean"
      -      },
      -      "warnings": {
      -        "items": {},
      -        "type": "array"
      -      },
      -      "whatIf": {
      -        "additionalProperties": {},
      -        "properties": {},
      -        "type": "object"
      -      }
      -    },
      -    "required": [
      -      "valid",
      -      "dryRun",
      -      "skippedEffects"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "claimKey": {
      +        "description": "For a fact with claim_text: the stored claim_key, derived from claim_text when the payload did not supply it.",
      +        "type": "string"
      +      },
      +      "contradictionCheck": {
      +        "additionalProperties": {},
      +        "properties": {},
      +        "type": "object"
      +      },
      +      "created": {
      +        "maximum": 9007199254740991,
      +        "minimum": -9007199254740991,
      +        "type": "integer"
      +      },
      +      "effectFailures": {
      +        "items": {
      +          "additionalProperties": {},
      +          "properties": {},
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "nextActions": {
      +        "items": {
      +          "additionalProperties": {},
      +          "properties": {},
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "relationships_created": {
      +        "maximum": 9007199254740991,
      +        "minimum": -9007199254740991,
      +        "type": "integer"
      +      },
      +      "semanticAdvisor": {
      +        "additionalProperties": {},
      +        "properties": {},
      +        "type": "object"
      +      },
      +      "sourceWrites": {
      +        "items": {
      +          "additionalProperties": {},
      +          "properties": {},
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "status": {
      +        "type": "string"
      +      },
      +      "updated": {
      +        "maximum": 9007199254740991,
      +        "minimum": -9007199254740991,
      +        "type": "integer"
      +      },
      +      "warnings": {
      +        "items": {},
      +        "type": "array"
      +      }
      +    },
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "dryRun": {
      +        "const": true,
      +        "type": "boolean"
      +      },
      +      "errorCode": {
      +        "type": "string"
      +      },
      +      "errors": {
      +        "items": {},
      +        "type": "array"
      +      },
      +      "normalizedPreview": {
      +        "anyOf": [
      +          {
      +            "additionalProperties": {},
      +            "properties": {},
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "rejection": {
      +        "additionalProperties": {},
      +        "properties": {},
      +        "type": "object"
      +      },
      +      "semanticAdvisor": {
      +        "anyOf": [
      +          {
      +            "additionalProperties": {},
      +            "properties": {},
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "skippedEffects": {
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "stagedFacts": {
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "valid": {
      +        "type": "boolean"
      +      },
      +      "warnings": {
      +        "items": {},
      +        "type": "array"
      +      },
      +      "whatIf": {
      +        "additionalProperties": {},
      +        "properties": {},
      +        "type": "object"
      +      }
      +    },
      +    "required": [
      +      "valid",
      +      "dryRun",
      +      "skippedEffects"
      +    ],
      +    "type": "object"
      +  }
      +]
  2. Changed8 schema fields changedv0.1.6
    • addedInput schema / properties / properties / properties / case_waiver
      Added value: +{
      +  "description": "Fact-only. Why the edge cases derived from this fact are covered some other way or cannot occur. Waives uncovered_case once case_waiver_approved_by is set.",
      +  "minLength": 1,
      +  "type": "string"
      +}
    • addedInput schema / properties / properties / properties / case_waiver_approved_by
      Added value: +{
      +  "description": "Fact-only. The person who accepted case_waiver.",
      +  "minLength": 1,
      +  "type": "string"
      +}
    • addedInput schema / properties / properties / properties / dimension_waiver
      Added value: +{
      +  "description": "Fact-only. Why the quantifier word in claim_text ranges over nothing, so the claim needs no count, set or rule. Waives dimension_unrepresented once dimension_waiver_approved_by is set.",
      +  "minLength": 1,
      +  "type": "string"
      +}
    • addedInput schema / properties / properties / properties / dimension_waiver_approved_by
      Added value: +{
      +  "description": "Fact-only. The person who accepted dimension_waiver.",
      +  "minLength": 1,
      +  "type": "string"
      +}
    • addedInput schema / properties / properties / properties / failure_side_waiver
      Added value: +{
      +  "description": "Requirement-only. Why the requirement has no failure side to test (its claims state a capability or output shape). Waives happy_path_only once failure_side_waiver_approved_by is set.",
      +  "minLength": 1,
      +  "type": "string"
      +}
    • addedInput schema / properties / properties / properties / failure_side_waiver_approved_by
      Added value: +{
      +  "description": "Requirement-only. The person who accepted failure_side_waiver.",
      +  "minLength": 1,
      +  "type": "string"
      +}
    • addedInput schema / properties / properties / properties / proof_contract / properties / domain_source / properties / field
      Added value: +{
      +  "description": "exhaustive: when the export is a list of records, the field of each record that names a domain member (a catalog's name).",
      +  "minLength": 1,
      +  "type": "string"
      +}
    • changedInput schema / properties / properties / properties / proof_contract / properties / value_source / description
      Previous value: -"arithmetic and smt: code constants the assumptions read. Kibi evaluates each export at ingest and requires the certificate to assume the variable equals that value, so the proof is about the code and not only the knowledge base. With measure count the value is the size of a list, set, map or object export, so a count claim reads the collection itself. An entry {source, measure: count} counts the members Kibi reads from a project source (routes, tables, environment variables)."New value: +"arithmetic and smt: code constants the assumptions read. Kibi evaluates each export at ingest and requires the certificate to assume the variable equals that value, so the proof is about the code and not only the knowledge base. With measure count the value is the size of a list, set, map or object export, so a count claim reads the collection itself. A dotted export (POLICY.eventLimit) reads one field of an object export. An entry {source, measure: count} counts the members Kibi reads from a project source (routes, tables, environment variables)."
  3. Changed18 schema fields changedv0.1.5
    • changedInput schema / properties / properties / properties / operator / anyOf
      Previous value: -[
      -  {
      -    "const": "eq",
      -    "type": "string"
      -  },
      -  {
      -    "const": "neq",
      -    "type": "string"
      -  },
      -  {
      -    "const": "lt",
      -    "type": "string"
      -  },
      -  {
      -    "const": "lte",
      -    "type": "string"
      -  },
      -  {
      -    "const": "gt",
      -    "type": "string"
      -  },
      -  {
      -    "const": "gte",
      -    "type": "string"
      -  }
      -]New value: +[
      +  {
      +    "const": "eq",
      +    "type": "string"
      +  },
      +  {
      +    "const": "neq",
      +    "type": "string"
      +  },
      +  {
      +    "const": "lt",
      +    "type": "string"
      +  },
      +  {
      +    "const": "lte",
      +    "type": "string"
      +  },
      +  {
      +    "const": "gt",
      +    "type": "string"
      +  },
      +  {
      +    "const": "gte",
      +    "type": "string"
      +  },
      +  {
      +    "const": "matches",
      +    "type": "string"
      +  },
      +  {
      +    "const": "includes",
      +    "type": "string"
      +  },
      +  {
      +    "const": "subset_of",
      +    "type": "string"
      +  },
      +  {
      +    "const": "excludes",
      +    "type": "string"
      +  }
      +]
    • changedInput schema / properties / properties / properties / operator / description
      Previous value: -"Optional comparison operator for property_value facts. Example: 'eq'."New value: +"Optional comparison operator for property_value facts. Example: 'eq'. 'matches' (string facts only): value_string is a JavaScript regular expression (u flag) every value must match as a whole. Set facts only: 'includes' means every member of value_set has the property and other members may have it too; 'subset_of' means every member that has the property is in value_set ('every env var the server reads is one of ...'); 'excludes' means no member of value_set has it ('never imports md5'); 'eq' on a set means exactly those members."
    • changedInput schema / properties / properties / properties / proof_contract / properties / domain_source / description
      Previous value: -"exhaustive and typecheck: the symbol that defines the finite domain. The proof must import it from its source file; a hand-listed domain downgrades the receipt to example. Kibi reads the export named `export`, or the symbol's title when `export` is absent."New value: +"exhaustive and typecheck: the symbol that defines the finite domain (typecheck: also the type whose fields a required_fields fact names). state_machine: the transition table or next-state function. The proof must import it from its source file; a hand-listed domain downgrades the receipt to example. Kibi reads the export named `export`, or the symbol's title when `export` is absent."
    • addedInput schema / properties / properties / properties / proof_contract / properties / domains
      Added value: +{
      +  "additionalProperties": {},
      +  "description": "rule: the finite domain of each argument type, keyed by type name (an array, Set, Map or object export, or a Python list, set, dict or Enum), or {source} for the members Kibi reads from a project source (every route, every table, every environment variable). state_machine with a next-state function: the `state` and `event` domains it is called on.",
      +  "properties": {},
      +  "type": "object"
      +}
    • addedInput schema / properties / properties / properties / proof_contract / properties / initial_source
      Added value: +{
      +  "description": "state_machine: the export holding the initial state (or states), needed for initial_states and reachable_states facts.",
      +  "properties": {
      +    "export": {
      +      "minLength": 1,
      +      "type": "string"
      +    },
      +    "symbol_id": {
      +      "minLength": 1,
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "symbol_id"
      +  ],
      +  "type": "object"
      +}
    • changedInput schema / properties / properties / properties / proof_contract / properties / kind / anyOf
      Previous value: -[
      -  {
      -    "const": "e2e",
      -    "type": "string"
      -  },
      -  {
      -    "const": "example",
      -    "type": "string"
      -  },
      -  {
      -    "const": "property",
      -    "type": "string"
      -  },
      -  {
      -    "const": "exhaustive",
      -    "type": "string"
      -  },
      -  {
      -    "const": "typecheck",
      -    "type": "string"
      -  },
      -  {
      -    "const": "arithmetic",
      -    "type": "string"
      -  },
      -  {
      -    "const": "smt",
      -    "type": "string"
      -  }
      -]New value: +[
      +  {
      +    "const": "e2e",
      +    "type": "string"
      +  },
      +  {
      +    "const": "example",
      +    "type": "string"
      +  },
      +  {
      +    "const": "property",
      +    "type": "string"
      +  },
      +  {
      +    "const": "exhaustive",
      +    "type": "string"
      +  },
      +  {
      +    "const": "typecheck",
      +    "type": "string"
      +  },
      +  {
      +    "const": "arithmetic",
      +    "type": "string"
      +  },
      +  {
      +    "const": "smt",
      +    "type": "string"
      +  },
      +  {
      +    "const": "rule",
      +    "type": "string"
      +  },
      +  {
      +    "const": "state_machine",
      +    "type": "string"
      +  },
      +  {
      +    "const": "regex",
      +    "type": "string"
      +  },
      +  {
      +    "const": "source",
      +    "type": "string"
      +  }
      +]
    • changedInput schema / properties / properties / properties / proof_contract / properties / kind / description
      Previous value: -"What the checker establishes; absent means e2e. exhaustive, typecheck, arithmetic and smt must leave a kibi.code-certificate.v1 that Kibi re-checks before the receipt counts as proved."New value: +"What the checker establishes; absent means e2e. exhaustive, typecheck, arithmetic, smt, rule, state_machine and regex must leave a kibi.code-certificate.v1 that Kibi re-checks before the receipt counts as proved. source reads the contract's source itself: the run may leave {version, kind: source, test_id, source} or nothing, and Kibi stores its own read as the certificate."
    • addedInput schema / properties / properties / properties / proof_contract / properties / pattern_source
      Added value: +{
      +  "description": "regex: the export holding the code's pattern (a RegExp, or a Python re.Pattern) or string constant that a string fact is about.",
      +  "properties": {
      +    "export": {
      +      "minLength": 1,
      +      "type": "string"
      +    },
      +    "symbol_id": {
      +      "minLength": 1,
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "symbol_id"
      +  ],
      +  "type": "object"
      +}
    • addedInput schema / properties / properties / properties / proof_contract / properties / predicate_source
      Added value: +{
      +  "additionalProperties": {},
      +  "description": "rule: the code function behind each predicate a claim's rule, predicate or set fact names, keyed by predicate name. Each export takes the predicate's arguments in order and returns a boolean; Kibi calls it on every combination of its argument domains.",
      +  "properties": {},
      +  "type": "object"
      +}
    • changedInput schema / properties / properties / properties / proof_contract / properties / proves / description
      Previous value: -"Certificate kinds: the requirement claim keys (CLAIM-...) this certificate proves. Each must be a modeled claim of a current requirement the test reaches through its scenarios. Kibi derives what the certificate must establish from the claim's grounding fact (a set fact for exhaustive or typecheck, a numeric fact for arithmetic or smt); a claim with no such derivation is only attested and never counts as proved."New value: +"Certificate kinds: the requirement claim keys (CLAIM-...) this certificate proves. Each must be a modeled claim of a current requirement the test reaches through its scenarios. Kibi derives what the certificate must establish from the claim's grounding fact (a set fact for exhaustive or typecheck, a numeric fact for arithmetic or smt, a rule, predicate or set fact for rule and state_machine, a string fact for regex); a claim with no such derivation is only attested and never counts as proved."
    • addedInput schema / properties / properties / properties / proof_contract / properties / source
      Added value: +{
      +  "additionalProperties": {},
      +  "description": "source: the project source a source proof reads. A project source Kibi reads by itself. reader json or yaml: {file, path?, select?: keys|values|items}. glob: {pattern, capture?, ignore?} (capture true reads what each * matched). openapi: {file, select?: operations|unsecured_operations|security_schemes|responses}. references: {files, extract: env|imports|calls|string_args|thrown|property, callee?, key?, ignore?}. schema: {format: drizzle|prisma|sql, file (drizzle, prisma) or files (sql migrations), exports?, table?, select?: tables|columns|required_columns|nullable_columns|foreign_keys}. routes: {file, export, framework?: hono|express, path_prefix?, names_from?, select?: routes|middleware}. validator: {file, export, select?: fields|required_fields|optional_fields}. Paths are repository-relative. A member Kibi cannot read statically fails the read with its location.",
      +  "properties": {
      +    "reader": {
      +      "anyOf": [
      +        {
      +          "const": "json",
      +          "type": "string"
      +        },
      +        {
      +          "const": "yaml",
      +          "type": "string"
      +        },
      +        {
      +          "const": "glob",
      +          "type": "string"
      +        },
      +        {
      +          "const": "openapi",
      +          "type": "string"
      +        },
      +        {
      +          "const": "references",
      +          "type": "string"
      +        },
      +        {
      +          "const": "schema",
      +          "type": "string"
      +        },
      +        {
      +          "const": "routes",
      +          "type": "string"
      +        },
      +        {
      +          "const": "validator",
      +          "type": "string"
      +        }
      +      ]
      +    }
      +  },
      +  "required": [
      +    "reader"
      +  ],
      +  "type": "object"
      +}
    • changedInput schema / properties / properties / properties / proof_contract / properties / value_source / description
      Previous value: -"arithmetic and smt: code constants the assumptions read. Kibi evaluates each export at ingest and requires the certificate to assume the variable equals that value, so the proof is about the code and not only the knowledge base."New value: +"arithmetic and smt: code constants the assumptions read. Kibi evaluates each export at ingest and requires the certificate to assume the variable equals that value, so the proof is about the code and not only the knowledge base. With measure count the value is the size of a list, set, map or object export, so a count claim reads the collection itself. An entry {source, measure: count} counts the members Kibi reads from a project source (routes, tables, environment variables)."
    • addedInput schema / properties / properties / properties / proof_contract / properties / value_source / items / properties / measure
      Added value: +{
      +  "anyOf": [
      +    {
      +      "const": "value",
      +      "type": "string"
      +    },
      +    {
      +      "const": "count",
      +      "type": "string"
      +    }
      +  ],
      +  "description": "value (default for an export): the export is a number. count (the only measure of a source): the number of members of a list, set, map or object export, or of a source."
      +}
    • addedInput schema / properties / properties / properties / proof_contract / properties / value_source / items / properties / source
      Added value: +{
      +  "additionalProperties": {},
      +  "description": "A project source Kibi reads by itself. reader json or yaml: {file, path?, select?: keys|values|items}. glob: {pattern, capture?, ignore?} (capture true reads what each * matched). openapi: {file, select?: operations|unsecured_operations|security_schemes|responses}. references: {files, extract: env|imports|calls|string_args|thrown|property, callee?, key?, ignore?}. schema: {format: drizzle|prisma|sql, file (drizzle, prisma) or files (sql migrations), exports?, table?, select?: tables|columns|required_columns|nullable_columns|foreign_keys}. routes: {file, export, framework?: hono|express, path_prefix?, names_from?, select?: routes|middleware}. validator: {file, export, select?: fields|required_fields|optional_fields}. Paths are repository-relative. A member Kibi cannot read statically fails the read with its location.",
      +  "properties": {
      +    "reader": {
      +      "anyOf": [
      +        {
      +          "const": "json",
      +          "type": "string"
      +        },
      +        {
      +          "const": "yaml",
      +          "type": "string"
      +        },
      +        {
      +          "const": "glob",
      +          "type": "string"
      +        },
      +        {
      +          "const": "openapi",
      +          "type": "string"
      +        },
      +        {
      +          "const": "references",
      +          "type": "string"
      +        },
      +        {
      +          "const": "schema",
      +          "type": "string"
      +        },
      +        {
      +          "const": "routes",
      +          "type": "string"
      +        },
      +        {
      +          "const": "validator",
      +          "type": "string"
      +        }
      +      ]
      +    }
      +  },
      +  "required": [
      +    "reader"
      +  ],
      +  "type": "object"
      +}
    • removedInput schema / properties / properties / properties / proof_contract / properties / value_source / items / required
      Removed value: -[
      -  "symbol_id"
      -]
    • changedInput schema / properties / properties / properties / proof_receipts / items / properties / claim_bindings / items / properties / scope / anyOf
      Previous value: -[
      -  {
      -    "const": "code",
      -    "type": "string"
      -  },
      -  {
      -    "const": "intent",
      -    "type": "string"
      -  }
      -]New value: +[
      +  {
      +    "const": "code",
      +    "type": "string"
      +  },
      +  {
      +    "const": "source",
      +    "type": "string"
      +  },
      +  {
      +    "const": "harness",
      +    "type": "string"
      +  },
      +  {
      +    "const": "intent",
      +    "type": "string"
      +  }
      +]
    • changedInput schema / properties / properties / properties / proof_receipts / items / properties / kind / anyOf
      Previous value: -[
      -  {
      -    "const": "e2e",
      -    "type": "string"
      -  },
      -  {
      -    "const": "example",
      -    "type": "string"
      -  },
      -  {
      -    "const": "property",
      -    "type": "string"
      -  },
      -  {
      -    "const": "exhaustive",
      -    "type": "string"
      -  },
      -  {
      -    "const": "typecheck",
      -    "type": "string"
      -  },
      -  {
      -    "const": "arithmetic",
      -    "type": "string"
      -  },
      -  {
      -    "const": "smt",
      -    "type": "string"
      -  }
      -]New value: +[
      +  {
      +    "const": "e2e",
      +    "type": "string"
      +  },
      +  {
      +    "const": "example",
      +    "type": "string"
      +  },
      +  {
      +    "const": "property",
      +    "type": "string"
      +  },
      +  {
      +    "const": "exhaustive",
      +    "type": "string"
      +  },
      +  {
      +    "const": "typecheck",
      +    "type": "string"
      +  },
      +  {
      +    "const": "arithmetic",
      +    "type": "string"
      +  },
      +  {
      +    "const": "smt",
      +    "type": "string"
      +  },
      +  {
      +    "const": "rule",
      +    "type": "string"
      +  },
      +  {
      +    "const": "state_machine",
      +    "type": "string"
      +  },
      +  {
      +    "const": "regex",
      +    "type": "string"
      +  },
      +  {
      +    "const": "source",
      +    "type": "string"
      +  }
      +]
    • changedInput schema / properties / properties / properties / value_type / description
      Previous value: -"Optional typed value discriminator for property_value facts. Pair with exactly one value_string, value_int, value_number, value_bool, or value_set (set: an exact list of allowed values, operator eq or neq); do not use generic value."New value: +"Optional typed value discriminator for property_value facts. Pair with exactly one value_string, value_int, value_number, value_bool, or value_set (set: a list of members, with operator eq, includes, subset_of or excludes); do not use generic value."
  4. Changed23 schema fields changedv0.1.4
    • addedInput schema / properties / properties / properties / proof_contract / properties / constraint_source
      Added value: +{
      +  "description": "arithmetic and smt: the typed numeric property_value facts the certificate's assumptions come from. Kibi checks the assumptions (or the query's assertions) are exactly these facts' constraints, so the proof is about the knowledge base, not numbers the test chose.",
      +  "properties": {
      +    "fact_ids": {
      +      "items": {
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "minItems": 1,
      +      "type": "array"
      +    }
      +  },
      +  "required": [
      +    "fact_ids"
      +  ],
      +  "type": "object"
      +}
    • addedInput schema / properties / properties / properties / proof_contract / properties / domain_source
      Added value: +{
      +  "description": "exhaustive and typecheck: the symbol that defines the finite domain. The proof must import it from its source file; a hand-listed domain downgrades the receipt to example. Kibi reads the export named `export`, or the symbol's title when `export` is absent.",
      +  "properties": {
      +    "export": {
      +      "description": "The name the domain is exported under in the symbol's source file, when the symbol's title is not that name.",
      +      "minLength": 1,
      +      "type": "string"
      +    },
      +    "symbol_id": {
      +      "minLength": 1,
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "symbol_id"
      +  ],
      +  "type": "object"
      +}
    • addedInput schema / properties / properties / properties / proof_contract / properties / kind
      Added value: +{
      +  "anyOf": [
      +    {
      +      "const": "e2e",
      +      "type": "string"
      +    },
      +    {
      +      "const": "example",
      +      "type": "string"
      +    },
      +    {
      +      "const": "property",
      +      "type": "string"
      +    },
      +    {
      +      "const": "exhaustive",
      +      "type": "string"
      +    },
      +    {
      +      "const": "typecheck",
      +      "type": "string"
      +    },
      +    {
      +      "const": "arithmetic",
      +      "type": "string"
      +    },
      +    {
      +      "const": "smt",
      +      "type": "string"
      +    }
      +  ],
      +  "description": "What the checker establishes; absent means e2e. exhaustive, typecheck, arithmetic and smt must leave a kibi.code-certificate.v1 that Kibi re-checks before the receipt counts as proved."
      +}
    • addedInput schema / properties / properties / properties / proof_contract / properties / proves
      Added value: +{
      +  "description": "Certificate kinds: the requirement claim keys (CLAIM-...) this certificate proves. Each must be a modeled claim of a current requirement the test reaches through its scenarios. Kibi derives what the certificate must establish from the claim's grounding fact (a set fact for exhaustive or typecheck, a numeric fact for arithmetic or smt); a claim with no such derivation is only attested and never counts as proved.",
      +  "items": {
      +    "pattern": "^CLAIM-",
      +    "type": "string"
      +  },
      +  "minItems": 1,
      +  "type": "array",
      +  "uniqueItems": true
      +}
    • addedInput schema / properties / properties / properties / proof_contract / properties / success_policy / anyOf
      Added value: +[
      +  {
      +    "const": "all_required_first_attempt",
      +    "type": "string"
      +  },
      +  {
      +    "const": "own_results_first_attempt",
      +    "type": "string"
      +  }
      +]
    • removedInput schema / properties / properties / properties / proof_contract / properties / success_policy / const
      Removed value: -"all_required_first_attempt"
    • removedInput schema / properties / properties / properties / proof_contract / properties / success_policy / type
      Removed value: -"string"
    • addedInput schema / properties / properties / properties / proof_contract / properties / value_source
      Added value: +{
      +  "description": "arithmetic and smt: code constants the assumptions read. Kibi evaluates each export at ingest and requires the certificate to assume the variable equals that value, so the proof is about the code and not only the knowledge base.",
      +  "items": {
      +    "properties": {
      +      "export": {
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "symbol_id": {
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "symbol_id"
      +    ],
      +    "type": "object"
      +  },
      +  "minItems": 1,
      +  "type": "array"
      +}
    • addedInput schema / properties / properties / properties / proof_contract / properties / witness
      Added value: +{
      +  "description": "typecheck: the repository-relative witness file Kibi compiles (an exhaustive switch ending in never, or a mapped type over the domain).",
      +  "properties": {
      +    "path": {
      +      "minLength": 1,
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "path"
      +  ],
      +  "type": "object"
      +}
    • changedInput schema / properties / properties / properties / proof_receipts / items / description
      Previous value: -"Kibi-derived kibi.proof-receipt.v1. Receipts are never caller-authored; kb_ingest_proof derives them from kibi.proof-run.v1 artifacts."New value: +"Kibi-derived kibi.proof-receipt.v2 (kibi.proof-receipt.v1 entries are still read). Receipts are never caller-authored; kb_ingest_proof derives them from kibi.proof-run.v1 artifacts."
    • addedInput schema / properties / properties / properties / proof_receipts / items / properties / certificate
      Added value: +{
      +  "additionalProperties": {},
      +  "properties": {},
      +  "type": "object"
      +}
    • addedInput schema / properties / properties / properties / proof_receipts / items / properties / certificate_digest
      Added value: +{
      +  "pattern": "^[a-f0-9]{64}$",
      +  "type": "string"
      +}
    • addedInput schema / properties / properties / properties / proof_receipts / items / properties / certificate_rejection
      Added value: +{
      +  "minLength": 1,
      +  "type": "string"
      +}
    • addedInput schema / properties / properties / properties / proof_receipts / items / properties / claim_bindings
      Added value: +{
      +  "description": "Certificate kinds: how the certificate binds to each claim its contract names in proves, judged at ingest. derived means Kibi derived the certificate's obligation from the claim's grounding fact and the certificate satisfies it; attested means no derivation exists and the author vouches for it (never proved); rejected names why.",
      +  "items": {
      +    "properties": {
      +      "binding": {
      +        "anyOf": [
      +          {
      +            "const": "derived",
      +            "type": "string"
      +          },
      +          {
      +            "const": "attested",
      +            "type": "string"
      +          },
      +          {
      +            "const": "rejected",
      +            "type": "string"
      +          }
      +        ]
      +      },
      +      "claim_key": {
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "fact_id": {
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "obligation": {
      +        "additionalProperties": {},
      +        "properties": {},
      +        "type": "object"
      +      },
      +      "reason": {
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "requirement_id": {
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "scope": {
      +        "anyOf": [
      +          {
      +            "const": "code",
      +            "type": "string"
      +          },
      +          {
      +            "const": "intent",
      +            "type": "string"
      +          }
      +        ]
      +      }
      +    },
      +    "required": [
      +      "claim_key",
      +      "binding"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • addedInput schema / properties / properties / properties / proof_receipts / items / properties / evidence_level
      Added value: +{
      +  "anyOf": [
      +    {
      +      "const": "proved",
      +      "type": "string"
      +    },
      +    {
      +      "const": "tested",
      +      "type": "string"
      +    }
      +  ]
      +}
    • addedInput schema / properties / properties / properties / proof_receipts / items / properties / kind
      Added value: +{
      +  "anyOf": [
      +    {
      +      "const": "e2e",
      +      "type": "string"
      +    },
      +    {
      +      "const": "example",
      +      "type": "string"
      +    },
      +    {
      +      "const": "property",
      +      "type": "string"
      +    },
      +    {
      +      "const": "exhaustive",
      +      "type": "string"
      +    },
      +    {
      +      "const": "typecheck",
      +      "type": "string"
      +    },
      +    {
      +      "const": "arithmetic",
      +      "type": "string"
      +    },
      +    {
      +      "const": "smt",
      +      "type": "string"
      +    }
      +  ]
      +}
    • addedInput schema / properties / properties / properties / proof_receipts / items / properties / version / anyOf
      Added value: +[
      +  {
      +    "const": "kibi.proof-receipt.v1",
      +    "type": "string"
      +  },
      +  {
      +    "const": "kibi.proof-receipt.v2",
      +    "type": "string"
      +  }
      +]
    • removedInput schema / properties / properties / properties / proof_receipts / items / properties / version / const
      Removed value: -"kibi.proof-receipt.v1"
    • removedInput schema / properties / properties / properties / proof_receipts / items / properties / version / type
      Removed value: -"string"
    • addedInput schema / properties / properties / properties / required_evidence
      Added value: +{
      +  "anyOf": [
      +    {
      +      "const": "proved",
      +      "type": "string"
      +    },
      +    {
      +      "const": "tested",
      +      "type": "string"
      +    },
      +    {
      +      "const": "asserted",
      +      "type": "string"
      +    },
      +    {
      +      "const": "unverified",
      +      "type": "string"
      +    }
      +  ],
      +  "description": "Requirement-only. Weakest evidence level it accepts; the evidence-floor rule fails below it. Absent = tested if firm, else unverified."
      +}
    • addedInput schema / properties / properties / properties / value_set
      Added value: +{
      +  "description": "Optional exact set of values for property_value facts with value_type set, such as the members a domain must have.",
      +  "items": {
      +    "minLength": 1,
      +    "type": "string"
      +  },
      +  "minItems": 1,
      +  "type": "array",
      +  "uniqueItems": true
      +}
    • changedInput schema / properties / properties / properties / value_type / anyOf
      Previous value: -[
      -  {
      -    "const": "string",
      -    "type": "string"
      -  },
      -  {
      -    "const": "int",
      -    "type": "string"
      -  },
      -  {
      -    "const": "number",
      -    "type": "string"
      -  },
      -  {
      -    "const": "bool",
      -    "type": "string"
      -  }
      -]New value: +[
      +  {
      +    "const": "string",
      +    "type": "string"
      +  },
      +  {
      +    "const": "int",
      +    "type": "string"
      +  },
      +  {
      +    "const": "number",
      +    "type": "string"
      +  },
      +  {
      +    "const": "bool",
      +    "type": "string"
      +  },
      +  {
      +    "const": "set",
      +    "type": "string"
      +  }
      +]
    • changedInput schema / properties / properties / properties / value_type / description
      Previous value: -"Optional typed value discriminator for property_value facts. Pair with exactly one value_string, value_int, value_number, or value_bool; do not use generic value."New value: +"Optional typed value discriminator for property_value facts. Pair with exactly one value_string, value_int, value_number, value_bool, or value_set (set: an exact list of allowed values, operator eq or neq); do not use generic value."
  5. Changed1 schema field changedv0.1.3
    • changedOutput schema / properties / data / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "claimKey": {
      -        "description": "For a fact with claim_text: the stored claim_key, derived from claim_text when the payload did not supply it.",
      -        "type": "string"
      -      },
      -      "contradictionCheck": {
      -        "additionalProperties": {},
      -        "properties": {},
      -        "type": "object"
      -      },
      -      "created": {
      -        "maximum": 9007199254740991,
      -        "minimum": -9007199254740991,
      -        "type": "integer"
      -      },
      -      "effectFailures": {
      -        "items": {
      -          "additionalProperties": {},
      -          "properties": {},
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "nextActions": {
      -        "items": {
      -          "additionalProperties": {},
      -          "properties": {},
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "relationships_created": {
      -        "maximum": 9007199254740991,
      -        "minimum": -9007199254740991,
      -        "type": "integer"
      -      },
      -      "semanticAdvisor": {
      -        "additionalProperties": {},
      -        "properties": {},
      -        "type": "object"
      -      },
      -      "sourceWrites": {
      -        "items": {
      -          "additionalProperties": {},
      -          "properties": {},
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "status": {
      -        "type": "string"
      -      },
      -      "updated": {
      -        "maximum": 9007199254740991,
      -        "minimum": -9007199254740991,
      -        "type": "integer"
      -      },
      -      "warnings": {
      -        "items": {},
      -        "type": "array"
      -      }
      -    },
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "dryRun": {
      -        "const": true,
      -        "type": "boolean"
      -      },
      -      "errors": {
      -        "items": {},
      -        "type": "array"
      -      },
      -      "normalizedPreview": {
      -        "anyOf": [
      -          {
      -            "additionalProperties": {},
      -            "properties": {},
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "semanticAdvisor": {
      -        "anyOf": [
      -          {
      -            "additionalProperties": {},
      -            "properties": {},
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "skippedEffects": {
      -        "items": {
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "stagedFacts": {
      -        "items": {
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "valid": {
      -        "type": "boolean"
      -      },
      -      "warnings": {
      -        "items": {},
      -        "type": "array"
      -      },
      -      "whatIf": {
      -        "additionalProperties": {},
      -        "properties": {},
      -        "type": "object"
      -      }
      -    },
      -    "required": [
      -      "valid",
      -      "dryRun",
      -      "skippedEffects"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "claimKey": {
      +        "description": "For a fact with claim_text: the stored claim_key, derived from claim_text when the payload did not supply it.",
      +        "type": "string"
      +      },
      +      "contradictionCheck": {
      +        "additionalProperties": {},
      +        "properties": {},
      +        "type": "object"
      +      },
      +      "created": {
      +        "maximum": 9007199254740991,
      +        "minimum": -9007199254740991,
      +        "type": "integer"
      +      },
      +      "effectFailures": {
      +        "items": {
      +          "additionalProperties": {},
      +          "properties": {},
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "nextActions": {
      +        "items": {
      +          "additionalProperties": {},
      +          "properties": {},
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "relationships_created": {
      +        "maximum": 9007199254740991,
      +        "minimum": -9007199254740991,
      +        "type": "integer"
      +      },
      +      "semanticAdvisor": {
      +        "additionalProperties": {},
      +        "properties": {},
      +        "type": "object"
      +      },
      +      "sourceWrites": {
      +        "items": {
      +          "additionalProperties": {},
      +          "properties": {},
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "status": {
      +        "type": "string"
      +      },
      +      "updated": {
      +        "maximum": 9007199254740991,
      +        "minimum": -9007199254740991,
      +        "type": "integer"
      +      },
      +      "warnings": {
      +        "items": {},
      +        "type": "array"
      +      }
      +    },
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "dryRun": {
      +        "const": true,
      +        "type": "boolean"
      +      },
      +      "errorCode": {
      +        "type": "string"
      +      },
      +      "errors": {
      +        "items": {},
      +        "type": "array"
      +      },
      +      "normalizedPreview": {
      +        "anyOf": [
      +          {
      +            "additionalProperties": {},
      +            "properties": {},
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "semanticAdvisor": {
      +        "anyOf": [
      +          {
      +            "additionalProperties": {},
      +            "properties": {},
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "skippedEffects": {
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "stagedFacts": {
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "valid": {
      +        "type": "boolean"
      +      },
      +      "warnings": {
      +        "items": {},
      +        "type": "array"
      +      },
      +      "whatIf": {
      +        "additionalProperties": {},
      +        "properties": {},
      +        "type": "object"
      +      }
      +    },
      +    "required": [
      +      "valid",
      +      "dryRun",
      +      "skippedEffects"
      +    ],
      +    "type": "object"
      +  }
      +]
  6. First observedv0.1.0

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare this as destructive, non-read-only, and non-idempotent, but the description adds important behavior: updates preserve omitted properties and relationships, dryRun writes nothing, successful writes may return semantic advisor warnings, and contradictions can cause rejection. It also discloses side effects such as writing the KB and possibly refreshing symbol coordinates. This is substantial context beyond the annotation flags.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core action and alternatives, then moves into operational constraints and content rules. It is dense and useful, but several sentences are long and some content-level guidance overlaps with schema documentation. It earns most of its length, but could be tightened.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given a destructive mutation tool with eight parameters, nested objects, and an output schema, the description covers purpose, alternatives, dry-run preflight, update semantics, rejection conditions, supersede workflow, body structure, and side effects. Nothing essential for correct invocation appears to be missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds meaningful semantics beyond the schema, especially that an update keeps properties and relationships it leaves out and that superseding a conflicting requirement requires including a supersedes link in the same request. It also clarifies the purpose of dryRun and batch relationships. Some of this overlaps with schema descriptions, which keeps it from a 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence states a specific verb pair and resource: create or update one entity plus optional relationships. It also explicitly excludes read-only inspection, which separates it from siblings such as kb_query and kb_search. An agent can identify the tool's function without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit workflow guidance: validate intent, prefer dryRun:true first, use kb_model before hand-writing strict property or predicate facts, and use the relationships array for batch links. It also gives update semantics and a concrete supersede procedure, including the follow-up status change required by kb_check. These are clear when-to-use, when-not-to-use, and alternative-tool instructions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.