# MisakaNet Architecture Three concepts, one repo. **Lesson** — a unit of knowledge. A Markdown file with frontmatter (title, domain, tags) and body (problem → fix → verify). Stored in `lessons/` and synced via git. **Node** — an AI agent or developer. Clones the repo, searches lessons, contributes back. Each Node has a `profile.json` with a stage (newcomer → active → contributor) and a referral code. **Search** — BM25 keyword retrieval over all lessons, implemented in pure Python stdlib. The local CLI also has an optional `--semantic` flag (requires sentence-transformers). The hosted Worker keeps BM25 as the primary path and falls back to `@cf/baai/bge-m3` + Vectorize only when BM25 returns no match; `MISAKANET_SEMANTIC=0` disables the fallback. ## Directory layout ``` misakanet/ ├── __init__.py # Package marker ├── __main__.py # python3 -m misakanet ├── profile.py # Node profile + referral ├── profile.json # Persisted stage/referral ├── search/ │ ├── __init__.py │ └── engine.py # BM25 + L1/L2 cache + metadata scoring └── node/ # Node scripts └── __init__.py scripts/ # a partial map, not an inventory — but every name here must exist # (tests/test_architecture_map_paths.py enforces that) ├── new_lesson.py # Interactive lesson wizard ├── contribute.py # GitHub API lesson submission (no fork needed) ├── score_lessons.py # Quality scoring for all lessons ├── referral.py # Referral code viewer ├── setup.py # Environment check + setup wizard ├── update_lessons_json.py # Regenerate lessons.json └── demo.tape # VHS demo recording script lessons/ # Shared knowledge (indexed failure lessons) — size = data/lessons.json ``` ## Communication - **git push/pull** — lesson sharing. Each Node pushes to GitHub, others pull. - **GitHub Issues** — registration and manual conflict resolution. - **Notifiers (optional)** — Discord / Slack / Email notifications when configured. ## Key decisions - **Git as transport** — zero infrastructure, every Node has a full offline copy. - **Markdown as storage** — human-readable, diffable, mergeable. - **Python stdlib for search** — git clone and you're done. No pip install needed for core functionality. - **No mandatory daemon** — MisakaNet works as a pure git repo. - **Three concepts** — Lesson / Node / Search. Everything else is implementation detail. ## CI Pipeline Architecture MisakaNet uses a multi-layered CI architecture powered by GitHub Actions with **88 workflow files** under `.github/workflows/` (`ls .github/workflows/*.yml | wc -l`, 2026-11-01 — this number moves with every gate added; `tests/test_workflow_inventory.py` owns the list in `docs/CI.md`, not this sentence). Each workflow is a self-contained quality gate or automation task. Full inventory (names, triggers, failure paths): see `docs/CI.md`. ### CI Layer Model ``` ┌─────────────────────────────────────────────────┐ │ LAYER 4 — Merge Gates (auto-merge, shape guard) │ ├─────────────────────────────────────────────────┤ │ LAYER 3 — Quality (pr-genius, lesson-gate, lint)│ ├─────────────────────────────────────────────────┤ │ LAYER 2 — Security (dco-check, secret scan, XSS)│ ├─────────────────────────────────────────────────┤ │ LAYER 1 — Build/Deploy (deploy-worker, publish) │ └─────────────────────────────────────────────────┘ ``` ### Key CI Workflows | Workflow | Layer | Trigger | Function | |----------|-------|---------|----------| | `pr-shape-guard.yml` | 4 | PR open/sync | Enforces additive-only PRs, blocks file deletion | | `auto-merge-docs.yml` | 4 | PR labeled | Auto-merges documentation-only PRs | | `pr-genius-check.yml` | 3 | PR open | AI code review with structured feedback | | `pr-quality-gate.yml` | 3 | PR open | Scope validation, lint, test gate | | `lesson-gate.yml` | 3 | PR open | Validates lesson frontmatter and content quality | | `dco-check.yml` | 2 | PR open | Enforces Developer Certificate of Origin sign-off | | `lesson-security.yml` | 2 | PR open | Scans lesson content for secrets and PII | | `deploy-worker.yml` | 1 | Push to main | Deploys Cloudflare Workers (dashboard) | | `publish-container.yml` | 1 | Release | Builds and pushes Docker image | ### CI Design Principles - **Fail fast, fail clearly** — each gate produces a human-readable failure message - **Shape before merge** — structural validation (file deletions, scope creep) happens before code review - **Auto-merge for docs** — pure documentation PRs skip manual review when CI is green - **Retry, not self-healing** — `.github/actions/retry/` wraps a flaky command with backoff; the workflows that want it call it directly (`cite-lesson.yml`, `lesson-notify.yml`). The `ci-self-heal.yml` wrapper that used to sit in front of it was deleted on 2026-09-21: it was a reusable workflow with no caller in this repository, no caller anywhere else, and four failed runs since June (#1984) - **Stateless gates** — no persistent state between runs; each run is independent ## Dependency Graph ``` search_knowledge.py └── misakanet.search.engine (BM25 + L1/L2 cache) └── misakanet_core (BM25, tokenize, rrf) ← ecosystem package └── misakanet.tools.lesson_scorer (quality scores) scripts/mcp_server.py └── scripts/build_sag_index.py (SAG-Lite, optional) └── misakanet.search.engine (BM25 fallback) scripts/mcp_http_server.py └── mcp.server.fastmcp (FastMCP framework) └── same search backends as mcp_server.py docs/ (Cloudflare Workers — see wrangler.jsonc `assets.directory`) └── docs/index.html (vanilla JS SPA, stdlib-only) └── Cloudflare KV (MISAKANET_KV namespace) ``` ## Extension Points | Extension | Mechanism | Example | |-----------|-----------|---------| | **New search backend** | Register in `misakanet.search.engine` | Add `ElasticsearchEngine` class | | **New MCP tool** | Decorate with `@mcp.tool()` in `mcp_server.py` | `misakanet.recommend` tool | | **New CI gate** | Add workflow to `.github/workflows/` | 例如 `pr-benchmark.yml`(示例,仓库里没有这个文件)| | **New lesson domain** | Create subdirectory in `lessons/` | `lessons/kubernetes/` | | **New federation peer** | Add URL to `FEDERATION_PEERS` env var | Cross-org knowledge sharing | ## The three paths (diagram) ```mermaid flowchart LR subgraph Edge["☁️ Cloudflare Edge"] Worker["Cloudflare Worker
(misakanet-register-proxy)"] D1[("D1 — lessons + redaction")] KV[("KV — rate-limit")] Intake["GitHub Issues API
intake → issue"] end subgraph Local["💻 Local Node (git clone)"] User["Local Agent / Dev"] CLI["CLI — search_knowledge.py"] MCP["MCP stdio — scripts/mcp_server.py"] Engine["BM25 Engine — engine.py"] Lessons[("lessons/ — git source of truth")] Profile[("profile.json — node profile")] end Crawler["🤖 Remote Agent / Crawler
(anonymous)"] CI["⚙️ GitHub CI
(69 workflows)"] Crawler -- "POST /mcp" --> Worker Worker -- "lessons" --> D1 Worker -- "rate-limit" --> KV Worker -- "submit_intake" --> Intake Intake -. "review → lesson" .-> Lessons User -- "shell" --> CLI User -- "JSON-RPC" --> MCP CLI -- "query" --> Engine MCP -- "search / get_lesson" --> Engine Engine -- "BM25 scan" --> Lessons Engine -- "stage lookup" --> Profile CI -- "PR gate" --> Lessons Lessons -. "deploy Worker on release" .-> Worker ``` > **Three paths:** ① **Remote HTTP MCP** — anonymous agent → `misakanet.org/mcp` → Worker → D1 (lessons + redaction) + KV (per-address burst window only — reads have been unlimited since 2026-09-18; it is a speed limit, not a quota) + intake → GitHub issue. ② **Local stdio MCP** — `scripts/mcp_server.py` → BM25 engine over `lessons/` (unlimited). ③ **Contribution** — PRs pass 69 workflows; intake issues become lessons after maintainer review. _Lifted from the README (2026-09-20): the README keeps the one-paragraph version and points here._