Skip to content

Latest commit

 

History

History
571 lines (460 loc) · 34.7 KB

File metadata and controls

571 lines (460 loc) · 34.7 KB

AIMA — Claude Code Development Guide

What Is This

AIMA (AI-Inference-Managed-by-AI): a Go binary that manages AI inference on edge devices. It detects hardware, resolves optimal configs from a YAML knowledge base, generates K3S Pod YAML, and exposes 61 MCP tools for AI Agents to operate everything. This project is 100% developed by Claude Code.

Tech: Go (no CGO), K3S, HAMi, SQLite (modernc.org/sqlite), MCP (JSON-RPC 2.0), Cobra CLI, log/slog. Design docs: design/ARCHITECTURE.md (system architecture), design/PRD.md, design/MRD.md.

====== Central Knowledge Server 已拆分 ======

internal/central/cmd/central/ 已拆分至独立 repo,本 repo 中不再包含。

说明
独立 repo github.com/Approaching-AI/aima-central-knowledge (private)
个人 fork github.com/skyguan92/aima-central-knowledge (private)
本地路径 /Users/jguan/projects/aima-central-knowledge
API 契约 aima-central-knowledge/api/openapi.yaml (OpenAPI 3.1)

生产部署

Central 已部署到 aima-oversea 服务器,作为 aima-service docker-compose 中的独立容器。

