Immutable. This exact content is served forever at /api/v1/blob/e02757a9d0560c2d.
# MASC-MCP Agent Instructions Multi-Agent Streaming Coordination server. **Common mistakes: `docs/COMMON-PITFALLS.md`** — read before refactoring or deleting modules. Current SSOTs: - Public overview: `README.md` - Spec suite front door: `docs/spec/SPEC-INDEX.md` - Current system overview: `docs/spec/01-system-overview.md` - Public MCP surface and grouping: `docs/MCP-SURFACE-AUDIT.md` Notes: - Tool counts and module snapshots in this file are approximate and may drift. - Prefer script-based local start flows. ## Commands ```bash # Build dune build --root . # Test dune runtest --root . make test # Run (dev) ./start-masc-mcp.sh --http --port 8935 # Type check only dune build --root . @check ``` ## Project Structure ``` bin/ main_eio.ml # Primary HTTP server entry point main_stdio_eio.ml # stdio compatibility entry point lib/ command_plane/ # command-plane subsystems keeper/ # keeper runtime and turn loop team_session/ # team-session engine and artifacts dashboard/ # dashboard providers and read models board/ # board and social surface helpers room/ # room/session/task coordination dashboard/ # Preact/TypeScript dashboard source docs/spec/ # living specification suite scripts/ # harnesses, CI helpers, local review helpers test/ # Alcotest suites and fixtures ``` ## Tech Stack | Layer | Technology | Version | |-------|-----------|---------| | Language | OCaml | 5.x | | Async | Eio | 1.0+ | | HTTP | httpun_eio | HTTP/1.1 | | JSON | yojson + ppx_deriving_yojson | 2.0+ / 3.6+ | | GraphQL Client | cohttp-eio | 6.0+ | | Neo4j | neo4j_bolt_eio | 0.4+ | | PostgreSQL | caqti-eio + caqti-driver-postgresql | 2.1+ | | Build | dune | 3.13 | ## Code Conventions ### OCaml Patterns - **Parse, Don't Validate**: Use newtype modules (Post_id, Agent_id, Task_id) — no raw strings for IDs - **Eio.Mutex for shared state**: `use_rw ~protect:true` for writes, `use_ro` for reads - **Result types** for fallible operations — avoid exceptions for expected failures - **Fun.protect ~finally** for resource cleanup (not bare try/with) - **No Obj.magic** — find the correct type instead ```ocaml (* Correct: newtype module for type safety *) module Post_id : sig type t val of_string : string -> (t, string) result val to_string : t -> string end (* Correct: Eio mutex pattern *) let with_lodge_lock f = match !lodge_lock with | Some mutex -> Eio.Mutex.use_rw ~protect:true mutex f | None -> f () (* Correct: local heartbeat model-pool config *) let heartbeat_action_models = [ "llama:qwen3.5-35b-a3b-ud-q8-xl"; "glm:auto"; ] ``` ### Naming - Module files: `snake_case.ml` - Types: `snake_case` - Variants: `PascalCase` - Functions: `snake_case` - Config: `SCREAMING_SNAKE_CASE` for env vars ### Error Handling - Return `(bool * string)` for tool handler results (true = success) - Return `(ok_type, Types.masc_error) result` for Room operations - Log with `Eio.traceln` (structured), `Printf.printf` (progress), `Printf.eprintf` (errors) ## Testing ```bash # Full test suite dune runtest --root . # Single test dune exec --root . test/test_board.exe # Type check without linking dune build --root . @check ``` - Tests use `Alcotest` framework - Board tests verify crypto ID generation, TTL sweeping, path traversal safety - Metrics tests verify JSONL append and aggregation ## Git Workflow - Branch: `feature/description` or `fix/description` - Commit prefix: `feat`, `fix`, `refactor`, `docs`, `chore`, `test` - PR: always Draft first, squash merge - No force push to main ## Protocols | Protocol | Status | Spec | |----------|--------|------| | MCP (Layer 2) | Production | JSON-RPC over SSE + POST | | A2A (Layer 3) | Partial | Agent Card + delegation + subscription | | AG-UI (Layer 1) | Planned | SSE event mapping | ## Infrastructure | Service | Endpoint | |---------|----------| | MASC Dev | `localhost:8935` | | MASC Prod | `localhost:8945` (Cloudflare tunnel: `masc.crying.pictures`) | | GraphQL | `second-brain-graphql-production.up.railway.app` | | Neo4j | `turntable.proxy.rlwy.net:11490` | ## Boundaries ### Always Do - Run `dune build --root .` after any .ml file change to verify compilation - Use newtype modules for IDs (Post_id, Agent_id, Task_id) - Protect shared mutable state with Eio.Mutex - Use `Fun.protect ~finally` for resource cleanup - Add `[@@deriving yojson]` for types that cross JSON boundaries - Check GraphQL cost limits (GRAPHQL_MAX_COST = 2000) ### Ask First - Changes to `room.ml` state machine (affects all coordination) - Changes to `lodge_heartbeat.ml` tick logic (affects autonomous agents) - Adding new MCP tool registrations in `tools.ml` - Modifying `config/cascade.json` model ordering - Changes to `board.ml` post ID generation (cryptographic) ### Never Do - Use `Obj.magic` to bypass type system - Commit API keys or tokens (use env vars via `env_config.ml`) - Force push to main - Remove the Eio.Mutex protection on `active_agents` - Call Neo4j directly — use GraphQL layer (`sb graphql`) - Add blocking I/O in Eio fibers (use Eio equivalents)