Technical brief

projects/dkr-agency/concept-space-2026-08-01-video-corpus/manus-pack/TECHNICAL-BRIEF.md

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.

  1. The format cannot carry typed edges or second-order dynamics.
  2. A deliberate export projection chooses which types ship and which extension keys are allowed through.
  3. 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.

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

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.