Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions docs/architecture/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@ Or preview in the browser (no extension):
npx likec4 serve docs/architecture
```

Then open the URL it prints (usually `http://localhost:5173`). Views: `/view/index`, `/view/house`, `/view/pull`, `/view/boot`, `/view/connect`.
Then open the URL it prints (usually `http://localhost:5173`). Views: `/view/index`, `/view/house`, `/view/pairing`, `/view/pull`, `/view/boot`, `/view/connect`.

| View | Story |
| --- | --- |
| `index` | Landscape |
| `house` / `pull` | Store: pull, scaffold, the two cards |
| `boot` | Resolve adapter (paired client env when connected) → spawn llama-server |
| `clients-landscape` / `connect` | Harness + project + proxy. `mba connect` pairs a token and stages `instructions.md`. Operator may add a client (name + envelope). |
| `boot` | Paired client env (else Copilot/VS Code) → spawn llama-server |
| `pairing` | `sessions.json` (token hash) and `clients.json` (added envelopes) |
| `clients-landscape` / `connect` | Stage card, mint token, proxy requires Bearer. Add a client is name + envelope. |

One `instructions.md` in the store. Environment (`harness` + `ide`) only changes the **filename/path** when staging exists. `notes.md` never leaves the house.
One `instructions.md` in the store. Environment folders overlay **dials**, not the card. Staging copies the winning card into a harness file (built-in table or `clients.json`). `notes.md` never leaves the house.
36 changes: 25 additions & 11 deletions docs/architecture/model.c4
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
model {
operator = actor "Operator" {
description "You. Pull, boot, fill cards, read notes."
description "You. Pull, boot, connect a client, fill cards, read notes."
}

host = system "Download host" {
Expand All @@ -9,7 +9,7 @@ model {
}

harness = app "Harness" {
description "Cursor, Copilot, Cline, Claude Code. Not MBA. Reads the project and talks HTTP to the model endpoint."
description "Cursor, Copilot, Cline, Claude Code, Continue, or a name you added. Not MBA. Reads the project and talks HTTP to the MBA proxy."
style { color sky }
}

Expand All @@ -28,7 +28,8 @@ model {
}
envelope = file "Staged model card" {
description """
Live copy of the winning instructions.md. Filename from harness+ide.
Live copy of the winning instructions.md. Path from the built-in
harness table or from an added client (name + envelope).
The project's own CLAUDE.md stays the project's. notes.md never lands here.
"""
}
Expand All @@ -39,19 +40,19 @@ model {
technology "Node"

cli = app "mba CLI" {
description "mba models pull, mba s boot, status."
description "mba models, mba s boot, mba connect, mba clients add."
}
service = service "Service" {
description "Daemon on 127.0.0.1. Owns pull, boot, registry, proxy."
description "Daemon on 127.0.0.1. Owns pull, boot, pairing, registry, proxy."
}
resolver = component "Resolver" {
description "Family then model, then environment folder. Last-specific wins."
description "Family then model, then environment folder (harness+ide+runtime). Last-specific wins. Env folders overlay dials, not instructions.md."
}
mcp = service "MCP server" {
description "Control plane for hosts. Not on the per-request chat path."
}
proxy = service "Proxy" {
description "Chat HTTP in, llama-server out. Sanitize mop and slot erase live here."
description "Chat HTTP in, llama-server out. Pairing check, sanitize mop, and slot erase live here."
}
store = store "Model store" {
description "The house for one model. Source of truth."
Expand All @@ -69,20 +70,33 @@ model {
description "kv/upstream/slots and kv/llama.cpp/slots. Boot-ready empty dirs on pull."
}
}
state = store "Daemon state" {
description "Local pairing and added clients. Not the model house."

sessions = file "sessions.json" {
description "Paired model + harness + project. SHA-256 of the token. Empty file = chat open."
}
clients = file "clients.json" {
description "Operator-defined name + envelope path. The five built-in harnesses live in code. No disk scan."
}
}
}

operator -> mba.cli "runs commands"
mba.cli -> mba.service "HTTP to the daemon"
mba.cli -> mba.state.clients "mba clients add"
mba.service -> mba.resolver "resolve adapter"
mba.resolver -> mba.store "read YAML and bindings"
mba.service -[writes]-> mba.store "pull writes the house"
mba.service -> llama "spawn + flags + slot-save-path"
mba.service -> mba.state.sessions "read/write pairing (hash at rest)"
mba.service -> llama "spawn + flags from paired env"
mba.mcp -> mba.service "control plane"
harness -> mba.proxy "chat completions"
harness -> mba.proxy "chat completions (Bearer)"
mba.proxy -> mba.state.sessions "match hashed token + model"
mba.proxy -> llama "forward (and mop / erase slot)"
harness -> project.card "injects project playbook"
mba.service -> project.envelope "stage card (env picks filename)" {
description "Same instructions.md. Envelope from harness+ide."
mba.service -> project.envelope "stage card" {
description "Same instructions.md. Envelope from built-in table or clients.json."
}
mba.service -> host "download GGUF"
}
37 changes: 26 additions & 11 deletions docs/architecture/views.c4
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
views {
view index {
title "MBA landscape"
description "Three stories: store the house, boot the server, talk through a harness."
description "Three stories: store the house, boot the server, connect a client."
include operator, host, harness, llama, project, mba
include mba.*
exclude mba.store.*
exclude mba.store.*, mba.state.*
autoLayout LeftRight
}

Expand All @@ -15,10 +15,17 @@ views {
include -> mba.store
}

view pairing of mba.state {
title "3 — Pairing state"
description "Token hash and operator-defined envelopes. Empty sessions = door open. Not the model house."
include *
include -> mba.state
}

view clients-landscape {
title "3 — Harness, project, proxy"
description "MBA is not the client. Environment (harness + ide) picks the envelope filename."
include harness, project, project.*, mba.proxy, mba.service, llama, mba.mcp
description "MBA is not the client. Built-in or added name picks the envelope. Pairing token is the lock."
include operator, mba.cli, harness, project, project.*, mba.proxy, mba.service, llama, mba.state, mba.state.*
autoLayout LeftRight
}

Expand All @@ -44,30 +51,38 @@ views {

dynamic view boot {
title "2 — Boot the model"
description "Resolve the house into llama.cpp flags using the paired client's environment, then spawn. Slot-save-path is already on disk from pull."
description "Paired client supplies harness+ide+runtime. No pairing → Copilot + VS Code + llama.cpp. Env folders overlay dials, not instructions.md."
variant sequence

operator -> mba.cli "mba s boot <id>"
mba.cli -> mba.service "POST boot"
mba.service -> mba.resolver "family then model then env folder (paired client)"
mba.resolver -> mba.store "read yaml, bcb, tcb, server_setup"
mba.service -> mba.state.sessions "newest pairing for this model"
mba.service -> mba.resolver "family, model, then env folder"
mba.resolver -> mba.store "yaml, bcb, tcb, server_setup"
mba.service -> llama "spawn llama-server (ctx, GPU, slot-save-path)"
mba.service -> mba.store.kv "use existing slot dirs"
}

dynamic view connect {
title "3 — Connect a client"
description "Harness builds the prompt from the project. MBA pairs a token, stages the model card, then proxies the HTTP call."
description "Stage the card, mint a token once, store the hash. Chat through the proxy must present that Bearer for the paired model."
variant sequence

opt "sixth editor" {
operator -> mba.cli "mba clients add --envelope"
mba.cli -> mba.state.clients "name + path"
}
operator -> mba.cli "mba connect"
mba.cli -> mba.service "POST /connect"
mba.service -> mba.resolver "winning instructions.md"
mba.service -> mba.state.clients "envelope if added"
mba.service -> mba.resolver "winning instructions.md (family then model)"
mba.service -> project.envelope "copy into harness slot"
mba.service -> mba.state.sessions "store SHA-256, return token once"
harness -> project.card "reads project CLAUDE.md"
harness -> project.envelope "same pipe as CLAUDE.md"
harness -> mba.proxy "POST /v1/chat/completions (Bearer token)"
mba.proxy -> llama "forward"
harness -> mba.proxy "POST /v1/chat/completions (Bearer)"
mba.proxy -> mba.state.sessions "hash Bearer, match model"
mba.proxy -> llama "forward (strip Authorization)"
opt "sanitize actually changed what the model sees" {
mba.proxy -> llama "POST /slots/0?action=erase"
}
Expand Down