# Mosaic Stack

Self-hosted, multi-user AI agent platform. One config, every runtime, same standards.

Mosaic gives you a unified launcher for Claude Code, Codex, OpenCode, and Pi — injecting consistent system prompts, guardrails, skills, and mission context into every session. A NestJS gateway provides the API surface, a Next.js dashboard gives you the UI, and a plugin system connects Discord, Telegram, and more.

## Quick Install

```bash
curl -fsSL https://mosaicstack.dev/install.sh | bash
```

Or use the direct URL:

```bash
bash <(curl -fsSL https://git.mosaicstack.dev/mosaicstack/stack/raw/branch/main/tools/install.sh)
```

The installer auto-launches the setup wizard, which walks you through gateway install and verification. Flags for non-interactive use:

```bash
bash <(curl -fsSL …) --yes               # Accept all defaults
bash <(curl -fsSL …) --yes --no-auto-launch  # Install only, skip wizard
```

This installs both components:

| Component               | What                                                             | Where                |
| ----------------------- | ---------------------------------------------------------------- | -------------------- |
| **Framework**           | Bash launcher, guides, runtime configs, tools, skills            | `~/.config/mosaic/`  |
| **@mosaicstack/mosaic** | Unified `mosaic` CLI — TUI, gateway client, wizard, auto-updater | `~/.npm-global/bin/` |

### Install lanes

| Lane                     | Command                               | Use when                                              | Source                                                                  |
| ------------------------ | ------------------------------------- | ----------------------------------------------------- | ----------------------------------------------------------------------- |
| Stable                   | `bash tools/install.sh`               | You want the released Mosaic CLI/framework            | npm registry `@mosaicstack/mosaic@latest` + framework archive at `main` |
| Prerelease integration   | `bash tools/install.sh --next`        | You want the current `next` integration branch        | Build-from-source at `next`                                             |
| Contributor/source build | `bash tools/install.sh --dev --ref X` | You are testing a branch before release; `--ref` wins | Build-from-source at the requested ref                                  |

`--next` is shorthand for the prerelease integration lane: it enables source-build mode and uses `next` unless an explicit `--ref` or `MOSAIC_REF` is provided.

After install, the wizard runs automatically or you can invoke it manually:

```bash
mosaic wizard        # Full guided setup (gateway install → verify)
```

### Requirements

