Technical brief: how the ShurIQ and DKR system is actually built
This document describes the working system for an engineer-grade agent who has to build or write about it. It states which components run, which are specified and unbuilt, and what every named tool really does. Read it in place of any earlier description of this stack.
Verified against the vault on 2026-08-01. Style guide: Google developer documentation style.
Read this first: what this system is not
An earlier pass read the starred and forked repositories on the jonnydubowsky
GitHub account and treated them as the working stack. They are reference material
and abandoned experiments. graphify, knowledge-base-server-demo, obsidian-mcp,
SimpleMem, mempalace, and NexAU have no role here. Any instruction grounded
in them cannot be followed, because those tools are not installed and not called.
The work runs out of an Obsidian vault driven by Claude Code. The vault at
/Users/jonnydubowsky/Documents/totem-terminal/ holds the Markdown corpus, the
Python and Ruby scripts, the agent specifications, the skills, and about 40 Obsidian
Bases dashboards that read the frontmatter. There is no conventional application
repository holding this system. One production web app exists outside the vault
(Report Studio, described below), and it is the exception.
The three-layer knowledge model
Three things compose. Deciding which layer a piece of information belongs in is the most common judgment an agent makes here.
Layer 1: myKG, the producer and the typed store
myKG holds entities, typed edges, confidences, and attribute values. Typed
relationships live here and nowhere else. Every concept space in the vault emits a
myKG bundle of four files: nodes.jsonl, edges.jsonl, schema.json, and
knowledge_graph.ttl.
Put something in Layer 1 when it is a relationship with a type, a confidence score, a provenance chain, or an attribute value that a query has to filter on.
Layer 2: OKF, the portable container
OKF is the Open Knowledge Format, Google Cloud version 0.1, released 2026-06-12. A
bundle is a folder of Markdown files. Each file is a concept whose YAML frontmatter
has exactly one hard requirement: a non-empty type.
OKF links carry no edge type. Relationship meaning lives in prose. That poverty is the point on our side. A bundle cannot carry typed edges or second-order dynamics, so a bundle is a Layer 2 projection by construction.
Put something in Layer 2 when a teammate, a client, or an outside agent has to read it, and when losing the edge types costs nothing.
Layer 3: dotprompt, the verbs
A dotprompt input.schema is where an OKF record plugs into a model call, and
output.schema writes records back. Dotprompt is in production in the module
gallery at projects/shur/report-grammar/module-gallery/prompts/. The OKF Tier 2
enrichment pass uses one, projects/shur/okf/okf-concept.prompt.
Put something in Layer 3 when it is an operation over records rather than a record.
How the three relate
OKF does not replace myKG. If OKF were abandoned tomorrow the loss would be a serializer, and the typed store would be untouched.
The vault of Markdown files is the system of record. myKG is the typed graph derived
from it. OKF is how that travels. No vector database sits on the primary retrieval
path. The census of every place the agents look things up was taken on 2026-07-24 and
lives at projects/dkr-agency/concept-space-2026-07-24-retrieval-grammar/.
The export firewall
Three separate things protect a bundle that leaves the team. None of them is encryption, and OKF access-controls nothing on its own.
- The format cannot carry typed edges or second-order dynamics.
- A deliberate export projection chooses which types ship and which extension keys are allowed through.
- An authenticated rehydration endpoint sits behind the
resource:URIs.
Export-safe extension keys: shuriq_source_path, shuriq_source_type,
shuriq_source_sha256, shuriq_layer, shuriq_okf_generated, shuriq_rea_type,
shuriq_bmc_cell, shuriq_bmc_variant, shuriq_bundle_role.
Never exported: any key matching sbpi* or dkr_*, shuriq_confidence above the
concept level, and anything referencing typed edges or scoring internals.
The gate runs live. Verified 2026-08-01:
curl -s -o /dev/null -w "%{http_code}" https://okf-persona-gate.jonny-a6b.workers.dev/
# 200 -> open routes serve Layer 2
curl -s -o /dev/null -w "%{http_code}" https://okf-persona-gate.jonny-a6b.workers.dev/rehydrate/test
# 401 -> the deep model needs a bearer token
The OKF toolchain
Seven Python scripts at projects/shur/okf/. Dependencies: pyyaml, plus the local
claude CLI for the enrichment pass only. Every script is nondestructive: it writes
under a target directory and never modifies, renames, or moves a source document.
The versioned standard the scripts implement is projects/shur/okf/shuriq-okf-profile.md,
currently v0.5.1. It defines the type vocabulary, the extension keys, the guards, and
the conformance rules. The mirror passes the openknowledgeformat.com validator with
zero blocking errors.
okf_mirror.py, the document mirror
Tier 1, deterministic, no model call. Walks a document folder and writes one OKF
concept per .md into a parallel _okf/ bundle. Promotes title and description,
maps the source type: through a fixed table, hashes the source, and writes a
resource: pointer back. Idempotent through shuriq_source_sha256: an unchanged
source is skipped on a rerun.
python3 okf_mirror.py <source-root> [--okf-subdir _okf] [--dry-run]
python3 okf_mirror.py projects/fiserv
It skips _okf, _deploy, node_modules, .git, .wrangler, .letta,
.smart-env, viz-hub, review-site, faq-site, session-report-site,
site-editorial, and site, plus any directory ending in -site, _deploy, or
/deploy. Only .md becomes a concept. .ttl and .jsonl graph internals are
never read.
Filenames are slugged to lowercase and hyphens, because OKF warns on spaces. The
source keeps its real name and resource preserves the true path. A source named
INDEX.md or LOG.md maps to INDEX__doc.md so it cannot collide with the
generated index.md on a case-insensitive filesystem.
okf_extract_entities.py, the entity extractor
Tier 1, deterministic. Reads a myKG Obsidian-vault export, one .md per entity
grouped into class subfolders, and writes one OKF concept per qualifying entity into
_okf/entities/. Where the mirror serializes documents, the extractor serializes
entities.
python3 okf_extract_entities.py <mykg-vault> <target-root> \
[--subdir _okf/entities] \
[--min-confidence 0.6] \
[--map projects/<client>/okf-entity-map.yml] \
[--variant traditional|lean|temporal] \
[--overwrite-canonical] \
[--dry-run]
Each qualifying entity gets a shuriq_rea_type and a shuriq_bmc_cell derived from
a documented 21-row class map in DEFAULT_MAP. A class mapping to neither typing
stays in myKG and is not extracted. Five engine-state classes are in SKIP_CLASSES
and never extracted: OntologyNode, SimulationRun, MessageIntentProvenance,
ReactiveRequestLoop, CopyGateway. Entities below --min-confidence are skipped
and logged.
Hand-authored canonical concepts survive a merge. A file without
shuriq_okf_generated: true is never overwritten unless --overwrite-canonical is
passed.
shuriq_rea_type takes one of EconomicAgent, EconomicResource, EconomicEvent,
Commitment, Exchange. shuriq_bmc_cell takes one of the nine Business Model
Canvas cells. The two typings are orthogonal reads of the same node, and a concept
can carry both.
okf_enrich.py plus okf-concept.prompt, the Tier 2 pass
The only script that calls a model. It runs the okf-concept.prompt dotprompt
through the local claude CLI over concepts whose deterministic description and
intent came out weak, typically raw transcripts and meeting notes, and patches
those two fields. It reads the source and writes only the _okf concept file.
python3 okf_enrich.py <bundle-root> [--types Transcript,Meeting,Document] [--limit N] [--dry-run]
python3 okf_enrich.py projects/fiserv/_okf
--limit 0 means no limit. The subprocess call to claude has a 180 second timeout
and the response is parsed by brace-matching the first JSON object.
okf_persona_export.py, the firewall demonstration
Reads a Totem Persona entity vault once and writes two artifacts. The first is a
Layer 2 OKF bundle where related concepts appear as plain links with edge types,
confidence scores, and attribute values stripped. The second is the deep model,
deep.json plus layer2.json, consumed by the gated Cloudflare Worker and served
only with authorization. The contrast between the two is the firewall made concrete.
python3 okf_persona_export.py <vault-root> <bundle-out-dir> <serving-data-dir> \
[--base-url https://okf-persona-gate.example.workers.dev]
Tags encode untyped adjacency, the concept's own slug plus its linked-entity slugs,
so a static visualiser can draw real link structure without learning edge semantics.
resource: targets <base-url>/rehydrate/<id> rather than a vault:// pointer.
okf_viz.py, the static visualiser
Renders a bundle as one self-contained HTML constellation graph. D3 and the bundle data are inlined, so the file opens offline and makes no network request. Only Layer 2 concept metadata enters the payload.
python3 okf_viz.py <bundle-root> <out.html> [--d3 /tmp/d3.min.js]
Nodes are concepts colored by type. Edges prefer real intra-bundle Markdown links, which is OKF's native link mechanism. A pure document mirror carries no such links, so edges fall back to shared-tag co-occurrence with near-universal tags dropped.
okf_rea_sample.py and okf_tag_hints.py
okf_rea_sample.py <out-dir> generates a generic specialty-coffee value chain
bundle with five economic agents, three resources, and six events, used to
demonstrate REA join paths with no client data in it.
okf_tag_hints.py <bundle-root> is a deterministic post-pass. Some sources carry
their linkable structure in scalar frontmatter such as entity: or week: rather
than a tags: list, so their concepts render as isolated nodes. This script folds a
fixed allow-list of scalar keys into tags. The allow-list is entity,
entity_type, week, project, vertical, methodology.
The concept-space pattern
Concept-space research runs at projects/dkr-agency/concept-space-<ISO-date>-<slug>/.
Eleven exist as of 2026-08-01. The mature ones carry five directories.
| Directory | Holds |
|---|---|
intake/ |
The raw source note, with normal vault frontmatter |
analysis/ |
An InfraNodus text-network pass: clusters, structural gaps, and the new edges each gap produced |
mykg/ |
The typed bundle plus its deterministic builder |
_okf/ |
The Layer 2 mirror generated by okf_mirror.py |
site/ |
graph.json plus the published index.html |
The reference example is
projects/dkr-agency/concept-space-2026-07-23-agent-harnesses/. Read it before
building one.
site/graph.json
The hand-built graph, and the input to the myKG builder. Two arrays, nodes and
links. A node line:
{"id": "System:osaurus", "label": "Osaurus", "entity": "System"}
The id is <Entity>:<slug>. That convention is load-bearing: the myKG builder,
the TTL emitter, and the edge records all key on it.
mykg/nodes.jsonl
One JSON object per line. Properties are enriched by the builder from small membership sets rather than by a model.
{"id": "System:osaurus", "entity": "System", "label": "Osaurus", "props": {"origin": "external", "status": "evaluating"}}
mykg/edges.jsonl
One JSON object per line. Three keys, no weights and no confidences at this tier.
{"from": "System:osaurus", "rel": "provides", "to": "Primitive:mlx-local"}
mykg/schema.json
The typed schema for the space. Five top-level keys: name, version, created,
description, entities, relations, counts. Each entity class carries a
description and a properties list. relations is a flat sorted array of the
relation names actually used. counts records node and edge totals.
{
"name": "concept-space-agent-harnesses",
"version": "0.1.0",
"created": "2026-07-23",
"description": "Typed concept space for the 2026-07-23 agent-harness landscape research: ...",
"entities": {
"System": {
"description": "A running agent harness or model host, ours or external",
"properties": ["origin", "status"]
}
},
"relations": ["answers", "backs", "candidate_for", "provides", "runs"],
"counts": {"nodes": 41, "edges": 55}
}
The agent-harness space declares 11 entity classes, 27 relations, 41 nodes, and 55 edges. Entity classes and relations are per-space, not global. There is no closed vocabulary across concept spaces at this tier.
mykg/knowledge_graph.ttl
Two prefixes and one triple set. Class membership and label only.
@prefix cs: <https://shur.ai/ontology/concept-space#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
cs:System_osaurus a cs:System ; rdfs:label "Osaurus" .
The colon in a node id becomes an underscore in the TTL subject.
mykg/build_mykg.py
A per-space deterministic builder, roughly 100 lines, safe to rerun. It reads
../site/graph.json and writes all four myKG files. The entity definitions and the
property enrichment sets are literals at the top of the file, so the schema is
readable without running anything.
_okf/
Generated, never hand-edited. index.md lists each mirrored concept grouped by
source directory. Each concept file carries the profile frontmatter and a three-part
body: ## Intent, ## What this document is, and ## Sources. The body states what
the document is and points back. It never re-derives analysis and never narrates a
typed relationship.
SBPI
SBPI is the Structural Brand Power Index, the scoring layer over the competitive graph. It has two tiers and they are never merged.
- Tier 1 is universal brand health across five dimensions: Content Strength, Narrative Ownership, Distribution Power, Community Strength, and Monetization Infrastructure. It applies to any brand in any vertical.
- Tier 2 is a per-vertical rubric. A construction rubric and a medical rubric measure different things and their numbers are not comparable.
A client is always one row in a stack-ranked set of their vertical. A client is never scored alone.
The canonical dimension registry is
projects/shur/value-flows/sbpi-dimension-ontology-inventory.md, and it went to
status: approved under Schema-is-Law on 2026-07-27. Eight named scoring systems are
views over that one registry rather than eight registries.
Dimension weights, scoring formulas, rubric internals, and every client's scores are withheld from this document by policy. They are the Layer 1 material the export firewall exists to hold back. Do not ask for them and do not reconstruct them.
The semantic layer
shuriq_kg is a Python package at projects/shur/shuriq-kg/shuriq_kg/. It carries a
TripleStore abstract base class with five abstract methods: load_graph, query,
count, clear, and healthy.
Three concrete adapters implement it.
| Adapter | Backing store | Endpoint |
|---|---|---|
InMemoryRdflib |
rdflib.Dataset, zero infrastructure |
none |
OxigraphHTTP |
Oxigraph over SPARQL 1.1 | http://127.0.0.1:7878 |
GraphDBHTTP |
GraphDB over SPARQL 1.1 | http://localhost:7200/repositories/{repo} |
get_store(name, **kwargs) is the factory. It accepts memory, rdflib,
in-memory, in-memory-rdflib, oxigraph, or graphdb. Anything speaking SPARQL
1.1 Query, SPARQL 1.1 Update, and the Graph Store Protocol can join by writing one
more adapter class. The portability claim is that the same RDF and the same SPARQL
produce the same answers on any of the three, and examples/portability_demo.py
runs that proof.
The running default is Oxigraph. The CLI docstring records that GraphDB's licence
expired on 2026-05-22, so --target graphdb fails on a licence error until it is
renewed. Oxigraph is Apache-2.0 and needs no key. It is not left running: the nightly
pipeline starts it, uses it, and kills it on exit, so a human command has to start it
first.
~/.cargo/bin/oxigraph serve \
--location projects/microco/competitive-intel/semantic-layer/store \
--bind 127.0.0.1:7878
Named graphs follow https://shurai.com/graphs/{vertical}/{week}. In
shuriq_kg/cli.py the template is literal for the micro-drama vertical:
https://shurai.com/graphs/micro-drama/{week}. Weeks are ISO-style identifiers such
as W19-2026.
The CLI has four commands: ingest one week's state file, backfill the whole graph
from every archived week plus current, export the latest week back to a state file,
and portability to run the cross-store proof.
python -m shuriq_kg.cli ingest --state projects/microco/competitive-intel/state/current.json
python -m shuriq_kg.cli backfill --archive projects/microco/competitive-intel/state/archive \
--current projects/microco/competitive-intel/state/current.json
python -m shuriq_kg.cli portability --state projects/microco/competitive-intel/state/current.json --skip-graphdb
The store held 119,054 triples on 2026-07-29, up from 73,559 on 2026-03-23. The first
figure covers one vertical and the second covers two. shuriq_kg/decay.py computes
pairwise week-over-week decay metrics from those observations and writes them back as
a derived named graph. The nightly pipeline runs at 06:13 and has written 127 dated
result sets since 2026-03-21.
What DKR means here
DKR is Engelbart's Dynamic Knowledge Repository: a body of knowledge continuously
developed, integrated, and applied. The agent is the harness, the knowledge graph is
the territory, and intent is the fuel. The canonical statement is
projects/dkr-agency/DKR-SYNTHESIS-OUTLINE.md, and the operations manual is
projects/dkr-agency/guides/DKR-OPERATIONS-GUIDE.md.
The governing model is Argyris and Schon: Governing Variable, then Action Strategy, then Consequences. Single-loop correction adjusts the strategy. Double-loop correction interrogates the governing variable itself. Large platforms build a profile about a person and never let them edit the governing variables. DKR puts those variables in the person's hands.
The DKR agent works on the quality and structure of what a person knows. It is a different tier from a personal assistant that handles items and deadlines.
Scout, the discovery agent, uses negative-space methodology. It asks what we are not discussing rather than what we know, across four question types: absence, bridge, decay, and contradiction.
What runs today versus what is specified
| System | Where | State on 2026-08-01 |
|---|---|---|
| ShurIQ Report Studio | ~/Documents/projects/shuriq-report-studio/, deployed to shuriq-report-studio.pages.dev |
Production. Vite, React, TypeScript, Cloudflare Pages Functions, D1, Anthropic SDK. Production branch is main |
| Report Engine managed agent | Anthropic managed agent agent_01Uj1TbRtS5jAbLGNzpyKrT5 |
Live since 2026-05-29 |
| Semantic layer | projects/shur/shuriq-kg/, Oxigraph store |
Live. 119,054 triples on 2026-07-29 |
| Nightly SBPI pipeline | Scheduled, 06:13 | Live. 127 result sets since 2026-03-21 |
| OKF toolchain | projects/shur/okf/ |
Live. Seven scripts |
| OKF persona gate | https://okf-persona-gate.jonny-a6b.workers.dev |
Live. Verified 200 open, 401 gated on 2026-08-01 |
| Content series pipeline | content/build.rb and content/publish.rb, deployed to content-series-b6l.pages.dev |
Live. 14 series directories, 13 registered, 91 lessons |
| Slack agent | projects/shur/slack-agent/, channel #shur-iq |
Live. Python package with Docker compose and tests |
| Concept spaces | projects/dkr-agency/concept-space-*/ |
Live. 11 exist |
grammar-gate.py |
projects/shur/report-grammar/grammar-gate.py |
Built and used by hand. Not in CI, because no CI exists |
route-gate.py |
projects/shur/dev-sprint-1/monorepo-seed/gates/route-gate.py |
Built, selftest passing. Not in a repository and not in CI |
| Monorepo | Specified only | Does not exist. No repository has been created |
| Jira | Specified only | Does not exist. No site, no project, no board |
| Template gates | Specified only | Not written |
| Route declarations | Specified only | Zero exist as files |
The engineering state is covered in full by the companion document DEV-SETUP-STATE.md.
The tools genuinely in the loop
- Obsidian. The vault is the system of record. About 40
.basedashboards read the frontmatter, so the schemas atsystem/agents/claude/SCHEMA-REFERENCE.mdare enforced as law. - Claude Code. The harness. Skills, agent specifications, and slash commands live
in the vault and in
~/.dotfiles/ai/skills/. - InfraNodus. Text network analysis and knowledge graphs, reached over MCP and
over REST. Every concept space has an InfraNodus pass in
analysis/. - DEVONthink. Document store, reached over MCP.
- mem0 and OpenMemory. Semantic recall over a REST endpoint on port 8765.
- Cloudflare Pages and Workers. Every deploy.
- Oxigraph. The running triple store. GraphDB is a supported target with an expired licence.
- Excalidraw. Diagrams.
Writing and quality gates
Three gates apply to anything a person reads.
grammar-gate.py
A deterministic banned-term check at projects/shur/report-grammar/grammar-gate.py,
162 lines, no model calls.
grammar-gate.py <dir-or-file> [<dir-or-file> ...] [--also <extra-banned.txt>] [--quiet]
It extracts rendered text from HTML, dropping comments, <script>, <style>, then
all tags and entities, and greps banned-terms.txt. That file holds 32 rules in the
form TIER|||regex|||hint, 20 at BLOCK and 12 at WARN. A BLOCK hit exits 1, so
a deploy hook can refuse to ship. A grammar-allow.txt in a checked directory
exempts occurrences whose surrounding 45 characters of context contain one of its
lines.
Known coverage gap, found 2026-07-30: the directory walk globs *.html only, so
every Markdown document is ungated by construction. Markdown files must be passed by
path, and the rules are applied by hand until the gate is extended.
It exists because a language model reading prose asserts a pass by reading rather than measuring, and misses enumerable terms every time.
The megaeval
shuriq-megaeval is a multi-agent voice and grammar check on a built report: six
auditors, one fix ledger, editing passes, adversarial verification to zero findings,
then a Playwright check and a redeploy. It is mandatory before anything ships
externally. A build passing its own linters is not sufficient and has shipped defects
twice.
The style registry
projects/shur/report-grammar/STYLE-REGISTRY.md, active since 2026-07-30, maps each
kind of writing to a reader, a style guide, and a gate.
| What we write | Who reads it | Style guide | Gate |
|---|---|---|---|
| Client reports and briefs | Client executives | House voice canon | megaeval plus grammar-gate.py |
| Memos to a named person | That person | House voice canon | grammar-gate.py |
| Technical documentation, architecture, build plans, READMEs, specs | Whoever builds it | Google developer documentation style | Pending |
| Plans and handoffs the team reads | Whoever runs the work | Google developer documentation style, plain English first | Pending |
| Handoffs written for an agent to execute | An agent | None required. Say so in the document | None |
| Slack messages | The channel | Plain English, Slack mrkdwn | Read it aloud before sending |
Two rules bind every document. Name a reader, because audience: internal says who
may see a document and nothing about how to write it. Open with two or three
sentences saying what the thing does and who it is for, before any architecture,
decision list, or table.
The hard rules the gates enforce: full ISO dates, never a month name or a quarter with a year. No em-dashes. No inversion rhetoric of the "not X, but Y" shape. No consulting abstraction the reader cannot point to. One thought per sentence. Each point said once.
Where the concept writing lives
Published and drafted concept posts are at
content/series/<series>/pathways/<NN-pathway>/<NN-slug>.md. content/build.rb
builds the site and content/publish.rb orchestrates it with the subcommands site,
list, show, status, schedule, prep, and mark. The field reference is
content/series/README.md. Deploys go to https://content-series-b6l.pages.dev.
Counted 2026-08-01: 14 series directories, 13 of them in _registry.yml, 27 pathway
directories, and 91 lessons at 6 published, 16 ready, 69 draft.
The densest correct explanation of the architecture is the 08-composite-intelligence
pathway of the shuriq-concept-flywheel series, eight lessons running from intake as
ontology induction, through REA as a value grammar and BMC as a canvas grammar, to
SBPI as the scoring pass, OKF as the shared substrate, Totem Persona as portable
identity, and active notes where rules live with knowledge.
Confidentiality
ShurIQ is in stealth. Do not name the product or the framework in public material.
Describe it by capability. The GitHub organization slug shuriq-lab is an accepted
exception, decided 2026-07-28.
Client artifacts never expose internal methodology, system vocabulary, or self-audit. Content produced for a client publishes under that client's account.