quicue-kg is a CUE-native knowledge graph framework for tracking architectural decisions, validated discoveries, reusable patterns, and rejected approaches within software projects. It uses the CUE language's type system and lattice-based unification to provide compile-time validation, conflict detection, and zero-infrastructure federation of knowledge across project boundaries.

This specification defines the data model, directory layout, type constraints, aggregation semantics, W3C vocabulary projections, and federation protocol for conforming .kg/ knowledge graphs.

This is an unofficial specification published by the quicue project. It is not a W3C Standard nor is it on the W3C Standards Track. It documents the quicue-kg framework as implemented in the quicue.ca/kg@v0 CUE module. Feedback is welcome via the project's issue tracker.

Introduction

Software projects accumulate knowledge that is broader than source code: why a technology was chosen, what approaches were tried and abandoned, which patterns recur across repositories, and what discoveries emerged during development. This knowledge is typically scattered across wiki pages, chat logs, commit messages, and individual memory. When it is lost, teams re-explore failed paths, re-derive known insights, and make decisions without context.

quicue-kg addresses this by defining a typed, validated, machine-readable knowledge graph that lives alongside source code in a .kg/ directory. The framework leverages the [[CUE]] language's properties:

Design Goals

  1. Knowledge conflicts are type errors, detected at build time.
  2. Federation across projects is CUE unification, not a service call.
  3. Every rejected approach MUST record a constructive alternative, preventing re-exploration of known dead ends.
  4. Schema evolution is a quality ratchet: adding a required field makes every existing entry without it a validation error.
  5. W3C vocabulary projections enable interoperability without replacing CUE as the source of truth.

Intended Audience

This specification is intended for:

Conformance

As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [[RFC2119]].

Conformance Classes

Conforming Knowledge Graph

A conforming knowledge graph is a .kg/ directory that:

  1. MUST contain a valid CUE module declaration.
  2. MUST declare package kg in all .cue files at the directory root.
  3. MUST contain at least one entry conforming to a core type.
  4. MUST pass cue vet without errors when evaluated against the quicue.ca/kg schemas.
  5. MUST NOT contain .cue files in subdirectories (CUE packages are directory-scoped; see Directory Layout).

Conforming Processor

A conforming processor is a tool that:

  1. MUST validate input against the quicue-kg CUE schemas before processing.
  2. MUST reject entries with missing required fields as validation errors.
  3. MUST preserve the @type field in all serialization formats.
  4. SHOULD produce valid [[JSON-LD]] when exporting to W3C projection formats.

Terminology

Knowledge Graph
A typed, validated collection of interconnected knowledge entries stored in a .kg/ directory. Abbreviated as KG.
Entry
A single record in the knowledge graph, conforming to one of the defined types (Decision, Insight, Rejected, Pattern, Derivation, Context, or Workspace).
Core Type
One of the four fundamental entry types that every conforming knowledge graph MUST support: Decision, Insight, Rejected, and Pattern.
Extension Type
An optional entry type that a knowledge graph MAY support for domain-specific use cases: Derivation, Context, and Workspace.
Struct-as-Set
The CUE idiom {[string]: true} used to represent set membership. Provides O(1) lookup, deduplication, and clean unification across projects. Used for related, used_in, and similar fields.
Unification
The CUE operation that merges two values. If the values are compatible, the result is the most specific value satisfying both constraints. If they conflict, unification produces a type error. This property is the foundation for federation.
Projection
A computed transformation from CUE-native knowledge graph data to a W3C vocabulary format (e.g., [[PROV-O]], [[DCAT]], [[WEB-ANNOTATION]]). Projections are export-only; CUE remains the source of truth.
Federation
The process of discovering, merging, and querying multiple knowledge graphs across project boundaries using CUE unification.
Canon Purity
A classification of data provenance used in Derivation entries: pure (original source data), mixed (partially derived), or derived (fully computed).

Directory Layout

A conforming knowledge graph resides in a .kg/ directory at the root of a project. All CUE files MUST be at the directory root level — CUE packages are directory-scoped, meaning files in subdirectories constitute separate package instances even if they declare the same package name.

project/
  .kg/
    cue.mod/
      module.cue          # Module declaration
      pkg/
        quicue.ca/
          kg/             # Schema dependency (symlink or registry)
            core/
            ext/
            aggregate/
            vocab/
    decisions.cue         # Entry files (package kg)
    insights.cue
    rejected.cue
    patterns.cue
    project.cue           # ext.#Context (optional)
    index.cue             # aggregate.#KGIndex (recommended)
    

Module Declaration

The .kg/cue.mod/module.cue file MUST declare a CUE module. The module name SHOULD follow the pattern {project-domain}/.kg but MAY use any valid CUE module identifier.

// .kg/cue.mod/module.cue
module: ""
language: version: "v0.11.0"

Schema Dependency

The quicue-kg schemas MUST be available to the CUE evaluator. This MAY be achieved through any of the following mechanisms, in order of preference:

  1. CUE Central Registrycue mod tidy resolves the quicue.ca/kg@v0 dependency automatically.
  2. OCI Registry (GHCR) — set CUE_REGISTRY='quicue.ca=ghcr.io/quicue/cue-modules,registry.cue.works' and run cue mod tidy.
  3. Local symlink — create a symlink at .kg/cue.mod/pkg/quicue.ca/kg/ pointing to a local checkout of the quicue-kg repository.