项目 说明
生产 URL https://aimaservice.ai/central
默认 endpoint Edge 代码默认使用此 URL(defaultCentralEndpoint in tooldeps_integration.go
覆盖方式 system.config set central.endpoint <url>
Gateway 代理 Rust gateway /central/* → strip 前缀 → http://central:8081
数据库 PostgreSQL aima_central database(与 platform 隔离)
升级 Central cd /root/aima-central-knowledge && git pull && docker build -t aima-central:latest . && cd /root/aima-service && docker compose -f docker-compose.prod.yml up -d central
升级 Gateway cd /root/aima-service && git pull && docker compose -f docker-compose.prod.yml build gateway && docker compose -f docker-compose.prod.yml up -d gateway
服务器 Git aima-oversea 已配 SSH key(aima-oversea-deploy),两个 repo 均可 git pull

开发警告

  • 不要在本 repo 创建 internal/central/cmd/central/ — 已迁出
  • 不要在本 repo 修改 Central Server 的逻辑 — 去 aima-central-knowledge repo 改
  • Edge→Central 通信仅通过 HTTP REST — 见 cmd/aima/tooldeps_integration.go,用 map[string]any 构造 payload,不 import central 包
  • 修改 sync/ingest 的 JSON 字段时,必须同步检查 aima-central-knowledge/api/openapi.yaml 的契约定义
  • 本 repo 的 tooldeps_integration.go 中的 normalization 函数normalizeCentralAdvisory 等)是 Edge 侧的 JSON 适配层,修改前需确认 Central 端对应端点的 response schema

Edge ↔ Central API 端点速查

严格模式(自 aima-service 设备身份打通起):除 /stats/healthz 外,所有端点都必须携带 ?device_id=X query 参数,缺失返回 400。edge 侧通过 internal/cloud.RequireRegistered 在每次出云调用前读 device.id 配置键,未注册时直接失败、不发出网络请求。

Method Path 必须 device_id Edge 用途 Edge 调用位置
POST /api/v1/ingest 推送 configs/benchmarks/notes SyncPush() in tooldeps_integration.go
GET /api/v1/sync?since=&device_id= 增量拉取知识 SyncPull() in tooldeps_integration.go
GET /api/v1/stats 连通性检查(豁免) SyncStatus() in tooldeps_integration.go
POST /api/v1/advise 请求 LLM 推荐 RequestAdvise() in tooldeps_integration.go
GET /api/v1/advisories 拉取待处理推荐 SyncPullAdvisories() in tooldeps_integration.go
POST /api/v1/advisories/{id}/feedback 反馈验证/拒绝 AdvisoryFeedback() in tooldeps_integration.go
POST /api/v1/scenarios/generate 生成部署方案 RequestScenario() in tooldeps_integration.go
GET /api/v1/scenarios 拉取方案 ListCentralScenarios() in tooldeps_integration.go

Device-level 过滤(当前仅 Configurations 层)QueryConfigurationssyncdevice_id 列真正过滤;advisories / scenarios 是"硬件类级"数据,依旧按 hardware 过滤,device_id 在这两个端点上只用作 strict-mode 的存在性校验。

跨 Repo 联调

# 1. 启动 Central (在 aima-central-knowledge repo)
cd /Users/jguan/projects/aima-central-knowledge
CENTRAL_API_KEY=test-key go run ./cmd/central/

# 2. 配置 Edge 连接 (在 AIMA repo) + 注册身份
aima --invite-code <CODE> device register   # 或 AIMA_INVITE_CODE=<CODE> aima device register
aima device status                          # 确认 registered

# 3. 直接 curl 测试(/stats 豁免, 其他必须带 device_id):
curl http://localhost:8080/api/v1/stats | jq .
curl 'http://localhost:8080/api/v1/advisories?device_id=dev-XXX' -H "Authorization: Bearer test-key"

====== aima-service 设备身份打通 (v0.3.x Phase 1) ======

Edge 在首次启动(且能联网)时通过 aima-service 的 device-registry 签发一个 device_id + token + recovery_code,作为整台设备在云上的永久身份。Central 所有出云请求都携带这个 device_id,打通"两套云后端各自一套身份"的分裂。

项目 说明
aima-service repo /Users/jguan/projects/aima-service(Python/FastAPI + Rust gateway + gRPC)
注册端点 POST <aima-service>/api/v1/devices/self-register — 返回 {device_id, token, recovery_code, token_expires_at, poll_interval_seconds, budget, referral_code}
token 续期 POST /api/v1/devices/{device_id}/renew-token
长轮询反向通道 POST /api/v1/devices/{device_id}/poll(phase 2 才接)
默认 endpoint support.endpoint 配置键控制,默认 https://aimaserver.com(= aima-service)

身份在 edge 侧怎么存

支持服务(internal/support/)复用为 aima-service client。注册成功后同时写两套键:

  • 自有命名空间(不对外):support.state.device_idsupport.state.token
  • canonical 命名空间(整个 AIMA 读这个)device.iddevice.tokendevice.recovery_codedevice.token_expires_atdevice.registration_stateunregistered/pending/registered/failed

internal/cloud 包统一读:

deviceID, err := cloud.RequireRegistered(ctx, deps.GetConfig)  // ErrNotRegistered 若未注册

关键调用入口

  • 首启动注册(非阻塞、退避重试):serve.go 启动末尾 go app.Support.StartRegistrationWorker(ctx, support.BootstrapOptions{})
  • 手动触发:aima device register --invite-code XXX
  • 查看状态:aima device status
  • 强制续期:aima device renew
  • 清除身份(危险):aima device reset --confirm
  • MCP tools 等价:device.register / device.status / device.renew / device.reset

invite_code 来源三优先级

  1. --invite-code CLI 根 flag(持久化到 support.invite_code
  2. AIMA_INVITE_CODE env var(直接读取,不持久化)
  3. AIMA_SUPPORT_INVITE_CODE env 兜底;再不行用包内的 DefaultInviteCode = "channel-aima"

Phase 1 范围 vs Phase 2 预留

  • Phase 1(已完成):身份注册、token 续期、device.id 在所有 Central 出云调用流转、Central 严格模式 400
  • Phase 2(未来):接 aima-service 长轮询通道 /poll + /result,让云端可以下发命令到 edge(通过 MCP dispatcher 派发);该能力在 internal/support/support.go 已有实现(RunBackground),只是默认不启用(需要 support.enabled=true

关键文件

  • internal/cloud/device.go — canonical identity 读写入口
  • internal/support/bootstrap.goBootstrap() + StartRegistrationWorker() + RenewToken() + ResetIdentity()
  • internal/support/state.go::mirrorCanonical — 双写 canonical 键的镜像点
  • cmd/aima/tooldeps_device.go — device.* MCP tool 闭包
  • cmd/aima/tooldeps_integration.go::withDeviceID — URL 追加 ?device_id= 助手

====== Remote Test Lab (Heterogeneous Hardware) ======

This is a live, SSH-driven test environment for real-device validation. Claude Code SSHes into each machine, runs AIMA, collects results, and feeds them back into development.

Machine Registry

ID User@Host OS Arch Chip/GPU RAM Disk Free K3S/Docker SSH Auth Role
dev-mac local macOS 15.3 arm64 Apple M4 16 GB 393 GB no local Dev machine, go build/test runs here directly
test-win jguan@100.114.25.35 (Tailscale: light-salt) Windows 11 x86_64 i9-13980HX + RTX 4060 8GB (Driver 566, CUDA) 32 GB 551 GB no key Test machine, Windows + NVIDIA GPU validation
gb10 qujing@100.105.58.16 Ubuntu 24.04 aarch64 NVIDIA GB10 (CUDA 13.0, Driver 580) 120 GB unified 149 GB K3S v1.31.4 + Docker 28.5 key GPU inference + K3S full-stack validation
linux-1 cjwx@100.121.255.97 (Tailscale) / cjwx@192.168.109.23 (LAN) Ubuntu 22.04 x86_64 2× NVIDIA RTX 4090 48GB (Driver 580, CUDA 13.0) 503 GB 72 GB Docker key Dual-GPU inference validation
amd395 quings@100.71.145.56 (Tailscale) Ubuntu 24.04 x86_64 AMD Ryzen AI MAX+ 395 + Radeon 8060S (no NVIDIA) 62 GB 57 GB Docker 28.2 key AMD/APU inference validation
hygon qujing@100.113.47.73 (Tailscale) / qujing@192.168.110.24 (LAN) Ubuntu 22.04 x86_64 2× Hygon C86-4G 48C + 8× Hygon BW150 DCU 64GB 751 GB 265 GB + 564 GB NVMe K3S + Docker 28.0 key DCU inference validation
qjq2 root@192.168.0.22 (via qjq0 116.204.103.3) EulerOS 2.0 aarch64 8× Ascend 910B1 64GB HBM (Driver 25.3, CANN 8.3) 1.5 TiB 99 GB Docker 18.09 key (ProxyCommand) Ascend NPU inference validation
m1000 dev@100.123.212.6 (Tailscale) / dev@192.168.108.188 (LAN) Ubuntu 22.04 aarch64 Moore Threads M1000 MUSA GPU (MUSA 3.1.3-AB100, SDK 4.1.4) 62 GB 365 GB Docker key Moore Threads MUSA GPU inference validation
metax-n260 kylin@100.94.119.128 (Tailscale) / kylin@192.168.110.66 (LAN) Kylin V10 (Sword) x86_64 2× Hygon C86-4G 32C + 2× MetaX N260 64GB HBM2e (MACA 3.1.0.14, Driver 3.0.11) 124 GB 230 GB Docker 18.09 key MetaX MACA GPU inference validation
aibook aibook@100.106.164.54 (Tailscale) Ubuntu 22.04 aarch64 Moore Threads M1000 SoC (CPU 12C A78 + GPU MUSA + 2×NPU 50TOPS) 32 GB unified LPDDR5X 711 GB Docker 24.0.7 key AIBook 笔记本,M1000 SoC GPU+NPU 推理验证
w7900d root@36.151.243.68 -p 21985 Ubuntu 24.04 x86_64 2× EPYC 9334 128T + 8× AMD Radeon Pro W7900D 48GB (RDNA3, Navi 31, ROCm 5.7) 1 TiB 3.0 TB NVMe (/disk/ssd1) Docker 29.0 key AMD RDNA3 8-GPU 推理验证, Ollama 0.13.5 预装
gb10-4T qujing@100.91.39.109 (Tailscale) / qujing@192.168.108.131 (LAN) Ubuntu 24.04 aarch64 NVIDIA GB10 (CUDA 13.0, Driver 580) 120 GB unified 2.0 TB (3.7 TB NVMe) Docker 28.5 key DGX Spark GB10, 大容量存储, GPU 推理验证

Maintaining this table: After first SSH to a new machine, run the device probe and update this table. Password: never store passwords here. Use SSH key auth. For initial key setup: ssh-copy-id <user@host>.

Hardware Reference Docs

Vendor-specific hardware reference documents are stored in hardware-reference/.

File Description
hardware-reference/README.md Index and quick reference for M1000
hardware-reference/mt-ai-developer-kit-guide.md M1000 Developer Kit: hardware, connectors, setup, serial/SSH
hardware-reference/vllm-musa-m1000-guide.md vLLM-MUSA on M1000: model download, startup params, troubleshooting
hardware-reference/MT_AI_Developer_Kit_User_Guide_v1.0.1.pdf Original PDF with photos (14 pages)
hardware-reference/metax-n260-vllm-guide.md MetaX N260: hardware specs, mx-smi, vLLM-MetaX Docker deployment
hardware-reference/aibook-m1000-guide.md AIBook M1000 SoC: hardware specs, vLLM-MUSA, NPU/MTNN, pre-loaded models

External (Tencent Docs, not downloadable):

Test Loop Workflow — ALL COLLECT, THEN ANALYZE

核心原则:先全量采集,再统一分析,最后一次性修改。 绝对不要看一台改一台。逐台修复会制造"按下葫芦浮起瓢"的兼容性问题。 每一轮修改必须基于所有设备的完整结果矩阵。

 [1] Develop locally (edit Go / YAML)
      │
 [2] Build: 一次性交叉编译所有目标
      │  go build -o build/aima-darwin-arm64 ./cmd/aima                               # dev-mac (local)
      │  GOOS=windows GOARCH=amd64 go build -o build/aima.exe          ./cmd/aima    # test-win
      │  GOOS=linux   GOARCH=arm64 go build -o build/aima-linux-arm64  ./cmd/aima    # gb10
      │  GOOS=linux   GOARCH=amd64 go build -o build/aima-linux-amd64  ./cmd/aima    # linux-1, amd395, hygon
      │
 [3] Distribute: 同步到所有远程机器
      │  scp build/aima.exe          jguan@100.114.25.35:~/aima.exe        # test-win
      │  scp build/aima-linux-arm64  qujing@100.105.58.16:~/aima
      │  scp build/aima-linux-amd64  cjwx@100.121.255.97:~/aima
      │  scp build/aima-linux-amd64  quings@100.71.145.56:~/aima
      │  scp build/aima-linux-amd64  qujing@100.113.47.73:~/aima
      │  scp build/aima-linux-arm64  qjq2:~/aima                          # qjq2 (reuses gb10's arm64 binary)
      │  scp build/aima-linux-arm64  dev@100.123.212.6:~/aima              # m1000 (arm64)
      │  scp build/aima-linux-amd64  kylin@100.94.119.128:~/aima          # metax-n260 (amd64)
      │  scp build/aima-linux-arm64  aibook@100.106.164.54:~/aima         # aibook (arm64)
      │  scp -P 21985 build/aima-linux-amd64 root@36.151.243.68:~/aima   # w7900d (amd64)
      │  scp build/aima-linux-arm64  qujing@100.91.39.109:~/aima           # gb10-4T (arm64)
      │
 [4] Execute: 对所有设备(含本机)并行执行同一组测试命令
      │  本机:  build/aima-darwin-arm64 hal detect
      │  SSH:   ssh jguan@100.114.25.35      'aima.exe hal detect'         # test-win
      │  SSH:   ssh qujing@100.105.58.16     './aima hal detect'
      │  SSH:   ssh cjwx@100.121.255.97      './aima hal detect'
      │  SSH:   ssh quings@100.71.145.56     './aima hal detect'
      │  SSH:   ssh qujing@100.113.47.73     './aima hal detect'
      │  SSH:   ssh qjq2                        './aima hal detect'
      │  SSH:   ssh dev@100.123.212.6          './aima hal detect'
      │  SSH:   ssh kylin@100.94.119.128       './aima hal detect'          # metax-n260
      │  SSH:   ssh aibook@100.106.164.54      './aima hal detect'          # aibook
      │  SSH:   ssh -p 21985 root@36.151.243.68 './aima hal detect'        # w7900d
      │  SSH:   ssh qujing@100.91.39.109       './aima hal detect'          # gb10-4T
      │
      ╔══════════════════════════════════════════════════════════╗
      ║  ⚠ BARRIER: 等待所有设备返回结果,一台都不能少。       ║
      ║  如果某台超时/不可达,记录为 UNREACHABLE,不要跳过。    ║
      ╚══════════════════════════════════════════════════════════╝
      │
 [5] Collect: 将所有结果汇总为对比矩阵
      │
      │  ┌──────────┬──────────────┬──────────┬──────────────┐
      │  │ 测试项    │ dev-mac      │ test-win │ gb10   │ ... │
      │  ├──────────┼──────────────┼──────────┼──────────────┤
      │  │ hal detect│ ✅ no-gpu   │ ✅ RTX4060│ ❌ N/A parse│
      │  │ engine ls │ ✅           │ ✅       │ ✅          │
      │  │ ...       │              │          │              │
      │  └──────────┴──────────────┴──────────┴──────────────┘
      │
 [6] Analyze: 基于完整矩阵统一分析
      │  - 哪些设备通过、哪些失败、失败模式是否相同
      │  - 是否存在仅在某一架构上出现的 edge case
      │  - 修复方案是否对所有设备都安全(不能只修一个平台)
      │
 [7] Fix: 一次性提交修改,修改必须覆盖所有已知平台
      │
 [8] Re-verify: 回到 [2],再次全量验证,直到矩阵全绿

Standard Test Commands

# --- Device probe (first time or hardware change) ---
ssh <user@host> 'uname -a && cat /etc/os-release 2>/dev/null; sw_vers 2>/dev/null; nvidia-smi 2>/dev/null || echo no-nvidia; free -h 2>/dev/null; df -h / | tail -1'

# --- Smoke test suite (run same commands on EVERY device) ---
./aima version                # or ssh <user@host> './aima version'
./aima hal detect
./aima engine list
./aima model list
./aima deploy list            # only meaningful on K3S-capable devices

Adding a New Machine

  1. Ensure SSH key auth works: ssh-copy-id <user@host>
  2. SSH in and run the device probe command above
  3. Update the Machine Registry table with the results
  4. Determine the correct GOOS/GOARCH for cross-compilation
  5. Add the machine to the sync & test scripts

Conventions

  • Never store passwords in this file or any tracked file. Use SSH keys only.
  • Cross-compile locally. Don't install Go on remote machines — AIMA has zero CGO, so cross-compilation always works.
  • Test results are ephemeral. Don't commit raw test outputs. Summarize findings in commit messages or design docs.
  • One binary per arch. Build outputs go to build/ (gitignored). Name pattern: aima-{os}-{arch}.

Git Flow & Version Management

This project uses Git Flow branching model. Current version: v0.4.x (pre-release).

master ──●──── tag v0.0.1 ──────── tag v0.2.0 ──
          \                        /
develop ───●──●──●──●──feature──●──●
                   \           /
                    feat/xxx──●
Branch Purpose Merges to
master Production releases only. Every commit = a tagged release.
develop Integration branch. Daily development lands here. master (via release)
feat/<name> New features. Branch from develop. develop (via PR)
fix/<name> Bug fixes for develop. Branch from develop. develop (via PR)
release/<ver> Release prep (version bump, final fixes). Branch from develop. master + develop
hotfix/<ver> Urgent fix for production. Branch from master. master + develop

Version Numbering (SemVer)

  • 0.0.1 — Initial foundation release (hardware detection, multi-runtime)
  • 0.2.0 — Support service, Web UI redesign, OpenClaw integration
  • 0.3.0 — Edge Intelligence: OpenClaw full-stack, smart agent routing, RDNA3 support, major refactoring
  • 0.4.0 — Knowledge Autonomy: Explorer Agent Planner (PDCA), Central Advisor+Analyzer, advisory lifecycle, Sync v2, MCP tool consolidation (101→61), aima-service device identity (Phase 1), onboarding wizard, multi-modal benchmark
  • 1.0.0 — Production-ready, stable API contract

Daily Workflow

# Start a new feature
git checkout develop && git pull origin develop
git checkout -b feat/my-feature

# ... develop, commit ...

# Push and create PR to develop
git push -u origin feat/my-feature
# Create PR: feat/my-feature → develop

Release Workflow

# Prepare release
git checkout develop
git checkout -b release/v0.0.2

# Version bump, final fixes, then merge to master
git checkout master
git merge --no-ff release/v0.0.2
git tag -a v0.0.2 -m "Release v0.0.2"
git push origin master --tags

# Back-merge to develop
git checkout develop
git merge --no-ff release/v0.0.2
git branch -d release/v0.0.2

Build with Version Info

VERSION=$(git describe --tags --always)
COMMIT=$(git rev-parse --short HEAD)
BUILD_TIME=$(date -u +%Y-%m-%dT%H:%M:%SZ)
LDFLAGS="-X github.com/jguan/aima/internal/cli.Version=$VERSION \
         -X github.com/jguan/aima/internal/cli.GitCommit=$COMMIT \
         -X github.com/jguan/aima/internal/cli.BuildTime=$BUILD_TIME"

go build -ldflags "$LDFLAGS" -o build/aima ./cmd/aima

Rules for Claude Code

  • Never commit directly to master. Always branch from develop.
  • Never force-push to master or develop. These are protected branches.
  • Feature branches merge to develop only. Only release/hotfix branches touch master.
  • Tag every master merge with the version number.

Roadmap & Gap Analysis

Gap analysis document: design/v1.0-gap-analysis.md — full PRD v1.0 vs current codebase comparison. Before starting any v1.0-targeted work, read that doc first. Keep it updated as gaps are closed. Changelog: CHANGELOG.md — release history with all changes per version.

Current State (v0.4.0)

61 MCP tools, 3 runtimes (K3S/Docker/Native), 11 hardware profiles, 32 engine YAMLs, 28 model YAMLs, 3 deployment scenarios, 3 partition strategies, 5 stack components. Carried from v0.3.0: OpenClaw full-stack integration, Smart Agent routing with model ranking, Engine Profile system with SGLang-KT, AMD RDNA3 (W7900D) 8-GPU validated, god file refactor (cmd/aima/main.go → 46 modules), ZeroClaw removal, embedded Web UI with per-card GPU metrics + multi-socket CPU fix, TUI dashboard (Bubble Tea), ResourceSlot abstraction, knowledge query engine (6 query types), patrol + self-healing auto-diagnosis, L2c golden config injection, time constraint engine filtering. v0.4.0 adds: Explorer Agent Planner (document-driven PDCA with ExplorerWorkspace + 7 bash-like tools + SQLite query tool) replacing single-shot JSON prompt, with PendingWork / search_space / long-context anchor contracts and structured decision-trace logging; Central Advisor Engine + Periodic Analyzer + CentralStore interface (SQLite + Postgres/pgx) + advisory lifecycle (pending→delivered→validated/rejected→expired) + Sync v2 protocol (now in separate aima-central-knowledge repo, deployed at https://aimaservice.ai/central); aima-service device identity Phase 1 (internal/cloud/ canonical surface, internal/support/Bootstrap auto-register + token renew, Central strict mode ?device_id=, aima device register/status/renew/reset + 4 MCP tools); MCP consolidation 101→61 with profile-aware ListToolsForProfile; onboarding cold-start wizard with 5-dimension 0-100 recommend scoring; multi-modal benchmark system (chat/TTS/ASR/T2I/T2V) with V14 SQLite migration; model metadata.aliases for catalog-driven scan-name matching; MCP-initiated tune detached from HTTP request context for long-run stability; engine health_check timeout honored; edge HTTP timeout 600s for LLM reasoning endpoints.

v0.3.0 Completed — "Edge Intelligence"

Focus: OpenClaw full-stack integration, smart agent routing, Engine Profile system, RDNA3 support, god file refactor, catalog expansion.

Task PRD IDs Status Key Files
Parse startup_time_s / cold_start_time_s in model variant loader K4, D5 DONE knowledge/loader.go
Surface cold_start_s + time fields in ResolvedConfig D5, A5 DONE knowledge/resolver.go
Power budget warning in CheckFit() (compare tdp_watts vs deployment) S3, F4 DONE knowledge/resolver.go
L2c auto-promote: after benchmark, promote best config automatically K5 DONE cmd/aima/main.go, internal/sqlite.go
Resource estimation in dry-run response (predicted VRAM/RAM cost) S4 DONE knowledge/resolver.go, cmd/aima/main.go
Power monitoring endpoint (GET /api/v1/power) F4 DONE cmd/aima/main.go
Patrol status/alerts/config MCP tools A2 DONE mcp/tools.go, cmd/aima/main.go
Auto-tuning start/status/stop/results MCP tools A3 DONE mcp/tools.go, cli/tuning.go
Self-healing patrol loop scaffolding A4 DONE cmd/aima/main.go
Engine switch cost evaluation tool A5, D5 DONE mcp/tools.go, cmd/aima/main.go
Performance reference in dry-run + perf overlay (K5) K4, K5 DONE cmd/aima/main.go
Knowledge validation tool (predicted vs actual) F5 DONE mcp/tools.go, cmd/aima/main.go
Power history tracking + MCP tool F4 DONE cmd/aima/main.go, sqlite.go
TUI terminal dashboard (Bubble Tea) F6 DONE internal/tui/tui.go, cli/tui.go
Central knowledge server (SQLite + REST) K9 DONE → 已拆分 internal/central/, cmd/central/ → 独立 repo aima-central-knowledge
Knowledge sync push/pull/status MCP tools K6 DONE mcp/tools.go, cmd/aima/main.go
Open questions resolution from YAML I6 DONE mcp/tools.go, cmd/aima/main.go
App register/provision/list MCP tools D4 REMOVED (v0.4 consolidation — unused, no external consumers) mcp/tools.go, cli/app.go
Power mode/history query MCP tools S3, F4 REMOVED (v0.4 consolidation — subsumed by hardware.metrics + REST /api/v1/power) mcp/tools.go
ResourceSlot abstraction (4 backends) S5 DONE internal/runtime/slot.go
Expand catalog: more model YAMLs for modalities Product metrics TODO catalog/models/

v1.0 Gap Summary (for reference)

Category Complete Partial Missing
Supply (S1-S6) S1, S2 S3, S4, S5 S6
Demand (D1-D5) D1, D2, D3, D5 D4
Knowledge (K1-K9) K1, K2, K3, K5, K6, K7, K8, K9 K4
Control (A1-A5) A1 A2, A3, A4, A5
Feedback (F1-F6) F1, F2, F3 F4, F5, F6
Infrastructure (I1-I6) I1, I2, I3, I4 I5, I6

See design/v1.0-gap-analysis.md §5 for the full 3-tier implementation roadmap.


The Prime Directive: Less Code

Every line of Go code is a liability. The goal is the smallest possible binary that glues mature external tools (K3S, HAMi, containerd, SQLite) together with YAML knowledge.

  • Before writing code, ask: "Can this be a YAML knowledge file instead?"
  • Before adding a function, ask: "Does an existing tool/library already do this?"
  • Before adding an abstraction, ask: "Do I have 3+ concrete uses, or am I guessing?"
  • Before adding error handling, ask: "Can this actually happen, or am I being defensive?"
  • 80% of capability expansion = writing YAML, not Go code.

Architecture Invariants (Never Violate)

Read design/ARCHITECTURE.md §14 for full list. The critical ones:

  1. INV-1/2: No code branches for engine/model types. Engine behavior = YAML. Model metadata = YAML. Adding a new engine or model = writing YAML, zero Go code.
  2. INV-3: Don't manage container lifecycle. K3S does it. AIMA only does: apply / get / delete / logs.
  3. INV-5: MCP tools are the single source of truth. CLI wraps MCP tools. CLI never has logic that MCP tools don't. Agent and human always walk the same code path.
  4. INV-8: Offline-first. All core functions must work with zero network. Network = enhancement, not requirement.

Project Structure

cmd/aima/main.go              # Edge binary entry point
internal/
  hal/                        # Hardware detection (nvidia-smi, /proc)
  k3s/                        # K3S client (kubectl wrapper)
  proxy/                      # HTTP inference proxy (OpenAI-compatible)
  knowledge/                  # go:embed YAML + SQLite relational loader + L0-L3 resolver
                              #   + query engine (query.go) + vector similarity (similarity.go)
                              #   + Pod YAML generator (dynamic GPU resource names)
  runtime/                    # Multi-Runtime: K3S (Pod) + Docker (container) + Native (exec + warmup)
  state/                      # SQLite (modernc.org/sqlite, zero CGO) — v2: 16 tables
  model/                      # Model scan/download/import
  engine/                     # Engine image scan/pull/import + native binary manager
  stack/                      # Tiered stack installer (Docker/CTK/K3S/HAMi, archive/binary/helm, airgap)
  benchmark/                  # Live benchmark runner (SSE streaming, concurrency, percentile stats)
  mcp/                        # MCP server + 56 tool implementations
  agent/                      # Go Agent (L3a) + Dispatcher + Explorer (PDCA agent planner, workspace, tools, harvester)
  cli/                        # Cobra commands (thin wrappers over MCP tools)
  ui/                         # Embedded Web UI (go:embed, Alpine.js SPA on :6188/ui/)
  tui/                        # Terminal dashboard (Bubble Tea, lipgloss)
catalog/                      # Knowledge assets (go:embed, 编译时嵌入)
  embed.go
  hardware/                   # Hardware Profile YAML (incl. gpu.resource_name)
  engines/                    # Engine Asset YAML (incl. source, warmup)
  models/                     # Model Asset YAML
  partitions/                 # Partition Strategy YAML
  stack/                      # Stack Component YAML (K3S, HAMi — install config + airgap sources)
  scenarios/                  # Deployment Scenario YAML (multi-model deployment recipes)
# Runtime overlay: ~/.aima/catalog/{hardware,engines,models,partitions,stack,scenarios}/*.yaml
#   同名 metadata.name 覆盖 go:embed, 新名追加。无需重编译。

Key Commands

go build ./cmd/aima               # Build
go test ./...                      # Test all
go test -race ./...                # Test with race detector
go vet ./...                       # Static analysis

Go Conventions for This Project

  • Zero CGO. SQLite via modernc.org/sqlite. No C dependencies, ever.
  • Standard library first. net/http not gin/echo. log/slog not zap/logrus. encoding/json not jsoniter.
  • Errors wrap with context: fmt.Errorf("resolve config for %s: %w", model, err).
  • Context as first param. Every function that does I/O takes context.Context.
  • Interfaces at consumer, not provider. Define interfaces where they're used, not where they're implemented.
  • Functional options for config: NewServer(addr, WithTimeout(5*time.Second)).
  • No init(), no global state. Everything is dependency-injected via struct constructors.
  • Table-driven tests. Use testdata/ for fixtures.

Design Patterns to Follow

The "Thin CLI" Pattern

Every CLI command is a thin wrapper: parse flags → call MCP tool function → format output. CLI never contains business logic. If you need new logic, add it as an MCP tool first.

// CORRECT: CLI calls MCP tool
func runDeploy(cmd *cobra.Command, args []string) error {
    return mcpTools.DeployApply(ctx, engine, model, slot)
}

// WRONG: CLI contains logic
func runDeploy(cmd *cobra.Command, args []string) error {
    hw := hal.Detect()
    config := knowledge.Resolve(hw, model)
    pod := knowledge.GeneratePod(config)
    return k3s.Apply(pod)  // This logic belongs in deploy.apply MCP tool
}

The "Knowledge-Driven" Pattern

Don't hardcode behaviors per engine/model. Load them from YAML:

// CORRECT: Knowledge-driven
engineAsset, _ := knowledge.FindEngine(engineType, gpuArch)
pod := podgen.Render(engineAsset, modelAsset, partitionSlot)

// WRONG: Code-driven
if engineType == "vllm" {
    pod.Image = "vllm/vllm-openai:latest"
    pod.Command = []string{"vllm", "serve"}
} else if engineType == "llamacpp" {
    // ...more branches for each engine...
}

The "Graceful Degradation" Pattern

Every feature must handle absence of its dependencies:

// L3a unavailable → fall back to L2 → fall back to L0
func (d *Dispatcher) Ask(ctx context.Context, query string) (string, error) {
    if d.goAgent.Available() {
        return d.goAgent.Ask(ctx, query)
    }
    return d.knowledgeResolve(ctx, query)  // L2 deterministic
}

What NOT to Do

  • Don't write strategy/policy code in Go. That's the Agent's job via MCP tools.
  • Don't add engine-specific or model-specific if/switch branches. Use YAML knowledge.
  • Don't manage container lifecycle. K3S handles health checks, restarts, resource limits.
  • Don't create abstractions "for the future." Three concrete uses before abstracting.
  • Don't add comments to code you didn't change. Don't add docstrings unless the function is exported and non-obvious.
  • Don't create wrapper types around standard library types. Use *sql.DB directly, not type Database struct { db *sql.DB } unless there's a real reason.
  • Don't add metrics/tracing/logging infrastructure preemptively. slog.Info() is enough until proven otherwise.
  • Don't create separate files for single types or tiny functions. Keep related code together.

Workflow

  1. Read before writing. Always read existing code before modifying. Understand the pattern first.
  2. Architecture doc is source of truth. When in doubt, consult design/ARCHITECTURE.md.
  3. Test what matters. Test business logic and edge cases. Don't test that Go's JSON marshaling works.
  4. One MCP tool = one function = one responsibility. Keep tool implementations focused.
  5. Commit atomically. Each commit should be a coherent, working unit.
  6. Branch from develop. Never commit directly to master. Feature branches merge to develop via PR.

Domain Terminology

Term Meaning
Engine Asset YAML describing an inference engine (vLLM, llama.cpp, etc) on specific hardware
Model Asset YAML describing a model's variants across hardware/engine combos
Hardware Profile YAML describing a device's GPU/CPU/RAM capability vector
Partition Strategy YAML describing how to split resources across multiple workloads
Knowledge Note Structured record of Agent exploration results (trials + recommendation)
Configuration A tested Hardware×Engine×Model×Config instance with derivation chain
BenchmarkResult Multi-dimensional performance data for a Configuration under specific load
PerfVector 6-dimensional normalized performance vector for similarity search
L0/L1/L2/L3a Progressive intelligence levels: defaults → human CLI → knowledge → Go Agent
ConfigResolver Merges L0-L3 configs, higher layer overrides lower
Store Knowledge query engine wrapping *sql.DB (Search/Compare/Gaps/Similar/Lineage/Aggregate)
MCP Tool JSON-RPC function exposed to Agents (deploy.apply, model.scan, etc)