================================================================================
SDOA MCP — HYBRID PIPELINE ARCHITECTURE PLAN
Constraint-Solver × Graph-Driven × State-Machine
Version: 1.0  |  Date: 2026-06-17  |  Status: PRE-IMPLEMENTATION
================================================================================

This document is the complete pre-code plan for the SDOA MCP server.
No code is written until this plan is confirmed.

All four architecture decisions are locked:
  [1] TOOL GRANULARITY  — one coarse-grained tool per pipeline phase
  [2] STATE PERSISTENCE — checkpointed SQLite (not raw JSON)
  [3] INPUT SURFACE     — directory | single file | module ID
  [4] CONSTRAINT SCOPE  — all SDOA rules including v4.1 line-limit amendment

================================================================================
SECTION 1 — AVAILABLE TOOL INVENTORY
================================================================================

1A. LOCAL LLM MODELS (Ollama @ localhost:11434)
--------------------------------------------------------------------------------
  codellama:latest     3.8 GB   Specialized code generation
  llama3.2:latest      2.0 GB   General purpose, fast reasoning
  nomic-embed-text     274 MB   Semantic search & embeddings
  llama3:8b            4.7 GB   Advanced reasoning, instruction following

1B. MCP SERVERS (from Antigravity CLI plugins)
--------------------------------------------------------------------------------
  context7             resolve-library-id, get-library-docs
  firecrawl            scrape, map, search, feedback (+16 more)
  github               create/update files, search repos, push files (+21 more)
  notebooklm           ask_question, add/list/get notebooks (+15 more)
  playwright           navigate, click, fill, screenshot, codegen (+28 more)
  sentry               whoami, find_orgs, find_projects, find_releases (+17 more)
  sequential_thinking  sequentialthinking
  sqlite               read_query, write_query, create_table, list_tables

1C. CLIs AVAILABLE IN PATH
--------------------------------------------------------------------------------
  agy      Antigravity CLI
  ollama   Local inference engine
  claude   Anthropic CLI
  gemini   Google Gemini CLI

1D. PYTHON AI SDKS (globally installed)
--------------------------------------------------------------------------------
  huggingface_hub  v0.36.2
  openai           v2.34.0
  transformers     v4.52.0.dev0

1E. IDE — ANTIGRAVITY (VS Code fork — .vsix extension model confirmed)
--------------------------------------------------------------------------------
  Ghost 0.1.4           Terminal intelligence powered by Ollama
  Seshat 0.1.0          Gemini AI bridge
  SonarQube 5.3.0       Code quality and security analysis
  ESLint 3.0.24         JavaScript linting
  Error Lens 3.28.0     Inline error diagnostics
  GitLens 18.1.0        Git history + blame
  Playwright (browser)  Available via MCP for test automation

1F. NODE PACKAGE DEPENDENCIES (to install)
--------------------------------------------------------------------------------
  @modelcontextprotocol/sdk    MCP server protocol + stdio transport
  graphology                   Directed graph engine
  graphology-algorithms        Cycle detection, topo sort, reachability
  zod                          Schema validation for tool inputs/outputs
  better-sqlite3               Synchronous SQLite bindings for Node.js
                               (supplements the sqlite MCP for in-process writes)

================================================================================
SECTION 2 — MODEL ROUTING STRATEGY
================================================================================