Package Declaration

Every .cue file at the root of the .kg/ directory MUST declare package kg. Files MUST NOT be placed in subdirectories, as CUE treats each directory as a separate package scope.

package kg

import "quicue.ca/kg/core@v0"

decisions: {
    "ADR-001": core.#Decision & {
        // ...
    }
}

File Organization

Within the flat .kg/ directory, entries SHOULD be organized by type into separate files for readability. The RECOMMENDED file organization is:

FileContentsStatus
decisions.cueAll #Decision entriesRECOMMENDED
insights.cueAll #Insight entriesRECOMMENDED
rejected.cueAll #Rejected entriesRECOMMENDED
patterns.cueAll #Pattern entriesRECOMMENDED
project.cueext.#Context identityOPTIONAL
index.cueaggregate.#KGIndexRECOMMENDED

A conforming knowledge graph MAY combine all entries into a single file. The file boundaries are not semantically significant — CUE evaluates all files in a package as a single logical unit.

Core Types

Core types define the four fundamental categories of knowledge that every conforming knowledge graph MUST support. They are defined in the quicue.ca/kg/core@v0 package and have no external dependencies.

All core types share the following conventions:

Decision (#Decision)

A Decision records an architecture decision with mandatory rationale, following the Architecture Decision Record ([[ADR]]) methodology. Status transitions follow a defined lifecycle: proposedaccepteddeprecated | superseded.

FieldTypeConstraintRequiredDescription
@type string Fixed: "kg:Decision" REQUIRED JSON-LD type discriminator.
id string Pattern: ^ADR-\d{3}$ REQUIRED Unique identifier. Three-digit zero-padded number (e.g., ADR-001).
title string Non-empty REQUIRED Human-readable title of the decision.
status string Enum: "proposed" | "accepted" | "deprecated" | "superseded" REQUIRED Current lifecycle state.
date string Pattern: ^\d{4}-\d{2}-\d{2}$ REQUIRED Date the decision was recorded (ISO 8601 date).
context string Non-empty REQUIRED The situation or problem that motivates this decision.
decision string Non-empty REQUIRED The decision that was made.
rationale string Non-empty REQUIRED Why this decision was chosen over alternatives.
consequences [...string] At least one element REQUIRED Known consequences of the decision (positive or negative).
supersedes string Pattern: ^ADR-\d{3}$ OPTIONAL The ID of a previous decision this one replaces.
appliesTo [...{...}] List of open structs OPTIONAL Domain objects this decision applies to.
related {[string]: true} Struct-as-set OPTIONAL Cross-references to other entries by ID.
import "quicue.ca/kg/core@v0"

decisions: {
    "ADR-001": core.#Decision & {
        id:     "ADR-001"
        title:  "Use CUE for configuration"
        status: "accepted"
        date:   "2026-02-15"

        context:   "Need a type-safe configuration language."
        decision:  "Use CUE for all configuration and schema definitions."
        rationale: "CUE provides compile-time validation, unification, and a lattice-based type system."
        consequences: [
            "All config files are .cue, validated with cue vet",
        ]
    }
}

Insight (#Insight)

An Insight records a validated discovery worth preserving. Every insight MUST include at least one piece of evidence and an explicit confidence level, ensuring that knowledge is grounded in observable facts rather than assumption.

FieldTypeConstraintRequiredDescription
@type string Fixed: "kg:Insight" REQUIRED JSON-LD type discriminator.
id string Pattern: ^INSIGHT-\d{3}$ REQUIRED Unique identifier (e.g., INSIGHT-001).
statement string Non-empty REQUIRED The insight expressed as a declarative statement.
evidence [...string] At least one element REQUIRED Observable facts supporting the insight.
method string Enum: "cross_reference" | "gap_analysis" | "statistics" | "experiment" | "observation" REQUIRED How the insight was discovered (for reproducibility).
confidence string Enum: "high" | "medium" | "low" REQUIRED Current confidence level in the insight's validity.
discovered string Pattern: ^\d{4}-\d{2}-\d{2}$ REQUIRED Date the insight was first identified (ISO 8601 date).
implication string Non-empty REQUIRED What this insight means for the project or domain.
action_items [...string] OPTIONAL Concrete next steps prompted by this insight.
related {[string]: true} Struct-as-set OPTIONAL Cross-references to other entries by ID.
import "quicue.ca/kg/core@v0"

insights: {
    "INSIGHT-001": core.#Insight & {
        id:        "INSIGHT-001"
        statement: "CUE graph validation performance depends on topology, not node count"
        evidence: [
            "18-node/27-edge NHCF graph validates in 3.8 seconds",
            "17-node/25-edge greener-homes graph validates without issues",
            "Wide fan-in (high edge density) is the bottleneck, not node count",
        ]
        method:     "experiment"
        confidence: "high"
        discovered: "2026-02-10"

        implication: "Graph complexity should be managed by reducing fan-in, not by capping node count."
        action_items: [
            "Profile edge density before optimizing graph size",
        ]
    }
}