- Node.js ≥ 22
- npm (for global @mosaicstack/mosaic install)
- One or more runtimes:
  - [Claude Code](https://docs.anthropic.com/en/docs/claude-code)
  - [Codex](https://github.com/openai/codex)
  - [OpenCode](https://opencode.ai)
  - [Pi](https://pi.dev)

## Usage

### Launching Agent Sessions

```bash
mosaic pi                    # Launch Pi with Mosaic injection
mosaic claude                # Launch Claude Code with Mosaic injection
mosaic codex                 # Launch Codex with Mosaic injection
mosaic opencode              # Launch OpenCode with Mosaic injection

mosaic yolo claude           # Claude with dangerous-permissions mode
mosaic yolo pi               # Pi in yolo mode
```

The launcher verifies your config, checks for `SOUL.md`, injects your `AGENTS.md` standards into the runtime, and forwards all arguments.

Pi launches default to a token-lean skill posture: `mosaic pi` passes `--no-skills` so Pi does not preload every global skill description into the system prompt. Use `MOSAIC_PI_SKILL_MODE=all mosaic pi` for the legacy all-skills catalog, or `MOSAIC_PI_SKILL_MODE=discover mosaic pi` to let Pi use its native settings/project skill discovery.

Mosaic also loads its Pi extensions from `~/.config/mosaic/runtime/pi/`. Inside Pi,
`/goal set <statement>` starts a bounded persistent loop that checks every turn and successful
compaction, requires two evidence-bearing completion reports, and can be inspected or stopped with
`/goal status`, `/goal pause`, `/goal resume`, and `/goal cancel`. Controller-owned goal-state
entries redact common credential shapes, but Pi's model/tool-call history is separate, so goals and
evidence must never contain secrets or raw sensitive output. Mosaic does not install this extension
into `~/.pi/agent/extensions/`.

### TUI & Gateway

```bash
mosaic tui                   # Interactive TUI connected to the gateway
mosaic gateway login         # Authenticate with a gateway instance
mosaic sessions list         # List active agent sessions
```

### Gateway Management

```bash
mosaic gateway install       # Install and configure the gateway service
mosaic gateway verify        # Post-install health check
mosaic gateway login         # Authenticate and store a session token
mosaic gateway config rotate-token    # Rotate your API token
mosaic gateway config recover-token  # Recover a token via BetterAuth cookie
```

If you already have a gateway account but no token, use `mosaic gateway config recover-token` to retrieve one without recreating your account.

### Configuration

Mosaic supports three storage tiers: `local` (PGlite, single-host), `standalone` (PostgreSQL, single-host), and `federated` (PostgreSQL + pgvector + Valkey, multi-host). See [Federated Tier Setup](docs/federation/SETUP.md) for multi-user and production deployments, or [Migrating to Federated](docs/guides/migrate-tier.md) to upgrade from existing tiers.

```bash
mosaic config show           # Print full config as JSON
mosaic config get <key>      # Read a specific key
mosaic config set <key> <val># Write a key
mosaic config edit           # Open config in $EDITOR
mosaic config path           # Print config file path
```

### Management

```bash
mosaic doctor                # Health audit — detect drift and missing files
mosaic sync                  # Sync skills from canonical source
mosaic skill list            # Audit Claude skill registrations and conflicts
mosaic skill register <name> # Register one canonical skill with Claude Code
mosaic skill unregister <name> # Remove one Mosaic-owned Claude link
mosaic update                # Update CLI/framework and auto-register canonical skills
mosaic wizard                # Full guided setup wizard
mosaic bootstrap <path>      # Bootstrap a repo with Mosaic standards
mosaic coord init            # Initialize a new orchestration mission
mosaic prdy init             # Create a PRD via guided session
```

### Sub-package Commands

Each Mosaic sub-package exposes its API surface through the unified CLI:

```bash
# User management
mosaic auth users list
mosaic auth users create
mosaic auth sso

# Agent brain (projects, missions, tasks)
mosaic brain projects
mosaic brain missions
mosaic brain tasks
mosaic brain conversations

# Agent forge pipeline
mosaic forge run [--simulate]        # fails closed (FORGE_NO_EXECUTOR) with no executor wired; --simulate for typed simulated runs
mosaic forge status
mosaic forge resume [--simulate]     # same fail-closed rule as forge run
mosaic forge personas

# Structured logging
mosaic log tail
mosaic log search
mosaic log export
mosaic log level

# MACP protocol
mosaic macp tasks
mosaic macp submit
mosaic macp gate
mosaic macp events

# Agent memory
mosaic memory search
mosaic memory stats
mosaic memory insights
mosaic memory preferences

# Task queue (Valkey)
mosaic queue list
mosaic queue stats
mosaic queue pause
mosaic queue resume
mosaic queue jobs
mosaic queue drain

# Object storage
mosaic storage status
mosaic storage tier
mosaic storage export
mosaic storage import
# Schema migration is unavailable in this release. The current storage wrapper shells
# directly to `pnpm --filter @mosaicstack/db db:migrate`; it is legacy N-1,
# uncertified, and MUST NOT be invoked pending KBN-101-02/-03/-06/-08 activation.
# Future schema migration is non-operative: external bootstrap → TLS/roles → runner
# --run → runner --verify → readiness. Tier copy uses only the separately held secure
# migrate-tier route.
```

### Telemetry

```bash
# Local observability (OTEL / Jaeger)
mosaic telemetry local status
mosaic telemetry local tail
mosaic telemetry local jaeger

# Remote telemetry (dry-run by default)
mosaic telemetry status
mosaic telemetry opt-in
mosaic telemetry opt-out
mosaic telemetry test
mosaic telemetry upload        # Dry-run unless opted in
```

Consent state is persisted in config. Remote upload is a no-op until you run `mosaic telemetry opt-in`.

## Development

### Prerequisites

- Node.js ≥ 22
- pnpm 10.6+
- Docker & Docker Compose

### Setup

```bash
git clone git@git.mosaicstack.dev:mosaicstack/stack.git
cd stack

# Install dependencies. The local tier uses in-process PGlite; leave DATABASE_URL unset.
# The pnpm store defaults to $HOME/.local/share/pnpm/store. Override it without
# editing the checkout with NPM_CONFIG_STORE_DIR=$HOME/another-store if needed.
pnpm install

# Verify dependencies and generated state before running source-quality gates.
# Missing dependencies exit 42; stale/foreign apps/web/.next state exits 43.
# The web build certifies its exact standalone symlink manifest; added, removed,
# retargeted, or manifest-only-tampered generated links also exit 43. This detects
# accidental, independent, stale, and foreign-residue mutation—the class exposed by
# a five-month-stale .next that produced 19 phantom TS2307 errors.
# It does NOT defend against a same-UID actor that can rewrite both manifest and
# marker consistently (CWE-345). RM-59 tracks the required executor/spine-side
# trust anchor outside worktree authority.
pnpm preflight

# Optional local queue service only. This does not start PostgreSQL.
docker compose up -d valkey

# The current Gateway/Web local process is held; see docs/guides/dev-guide.md.
# Do not start it until KBN-101-02 makes inherited dotenv/DSN state fail closed.
```

### Held future procedure

The checked-in Compose PostgreSQL service mounts legacy initialization SQL and is **not** a
current PostgreSQL, standalone, or federated developer route. Do not start it with Compose,
invoke initialization SQL, or treat the planned migrator as currently executable.

**Held future activation procedure — non-operative and no current command authority until KBN-101-00, KBN-101-03, and KBN-101-05
land:** external bootstrap → TLS/roles → `mosaic-db-migrator --run` →
`mosaic-db-migrator --verify` → Gateway/Compose readiness. The future deployment artifacts—not
this README—will provide the reviewed commands and secret-consumer interface.

For local data-layer work, PGlite needs no PostgreSQL service. The optional Compose command above
starts only Valkey; OTEL Collector and Jaeger may likewise be started individually if needed,
without starting PostgreSQL. A Gateway/Web local process is not currently a safe PGlite route:
its unguarded dotenv loader may inherit a daemon PostgreSQL DSN. Do not use root `pnpm dev` or a
Gateway start command until KBN-101-02 makes that state fail closed.

### Quality Gates

```bash
pnpm preflight               # Checkout/dependency/generated-state validation
pnpm typecheck               # TypeScript type checking (all packages)
pnpm lint                    # ESLint (all packages)
pnpm test                    # Vitest (all packages)
pnpm format:check            # Prettier check
pnpm format                  # Prettier auto-fix
```

### CI

Woodpecker CI runs on every push:

- `pnpm install --frozen-lockfile`
- **Legacy N-1 CI status only — active, uncertified, and non-authorizing as an operator route:** the checked-in job currently invokes `pnpm --filter @mosaicstack/db run db:migrate` with `DATABASE_URL` against an isolated disposable PostgreSQL CI database. It performs direct DDL in that CI database, is not approved ordinary behavior or an operator route, and remains a known exception pending KBN-101-06 removal/replacement by the certified runner-backed CI path.
- `pnpm test` (Turbo-orchestrated across all packages)

npm packages are published to the Gitea package registry on main merges.

## Architecture

```
stack/
├── apps/
│   ├── gateway/             NestJS API + WebSocket hub (Fastify, Socket.IO, OTEL)
│   └── web/                 Next.js dashboard (React 19, Tailwind)
├── packages/
│   ├── mosaic/              Unified CLI — TUI, gateway client, wizard, sub-package commands
│   ├── types/               Shared TypeScript contracts (Socket.IO typed events)
│   ├── db/                  Drizzle ORM schema + migrations (pgvector)
│   ├── auth/                BetterAuth configuration
│   ├── brain/               Data layer (PG-backed)
│   ├── queue/               Valkey task queue + MCP
│   ├── coord/               Mission coordination
│   ├── forge/               Multi-stage AI pipeline (intake → board → plan → code → review)
│   ├── macp/                MACP protocol — credential resolution, gate runner, events
│   ├── agent/               Agent session management
│   ├── memory/              Agent memory layer
│   ├── log/                 Structured logging
│   ├── prdy/                PRD creation and validation
│   ├── quality-rails/       Quality templates (TypeScript, Next.js, monorepo)
│   └── design-tokens/       Shared design tokens
├── plugins/
│   ├── discord/             Discord channel plugin (discord.js)
│   ├── telegram/            Telegram channel plugin (Telegraf)
│   ├── macp/                OpenClaw MACP runtime plugin
│   └── mosaic-framework/    OpenClaw framework injection plugin
├── tools/
│   └── install.sh           Unified installer (framework + npm CLI, --yes / --no-auto-launch)
├── scripts/agent/           Agent session lifecycle scripts
├── docker-compose.yml       Dev infrastructure
└── .woodpecker/             CI pipeline configs
```

### Key Design Decisions

- **Gateway is the single API surface** — all clients (TUI, web, Discord, Telegram) connect through it
- **ESM everywhere** — `"type": "module"`, `.js` extensions in imports, NodeNext resolution
- **Socket.IO typed events** — defined in `@mosaicstack/types`, enforced at compile time
- **OTEL auto-instrumentation** — loads before NestJS bootstrap
- **Explicit `@Inject()` decorators** — required since tsx/esbuild doesn't emit decorator metadata

### Framework (`~/.config/mosaic/`)

The framework is the bash-based standards layer installed to every developer machine:

```
~/.config/mosaic/
├── AGENTS.md              ← Central standards (loaded into every runtime)
├── SOUL.md                ← Agent identity (name, style, guardrails)
├── USER.md                ← User profile (name, timezone, preferences)
├── TOOLS.md               ← Machine-level tool reference
├── bin/mosaic             ← Unified launcher (claude, codex, opencode, pi, yolo)
├── guides/                ← E2E delivery, orchestrator protocol, PRD, etc.
├── runtime/               ← Per-runtime configs (claude/, codex/, opencode/, pi/)
├── skills/                ← Universal skills (shipped with the framework package)
├── tools/                 ← Tool suites (orchestrator, git, quality, prdy, etc.)
└── memory/                ← Persistent agent memory (preserved across upgrades)
```

### Forge Pipeline

Forge is a multi-stage AI pipeline for autonomous feature delivery:

```
Intake → Discovery → Board Review → Planning (3 stages) → Coding → Review → Remediation → Test → Deploy
```

Each stage has a dispatch mode (`exec` for research/review, `yolo` for coding), quality gates, and timeouts. The board review uses multiple AI personas (CEO, CTO, CFO, COO + specialists) to evaluate briefs before committing resources.

## Upgrading

Run the installer again — it handles upgrades automatically:

```bash
curl -fsSL https://mosaicstack.dev/install.sh | bash
```

Or use the direct URL:

```bash
bash <(curl -fsSL https://git.mosaicstack.dev/mosaicstack/stack/raw/branch/main/tools/install.sh)
```

Or use the CLI:

```bash
mosaic update                # Check + install CLI updates
mosaic update --check        # Check only, don't install
```

The CLI also performs a background update check on every invocation (cached for 1 hour).

### Installer Flags

```bash
bash tools/install.sh --check           # Version check only
bash tools/install.sh --framework       # Framework only (skip npm CLI)
bash tools/install.sh --cli             # npm CLI only (skip framework)
bash tools/install.sh --next            # Prerelease lane: source build from next
bash tools/install.sh --dev             # Contributor lane: source build at --ref/main
bash tools/install.sh --ref v1.0        # Install from a specific git ref (--ref wins over --next)
bash tools/install.sh --yes             # Non-interactive, accept all defaults
bash tools/install.sh --no-auto-launch  # Skip auto-launch of wizard
```

The installer rejects unrecognized flags or positional arguments before making changes and prints the supported-option usage.

## Contributing

```bash
# Create a feature branch
git checkout -b feat/my-feature

# Make changes, then verify
pnpm typecheck && pnpm lint && pnpm test && pnpm format:check

# Commit (husky runs lint-staged automatically)
git commit -m "feat: description of change"

# Push and create PR
git push -u origin feat/my-feature
```

DTOs go in `*.dto.ts` files at module boundaries. Scratchpads (`docs/scratchpads/`) are mandatory for non-trivial tasks. See `AGENTS.md` for the full standards reference.

## License

Proprietary — all rights reserved.
