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.
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:
cue CLI. No database, no server, no runtime dependency.This specification is intended for:
.kg/ knowledge graphs in their projects.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]].
A conforming knowledge graph is a .kg/ directory that:
package kg in all .cue files at the directory root.cue vet without errors when evaluated against the
quicue.ca/kg schemas..cue files in subdirectories (CUE packages
are directory-scoped; see Directory Layout).A conforming processor is a tool that:
@type field in all serialization formats..kg/ directory. Abbreviated as KG.{[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.pure (original source data), mixed (partially
derived), or derived (fully computed).
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)
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"
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:
cue mod tidy resolves
the quicue.ca/kg@v0 dependency automatically.CUE_REGISTRY='quicue.ca=ghcr.io/quicue/cue-modules,registry.cue.works'
and run cue mod tidy..kg/cue.mod/pkg/quicue.ca/kg/ pointing to a local checkout of the
quicue-kg repository.
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 & {
// ...
}
}
Within the flat .kg/ directory, entries SHOULD be organized by type into
separate files for readability. The RECOMMENDED file organization is:
| File | Contents | Status |
|---|---|---|
decisions.cue | All #Decision entries | RECOMMENDED |
insights.cue | All #Insight entries | RECOMMENDED |
rejected.cue | All #Rejected entries | RECOMMENDED |
patterns.cue | All #Pattern entries | RECOMMENDED |
project.cue | ext.#Context identity | OPTIONAL |
index.cue | aggregate.#KGIndex | RECOMMENDED |
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 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:
@type field with a fixed kg:-prefixed value for
JSON-LD compatibility.id field matching a type-specific pattern.related field using the struct-as-set idiom for
cross-referencing other entries.#Decision)
A Decision records an architecture decision with mandatory rationale,
following the Architecture Decision Record ([[ADR]]) methodology. Status transitions
follow a defined lifecycle: proposed → accepted →
deprecated | superseded.
| Field | Type | Constraint | Required | Description |
|---|---|---|---|---|
@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)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.
| Field | Type | Constraint | Required | Description |
|---|---|---|---|---|
@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)
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.
| Field | Type | Constraint | Required | Description |
|---|---|---|---|---|
@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)
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.
| Field | Type | Constraint | Required | Description |
|---|---|---|---|---|
@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 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)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.
| Field | Type | Constraint | Required | Description |
|---|---|---|---|---|
@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)
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).
| Field | Type | Constraint | Required | Description |
|---|---|---|---|---|
@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)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.
| Field | Type | Constraint | Required | Description |
|---|---|---|---|---|
@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:
| Field | Type | Constraint | Required | Description |
|---|---|---|---|---|
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 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)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.
| Field | Type | Computed | Description |
|---|---|---|---|
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)
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.
| Field | Type | Description |
|---|---|---|
index |
#KGIndex |
The knowledge graph index to lint. |
results |
[...#LintResult] |
List of lint findings. |
Each #LintResult contains:
| Field | Type | Description |
|---|---|---|
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.
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#.
#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#"
}
#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
#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
#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)
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
#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)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:
| Rule | Semantics |
|---|---|
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)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)
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 Prefix | IRI |
|---|---|
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:
kg:Decision — rdfs:subClassOf prov:Activitykg:Insight — rdfs:subClassOf prov:Entitykg:Rejected — rdfs:subClassOf oa:Annotationkg:Derivation — rdfs:subClassOf prov:Activitykg:Context — rdfs:subClassOf dcat:Datasetkg:Pattern — no W3C superclass (domain-specific)kg:Workspace — no W3C superclass (domain-specific)cue export ./vocab -e context --out json > kg-context.jsonld
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.
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:
.kg/cue.mod/module.cue..kg/ directory with cue vet.kg fed ~/project-a/.kg/ ~/project-b/.kg/ ~/project-c/.kg/
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.
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", ... }
]
}
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.
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 Name | Description | Returns |
|---|---|---|
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 |
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:
.kg/cue.mod/module.cue in the project.kg index to retrieve the current knowledge graph state.kg rejected to load all rejected approaches.This ensures the agent begins work with awareness of prior decisions and known dead ends, reducing the likelihood of proposing previously rejected solutions.
To prevent autonomous software agents from proposing solutions that have already been tried and rejected, the following protocol is RECOMMENDED:
kg_rejected.approach field,
the agent MUST acknowledge the prior rejection and explain why the new proposal
differs or why circumstances have changed.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.
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:
.kg/ directories committed to version control inherit the repository's
access control. If the repository is public, all knowledge graph entries are public.context and rationale fields of #Decision
entries may inadvertently expose threat models or security assumptions.#Workspace entries expose filesystem paths, git remote URLs, and
deployment topology — information useful for reconnaissance.
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).
The federation protocol exposes project metadata across organizational boundaries. When federating knowledge graphs:
used_in fields reveal which projects use which patterns.
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).
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.
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:
Accept: application/ld+json → the JSON-LD context document.Accept: text/html → this specification document.
This appendix reproduces the normative CUE type definitions for reference. The
canonical definitions are in the quicue.ca/kg@v0 module.
// 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}
}
// 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}
}
// 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}
}
// 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}
}
// 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}
}
// 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?: [...{...}]
}
// 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
...
}
}
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":{}}
This section is non-normative.
CUE's lattice-based type system provides properties that are uniquely suited to knowledge management:
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."
CUE arrays allow duplicates and have O(n) membership testing. The struct-as-set
idiom ({[string]: true}) provides:
{"a": true} & {"b": true} yields
{"a": true, "b": true}.This pattern has been validated across 48+ patterns in production use.
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.