The confidence field is subject to the CUE lattice property: it can only be narrowed over time. An insight at "low" confidence MAY be updated to "medium" or "high" as evidence accumulates, but the type system prevents broadening a specific confidence back to a less specific value.

Rejected (#Rejected)

A Rejected entry documents an approach that was tried and failed, or was evaluated and dismissed. The alternative field is REQUIRED — every rejection MUST be constructive, pointing toward what to do instead. This design prevents the "we tried that and it didn't work" conversation loop by ensuring that dead ends always include a signpost to viable paths.

FieldTypeConstraintRequiredDescription
@type string Fixed: "kg:Rejected" REQUIRED JSON-LD type discriminator.
id string Pattern: ^REJ-\d{3}$ REQUIRED Unique identifier (e.g., REJ-001).
approach string Non-empty REQUIRED Description of the approach that was rejected.
reason string Non-empty REQUIRED Why the approach was rejected.
date string Pattern: ^\d{4}-\d{2}-\d{2}$ REQUIRED Date the rejection was recorded (ISO 8601 date).
alternative string Non-empty REQUIRED What to do instead. MUST be non-empty — forces constructive rejection.
related {[string]: true} Struct-as-set OPTIONAL Cross-references to other entries by ID.
import "quicue.ca/kg/core@v0"

rejected: {
    "REJ-001": core.#Rejected & {
        id:          "REJ-001"
        approach:    "Use SPARQL for cross-project knowledge querying"
        reason:      "Requires external infrastructure (triple store, query engine). Adds deployment complexity."
        date:        "2026-02-15"
        alternative: "Use CUE unification for federation. Zero infrastructure, conflict detection is free."
        related: {"ADR-002": true}
    }
}

Pattern (#Pattern)

A Pattern captures a reusable problem/solution pair in the tradition of Christopher Alexander's pattern language. The used_in field tracks which projects employ the pattern, using the struct-as-set idiom for O(1) membership testing and clean unification when federating across project boundaries.

FieldTypeConstraintRequiredDescription
@type string Fixed: "kg:Pattern" REQUIRED JSON-LD type discriminator.
name string Non-empty REQUIRED Human-readable name of the pattern.
category string Non-empty REQUIRED Classification category (e.g., "architecture", "data", "operations").
problem string Non-empty REQUIRED The problem this pattern addresses.
solution string Non-empty REQUIRED The solution approach.
context string Non-empty REQUIRED When and where this pattern applies.
example string OPTIONAL A concrete example of the pattern in use.
used_in {[string]: true} Struct-as-set REQUIRED Projects using this pattern. MUST contain at least the declaring project.
related {[string]: true} Struct-as-set OPTIONAL Cross-references to related patterns or entries.
import "quicue.ca/kg/core@v0"

patterns: {
    "struct-as-set": core.#Pattern & {
        name:     "Struct-as-Set"
        category: "data-modeling"
        problem:  "CUE arrays allow duplicates and lack O(1) membership testing."
        solution: "Use {[string]: true} for set-valued fields."
        context:  "Any field representing set membership (related, used_in, depends_on)."
        used_in: {
            "quicue-kg":       true
            "quicue-proxmox":  true
            "energy-retrofit": true
        }
    }
}

Extension Types

Extension types address domain-specific concerns that not all projects require. A conforming knowledge graph MAY include entries of extension types. Extension types are defined in the quicue.ca/kg/ext@v0 package and MAY import from core but core types MUST NOT import from extensions.

