System Design · How it all fits together

Architecture & Information Flow

From a single source of truth to a published, navigable knowledge graph — and a three-phase contribution loop that lets anyone add content, with human review at every gate.

Phase 1 · GitHub-issue submission Phase 2 · Account-free proxy Phase 3 · AI promotion agent all live · verified 2026-06-27

The whole loop

Source builds the graph; the graph powers the site; people read it and contribute back; you approve; the agent promotes — and it's live again. One closed loop.

              DBA KNOWLEDGE BASE — ARCHITECTURE & INFORMATION FLOW   (all phases LIVE)

  LEGEND:   [LIVE]   [FUTURE]      ──► data flow      ═╌► deliberate human gate


╔══════════════════════════════════════════════════════════════════════════════════╗
║ 1 · SOURCE OF TRUTH        git repo  bundle/*.md                          [LIVE]   ║
║   6 courses · 74 sessions · 23 concepts · 4 references · 11 assignments = 118 nodes ║
║   each node = Markdown + YAML front-matter, cross-linked by relative .md paths      ║
╚════════════════════════════════════════╤═══════════════════════════════════════════╝
                                          │  tools/build_bundle.py  (md → parse → edges)
                                          ▼
                            ┌───────────────────────────────┐
                            │  bundle.json  {nodes, edges,  │  [LIVE]  118 nodes / 1,121 edges
                            │   bodies, types, palette}     │
                            └──────┬─────────────────┬──────┘
                 tools/gen_viz_v2  │                 │  copied →  docs/kb-data.json
                                   ▼                 ▼
╔══════════════════════════════════════════════════════════════════════════════════╗
║ 2 · PUBLISHED SITE       GitHub Pages (static, served from docs/)         [LIVE]   ║
║   index.html · map.html (Cytoscape graph) · okf-explained · vision                 ║
║   ask.html  ──►  kb-tools.js  (8 read-only tools)  ──►  tutor backends:            ║
║                  search·node·related·outline·concept·rubric·path·cite              ║
║                  1. BYO Gemini key  →  2. on-device Nano  →  3. keyword search      ║
║   contribute.html ──► the intake form (dedup · size · PII · honeypot)              ║
╚════════════════════════════════════════╤═══════════════════════════════════════════╝
                                          │
        ════════════════  CONTRIBUTION  →  REVIEW  →  PROMOTE  LOOP  ════════════════
                                          │
   CONTRIBUTOR fills contribute.html      ▼
        │
        ├──── PHASE 1 ─────────────────────────────────────────────────────  [LIVE]
        │   pre-filled GitHub issue  ═╌►  signs in, clicks Submit
        │        └─►  PUBLIC repo issue (labels: contribution, needs-review)
        │
        └──── PHASE 2 · account-free ──────────────────────────────────────  [LIVE]
            Turnstile CAPTCHA
                 │  POST (JSON + file as base64)
                 ▼
            Cloudflare Worker   dba-kb-contrib.dba-kb.workers.dev
              fail-closed captcha · per-IP rate-limit · validate · sanitize
                 │  one scoped token (cannot touch main)
                 ▼
            PRIVATE inbox repo   dba-kb-contrib-inbox
              · issue (review queue)   · raw file → inbox/<refid>/<file>
              · returns reference ID   (nothing public yet)
                                          │
                                          ▼
        ┌─────────────────────────────────────────────────────────────────────────┐
        │  REVIEW GATE      you read the inbox issue + file        ═╌►   [LIVE]     │
        │  approve (run the agent)   ·   reject (close the issue)                   │
        └───────────────────────────────┬─────────────────────────────────────────┘
                                         │  approve
                                         ▼
        ┌──── PHASE 3 · promotion agent ──  tools/promote.py  ──────────  [LIVE] ──┐
        │  fetch issue+file ─► catalogue of 118 node ids ─► Gemini 3.5-flash       │
        │  (PDF inline/multimodal) ─► STRICT JSON {title,desc,tags,body,related}    │
        │  ─► validate (links ⊆ catalogue, never invent) ─► synthesise (not copy)  │
        │  ─► write bundle/<dir>/<slug>.md ─► rebuild (+1-node assertion)          │
        │  ─► branch + PR on the public repo                                       │
        └───────────────────────────────┬─────────────────────────────────────────┘
                                         │  PR
                                         ▼
        ┌─────────────────────────────────────────────────────────────────────────┐
        │  MERGE GATE      you review the PR's .md node, click Merge   ═╌►  [LIVE]  │
        └───────────────────────────────┬─────────────────────────────────────────┘
                                         │  merge
                                         ▼
                       back to  ①  SOURCE  →  Pages rebuilds  →  live in map + tutor
                       (loop closed — contributor credited by name)


  [FUTURE]  optional GitHub Action: trigger promote.py on an `approved` label →
            unattended drafting (you'd still merge the PR). Build only when volume justifies.
──► data flow ═╌► deliberate human gate [LIVE] built & operational [FUTURE] optional, deferred

What's live

Every phase is built, deployed, and verified. The only deferred item is unattended automation — deliberately, until contribution volume justifies it.

StageStatusWhat it is
Source → build → siteLIVEbundle/*.md → build_bundle.py → bundle.json → gen_viz_v2.py → map.html, served on GitHub Pages.
Ask the KB (tutor)LIVE8 read-only tools in kb-tools.js; backends fall back BYO-key → on-device → keyword search.
Phase 1 — issue submissionLIVEThe form pre-fills a GitHub issue on the public repo. Needs a GitHub login.
Phase 2 — account-free proxyLIVETurnstile → Cloudflare Worker → private inbox repo (issue + raw file). No login; nothing public until approved.
Phase 3 — promotion agentLIVEtools/promote.py synthesises an approved submission into an OKF node (Gemini 3.5-flash) and opens a PR.
Unattended automationFUTUREAn optional GitHub Action to run the agent on an approved label — you'd still merge the PR.

The two human gates

Everything between these is automated. The gates are deliberate — content is published only when a person decides.

Gate 1 · Review

Approve the submission

You read the inbox issue and its file in the private repo. Approve by running the promotion agent; reject by closing the issue. Nothing reaches the public KB at this stage.

Gate 2 · Merge

Merge the pull request

The agent drafts a PR with the synthesised node (regenerated artifacts collapsed in the diff). You review the Markdown node and merge — the merge is what publishes. Pages rebuilds and it's live.

Components

Five moving parts, each with a single responsibility.

Source & build

OKF Markdown in bundle/ → graph JSON via build_bundle.py; the map via gen_viz_v2.py.

Published site

Static GitHub Pages — home, knowledge map, the AI tutor, and the contribution form.

Account-free proxy

A Cloudflare Worker behind Turnstile that records submissions into a private inbox using one scoped token.

Private inbox

A separate private repo holding the review queue (issues) and raw uploads under inbox/<refid>/.

Promotion agent

tools/promote.py — synthesises approved content into a cross-linked node and opens a PR for approval.