# AGENTS.md — MSO agent instructions `CLAUDE.md` is the full repository/operator contract and remains authoritative. Read it before changing MSO. This file gives non-Claude agents the minimum routing needed to avoid re-discovering the same failure patterns. Volatile host, ownership, and freshness facts live in [`.mso/KNOWLEDGE.md`](./.mso/KNOWLEDGE.md). ## Systematic implementation default For debugging, integrations, refactors, deployments, and MCP work, use this loop: 1. **Resolve the real target** — identify the canonical repository, active branch, running process/container, deployed version, state directory, and public route. Never edit the first matching clone, package cache, generated build, or `/tmp` checkout. 2. **Observe before changing** — reproduce the behavior and preserve the first concrete error, response, screenshot, cookie, process state, or diff that proves it. 3. **Map the pattern end to end** — trace entry point → adapter/schema → handler → shared guard/state → UI/client → deploy/runtime. Find a working sibling implementation before inventing a new architecture. 4. **Name the limits** — record scope, permissions, trust, client caches, pagination/cursors, process lifetime, ports/domains, persistence, cross-repo contracts, and deployment boundaries. Separate facts, inferences, and unknowns. 5. **Run the smallest discriminating experiment** — test one hypothesis at a time. Do not stack several speculative fixes or retry an unchanged command without new information. 6. **Make one reversible change** — preserve current configuration and data, keep a rollback, and change the smallest authoritative layer rather than patching symptoms in every caller. 7. **Verify in layers** — targeted test → contract/parity check → build → runtime health → browser/mobile/session-restart proof when applicable. A zero exit code is not proof of the requested behavior. 8. **Record the reusable pattern** — durable workflow policy belongs in `AGENTS.md`, `CLAUDE.md`, or a trusted `SKILL.md`; implementation contracts belong in current docs; volatile host facts stay in project/runbook notes. ## Frontend ownership Before any UI, UX, state or responsive change, read [`docs/FRONTEND-CONTRACT.md`](./docs/FRONTEND-CONTRACT.md), `DESIGN.md` and the affected shell/feature contracts. This applies to every feature and native DOM UI in `lib/`, not only Integrations. Whole-product work must record per-feature evidence and unverified/configuration limits; a shared foundation change alone is not proof of every consumer journey. ## Architecture ownership Before adding another adapter/facade/barrel, read [`docs/ARCHITECTURE.md`](./docs/ARCHITECTURE.md) and run `node scripts/check-architecture.mjs`. The architecture policy is ratcheted: transports share `lib/capabilities`, cross-layer DTOs live in `lib/contracts`, host calls use narrow `lib/host/*-api.ts`, generic apps use AppShell directly, and workflow persistence belongs to `lib/workflow`. Do not raise a ratchet just to make a change pass. Exact MCP catalog facts are generated with `node scripts/gen-mcp-catalog.mjs`; never hand-copy the current tool list into reference docs. ## Hosts / dual-instance MSO has **two separate hosts**. Do not conflate them: - **Grok box cache** and the **laptop/WSL live cockpit** are different deployments, each with its own operator host (portable docs use `mso-grok.example.com` and `mso.example.com`), passwords, approved devices, builds, and tunnels. - Never retarget the laptop cockpit tunnel or change that live instance from box work unless Rahman asks. - Current tunnel IDs, store paths, and ports are volatile: read `.mso/KNOWLEDGE.md`. Do not hard-code guessed host facts into new docs. ## Repository and worktree policy - The repository root resolved by `git rev-parse --show-toplevel` on `main` is the **canonical MSO checkout and release SSOT for this installation**. Do not infer another operator's home/project path or create task-specific sibling checkouts under the projects root. - Parallel coding/review tasks may use isolated Git worktrees only under `~/.cache/mso-worktrees/mso-`. Never let two sessions share one worktree, HEAD, or index. - Keep development worktrees out of `~/.mso`: that tree is private runtime/credential state and is deliberately denied by MSO host-file guards. `~/.cache/mso-worktrees` is disposable developer isolation. - A worktree is disposable development isolation, **never an install or release source**. Every user-deliverable change must be committed, reconciled into `main`, verified, and present on `origin/main` before the task can be called shipped. The installer/updater consumes `main`. - Never delete or prune a dirty worktree. First preserve its tracked and untracked work in a commit/branch or explicit archive, then verify that the deliverable commits are reachable from `main` (or intentionally retained as non-release work). - Demo/review runtimes may have hidden internal checkouts, but they do not become a second source of truth and must not be presented as another MSO project. ## Agent-work coding path (Rahman laptop / fleet) When coding on Rahman's laptop for fleet work: - Work **only** under `~/agent-work/mso/` (separate clone). Never edit `~/projects/**` or the live WSL MSO checkout. - Prefer `opencode2 --auto` inside that clone. Do **not** use Cursor cloud agents (Rahman 2026-10-22). - Local commits are OK. Push, PR, and merge need Rahman GO in his own words (agent-relayed OK does not count). - This install's parallel coding/review worktrees under `~/.cache/mso-worktrees/` remain valid; they are not a substitute for the fleet `~/agent-work/mso/` path on the laptop. ## Install and update requests When a user asks an agent to "install MSO from this repo" or "update MSO", do not invent a parallel setup flow. Read `README.md` + `docs/INSTALL.md` and use the repository-owned entry points: - fresh install or legacy install without `mso update`: run the official `scripts/install.sh` bootstrap; - current install: prefer `mso update` or the equivalent Settings → Update MSO action; - never create a second checkout when `mso.service` already owns one; preserve `.env.local`, `~/.mso`, and any dirty/diverged source rather than resetting it; - finish with `mso doctor` plus runtime health, and report only the remaining action the user must take; - when a provider credential is required, name the official place/endpoint to create it and where MSO stores it, then use hidden/STDIN input. Never place a secret in argv, Git, documentation, or agent logs. ## MCP feature work Use [`docs/MCP-FEATURE-IMPLEMENTATION.md`](./docs/MCP-FEATURE-IMPLEMENTATION.md) and the official [`mso-mcp-feature-engineering`](./claude-skills/mso-mcp-feature-engineering/SKILL.md) skill. Public MCP tool names, schemas, scope, audit metadata, parity, toolset signature, external mappings, skill trust/routing, and client action refresh are one release contract. Do not declare an MCP change complete until that full contract is verified. Agents *using* MSO over MCP start from [`docs/AGENT-BOOTSTRAP.md`](./docs/AGENT-BOOTSTRAP.md) and official skill `mso-agent-bootstrap`, not by jumping to `exec_run`. ## Integrations / Convex - There is **one** Convex provider with a **project dimension** (#160 / closes #152). - Do **not** reintroduce dual `convex` / `convex-cloud` cards, dual registry rows, or operations that 404 on self-hosted Convex. - Provider UI and infra code must treat cloud vs self-hosted as a dimension of one provider, not two providers. ## Composio Connect - Composio Connect API keys (`ck_…`) route to `connect.composio.dev/mcp` (#146 / #148). - Validate Connect keys at the Connect MCP endpoint; do not assume the older platform MCP host for `ck_` keys. ## Agent UI - One live agent activity row per turn; turn budgets are env-tunable (#154). - Settings update cue is a **single in-Settings signal** (Updates nav badge + Software update section). Do not bring back a new-version toast or dock-adjacent floating badge (#161). - User-visible copy must **not** use em dashes (U+2014). Antislop R-02 is a hard gate (#162). ## License - The repository is under **PolyForm Noncommercial** (#155). Read `LICENSE` before reintroducing or asserting any other license claim in docs, UI, or packaging. ## Cognitive-runtime work - The LLM provider is replaceable. Do not solve MSO agent quality by hard-coding one vendor's hidden reasoning/session behavior when the same invariant can live in the provider-neutral harness. - Preserve the three identity boundaries: authenticated client principal → durable conversation session → exact workflow/job. Active work is session-scoped; verified recipes may be client-scoped. - Public MCP remains capability-complete. MSO-owned model harnesses may defer/select schemas, compact history, or bound tool output only when capability recall and permissions remain unchanged. - Any context/tool optimization must run `bun run bench:cognitive`; smaller prompts are not a win if required-tool recall, deterministic behavior, verification, or security regresses. - Competitor claims require comparable measurements. A Hermes prompt-size win is not an overall Hermes win; do not claim OpenClaw superiority until an equivalent task/quality benchmark exists. - The current contract and P1 boundaries live in `docs/COGNITIVE-RUNTIME.md`. ## Comparison and privileged operations - `docs/comparison-data.json` is the comparison SSOT. Generate README/`docs/COMPARISON.md` with `node scripts/gen-comparison.mjs`; never edit those outputs manually or improve an MSO rating without existing code evidence. Use SEO-readable words (`Strong`, `Partial`, `Not offered`), never icon-only status legends; use official sources and honor the freshness gate. - Preserve the live Viewer/Operator/Owner route policy. UI filtering is not authorization; unknown mutations must fail to Owner. Device roles are not Linux users or SSO. - System service actions require exact owner allowlisting and fixed argv. Do not add wildcard units, raw `systemctl` arguments, or package-update/apply buttons to the Viewer/Operator surface. ## Pull request readiness (mandatory for all coding agents) **A code change is not PR-ready because it compiles or has been committed.** After targeted tests and a local commit on an isolated worktree: 1. Run `bun run pr:local` and capture the exact HEAD SHA + first failure. This reuses the full committed `scripts/gates.sh`: typecheck, lint, coverage, architecture/docs/audit, isolated build, and mandatory browser journeys. 2. Run `bun run pr:security` when Docker is available (pinned Semgrep + ShellCheck, same arguments/images as CI). **No Docker, failed scan, or incomplete evidence is BLOCKED, not PASSED.** Never interpret Semgrep's "0 findings" as success when its process exits nonzero; `--strict` also checks parse warnings. 3. If any check fails, fix it and rerun. If an environment prerequisite cannot be satisfied, create/leave a **Draft PR**, record the missing evidence, and do not assert "ready" or bypass checks. Never use `--no-verify`, `SKIP`, branch protection bypass, scanner suppression, or `continue-on-error` to fake green. 4. After opening the draft, verify the exact pushed SHA in GitHub Actions. CodeQL/Code scanning, Dependency Review and other remote required checks must complete successfully; resolve all actual review threads after fixing their underlying issues, then mark the PR ready. CodeQL new alerts require real remediation and retesting, not a blanket dismissal. 5. Report a compact evidence table: SHA, local result, security result, remote result, failing log URLs, unresolved threads, and merge-readiness. Never merge/declare shipped while required checks are red or the PR is a draft. Run `bun run pr:preflight` to request both local and scanner parity in one command. The gate exits 2 when required local tools are missing. If security scanners cannot run locally, CI can provide the missing evidence *after* a Draft PR; a local-only pass never implies CodeQL approval. ## Shipping Run validation with `umask 077`: security fixtures must create private files/directories, not inherit group-writable shell defaults. On a busy shared host, bound Vitest concurrency with `VITEST_MAX_WORKERS=2` before changing timeout or coverage limits. Follow `CLAUDE.md`: update `docs/PROGRESS.md`, run the relevant gates, and ship through `bun run ship ""`. Do not replace the repository's release path with a bare push. ## antislop UI, copy, people, mobile layout, and code-comment work is filtered by antislop before it ships. - Core filter, read first: `antislop` skill - UI and visual: `antislop-ui` - Copy and text: `antislop-copywriting` - People, contrast, keyboard: `antislop-human` - Mobile and responsive: `antislop-layoutmobile` - Code comments: `antislop-code` Hard gates that already apply to this repo, so a review will reject a change that breaks them: - No em dash in user-visible strings. Comments and docs are out of scope. - No fabricated numbers, testimonials, or security claims. - Every interactive element has real behaviour; no dead controls. - Text meets WCAG AA contrast; the repo gate is `node scripts/check-contrast.mjs`. - Both shipped themes must work. Design direction lives in `DESIGN.md`. Read it before any UI work. If it is absent, say so and treat the result as a draft without direction. If a rule and a task conflict, name the rule and ask. Do not silently override either one.