Each pipeline phase is assigned the optimal local model. Models are called
via Ollama REST API (http://localhost:11434/api/generate).

  PHASE       MODEL                REASON
  ---------   ------------------   -----------------------------------------------
  ANALYZE     llama3.2:latest      Fast pattern recognition, manifest extraction
  MAP         llama3.2:latest      Graph reasoning, dependency inference
  REUSE       nomic-embed-text     Semantic similarity over module embeddings
              + llama3.2           Final reasoning: does this module actually fit?
  INNOVATE    codellama:latest     Code generation of new SDOA module scaffolds
              + llama3:8b          Architecture design decisions, naming
              + sequential_think   Step-by-step module design with constraints
  PLAN        llama3:8b            Complex synthesis, ordering, risk assessment
              + sequential_think   Constraint-satisfying plan generation
  PATCH       codellama:latest     Targeted code edits, manifest generation
  AUDIT       llama3:8b            Edge-case reasoning for constraint violations
              + sequential_think   Systematic rule checking
  MIGRATE     (no LLM)             Deterministic file operations only
  VERIFY      llama3.2:latest      Summarize verification report

> RULE: All LLM output is constraint-validated before use. No unvalidated
> LLM output ever touches the filesystem.

================================================================================
SECTION 3 — MCP SERVER ROLE ASSIGNMENTS
================================================================================

  MCP SERVER          PHASE(S)             ROLE
  ----------------    -----------------    ----------------------------------------
  context7            REUSE, INNOVATE      Look up docs for external libs referenced
                                           in requires/dependencies fields
  firecrawl           INNOVATE (optional)  Research new libraries if gap requires one
  github              ANALYZE, MIGRATE     Read repo files; push migrated output,
                                           create PRs for review
  notebooklm          REUSE                Index SDOA docs; query for design patterns
                                           matching the current module's needs
  playwright          VERIFY               Run browser-based smoke tests on UI mods
                                           after migration
  sentry              VERIFY               Check for runtime error spikes post-migrate
  sequential_thinking INNOVATE, PLAN,      Structured chain-of-thought for non-trivial
                      AUDIT                design and audit steps
  sqlite              ALL phases           Primary state store — see Section 5

================================================================================
SECTION 4 — CONSTRAINT SOLVER SPECIFICATION
================================================================================

ConstraintSolver.service.js implements ALL of the following as hard constraints.
A violation is a structured error object, never a warning. AUDIT fails on any
unresolved violation.

  CONSTRAINT GROUP        RULES
  --------------------    -------------------------------------------------------
  Sovereignty             No module mutates another sovereign's files
                          No cross-sovereign imports without declared dependency
                          Variants must live in parent sovereign's variants/ dir

  Manifest Completeness   v1.2 required: id, type, version, runtime, capabilities,
                                         dependencies, docs, last_modified
                          v4.0 adds: layer, requires, dataFiles, lifecycle, actions,
                                     backendDeps
                          v5.0 adds: operationalRole, optimization
                          Variant adds: compliance, variant_of

  Layer Rules             Features (Layer 1) may import Primitives (Layer 2)
                          Primitives (Layer 2) may NOT import Features
                          Adapters (Layer 3) may import Primitives, not Features
                          No circular layer dependencies

  Naming Conventions      Primitives:  *.prim.js
                          Features:    *.feature.js
                          Adapters:    *.adapter.js | *.adapter.ts
                          Services:    *.service.js
                          Workflows:   *.workflow.js
                          Bridges:     *.bridge.js
                          Engines:     *.engine.js

  Placement Rules         Browser-runtime (.ui.js) → ui/adapters/ or ui/lib/
                          NodeJS services → substrate/services/
                          CSS → with consuming UI sovereign
                          Binary/WASM → with consuming engine
                          JSON (schema) → with consuming module
                          JSON (authority) → authorities/
                          Scripts/config → environment/
                          Python engines → substrate/engines/ or substrate/services/
                          Rust → substrate/engines/
                          Prohibited: /assets/ /static/ /deps/ /resources/ /misc/

  Line Limits (v4.1)      Primitives:   150–250 lines  (hard limit: ~500)
                          Features:     200–350 lines  (hard limit: ~500)
                          Adapters:     200–350 lines  (hard limit: ~500)
                          Workflows:    200–400 lines  (hard limit: ~500)
                          Repositories: 200–400 lines  (hard limit: ~500)

  Lifecycle Contracts     Frontend: init → mount → update → unmount → destroy
                          Backend:  init → run → dispose
                          Contract must be declared in manifest.lifecycle[]

  File Headers            All .js/.ts must have:
                          // ───────────────────────────
                          // File:    Name.type.js
                          // Version: x.x.xx
                          // Updated: YYYY-MM-DDTHH:MM:SSZ
                          // Changes: [description]
                          // ───────────────────────────

  Deduplication           Same name + ext + size → exact duplicate → delete non-canonical
                          Same name + ext, diff content → older becomes variant

================================================================================
SECTION 5 — STATE PERSISTENCE — SQLite SCHEMA
================================================================================

State lives at: .sdoa/pipeline.db
Managed via: sqlite MCP (external queries) + better-sqlite3 (in-process writes)

> Why SQLite over JSON files:
> ACID transactions — no partial phase writes
> Queryable across runs — find all violations of rule X across all time
> Embeddings stored as BLOBs — nomic-embed-text vectors for semantic search
> Single file — easy to back up, version, share

TABLE: runs
  runId       TEXT PRIMARY KEY
  input       TEXT    -- directory path, file path, or module ID
  inputType   TEXT    -- "directory" | "file" | "moduleId"
  status      TEXT    -- "running" | "paused" | "complete" | "failed"
  currentPhase TEXT
  createdAt   TEXT
  updatedAt   TEXT

TABLE: phases
  runId       TEXT
  phase       TEXT    -- ANALYZE | MAP | REUSE | ... | VERIFY
  status      TEXT    -- "pending" | "running" | "complete" | "failed"
  outputJson  TEXT    -- full phase output as JSON
  completedAt TEXT
  PRIMARY KEY (runId, phase)

TABLE: violations
  id          INTEGER PRIMARY KEY AUTOINCREMENT
  runId       TEXT
  phase       TEXT
  moduleId    TEXT
  rule        TEXT    -- constraint group + rule name
  severity    TEXT    -- "error" | "blocker"
  message     TEXT
  resolved    INTEGER -- 0 | 1

TABLE: modules
  id          TEXT PRIMARY KEY   -- matches MANIFEST.id
  type        TEXT               -- primitive | feature | adapter | ...
  layer       INTEGER
  sovereignty TEXT               -- which directory/sovereign owns it
  manifestJson TEXT              -- full MANIFEST as JSON
  embedding   BLOB               -- nomic-embed-text vector (float32[])
  sdoaVersion TEXT
  updatedAt   TEXT

TABLE: edges
  fromId      TEXT
  toId        TEXT
  edgeType    TEXT   -- "requires" | "imports" | "depends"
  PRIMARY KEY (fromId, toId, edgeType)

TABLE: run_log
  id          INTEGER PRIMARY KEY AUTOINCREMENT
  runId       TEXT
  phase       TEXT
  level       TEXT   -- "info" | "warn" | "error"
  message     TEXT
  timestamp   TEXT

================================================================================
SECTION 6 — THE NINE PIPELINE PHASES
================================================================================

6A. ANALYZE
--------------------------------------------------------------------------------
Input:   directory | file | moduleId
Model:   llama3.2:latest
MCPs:    sqlite (write), github (optional — read from remote repo)
Tools:   Desktop Commander (ripgrep), ConstraintSolver (detect-only mode)

Steps:
  1. Resolve input to file list
     - directory → glob all SDOA-convention files recursively
     - file → that file + its declared requires[] dependencies
     - moduleId → look up in modules table, resolve to file path
  2. For each file: extract MANIFEST block (static parse, no LLM)
  3. Run ConstraintSolver in detect mode — log violations, do not block
  4. Use llama3.2 to classify any files without MANIFEST (infer type/layer)
  5. Generate module embeddings via nomic-embed-text; store in modules table
  6. Write analysis.json to phases table

Output: analysis.json
  { modules: [...], violations: [...], unclassified: [...], fileCount: N }

6B. MAP
--------------------------------------------------------------------------------
Input:   runId (reads analysis.json from phases table)
Model:   llama3.2:latest
MCPs:    sqlite (read/write)
Tools:   graphology, graphology-algorithms

Steps:
  1. Load all modules from analysis output
  2. Build directed graph: nodes = modules, edges = requires/imports
  3. Run cycle detection — cycles are blocker violations
  4. Run topological sort — defines safe migration order
  5. Detect boundary violations (cross-layer imports, cross-sovereign mutations)
  6. Store graph as nodes/edges in sqlite edges table
  7. Cache to .sdoa/cache/graph-cache.json for IDE extension use

Output: mapping.json
  { graph: { nodes: N, edges: E }, cycles: [...], boundaryViolations: [...],
    topoOrder: [...], sovereignMap: {...} }

6C. REUSE
--------------------------------------------------------------------------------
Input:   runId
Model:   nomic-embed-text (similarity), llama3.2 (final fit reasoning)
MCPs:    sqlite (vector search), notebooklm (SDOA pattern query), context7 (lib docs)

Steps:
  1. For each module flagged as needing work (from violations):
     a. Embed its description/capabilities via nomic-embed-text
     b. Query modules table for cosine similarity > 0.85
     c. Ask notebooklm: "Does SDOA define a pattern for [capability]?"
     d. Ask context7: look up any external library in its dependencies
     e. llama3.2: "Can existing module X satisfy this requirement? Justify."
  2. Build reuse candidates list with fit scores and justifications

Output: reuse.json
  { candidates: [{ moduleId, targetNeed, fitScore, justification }] }

6D. INNOVATE
--------------------------------------------------------------------------------
Input:   runId (reads reuse.json — gaps with no reuse candidate)
Model:   codellama (scaffold), llama3:8b (design), sequential_thinking (structure)
MCPs:    context7 (library docs), sequential_thinking, sqlite (write)

Steps:
  1. For each gap not covered by reuse:
     a. sequential_thinking: design the module step-by-step against constraints
     b. llama3:8b: name the module, define its capabilities and dependencies
     c. context7: look up any new library needed
     d. codellama: generate the module scaffold (header, MANIFEST, stub methods)
     e. ConstraintSolver: validate the generated scaffold before accepting
  2. All generated modules must pass constraint check before added to plan

Output: innovation.json
  { newModules: [{ id, type, layer, scaffold, manifest, targetPath }] }

6E. PLAN
--------------------------------------------------------------------------------
Input:   runId (reads reuse.json + innovation.json)
Model:   llama3:8b, sequential_thinking
MCPs:    sequential_thinking, sqlite (write)

Steps:
  1. Merge reuse candidates and new module designs into unified change set
  2. sequential_thinking: order changes by topoOrder from MAP phase
  3. llama3:8b: identify risks, flag anything requiring manual review
  4. Group into phases: (a) patches to existing, (b) new files, (c) moves/renames
  5. Estimate line count impact — flag any post-plan file that would exceed limits
  6. Produce step-by-step migration plan with rollback points

Output: plan.json
  { steps: [{ action, target, source, reason, rollback }],
    risks: [...], manualReviewRequired: [...] }

6F. PATCH
--------------------------------------------------------------------------------
Input:   runId, dryRun?: boolean
Model:   codellama:latest
MCPs:    sqlite (write), github (read current file state)
Tools:   Desktop Commander (apply patches), ConstraintSolver (validate each patch)

Steps:
  1. For each patch-type step in plan.json:
     a. Read current file (Desktop Commander or github MCP)
     b. codellama: generate the specific diff/edit
     c. ConstraintSolver: validate patched file — reject if still violating
     d. If dryRun=false: write via Desktop Commander
     e. Log result to run_log
  2. Patch targets: missing manifest blocks, wrong require paths,
     missing file headers, manifest field gaps
  3. Never patch beyond what plan.json specifies

Output: patch.json
  { applied: [...], rejected: [...], dryRun: boolean }

6G. AUDIT
--------------------------------------------------------------------------------
Input:   runId
Model:   llama3:8b, sequential_thinking
MCPs:    sequential_thinking, sqlite (read/write)
Tools:   ConstraintSolver (enforce mode — all rules), SonarQube CLI (quality layer)

Steps:
  1. Run ConstraintSolver in enforce mode against ALL files in scope
     — sovereignty, manifests, layers, naming, placement, line limits,
       lifecycle, CSS/JSON/binary placement
  2. Run SonarQube scan for code quality (complexity, security hotspots)
  3. sequential_thinking: for any ambiguous violations, reason to resolution
  4. llama3:8b: classify each violation by root cause
  5. Build pass/fail report — pipeline cannot advance to MIGRATE with blockers
  6. Write all violations to violations table

Output: audit.json
  { passed: boolean, blockers: N, warnings: N,
    violations: [{ moduleId, rule, severity, message }],
    sonarReport: {...} }

> HARD RULE: sdoa.migrate will refuse to run if audit.json.passed === false.

6H. MIGRATE
--------------------------------------------------------------------------------
Input:   runId, dryRun?: boolean
Model:   none (deterministic only)
MCPs:    github (push + PR creation), sqlite (atomic state updates)
Tools:   Desktop Commander (batch file ops)

Steps:
  1. Verify audit passed (check phases table — AUDIT must be complete + passed)
  2. For each step in plan.json type "new-file": write scaffold to target path
  3. For each step type "move": move file to canonical location via Desktop Commander
  4. For each step type "rename": rename per naming conventions
  5. For each step type "delete-duplicate": remove exact duplicates
  6. After all writes: rebuild graph-cache.json
  7. github MCP: if repo connected — push changes to branch, create PR
     PR description auto-generated from plan.json summary
  8. Update all phases to MIGRATE complete in sqlite

Output: migration.json
  { created: [...], moved: [...], renamed: [...], deleted: [...],
    prUrl?: string, dryRun: boolean }

6I. VERIFY
--------------------------------------------------------------------------------
Input:   runId
Model:   llama3.2:latest (report summary)
MCPs:    playwright (browser tests), sentry (runtime error check), sqlite (final write)
Tools:   ConstraintSolver (final gate), Desktop Commander (run test suite)

Steps:
  1. ConstraintSolver final pass — must be clean (zero blockers)
  2. Rebuild and validate capability graph integrity
  3. playwright MCP: run smoke tests on any UI modules that were migrated
  4. sentry MCP: check for new error events since migration started
  5. Desktop Commander: run project test suite if one exists
  6. llama3.2: generate human-readable verification summary
  7. Write final compliance score to runs table — status = "complete" or "failed"

Output: verification.json
  { passed: boolean, constraintScore: "100%", graphIntegrity: boolean,
    testResults: {...}, sentryAlerts: N, summary: "..." }

================================================================================
SECTION 7 — MCP TOOL DEFINITIONS (9 phase tools + 4 utility tools)
================================================================================

All tools accept and return JSON. Input validated by zod schemas.

sdoa.analyze({ path?, file?, moduleId?, runId? }) → { runId, moduleCount, violationCount }
  -- Starts a new run (or resumes if runId given). Returns runId for all subsequent calls.

sdoa.map({ runId }) → { nodes, edges, cycles, boundaryViolations }

sdoa.reuse({ runId }) → { candidateCount, gapCount }

sdoa.innovate({ runId }) → { newModuleCount, scaffoldsGenerated }

sdoa.plan({ runId }) → { stepCount, risks, manualReviewCount }

sdoa.patch({ runId, dryRun? }) → { applied, rejected, dryRun }

sdoa.audit({ runId }) → { passed, blockers, warnings }

sdoa.migrate({ runId, dryRun? }) → { created, moved, deleted, prUrl? }

sdoa.verify({ runId }) → { passed, summary }

-- Utility tools --
sdoa.run.list() → [{ runId, status, currentPhase, createdAt }]
sdoa.run.status({ runId }) → { runId, status, currentPhase, completedPhases, violations }
sdoa.run.resume({ runId }) → { runId, resumedAt, currentPhase }
sdoa.run.reset({ runId, toPhase }) → { runId, resetTo, clearedPhases }

================================================================================
SECTION 8 — MODULE LAYOUT IN sdoavx/
================================================================================

authorities/
└── mcp/
    ├── SdoaMcp.service.js           Entry point — MCP server, tool registration
    ├── CapabilityGraph.engine.js    Graph construction, algorithms (uses graphology)
    ├── PipelineStateMachine.js      Phase transition enforcement, resume logic
    ├── ConstraintSolver.service.js  All SDOA rules as hard constraints
    ├── RunManager.service.js        SQLite run lifecycle (create/read/update runs)
    ├── LlmBroker.adapter.js         Ollama model routing — phase → model selection
    ├── EmbeddingService.js          nomic-embed-text wrapper, cosine similarity
    ├── manifest.json                SDOA v5 manifest for the MCP sovereign
    └── workflows/
        ├── Analyze.workflow.js
        ├── Map.workflow.js
        ├── Reuse.workflow.js
        ├── Innovate.workflow.js
        ├── Plan.workflow.js
        ├── Patch.workflow.js
        ├── Audit.workflow.js
        ├── Migrate.workflow.js
        └── Verify.workflow.js

authorities/
└── mcp/
    └── vscode-extension/            .vsix for Antigravity IDE
        ├── package.json             Extension manifest (also has SDOA manifest)
        ├── extension.ts             Activation, MCP stdio bridge
        ├── providers/
        │   ├── SdoaCodeLens.ts      Per-file compliance badges
        │   ├── SdoaDiagnostics.ts   SDOA violations as IDE Problems
        │   └── SdoaTreeView.ts      Sovereignty tree panel
        └── webview/
            └── PipelineDashboard.html  Run state visualization

environment/
    mcp.json                         MCP server registration for Claude/Antigravity
    sdoa.constraints.json            Machine-readable constraint rules (used by solver)
    .sdoa/
        config.json                  Ollama endpoint, sqlite path, run defaults
        pipeline.db                  SQLite state store
        cache/
            graph-cache.json         Capability graph snapshot (used by .vsix)

================================================================================
SECTION 9 — REGISTRATION FILE (environment/mcp.json)
================================================================================

{
  "mcpServers": {
    "sdoavx": {
      "command": "node",
      "args": ["authorities/mcp/SdoaMcp.service.js"],
      "cwd": "D:\\projects\\SDOAvX",
      "env": {
        "OLLAMA_HOST": "http://localhost:11434",
        "SDOA_DB": ".sdoa/pipeline.db",
        "SDOA_GRAPH_CACHE": ".sdoa/cache/graph-cache.json"
      }
    }
  }
}

================================================================================
SECTION 10 — BUILD SEQUENCE
================================================================================

Phase 0 — Bootstrap (do first, everything else depends on it)
  [0.1]  Install npm deps: @modelcontextprotocol/sdk, graphology,
         graphology-algorithms, zod, better-sqlite3
  [0.2]  Create .sdoa/ directory structure and initialize pipeline.db schema
  [0.3]  Write environment/sdoa.constraints.json — full constraint rule set
  [0.4]  Write environment/mcp.json — server registration

Phase 1 — Core Services (no dependencies between these — build in parallel)
  [1.1]  ConstraintSolver.service.js — all rules, detect + enforce modes
  [1.2]  RunManager.service.js — SQLite CRUD for runs, phases, violations
  [1.3]  LlmBroker.adapter.js — Ollama HTTP client, model routing table
  [1.4]  EmbeddingService.js — nomic-embed-text wrapper, cosine similarity

Phase 2 — Graph Engine (depends on Phase 1)
  [2.1]  CapabilityGraph.engine.js — graphology wrapper, cycle detection,
         boundary violation detection, topo sort, cache write

Phase 3 — State Machine (depends on Phase 1 + 2)
  [3.1]  PipelineStateMachine.js — transition table, resume/reset logic,
         phase gate enforcement (MIGRATE blocked until AUDIT passes)

Phase 4 — Workflow Modules (depends on all Phase 1-3 services)
  Build in pipeline order — each workflow can be validated independently:
  [4.1]  Analyze.workflow.js
  [4.2]  Map.workflow.js
  [4.3]  Reuse.workflow.js
  [4.4]  Innovate.workflow.js
  [4.5]  Plan.workflow.js
  [4.6]  Patch.workflow.js
  [4.7]  Audit.workflow.js
  [4.8]  Migrate.workflow.js
  [4.9]  Verify.workflow.js

Phase 5 — MCP Entry Point (depends on all Phase 4 workflows)
  [5.1]  SdoaMcp.service.js — tool registration, zod schemas, stdio server

Phase 6 — Antigravity .vsix Extension (depends on Phase 5 being registered)
  [6.1]  SdoaCodeLens.ts — reads .sdoa/cache/graph-cache.json
  [6.2]  SdoaDiagnostics.ts — reads violations table via sqlite MCP
  [6.3]  SdoaTreeView.ts — renders sovereignty tree from graph cache
  [6.4]  PipelineDashboard.html — reads phases table, renders run state
  [6.5]  extension.ts — wires all providers, activates on SDOA project detection
  [6.6]  Package as .vsix, install to Antigravity IDE

Phase 7 — Integration Test
  [7.1]  Run sdoa.analyze on SDOAvX project itself (dogfood test)
  [7.2]  Run full pipeline ANALYZE → VERIFY
  [7.3]  Verify the MCP sovereign itself is SDOA-compliant (self-audit)

================================================================================
SECTION 11 — OPEN QUESTIONS (must resolve before Phase 4)
================================================================================

  [Q1]  GitHub MCP scope: push to existing branches or always create new branch?
        Recommendation: always create branch sdoa/run-{runId}, then PR

  [Q2]  Sentry MCP: which project/org to watch during VERIFY?
        Needs: sentry org + project slug configured in .sdoa/config.json

  [Q3]  NotebookLM notebook: should SDOA docs be pre-loaded into a notebook
        before the first REUSE run? Or lazily on first use?
        Recommendation: pre-load in Phase 0 bootstrap (add_notebook call)

  [Q4]  .vsix communication: direct file read of .sdoa/ (simpler, read-only)
        vs stdio bridge to SdoaMcp.service.js (bidirectional control)?
        Recommendation: file read for display; stdio bridge for triggering phases

  [Q5]  EmbeddingService persistence: store embeddings in sqlite modules table
        (recommended) or in a separate vector store?
        Recommendation: sqlite BLOB — keeps everything in one file, simpler

================================================================================
SECTION 12 — SDOA COMPLIANCE FOR THE MCP ITSELF
================================================================================

The MCP server is a first-class SDOA sovereign. It must comply with all rules.

  authorities/mcp/manifest.json fields (v5.0 required):
    id:              "SdoaMcp"
    type:            "service"
    layer:           3
    runtime:         "NodeJS"
    version:         "1.0.0"
    capabilities:    ["mcp_server", "pipeline_orchestration", "constraint_solving",
                      "capability_graph", "sdoa_migration"]
    dependencies:    ["Captain.service", "Registrar.service", "Chronicle.persistence"]
    requires:        ["@modelcontextprotocol/sdk", "graphology", "zod",
                      "better-sqlite3"]
    operationalRole: "authority"
    optimization:    { priority: "correctness", assertionSuite: "sdoa-full" }
    lifecycle:       ["init", "run", "dispose"]
    docs:            { description: "SDOA hybrid pipeline MCP server —
                       Constraint-Solver x Graph-Driven x State-Machine compiler
                       for SDOA migration and compliance." }
    last_modified:   "2026-06-17T00:00:00Z"

  Line limits: SdoaMcp.service.js must stay within 200–400 lines (service type).
               Each workflow must stay within 200–400 lines.
               ConstraintSolver.service.js may be 200–350 lines (adapter-class logic).

================================================================================
END OF PLAN — READY FOR PHASE 0 IMPLEMENTATION ON CONFIRMATION
================================================================================