Derivation (#Derivation)

A Derivation records the provenance of a data pipeline output: what worker produced it, from what inputs, and how trustworthy the output is relative to canonical source data. This type supports audit trails for data engineering workflows where the distinction between original and computed data is significant.

FieldTypeConstraintRequiredDescription
@type string Fixed: "kg:Derivation" REQUIRED JSON-LD type discriminator.
id string Pattern: ^DERIV-\d{3}$ REQUIRED Unique identifier (e.g., DERIV-001).
worker string Non-empty REQUIRED The pipeline worker or process that produced the output.
output_file string Non-empty REQUIRED Path to the output file produced.
date string Pattern: ^\d{4}-\d{2}-\d{2}$ REQUIRED Date the derivation was performed (ISO 8601 date).
description string Non-empty REQUIRED What the derivation produced and why.
canon_purity string Enum: "pure" | "mixed" | "derived" REQUIRED Canon purity classification: pure = original source data; mixed = combination of source and computed; derived = fully computed from other data.
canon_sources [...string] At least one element REQUIRED Canonical data sources used as input.
non_canon_elements [...string] REQUIRED Elements in the output that are not from canonical sources (MAY be empty list).
action_required string Non-empty REQUIRED What action is needed regarding the derivation output.
input_files [...string] REQUIRED Files consumed as input (MAY be empty list).
record_count int ≥ 0 OPTIONAL Number of records in the output.
related {[string]: true} Struct-as-set OPTIONAL Cross-references to other entries by ID.

Context (#Context)

A Context entry is a project's identity card. It declares what the project is, what CUE module it belongs to, what patterns it uses, and what concepts it knows about. When projected to W3C vocabularies, a Context maps to a dcat:Dataset (see DCAT Projection).

FieldTypeConstraintRequiredDescription
@type string Fixed: "kg:Context" REQUIRED JSON-LD type discriminator.
@id string OPTIONAL IRI identifier for the project (used in JSON-LD exports).
name string Non-empty REQUIRED Human-readable project name.
description string Non-empty REQUIRED What the project does.
module string OPTIONAL CUE module path (e.g., quicue.ca/kg@v0).
repo string OPTIONAL Repository URL.
status string Enum: "active" | "experimental" | "archived" | "planned" REQUIRED Current project lifecycle state.
license string OPTIONAL SPDX license identifier.
cue_version string OPTIONAL Minimum CUE version required.
uses [...{...}] List of open structs OPTIONAL Patterns, frameworks, or libraries used by this project.
knows [...{...}] List of open structs OPTIONAL Concepts, domains, or vocabularies this project has knowledge of.
import "quicue.ca/kg/ext@v0"

project: ext.#Context & {
    "@id":        "https://quicue.ca/project/quicue-kg"
    name:         "quicue-kg"
    description:  "CUE-native knowledge graph framework"
    module:       "quicue.ca/kg@v0"
    status:       "active"
    license:      "Apache-2.0"
    cue_version:  "v0.15.3"
}

Workspace (#Workspace)

A Workspace maps the physical layout of a multi-repository project. Components describe each repository or directory with filesystem paths, symlinks, git remotes, and branch information. This type enables tooling to understand the topology of projects that span multiple repositories.

FieldTypeConstraintRequiredDescription
@type string Fixed: "kg:Workspace" REQUIRED JSON-LD type discriminator.
name string Non-empty REQUIRED Workspace name.
description string Non-empty REQUIRED What this workspace represents.
components {[string]: Component} Struct of named components REQUIRED Map of component name to component definition.
deploy struct Open struct OPTIONAL Deployment information (domain, container, host, path).

Each component within components has the following fields:

FieldTypeConstraintRequiredDescription
path string Non-empty REQUIRED Filesystem path to the component.
description string Non-empty REQUIRED What this component does.
symlink string OPTIONAL If this component is available via symlink, the target path.
module string OPTIONAL CUE module identifier.
git_remotes {[string]: string} OPTIONAL Map of remote name to URL.
branch string OPTIONAL Active git branch.

Components are open structs — additional domain-specific fields are permitted.

Aggregation

Aggregation types compute summary views and quality checks from raw knowledge graph entries. They are defined in the quicue.ca/kg/aggregate@v0 package and use CUE comprehensions to derive all computed fields. Aggregation views are never hand-maintained — they are recomputed on every cue eval invocation.

KGIndex (#KGIndex)

The KGIndex is the primary aggregation type. It collects all entries by type, computes summary counts, and derives cross-cutting views such as decisions grouped by status and insights grouped by confidence level.

FieldTypeComputedDescription
project string No (user-supplied) Project name. MUST be non-empty.
decisions {[string]: #Decision} No (user-supplied) Map of decision ID to Decision entry.
insights {[string]: #Insight} No (user-supplied) Map of insight ID to Insight entry.
rejected {[string]: #Rejected} No (user-supplied) Map of rejected ID to Rejected entry.
patterns {[string]: #Pattern} No (user-supplied) Map of pattern key to Pattern entry.
summary struct Yes Contains total_decisions, total_insights, total_rejected, total_patterns, and total (sum of all).
by_status struct Yes Decisions grouped by status. Keys: proposed, accepted, deprecated, superseded. Values: map of ID to title.
by_confidence struct Yes Insights grouped by confidence. Keys: high, medium, low. Values: map of ID to statement.
package kg

import "quicue.ca/kg/aggregate@v0"

index: aggregate.#KGIndex & {
    project: "my-project"

    decisions: decisions   // references from decisions.cue
    insights:  insights    // references from insights.cue
    rejected:  rejected    // references from rejected.cue
    patterns:  patterns    // references from patterns.cue
}

// Export: cue export .kg/ -e index.summary --out json

All fields within summary, by_status, and by_confidence are derived via CUE comprehensions. Adding an entry to the input maps automatically updates all computed views.

KGLint (#KGLint)

The KGLint type computes structural quality checks on a knowledge graph. It takes a populated #KGIndex as input and produces a list of lint results at varying severity levels.

FieldTypeDescription
index #KGIndex The knowledge graph index to lint.
results [...#LintResult] List of lint findings.

Each #LintResult contains:

FieldTypeDescription
level "error" | "warn" | "info" Severity of the finding.
code string Machine-readable lint rule identifier.
message string Human-readable description of the issue.
entry string OPTIONAL. The entry ID that triggered the finding.

The #KGLint type handles structural checks via CUE comprehensions (e.g., referential integrity of all known IDs). Temporal and heuristic checks (e.g., stale proposals older than 90 days, confidence level upgrade suggestions) are implemented in the CLI layer using jq over exported JSON.

W3C Projection Semantics

quicue-kg provides export projections from CUE-native types to W3C vocabularies, RDF serialization formats, and logic programming languages. These projections are one-way transformations: CUE is the source of truth, and external formats are interoperability surfaces. Each projection is a CUE type in the aggregate package that takes a #KGIndex as input and produces structured output (JSON-LD, RDF text, or logic programs).

All projections share the kg: namespace prefix, which resolves to https://quicue.ca/kg#.

PROV-O Projection (#Provenance)

The provenance projection maps knowledge graph entries to the [[PROV-O]] ontology, producing a machine-navigable audit trail of decisions.

Source (quicue-kg)Target (PROV-O)Semantics
#Decision prov:Activity The act of making a decision.
#Decision.decision prov:Entity (generated) The outcome produced by the decision activity.
#Decision.date prov:startedAtTime When the decision activity occurred.
#Decision.supersedes prov:wasInformedBy + prov:wasRevisionOf Supersession as provenance chain.
#Insight prov:Entity Discovered knowledge as provenance entity.
#Insight.method prov:Activity (generating) The discovery method as a generating activity.
project (from index) prov:Agent The project as the agent associated with decisions.
cue export .kg/ -e _provenance.graph --out json

The projection uses the following JSON-LD context:

{
  "prov":    "http://www.w3.org/ns/prov#",
  "dcterms": "http://purl.org/dc/terms/",
  "rdfs":    "http://www.w3.org/2000/01/rdf-schema#",
  "xsd":     "http://www.w3.org/2001/XMLSchema#",
  "kg":      "https://quicue.ca/kg#"
}

Web Annotation Projection (#Annotations)

The annotation projection maps insights and rejected approaches to the [[WEB-ANNOTATION]] data model. The two entry types map to different annotation motivations:

Source (quicue-kg)Target (Web Annotation)Semantics
#Insight oa:Annotation with oa:motivatedBy oa:commenting Commentary on the knowledge domain.
#Insight.statement oa:hasBody (oa:TextualBody) The annotation content.
#Insight.evidence kg:evidence within oa:hasBody Supporting evidence for the annotation.
#Insight.related oa:hasTarget The entries being annotated.
#Insight.action_items as:result (as:Note) Resulting action items as ActivityStreams notes.
#Rejected oa:Annotation with oa:motivatedBy oa:questioning Questioning a previous direction.
#Rejected.approach oa:hasBody (purpose: describing) What was rejected.
#Rejected.reason oa:hasBody (purpose: commenting) Why it was rejected.
#Rejected.alternative oa:hasBody (purpose: replying) The recommended alternative.
cue export .kg/ -e _annotations.graph --out json

DCAT Projection (#DatasetEntry, #FederatedCatalog)

The catalog projection maps knowledge graph metadata to the [[DCAT]] vocabulary. Each project with a .kg/ directory becomes a dcat:Dataset, and federation results become a dcat:Catalog.

Source (quicue-kg)Target (DCAT)Semantics
ext.#Context dcat:Dataset The project's knowledge graph as a dataset.
#Context.name dcterms:title Dataset title.
#Context.description dcterms:description Dataset description.
#Context.license dcterms:license License information.
CUE source (.kg/) dcat:Distribution (mediaType: application/cue) The CUE source distribution.
JSON-LD export dcat:Distribution (mediaType: application/ld+json) The JSON-LD export distribution.
Federation result dcat:Catalog Aggregation of multiple datasets.
# Single project dataset
cue export .kg/ -e _catalog.dataset --out json

# Federated catalog
kg fed ~/project-a/.kg/ ~/project-b/.kg/ --format dcat

N-Triples Projection (#NTriples)

The N-Triples projection produces the simplest possible RDF serialization: one <subject> <predicate> <object> . triple per line, with fully expanded IRIs (no prefixes). This format is greppable, sortable, and diffable — ideal for unix pipeline processing and bulk loading into any triplestore.

Source (quicue-kg)Target (RDF)Semantics
#Decision kg:Decision, prov:Activity Dual-typed: both a kg decision and a provenance activity.
#Insight kg:Insight, prov:Entity Dual-typed: both a kg insight and a provenance entity.
#Pattern kg:Pattern Pattern with skos:prefLabel for taxonomy interop.
ext.#SourceFile kg:SourceFile, prov:Entity Data source with origin and format metadata.
ext.#CollectionProtocol kg:CollectionProtocol, prov:Plan Data collection protocol as a provenance plan.
ext.#PipelineRun kg:PipelineRun, prov:Activity Pipeline execution with prov:used links to sources.
ext.#Derivation kg:Derivation, prov:Activity Derived output with canon purity tracking.
cue export .kg/ -e _ntriples.triples --out text
# Count triples by type
cue export .kg/ -e _ntriples.triples --out text | grep 'rdf-syntax-ns#type' | sort | uniq -c

# Find all provenance activities
cue export .kg/ -e _ntriples.triples --out text | grep 'prov#Activity'

Turtle Projection (#Turtle)

The Turtle projection produces human-readable RDF with @prefix declarations and subject grouping. It uses the same mappings as N-Triples but with compact prefixed names. The output is compatible with existing Turtle files in infra-ontology and can be loaded directly into Oxigraph or any SPARQL endpoint.

The document is organized by section: decisions, insights, patterns, sources, collection protocols, pipeline runs, and derivations. Each section uses standard RDF vocabularies (prov:, dcterms:, skos:, rdfs:) alongside the kg: namespace.

cue export .kg/ -e _turtle.document --out text

SKOS Taxonomy (#SKOSTaxonomy)

The SKOS projection maps the project's pattern categories to a skos:ConceptScheme and individual patterns to skos:Concept instances. Categories are top concepts; patterns are narrower concepts within their category. This produces a browsable taxonomy of the project's pattern language.

Source (quicue-kg)Target (SKOS)Semantics
Pattern categories skos:Concept (skos:topConceptOf) Category as a top-level concept.
#Pattern skos:Concept Pattern as a concept with skos:broader to its category.
#Pattern.name skos:prefLabel Preferred label.
#Pattern.problem skos:definition The problem the pattern solves.
#Pattern.solution skos:note The solution approach.
#Pattern.related skos:related Associative relationship between patterns.

The projection outputs both JSON-LD (_taxonomy.graph) and Turtle (_taxonomy.turtle). It also produces a summary with concept and category counts.

# JSON-LD concept scheme
cue export .kg/ -e _taxonomy.graph --out json

# Turtle for compatibility with existing SKOS files
cue export .kg/ -e _taxonomy.turtle --out text

Prolog Projection (#Prolog)

The Prolog projection generates facts and inference rules from knowledge graph entries. Unlike RDF projections that describe data, the Prolog projection makes knowledge computable: you can query transitive provenance chains, determine trust levels, and discover shared patterns across projects.

Facts are generated for each entry type. Rules encode inference logic:

RuleSemantics
contributed(Source, Deriv) Transitive provenance: which sources contributed to a derivation.
trust(Proto, Level) Trust level (high/medium/low) based on protocol authority rank.
most_authoritative(System, Proto) Most authoritative protocol for a given system.
shared_pattern(P, Proj1, Proj2) Patterns used in more than one project.
active_decision(Id) Decisions with status "accepted".
actionable(Id) High-confidence insights.
# Export Prolog program
cue export .kg/ -e _prolog.program --out text > kb.pl

# Query in SWI-Prolog
swipl -l kb.pl -g "shared_pattern(P, A, B), writef('%w shared by %w and %w\n', [P, A, B]), fail."

Datalog Projection (#Datalog)

The Datalog projection generates Soufflé-compatible Datalog programs. Unlike Prolog, Datalog always terminates — there are no function symbols, no cuts, no negation-as-failure cycles. This makes it safe for automated infrastructure queries at scale.

The program includes .decl relation declarations, .output directives for derived relations, facts from the knowledge graph, and the same inference rules as the Prolog projection. Soufflé compiles these to native C++ for high-performance evaluation.

# Export Soufflé-compatible Datalog
cue export .kg/ -e _datalog.program --out text > kb.dl

# Evaluate with Soufflé
souffle kb.dl

# Results are written to .csv files (one per .output relation)

JSON-LD Context

The kg: namespace resolves to https://quicue.ca/kg#. The full JSON-LD context document is defined in vocab/context.cue and SHOULD be served at https://quicue.ca/kg with content type application/ld+json.

The JSON-LD context provides the following mappings:

Namespace PrefixIRI
kg:https://quicue.ca/kg#
dcterms:http://purl.org/dc/terms/
prov:http://www.w3.org/ns/prov#
oa:http://www.w3.org/ns/oa#
dcat:http://www.w3.org/ns/dcat#
rdfs:http://www.w3.org/2000/01/rdf-schema#
xsd:http://www.w3.org/2001/XMLSchema#

The context also declares RDFS class hierarchy relationships:

cue export ./vocab -e context --out json > kg-context.jsonld

Federation Protocol

Federation is the process of discovering, merging, and querying multiple knowledge graphs across project boundaries. Unlike traditional knowledge management systems that require a shared ontology or a centralized query engine, quicue-kg federation uses CUE unification as its merge primitive. This means that conflicting assertions across projects are detected as type errors at build time.

Discovery

A conforming processor discovers knowledge graphs by performing a filesystem walk looking for the presence of .kg/cue.mod/module.cue. The discovery algorithm is:

  1. Walk the filesystem from a set of root directories.
  2. For each directory, check for the existence of .kg/cue.mod/module.cue.
  3. If found, the parent directory contains a knowledge graph.
  4. Validate the .kg/ directory with cue vet.
  5. If validation passes, include the knowledge graph in the federation set.
kg fed ~/project-a/.kg/ ~/project-b/.kg/ ~/project-c/.kg/

Merging

Federation merging uses CUE unification. When two knowledge graphs are unified:

The struct-as-set idiom ensures that set-valued fields (e.g., used_in, related) merge cleanly: the union of two sets {"a": true} and {"b": true} unifies to {"a": true, "b": true}.

Conflicts are features, not bugs. A type error during federation means two projects assert contradictory facts. The error message identifies the conflicting entries, requiring explicit human resolution.

Export

Federation results MAY be exported as a [[DCAT]] catalog using the #FederatedCatalog type. Each federated knowledge graph becomes a dcat:Dataset entry within a dcat:Catalog.

{
  "@context": {
    "dcat":    "http://www.w3.org/ns/dcat#",
    "dcterms": "http://purl.org/dc/terms/",
    "kg":      "https://quicue.ca/kg#"
  },
  "@type": "dcat:Catalog",
  "dcterms:title": "quicue Knowledge Graph Federation",
  "dcterms:description": "Federated catalog of CUE-native knowledge graphs",
  "dcat:dataset": [
    { "@type": "dcat:Dataset", "dcterms:title": "project-a", ... },
    { "@type": "dcat:Dataset", "dcterms:title": "project-b", ... }
  ]
}

Agent Integration

quicue-kg is designed to be consumed by autonomous software agents and tool-using agents operating within development workflows. This section specifies the interface contract between knowledge graphs and such agents.

Tool Interface

A conforming processor targeting agent integration SHOULD expose the following tool operations. Each operation corresponds to a kg CLI command and returns structured JSON.

Tool NameDescriptionReturns
kg_index Retrieve the full knowledge graph index. #KGIndex as JSON
kg_decisions List all decisions with status filtering. Array of #Decision
kg_rejected List all rejected approaches. Array of #Rejected
kg_insights List all insights with confidence filtering. Array of #Insight
kg_patterns List all patterns with category filtering. Array of #Pattern
kg_lint Run quality checks and return findings. Array of #LintResult
kg_query Execute a CUE expression against the knowledge graph. JSON result of the expression

Session Initialization

When an autonomous software agent begins a session in a project containing a .kg/ directory, the agent's runtime SHOULD automatically inject knowledge graph context. The RECOMMENDED initialization sequence is:

  1. Detect the presence of .kg/cue.mod/module.cue in the project.
  2. Run kg index to retrieve the current knowledge graph state.
  3. Run kg rejected to load all rejected approaches.
  4. Include the rejected approaches in the agent's working context.

This ensures the agent begins work with awareness of prior decisions and known dead ends, reducing the likelihood of proposing previously rejected solutions.

Anti-Hallucination Protocol

To prevent autonomous software agents from proposing solutions that have already been tried and rejected, the following protocol is RECOMMENDED:

  1. Before proposing a solution, the agent MUST query kg_rejected.
  2. If the proposed approach matches a rejected entry's approach field, the agent MUST acknowledge the prior rejection and explain why the new proposal differs or why circumstances have changed.
  3. If the agent cannot differentiate its proposal from a prior rejection, it SHOULD follow the alternative field from the rejected entry instead.

The rejected approach database functions as institutional memory. Its value scales with project age: a mature project may have dozens of documented dead ends that prevent cyclic re-exploration by both human developers and software agents.

Security Considerations

Sensitive Architectural Information

Knowledge graph entries MAY contain sensitive architectural decisions, such as security architecture choices, authentication strategy rationale, or infrastructure topology information. Implementors SHOULD consider the following:

Credential Prohibition

Knowledge graph entries MUST NOT contain credentials, secrets, API keys, tokens, or other authentication material. The .kg/ directory is designed for structural and architectural knowledge, not operational secrets.

A conforming processor SHOULD warn if entry content appears to contain credential-like patterns (e.g., strings matching common API key formats).

Federation Metadata Exposure

The federation protocol exposes project metadata across organizational boundaries. When federating knowledge graphs:

Organizations SHOULD establish federation policies that define which projects may be federated and with whom. The #Context.status field MAY be used to control federation eligibility (e.g., only federate "active" projects).

IANA Considerations

Media Type

The CUE source format used by .kg/ directories uses file extension .cue. As of publication, the CUE language does not have an IANA-registered media type. This specification uses application/cue as an informational media type identifier in DCAT distribution entries.

When exporting to JSON-LD, the standard media type application/ld+json SHOULD be used.

Namespace URI

The kg: namespace is bound to the URI https://quicue.ca/kg#. The JSON-LD context document SHOULD be served at https://quicue.ca/kg with content negotiation:

CUE Schema Reference

This appendix reproduces the normative CUE type definitions for reference. The canonical definitions are in the quicue.ca/kg@v0 module.

#Decision

// core/decision.cue
#Decision: {
    "@type": "kg:Decision"
    id:      =~"^ADR-\\d{3}$"
    title:   string & !=""
    status:  "proposed" | "accepted" | "deprecated" | "superseded"
    date:    =~"^\\d{4}-\\d{2}-\\d{2}$"

    context:      string & !=""
    decision:     string & !=""
    rationale:    string & !=""
    consequences: [...string] & [_, ...]

    supersedes?: =~"^ADR-\\d{3}$"
    appliesTo?:  [...{...}]
    related?:    {[string]: true}
}

#Insight

// core/insight.cue
#Insight: {
    "@type":    "kg:Insight"
    id:         =~"^INSIGHT-\\d{3}$"
    statement:  string & !=""
    evidence:   [...string] & [_, ...]
    method:     "cross_reference" | "gap_analysis" | "statistics" | "experiment" | "observation"
    confidence: "high" | "medium" | "low"
    discovered: =~"^\\d{4}-\\d{2}-\\d{2}$"

    implication:   string & !=""
    action_items?: [...string]
    related?:      {[string]: true}
}

#Rejected

// core/rejected.cue
#Rejected: {
    "@type":     "kg:Rejected"
    id:          =~"^REJ-\\d{3}$"
    approach:    string & !=""
    reason:      string & !=""
    date:        =~"^\\d{4}-\\d{2}-\\d{2}$"
    alternative: string & !=""
    related?:    {[string]: true}
}

#Pattern

// core/pattern.cue
#Pattern: {
    "@type":  "kg:Pattern"
    name:     string & !=""
    category: string & !=""
    problem:  string & !=""
    solution: string & !=""
    context:  string & !=""
    example?: string
    used_in:  {[string]: true}
    related?: {[string]: true}
}

#Derivation

// ext/derivation.cue
#Derivation: {
    "@type":            "kg:Derivation"
    id:                 =~"^DERIV-\\d{3}$"
    worker:             string & !=""
    output_file:        string & !=""
    date:               =~"^\\d{4}-\\d{2}-\\d{2}$"
    description:        string & !=""
    canon_purity:       "pure" | "mixed" | "derived"
    canon_sources:      [...string] & [_, ...]
    non_canon_elements: [...string]
    action_required:    string & !=""
    input_files:        [...string]
    record_count?:      int & >=0
    related?:           {[string]: true}
}

#Context

// ext/context.cue
#Context: {
    "@type":      "kg:Context"
    "@id"?:       string
    name:         string & !=""
    description:  string & !=""
    module?:      string
    repo?:        string
    status:       "active" | "experimental" | "archived" | "planned"
    license?:     string
    cue_version?: string
    uses?:        [...{...}]
    knows?:       [...{...}]
}

#Workspace

// ext/workspace.cue
#Workspace: {
    "@type":      "kg:Workspace"
    name:         string & !=""
    description:  string & !=""
    components: {[string]: {
        path:         string & !=""
        description:  string & !=""
        symlink?:     string
        module?:      string
        git_remotes?: {[string]: string}
        branch?:      string
        ...
    }}
    deploy?: {
        domain?:    string
        container?: string
        host?:      string
        path?:      string
        ...
    }
}

Complete Example

This appendix presents a minimal but complete .kg/ directory demonstrating all core types, a context entry, and an aggregation index.

package kg

import "quicue.ca/kg/core@v0"

decisions: {
    "ADR-001": core.#Decision & {
        id:     "ADR-001"
        title:  "Use CUE for configuration"
        status: "accepted"
        date:   "2026-01-15"

        context:      "Need a type-safe configuration language."
        decision:     "Use CUE for all configuration and schema definitions."
        rationale:    "CUE provides compile-time validation and a lattice-based type system."
        consequences: ["All config files are .cue, validated with cue vet"]
    }
}
package kg

import "quicue.ca/kg/core@v0"

insights: {
    "INSIGHT-001": core.#Insight & {
        id:         "INSIGHT-001"
        statement:  "CUE unification is sufficient for cross-project knowledge merging"
        evidence:   ["Successfully federated 5 .kg/ directories without conflicts"]
        method:     "experiment"
        confidence: "high"
        discovered: "2026-02-10"
        implication: "No external query engine needed for federation."
        related: {"ADR-001": true}
    }
}
package kg

import "quicue.ca/kg/core@v0"

rejected: {
    "REJ-001": core.#Rejected & {
        id:          "REJ-001"
        approach:    "Store knowledge graph in SQLite"
        reason:      "Adds runtime dependency. Loses CUE type safety. Cannot federate via unification."
        date:        "2026-01-10"
        alternative: "Use flat CUE files in .kg/ directory with cue vet for validation."
    }
}
package kg

import "quicue.ca/kg/core@v0"

patterns: {
    "struct-as-set": core.#Pattern & {
        name:     "Struct-as-Set"
        category: "data-modeling"
        problem:  "Arrays allow duplicates and lack O(1) membership testing."
        solution: "Use {[string]: true} for set-valued fields."
        context:  "Any field representing set membership."
        used_in: {"my-project": true}
    }
}
package kg

import "quicue.ca/kg/ext@v0"

project: ext.#Context & {
    name:        "my-project"
    description: "Example project with a knowledge graph"
    status:      "active"
    license:     "Apache-2.0"
}
package kg

import "quicue.ca/kg/aggregate@v0"

index: aggregate.#KGIndex & {
    project: "my-project"

    decisions: decisions
    insights:  insights
    rejected:  rejected
    patterns:  patterns
}
# Validate the knowledge graph
cue vet .kg/

# Export the summary
cue export .kg/ -e index.summary --out json
# Output: {"total_decisions":1,"total_insights":1,"total_rejected":1,"total_patterns":1,"total":4}

# Export decisions by status
cue export .kg/ -e index.by_status --out json
# Output: {"proposed":{},"accepted":{"ADR-001":"Use CUE for configuration"},"deprecated":{},"superseded":{}}

Design Rationale

This section is non-normative.

Why CUE?

CUE's lattice-based type system provides properties that are uniquely suited to knowledge management:

Why Constructive Rejection?

The #Rejected type requires an alternative field. This is a deliberate design constraint. A rejection without an alternative is a dead end with no signpost. By requiring a constructive alternative, every dead end becomes a redirect, reducing the cost of encountering it from "now what?" to "do this instead."

Why Struct-as-Set?

CUE arrays allow duplicates and have O(n) membership testing. The struct-as-set idiom ({[string]: true}) provides:

This pattern has been validated across 48+ patterns in production use.

Why Flat Directory?

CUE packages are directory-scoped. Files in subdirectories are treated as separate package instances, even if they declare the same package name. A file at .kg/decisions/adr-001.cue cannot reference values from .kg/index.cue — they are different packages. The flat directory requirement ensures all entries share a single package scope, enabling cross-referencing and aggregation.