Entity schema
The eight entity types, their fields, and every typed relationship the knowledge graph supports.
This document describes the entity and relationship schema for the Kibi Knowledge Base. It covers all supported entity types, their properties, relationship types, and provides frontmatter examples for each entity and relationship.
Entity Types
Kibi intentionally supports eight core entity types, organized into two logical groups:
Common Authoring Entities (Standard Workflow)
| Type | Description |
|---|---|
| req | Software requirement specifying functionality or constraints |
| scenario | BDD scenario describing user behavior (Given/When/Then) |
| test | Unit, integration, or e2e test case |
| fact | Atomic domain fact; includes strict lanes and observation/meta notes |
Supporting & System Entities (Context & Infrastructure)
| Type | Description |
|---|---|
| adr | Architecture Decision Record documenting technical choices |
| flag | Runtime or config gate (feature flag, kill-switch, deferred capability) |
| event | Domain or system event published/consumed by components |
| symbol | Abstract code symbol (function, class, module) - language-agnostic |
Entity Choice: When to Use Each Type
This section provides guidance on selecting the appropriate entity type for your documentation needs.
Decision Table
| What you are documenting | Entity Type | Notes |
|---|---|---|
| Intended or corrected behavior | req |
Requirements specify what the system should do |
| Bug, incident, or workaround | fact (observation/meta) |
Use fact_kind: observation or meta for non-blocking evidence |
| Runtime/config gate controlling feature access | flag |
Feature flags, kill-switches, deferred capabilities |
| Executable verification or reproduction | test |
Unit, integration, or e2e tests |
| Technical decision or tradeoff rationale | adr |
Architecture Decision Records |
Important Rules
Do NOT create a flag for bugs or workarounds unless there is an actual runtime/config gate. Use fact with fact_kind: observation or meta instead.
When a bug is mitigated by a feature gate: Create TWO records - a fact describing the issue and a flag representing the gate. Link them with relates_to since no typed relationship exists for this case.
Canonical Mapping Summary
flag= Runtime/config gate (includes kill-switches, deferred capabilities) - NOT for bug recordsfact(observation/meta) = Bug records, incident notes, workaroundsreq= Intended/corrected behaviortest= Executable verification/reproductionadr= Durable design rationale
Common Properties (All Entities)
| Property | Required | Type | Description |
|---|---|---|---|
| id | Yes | string | Unique identifier (SHA256 or explicit frontmatter) |
| title | Yes | string | Short summary/name |
| status | Yes | string | Entity status (see below for values) |
| created_at | Yes | ISO 8601 | Creation timestamp |
| updated_at | Yes | ISO 8601 | Last update timestamp |
| source | Yes | string | Provenance (file path, URL, or reference) |
| tags[] | No | array[string] | Array of metadata/search tags only |
| owner | No | string | Owner/assignee |
| priority | No | string | Priority level (must, should, could) |
| severity | No | string | Severity level |
| links[] | No | array[string] | Array of URLs |
| text_ref | No | string | Pointer to Markdown/doc blob |
Entity Type Details & Example Frontmatter
Requirement (req)
| Property | Required | Type | Description |
|---|---|---|---|
| id | Yes | string | Unique identifier |
| title | Yes | string | Requirement summary |
| status | Yes | string | open, in_progress, closed, deprecated. ADR vocabulary such as accepted compiles but is not a requirement status: it silently removes the requirement from the proof ladder, and kibi check reports it under req-status-vocabulary. Superseded requirements keep their status and gain a supersedes link from the successor. |
| created_at | Yes | ISO 8601 | Creation timestamp |
| updated_at | Yes | ISO 8601 | Last update timestamp |
| source | Yes | string | Provenance |
| tags[] | No | array[string] | Tags |
| owner | No | string | Owner/assignee |
| priority | No | string | must, should, could |
| severity | No | string | Severity level |
| links[] | No | array[string] | URLs or entity IDs (for relationships) |
| text_ref | No | string | Independent code/doc evidence pointer |
| proof_exempt | No | boolean | Marks a current requirement as intentionally outside E2E-proof scope. Requires proof_exempt_reason; coverage reports the requirement not_applicable with that reason |
| proof_exempt_reason | No | string | Required when proof_exempt is true — the reviewable justification surfaced in coverage rows |
| semantic_text | No | string | Requirement-only normalized authored prose that anchors semantic byte spans |
| logic_claims | No | array[string] | Requirement-only manifest of stable atomic claim keys |
| semantic_clauses | No | array[string] | Reviewed atomic decomposition override used against the exact semantic source |
| semantic_inventory_version | No | string | kibi.semantic-inventory.v1 for source-bound ledgers |
| semantic_source_field | No | string | semantic_text, text_ref, or title, identifying the field that owns ledger byte spans; new authored requirements prefer semantic_text |
| semantic_source_hash | No | string | SHA-256 of the exact semantic source text |
| semantic_inventory | No | array[object] | Proposition ledger with exact claim text, UTF-8 byte span, role, status, and optional semantic key |
Canonical Example: REQ + SCEN + TEST (Golden Path)
# .kb/requirements/REQ-auth-login.md
---
id: REQ-auth-login
title: User authentication
status: open
created_at: 2026-03-10T10:00:00Z
updated_at: 2026-03-10T10:00:00Z
source: .kb/requirements/REQ-auth-login.md
links:
- type: specified_by
target: SCEN-auth-login-success
---
# .kb/scenarios/SCEN-auth-login-success.md
---
id: SCEN-auth-login-success
title: Login with valid credentials
status: active
created_at: 2026-03-10T10:01:00Z
updated_at: 2026-03-10T10:01:00Z
source: .kb/scenarios/SCEN-auth-login-success.md
---
# .kb/tests/TEST-auth-login-success.md
---
id: TEST-auth-login-success
title: Login test
status: passing
created_at: 2026-03-10T10:02:00Z
updated_at: 2026-03-10T10:02:00Z
source: .kb/tests/TEST-auth-login-success.md
links:
- type: validates
target: SCEN-auth-login-success
---Generic Link Shorthand:
links:
- ADR-session-token-storage
- FACT-auth-session-ttlPlain string Markdown links entries are imported as generic relates_to
relationships. Use typed link objects or relationship rows when the semantic
relationship matters.
Relationship Rows Example:
# Relationship: REQ-auth-login specified_by SCEN-auth-login-success
relationship:
type: specified_by
source: REQ-auth-login
target: SCEN-auth-login-success
created_at: 2026-03-10T10:03:00Z
created_by: analyst
source: .kb/requirements/REQ-auth-login.md
---
# Relationship: REQ-auth-login verified_by TEST-auth-login-success
relationship:
type: verified_by
source: REQ-auth-login
target: TEST-auth-login-success
created_at: 2026-03-10T10:04:00Z
created_by: qa
source: .kb/requirements/REQ-auth-login.mdRule: Never embed scenarios or tests inside requirement records. Always create separate files for each entity and link them with explicit typed
linksentries or relationship rows (specified_by,verified_by). Plain stringlinksare genericrelates_toonly.
Strict Fact Modeling (Normative Lane):
Preserve readable requirement prose, but decompose the entire assertive body into atomic propositions with
kb_semantic_advisor. Context-only rationale, examples, and subjective commentary remain in the inventory asnonlogicaland do not enterlogic_claims.For a current requirement write, persist the receipt's
inventory_contractassemantic_inventory_version,semantic_source_field, andsemantic_source_hash. Ledger spans are UTF-8 byte offsets into that exact field; the advisor canonicalizes repeated identical normalized claims to one proposition at the first source occurrence, while duplicate keys/spans in a submitted ledger, source drift, and silent omission are rejected before mutation.Store exactly all returned assertive keys in the requirement
logic_claimsmanifest. Eachmodeledentry must resolve through exactly onerequires_property,requires_predicate, orrequires_ruleedge to a fact carrying the sameclaim_key; explicitambiguous,ontology_gap, ormissingentries remain ingestible but unresolved.logic-coveragechecks manifest-to-ground-fact correspondence and is enabled by default. Requirements without manifests remain a gradual-backfill case; quality diagnostics identify every current requirement with this debt, while the default rule prevents explicitly modeled manifests from drifting.New contradiction-sensitive requirements should use the strict fact lane:
- one
fact_kind: subjectfact linked viaconstrains - one
fact_kind: property_valuefact linked viarequires_property
- one
For v1, the supported evolution path is append-only: create a new requirement and link it to the prior one with
supersedes.Automated modeling via
kb_model_requirementcan produce deterministic write plans./kibi-bootstrapreturnskibi.bootstrap-plan.v1; bootstrap writes require a user-facing preview and explicit approval before callingkb_apply_plan.Low-confidence downgrade: If confidence is < 0.7, requirements are downgraded to
observationfacts to avoid false-positive contradictions.Use
observationandmetafacts for runtime evidence, historical notes, and governance context that should not participate in contradiction blocking.
Canonical Contradiction-Safe Example:
# .kb/facts/FACT-USER-ROLE.md
---
id: FACT-USER-ROLE
title: User Role Assignment
status: active
created_at: 2026-03-24T00:00:00Z
updated_at: 2026-03-24T00:00:00Z
source: .kb/facts/FACT-USER-ROLE.md
fact_kind: subject
subject_key: user.role_assignment
---
# .kb/facts/FACT-LIMIT-3.md
---
id: FACT-LIMIT-3
title: Maximum of Three
status: active
created_at: 2026-03-24T00:00:00Z
updated_at: 2026-03-24T00:00:00Z
source: .kb/facts/FACT-LIMIT-3.md
fact_kind: property_value
subject_key: user.role_assignment
property_key: max_roles
operator: lte
value_type: int
value_int: 3
---
# .kb/requirements/REQ-user-role-limits.md
---
id: REQ-user-role-limits
title: Users can now have 3 roles
status: open
created_at: 2026-02-20T13:06:00Z
updated_at: 2026-03-24T00:00:00Z
source: .kb/requirements/REQ-user-role-limits.md
links:
- type: constrains
target: FACT-USER-ROLE
- type: requires_property
target: FACT-LIMIT-3
- type: supersedes
target: REQ-user-role-assignment
---
**Schema Migration:**
Older KBs can be upgraded to the latest schema using the `migrate` command. This ensures all entities are compatible with the latest contradiction and validation rules.
```bash
# Check if migration is required
kibi status
# Perform the migration
kibi migrate --yesSchema version 2 introduces strict symbol granularity. During migration, existing coarse file/module links that can be explained by older ontology data are marked with granularity_reason: legacy-link; new or updated symbol traceability should target the narrow function, class method (ClassName.methodName), class, or other behavioral symbol whenever one exists. Interfaces, type aliases, and enums are type-shape symbols; they describe code shape and do not by themselves block a coarse behavioral link.
Invalid Example (Prohibited):
# WRONG - embedded scenario
---
id: REQ-auth-login
title: User authentication
scenarios:
- given: user is on login page
when: they enter valid credentials
then: they are logged in
---Scenario (scenario)
| Property | Required | Type | Description |
|---|---|---|---|
| id | Yes | string | Unique identifier |
| title | Yes | string | Scenario summary |
| status | Yes | string | draft, active, deprecated |
| created_at | Yes | ISO 8601 | Creation timestamp |
| updated_at | Yes | ISO 8601 | Last update timestamp |
| source | Yes | string | Provenance |
| tags[] | No | array[string] | Tags |
| owner | No | string | Owner/assignee |
| priority | No | string | Priority level |
| severity | No | string | Severity level |
| links[] | No | array[string] | URLs |
| text_ref | No | string | Markdown/doc pointer |
Example:
---
id: SCEN-auth-login-success
title: Sample scenario SCEN-auth-login-success
status: active
created_at: 2026-02-17T13:00:00Z
updated_at: 2026-02-17T13:00:00Z
source: https://example.com/fixtures/scenarios/SCEN-auth-login-success
tags:
- sample
---Test (test)
| Property | Required | Type | Description |
|---|---|---|---|
| id | Yes | string | Unique identifier |
| title | Yes | string | Test summary |
| status | Yes | string | passing, failing, skipped, pending |
| created_at | Yes | ISO 8601 | Creation timestamp |
| updated_at | Yes | ISO 8601 | Last update timestamp |
| source | Yes | string | Provenance |
| tags[] | No | array[string] | Tags |
| owner | No | string | Owner/assignee |
| priority | No | string | Priority level |
| severity | No | string | Severity level |
| links[] | No | array[string] | URLs |
| text_ref | No | string | Markdown/doc pointer |
| verification_scope | No | enum | unit, integration, or end_to_end |
| verification_perspective | No | enum | internal or consumer |
| proof_contract | No | object | kibi.proof-contract.v1: explicit required_proofs obligations (symbol_id + ecosystem-neutral target) executed by one configured integration; requires verification_scope |
| proof_bindings | No | array[object] | Optional native-runner bindings (native_id, aliases, source coordinates) for proof obligations; provenance metadata, never a contract replacement |
| proof_receipts | No | array[object] | Append-only proof-receipt execution history; evidence is kibi.proof-receipt.v1; requires verification_scope |
proof_receipts is append-only: never remove or rewrite existing entries, and include the full history when authoring a test file directly. Receipts are engine-derived from kibi.proof-run.v1 producer artifacts — see proving requirements for contracts, the kibi prove workflow, and the artifact reference.
tags remain metadata only. They do not alias or replace typed verification fields.
Coverage-depth reporting uses typed verification fields before legacy hints. A test with status: passing and verification_scope: end_to_end supplies structural depth evidence even if it has no e2e tag; tag or path heuristics are only fallback evidence for older records. Durable status never supplies conservative proof evidence by itself. Requirement coverage rows can therefore report deterministic depth labels without changing the underlying covered/uncovered decision:
direct_passing_e2e— the requirement is directly linked to a passing e2e test.scenario_passing_e2e— a linked scenario is validated by a passing e2e test.unit_only— passing evidence exists, but only at unit scope.open_or_nonpassing_tests_only— tests exist but none are passing.scenario_only_no_test— scenarios exist without executable test evidence.no_test_evidence— no scenario or test evidence is linked.
Conservative requirement proof uses receipt history instead. Each kibi.proof-receipt.v1 binds receipt_id, test_id, typed scope, outcome, code_snapshot, environment_hash, started_at, finished_at, artifact_digest, contract_hash, execution fingerprint, integration_id, producer, and command_argv. History is capped at 50 entries, receipt IDs are unique, finish times increase strictly, and existing entries cannot be removed, changed, or reordered through upsert or incremental sync. Proof accepts only the newest receipt for the deterministic current workspace snapshot when it passed, is not future-dated, and is at most seven days old. Missing, wrong-snapshot, stale, failed, malformed, or future-dated evidence produces explicit proof gaps.
kibi.workspace-snapshot.v2 hashes current versionable code plus requirement, scenario, fact, test-contract, and symbol-manifest inputs. It excludes .kb/ derived runtime trees, release changesets, general docs/, and the proof_receipts frontmatter field inside every tracked Markdown file, preventing a receipt from invalidating its own code hash without hiding changes to the surrounding test contract. A receipt bound to an older snapshot hash is not proof of the current snapshot. Rerun kibi prove so the receipt matches the snapshot the branch is on now.
Check output diagnostics
kibi check, MCP kb_check, staged impact checks, and OpenCode scheduled checks use a two-lane output contract rather than modeling audit findings as new entity types:
violations[]is the hard correctness lane. Graph, schema, contradiction, query-plan, and staged blocking failures stay here and continue to fail checks.qualityDiagnostics[]is the audit-quality lane. Modeling reviews, coverage-depth reviews, broad requirement fanout, duplicate coordinates, symbol fanout, status misuse, and strict-fact modeling suggestions are advisory unless a diagnostic explicitly setsblocking: trueorseverity: "error".
The public severity values are error, warning, review, and info. review and info do not fail checks by default; warning is also non-blocking unless paired with blocking: true. Integrations should inspect both severity and blocking instead of treating every diagnostic-like record as a failure.
Example:
---
id: TEST-auth-login-success
title: Sample test TEST-auth-login-success
status: passing
created_at: 2026-02-17T13:00:00Z
updated_at: 2026-02-17T13:00:00Z
source: https://example.com/fixtures/tests/TEST-auth-login-success
tags:
- sample
verification_scope: end_to_end
verification_perspective: consumer
proof_contract:
version: kibi.proof-contract.v1
integration: self-proof
required_proofs:
- symbol_id: SYM-test-auth-login-success
target: default
success_policy: all_required_first_attempt
proof_receipts:
- version: kibi.proof-receipt.v1
receipt_id: PR-TEST-auth-login-success-20260217T1305
test_id: TEST-auth-login-success
scope: end_to_end
outcome: passed
code_snapshot: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
environment_hash: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
started_at: 2026-02-17T13:00:00Z
finished_at: 2026-02-17T13:05:00Z
artifact_digest: cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
contract_hash: dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
fingerprint: eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
fingerprint_components:
contract: 111111111111111111111111111111111111111111111111111111111111111a
integration: 222222222222222222222222222222222222222222222222222222222222222a
command: 333333333333333333333333333333333333333333333333333333333333333a
bindings: 4444444444444444444444444444444444444444444444444444444444444444a
producer: 5555555555555555555555555555555555555555555555555555555555555555a
integration_id: self-proof
producer:
name: kibi-command-producer
command_argv: [node, scripts/run-proof-producer.mjs]
run_outcome: passed
proof_results:
- symbol_id: SYM-test-auth-login-success
target: default
outcome: passed
binding: aggregate_run
attempts:
status: unavailable
---See docs/examples/test-verification-fields.md for a complete example using both typed fields.
ADR (adr)
| Property | Required | Type | Description |
|---|---|---|---|
| id | Yes | string | Unique identifier |
| title | Yes | string | ADR summary |
| status | Yes | string | proposed, accepted, deprecated, superseded |
| created_at | Yes | ISO 8601 | Creation timestamp |
| updated_at | Yes | ISO 8601 | Last update timestamp |
| source | Yes | string | Provenance |
| tags[] | No | array[string] | Tags |
| owner | No | string | Owner/assignee |
| priority | No | string | Priority level |
| severity | No | string | Severity level |
| links[] | No | array[string] | URLs |
| text_ref | No | string | Markdown/doc pointer |
Example:
---
id: ADR-session-token-storage
title: Sample ADR ADR-session-token-storage
status: accepted
created_at: 2026-02-17T13:00:00Z
updated_at: 2026-02-17T13:00:00Z
source: https://example.com/fixtures/adrs/ADR-session-token-storage
tags:
- architecture
---Flag (flag)
| Property | Required | Type | Description |
|---|---|---|---|
| id | Yes | string | Unique identifier |
| title | Yes | string | Flag summary |
| status | Yes | string | active, inactive, deprecated |
| created_at | Yes | ISO 8601 | Creation timestamp |
| updated_at | Yes | ISO 8601 | Last update timestamp |
| source | Yes | string | Provenance |
| tags[] | No | array[string] | Tags |
| owner | No | string | Owner/assignee |
| priority | No | string | Priority level |
| severity | No | string | Severity level |
| links[] | No | array[string] | URLs |
| text_ref | No | string | Markdown/doc pointer |
Example:
---
id: FLAG-login-rate-limit
title: Sample flag FLAG-login-rate-limit
status: active
created_at: 2026-02-17T13:00:00Z
updated_at: 2026-02-17T13:00:00Z
source: https://example.com/fixtures/flags/FLAG-login-rate-limit
tags:
- rollout
---Event (event)
| Property | Required | Type | Description |
|---|---|---|---|
| id | Yes | string | Unique identifier |
| title | Yes | string | Event summary |
| status | Yes | string | active, deprecated |
| created_at | Yes | ISO 8601 | Creation timestamp |
| updated_at | Yes | ISO 8601 | Last update timestamp |
| source | Yes | string | Provenance |
| tags[] | No | array[string] | Tags |
| owner | No | string | Owner/assignee |
| priority | No | string | Priority level |
| severity | No | string | Severity level |
| links[] | No | array[string] | URLs |
| text_ref | No | string | Markdown/doc pointer |
Example:
---
id: EVT-user-logged-in
title: Sample event EVT-user-logged-in
status: active
created_at: 2026-02-17T13:00:00Z
updated_at: 2026-02-17T13:00:00Z
source: https://example.com/fixtures/events/EVT-user-logged-in
tags:
- domain
---Symbol (symbol)
| Property | Required | Type | Description |
|---|---|---|---|
| id | Yes | string | Unique identifier |
| title | Yes | string | Symbol summary |
| status | Yes | string | active, deprecated, removed |
| created_at | Yes | ISO 8601 | Creation timestamp |
| updated_at | Yes | ISO 8601 | Last update timestamp |
| source | Yes | string | Provenance |
| tags[] | No | array[string] | Tags |
| owner | No | string | Owner/assignee |
| priority | No | string | Priority level |
| severity | No | string | Severity level |
| links[] | No | array[string] | URLs |
| text_ref | No | string | Markdown/doc pointer |
| sourceFile | No | string | Code source path |
| sourceLine | Generated | integer | One-based start line persisted during sync |
| sourceColumn | Generated | integer | Zero-based start column persisted during sync |
| sourceEndLine | Generated | integer | One-based end line persisted during sync |
| sourceEndColumn | Generated | integer | Zero-based end column persisted during sync |
Example:
---
id: SYM-login-handler
title: Sample symbol SYM-login-handler
status: active
created_at: 2026-02-17T13:00:00Z
updated_at: 2026-02-17T13:00:00Z
source: https://example.com/fixtures/symbols/SYM-login-handler
tags:
- code
---Fact (fact)
Facts support two authoring lanes:
- Strict lane for normative, contradiction-sensitive knowledge
subject: requiressubject_keyproperty_value: requiressubject_key,property_key,operator,value_type, and exactly one value field
- Context lane for non-blocking knowledge
observationmeta
- Ontology lane for project-local predicate modeling
predicate_schema: defines an allowed predicate signature; requirespredicate_name,predicate_arity,argument_names, andargument_types. May close argument vocabularies withargument_constants(allowed values keyed by argument name) andargument_aliases(legacy spellings keyed by argument name, each mapped to a declared constant); unlisted arguments stay openpredicate: stores a ground predicate claim; requirespredicate_name, non-emptypredicate_args, andcanonical_key; may usepolarity: assertordeny; logical coverage also uses the pairedclaim_keyandclaim_textprovenance fields
- Logic lane for conditional and modal requirements
rule_schema: declares the stablekibi.logic.v1signature used by rule factsrule: stores schema-validated canonical Logic IR JSON, a fullrule_hash, semantic key, provenance span, andrule_schema_id
Legacy prose facts without fact_kind remain readable during migration, but new requirements should prefer the strict lane when the fact expresses a rule that should block contradictions.
fact entities represent atomic domain concepts and invariants (for example domain nouns, cardinalities, property values, ontology predicates, and safe rules). Requirements can link to strict facts using constrains and requires_property, ontology predicate facts using requires_predicate, or safe Logic IR rules using requires_rule, so domain claims become structural and queryable. When either claim_key or claim_text is supplied, both are required.
Migration note: schema v4 adds semantic_inventory, its source-binding contract, rule_schema, rule, and requires_rule additively. Existing Markdown requirements receive a one-time semantic-hash baseline; the next semantic edit, or any newly added requirement after that baseline, must carry a complete ledger. Projects can adopt the logic lane incrementally by preserving advisor proposition ledgers, adding rule schemas, then linking modeled requirements to safe facts while leaving unresolved states explicit.
Logic IR facts
rule_ir is a JSON object with version: kibi.logic.v1; it is validated and canonicalized before persistence. It supports typed atoms, variables, conjunction/disjunction, comparisons, bounded counts, temporal intervals, exceptions, and the modalities assert, deny, oblige, permit, and forbid. rule_hash is the full SHA-256 of canonical IR; semantic_key is a shorter stable identity for paraphrase convergence. Kibi renders Prolog for inspection, but never evaluates stored source text. rule-safety and rule-verifiability are blocking checks for new rule records.
Requirements also retain a semantic_inventory proposition ledger. Each entry binds a claim key and exact claim text to a UTF-8 byte span and one of modeled, ambiguous, ontology_gap, nonlogical, or missing. An assertive proposition that is not modeled must be explicitly unresolved; prose alone is not logical coverage.
Symbol coordinates are generated compiler state. Callers cannot author sourceLine, sourceColumn, sourceEndLine, or sourceEndColumn through kb_upsert: source-first symbol upserts re-extract the canonical manifest plus .kb/symbol-coordinates.yaml before committing, so partial payloads can no longer erase persisted coordinates, and coordinate refresh failures abort the mutation instead of being reported as complete. The artifact is version 2: every record carries an identity hash bound to the extraction that produced it, malformed artifacts fail sync and mutations closed, and publication is atomic. This lets conservative proof reporting validate the exact source-bound symbols that carry implementation and executable-test evidence; the authored manifest remains coordinate-free and .kb/symbol-coordinates.yaml remains the generated source of truth.
| Property | Required | Type | Description |
|---|---|---|---|
| id | Yes | string | Unique identifier |
| title | Yes | string | Fact summary |
| status | Yes | string | active, deprecated |
| created_at | Yes | ISO 8601 | Creation timestamp |
| updated_at | Yes | ISO 8601 | Last update timestamp |
| source | Yes | string | Provenance |
| tags[] | No | array[string] | Tags |
| owner | No | string | Owner/assignee |
| priority | No | string | Priority level |
| severity | No | string | Severity level |
| links[] | No | array[string] | URLs |
| text_ref | No | string | Markdown/doc pointer |
Example:
---
id: FACT-USER-ROLE
title: User Role Assignment
status: active
created_at: 2026-02-20T13:00:00Z
updated_at: 2026-02-20T13:00:00Z
source: .kb/facts/FACT-USER-ROLE.md
tags:
- domain
- auth
---Relationship Types
Kibi supports relationship types listed below. Each relationship has metadata:
| Property | Required | Type | Description |
|---|---|---|---|
| created_at | Yes | ISO 8601 | Creation timestamp |
| created_by | Yes | string | Creator identifier |
| source | Yes | string | Provenance |
| confidence | No | string/number | Optional confidence level |
Relationship Table
| Relationship | Source Entity | Target Entity | Description |
|---|---|---|---|
| depends_on | req | req | Requirement depends on another requirement |
| specified_by | req | scenario | Requirement is specified by a scenario |
| verified_by | req/scenario | test | Requirement or scenario is verified by a test |
| validates | test | req/scenario | Test validates a requirement or scenario |
| implements | symbol | req | Symbol owns or implements requirement behavior |
| covered_by | symbol | test | Production symbol has coverage evidence from a test |
| executable_for | symbol | test | Symbol is executable test code for a test entity |
| constrained_by | symbol | adr | Symbol constrained by ADR |
| constrains | req | fact | Requirement constrains a specific domain fact |
| requires_property | req | fact | Requirement requires a property fact/value |
| requires_predicate | req | fact | Requirement requires a ground ontology predicate fact |
| requires_rule | req | fact | Requirement requires a schema-validated kibi.logic.v1 rule fact |
| guards | flag | symbol/event/req | Flag guards symbol, event, or requirement |
| publishes | symbol | event | Symbol publishes event |
| consumes | symbol | event | Symbol consumes event |
| supersedes | adr | adr | The source ADR formally replaces the target ADR. The target is expected to carry status: archived or deprecated |
| supersedes | req | req | The source requirement replaces the target requirement; the target stops being current |
| restates | req | req | The source requirement intentionally restates a current requirement (e.g. a product requirement echoed in a platform requirement). Both stay current; domain-redundancy is suppressed for the pair |
| relates_to | a | b | Generic relationship (escape hatch) |
Relationship Examples
depends_on
# req REQ-auth-login-lockout depends_on req REQ-auth-login
relationship:
type: depends_on
source: REQ-auth-login-lockout
target: REQ-auth-login
created_at: 2026-02-17T13:10:00Z
created_by: analyst
source: https://example.com/fixtures/requirements/REQ-auth-login-lockoutspecified_by
# req REQ-auth-login specified_by scenario SCEN-auth-login-success
relationship:
type: specified_by
source: REQ-auth-login
target: SCEN-auth-login-success
created_at: 2026-02-17T13:15:00Z
created_by: analyst
source: https://example.com/fixtures/requirements/REQ-auth-loginverified_by
# req REQ-auth-login verified_by test TEST-auth-login-success
relationship:
type: verified_by
source: REQ-auth-login
target: TEST-auth-login-success
created_at: 2026-02-17T13:20:00Z
created_by: qa
source: https://example.com/fixtures/tests/TEST-auth-login-successverified_by has one frozen meaning: a requirement or scenario is verified by a test. Direct req -> test is fallback only when no scenario exists. Prefer req -> scenario -> test.
Facts are not directly verified by tests. Model the behavior through a requirement: link the requirement to strict or observation facts with constrains, requires_property, or requires_predicate, then link the requirement or scenario to the test with verified_by / validates.
validates
# test TEST-auth-login-success validates scenario SCEN-auth-login-success
relationship:
type: validates
source: TEST-auth-login-success
target: SCEN-auth-login-success
created_at: 2026-02-17T13:22:00Z
created_by: qa
source: https://example.com/fixtures/tests/TEST-auth-login-successvalidates is the inverse edge for req/scenario ↔ test links.
implements
# symbol SYM-login-handler implements req REQ-auth-login
relationship:
type: implements
source: SYM-login-handler
target: REQ-auth-login
created_at: 2026-02-17T13:25:00Z
created_by: dev
source: https://example.com/fixtures/symbols/SYM-login-handlerimplements is frozen to requirement ownership only (symbol -> req).
covered_by
# symbol SYM-login-handler covered_by test TEST-auth-login-success
relationship:
type: covered_by
source: SYM-login-handler
target: TEST-auth-login-success
created_at: 2026-02-17T13:30:00Z
created_by: dev
source: https://example.com/fixtures/tests/TEST-auth-login-successcovered_by is frozen to production coverage evidence only (symbol -> test).
executable_for
# symbol SYM-test-auth-login-success executable_for test TEST-auth-login-success
relationship:
type: executable_for
source: SYM-test-auth-login-success
target: TEST-auth-login-success
created_at: 2026-02-17T13:32:00Z
created_by: dev
source: https://example.com/fixtures/symbols/SYM-test-auth-login-successexecutable_for is frozen to executable test code identity only (symbol -> test).
For the canonical symbol taxonomy, integration/e2e N/A rubric, and anti-blanket requirement checklist, see Symbol Traceability Taxonomy.
constrained_by
# symbol SYM-login-handler constrained_by adr ADR-session-token-storage
relationship:
type: constrained_by
source: SYM-login-handler
target: ADR-session-token-storage
created_at: 2026-02-17T13:35:00Z
created_by: architect
source: https://example.com/fixtures/adrs/ADR-session-token-storageguards
# flag FLAG-login-rate-limit guards req REQ-auth-login
relationship:
type: guards
source: FLAG-login-rate-limit
target: REQ-auth-login
created_at: 2026-02-17T13:45:00Z
created_by: devops
source: https://example.com/fixtures/flags/FLAG-login-rate-limitpublishes
# symbol SYM-login-handler publishes event EVT-user-logged-in
relationship:
type: publishes
source: SYM-login-handler
target: EVT-user-logged-in
created_at: 2026-02-17T13:50:00Z
created_by: dev
source: https://example.com/fixtures/symbols/SYM-login-handlerconsumes
# symbol SYM-login-handler consumes event EVT-user-logged-in
relationship:
type: consumes
source: SYM-login-handler
target: EVT-user-logged-in
created_at: 2026-02-17T13:55:00Z
created_by: dev
source: https://example.com/fixtures/symbols/SYM-login-handlerconstrains
# req REQ-user-role-assignment constrains fact FACT-USER-ROLE
relationship:
type: constrains
source: REQ-user-role-assignment
target: FACT-USER-ROLE
created_at: 2026-02-20T14:00:00Z
created_by: analyst
source: .kb/requirements/REQ-user-role-assignment.mdrequires_property
# req REQ-user-role-assignment requires_property fact FACT-LIMIT-2
relationship:
type: requires_property
source: REQ-user-role-assignment
target: FACT-LIMIT-2
created_at: 2026-02-20T14:01:00Z
created_by: analyst
source: .kb/requirements/REQ-user-role-assignment.mdrelates_to
# Generic relationship between any two entities
relationship:
type: relates_to
source: ENTITY-A
target: ENTITY-B
kind: custom
created_at: 2026-02-17T14:00:00Z
created_by: analyst
source: https://example.com/fixtures/entities/ENTITY-Asupersedes
# adr ADR-session-token-storage-v2 supersedes adr ADR-session-token-storage
relationship:
type: supersedes
source: ADR-session-token-storage-v2
target: ADR-session-token-storage
created_at: 2026-02-20T10:00:00Z
created_by: architect
source: https://example.com/fixtures/adrs/ADR-session-token-storage-v2restates
# req REQ-billing-invoice-retention restates req REQ-platform-record-retention
relationship:
type: restates
source: REQ-billing-invoice-retention
target: REQ-platform-record-retention
created_at: 2026-09-28T10:00:00Z
created_by: analyst
source: .kb/requirements/REQ-billing-invoice-retention.mdNotes
- The schema is the eight entity types and the relationship catalog in this document.
- IDs must be stable and unique. Set an explicit frontmatter
idnamed by what the entity governs (<TYPE>-<area>-<behavior>, e.g.REQ-cli-gc) and keep the filename stem equal to it; never pick the next free number. A missingidfalls back to a path-and-title hash that changes on rename.entity-id-stylereports stem mismatches and newly created numeric IDs; legacy numbered entities are grandfathered. - Relationship metadata supports audit and conflict resolution.
- Status values are entity-type specific (see above).
End of schema documentation.