# Agent Guidelines — Mosaic Stack ## Required Load Order 1. `~/.config/mosaic/SOUL.md` 2. `~/.config/mosaic/STANDARDS.md` 3. `~/.config/mosaic/AGENTS.md` 4. `~/.config/mosaic/guides/E2E-DELIVERY.md` 5. `AGENTS.md` (this file) 6. Runtime-specific guide: `~/.config/mosaic/runtime//RUNTIME.md` ## Project Context Mosaic Stack is a self-hosted, multi-user AI agent platform. It is a TypeScript monorepo with a NestJS gateway, Next.js dashboard, Pi SDK agent runtime, and Discord/Telegram plugin architecture. ### Stack - **API:** NestJS with Fastify (`apps/gateway`) - **Web:** Next.js 16 with React 19 (`apps/web`) - **ORM and database:** Drizzle ORM, PostgreSQL 17, and pgvector (`packages/db`) - **Authentication:** BetterAuth (`packages/auth`) - **Agent runtime:** Pi SDK (`apps/gateway`, `packages/mosaic`) - **Queue:** Valkey 8 (`packages/queue`) - **Build:** pnpm workspaces and Turborepo - **CI:** Woodpecker CI - **Observability:** OpenTelemetry and Jaeger ### Package Map | Package | Purpose | Key Dependencies | | ------------------ | ----------------------------- | -------------------------------- | | `apps/gateway` | NestJS API + WebSocket hub | Fastify, Socket.IO, Pi SDK, OTEL | | `apps/web` | Next.js dashboard | React 19, Tailwind | | `packages/types` | Shared TypeScript contracts | class-validator | | `packages/db` | Drizzle schema and migrations | drizzle-orm, postgres | | `packages/auth` | BetterAuth configuration | better-auth, @mosaicstack/db | | `packages/brain` | Structured data layer | @mosaicstack/db | | `packages/queue` | Valkey task queue and MCP | ioredis | | `packages/coord` | Mission coordination | @mosaicstack/queue | | `packages/mosaic` | Unified `mosaic` CLI and TUI | Ink, Pi SDK, commander | | `plugins/discord` | Discord channel plugin | discord.js | | `plugins/telegram` | Telegram channel plugin | Telegraf | ## Architecture and Code Conventions 1. Gateway is the single API surface; all clients connect through it. 2. Pi SDK is ESM-only; gateway and CLI code must remain ESM. 3. Use `"type": "module"`, NodeNext module resolution, and `.js` extensions in imports. 4. Keep typed Socket.IO events in `@mosaicstack/types` to enforce client/server contracts. 5. Import OTEL tracing before NestJS bootstrap (`import './tracing.js'`). 6. Use explicit `@Inject()` decorators in NestJS because tsx/esbuild does not emit decorator metadata. 7. Keep DTOs in `*.dto.ts` files at module boundaries. 8. BetterAuth owns authentication tables; their schema is defined in `@mosaicstack/db`. 9. Create a task-specific scratchpad for non-trivial work. ## Development Workflow Requirements: Node.js 20+, pnpm 10.6.2, and Docker Compose when optional local services are needed. ```bash pnpm install --frozen-lockfile pnpm preflight # Optional local queue service only; do not start the full Compose stack. docker compose up -d valkey ``` The pre-push hook requires: ```bash pnpm preflight && pnpm typecheck && pnpm lint && pnpm format:check ``` Software delivery also requires the applicable tests. Common repository commands are: ```bash pnpm typecheck # TypeScript checks across the workspace pnpm lint # ESLint across the workspace pnpm test # Checkout tests and package Vitest suites pnpm format:check # Prettier check pnpm build # Build all packages and applications ``` ## Database and Local Runtime Safety - Current local data-layer work uses in-process PGlite; leave `DATABASE_URL` unset. - PostgreSQL execution is held until KBN-101-00, KBN-101-03, and KBN-101-05 land. - Do not invoke a migration runner, initialization SQL, or the Compose PostgreSQL service from this checkout. - Do not start Gateway/Web or run root `pnpm dev` as a local PGlite route. The current dotenv loader can inherit a daemon PostgreSQL DSN; KBN-101-02 must make that path fail closed first. - Migration artifact generation is offline and does not authorize PostgreSQL access: ```bash pnpm --filter @mosaicstack/db db:generate ``` ## docs/TASKS.md — Schema (CANONICAL) The `agent` column specifies the required model for each task. **This is set at task creation by the orchestrator and must not be changed by workers.** | Value | When to use | Budget | | --------- | ----------------------------------------------------------- | -------------------------- | | `codex` | All coding tasks (default for implementation) | OpenAI credits — preferred | | `glm-5.1` | Cost-sensitive coding where Codex is unavailable | Z.ai credits | | `haiku` | Review gates, verify tasks, status checks, docs-only | Cheapest Claude tier | | `sonnet` | Complex planning, multi-file reasoning, architecture review | Claude quota | | `opus` | Major cross-cutting architecture decisions ONLY | Most expensive — minimize | | `—` | No preference / auto-select cheapest capable | Pipeline decides | Pipeline crons read this column and spawn accordingly. Workers never modify `docs/TASKS.md` — only the orchestrator writes it. **Full schema:** ``` | id | status | description | issue | agent | repo | branch | depends_on | estimate | notes | ``` - `status`: `not-started` | `in-progress` | `done` | `failed` | `blocked` | `needs-qa` - `agent`: model value from table above (set before spawning) - `estimate`: token budget e.g. `8K`, `25K`