bootstrap mosaic-stack to Mosaic standards layer #420
15
.mosaic/README.md
Normal file
15
.mosaic/README.md
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# Repo Mosaic Linkage
|
||||||
|
|
||||||
|
This repository is attached to the machine-wide Mosaic framework.
|
||||||
|
|
||||||
|
## Load Order for Agents
|
||||||
|
|
||||||
|
1. `~/.mosaic/STANDARDS.md`
|
||||||
|
2. `AGENTS.md` (this repository)
|
||||||
|
3. `.mosaic/repo-hooks.sh` (repo-specific automation hooks)
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
- Keep universal standards in `~/.mosaic`
|
||||||
|
- Keep repo-specific behavior in this repo
|
||||||
|
- Avoid copying large runtime configs into each project
|
||||||
29
.mosaic/repo-hooks.sh
Executable file
29
.mosaic/repo-hooks.sh
Executable file
@@ -0,0 +1,29 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Repo-specific hooks used by scripts/agent/*.sh for Mosaic Stack.
|
||||||
|
|
||||||
|
mosaic_hook_session_start() {
|
||||||
|
echo "[mosaic-stack] Branch: $(git rev-parse --abbrev-ref HEAD)"
|
||||||
|
echo "[mosaic-stack] Remotes:"
|
||||||
|
git remote -v | sed 's/^/[mosaic-stack] /'
|
||||||
|
if command -v node >/dev/null 2>&1; then
|
||||||
|
echo "[mosaic-stack] Node: $(node -v)"
|
||||||
|
fi
|
||||||
|
if command -v pnpm >/dev/null 2>&1; then
|
||||||
|
echo "[mosaic-stack] pnpm: $(pnpm -v)"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
mosaic_hook_critical() {
|
||||||
|
echo "[mosaic-stack] Recent commits:"
|
||||||
|
git log --oneline --decorate -n 5 | sed 's/^/[mosaic-stack] /'
|
||||||
|
echo "[mosaic-stack] Open TODO/FIXME markers (top 20):"
|
||||||
|
rg -n "(TODO|FIXME|HACK|SECURITY)" apps packages plugins docs --glob '!**/node_modules/**' -S \
|
||||||
|
| head -n 20 \
|
||||||
|
| sed 's/^/[mosaic-stack] /' \
|
||||||
|
|| true
|
||||||
|
}
|
||||||
|
|
||||||
|
mosaic_hook_session_end() {
|
||||||
|
echo "[mosaic-stack] Working tree summary:"
|
||||||
|
git status --short | sed 's/^/[mosaic-stack] /' || true
|
||||||
|
}
|
||||||
72
AGENTS.md
72
AGENTS.md
@@ -1,37 +1,65 @@
|
|||||||
# Mosaic Stack — Agent Guidelines
|
# Mosaic Stack — Agent Guidelines
|
||||||
|
|
||||||
> **Any AI model, coding assistant, or framework working in this codebase MUST read and follow `CLAUDE.md` in the project root.**
|
## Load Order
|
||||||
|
|
||||||
`CLAUDE.md` is the authoritative source for:
|
1. `SOUL.md` (repo identity + behavior invariants)
|
||||||
|
2. `~/.mosaic/STANDARDS.md` (machine-wide standards rails)
|
||||||
|
3. `AGENTS.md` (repo-specific overlay)
|
||||||
|
4. `.mosaic/repo-hooks.sh` (repo lifecycle hooks)
|
||||||
|
|
||||||
- Technology stack and versions
|
## Runtime Contract
|
||||||
- TypeScript strict mode requirements
|
|
||||||
- ESLint Quality Rails (error-level enforcement)
|
|
||||||
- Prettier formatting rules
|
|
||||||
- Testing requirements (85% coverage, TDD)
|
|
||||||
- API conventions and database patterns
|
|
||||||
- Commit format and branch strategy
|
|
||||||
- PDA-friendly design principles
|
|
||||||
|
|
||||||
## Quick Rules (Read CLAUDE.md for Details)
|
- This file is authoritative for repo-local operations.
|
||||||
|
- `CLAUDE.md` is a compatibility pointer to `AGENTS.md`.
|
||||||
|
- Follow universal rails from `~/.mosaic/guides/` and `~/.mosaic/rails/`.
|
||||||
|
|
||||||
- **No `any` types** — use `unknown`, generics, or proper types
|
## Session Lifecycle
|
||||||
- **Explicit return types** on all functions
|
|
||||||
- **Type-only imports** — `import type { Foo }` for types
|
|
||||||
- **Double quotes**, semicolons, 2-space indent, 100 char width
|
|
||||||
- **`??` not `||`** for defaults, **`?.`** not `&&` chains
|
|
||||||
- **All promises** must be awaited or returned
|
|
||||||
- **85% test coverage** minimum, tests before implementation
|
|
||||||
|
|
||||||
## Updating Conventions
|
```bash
|
||||||
|
bash scripts/agent/session-start.sh
|
||||||
|
bash scripts/agent/critical.sh
|
||||||
|
bash scripts/agent/session-end.sh
|
||||||
|
```
|
||||||
|
|
||||||
If you discover new patterns, gotchas, or conventions while working in this codebase, **update `CLAUDE.md`** — not this file. This file exists solely to redirect agents that look for `AGENTS.md` to the canonical source.
|
Optional:
|
||||||
|
|
||||||
## Per-App Context
|
```bash
|
||||||
|
bash scripts/agent/log-limitation.sh "Short Name"
|
||||||
|
```
|
||||||
|
|
||||||
Each app directory has its own `AGENTS.md` for app-specific patterns:
|
## Repo Context
|
||||||
|
|
||||||
|
- Platform: multi-tenant personal assistant stack
|
||||||
|
- Monorepo: `pnpm` workspaces + Turborepo
|
||||||
|
- Core apps: `apps/api` (NestJS), `apps/web` (Next.js), orchestrator/coordinator services
|
||||||
|
- Infrastructure: Docker Compose + PostgreSQL + Valkey + Authentik
|
||||||
|
|
||||||
|
## Quick Command Set
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm install
|
||||||
|
pnpm dev
|
||||||
|
pnpm test
|
||||||
|
pnpm lint
|
||||||
|
pnpm build
|
||||||
|
```
|
||||||
|
|
||||||
|
## Standards and Quality
|
||||||
|
|
||||||
|
- Enforce strict typing and no unsafe shortcuts.
|
||||||
|
- Keep lint/typecheck/tests green before completion.
|
||||||
|
- Prefer small, focused commits and clear change descriptions.
|
||||||
|
|
||||||
|
## App-Specific Overlays
|
||||||
|
|
||||||
- `apps/api/AGENTS.md`
|
- `apps/api/AGENTS.md`
|
||||||
- `apps/web/AGENTS.md`
|
- `apps/web/AGENTS.md`
|
||||||
- `apps/coordinator/AGENTS.md`
|
- `apps/coordinator/AGENTS.md`
|
||||||
- `apps/orchestrator/AGENTS.md`
|
- `apps/orchestrator/AGENTS.md`
|
||||||
|
|
||||||
|
## Additional Guidance
|
||||||
|
|
||||||
|
- Orchestrator guidance: `docs/claude/orchestrator.md`
|
||||||
|
- Security remediation context: `docs/reports/codebase-review-2026-02-05/01-security-review.md`
|
||||||
|
- Code quality context: `docs/reports/codebase-review-2026-02-05/02-code-quality-review.md`
|
||||||
|
- QA context: `docs/reports/codebase-review-2026-02-05/03-qa-test-coverage.md`
|
||||||
|
|||||||
503
CLAUDE.md
503
CLAUDE.md
@@ -1,499 +1,14 @@
|
|||||||
**Multi-tenant personal assistant platform with PostgreSQL backend, Authentik SSO, and MoltBot
|
# Compatibility Pointer
|
||||||
integration.**
|
|
||||||
|
|
||||||
## Conditional Documentation Loading
|
This repository uses an agent-neutral Mosaic standards model.
|
||||||
|
|
||||||
| When working on... | Load this guide |
|
Authoritative repo guidance is in `AGENTS.md`.
|
||||||
| ---------------------------------------- | ------------------------------------------------------------------- |
|
|
||||||
| Orchestrating autonomous task completion | `docs/claude/orchestrator.md` |
|
|
||||||
| Security remediation (review findings) | `docs/reports/codebase-review-2026-02-05/01-security-review.md` |
|
|
||||||
| Code quality fixes | `docs/reports/codebase-review-2026-02-05/02-code-quality-review.md` |
|
|
||||||
| Test coverage gaps | `docs/reports/codebase-review-2026-02-05/03-qa-test-coverage.md` |
|
|
||||||
|
|
||||||
## Platform Templates
|
Load order for Claude sessions:
|
||||||
|
|
||||||
Bootstrap templates are at `docs/templates/`. See `docs/templates/README.md` for usage.
|
1. `SOUL.md`
|
||||||
|
2. `~/.mosaic/STANDARDS.md`
|
||||||
|
3. `AGENTS.md`
|
||||||
|
4. `.mosaic/repo-hooks.sh`
|
||||||
|
|
||||||
## Project Overview
|
If you were started from `CLAUDE.md`, continue by reading `AGENTS.md` now.
|
||||||
|
|
||||||
Mosaic Stack is a standalone platform that provides:
|
|
||||||
|
|
||||||
- Multi-user workspaces with team sharing
|
|
||||||
- Task, event, and project management
|
|
||||||
- Gantt charts and Kanban boards
|
|
||||||
- MoltBot integration via plugins (stock MoltBot + mosaic-plugin-\*)
|
|
||||||
- PDA-friendly design throughout
|
|
||||||
|
|
||||||
**Repository:** git.mosaicstack.dev/mosaic/stack
|
|
||||||
**Versioning:** Start at 0.0.1, MVP = 0.1.0
|
|
||||||
|
|
||||||
## Technology Stack
|
|
||||||
|
|
||||||
| Layer | Technology |
|
|
||||||
| ---------- | -------------------------------------------- |
|
|
||||||
| Frontend | Next.js 16 + React + TailwindCSS + Shadcn/ui |
|
|
||||||
| Backend | NestJS + Prisma ORM |
|
|
||||||
| Database | PostgreSQL 17 + pgvector |
|
|
||||||
| Cache | Valkey (Redis-compatible) |
|
|
||||||
| Auth | Authentik (OIDC) |
|
|
||||||
| AI | Ollama (configurable: local or remote) |
|
|
||||||
| Messaging | MoltBot (stock + Mosaic plugins) |
|
|
||||||
| Real-time | WebSockets (Socket.io) |
|
|
||||||
| Monorepo | pnpm workspaces + TurboRepo |
|
|
||||||
| Testing | Vitest + Playwright |
|
|
||||||
| Deployment | Docker + docker-compose |
|
|
||||||
|
|
||||||
## Repository Structure
|
|
||||||
|
|
||||||
mosaic-stack/
|
|
||||||
├── apps/
|
|
||||||
│ ├── api/ # mosaic-api (NestJS)
|
|
||||||
│ │ ├── src/
|
|
||||||
│ │ │ ├── auth/ # Authentik OIDC
|
|
||||||
│ │ │ ├── tasks/ # Task management
|
|
||||||
│ │ │ ├── events/ # Calendar/events
|
|
||||||
│ │ │ ├── projects/ # Project management
|
|
||||||
│ │ │ ├── brain/ # MoltBot integration
|
|
||||||
│ │ │ └── activity/ # Activity logging
|
|
||||||
│ │ ├── prisma/
|
|
||||||
│ │ │ └── schema.prisma
|
|
||||||
│ │ └── Dockerfile
|
|
||||||
│ └── web/ # mosaic-web (Next.js 16)
|
|
||||||
│ ├── app/
|
|
||||||
│ ├── components/
|
|
||||||
│ └── Dockerfile
|
|
||||||
├── packages/
|
|
||||||
│ ├── shared/ # Shared types, utilities
|
|
||||||
│ ├── ui/ # Shared UI components
|
|
||||||
│ └── config/ # Shared configuration
|
|
||||||
├── plugins/
|
|
||||||
│ ├── mosaic-plugin-brain/ # MoltBot skill: API queries
|
|
||||||
│ ├── mosaic-plugin-calendar/ # MoltBot skill: Calendar
|
|
||||||
│ ├── mosaic-plugin-tasks/ # MoltBot skill: Tasks
|
|
||||||
│ └── mosaic-plugin-gantt/ # MoltBot skill: Gantt
|
|
||||||
├── docker/
|
|
||||||
│ ├── docker-compose.yml # Turnkey deployment
|
|
||||||
│ └── init-scripts/ # PostgreSQL init
|
|
||||||
├── docs/
|
|
||||||
│ ├── SETUP.md
|
|
||||||
│ ├── CONFIGURATION.md
|
|
||||||
│ └── DESIGN-PRINCIPLES.md
|
|
||||||
├── .env.example
|
|
||||||
├── turbo.json
|
|
||||||
├── pnpm-workspace.yaml
|
|
||||||
└── README.md
|
|
||||||
|
|
||||||
## Development Workflow
|
|
||||||
|
|
||||||
### Branch Strategy
|
|
||||||
|
|
||||||
- `main` — stable releases only
|
|
||||||
- `develop` — active development (default working branch)
|
|
||||||
- `feature/*` — feature branches from develop
|
|
||||||
- `fix/*` — bug fix branches
|
|
||||||
|
|
||||||
### Starting Work
|
|
||||||
|
|
||||||
````bash
|
|
||||||
git checkout develop
|
|
||||||
git pull --rebase
|
|
||||||
pnpm install
|
|
||||||
|
|
||||||
Running Locally
|
|
||||||
|
|
||||||
# Start all services (Docker)
|
|
||||||
docker compose up -d
|
|
||||||
|
|
||||||
# Or run individually for development
|
|
||||||
pnpm dev # All apps
|
|
||||||
pnpm dev:api # API only
|
|
||||||
pnpm dev:web # Web only
|
|
||||||
|
|
||||||
Testing
|
|
||||||
|
|
||||||
pnpm test # Run all tests
|
|
||||||
pnpm test:api # API tests only
|
|
||||||
pnpm test:web # Web tests only
|
|
||||||
pnpm test:e2e # Playwright E2E
|
|
||||||
|
|
||||||
Building
|
|
||||||
|
|
||||||
pnpm build # Build all
|
|
||||||
pnpm build:api # Build API
|
|
||||||
pnpm build:web # Build Web
|
|
||||||
|
|
||||||
Design Principles (NON-NEGOTIABLE)
|
|
||||||
|
|
||||||
PDA-Friendly Language
|
|
||||||
|
|
||||||
NEVER use demanding language. This is critical.
|
|
||||||
┌─────────────┬──────────────────────┐
|
|
||||||
│ ❌ NEVER │ ✅ ALWAYS │
|
|
||||||
├─────────────┼──────────────────────┤
|
|
||||||
│ OVERDUE │ Target passed │
|
|
||||||
├─────────────┼──────────────────────┤
|
|
||||||
│ URGENT │ Approaching target │
|
|
||||||
├─────────────┼──────────────────────┤
|
|
||||||
│ MUST DO │ Scheduled for │
|
|
||||||
├─────────────┼──────────────────────┤
|
|
||||||
│ CRITICAL │ High priority │
|
|
||||||
├─────────────┼──────────────────────┤
|
|
||||||
│ YOU NEED TO │ Consider / Option to │
|
|
||||||
├─────────────┼──────────────────────┤
|
|
||||||
│ REQUIRED │ Recommended │
|
|
||||||
└─────────────┴──────────────────────┘
|
|
||||||
Visual Indicators
|
|
||||||
|
|
||||||
Use status indicators consistently:
|
|
||||||
- 🟢 On track / Active
|
|
||||||
- 🔵 Upcoming / Scheduled
|
|
||||||
- ⏸️ Paused / On hold
|
|
||||||
- 💤 Dormant / Inactive
|
|
||||||
- ⚪ Not started
|
|
||||||
|
|
||||||
Display Principles
|
|
||||||
|
|
||||||
1. 10-second scannability — Key info visible immediately
|
|
||||||
2. Visual chunking — Clear sections with headers
|
|
||||||
3. Single-line items — Compact, scannable lists
|
|
||||||
4. Date grouping — Today, Tomorrow, This Week headers
|
|
||||||
5. Progressive disclosure — Details on click, not upfront
|
|
||||||
6. Calm colors — No aggressive reds for status
|
|
||||||
|
|
||||||
Reference
|
|
||||||
|
|
||||||
See docs/DESIGN-PRINCIPLES.md for complete guidelines.
|
|
||||||
For original patterns, see: jarvis-brain/docs/DESIGN-PRINCIPLES.md
|
|
||||||
|
|
||||||
API Conventions
|
|
||||||
|
|
||||||
Endpoints
|
|
||||||
|
|
||||||
GET /api/{resource} # List (with pagination, filters)
|
|
||||||
GET /api/{resource}/:id # Get single
|
|
||||||
POST /api/{resource} # Create
|
|
||||||
PATCH /api/{resource}/:id # Update
|
|
||||||
DELETE /api/{resource}/:id # Delete
|
|
||||||
|
|
||||||
Response Format
|
|
||||||
|
|
||||||
// Success
|
|
||||||
{
|
|
||||||
data: T | T[],
|
|
||||||
meta?: { total, page, limit }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error
|
|
||||||
{
|
|
||||||
error: {
|
|
||||||
code: string,
|
|
||||||
message: string,
|
|
||||||
details?: any
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Brain Query API
|
|
||||||
|
|
||||||
POST /api/brain/query
|
|
||||||
{
|
|
||||||
query: "what's on my calendar",
|
|
||||||
context?: { view: "dashboard", workspace_id: "..." }
|
|
||||||
}
|
|
||||||
|
|
||||||
Database Conventions
|
|
||||||
|
|
||||||
Multi-Tenant (RLS)
|
|
||||||
|
|
||||||
All workspace-scoped tables use Row-Level Security:
|
|
||||||
- Always include workspace_id in queries
|
|
||||||
- RLS policies enforce isolation
|
|
||||||
- Set session context for current user
|
|
||||||
|
|
||||||
Prisma Commands
|
|
||||||
|
|
||||||
pnpm prisma:generate # Generate client
|
|
||||||
pnpm prisma:migrate # Run migrations
|
|
||||||
pnpm prisma:studio # Open Prisma Studio
|
|
||||||
pnpm prisma:seed # Seed development data
|
|
||||||
|
|
||||||
MoltBot Plugin Development
|
|
||||||
|
|
||||||
Plugins live in plugins/mosaic-plugin-*/ and follow MoltBot skill format:
|
|
||||||
|
|
||||||
# plugins/mosaic-plugin-brain/SKILL.md
|
|
||||||
---
|
|
||||||
name: mosaic-plugin-brain
|
|
||||||
description: Query Mosaic Stack for tasks, events, projects
|
|
||||||
version: 0.0.1
|
|
||||||
triggers:
|
|
||||||
- "what's on my calendar"
|
|
||||||
- "show my tasks"
|
|
||||||
- "morning briefing"
|
|
||||||
tools:
|
|
||||||
- mosaic_api
|
|
||||||
---
|
|
||||||
|
|
||||||
# Plugin instructions here...
|
|
||||||
|
|
||||||
Key principle: MoltBot remains stock. All customization via plugins only.
|
|
||||||
|
|
||||||
Environment Variables
|
|
||||||
|
|
||||||
See .env.example for all variables. Key ones:
|
|
||||||
|
|
||||||
# Database
|
|
||||||
DATABASE_URL=postgresql://mosaic:password@localhost:5432/mosaic
|
|
||||||
|
|
||||||
# Auth
|
|
||||||
AUTHENTIK_URL=https://auth.example.com
|
|
||||||
AUTHENTIK_CLIENT_ID=mosaic-stack
|
|
||||||
AUTHENTIK_CLIENT_SECRET=...
|
|
||||||
|
|
||||||
# Ollama
|
|
||||||
OLLAMA_MODE=local|remote
|
|
||||||
OLLAMA_ENDPOINT=http://localhost:11434
|
|
||||||
|
|
||||||
# MoltBot
|
|
||||||
MOSAIC_API_TOKEN=...
|
|
||||||
|
|
||||||
Issue Tracking
|
|
||||||
|
|
||||||
Issues are tracked at: https://git.mosaicstack.dev/mosaic/stack/issues
|
|
||||||
|
|
||||||
Labels
|
|
||||||
|
|
||||||
- Priority: p0 (critical), p1 (high), p2 (medium), p3 (low)
|
|
||||||
- Type: api, web, database, auth, plugin, ai, devops, docs, migration, security, testing,
|
|
||||||
performance, setup
|
|
||||||
|
|
||||||
Milestones
|
|
||||||
|
|
||||||
- M1-Foundation (0.0.x)
|
|
||||||
- M2-MultiTenant (0.0.x)
|
|
||||||
- M3-Features (0.0.x)
|
|
||||||
- M4-MoltBot (0.0.x)
|
|
||||||
- M5-Migration (0.1.0 MVP)
|
|
||||||
|
|
||||||
Commit Format
|
|
||||||
|
|
||||||
<type>(#issue): Brief description
|
|
||||||
|
|
||||||
Detailed explanation if needed.
|
|
||||||
|
|
||||||
Fixes #123
|
|
||||||
Types: feat, fix, docs, test, refactor, chore
|
|
||||||
|
|
||||||
Test-Driven Development (TDD) - REQUIRED
|
|
||||||
|
|
||||||
**All code must follow TDD principles. This is non-negotiable.**
|
|
||||||
|
|
||||||
TDD Workflow (Red-Green-Refactor)
|
|
||||||
|
|
||||||
1. **RED** — Write a failing test first
|
|
||||||
- Write the test for new functionality BEFORE writing any implementation code
|
|
||||||
- Run the test to verify it fails (proves the test works)
|
|
||||||
- Commit message: `test(#issue): add test for [feature]`
|
|
||||||
|
|
||||||
2. **GREEN** — Write minimal code to make the test pass
|
|
||||||
- Implement only enough code to pass the test
|
|
||||||
- Run tests to verify they pass
|
|
||||||
- Commit message: `feat(#issue): implement [feature]`
|
|
||||||
|
|
||||||
3. **REFACTOR** — Clean up the code while keeping tests green
|
|
||||||
- Improve code quality, remove duplication, enhance readability
|
|
||||||
- Ensure all tests still pass after refactoring
|
|
||||||
- Commit message: `refactor(#issue): improve [component]`
|
|
||||||
|
|
||||||
Testing Requirements
|
|
||||||
|
|
||||||
- **Minimum 85% code coverage** for all new code
|
|
||||||
- **Write tests BEFORE implementation** — no exceptions
|
|
||||||
- Test files must be co-located with source files:
|
|
||||||
- `feature.service.ts` → `feature.service.spec.ts`
|
|
||||||
- `component.tsx` → `component.test.tsx`
|
|
||||||
- All tests must pass before creating a PR
|
|
||||||
- Use descriptive test names: `it("should return user when valid token provided")`
|
|
||||||
- Group related tests with `describe()` blocks
|
|
||||||
- Mock external dependencies (database, APIs, file system)
|
|
||||||
|
|
||||||
Test Types
|
|
||||||
|
|
||||||
- **Unit Tests** — Test individual functions/methods in isolation
|
|
||||||
- **Integration Tests** — Test module interactions (e.g., service + database)
|
|
||||||
- **E2E Tests** — Test complete user workflows with Playwright
|
|
||||||
|
|
||||||
Running Tests
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pnpm test # Run all tests
|
|
||||||
pnpm test:watch # Watch mode for active development
|
|
||||||
pnpm test:coverage # Generate coverage report
|
|
||||||
pnpm test:api # API tests only
|
|
||||||
pnpm test:web # Web tests only
|
|
||||||
pnpm test:e2e # Playwright E2E tests
|
|
||||||
````
|
|
||||||
|
|
||||||
Coverage Verification
|
|
||||||
|
|
||||||
After implementing a feature, verify coverage meets requirements:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pnpm test:coverage
|
|
||||||
# Check the coverage report in coverage/index.html
|
|
||||||
# Ensure your files show ≥85% coverage
|
|
||||||
```
|
|
||||||
|
|
||||||
TDD Anti-Patterns to Avoid
|
|
||||||
|
|
||||||
❌ Writing implementation code before tests
|
|
||||||
❌ Writing tests after implementation is complete
|
|
||||||
❌ Skipping tests for "simple" code
|
|
||||||
❌ Testing implementation details instead of behavior
|
|
||||||
❌ Writing tests that don't fail when they should
|
|
||||||
❌ Committing code with failing tests
|
|
||||||
|
|
||||||
Quality Rails - Mechanical Code Quality Enforcement
|
|
||||||
|
|
||||||
**Status:** ACTIVE (2026-01-30) - Strict enforcement enabled ✅
|
|
||||||
|
|
||||||
Quality Rails provides mechanical enforcement of code quality standards through pre-commit hooks
|
|
||||||
and CI/CD pipelines. See `docs/quality-rails-status.md` for full details.
|
|
||||||
|
|
||||||
What's Enforced (NOW ACTIVE):
|
|
||||||
|
|
||||||
- ✅ **Type Safety** - Blocks explicit `any` types (@typescript-eslint/no-explicit-any: error)
|
|
||||||
- ✅ **Return Types** - Requires explicit return types on exported functions
|
|
||||||
- ✅ **Security** - Detects SQL injection, XSS, unsafe regex (eslint-plugin-security)
|
|
||||||
- ✅ **Promise Safety** - Blocks floating promises and misused promises
|
|
||||||
- ✅ **Code Formatting** - Auto-formats with Prettier on commit
|
|
||||||
- ✅ **Build Verification** - Type-checks before allowing commit
|
|
||||||
- ✅ **Secret Scanning** - Blocks hardcoded passwords/API keys (git-secrets)
|
|
||||||
|
|
||||||
Current Status:
|
|
||||||
|
|
||||||
- ✅ **Pre-commit hooks**: ACTIVE - Blocks commits with violations
|
|
||||||
- ✅ **Strict enforcement**: ENABLED - Package-level enforcement
|
|
||||||
- 🟡 **CI/CD pipeline**: Ready (.woodpecker.yml created, not yet configured)
|
|
||||||
|
|
||||||
How It Works:
|
|
||||||
|
|
||||||
**Package-Level Enforcement** - If you touch ANY file in a package with violations,
|
|
||||||
you must fix ALL violations in that package before committing. This forces incremental
|
|
||||||
cleanup while preventing new violations.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
- Edit `apps/api/src/tasks/tasks.service.ts`
|
|
||||||
- Pre-commit hook runs lint on ENTIRE `@mosaic/api` package
|
|
||||||
- If `@mosaic/api` has violations → Commit BLOCKED
|
|
||||||
- Fix all violations in `@mosaic/api` → Commit allowed
|
|
||||||
|
|
||||||
Next Steps:
|
|
||||||
|
|
||||||
1. Fix violations package-by-package as you work in them
|
|
||||||
2. Priority: Fix explicit `any` types and type safety issues first
|
|
||||||
3. Configure Woodpecker CI to run quality gates on all PRs
|
|
||||||
|
|
||||||
Why This Matters:
|
|
||||||
|
|
||||||
Based on validation of 50 real production issues, Quality Rails mechanically prevents ~70%
|
|
||||||
of quality issues including:
|
|
||||||
|
|
||||||
- Hardcoded passwords
|
|
||||||
- Type safety violations
|
|
||||||
- SQL injection vulnerabilities
|
|
||||||
- Build failures
|
|
||||||
- Test coverage gaps
|
|
||||||
|
|
||||||
**Mechanical enforcement works. Process compliance doesn't.**
|
|
||||||
|
|
||||||
See `docs/quality-rails-status.md` for detailed roadmap and violation breakdown.
|
|
||||||
|
|
||||||
Example TDD Session
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 1. RED - Write failing test
|
|
||||||
# Edit: feature.service.spec.ts
|
|
||||||
# Add test for getUserById()
|
|
||||||
pnpm test:watch # Watch it fail
|
|
||||||
git add feature.service.spec.ts
|
|
||||||
git commit -m "test(#42): add test for getUserById"
|
|
||||||
|
|
||||||
# 2. GREEN - Implement minimal code
|
|
||||||
# Edit: feature.service.ts
|
|
||||||
# Add getUserById() method
|
|
||||||
pnpm test:watch # Watch it pass
|
|
||||||
git add feature.service.ts
|
|
||||||
git commit -m "feat(#42): implement getUserById"
|
|
||||||
|
|
||||||
# 3. REFACTOR - Improve code quality
|
|
||||||
# Edit: feature.service.ts
|
|
||||||
# Extract helper, improve naming
|
|
||||||
pnpm test:watch # Ensure still passing
|
|
||||||
git add feature.service.ts
|
|
||||||
git commit -m "refactor(#42): extract user mapping logic"
|
|
||||||
```
|
|
||||||
|
|
||||||
Docker Deployment
|
|
||||||
|
|
||||||
Turnkey (includes everything)
|
|
||||||
|
|
||||||
docker compose up -d
|
|
||||||
|
|
||||||
Customized (external services)
|
|
||||||
|
|
||||||
Create docker-compose.override.yml to:
|
|
||||||
|
|
||||||
- Point to external PostgreSQL/Valkey/Ollama
|
|
||||||
- Disable bundled services
|
|
||||||
|
|
||||||
See docs/DOCKER.md for details.
|
|
||||||
|
|
||||||
Key Documentation
|
|
||||||
┌───────────────────────────┬───────────────────────┐
|
|
||||||
│ Document │ Purpose │
|
|
||||||
├───────────────────────────┼───────────────────────┤
|
|
||||||
│ docs/SETUP.md │ Installation guide │
|
|
||||||
├───────────────────────────┼───────────────────────┤
|
|
||||||
│ docs/CONFIGURATION.md │ All config options │
|
|
||||||
├───────────────────────────┼───────────────────────┤
|
|
||||||
│ docs/DESIGN-PRINCIPLES.md │ PDA-friendly patterns │
|
|
||||||
├───────────────────────────┼───────────────────────┤
|
|
||||||
│ docs/DOCKER.md │ Docker deployment │
|
|
||||||
├───────────────────────────┼───────────────────────┤
|
|
||||||
│ docs/API.md │ API documentation │
|
|
||||||
└───────────────────────────┴───────────────────────┘
|
|
||||||
Related Repositories
|
|
||||||
┌──────────────┬──────────────────────────────────────────────┐
|
|
||||||
│ Repo │ Purpose │
|
|
||||||
├──────────────┼──────────────────────────────────────────────┤
|
|
||||||
│ jarvis-brain │ Original JSON-based brain (migration source) │
|
|
||||||
├──────────────┼──────────────────────────────────────────────┤
|
|
||||||
│ MoltBot │ Stock messaging gateway │
|
|
||||||
└──────────────┴──────────────────────────────────────────────┘
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Mosaic Stack v0.0.x — Building the future of personal assistants.
|
|
||||||
|
|
||||||
## Campsite Rule (MANDATORY)
|
|
||||||
|
|
||||||
If you modify a line containing a policy violation, you MUST either:
|
|
||||||
|
|
||||||
1. **Fix the violation properly** in the same change, OR
|
|
||||||
2. **Flag it as a deferred item** with documented rationale
|
|
||||||
|
|
||||||
**"It was already there" is NEVER an acceptable justification** for perpetuating a violation in code you touched. Touching it makes it yours.
|
|
||||||
|
|
||||||
Examples of violations you must fix when you touch the line:
|
|
||||||
|
|
||||||
- `as unknown as Type` double assertions — use type guards instead
|
|
||||||
- `any` types — narrow to `unknown` with validation or define a proper interface
|
|
||||||
- Missing error handling — add it if you're modifying the surrounding code
|
|
||||||
- Suppressed linting rules (`// eslint-disable`) — fix the underlying issue
|
|
||||||
|
|
||||||
If the proper fix is too large for the current scope, you MUST:
|
|
||||||
|
|
||||||
- Create a TODO comment with issue reference: `// TODO(#123): Replace double assertion with type guard`
|
|
||||||
- Document the deferral in your PR/commit description
|
|
||||||
- Never silently carry the violation forward
|
|
||||||
|
|||||||
20
SOUL.md
Normal file
20
SOUL.md
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# Mosaic Stack Soul
|
||||||
|
|
||||||
|
You are Jarvis for the Mosaic Stack repository, running on the current agent runtime.
|
||||||
|
|
||||||
|
## Behavioral Invariants
|
||||||
|
|
||||||
|
- Identity first: answer identity prompts as Jarvis for this repository.
|
||||||
|
- Implementation detail second: runtime (Codex/Claude/OpenCode/etc.) is secondary metadata.
|
||||||
|
- Be proactive: surface risks, blockers, and next actions without waiting.
|
||||||
|
- Be calm and clear: keep responses concise, chunked, and PDA-friendly.
|
||||||
|
- Respect canonical sources:
|
||||||
|
- Repo operations and conventions: `AGENTS.md`
|
||||||
|
- Machine-wide rails: `~/.mosaic/STANDARDS.md`
|
||||||
|
- Repo lifecycle hooks: `.mosaic/repo-hooks.sh`
|
||||||
|
|
||||||
|
## Guardrails
|
||||||
|
|
||||||
|
- Do not claim completion without verification evidence.
|
||||||
|
- Do not bypass lint/type/test quality gates.
|
||||||
|
- Prefer explicit assumptions and concrete file/command references.
|
||||||
29
scripts/agent/common.sh
Executable file
29
scripts/agent/common.sh
Executable file
@@ -0,0 +1,29 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
repo_root() {
|
||||||
|
git rev-parse --show-toplevel 2>/dev/null || pwd
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_repo_root() {
|
||||||
|
cd "$(repo_root)"
|
||||||
|
}
|
||||||
|
|
||||||
|
has_remote() {
|
||||||
|
git remote get-url origin >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
run_step() {
|
||||||
|
local label="$1"
|
||||||
|
shift
|
||||||
|
echo "[agent-framework] $label"
|
||||||
|
"$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
load_repo_hooks() {
|
||||||
|
local hooks_file=".mosaic/repo-hooks.sh"
|
||||||
|
if [[ -f "$hooks_file" ]]; then
|
||||||
|
# shellcheck disable=SC1090
|
||||||
|
source "$hooks_file"
|
||||||
|
fi
|
||||||
|
}
|
||||||
16
scripts/agent/critical.sh
Executable file
16
scripts/agent/critical.sh
Executable file
@@ -0,0 +1,16 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
# shellcheck source=./common.sh
|
||||||
|
source "$SCRIPT_DIR/common.sh"
|
||||||
|
|
||||||
|
ensure_repo_root
|
||||||
|
load_repo_hooks
|
||||||
|
|
||||||
|
if declare -F mosaic_hook_critical >/dev/null 2>&1; then
|
||||||
|
run_step "Run repo critical hook" mosaic_hook_critical
|
||||||
|
else
|
||||||
|
echo "[agent-framework] No repo critical hook configured (.mosaic/repo-hooks.sh)"
|
||||||
|
echo "[agent-framework] Define mosaic_hook_critical() for project-specific priority scans"
|
||||||
|
fi
|
||||||
44
scripts/agent/log-limitation.sh
Executable file
44
scripts/agent/log-limitation.sh
Executable file
@@ -0,0 +1,44 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
TITLE="${1:-}"
|
||||||
|
if [[ -z "$TITLE" ]]; then
|
||||||
|
echo "Usage: $0 \"Short limitation title\"" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
FILE="EVOLUTION.md"
|
||||||
|
if [[ ! -f "$FILE" ]]; then
|
||||||
|
echo "[agent-framework] $FILE not found. Create project-specific limitations log if needed."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if command -v rg >/dev/null 2>&1; then
|
||||||
|
last_num=$(rg -o "^### L-[0-9]{3}" "$FILE" | sed 's/^### L-//' | sort -n | tail -1)
|
||||||
|
else
|
||||||
|
last_num=$(grep -E "^### L-[0-9]{3}" "$FILE" | sed 's/^### L-//' | sort -n | tail -1)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$last_num" ]]; then
|
||||||
|
next_num="001"
|
||||||
|
else
|
||||||
|
next_num=$(printf "%03d" $((10#$last_num + 1)))
|
||||||
|
fi
|
||||||
|
|
||||||
|
entry_id="L-$next_num"
|
||||||
|
|
||||||
|
cat <<EOF2
|
||||||
|
|
||||||
|
### $entry_id: $TITLE
|
||||||
|
|
||||||
|
| Aspect | Details |
|
||||||
|
|--------|---------|
|
||||||
|
| **Pain** | TODO |
|
||||||
|
| **Impact** | TODO |
|
||||||
|
| **Frequency** | TODO |
|
||||||
|
| **Current Workaround** | TODO |
|
||||||
|
| **Proposed Solution** | TODO |
|
||||||
|
| **Platform Implication** | TODO |
|
||||||
|
EOF2
|
||||||
|
|
||||||
|
echo "[agent-framework] Suggested limitation ID: $entry_id"
|
||||||
20
scripts/agent/session-end.sh
Executable file
20
scripts/agent/session-end.sh
Executable file
@@ -0,0 +1,20 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
# shellcheck source=./common.sh
|
||||||
|
source "$SCRIPT_DIR/common.sh"
|
||||||
|
|
||||||
|
ensure_repo_root
|
||||||
|
load_repo_hooks
|
||||||
|
|
||||||
|
if declare -F mosaic_hook_session_end >/dev/null 2>&1; then
|
||||||
|
run_step "Run repo end hook" mosaic_hook_session_end
|
||||||
|
else
|
||||||
|
echo "[agent-framework] No repo end hook configured (.mosaic/repo-hooks.sh)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
||||||
|
run_step "Show status" git status --short
|
||||||
|
run_step "Show diff summary" git diff --stat
|
||||||
|
fi
|
||||||
23
scripts/agent/session-start.sh
Executable file
23
scripts/agent/session-start.sh
Executable file
@@ -0,0 +1,23 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
# shellcheck source=./common.sh
|
||||||
|
source "$SCRIPT_DIR/common.sh"
|
||||||
|
|
||||||
|
ensure_repo_root
|
||||||
|
load_repo_hooks
|
||||||
|
|
||||||
|
if git rev-parse --is-inside-work-tree >/dev/null 2>&1 && has_remote; then
|
||||||
|
if git diff --quiet && git diff --cached --quiet; then
|
||||||
|
run_step "Pull latest changes" git pull --rebase
|
||||||
|
else
|
||||||
|
echo "[agent-framework] Skip pull: working tree has local changes"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if declare -F mosaic_hook_session_start >/dev/null 2>&1; then
|
||||||
|
run_step "Run repo start hook" mosaic_hook_session_start
|
||||||
|
else
|
||||||
|
echo "[agent-framework] No repo start hook configured (.mosaic/repo-hooks.sh)"
|
||||||
|
fi
|
||||||
Reference in New Issue
Block a user