Files
mosaic/docs/PRD.md
Jason Woltje 5103406c93 chore: scaffold mosaic monorepo (Phase 0)
- pnpm workspaces + Turborepo
- tsconfig.base.json strict ESM
- @mosaic/types stub package
- Woodpecker CI pipeline with Valkey service
- docs/PRD.md, docs/TASKS.md, CONTEXT.md
2026-03-06 13:15:47 -06:00

18 KiB
Raw Blame History

PRD: Mosaic Monorepo & @mosaic/* Package Ecosystem

Status: Draft
Created: 2026-03-06
Updated: 2026-03-06 (post-bootstrap audit)
Owner: Jason Woltje
Repo (target): git.mosaicstack.dev/mosaic/mosaic


1. Problem Statement

Mosaic tooling is currently spread across five polyrepos. Each repo duplicates TypeScript config, ESLint rules, Vitest setup, and core type definitions. Cross-repo changes require synchronized PRs with a window of inconsistency. Agent workers lose context when they must span multiple repos. There is no standardized installation path — getting the full Mosaic toolkit requires knowing which repos exist and cloning them individually.

Symptoms:

  • tsconfig.json, eslint.config.js, vitest.config.ts duplicated across every repo
  • Task, Mission, Agent, and related types redefined in each package
  • A feature touching coord + queue requires 2 PRs, 2 CI runs, 2 merges
  • No npm install story — setup is tribal knowledge
  • Agent workers clone one repo with no visibility into sibling packages

2. Goals

  1. Reduce duplication — One tsconfig, one ESLint config, one set of shared types, inherited by all packages
  2. Standardize naming — All packages published under @mosaic/ scope to the Gitea npm registry
  3. Single install entry pointnpm i -g @mosaic/mosaic runs guided onboarding, installs selected packages
  4. CI publishes packages — Push to main triggers Turborepo affected-only build + publish to registry
  5. Agent-friendly context — One monorepo means one clone, one TASKS.md, one root CONTEXT.md for workers
  6. Eventual full TypeScriptcoord and prdy start as shell distribution, graduate to TypeScript packages over time

3. Non-Goals

  • Not replacing OpenBrain — Queue is for coordination, OpenBrain is for memory. No overlap.
  • Not open-sourcing — These are personal/internal tools. Public registry not in scope.
  • Not containerizing packages — Packages are CLI tools and libraries, not services.
  • Not forced independent versioning — All packages use fixed/synchronized versioning (simpler for solo developer).
  • agent-skills not included — Skills are files consumed by agents, not npm packages. Stays in its own repo.
  • Not rewriting coord/prdy immediately — Shell scripts are distributed first; TypeScript rewrite is a later phase.

4. Bootstrap Audit (Current State)

mosaic-bootstrap contains four distinct categories of content. Understanding this is critical before migrating:

4a. Installation Wizard (TypeScript) — becomes @mosaic/mosaic

28 TypeScript source files. Handles fresh Mosaic install: creates SOUL.md, USER.md, TOOLS.md, configures MCP for Claude/Codex/opencode, selects and installs skills. Currently published as mosaic-wizard@0.2.0. This is the npm i -g @mosaic/mosaic entry point. Already substantially complete — needs rename, cleanup, monorepo integration.

4b. Shell Tool Suite — distributed as files, not npm packages

~150 shell scripts, ~2,500+ lines of bash across:

  • tools/git/ — PR, issue, milestone management (Gitea API)
  • tools/orchestrator/ — ~1,800 lines: mission-init, session-run, session-resume, session-status
  • tools/prdy/ — ~470 lines: prdy-init, prdy-update, prdy-validate, prdy-status
  • tools/orchestrator-matrix/ — Python Matrix transport for multi-agent coordination
  • tools/qa/ — hook handlers, memory write prevention, QA monitors
  • tools/woodpecker/, portainer/, cloudflare/, authentik/, coolify/, codex/, glpi/ — infra integrations

These are NOT npm packages today. They are bash/Python scripts distributed by the wizard to ~/.config/mosaic/. The wizard is the install vehicle.

4c. Agent Guides (Markdown) — distributed as files

17 markdown guides: ORCHESTRATOR.md, E2E-DELIVERY.md, CODE-REVIEW.md, etc. Loaded by agents at runtime from ~/.config/mosaic/guides/. Not code, not packages. Distributed by the wizard.

4d. Runtime Configs — distributed as files

Per-agent config overlays for Claude, Codex, opencode. Distributed to ~/.config/mosaic/runtime/ on install.


5. Package Structure

Migration Philosophy: Staged

The monorepo is built in waves. Existing TypeScript code migrates first. Shell-based tools (coord, prdy) are distributed as-is initially, then rewritten as TypeScript packages in a later wave when the monorepo foundation is proven.

Wave 1 — Foundation
  @mosaic/types           Shared type definitions (new)
  @mosaic/queue           Migrate from mosaic/queue (TypeScript, already mature)
Wave 2 — Entry Point
  @mosaic/mosaic          Migrate wizard from mosaic-bootstrap (TypeScript, already built)
  @mosaic/openclaw-context  Migrate from mosaic/openclaw-openbrain-context (TypeScript)

Wave 3 — TypeScript Rewrites (future)
  @mosaic/coord           Rewrite of tools/orchestrator/ bash suite
  @mosaic/prdy            Rewrite of tools/prdy/ bash suite
  @mosaic/quality-rails   Rewrite of quality-rails template distributor (shell+templates → TS scaffolder)
  @mosaic/cli             Unified CLI binary composing all @mosaic/* packages

Repository Layout

mosaic/mosaic  (monorepo)
├── packages/
│   ├── types/              @mosaic/types            Shared interfaces — zero deps
│   ├── queue/              @mosaic/queue            Task queue + MCP server
│   ├── quality-rails/      @mosaic/quality-rails    Quality gate enforcement
│   ├── mosaic/             @mosaic/mosaic           Install wizard + meta package
│   ├── coord/              @mosaic/coord            [Wave 3] Mission coordination
│   ├── prdy/               @mosaic/prdy             [Wave 3] PRD generation
│   └── cli/                @mosaic/cli              [Wave 3] Unified CLI binary
├── plugins/
│   └── openclaw-context/   @mosaic/openclaw-context  OpenClaw → OpenBrain plugin
└── docs/
    ├── PRD.md              (this file, symlinked from jarvis-brain)
    └── TASKS.md            (orchestrator-owned)

Package Responsibilities

@mosaic/types (Wave 1)

  • Shared interfaces: Task, TaskStatus, TaskPriority, Mission, Agent, QueueConfig
  • No runtime code — types only, zero dependencies
  • Every other @mosaic/* package imports from here; never defines its own copies
  • Published first; version bump propagates to all consumers

@mosaic/queue (Wave 1)

  • Task queue backed by Valkey/Redis with atomic WATCH/MULTI/EXEC ownership
  • MCP server with 8 tools: queue_list/get/claim/heartbeat/release/complete/fail/status
  • Migrated from mosaic/queue — code mature (Phase 1 + atomicity fixes complete)
  • Updates imports to use @mosaic/types

@mosaic/quality-rails (Wave 3 — TypeScript rewrite)

  • Audit result: mosaic/quality-rails is shell scripts + template files, no TypeScript. No package.json.
  • Current form: scripts/install.sh, verify.sh + config templates for monorepo/nextjs/node/python project types
  • Wave 3 rewrite: TypeScript scaffolder that generates/installs config files programmatically rather than distributing static copies
  • Until Wave 3: templates bundled as wizard distributed assets alongside other shell tools
  • Migrated from mosaic/quality-rails (archive after wizard bundles it)

@mosaic/mosaic (Wave 2)

  • Entry point: npm i -g @mosaic/mosaic
  • Onboarding wizard (migrated from mosaic-wizard in bootstrap)
  • Stages: detect installs → mode select → soul/user/tools setup → skill selection → runtime config → finalize
  • Copies shell tool suite (tools/, guides/, runtime/) to ~/.config/mosaic/
  • Prompts which additional @mosaic/* packages to install
  • Config validation: checks OpenBrain connectivity, Gitea token, etc.
  • When Wave 3 completes: wizard shifts from "copy shell scripts" to "just install TypeScript packages"

@mosaic/openclaw-context (Wave 2, plugins/)

  • OpenClaw → OpenBrain context engine plugin
  • Lives in monorepo for shared tooling, published standalone
  • Installable independently: openclaw plugin install @mosaic/openclaw-context
  • Migrated from mosaic/openclaw-openbrain-context

@mosaic/coord (Wave 3 — TypeScript rewrite)

  • TypeScript rewrite of tools/orchestrator/ bash suite
  • Mission lifecycle: init, run, resume, status, drain
  • Reads/writes docs/TASKS.md in target project
  • CLI subcommand: mosaic coord <init|run|resume|status>
  • Will replace shell scripts in the distributed toolkit
  • Prerequisite: Wave 1+2 complete and stable

@mosaic/prdy (Wave 3 — TypeScript rewrite)

  • TypeScript rewrite of tools/prdy/ bash suite
  • AI-assisted PRD generation, update, validation
  • CLI subcommand: mosaic prdy <init|update|validate|status>
  • Depends on LLM client (OpenAI / Anthropic / Z.ai — configured via env)
  • Prerequisite: Wave 1+2 complete and stable

@mosaic/cli (Wave 3)

  • Unified mosaic binary — thin shell over all @mosaic/* packages
  • Plugin discovery: checks installed @mosaic/* packages, registers CLI contributions
  • Subcommand routing: mosaic coord, mosaic prdy, mosaic queue, mosaic prdy, etc.
  • Does NOT bundle everything — loads plugins dynamically

6. Tooling

Package Manager

pnpm workspaces — single lockfile, workspace-linked packages during development, content-addressed store.

Build Orchestration

Turborepo — affected-only builds, remote cache (optional), pipeline definitions per task type.

// turbo.json (root)
{
  "pipeline": {
    "build":     { "dependsOn": ["^build"], "outputs": ["dist/**"] },
    "test":      { "dependsOn": ["^build"] },
    "lint":      {},
    "typecheck": { "dependsOn": ["^build"] },
    "publish":   { "dependsOn": ["build", "test", "lint", "typecheck"] }
  }
}

Shared Root Config (inherited by all packages)

  • tsconfig.base.json — strict mode, ESM, NodeNext module resolution
  • eslint.config.js — shared ruleset (from tools/quality/templates/ in bootstrap — already exists!)
  • vitest.workspace.ts — workspace-level test runner

Each package tsconfig.json extends ../../tsconfig.base.json.

Versioning

Fixed (synchronized): All packages share a version number. @mosaic/queue@0.2.0 implies @mosaic/types@0.2.0. Revisit if packages diverge significantly in maturity.

Tool: Changesets (@changesets/cli) — human-authored change descriptions → automated version bumps + changelogs on release.


7. Registry & CI

Gitea npm Registry

Packages published to https://git.mosaicstack.dev/api/packages/mosaic/npm.

.npmrc (root):

@mosaic:registry=https://git.mosaicstack.dev/api/packages/mosaic/npm
//git.mosaicstack.dev/api/packages/mosaic/npm/:_authToken=${GITEA_TOKEN}

CI Pipeline (Woodpecker)

Trigger: push to main

Steps:

  1. pnpm install --frozen-lockfile
  2. pnpm turbo lint typecheck
  3. pnpm turbo test (with Valkey service container for @mosaic/queue tests)
  4. pnpm turbo build
  5. Detect changed packages (Turborepo affected output)
  6. pnpm changeset publish → publish affected packages to Gitea registry

PR pipeline (no publish): steps 14 only + pnpm changeset status.

Valkey service for queue tests:

# .woodpecker.yml
services:
  - name: valkey
    image: valkey/valkey:8-alpine
    ports: ["6379:6379"]

8. Migration Plan

Prerequisites (check before starting)

  • mosaic/queue atomicity fix (issue #4) merged
  • mosaic/openclaw-openbrain-context compact/ingest fix (issue #4) merged
  • No active agent branches on repos being migrated

Wave 1 — Foundation

Phase 0: Scaffold Monorepo

  • Create mosaic/mosaic repo on Gitea
  • Initialize pnpm workspace + Turborepo
  • Add root tsconfig.base.json, eslint.config.js, vitest.workspace.ts
  • Add .npmrc pointing to Gitea registry
  • Smoke-test publish (empty @mosaic/types@0.0.1) to validate CI+registry auth
  • Add Woodpecker pipeline with Valkey service
  • Add root CONTEXT.md, docs/TASKS.md, docs/PRD.md

Phase 1: @mosaic/types

  • Extract all shared types from queue, coord, prdy, quality-rails (audit each for duplicates)
  • Publish @mosaic/types@0.1.0
  • No other package migrates until types are published

Phase 2: @mosaic/queue

  • Move mosaic/queue/packages/queue/srcmosaic/mosaic/packages/queue/src
  • Update imports to use @mosaic/types
  • All tests green including integration (Valkey CI service)
  • Publish @mosaic/queue@0.1.0
  • Archive mosaic/queue repo (read-only, redirect notice in README)

Wave 2 — Entry Point

Phase 4: @mosaic/mosaic (wizard migration)

  • Move mosaic-bootstrap/src/packages/mosaic/src/
  • Update package name: mosaic-wizard@mosaic/mosaic
  • Update wizard to reference monorepo packages where applicable
  • postinstall script: run wizard on first install
  • Shell tool suite (tools/, guides/, runtime/) bundled as static assets
  • Publish @mosaic/mosaic@0.1.0
  • Validate: npm i -g @mosaic/mosaic on clean machine completes setup
  • Archive mosaic/bootstrap (read-only, redirect notice)

Phase 5: @mosaic/openclaw-context

  • Move mosaic/openclaw-openbrain-context/srcplugins/openclaw-context/src
  • Update shared tooling to use root configs
  • Publish @mosaic/openclaw-context@0.1.0
  • Validate standalone install works: openclaw plugin install @mosaic/openclaw-context
  • Archive mosaic/openclaw-openbrain-context

Wave 3 — TypeScript Rewrites (future, no timeline set)

Phase 6: @mosaic/coord

  • Design TypeScript API mirroring current bash behavior
  • Implement: init, run, resume, status, drain
  • CLI subcommand registration for @mosaic/cli
  • Migrate shell scripts to integration tests (parity verification)
  • Wizard updated: stop distributing orchestrator shell scripts once this ships
  • Publish @mosaic/coord@0.1.0

Phase 7: @mosaic/prdy

  • Design TypeScript API mirroring current bash behavior
  • LLM client abstraction (supports Anthropic / OpenAI / Z.ai via config)
  • Implement: init, update, validate, status
  • CLI subcommand registration for @mosaic/cli
  • Wizard updated: stop distributing prdy shell scripts once this ships
  • Publish @mosaic/prdy@0.1.0

Phase 8: @mosaic/quality-rails

  • TypeScript scaffolder API — generates ESLint, tsconfig, Woodpecker, husky, lint-staged for a project
  • Supports project types: monorepo, typescript-node, typescript-nextjs, python
  • CLI: mosaic quality install [--type monorepo|node|nextjs|python], mosaic quality verify
  • Replaces static template distribution from wizard
  • Archive mosaic/quality-rails
  • Publish @mosaic/quality-rails@0.1.0

Phase 9: @mosaic/cli

  • Unified binary with plugin discovery
  • Subcommands: mosaic coord, mosaic prdy, mosaic queue, mosaic prdy
  • Wizard updated to install @mosaic/cli as primary binary instead of path-based scripts
  • Publish @mosaic/cli@0.1.0

9. Open Questions

# Question Priority Status
1 Bootstrap audit: what in tools/ is safe to archive vs still needed? Shell scripts will coexist during Wave 1+2 High Answered — shell tools distributed by wizard until Wave 3
2 quality-rails audit complete: shell scripts + templates, no TypeScript, no package.json High Wave 3 rewrite
3 @mosaic/prdy LLM client: peer dep or bundled? Medium Open
4 Valkey CI service in Woodpecker: verify swarm runner can spin Docker services High Open
5 Changesets vs manual semver? (Recommendation: Changesets) Low Open
6 Matrix orchestrator (tools/orchestrator-matrix/, Python) — migrate to TypeScript in Wave 3 or keep Python? Medium Open
7 mosaic/agent-skills — stays polyrepo, but should the wizard install it? Low Open

10. Success Criteria

Wave 1+2 (MVP)

  • npm i -g @mosaic/mosaic on a clean machine completes setup end-to-end
  • mosaic coord init, mosaic prdy init, mosaic queue list all work (bash, distributed by wizard)
  • Zero duplicated TypeScript config files across Wave 1+2 packages
  • One PR for a shared type change, no follow-up PRs in sibling repos
  • CI publishes affected packages on every merge to main
  • All existing functionality preserved — no regressions

Wave 3 (Full TypeScript)

  • mosaic coord and mosaic prdy run as native TypeScript packages, no bash distribution needed
  • Wizard no longer ships shell scripts for coord/prdy
  • @mosaic/cli is the single mosaic binary entry point

11. Risks

Risk Likelihood Impact Mitigation
mosaic/quality-rails is also shell (not TypeScript) Medium Medium Audit before Phase 3; if shell, it becomes Wave 3
Wizard migration breaks existing installs on Jason's machines Medium High Keep bootstrap installable alongside; wizard detects existing config and upgrades safely
Turborepo cache invalidation surprises Low Low Start without remote cache; add later
Gitea npm registry auth in CI Medium High Smoke-test publish in Phase 0 before any real migration
Breaking installed tools mid-migration Low High Keep old repos live until new packages verified working
Matrix orchestrator (Python) creates a language gap in Wave 3 Low Medium Decision deferred; can keep as Python microservice or wrap in TypeScript subprocess

Start: Phase 0 scaffold after current fix workers complete (queue + openclaw-context issue #4).
Wave 3 timeline: TBD — start after Wave 1+2 are stable in production.