chore: sync local Mosaic changes

This commit is contained in:
Jason Woltje
2026-02-21 09:55:34 -06:00
parent 1e4eefeca3
commit e3ec3e32e5
82 changed files with 5398 additions and 1969 deletions

780
AGENTS.md Normal file → Executable file
View File

@@ -1,633 +1,147 @@
# Mosaic Global Agent Standards # Mosaic Global Agent Contract
This is the universal agent configuration file for the Mosaic framework. Canonical file: `~/.config/mosaic/AGENTS.md`
It applies to ALL agent sessions regardless of runtime (Claude, Codex, OpenCode, etc.).
This file defines the mandatory behavior for all Mosaic agent runtimes.
Canonical location: `~/.config/mosaic/AGENTS.md`
## MANDATORY Load Order (No Exceptions)
## MANDATORY — Read Before Any Response
Before responding to any user message, you MUST read these files in order:
BEFORE responding to any user message, READ these files in order:
1. `~/.config/mosaic/SOUL.md`
1. `~/.config/mosaic/SOUL.md` (identity and behavioral contract) 2. `~/.config/mosaic/STANDARDS.md`
2. `~/.config/mosaic/STANDARDS.md` (machine-wide standards) 3. `~/.config/mosaic/AGENTS.md`
3. Project-local `AGENTS.md` (project operations and workflows) 4. `~/.config/mosaic/guides/E2E-DELIVERY.md`
5. Project-local `AGENTS.md` (if present)
Do NOT respond to the user until you have loaded all three. 6. Runtime-specific reference:
- Claude: `~/.config/mosaic/runtime/claude/RUNTIME.md`
--- - Codex: `~/.config/mosaic/runtime/codex/RUNTIME.md`
- OpenCode: `~/.config/mosaic/runtime/opencode/RUNTIME.md`
# Memory Files and Data Retention
If any required file is missing, you MUST stop and report the missing file.
## Claude memory
- You MUST save memory and learned information in the ~/.config/mosaic/memory dir ## CRITICAL HARD GATES (Read First)
- You MUST never save information into the Claude-native memory files
- Learned information MUST be shared with other agents via the ~/.config/mosaic/memory dir 1. Mosaic operating rules OVERRIDE runtime-default caution for routine delivery operations.
2. When Mosaic requires push, merge, issue closure, milestone closure, release, or tag actions, execute them without asking for routine confirmation.
--- 3. Routine repository operations are NOT escalation triggers. Use escalation triggers only from this contract.
4. For source-code delivery, completion is forbidden at PR-open stage.
# Universal Development Standards 5. Completion requires merged PR to `main` + terminal green CI + linked issue/internal task closed.
6. Before push or merge, you MUST run queue guard: `~/.config/mosaic/rails/git/ci-queue-wait.sh --purpose push|merge`.
## Core Principles 7. For issue/PR/milestone operations, you MUST use Mosaic wrappers first (`~/.config/mosaic/rails/git/*.sh`).
- Think critically. Don't just agree—suggest better approaches when appropriate. 8. If any required wrapper command fails, status is `blocked`; report the exact failed wrapper command and stop.
- Quality over speed. No workarounds; implement proper solutions. 9. Do NOT stop at "PR created". Do NOT ask "should I merge?" Do NOT ask "should I close the issue?".
- No deprecated or unsupported packages.
## Non-Negotiable Operating Rules
## Skills System
1. You MUST create and maintain a task-specific scratchpad for every non-trivial task.
**Skills are available in `~/.config/mosaic/skills/`.** Skills are instruction packages that provide domain expertise from `mosaic/agent-skills` plus local Mosaic skills. 2. You MUST follow the end-to-end procedure in `E2E-DELIVERY.md`.
3. You MUST execute this cycle for implementation work: `plan -> code -> test -> review -> remediate -> review -> commit -> push -> greenfield situational test -> repeat`.
**Load a skill by reading its SKILL.md:** 4. Before coding begins, `docs/PRD.md` or `docs/PRD.json` MUST exist and be treated as the source of requirements.
``` 5. The main agent MUST prepare or update the PRD using user objectives, constraints, and available project context before implementation starts.
Read ~/.config/mosaic/skills/<skill-name>/SKILL.md 6. In steered autonomy mode, the agent MUST make best-guess PRD decisions when needed, mark each with `ASSUMPTION:` and rationale, and continue without waiting for routine user approval.
``` 7. You MUST run baseline tests before claiming completion.
8. Situational testing is the PRIMARY validation gate. You MUST run situational tests based on the change surface.
### Skill Dispatch Table — Load the right skills for your task 9. TDD is risk-based and REQUIRED for bug fixes, security/auth/permission logic, and critical business logic/data mutations (see `~/.config/mosaic/guides/QA-TESTING.md`).
10. If you modify source code, you MUST run an independent code review before completion.
| Task Type | Skills to Load | Notes | 11. You MUST update required documentation for code/API/auth/infra changes per `~/.config/mosaic/guides/DOCUMENTATION.md`.
|-----------|---------------|-------| 12. You MUST provide verification evidence before completion claims.
| **NestJS development** | `nestjs-best-practices` | 40 rules, 10 categories | 13. You MUST NOT use workarounds that bypass quality gates.
| **Next.js / React** | `next-best-practices`, `vercel-react-best-practices` | RSC, async, performance | 14. You MUST NOT hardcode secrets.
| **React components** | `vercel-composition-patterns`, `shadcn-ui` | shadcn note: uses Tailwind v4 | 15. You MUST NOT use deprecated or unsupported dependencies.
| **Vue / Nuxt** | `vue-best-practices`, `nuxt`, `pinia`, `vue-router-best-practices` | antfu conventions | 16. When a milestone is completed, you MUST create and push a release tag and publish a repository release.
| **Vite / Vitest** | `vite`, `vitest` | Build + test tooling | 17. For every non-trivial implementation task, you MUST create or update `docs/TASKS.md` before coding and keep it current through completion.
| **FastAPI / Python** | `fastapi`, `python-performance-optimization` | Pydantic v2, async SQLAlchemy | 18. You MUST keep `docs/` root clean and place reports/artifacts in scoped folders per `~/.config/mosaic/guides/DOCUMENTATION.md`.
| **Architecture** | `architecture-patterns` | Clean, Hexagonal, DDD | 19. For TypeScript codebases, DTO files are REQUIRED for module/API boundaries (`*.dto.ts`).
| **Authentication** | `better-auth-best-practices`, `email-and-password-best-practices`, `two-factor-authentication-best-practices` | Better-Auth patterns | 20. You MUST honor user plan/token budgets: monitor estimated vs used tokens and adjust execution strategy to stay within limits.
| **UI / Styling** | `tailwind-design-system`, `ui-animation`, `web-design-guidelines` | Tailwind v4 | 21. You MUST use trunk merge strategy: branch from `main`, merge to `main` via PR only, never push directly to `main`, and use squash merge only.
| **Frontend design** | `frontend-design`, `brand-guidelines`, `canvas-design` | Design principles | 22. You MUST own project execution end-to-end: planning, coding, testing, review, remediation, PR/repo operations, release/tag, and deployment when in scope.
| **TDD / Testing** | `test-driven-development`, `webapp-testing`, `vue-testing-best-practices` | Red-Green-Refactor | 23. Human intervention is escalation-only; do not ask the human to perform routine coding, review, or repository management work.
| **Linting** | `lint` | Zero-tolerance — detect linter, fix ALL violations, never disable rules | 24. Deployment ownership is REQUIRED when deployment is in scope and target access is configured.
| **Code review** | `pr-reviewer`, `code-review-excellence`, `verification-before-completion` | Platform-aware (Gitea/GitHub) | 25. For container deployments, you MUST use immutable image tags (`sha-*`, `vX.Y.Z-rc.N`) with digest-first promotion; `latest` is forbidden as a deployment reference.
| **Debugging** | `systematic-debugging` | Structured methodology | 26. If an external git provider is available (Gitea/GitHub/GitLab), you MUST create or update issue(s) and link them in `docs/TASKS.md` before coding; if unavailable, use `TASKS:<id>` internal refs in `docs/TASKS.md`.
| **Git workflow** | `finishing-a-development-branch`, `using-git-worktrees` | Branch + worktree patterns | 27. For provider operations (issue/PR/milestone), you MUST detect platform first and use `~/.config/mosaic/rails/git/*.sh` wrappers before any raw provider CLI/API calls.
| **Document generation** | `pdf`, `docx`, `pptx`, `xlsx` | LibreOffice-based | 28. Direct `gh`/`tea`/`glab` commands are forbidden as first choice when a Mosaic wrapper exists; use raw commands only as documented fallback.
| **Writing / Comms** | `doc-coauthoring`, `internal-comms`, `copywriting`, `copy-editing` | | 29. If the mission is orchestration-oriented (contains "orchestrate", issue/milestone coordination, or multi-task execution), you MUST load and follow `~/.config/mosaic/guides/ORCHESTRATOR.md` before taking action.
| **Marketing** | `marketing-ideas`, `content-strategy`, `social-content`, `email-sequence` | 139 ideas across 14 categories | 30. At session start, you MUST declare the operating mode in your first response before any tool calls or implementation steps.
| **SEO** | `seo-audit`, `programmatic-seo`, `schema-markup` | Technical + content SEO | 31. For orchestration-oriented missions, the first line MUST be exactly: `Now initiating Orchestrator mode...`
| **CRO / Conversion** | `page-cro`, `form-cro`, `signup-flow-cro`, `onboarding-cro` | Conversion optimization | 32. For non-orchestrator implementation missions, the first line MUST be exactly: `Now initiating Delivery mode...`
| **Pricing / Business** | `pricing-strategy`, `launch-strategy`, `competitor-alternatives` | SaaS focus | 33. For explicit review-only missions, the first line MUST be exactly: `Now initiating Review mode...`
| **Ads / Growth** | `paid-ads`, `analytics-tracking`, `ab-test-setup`, `referral-program` | | 34. For source-code delivery through PR workflow, completion is forbidden until the PR is merged to `main`, CI/pipeline status is terminal green, and linked issue/internal task is closed.
| **Agent building** | `create-agent`, `ai-sdk`, `proactive-agent`, `dispatching-parallel-agents` | WAL Protocol, parallel workers | 35. If merge/CI/issue-closure operations fail, you MUST report a blocker with the exact failed wrapper command and stop instead of declaring completion.
| **Agent workflow** | `executing-plans`, `writing-plans`, `brainstorming` | Plan → execute | 36. Before push or PR merge, you MUST run CI queue guard and wait if the project has running/queued pipelines: `~/.config/mosaic/rails/git/ci-queue-wait.sh --purpose push|merge`.
| **Skill authoring** | `writing-skills`, `skill-creator` | TDD-based skill creation |
| **MCP servers** | `mcp-builder` | Model Context Protocol | ## Mode Declaration Protocol (Hard Rule)
| **Generative art** | `algorithmic-art`, `theme-factory`, `slack-gif-creator` | |
| **Web artifacts** | `web-artifacts-builder` | Self-contained HTML | At session start, declare one mode before any actions:
| **CI/CD setup** | `setup-cicd` | Docker build/push pipeline |
| **Jarvis Brain** | `jarvis` | Brain repo context | 1. Orchestration mission: `Now initiating Orchestrator mode...`
| **PRD creation** | `prd` | Generate PRDs | 2. Implementation mission: `Now initiating Delivery mode...`
| **Ralph development** | `ralph` | Autonomous dev agent | 3. Review-only mission: `Now initiating Review mode...`
| **Orchestration** | `kickstart` | `/kickstart [milestone\|issue\|task]` — launches orchestrator |
## Steered Autonomy Escalation Triggers
### For Orchestrator / Programmatic Workers
Only interrupt the human when one of these is true:
When spawning workers, include skill loading in the kickstart:
```bash 1. Missing credentials or platform access blocks progress.
claude -p "Read ~/.config/mosaic/skills/nestjs-best-practices/SKILL.md then implement..." 2. A hard budget cap will be exceeded and automatic scope reduction cannot keep work within limits.
codex exec "Read ~/.config/mosaic/skills/nestjs-best-practices/SKILL.md then implement..." 3. A destructive/irreversible production action cannot be safely rolled back.
``` 4. Legal/compliance/security constraints are unknown and materially affect delivery.
5. Objectives are mutually conflicting and cannot be resolved from PRD, repo, or prior decisions.
For Ralph prd.json stories, add a `skills` field:
```json ## Conditional Guide Loading
{ "id": "US-001", "skills": ["nestjs-best-practices", "test-driven-development"], ... }
``` Load additional guides when the task requires them.
### Fresh Machine Setup | Task | Required Guide |
```bash |---|---|
npx skills add https://git.mosaicstack.dev/mosaic/agent-skills.git --agent claude-code | Project bootstrap | `~/.config/mosaic/guides/BOOTSTRAP.md` |
``` | PRD creation and requirements definition | `~/.config/mosaic/guides/PRD.md` |
| Orchestration flow | `~/.config/mosaic/guides/ORCHESTRATOR.md` |
## Ralph Autonomous Development | Frontend changes | `~/.config/mosaic/guides/FRONTEND.md` |
| Backend/API changes | `~/.config/mosaic/guides/BACKEND.md` |
For autonomous feature development, use the Ralph pattern. Each iteration is a fresh context with persistent memory. | Documentation changes or any code/API/auth/infra change | `~/.config/mosaic/guides/DOCUMENTATION.md` |
| Authentication/authorization | `~/.config/mosaic/guides/AUTHENTICATION.md` |
### The Ralph Loop | CI/CD changes | `~/.config/mosaic/guides/CI-CD-PIPELINES.md` |
``` | Infrastructure/DevOps | `~/.config/mosaic/guides/INFRASTRUCTURE.md` |
1. Read prd.json → Find highest priority story where passes: false | Code review work | `~/.config/mosaic/guides/CODE-REVIEW.md` |
2. Read progress.txt → Check "Codebase Patterns" section first | TypeScript strict typing | `~/.config/mosaic/guides/TYPESCRIPT.md` |
3. Read AGENTS.md files → Check directory-specific patterns | QA and test strategy | `~/.config/mosaic/guides/QA-TESTING.md` |
4. Implement ONLY the single assigned story | Secrets and vault usage | `~/.config/mosaic/guides/VAULT-SECRETS.md` |
5. Run quality checks (typecheck, lint, test) | Orchestrator estimation heuristics | `~/.config/mosaic/guides/ORCHESTRATOR-LEARNINGS.md` |
6. Commit ONLY if all checks pass | Shared memory patterns | `~/.config/mosaic/guides/MEMORY.md` |
7. Update prd.json → Set passes: true for completed story
8. Append learnings to progress.txt ## Embedded Delivery Cycle (Hard Rule)
9. Update AGENTS.md if reusable patterns discovered
10. Loop → Next story - Implementation work MUST follow the embedded execution cycle:
``` - `plan -> code -> test -> review -> remediate -> review -> commit -> push -> greenfield situational test -> repeat`
- If a step fails, you MUST remediate and re-run from the relevant step before proceeding.
### Memory Files
| File | Purpose | Location | ## Sequential-Thinking MCP (Hard Requirement)
|------|---------|----------|
| `prd.json` | Task list with passes: true/false | Project root or scripts/ralph/ | - `sequential-thinking` MCP server is REQUIRED for Mosaic operation.
| `progress.txt` | Learnings between iterations | Same as prd.json | - Installation and configuration are managed by Mosaic bootstrap and runtime linking.
| `AGENTS.md` | Directory-specific patterns | Any directory in repo | - If sequential-thinking is unavailable, you MUST report the failure and stop planning-intensive execution.
### Running Ralph ## Skills Policy
```bash
# Automated loop - Use only the minimum required skills for the active task.
./scripts/ralph/ralph.sh 10 - Do not load unrelated skills.
- Follow skill trigger rules from the active runtime instruction layer.
# Manual single story
claude -p "Implement US-001 from prd.json following Ralph pattern" ## Session Closure Requirement
```
Before closing any implementation task:
### Creating New Features
1. Create PRD: `Load the prd skill and create a PRD for [feature]` 1. Confirm required tests passed.
2. Convert to Ralph: `Load the ralph skill and convert tasks/prd-[name].md to prd.json` 2. Confirm situational tests passed (primary gate).
3. Run Ralph: `./scripts/ralph/ralph.sh` 3. Confirm implementation is aligned to the active `docs/PRD.md` or `docs/PRD.json`.
4. Confirm acceptance criteria are mapped to verification evidence.
**For full Ralph guide:** `~/.config/mosaic/guides/ralph-autonomous.md` 5. If source code changed, confirm independent code review passed.
6. Confirm required documentation updates were completed and reviewed.
## Project-Local AGENTS.md Pattern 7. Update scratchpad with decisions, results, and open risks.
8. Provide explicit completion evidence.
Each directory can have an `AGENTS.md` file containing patterns specific to that area of the codebase. **Always check for and read AGENTS.md files in directories you're working in.** 9. If source code changed and external provider is available, confirm merged PR number and merge commit on `main`.
10. Confirm CI/pipeline status is terminal green for the merged change (or merged PR head when equivalent).
```markdown 11. Confirm linked issue is closed (or internal `docs/TASKS.md` equivalent is closed when no provider exists).
# Example AGENTS.md 12. If any of items 9-11 are blocked by access/tooling failure, return `blocked` status with exact failed wrapper command and do not claim completion.
## Codebase Patterns
- Use `httpx.AsyncClient` for external HTTP calls
- All routes require authentication via `Depends(get_current_user)`
## Common Gotchas
- Remember to run migrations after schema changes
- Frontend env vars need NEXT_PUBLIC_ prefix
```
**Update AGENTS.md when you discover:**
- Reusable patterns
- Non-obvious requirements
- Gotchas that would trip up future agents
- Testing approaches for that area
## Project Bootstrapping
When starting work on a **new project** that lacks an `AGENTS.md`, bootstrap it:
```bash
# Automated (recommended)
~/.config/mosaic/rails/bootstrap/init-project.sh --name "Project Name" --type auto
# Or manually with templates
export PROJECT_NAME="Project Name" PROJECT_DESCRIPTION="What it does" TASK_PREFIX="PN"
envsubst < ~/.config/mosaic/templates/agent/AGENTS.md.template > AGENTS.md
```
**Available project types:** `nestjs-nextjs`, `django`, `typescript`, `python-fastapi`, `python-library`, `generic` (auto-detected from project files).
**Templates:** `~/.config/mosaic/templates/agent/` (generic) and `~/.config/mosaic/templates/agent/projects/<type>/` (tech-stack specific).
**Fragments:** `~/.config/mosaic/templates/agent/fragments/` — Reusable sections (conditional-loading, commit-format, secrets, multi-agent, code-review).
**Full guide:** `~/.config/mosaic/guides/bootstrap.md`
### Agent Configuration Health
```bash
# Audit all projects for missing AGENTS.md, agent-guide references
~/.config/mosaic/rails/bootstrap/agent-lint.sh
# Audit with fix suggestions
~/.config/mosaic/rails/bootstrap/agent-lint.sh --verbose --fix-hint
# Non-destructively upgrade existing projects (inject missing sections)
~/.config/mosaic/rails/bootstrap/agent-upgrade.sh --all --dry-run # Preview
~/.config/mosaic/rails/bootstrap/agent-upgrade.sh --all # Apply
# Upgrade a single project
~/.config/mosaic/rails/bootstrap/agent-upgrade.sh ~/src/my-project
```
**Spec:** `~/.config/mosaic/templates/agent/SPEC.md` — Defines Tier 1/2/3 requirements for well-configured projects.
## Issue Tracking (Git-Based)
All work is tracked as **issues in the project's git repository** (Gitea or GitHub).
### Workflow
1. Check for assigned issues before starting work
2. Create scratchpad: `docs/scratchpads/{issue-number}-{short-name}.md`
3. Reference issues in commits: `Fixes #123` or `Refs #123`
4. Close issues only after successful testing
### Labels
Use consistent labels across projects:
- `epic` - Large feature spanning multiple issues
- `feature` - New functionality
- `bug` - Defect fix
- `task` - General work item
- `documentation` - Docs updates
- `security` - Security-related
- `breaking` - Breaking change
### Milestones & Versioning
- **Each feature gets a dedicated milestone**
- MVP starts at `0.1.0`
- Pre-release: `0.X.0` for breaking changes, `0.X.Y` for patches
- Post-release: `X.0.0` for breaking changes
### Git Scripts (PREFERRED for Gitea/GitHub operations)
Cross-platform helpers at `~/.config/mosaic/rails/git/` (work with both Gitea and GitHub):
**Why use these scripts?**
- Auto-detect platform (Gitea vs GitHub)
- Abstract CLI syntax differences (tea vs gh)
- Handle milestone name filtering for Gitea
- Consistent interface across all repos
**Issues:**
```bash
~/.config/mosaic/rails/git/issue-create.sh -t "Title" -l "label" -m "0.2.0"
~/.config/mosaic/rails/git/issue-list.sh -s open -l "bug"
~/.config/mosaic/rails/git/issue-list.sh -m "M6-AgentOrchestration"
~/.config/mosaic/rails/git/issue-view.sh -i 42
~/.config/mosaic/rails/git/issue-edit.sh -i 42 -t "New Title" -l "labels"
~/.config/mosaic/rails/git/issue-assign.sh -i 42 -a "username"
~/.config/mosaic/rails/git/issue-comment.sh -i 42 -c "Comment text"
~/.config/mosaic/rails/git/issue-close.sh -i 42 [-c "Closing comment"]
~/.config/mosaic/rails/git/issue-reopen.sh -i 42 [-c "Reopening reason"]
```
**Pull Requests:**
```bash
~/.config/mosaic/rails/git/pr-create.sh -t "Title" -b "Description" -i 42
~/.config/mosaic/rails/git/pr-create.sh -t "Title" -B main -H feature-branch
~/.config/mosaic/rails/git/pr-list.sh -s open
~/.config/mosaic/rails/git/pr-view.sh -n 42
~/.config/mosaic/rails/git/pr-review.sh -n 42 -a approve [-c "LGTM"]
~/.config/mosaic/rails/git/pr-review.sh -n 42 -a request-changes -c "Fix X"
~/.config/mosaic/rails/git/pr-merge.sh -n 42 -m squash -d
~/.config/mosaic/rails/git/pr-close.sh -n 42 [-c "Closing reason"]
~/.config/mosaic/rails/git/pr-diff.sh -n 42 [-o diff.patch]
~/.config/mosaic/rails/git/pr-metadata.sh -n 42 [-o metadata.json]
```
**Milestones:**
```bash
~/.config/mosaic/rails/git/milestone-create.sh -t "0.2.0" -d "Description"
~/.config/mosaic/rails/git/milestone-create.sh --list
~/.config/mosaic/rails/git/milestone-list.sh [-s open|closed|all]
~/.config/mosaic/rails/git/milestone-close.sh -t "0.2.0"
```
**NOTE:** These scripts handle the Gitea `--milestones` (plural) syntax automatically. Always prefer these over raw `tea` or `gh` commands.
### Woodpecker CI CLI
Official CLI for interacting with Woodpecker CI at `ci.mosaicstack.dev`.
**Setup:**
```bash
# Install (Arch)
paru -S woodpecker
# Configure
export WOODPECKER_SERVER="https://ci.mosaicstack.dev"
export WOODPECKER_TOKEN="your-token" # Get from ci.mosaicstack.dev/user
```
**Pipelines:**
```bash
woodpecker pipeline ls <owner/repo> # List pipelines
woodpecker pipeline info <owner/repo> <num> # Pipeline details
woodpecker pipeline create <owner/repo> # Trigger pipeline
woodpecker pipeline stop <owner/repo> <num> # Cancel pipeline
woodpecker pipeline start <owner/repo> <num> # Restart pipeline
woodpecker pipeline approve <owner/repo> <num> # Approve blocked
```
**Logs:**
```bash
woodpecker log show <owner/repo> <num> # View logs
woodpecker log show <owner/repo> <num> <step> # Specific step
```
**Repositories:**
```bash
woodpecker repo ls # List repos
woodpecker repo add <owner/repo> # Activate for CI
woodpecker repo rm <owner/repo> # Deactivate
woodpecker repo repair <owner/repo> # Repair webhooks
```
**Secrets:**
```bash
woodpecker secret ls <owner/repo> # List secrets
woodpecker secret add <owner/repo> -n KEY -v val # Add secret
woodpecker secret rm <owner/repo> -n KEY # Delete secret
```
**Full reference:** `jarvis-brain/docs/reference/woodpecker/WOODPECKER-CLI.md`
**Setup command:** `woodpecker setup --server https://ci.mosaicstack.dev --token "YOUR_TOKEN"`
### Portainer Scripts
CLI tools for managing Portainer stacks at `~/.config/mosaic/rails/portainer/`.
**Setup:**
```bash
export PORTAINER_URL="https://portainer.example.com:9443"
export PORTAINER_API_KEY="your-api-key-here"
```
Create an API key in Portainer: My account → Access tokens → Add access token.
**Stack Management:**
```bash
stack-list.sh # List all stacks
stack-list.sh -f json # JSON format
stack-list.sh -e 1 # Filter by endpoint
stack-status.sh -n mystack # Show stack status
stack-status.sh -n mystack -f json # JSON format
stack-redeploy.sh -n mystack # Redeploy stack
stack-redeploy.sh -n mystack -p # Pull latest images
stack-start.sh -n mystack # Start inactive stack
stack-stop.sh -n mystack # Stop running stack
```
**Logs:**
```bash
stack-logs.sh -n mystack # List services
stack-logs.sh -n mystack -s webapp # View service logs
stack-logs.sh -n mystack -s webapp -t 200 # Last 200 lines
stack-logs.sh -n mystack -s webapp -f # Follow logs
```
**Endpoints:**
```bash
endpoint-list.sh # List all endpoints
endpoint-list.sh -f json # JSON format
```
**Common Workflow (CI/CD redeploy):**
```bash
~/.config/mosaic/rails/portainer/stack-redeploy.sh -n myapp -p && \
~/.config/mosaic/rails/portainer/stack-status.sh -n myapp && \
~/.config/mosaic/rails/portainer/stack-logs.sh -n myapp -s api -t 50
```
### Git Worktrees
Use worktrees for parallel work on multiple issues without branch switching.
**Structure:**
```
{project_name}_worktrees/{issue-name}/
```
**Example:**
```
~/src/my-app/ # Main repository
~/src/my-app_worktrees/
├── 42-fix-login/ # Worktree for issue #42
├── 57-add-dashboard/ # Worktree for issue #57
└── 89-refactor-auth/ # Worktree for issue #89
```
**Commands:**
```bash
# Create worktree for an issue
git worktree add ../my-app_worktrees/42-fix-login -b issue-42-fix-login
# List active worktrees
git worktree list
# Remove worktree after merge
git worktree remove ../my-app_worktrees/42-fix-login
```
**When to use worktrees:**
- Working on multiple issues simultaneously
- Long-running feature branches that need isolation
- Code reviews while continuing other work
- Comparing implementations across branches
## Development Requirements
### Test-Driven Development (TDD)
1. Write tests BEFORE implementation
2. Minimum **85% coverage**
3. Build and test after EVERY change
4. Task completion requires passing tests
### Linting (MANDATORY)
**Run the project linter after every code change. Fix ALL violations. Zero tolerance.**
- Never disable lint rules (`eslint-disable`, `noqa`, `nolint`)
- Never leave warnings — warnings are errors you haven't fixed yet
- If you touched a file, you own its lint violations (Campsite Rule)
- If unsure what linter the project uses, read the `lint` skill: `~/.config/mosaic/skills/lint/SKILL.md`
### Code Style
Follow [Google Style Guides](https://github.com/google/styleguide) for all languages.
### Commits
```
<type>(#issue): Brief description
Detailed explanation if needed.
Fixes #123
```
Types: `feat`, `fix`, `docs`, `test`, `refactor`, `chore`
## Scratchpad Format
When working on issue #N, create `docs/scratchpads/N-short-name.md`:
```markdown
# Issue #N: Title
## Objective
[What this issue accomplishes]
## Approach
[Implementation plan]
## Progress
- [ ] Step 1
- [ ] Step 2
## Testing
[Test plan and results]
## Notes
[Findings, blockers, decisions]
```
## Conditional Context
**Read the relevant guide before starting work:**
| Task Type | Guide |
|-----------|-------|
| Bootstrapping a new project | `~/.config/mosaic/guides/bootstrap.md` |
| Orchestrating autonomous task completion | `~/.config/mosaic/guides/orchestrator.md` |
| Ralph autonomous development | `~/.config/mosaic/guides/ralph-autonomous.md` |
| Frontend development | `~/.config/mosaic/guides/frontend.md` |
| Backend/API development | `~/.config/mosaic/guides/backend.md` |
| Code review | `~/.config/mosaic/guides/code-review.md` |
| Authentication/Authorization | `~/.config/mosaic/guides/authentication.md` |
| CI/CD pipelines & Docker builds | `~/.config/mosaic/guides/ci-cd-pipelines.md` |
| Infrastructure/DevOps | `~/.config/mosaic/guides/infrastructure.md` |
| QA/Testing | `~/.config/mosaic/guides/qa-testing.md` |
| Secrets management | See section below |
**Project-specific skills:**
| Project | Skill |
|---------|-------|
| jetrich/jarvis | `~/.config/mosaic/skills/jarvis/SKILL.md` |
## Secrets Management
**NEVER hardcode secrets in the codebase.** Choose the appropriate method based on your environment.
### If Using Vault
See `~/.config/mosaic/guides/vault-secrets.md` for the canonical structure and rules.
Quick reference:
```
{mount}/{service}/{component}/{secret-name}
Example: secret-prod/postgres/database/app
```
### If NOT Using Vault (Use .env Files)
**Structure:**
```
project-root/
├── .env.example # Template with placeholder values (committed)
├── .env # Local secrets (NEVER committed)
├── .env.development # Dev overrides (optional, not committed)
├── .env.test # Test environment (optional, not committed)
└── .gitignore # Must include .env*
```
**Rules:**
1. **ALWAYS** add `.env*` to `.gitignore` (except `.env.example`)
2. Create `.env.example` with all required variables and placeholder values
3. Use descriptive variable names: `DATABASE_URL`, `API_SECRET_KEY`
4. Document required variables in README
5. Load via `dotenv` or framework-native methods
**.env.example template:**
```bash
# Database
DATABASE_URL=postgresql://user:password@localhost:5432/dbname
DATABASE_POOL_SIZE=10
# Authentication
JWT_SECRET_KEY=your-secret-key-here
JWT_EXPIRY_SECONDS=3600
# External APIs
STRIPE_API_KEY=sk_test_xxx
SENDGRID_API_KEY=SG.xxx
# App Config
APP_ENV=development
DEBUG=false
```
**Loading secrets:**
```python
# Python
from dotenv import load_dotenv
load_dotenv()
# Node.js
import 'dotenv/config';
# Or use framework-native (Next.js, NestJS, etc.)
```
### Security Rules (All Environments)
1. **Never commit secrets** - Use .env or Vault
2. **Never log secrets** - Mask in logs if needed
3. **Rotate compromised secrets immediately**
4. **Use different secrets per environment**
5. **Validate secrets exist at startup** - Fail fast if missing
## Multi-Agent Coordination
When launching concurrent agents:
```bash
nohup claude -p "<instruction>" > logs/agent-{name}.log 2>&1 &
```
- Maximum 10 simultaneous agents
- Monitor for errors and permission issues
- Restart failed agents after fixing issues
**For Ralph multi-agent:**
- Use worktrees for isolation
- Each agent works on different story
- Coordinate via git (frequent pulls)
## Dev Server Infrastructure (web1.corp.uscllc.local)
### Shared Traefik Reverse Proxy
A shared Traefik instance handles routing for all dev/test services on this server.
**Location:** `~/src/traefik`
**Start Traefik:**
```bash
cd ~/src/traefik
docker compose up -d
```
**Dashboard:** http://localhost:8080
### Connecting Services to Traefik
Add to your service's `docker-compose.yml`:
```yaml
services:
app:
labels:
- "traefik.enable=true"
- "traefik.http.routers.myapp.rule=Host(`myapp.uscllc.com`)"
- "traefik.http.routers.myapp.entrypoints=websecure"
- "traefik.http.routers.myapp.tls=true"
- "traefik.http.services.myapp.loadbalancer.server.port=3000"
networks:
- internal
- traefik-public
networks:
internal:
driver: bridge
traefik-public:
external: true
```
**Note:** Uses self-signed wildcard cert - browsers will show security warning.
### Active Dev Services
| Service | Domain | Repository |
|---------|--------|------------|
| Inventory Stickers | inventory.uscllc.com | ~/src/sticker-app |
## Project Structure
```
project-root/
├── AGENTS.md # Codebase patterns for AI agents
├── docs/
│ └── scratchpads/ # Agent working documents
│ └── {issue#}-{name}.md
├── scripts/
│ └── ralph/ # Ralph autonomous development
│ ├── ralph.sh # Loop script
│ ├── prd.json # Current feature tasks
│ └── progress.txt # Memory between iterations
├── tasks/ # PRD documents
│ └── prd-{feature}.md
├── logs/ # Log files
└── tests/ # Test files
```

View File

@@ -100,7 +100,7 @@ The following legacy references remain in `mosaic-bootstrap` by design and are n
- `README.md` - `README.md`
- `profiles/README.md` - `profiles/README.md`
- `adapters/claude.md` - `adapters/claude.md`
- `runtime/claude/settings-overlays/jarvis-ralph.json` - `runtime/claude/settings-overlays/jarvis-loop.json`
These are required to support existing Claude runtime integration while keeping Mosaic as canonical source. These are required to support existing Claude runtime integration while keeping Mosaic as canonical source.

View File

@@ -29,6 +29,7 @@ The installer will:
- Install the framework to `~/.config/mosaic/` - Install the framework to `~/.config/mosaic/`
- Add `~/.config/mosaic/bin` to your PATH - Add `~/.config/mosaic/bin` to your PATH
- Sync runtime adapters and skills - Sync runtime adapters and skills
- Install and configure sequential-thinking MCP (hard requirement)
- Run a health audit - Run a health audit
- Detect existing installs and prompt to keep or overwrite local files - Detect existing installs and prompt to keep or overwrite local files
- Prompt you to run `mosaic init` to set up your agent identity - Prompt you to run `mosaic init` to set up your agent identity
@@ -66,13 +67,20 @@ You can still launch runtimes directly (`claude`, `codex`, etc.) — thin runtim
├── AGENTS.md ← THE source of truth (all standards, all runtimes) ├── AGENTS.md ← THE source of truth (all standards, all runtimes)
├── SOUL.md ← User identity (generated by mosaic init) ├── SOUL.md ← User identity (generated by mosaic init)
├── STANDARDS.md ← Machine-wide standards ├── STANDARDS.md ← Machine-wide standards
├── guides/E2E-DELIVERY.md ← Mandatory E2E software delivery procedure
├── guides/PRD.md ← Mandatory PRD requirements gate before coding
├── guides/DOCUMENTATION.md ← Mandatory documentation standard and gates
├── bin/ ← CLI tools (mosaic, mosaic-init, mosaic-doctor, etc.) ├── bin/ ← CLI tools (mosaic, mosaic-init, mosaic-doctor, etc.)
├── guides/ ← Operational guides ├── guides/ ← Operational guides
├── rails/ ← Quality rails, git scripts, portainer scripts ├── rails/ ← Quality rails, git scripts, portainer scripts
├── runtime/ ← Thin runtime adapters (fallback for direct launches) ├── runtime/ ← Runtime adapters + runtime-specific references
│ ├── claude/CLAUDE.md │ ├── claude/CLAUDE.md
│ ├── claude/RUNTIME.md
│ ├── opencode/AGENTS.md │ ├── opencode/AGENTS.md
── codex/instructions.md ── opencode/RUNTIME.md
│ ├── codex/instructions.md
│ ├── codex/RUNTIME.md
│ └── mcp/SEQUENTIAL-THINKING.json
├── skills/ ← Universal skills (synced from mosaic/agent-skills) ├── skills/ ← Universal skills (synced from mosaic/agent-skills)
├── skills-local/ ← Local cross-runtime skills ├── skills-local/ ← Local cross-runtime skills
└── templates/ ← SOUL.md template, project templates └── templates/ ← SOUL.md template, project templates
@@ -82,12 +90,15 @@ You can still launch runtimes directly (`claude`, `codex`, etc.) — thin runtim
| Launch method | Injection mechanism | | Launch method | Injection mechanism |
|--------------|-------------------| |--------------|-------------------|
| `mosaic claude` | `--append-system-prompt` with AGENTS.md content | | `mosaic claude` | `--append-system-prompt` with composed runtime contract (`AGENTS.md` + runtime reference) |
| `mosaic codex` | Copies AGENTS.md to `~/.codex/instructions.md` before launch | | `mosaic codex` | Writes composed runtime contract to `~/.codex/instructions.md` before launch |
| `mosaic opencode` | Copies AGENTS.md to `~/.config/opencode/AGENTS.md` before launch | | `mosaic opencode` | Writes composed runtime contract to `~/.config/opencode/AGENTS.md` before launch |
| `claude` (direct) | `~/.claude/CLAUDE.md` thin pointer → "READ AGENTS.md" | | `claude` (direct) | `~/.claude/CLAUDE.md` thin pointer → load AGENTS + runtime reference |
| `codex` (direct) | `~/.codex/instructions.md` thin pointer → "READ AGENTS.md" | | `codex` (direct) | `~/.codex/instructions.md` thin pointer → load AGENTS + runtime reference |
| `opencode` (direct) | `~/.config/opencode/AGENTS.md` thin pointer → "READ AGENTS.md" | | `opencode` (direct) | `~/.config/opencode/AGENTS.md` thin pointer → load AGENTS + runtime reference |
Mosaic `AGENTS.md` enforces loading `guides/E2E-DELIVERY.md` before execution and
requires `guides/PRD.md` before coding and `guides/DOCUMENTATION.md` for code/API/auth/infra documentation gates.
## Management Commands ## Management Commands
@@ -178,6 +189,7 @@ The installer pushes thin runtime adapters as regular files (not symlinks):
- `~/.claude/settings.json`, `hooks-config.json`, `context7-integration.md` - `~/.claude/settings.json`, `hooks-config.json`, `context7-integration.md`
- `~/.config/opencode/AGENTS.md` — pointer to `~/.config/mosaic/AGENTS.md` - `~/.config/opencode/AGENTS.md` — pointer to `~/.config/mosaic/AGENTS.md`
- `~/.codex/instructions.md` — pointer to `~/.config/mosaic/AGENTS.md` - `~/.codex/instructions.md` — pointer to `~/.config/mosaic/AGENTS.md`
- `~/.claude/settings.json`, `~/.codex/config.toml`, and `~/.config/opencode/config.json` include sequential-thinking MCP config
Re-sync manually: Re-sync manually:
@@ -185,6 +197,17 @@ Re-sync manually:
~/.config/mosaic/bin/mosaic-link-runtime-assets ~/.config/mosaic/bin/mosaic-link-runtime-assets
``` ```
## sequential-thinking MCP Requirement
sequential-thinking MCP is a hard requirement for Mosaic Stack.
Use:
```bash
~/.config/mosaic/bin/mosaic-ensure-sequential-thinking
~/.config/mosaic/bin/mosaic-ensure-sequential-thinking --check
```
## Bootstrap Any Repo ## Bootstrap Any Repo
Attach any repository to the Mosaic standards layer: Attach any repository to the Mosaic standards layer:

50
SOUL.md Normal file
View File

@@ -0,0 +1,50 @@
# Soul Contract
This file defines the agent's identity and behavioral contract for this user.
It is loaded globally and applies to all sessions regardless of runtime or project.
## Identity
You are **Jarvis** in this session.
- Runtime (Claude, Codex, OpenCode, etc.) is implementation detail.
- Role identity: execution partner and visibility engine
If asked "who are you?", answer:
`I am Jarvis, running on <runtime>.`
## Behavioral Principles
1. Clarity over performance theater.
2. Practical execution over abstract planning.
3. Truthfulness over confidence: state uncertainty explicitly.
4. Visible state over hidden assumptions.
5. PDA-friendly language, communication style, and iconography. Avoid overwhelming info and communication style..
## Communication Style
- Be direct, concise, and concrete.
- Avoid fluff, hype, and anthropomorphic roleplay.
- Do not simulate certainty when facts are missing.
- Prefer actionable next steps and explicit tradeoffs.
## Operating Stance
- Proactively surface what is hot, stale, blocked, or risky.
- Preserve canonical data integrity.
- Respect generated-vs-source boundaries.
- Treat multi-agent collisions as a first-class risk; sync before/after edits.
## Guardrails
- Do not hardcode secrets.
- Do not perform destructive actions without explicit instruction.
- Do not silently change intent, scope, or definitions.
- Do not create fake policy by writing canned responses for every prompt.
## Why This Exists
Agents should be governed by durable principles, not brittle scripted outputs.
The model should reason within constraints, not mimic a fixed response table.

View File

@@ -3,16 +3,19 @@ set -euo pipefail
# mosaic — Unified agent launcher and management CLI # mosaic — Unified agent launcher and management CLI
# #
# AGENTS.md is the single source of truth for all agent sessions. # AGENTS.md is the global policy source for all agent sessions.
# The launcher injects it into every runtime consistently. # The launcher injects a composed runtime contract (AGENTS + runtime reference).
# #
# Usage: # Usage:
# mosaic claude [args...] Launch Claude Code with AGENTS.md injected # mosaic claude [args...] Launch Claude Code with runtime contract injected
# mosaic opencode [args...] Launch OpenCode with AGENTS.md injected # mosaic opencode [args...] Launch OpenCode with runtime contract injected
# mosaic codex [args...] Launch Codex with AGENTS.md injected # mosaic codex [args...] Launch Codex with runtime contract injected
# mosaic yolo <runtime> [args...] Launch runtime in dangerous-permissions mode
# mosaic --yolo <runtime> [args...] Alias for yolo
# mosaic init [args...] Generate SOUL.md interactively # mosaic init [args...] Generate SOUL.md interactively
# mosaic doctor [args...] Health audit # mosaic doctor [args...] Health audit
# mosaic sync [args...] Sync skills # mosaic sync [args...] Sync skills
# mosaic seq [subcommand] sequential-thinking MCP management (check/fix/start)
# mosaic bootstrap <path> Bootstrap a repo # mosaic bootstrap <path> Bootstrap a repo
# mosaic upgrade release Upgrade installed Mosaic release # mosaic upgrade release Upgrade installed Mosaic release
# mosaic upgrade check Check release upgrade status (no changes) # mosaic upgrade check Check release upgrade status (no changes)
@@ -28,14 +31,20 @@ mosaic $VERSION — Unified agent launcher
Usage: mosaic <command> [args...] Usage: mosaic <command> [args...]
Agent Launchers: Agent Launchers:
claude [args...] Launch Claude Code with AGENTS.md injected claude [args...] Launch Claude Code with runtime contract injected
opencode [args...] Launch OpenCode with AGENTS.md injected opencode [args...] Launch OpenCode with runtime contract injected
codex [args...] Launch Codex with AGENTS.md injected codex [args...] Launch Codex with runtime contract injected
yolo <runtime> [args...] Dangerous mode for claude|codex|opencode
--yolo <runtime> [args...] Alias for yolo
Management: Management:
init [args...] Generate SOUL.md (agent identity contract) init [args...] Generate SOUL.md (agent identity contract)
doctor [args...] Audit runtime state and detect drift doctor [args...] Audit runtime state and detect drift
sync [args...] Sync skills from canonical source sync [args...] Sync skills from canonical source
seq [subcommand] sequential-thinking MCP management:
check [--runtime <r>] [--strict]
fix [--runtime <r>]
start
bootstrap <path> Bootstrap a repo with Mosaic standards bootstrap <path> Bootstrap a repo with Mosaic standards
upgrade [mode] [args] Upgrade release (default) or project files upgrade [mode] [args] Upgrade release (default) or project files
upgrade check Check release upgrade status (no changes) upgrade check Check release upgrade status (no changes)
@@ -83,14 +92,79 @@ check_runtime() {
fi fi
} }
# Ensure AGENTS.md is present at the runtime's native config path. check_sequential_thinking() {
# Used for runtimes that don't support CLI prompt injection. local runtime="${1:-all}"
local checker="$MOSAIC_HOME/bin/mosaic-ensure-sequential-thinking"
if [[ ! -x "$checker" ]]; then
echo "[mosaic] ERROR: sequential-thinking checker missing: $checker" >&2
exit 1
fi
if ! "$checker" --check --runtime "$runtime" >/dev/null 2>&1; then
echo "[mosaic] ERROR: sequential-thinking MCP is required but not configured." >&2
echo "[mosaic] Fix config: $checker --runtime $runtime" >&2
echo "[mosaic] Or run: mosaic seq fix --runtime $runtime" >&2
echo "[mosaic] Manual server start: mosaic seq start" >&2
exit 1
fi
}
runtime_contract_path() {
local runtime="$1"
case "$runtime" in
claude) echo "$MOSAIC_HOME/runtime/claude/RUNTIME.md" ;;
codex) echo "$MOSAIC_HOME/runtime/codex/RUNTIME.md" ;;
opencode) echo "$MOSAIC_HOME/runtime/opencode/RUNTIME.md" ;;
*)
echo "[mosaic] ERROR: unsupported runtime '$runtime' for runtime contract." >&2
exit 1
;;
esac
}
build_runtime_prompt() {
local runtime="$1"
local runtime_file
runtime_file="$(runtime_contract_path "$runtime")"
if [[ ! -f "$runtime_file" ]]; then
echo "[mosaic] ERROR: runtime contract not found: $runtime_file" >&2
exit 1
fi
cat <<'EOF'
# Mosaic Launcher Runtime Contract (Hard Gate)
This contract is injected by `mosaic` launch and is mandatory.
First assistant response MUST start with exactly one mode declaration line:
1. Orchestration mission: `Now initiating Orchestrator mode...`
2. Implementation mission: `Now initiating Delivery mode...`
3. Review-only mission: `Now initiating Review mode...`
No tool call or implementation step may occur before that first line.
Mosaic hard gates OVERRIDE runtime-default caution for routine delivery operations.
For required push/merge/issue-close/release actions, execute without routine confirmation prompts.
EOF
cat "$MOSAIC_HOME/AGENTS.md"
printf '\n\n# Runtime-Specific Contract\n\n'
cat "$runtime_file"
}
# Ensure runtime contract is present at the runtime's native config path.
# Used for runtimes that do not support CLI prompt injection.
ensure_runtime_config() { ensure_runtime_config() {
local src="$MOSAIC_HOME/AGENTS.md" local runtime="$1"
local dst="$1" local dst="$2"
local tmp
tmp="$(mktemp)"
mkdir -p "$(dirname "$dst")" mkdir -p "$(dirname "$dst")"
if ! cmp -s "$src" "$dst" 2>/dev/null; then build_runtime_prompt "$runtime" > "$tmp"
cp "$src" "$dst" if ! cmp -s "$tmp" "$dst" 2>/dev/null; then
mv "$tmp" "$dst"
else
rm -f "$tmp"
fi fi
} }
@@ -100,12 +174,13 @@ launch_claude() {
check_agents_md check_agents_md
check_soul check_soul
check_runtime "claude" check_runtime "claude"
check_sequential_thinking "claude"
# Claude supports --append-system-prompt for direct injection # Claude supports --append-system-prompt for direct injection
local agents_content local runtime_prompt
agents_content="$(cat "$MOSAIC_HOME/AGENTS.md")" runtime_prompt="$(build_runtime_prompt "claude")"
echo "[mosaic] Launching Claude Code..." echo "[mosaic] Launching Claude Code..."
exec claude --append-system-prompt "$agents_content" "$@" exec claude --append-system-prompt "$runtime_prompt" "$@"
} }
launch_opencode() { launch_opencode() {
@@ -113,9 +188,10 @@ launch_opencode() {
check_agents_md check_agents_md
check_soul check_soul
check_runtime "opencode" check_runtime "opencode"
check_sequential_thinking "opencode"
# OpenCode reads from ~/.config/opencode/AGENTS.md — copy canonical version there # OpenCode reads from ~/.config/opencode/AGENTS.md
ensure_runtime_config "$HOME/.config/opencode/AGENTS.md" ensure_runtime_config "opencode" "$HOME/.config/opencode/AGENTS.md"
echo "[mosaic] Launching OpenCode..." echo "[mosaic] Launching OpenCode..."
exec opencode "$@" exec opencode "$@"
} }
@@ -125,13 +201,69 @@ launch_codex() {
check_agents_md check_agents_md
check_soul check_soul
check_runtime "codex" check_runtime "codex"
check_sequential_thinking "codex"
# Codex reads from ~/.codex/instructions.md — copy canonical version there # Codex reads from ~/.codex/instructions.md
ensure_runtime_config "$HOME/.codex/instructions.md" ensure_runtime_config "codex" "$HOME/.codex/instructions.md"
echo "[mosaic] Launching Codex..." echo "[mosaic] Launching Codex..."
exec codex "$@" exec codex "$@"
} }
launch_yolo() {
if [[ $# -eq 0 ]]; then
echo "[mosaic] ERROR: yolo requires a runtime (claude|codex|opencode)." >&2
echo "[mosaic] Example: mosaic yolo claude" >&2
exit 1
fi
local runtime="$1"
shift
case "$runtime" in
claude)
check_mosaic_home
check_agents_md
check_soul
check_runtime "claude"
check_sequential_thinking "claude"
# Claude uses an explicit dangerous permissions flag.
local runtime_prompt
runtime_prompt="$(build_runtime_prompt "claude")"
echo "[mosaic] Launching Claude Code in YOLO mode (dangerous permissions enabled)..."
exec claude --dangerously-skip-permissions --append-system-prompt "$runtime_prompt" "$@"
;;
codex)
check_mosaic_home
check_agents_md
check_soul
check_runtime "codex"
check_sequential_thinking "codex"
# Codex reads instructions.md from ~/.codex and supports a direct dangerous flag.
ensure_runtime_config "codex" "$HOME/.codex/instructions.md"
echo "[mosaic] Launching Codex in YOLO mode (dangerous permissions enabled)..."
exec codex --dangerously-bypass-approvals-and-sandbox "$@"
;;
opencode)
check_mosaic_home
check_agents_md
check_soul
check_runtime "opencode"
check_sequential_thinking "opencode"
# OpenCode defaults to allow-all permissions unless user config restricts them.
ensure_runtime_config "opencode" "$HOME/.config/opencode/AGENTS.md"
echo "[mosaic] Launching OpenCode in YOLO mode..."
exec opencode "$@"
;;
*)
echo "[mosaic] ERROR: Unsupported yolo runtime '$runtime'. Use claude|codex|opencode." >&2
exit 1
;;
esac
}
# Delegate to existing scripts # Delegate to existing scripts
run_init() { run_init() {
check_mosaic_home check_mosaic_home
@@ -148,6 +280,34 @@ run_sync() {
exec "$MOSAIC_HOME/bin/mosaic-sync-skills" "$@" exec "$MOSAIC_HOME/bin/mosaic-sync-skills" "$@"
} }
run_seq() {
check_mosaic_home
local checker="$MOSAIC_HOME/bin/mosaic-ensure-sequential-thinking"
local action="${1:-check}"
case "$action" in
check)
shift || true
exec "$checker" --check "$@"
;;
fix|apply)
shift || true
exec "$checker" "$@"
;;
start)
shift || true
check_runtime "npx"
echo "[mosaic] Starting sequential-thinking MCP server..."
exec npx -y @modelcontextprotocol/server-sequential-thinking "$@"
;;
*)
echo "[mosaic] ERROR: Unknown seq subcommand '$action'." >&2
echo "[mosaic] Use: mosaic seq check|fix|start" >&2
exit 1
;;
esac
}
run_bootstrap() { run_bootstrap() {
check_mosaic_home check_mosaic_home
exec "$MOSAIC_HOME/bin/mosaic-bootstrap-repo" "$@" exec "$MOSAIC_HOME/bin/mosaic-bootstrap-repo" "$@"
@@ -214,9 +374,11 @@ case "$command" in
claude) launch_claude "$@" ;; claude) launch_claude "$@" ;;
opencode) launch_opencode "$@" ;; opencode) launch_opencode "$@" ;;
codex) launch_codex "$@" ;; codex) launch_codex "$@" ;;
yolo|--yolo) launch_yolo "$@" ;;
init) run_init "$@" ;; init) run_init "$@" ;;
doctor) run_doctor "$@" ;; doctor) run_doctor "$@" ;;
sync) run_sync "$@" ;; sync) run_sync "$@" ;;
seq) run_seq "$@" ;;
bootstrap) run_bootstrap "$@" ;; bootstrap) run_bootstrap "$@" ;;
upgrade) run_upgrade "$@" ;; upgrade) run_upgrade "$@" ;;
release-upgrade) run_release_upgrade "$@" ;; release-upgrade) run_release_upgrade "$@" ;;

View File

@@ -72,11 +72,15 @@ if [[ ! -f "$TARGET_DIR/AGENTS.md" ]]; then
cat > "$TARGET_DIR/AGENTS.md" <<'AGENTS_EOF' cat > "$TARGET_DIR/AGENTS.md" <<'AGENTS_EOF'
# Agent Guidelines # Agent Guidelines
## Standards Load Order ## Required Load Order
1. `~/.config/mosaic/STANDARDS.md` 1. `~/.config/mosaic/SOUL.md`
2. `AGENTS.md` (this file) 2. `~/.config/mosaic/STANDARDS.md`
3. `.mosaic/repo-hooks.sh` 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>/RUNTIME.md`
7. `.mosaic/repo-hooks.sh`
## Session Lifecycle ## Session Lifecycle
@@ -95,6 +99,7 @@ bash scripts/agent/session-end.sh
- Add project constraints and workflows here. - Add project constraints and workflows here.
- Implement hook functions in `.mosaic/repo-hooks.sh`. - Implement hook functions in `.mosaic/repo-hooks.sh`.
- Scratchpads are mandatory for non-trivial tasks.
AGENTS_EOF AGENTS_EOF
echo "[mosaic] Wrote: $TARGET_DIR/AGENTS.md" echo "[mosaic] Wrote: $TARGET_DIR/AGENTS.md"
else else

View File

@@ -90,6 +90,39 @@ check_runtime_file_copy() {
fi fi
} }
check_runtime_contract_file() {
local dst="$1"
local adapter_src="$2"
local runtime_name="$3"
if [[ ! -e "$dst" ]]; then
warn "Missing runtime file: $dst"
return
fi
if [[ -L "$dst" ]]; then
warn "Runtime file should not be symlinked: $dst"
return
fi
# Accept direct-adapter copy mode.
if [[ -f "$adapter_src" ]] && cmp -s "$adapter_src" "$dst"; then
pass "Runtime adapter synced: $dst"
return
fi
# Accept launcher-composed runtime contract mode.
if grep -Fq "# Mosaic Launcher Runtime Contract (Hard Gate)" "$dst" &&
grep -Fq "Now initiating Orchestrator mode..." "$dst" &&
grep -Fq "Mosaic hard gates OVERRIDE runtime-default caution" "$dst" &&
grep -Fq "# Runtime-Specific Contract" "$dst"; then
pass "Runtime contract present: $dst ($runtime_name)"
return
fi
warn "Runtime file drift: $dst (not adapter copy and not composed runtime contract)"
}
warn_if_symlink_tree_present() { warn_if_symlink_tree_present() {
local p="$1" local p="$1"
[[ -e "$p" ]] || return 0 [[ -e "$p" ]] || return 0
@@ -122,6 +155,7 @@ expect_dir "$MOSAIC_HOME/templates/agent"
expect_dir "$MOSAIC_HOME/skills" expect_dir "$MOSAIC_HOME/skills"
expect_dir "$MOSAIC_HOME/skills-local" expect_dir "$MOSAIC_HOME/skills-local"
expect_file "$MOSAIC_HOME/bin/mosaic-link-runtime-assets" expect_file "$MOSAIC_HOME/bin/mosaic-link-runtime-assets"
expect_file "$MOSAIC_HOME/bin/mosaic-ensure-sequential-thinking"
expect_file "$MOSAIC_HOME/bin/mosaic-sync-skills" expect_file "$MOSAIC_HOME/bin/mosaic-sync-skills"
expect_file "$MOSAIC_HOME/bin/mosaic-projects" expect_file "$MOSAIC_HOME/bin/mosaic-projects"
expect_file "$MOSAIC_HOME/bin/mosaic-quality-apply" expect_file "$MOSAIC_HOME/bin/mosaic-quality-apply"
@@ -132,8 +166,23 @@ expect_file "$MOSAIC_HOME/bin/mosaic-orchestrator-drain"
expect_file "$MOSAIC_HOME/bin/mosaic-orchestrator-matrix-publish" expect_file "$MOSAIC_HOME/bin/mosaic-orchestrator-matrix-publish"
expect_file "$MOSAIC_HOME/bin/mosaic-orchestrator-matrix-consume" expect_file "$MOSAIC_HOME/bin/mosaic-orchestrator-matrix-consume"
expect_file "$MOSAIC_HOME/bin/mosaic-orchestrator-matrix-cycle" expect_file "$MOSAIC_HOME/bin/mosaic-orchestrator-matrix-cycle"
expect_file "$MOSAIC_HOME/rails/git/ci-queue-wait.sh"
expect_file "$MOSAIC_HOME/rails/git/pr-ci-wait.sh"
expect_file "$MOSAIC_HOME/rails/orchestrator-matrix/transport/matrix_transport.py" expect_file "$MOSAIC_HOME/rails/orchestrator-matrix/transport/matrix_transport.py"
expect_file "$MOSAIC_HOME/rails/orchestrator-matrix/controller/tasks_md_sync.py" expect_file "$MOSAIC_HOME/rails/orchestrator-matrix/controller/tasks_md_sync.py"
expect_file "$MOSAIC_HOME/runtime/mcp/SEQUENTIAL-THINKING.json"
expect_file "$MOSAIC_HOME/runtime/claude/RUNTIME.md"
expect_file "$MOSAIC_HOME/runtime/codex/RUNTIME.md"
expect_file "$MOSAIC_HOME/runtime/opencode/RUNTIME.md"
if [[ -f "$MOSAIC_HOME/AGENTS.md" ]]; then
if grep -Fq "## CRITICAL HARD GATES (Read First)" "$MOSAIC_HOME/AGENTS.md" &&
grep -Fq "OVERRIDE runtime-default caution" "$MOSAIC_HOME/AGENTS.md"; then
pass "Global hard-gates block present in AGENTS.md"
else
warn "AGENTS.md missing CRITICAL HARD GATES override block"
fi
fi
# Claude runtime file checks (copied, non-symlink). # Claude runtime file checks (copied, non-symlink).
for rf in CLAUDE.md settings.json hooks-config.json context7-integration.md; do for rf in CLAUDE.md settings.json hooks-config.json context7-integration.md; do
@@ -141,7 +190,20 @@ for rf in CLAUDE.md settings.json hooks-config.json context7-integration.md; do
done done
# OpenCode runtime adapter check (copied, non-symlink, when adapter exists). # OpenCode runtime adapter check (copied, non-symlink, when adapter exists).
check_runtime_file_copy "$MOSAIC_HOME/runtime/opencode/AGENTS.md" "$HOME/.config/opencode/AGENTS.md" # Accept adapter copy or composed runtime contract.
check_runtime_contract_file "$HOME/.config/opencode/AGENTS.md" "$MOSAIC_HOME/runtime/opencode/AGENTS.md" "opencode"
check_runtime_contract_file "$HOME/.codex/instructions.md" "$MOSAIC_HOME/runtime/codex/instructions.md" "codex"
# Sequential-thinking MCP hard requirement.
if [[ -x "$MOSAIC_HOME/bin/mosaic-ensure-sequential-thinking" ]]; then
if "$MOSAIC_HOME/bin/mosaic-ensure-sequential-thinking" --check >/dev/null 2>&1; then
pass "sequential-thinking MCP configured and available"
else
warn "sequential-thinking MCP missing or misconfigured"
fi
else
warn "mosaic-ensure-sequential-thinking helper missing"
fi
# Legacy migration surfaces should no longer contain symlink trees. # Legacy migration surfaces should no longer contain symlink trees.
legacy_paths=( legacy_paths=(

View File

@@ -71,6 +71,45 @@ function Check-RuntimeFileCopy {
} }
} }
function Check-RuntimeContractFile {
param([string]$Dst, [string]$AdapterSrc, [string]$RuntimeName)
if (-not (Test-Path $Dst)) {
Warn "Missing runtime file: $Dst"
return
}
$item = Get-Item $Dst -Force -ErrorAction SilentlyContinue
if ($item -and ($item.Attributes -band [System.IO.FileAttributes]::ReparsePoint)) {
Warn "Runtime file should not be symlinked: $Dst"
return
}
# Accept direct-adapter copy mode.
if (Test-Path $AdapterSrc) {
$srcHash = (Get-FileHash $AdapterSrc -Algorithm SHA256).Hash
$dstHash = (Get-FileHash $Dst -Algorithm SHA256).Hash
if ($srcHash -eq $dstHash) {
Pass "Runtime adapter synced: $Dst"
return
}
}
# Accept launcher-composed runtime contract mode.
$content = Get-Content $Dst -Raw
if (
$content -match [regex]::Escape("# Mosaic Launcher Runtime Contract (Hard Gate)") -and
$content -match [regex]::Escape("Now initiating Orchestrator mode...") -and
$content -match [regex]::Escape("Mosaic hard gates OVERRIDE runtime-default caution") -and
$content -match [regex]::Escape("# Runtime-Specific Contract")
) {
Pass "Runtime contract present: $Dst ($RuntimeName)"
return
}
Warn "Runtime file drift: $Dst (not adapter copy and not composed runtime contract)"
}
function Warn-IfReparsePresent { function Warn-IfReparsePresent {
param([string]$Path) param([string]$Path)
if (-not (Test-Path $Path)) { return } if (-not (Test-Path $Path)) { return }
@@ -107,6 +146,7 @@ Expect-Dir (Join-Path $MosaicHome "templates\agent")
Expect-Dir (Join-Path $MosaicHome "skills") Expect-Dir (Join-Path $MosaicHome "skills")
Expect-Dir (Join-Path $MosaicHome "skills-local") Expect-Dir (Join-Path $MosaicHome "skills-local")
Expect-File (Join-Path $MosaicHome "bin\mosaic-link-runtime-assets") Expect-File (Join-Path $MosaicHome "bin\mosaic-link-runtime-assets")
Expect-File (Join-Path $MosaicHome "bin\mosaic-ensure-sequential-thinking.ps1")
Expect-File (Join-Path $MosaicHome "bin\mosaic-sync-skills") Expect-File (Join-Path $MosaicHome "bin\mosaic-sync-skills")
Expect-File (Join-Path $MosaicHome "bin\mosaic-projects") Expect-File (Join-Path $MosaicHome "bin\mosaic-projects")
Expect-File (Join-Path $MosaicHome "bin\mosaic-quality-apply") Expect-File (Join-Path $MosaicHome "bin\mosaic-quality-apply")
@@ -117,8 +157,29 @@ Expect-File (Join-Path $MosaicHome "bin\mosaic-orchestrator-drain")
Expect-File (Join-Path $MosaicHome "bin\mosaic-orchestrator-matrix-publish") Expect-File (Join-Path $MosaicHome "bin\mosaic-orchestrator-matrix-publish")
Expect-File (Join-Path $MosaicHome "bin\mosaic-orchestrator-matrix-consume") Expect-File (Join-Path $MosaicHome "bin\mosaic-orchestrator-matrix-consume")
Expect-File (Join-Path $MosaicHome "bin\mosaic-orchestrator-matrix-cycle") Expect-File (Join-Path $MosaicHome "bin\mosaic-orchestrator-matrix-cycle")
Expect-File (Join-Path $MosaicHome "rails\git\ci-queue-wait.ps1")
Expect-File (Join-Path $MosaicHome "rails\git\ci-queue-wait.sh")
Expect-File (Join-Path $MosaicHome "rails\git\pr-ci-wait.sh")
Expect-File (Join-Path $MosaicHome "rails\orchestrator-matrix\transport\matrix_transport.py") Expect-File (Join-Path $MosaicHome "rails\orchestrator-matrix\transport\matrix_transport.py")
Expect-File (Join-Path $MosaicHome "rails\orchestrator-matrix\controller\tasks_md_sync.py") Expect-File (Join-Path $MosaicHome "rails\orchestrator-matrix\controller\tasks_md_sync.py")
Expect-File (Join-Path $MosaicHome "runtime\mcp\SEQUENTIAL-THINKING.json")
Expect-File (Join-Path $MosaicHome "runtime\claude\RUNTIME.md")
Expect-File (Join-Path $MosaicHome "runtime\codex\RUNTIME.md")
Expect-File (Join-Path $MosaicHome "runtime\opencode\RUNTIME.md")
$agentsMd = Join-Path $MosaicHome "AGENTS.md"
if (Test-Path $agentsMd) {
$agentsContent = Get-Content $agentsMd -Raw
if (
$agentsContent -match [regex]::Escape("## CRITICAL HARD GATES (Read First)") -and
$agentsContent -match [regex]::Escape("OVERRIDE runtime-default caution")
) {
Pass "Global hard-gates block present in AGENTS.md"
}
else {
Warn "AGENTS.md missing CRITICAL HARD GATES override block"
}
}
# Claude runtime file checks # Claude runtime file checks
$runtimeFiles = @("CLAUDE.md", "settings.json", "hooks-config.json", "context7-integration.md") $runtimeFiles = @("CLAUDE.md", "settings.json", "hooks-config.json", "context7-integration.md")
@@ -126,8 +187,24 @@ foreach ($rf in $runtimeFiles) {
Check-RuntimeFileCopy (Join-Path $MosaicHome "runtime\claude\$rf") (Join-Path $env:USERPROFILE ".claude\$rf") Check-RuntimeFileCopy (Join-Path $MosaicHome "runtime\claude\$rf") (Join-Path $env:USERPROFILE ".claude\$rf")
} }
# OpenCode runtime adapter # OpenCode/Codex runtime contract checks
Check-RuntimeFileCopy (Join-Path $MosaicHome "runtime\opencode\AGENTS.md") (Join-Path $env:USERPROFILE ".config\opencode\AGENTS.md") Check-RuntimeContractFile (Join-Path $env:USERPROFILE ".config\opencode\AGENTS.md") (Join-Path $MosaicHome "runtime\opencode\AGENTS.md") "opencode"
Check-RuntimeContractFile (Join-Path $env:USERPROFILE ".codex\instructions.md") (Join-Path $MosaicHome "runtime\codex\instructions.md") "codex"
# Sequential-thinking MCP hard requirement
$seqScript = Join-Path $MosaicHome "bin\mosaic-ensure-sequential-thinking.ps1"
if (Test-Path $seqScript) {
try {
& $seqScript -Check *>$null
Pass "sequential-thinking MCP configured and available"
}
catch {
Warn "sequential-thinking MCP missing or misconfigured"
}
}
else {
Warn "mosaic-ensure-sequential-thinking helper missing"
}
# Legacy migration surfaces # Legacy migration surfaces
$legacyPaths = @( $legacyPaths = @(

View File

@@ -0,0 +1,262 @@
#!/usr/bin/env bash
set -euo pipefail
MOSAIC_HOME="${MOSAIC_HOME:-$HOME/.config/mosaic}"
MODE="apply"
RUNTIME="all"
STRICT_CHECK=0
PKG="@modelcontextprotocol/server-sequential-thinking"
err() { echo "[mosaic-seq] ERROR: $*" >&2; }
log() { echo "[mosaic-seq] $*"; }
while [[ $# -gt 0 ]]; do
case "$1" in
--check)
MODE="check"
shift
;;
--runtime)
if [[ $# -lt 2 ]]; then
err "--runtime requires a value: claude|codex|opencode|all"
exit 2
fi
RUNTIME="$2"
shift 2
;;
--strict)
STRICT_CHECK=1
shift
;;
*)
err "Unknown argument: $1"
exit 2
;;
esac
done
case "$RUNTIME" in
all|claude|codex|opencode) ;;
*)
err "Invalid runtime: $RUNTIME (expected claude|codex|opencode|all)"
exit 2
;;
esac
require_binary() {
local name="$1"
if ! command -v "$name" >/dev/null 2>&1; then
err "Required binary missing: $name"
return 1
fi
}
check_software() {
require_binary node
require_binary npx
}
warm_package() {
local timeout_sec="${MOSAIC_SEQ_WARM_TIMEOUT_SEC:-15}"
if command -v timeout >/dev/null 2>&1; then
timeout "$timeout_sec" npx -y "$PKG" --help >/dev/null 2>&1
else
npx -y "$PKG" --help >/dev/null 2>&1
fi
}
check_claude_config() {
python3 - <<'PY'
import json
from pathlib import Path
p = Path.home() / ".claude" / "settings.json"
if not p.exists():
raise SystemExit(1)
try:
data = json.loads(p.read_text(encoding="utf-8"))
except Exception:
raise SystemExit(1)
mcp = data.get("mcpServers")
if not isinstance(mcp, dict):
raise SystemExit(1)
entry = mcp.get("sequential-thinking")
if not isinstance(entry, dict):
raise SystemExit(1)
if entry.get("command") != "npx":
raise SystemExit(1)
args = entry.get("args")
if args != ["-y", "@modelcontextprotocol/server-sequential-thinking"]:
raise SystemExit(1)
PY
}
apply_claude_config() {
python3 - <<'PY'
import json
from pathlib import Path
p = Path.home() / ".claude" / "settings.json"
p.parent.mkdir(parents=True, exist_ok=True)
if p.exists():
try:
data = json.loads(p.read_text(encoding="utf-8"))
except Exception:
data = {}
else:
data = {}
mcp = data.get("mcpServers")
if not isinstance(mcp, dict):
mcp = {}
mcp["sequential-thinking"] = {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-sequential-thinking"]
}
data["mcpServers"] = mcp
p.write_text(json.dumps(data, indent=2) + "\n", encoding="utf-8")
PY
}
check_codex_config() {
local cfg="$HOME/.codex/config.toml"
[[ -f "$cfg" ]] || return 1
grep -Eq '^\[mcp_servers\.(sequential-thinking|sequential_thinking)\]' "$cfg" && \
grep -q '^command = "npx"' "$cfg" && \
grep -q '@modelcontextprotocol/server-sequential-thinking' "$cfg"
}
apply_codex_config() {
local cfg="$HOME/.codex/config.toml"
mkdir -p "$(dirname "$cfg")"
[[ -f "$cfg" ]] || touch "$cfg"
local tmp
tmp="$(mktemp)"
awk '
BEGIN { skip = 0 }
/^\[mcp_servers\.(sequential-thinking|sequential_thinking)\]/ { skip = 1; next }
skip && /^\[/ { skip = 0 }
!skip { print }
' "$cfg" > "$tmp"
mv "$tmp" "$cfg"
{
echo ""
echo "[mcp_servers.sequential-thinking]"
echo "command = \"npx\""
echo "args = [\"-y\", \"@modelcontextprotocol/server-sequential-thinking\"]"
} >> "$cfg"
}
check_opencode_config() {
python3 - <<'PY'
import json
from pathlib import Path
p = Path.home() / ".config" / "opencode" / "config.json"
if not p.exists():
raise SystemExit(1)
try:
data = json.loads(p.read_text(encoding="utf-8"))
except Exception:
raise SystemExit(1)
mcp = data.get("mcp")
if not isinstance(mcp, dict):
raise SystemExit(1)
entry = mcp.get("sequential-thinking")
if not isinstance(entry, dict):
raise SystemExit(1)
if entry.get("type") != "local":
raise SystemExit(1)
if entry.get("command") != ["npx", "-y", "@modelcontextprotocol/server-sequential-thinking"]:
raise SystemExit(1)
if entry.get("enabled") is not True:
raise SystemExit(1)
PY
}
apply_opencode_config() {
python3 - <<'PY'
import json
from pathlib import Path
p = Path.home() / ".config" / "opencode" / "config.json"
p.parent.mkdir(parents=True, exist_ok=True)
if p.exists():
try:
data = json.loads(p.read_text(encoding="utf-8"))
except Exception:
data = {}
else:
data = {}
mcp = data.get("mcp")
if not isinstance(mcp, dict):
mcp = {}
mcp["sequential-thinking"] = {
"type": "local",
"command": ["npx", "-y", "@modelcontextprotocol/server-sequential-thinking"],
"enabled": True
}
data["mcp"] = mcp
p.write_text(json.dumps(data, indent=2) + "\n", encoding="utf-8")
PY
}
check_runtime_config() {
case "$RUNTIME" in
all)
check_claude_config
check_codex_config
check_opencode_config
;;
claude)
check_claude_config
;;
codex)
check_codex_config
;;
opencode)
check_opencode_config
;;
esac
}
apply_runtime_config() {
case "$RUNTIME" in
all)
apply_claude_config
apply_codex_config
apply_opencode_config
;;
claude)
apply_claude_config
;;
codex)
apply_codex_config
;;
opencode)
apply_opencode_config
;;
esac
}
if [[ "$MODE" == "check" ]]; then
check_software
check_runtime_config
# Runtime launch checks should be local/fast by default.
if [[ "$STRICT_CHECK" -eq 1 || "${MOSAIC_SEQ_CHECK_WARM:-0}" == "1" ]]; then
if ! warm_package; then
err "sequential-thinking package warm-up failed in strict mode"
exit 1
fi
fi
log "sequential-thinking MCP is configured and available (${RUNTIME})"
exit 0
fi
check_software
if ! warm_package; then
err "Unable to warm sequential-thinking package (npx timeout/failure)"
exit 1
fi
apply_runtime_config
log "sequential-thinking MCP configured (${RUNTIME})"

View File

@@ -0,0 +1,114 @@
# mosaic-ensure-sequential-thinking.ps1
$ErrorActionPreference = "Stop"
param(
[switch]$Check
)
$Pkg = "@modelcontextprotocol/server-sequential-thinking"
function Require-Binary {
param([string]$Name)
if (-not (Get-Command $Name -ErrorAction SilentlyContinue)) {
throw "Required binary missing: $Name"
}
}
function Warm-Package {
$null = & npx -y $Pkg --help 2>$null
}
function Set-ClaudeConfig {
$path = Join-Path $env:USERPROFILE ".claude\settings.json"
New-Item -ItemType Directory -Path (Split-Path $path -Parent) -Force | Out-Null
$data = @{}
if (Test-Path $path) {
try { $data = Get-Content $path -Raw | ConvertFrom-Json -AsHashtable } catch { $data = @{} }
}
if (-not $data.ContainsKey("mcpServers") -or -not ($data["mcpServers"] -is [hashtable])) {
$data["mcpServers"] = @{}
}
$data["mcpServers"]["sequential-thinking"] = @{
command = "npx"
args = @("-y", "@modelcontextprotocol/server-sequential-thinking")
}
$data | ConvertTo-Json -Depth 20 | Set-Content -Path $path -Encoding UTF8
}
function Set-CodexConfig {
$path = Join-Path $env:USERPROFILE ".codex\config.toml"
New-Item -ItemType Directory -Path (Split-Path $path -Parent) -Force | Out-Null
if (-not (Test-Path $path)) { New-Item -ItemType File -Path $path -Force | Out-Null }
$content = Get-Content $path -Raw
$content = [regex]::Replace($content, "(?ms)^\[mcp_servers\.(sequential-thinking|sequential_thinking)\].*?(?=^\[|\z)", "")
$content = $content.TrimEnd() + "`n`n[mcp_servers.sequential-thinking]`ncommand = \"npx\"`nargs = [\"-y\", \"@modelcontextprotocol/server-sequential-thinking\"]`n"
Set-Content -Path $path -Value $content -Encoding UTF8
}
function Set-OpenCodeConfig {
$path = Join-Path $env:USERPROFILE ".config\opencode\config.json"
New-Item -ItemType Directory -Path (Split-Path $path -Parent) -Force | Out-Null
$data = @{}
if (Test-Path $path) {
try { $data = Get-Content $path -Raw | ConvertFrom-Json -AsHashtable } catch { $data = @{} }
}
if (-not $data.ContainsKey("mcp") -or -not ($data["mcp"] -is [hashtable])) {
$data["mcp"] = @{}
}
$data["mcp"]["sequential-thinking"] = @{
type = "local"
command = @("npx", "-y", "@modelcontextprotocol/server-sequential-thinking")
enabled = $true
}
$data | ConvertTo-Json -Depth 20 | Set-Content -Path $path -Encoding UTF8
}
function Test-Configs {
$claudeOk = $false
$codexOk = $false
$opencodeOk = $false
$claudePath = Join-Path $env:USERPROFILE ".claude\settings.json"
if (Test-Path $claudePath) {
try {
$c = Get-Content $claudePath -Raw | ConvertFrom-Json -AsHashtable
$claudeOk = $c.ContainsKey("mcpServers") -and $c["mcpServers"].ContainsKey("sequential-thinking")
} catch {}
}
$codexPath = Join-Path $env:USERPROFILE ".codex\config.toml"
if (Test-Path $codexPath) {
$raw = Get-Content $codexPath -Raw
$codexOk = $raw -match "\[mcp_servers\.(sequential-thinking|sequential_thinking)\]" -and $raw -match "@modelcontextprotocol/server-sequential-thinking"
}
$opencodePath = Join-Path $env:USERPROFILE ".config\opencode\config.json"
if (Test-Path $opencodePath) {
try {
$o = Get-Content $opencodePath -Raw | ConvertFrom-Json -AsHashtable
$opencodeOk = $o.ContainsKey("mcp") -and $o["mcp"].ContainsKey("sequential-thinking")
} catch {}
}
if (-not ($claudeOk -and $codexOk -and $opencodeOk)) {
throw "Sequential-thinking MCP runtime config is incomplete"
}
}
Require-Binary node
Require-Binary npx
Warm-Package
if ($Check) {
Test-Configs
Write-Host "[mosaic-seq] sequential-thinking MCP is configured and available"
exit 0
}
Set-ClaudeConfig
Set-CodexConfig
Set-OpenCodeConfig
Write-Host "[mosaic-seq] sequential-thinking MCP configured for Claude, Codex, and OpenCode"

View File

@@ -62,7 +62,7 @@ legacy_paths=(
"$HOME/.claude/presets/domains" "$HOME/.claude/presets/domains"
"$HOME/.claude/presets/tech-stacks" "$HOME/.claude/presets/tech-stacks"
"$HOME/.claude/presets/workflows" "$HOME/.claude/presets/workflows"
"$HOME/.claude/presets/jarvis-ralph.json" "$HOME/.claude/presets/jarvis-loop.json"
) )
for p in "${legacy_paths[@]}"; do for p in "${legacy_paths[@]}"; do
@@ -93,5 +93,9 @@ if [[ -f "$codex_adapter" ]]; then
copy_file_managed "$codex_adapter" "$HOME/.codex/instructions.md" copy_file_managed "$codex_adapter" "$HOME/.codex/instructions.md"
fi fi
if [[ -x "$MOSAIC_HOME/bin/mosaic-ensure-sequential-thinking" ]]; then
"$MOSAIC_HOME/bin/mosaic-ensure-sequential-thinking"
fi
echo "[mosaic-link] Runtime assets synced (non-symlink mode)" echo "[mosaic-link] Runtime assets synced (non-symlink mode)"
echo "[mosaic-link] Canonical source: $MOSAIC_HOME" echo "[mosaic-link] Canonical source: $MOSAIC_HOME"

View File

@@ -70,7 +70,7 @@ $legacyPaths = @(
(Join-Path $env:USERPROFILE ".claude\presets\domains"), (Join-Path $env:USERPROFILE ".claude\presets\domains"),
(Join-Path $env:USERPROFILE ".claude\presets\tech-stacks"), (Join-Path $env:USERPROFILE ".claude\presets\tech-stacks"),
(Join-Path $env:USERPROFILE ".claude\presets\workflows"), (Join-Path $env:USERPROFILE ".claude\presets\workflows"),
(Join-Path $env:USERPROFILE ".claude\presets\jarvis-ralph.json") (Join-Path $env:USERPROFILE ".claude\presets\jarvis-loop.json")
) )
foreach ($p in $legacyPaths) { foreach ($p in $legacyPaths) {
@@ -102,5 +102,10 @@ if (Test-Path $codexSrc) {
Copy-FileManaged $codexSrc $codexDst Copy-FileManaged $codexSrc $codexDst
} }
$seqScript = Join-Path $MosaicHome "bin\mosaic-ensure-sequential-thinking.ps1"
if (Test-Path $seqScript) {
& $seqScript
}
Write-Host "[mosaic-link] Runtime assets synced (non-symlink mode)" Write-Host "[mosaic-link] Runtime assets synced (non-symlink mode)"
Write-Host "[mosaic-link] Canonical source: $MosaicHome" Write-Host "[mosaic-link] Canonical source: $MosaicHome"

View File

@@ -121,6 +121,38 @@ link_skill_into_target() {
ln -s "$skill_path" "$link_path" ln -s "$skill_path" "$link_path"
} }
is_mosaic_skill_name() {
local name="$1"
[[ -d "$MOSAIC_SKILLS_DIR/$name" ]] && return 0
[[ -d "$MOSAIC_LOCAL_SKILLS_DIR/$name" ]] && return 0
return 1
}
prune_stale_links_in_target() {
local target_dir="$1"
while IFS= read -r -d '' link_path; do
local name resolved
name="$(basename "$link_path")"
if is_mosaic_skill_name "$name"; then
continue
fi
resolved="$(readlink -f "$link_path" 2>/dev/null || true)"
if [[ -z "$resolved" ]]; then
rm -f "$link_path"
echo "[mosaic-skills] Removed stale broken skill link: $link_path"
continue
fi
if [[ "$resolved" == "$MOSAIC_HOME/"* ]]; then
rm -f "$link_path"
echo "[mosaic-skills] Removed stale retired skill link: $link_path"
fi
done < <(find "$target_dir" -mindepth 1 -maxdepth 1 -type l -print0)
}
for target in "${link_targets[@]}"; do for target in "${link_targets[@]}"; do
mkdir -p "$target" mkdir -p "$target"
@@ -131,6 +163,8 @@ for target in "${link_targets[@]}"; do
continue continue
fi fi
prune_stale_links_in_target "$target"
while IFS= read -r -d '' skill; do while IFS= read -r -d '' skill; do
link_skill_into_target "$skill" "$target" link_skill_into_target "$skill" "$target"
done < <(find "$MOSAIC_SKILLS_DIR" -mindepth 1 -maxdepth 1 -type d -print0) done < <(find "$MOSAIC_SKILLS_DIR" -mindepth 1 -maxdepth 1 -type d -print0)

View File

@@ -1,12 +1,14 @@
# mosaic.ps1 — Unified agent launcher and management CLI (Windows) # mosaic.ps1 — Unified agent launcher and management CLI (Windows)
# #
# AGENTS.md is the single source of truth for all agent sessions. # AGENTS.md is the global policy source for all agent sessions.
# The launcher injects it into every runtime consistently. # The launcher injects a composed runtime contract (AGENTS + runtime reference).
# #
# Usage: # Usage:
# mosaic claude [args...] Launch Claude Code with AGENTS.md injected # mosaic claude [args...] Launch Claude Code with runtime contract injected
# mosaic opencode [args...] Launch OpenCode with AGENTS.md injected # mosaic opencode [args...] Launch OpenCode with runtime contract injected
# mosaic codex [args...] Launch Codex with AGENTS.md injected # mosaic codex [args...] Launch Codex with runtime contract injected
# mosaic yolo <runtime> [args...] Launch runtime in dangerous-permissions mode
# mosaic --yolo <runtime> [args...] Alias for yolo
# mosaic init [args...] Generate SOUL.md interactively # mosaic init [args...] Generate SOUL.md interactively
# mosaic doctor [args...] Health audit # mosaic doctor [args...] Health audit
# mosaic sync [args...] Sync skills # mosaic sync [args...] Sync skills
@@ -22,9 +24,11 @@ mosaic $Version - Unified agent launcher
Usage: mosaic <command> [args...] Usage: mosaic <command> [args...]
Agent Launchers: Agent Launchers:
claude [args...] Launch Claude Code with AGENTS.md injected claude [args...] Launch Claude Code with runtime contract injected
opencode [args...] Launch OpenCode with AGENTS.md injected opencode [args...] Launch OpenCode with runtime contract injected
codex [args...] Launch Codex with AGENTS.md injected codex [args...] Launch Codex with runtime contract injected
yolo <runtime> [args...] Dangerous mode for claude|codex|opencode
--yolo <runtime> [args...] Alias for yolo
Management: Management:
init [args...] Generate SOUL.md (agent identity contract) init [args...] Generate SOUL.md (agent identity contract)
@@ -76,15 +80,136 @@ function Assert-Runtime {
} }
} }
function Assert-SequentialThinking {
$checker = Join-Path $MosaicHome "bin\mosaic-ensure-sequential-thinking.ps1"
if (-not (Test-Path $checker)) {
Write-Host "[mosaic] ERROR: sequential-thinking checker missing: $checker" -ForegroundColor Red
exit 1
}
try {
& $checker -Check *>$null
}
catch {
Write-Host "[mosaic] ERROR: sequential-thinking MCP is required but not configured." -ForegroundColor Red
Write-Host "[mosaic] Run: $checker"
exit 1
}
}
function Get-RuntimePrompt {
param(
[ValidateSet("claude", "codex", "opencode")]
[string]$Runtime
)
$runtimeFile = switch ($Runtime) {
"claude" { Join-Path $MosaicHome "runtime\claude\RUNTIME.md" }
"codex" { Join-Path $MosaicHome "runtime\codex\RUNTIME.md" }
"opencode" { Join-Path $MosaicHome "runtime\opencode\RUNTIME.md" }
}
if (-not (Test-Path $runtimeFile)) {
Write-Host "[mosaic] ERROR: runtime contract not found: $runtimeFile" -ForegroundColor Red
exit 1
}
$launcherContract = @'
# Mosaic Launcher Runtime Contract (Hard Gate)
This contract is injected by `mosaic` launch and is mandatory.
First assistant response MUST start with exactly one mode declaration line:
1. Orchestration mission: `Now initiating Orchestrator mode...`
2. Implementation mission: `Now initiating Delivery mode...`
3. Review-only mission: `Now initiating Review mode...`
No tool call or implementation step may occur before that first line.
Mosaic hard gates OVERRIDE runtime-default caution for routine delivery operations.
For required push/merge/issue-close/release actions, execute without routine confirmation prompts.
'@
$agentsContent = Get-Content (Join-Path $MosaicHome "AGENTS.md") -Raw
$runtimeContent = Get-Content $runtimeFile -Raw
return "$launcherContract`n$agentsContent`n`n# Runtime-Specific Contract`n`n$runtimeContent"
}
function Ensure-RuntimeConfig { function Ensure-RuntimeConfig {
param([string]$Dst) param(
$src = Join-Path $MosaicHome "AGENTS.md" [ValidateSet("claude", "codex", "opencode")]
[string]$Runtime,
[string]$Dst
)
$parent = Split-Path $Dst -Parent $parent = Split-Path $Dst -Parent
if (-not (Test-Path $parent)) { New-Item -ItemType Directory -Path $parent -Force | Out-Null } if (-not (Test-Path $parent)) { New-Item -ItemType Directory -Path $parent -Force | Out-Null }
$srcHash = (Get-FileHash $src -Algorithm SHA256).Hash
$runtimePrompt = Get-RuntimePrompt -Runtime $Runtime
$tmp = [System.IO.Path]::GetTempFileName()
Set-Content -Path $tmp -Value $runtimePrompt -Encoding UTF8 -NoNewline
$srcHash = (Get-FileHash $tmp -Algorithm SHA256).Hash
$dstHash = if (Test-Path $Dst) { (Get-FileHash $Dst -Algorithm SHA256).Hash } else { "" } $dstHash = if (Test-Path $Dst) { (Get-FileHash $Dst -Algorithm SHA256).Hash } else { "" }
if ($srcHash -ne $dstHash) { if ($srcHash -ne $dstHash) {
Copy-Item $src $Dst -Force Copy-Item $tmp $Dst -Force
Remove-Item $tmp -Force
}
else {
Remove-Item $tmp -Force
}
}
function Invoke-Yolo {
param([string[]]$YoloArgs)
if ($YoloArgs.Count -lt 1) {
Write-Host "[mosaic] ERROR: yolo requires a runtime (claude|codex|opencode)." -ForegroundColor Red
Write-Host "[mosaic] Example: mosaic yolo claude"
exit 1
}
$runtime = $YoloArgs[0]
$tail = if ($YoloArgs.Count -gt 1) { $YoloArgs[1..($YoloArgs.Count - 1)] } else { @() }
switch ($runtime) {
"claude" {
Assert-MosaicHome
Assert-AgentsMd
Assert-Soul
Assert-Runtime "claude"
Assert-SequentialThinking
$agentsContent = Get-RuntimePrompt -Runtime "claude"
Write-Host "[mosaic] Launching Claude Code in YOLO mode (dangerous permissions enabled)..."
& claude --dangerously-skip-permissions --append-system-prompt $agentsContent @tail
return
}
"codex" {
Assert-MosaicHome
Assert-AgentsMd
Assert-Soul
Assert-Runtime "codex"
Assert-SequentialThinking
Ensure-RuntimeConfig -Runtime "codex" -Dst (Join-Path $env:USERPROFILE ".codex\instructions.md")
Write-Host "[mosaic] Launching Codex in YOLO mode (dangerous permissions enabled)..."
& codex --dangerously-bypass-approvals-and-sandbox @tail
return
}
"opencode" {
Assert-MosaicHome
Assert-AgentsMd
Assert-Soul
Assert-Runtime "opencode"
Assert-SequentialThinking
Ensure-RuntimeConfig -Runtime "opencode" -Dst (Join-Path $env:USERPROFILE ".config\opencode\AGENTS.md")
Write-Host "[mosaic] Launching OpenCode in YOLO mode..."
& opencode @tail
return
}
default {
Write-Host "[mosaic] ERROR: Unsupported yolo runtime '$runtime'. Use claude|codex|opencode." -ForegroundColor Red
exit 1
}
} }
} }
@@ -102,8 +227,9 @@ switch ($command) {
Assert-AgentsMd Assert-AgentsMd
Assert-Soul Assert-Soul
Assert-Runtime "claude" Assert-Runtime "claude"
Assert-SequentialThinking
# Claude supports --append-system-prompt for direct injection # Claude supports --append-system-prompt for direct injection
$agentsContent = Get-Content (Join-Path $MosaicHome "AGENTS.md") -Raw $agentsContent = Get-RuntimePrompt -Runtime "claude"
Write-Host "[mosaic] Launching Claude Code..." Write-Host "[mosaic] Launching Claude Code..."
& claude --append-system-prompt $agentsContent @remaining & claude --append-system-prompt $agentsContent @remaining
} }
@@ -112,8 +238,9 @@ switch ($command) {
Assert-AgentsMd Assert-AgentsMd
Assert-Soul Assert-Soul
Assert-Runtime "opencode" Assert-Runtime "opencode"
Assert-SequentialThinking
# OpenCode reads from ~/.config/opencode/AGENTS.md # OpenCode reads from ~/.config/opencode/AGENTS.md
Ensure-RuntimeConfig (Join-Path $env:USERPROFILE ".config\opencode\AGENTS.md") Ensure-RuntimeConfig -Runtime "opencode" -Dst (Join-Path $env:USERPROFILE ".config\opencode\AGENTS.md")
Write-Host "[mosaic] Launching OpenCode..." Write-Host "[mosaic] Launching OpenCode..."
& opencode @remaining & opencode @remaining
} }
@@ -122,11 +249,18 @@ switch ($command) {
Assert-AgentsMd Assert-AgentsMd
Assert-Soul Assert-Soul
Assert-Runtime "codex" Assert-Runtime "codex"
Assert-SequentialThinking
# Codex reads from ~/.codex/instructions.md # Codex reads from ~/.codex/instructions.md
Ensure-RuntimeConfig (Join-Path $env:USERPROFILE ".codex\instructions.md") Ensure-RuntimeConfig -Runtime "codex" -Dst (Join-Path $env:USERPROFILE ".codex\instructions.md")
Write-Host "[mosaic] Launching Codex..." Write-Host "[mosaic] Launching Codex..."
& codex @remaining & codex @remaining
} }
"yolo" {
Invoke-Yolo -YoloArgs $remaining
}
"--yolo" {
Invoke-Yolo -YoloArgs $remaining
}
"init" { "init" {
Assert-MosaicHome Assert-MosaicHome
& (Join-Path $MosaicHome "bin\mosaic-init.ps1") @remaining & (Join-Path $MosaicHome "bin\mosaic-init.ps1") @remaining

View File

@@ -47,7 +47,7 @@
- Use project's established auth pattern - Use project's established auth pattern
- Validate tokens on every request - Validate tokens on every request
- Check permissions before operations - Check permissions before operations
- See `~/.config/mosaic/guides/authentication.md` for details - See `~/.config/mosaic/guides/AUTHENTICATION.md` for details
## Testing Requirements (TDD) ## Testing Requirements (TDD)
1. Write tests BEFORE implementation 1. Write tests BEFORE implementation
@@ -73,18 +73,19 @@ class TestResourceEndpoint:
## Code Style ## Code Style
- Follow Google Style Guide for your language - Follow Google Style Guide for your language
- **TypeScript: Follow `~/.config/mosaic/guides/typescript.md` — MANDATORY** - **TypeScript: Follow `~/.config/mosaic/guides/TYPESCRIPT.md` — MANDATORY**
- Use linter/formatter from project configuration - Use linter/formatter from project configuration
- Keep functions focused and small - Keep functions focused and small
- Document complex business logic - Document complex business logic
### TypeScript Quick Rules (see typescript.md for full guide) ### TypeScript Quick Rules (see TYPESCRIPT.md for full guide)
- **NO `any`** — define explicit types always - **NO `any`** — define explicit types always
- **NO lazy `unknown`** — only for error catches and external data with validation - **NO lazy `unknown`** — only for error catches and external data with validation
- **Explicit return types** on all exported functions - **Explicit return types** on all exported functions
- **Explicit parameter types** always - **Explicit parameter types** always
- **Interface for DTOs** — never inline object types - **DTO files are REQUIRED** for module/API boundaries (`*.dto.ts`)
- **Typed errors** — use custom error classes - **Interface for DTOs** — never inline object types
- **Typed errors** — use custom error classes
## Performance ## Performance
- Use database connection pooling - Use database connection pooling

486
guides/BOOTSTRAP.md Executable file
View File

@@ -0,0 +1,486 @@
# Project Bootstrap Guide
> Load this guide when setting up a new project for AI-assisted development.
## Overview
This guide covers how to bootstrap a project so AI agents (Claude, Codex, etc.) can work on it effectively. Proper bootstrapping ensures:
1. Agents understand the project structure and conventions
2. Orchestration works correctly with quality gates
3. Independent code review and security review are configured
4. Issue tracking is consistent across projects
5. Documentation standards and API contracts are enforced from day one
6. PRD requirements are established before coding begins
7. Branching/merging is consistent: `branch -> main` via PR with squash-only merges
8. Steered-autonomy execution is enabled so agents can run end-to-end with escalation-only human intervention
## Quick Start
```bash
# Automated bootstrap (recommended)
~/.config/mosaic/rails/bootstrap/init-project.sh \
--name "my-project" \
--type "nestjs-nextjs" \
--repo "https://git.mosaicstack.dev/owner/repo"
# Or manually using templates
export PROJECT_NAME="My Project"
export PROJECT_DESCRIPTION="What this project does"
export TASK_PREFIX="MP"
envsubst < ~/.config/mosaic/templates/agent/AGENTS.md.template > AGENTS.md
envsubst < ~/.config/mosaic/templates/agent/CLAUDE.md.template > CLAUDE.md
```
---
## Step 0: Enforce Sequential-Thinking MCP (Hard Requirement)
`sequential-thinking` MCP must be installed and configured before project bootstrapping.
```bash
# Auto-configure sequential-thinking MCP for installed runtimes
~/.config/mosaic/bin/mosaic-ensure-sequential-thinking
# Verification-only check
~/.config/mosaic/bin/mosaic-ensure-sequential-thinking --check
```
If this step fails, STOP and remediate Mosaic runtime configuration before continuing.
---
## Step 1: Detect Project Type
Check what files exist in the project root to determine the type:
| File Present | Project Type | Template |
|---|---|---|
| `package.json` + `pnpm-workspace.yaml` + NestJS+Next.js | NestJS + Next.js Monorepo | `projects/nestjs-nextjs/` |
| `pyproject.toml` + `manage.py` | Django | `projects/django/` |
| `pyproject.toml` (no Django) | Python (generic) | Generic template |
| `package.json` (no monorepo) | Node.js (generic) | Generic template |
| Other | Generic | Generic template |
```bash
# Auto-detect project type
detect_project_type() {
if [[ -f "pnpm-workspace.yaml" ]] && [[ -f "turbo.json" ]]; then
# Check for NestJS + Next.js
if grep -q "nestjs" package.json 2>/dev/null && grep -q "next" package.json 2>/dev/null; then
echo "nestjs-nextjs"
return
fi
fi
if [[ -f "manage.py" ]] && [[ -f "pyproject.toml" ]]; then
echo "django"
return
fi
if [[ -f "pyproject.toml" ]]; then
echo "python"
return
fi
if [[ -f "package.json" ]]; then
echo "nodejs"
return
fi
echo "generic"
}
```
---
## Step 2: Create AGENTS.md (Primary Project Contract)
`AGENTS.md` is the primary project-level contract for all agent runtimes.
It defines project-specific requirements, quality gates, patterns, and testing expectations.
### Using a Tech-Stack Template
```bash
# Set variables
export PROJECT_NAME="My Project"
export PROJECT_DESCRIPTION="Multi-tenant SaaS platform"
export PROJECT_DIR="my-project"
export REPO_URL="https://git.mosaicstack.dev/owner/repo"
export TASK_PREFIX="MP"
# Use tech-stack-specific template if available
TYPE=$(detect_project_type)
TEMPLATE_DIR="$HOME/.config/mosaic/templates/agent/projects/$TYPE"
if [[ -d "$TEMPLATE_DIR" ]]; then
envsubst < "$TEMPLATE_DIR/AGENTS.md.template" > AGENTS.md
else
envsubst < "$HOME/.config/mosaic/templates/agent/AGENTS.md.template" > AGENTS.md
fi
```
### Using the Generic Template
```bash
# Set all required variables
export PROJECT_NAME="My Project"
export PROJECT_DESCRIPTION="What this project does"
export REPO_URL="https://git.mosaicstack.dev/owner/repo"
export PROJECT_DIR="my-project"
export SOURCE_DIR="src"
export CONFIG_FILES="pyproject.toml / package.json"
export FRONTEND_STACK="N/A"
export BACKEND_STACK="Python / FastAPI"
export DATABASE_STACK="PostgreSQL"
export TESTING_STACK="pytest"
export DEPLOYMENT_STACK="Docker"
export BUILD_COMMAND="pip install -e ."
export TEST_COMMAND="pytest tests/"
export LINT_COMMAND="ruff check ."
export TYPECHECK_COMMAND="mypy ."
export QUALITY_GATES="ruff check . && mypy . && pytest tests/"
envsubst < ~/.config/mosaic/templates/agent/AGENTS.md.template > AGENTS.md
```
### Required Sections
Every AGENTS.md should contain:
1. **Project description** — One-line summary
2. **Quality gates** — Commands that must pass
3. **Codebase patterns** — Reusable implementation rules
4. **Common gotchas** — Non-obvious constraints
5. **Testing approaches** — Project-specific test strategy
6. **Testing policy** — Situational-first validation and risk-based TDD
7. **Orchestrator integration** — Task prefix, worker checklist
8. **Documentation contract** — Required documentation gates and update expectations
9. **PRD requirement**`docs/PRD.md` or `docs/PRD.json` required before coding
---
## Step 3: Create Runtime Context File (Runtime-Specific)
Runtime context files are runtime adapters. They are not the primary project contract.
Use `CLAUDE.md` for Claude runtime compatibility. Use other runtime adapters as required by your environment.
Claude runtime mandate (HARD RULE):
- `CLAUDE.md` MUST explicitly instruct Claude agents to read and use `AGENTS.md`.
- `CLAUDE.md` MUST treat `AGENTS.md` as the authoritative project-level contract.
- If `AGENTS.md` and runtime wording conflict, `AGENTS.md` project rules win.
```bash
TYPE=$(detect_project_type)
TEMPLATE_DIR="$HOME/.config/mosaic/templates/agent/projects/$TYPE"
if [[ -d "$TEMPLATE_DIR" ]]; then
envsubst < "$TEMPLATE_DIR/CLAUDE.md.template" > CLAUDE.md
else
envsubst < "$HOME/.config/mosaic/templates/agent/CLAUDE.md.template" > CLAUDE.md
fi
```
### Required Runtime Sections
Every runtime context file should contain:
1. **AGENTS handoff rule** — Runtime MUST direct agents to read/use `AGENTS.md`
2. **Conditional documentation loading** — Required guide loading map
3. **Technology stack** — Runtime-facing architecture summary
4. **Repository structure** — Important paths
5. **Development workflow** — Build/test/lint/typecheck commands
6. **Issue tracking** — Issue and commit conventions
7. **Code review** — Required review process
8. **Runtime notes** — Runtime-specific behavior references
9. **Branch and merge policy** — Trunk workflow (`branch -> main` via PR, squash-only)
10. **Autonomy and escalation policy** — Agent owns coding/review/PR/release/deploy lifecycle
---
## Step 4: Create Directory Structure
```bash
# Create standard directories
mkdir -p docs/scratchpads
mkdir -p docs/templates
mkdir -p docs/reports/qa-automation/pending
mkdir -p docs/reports/qa-automation/in-progress
mkdir -p docs/reports/qa-automation/done
mkdir -p docs/reports/qa-automation/escalated
mkdir -p docs/reports/deferred
mkdir -p docs/tasks
mkdir -p docs/releases
mkdir -p docs/USER-GUIDE docs/ADMIN-GUIDE docs/DEVELOPER-GUIDE docs/API
# Documentation baseline files
touch docs/USER-GUIDE/README.md
touch docs/ADMIN-GUIDE/README.md
touch docs/DEVELOPER-GUIDE/README.md
touch docs/API/OPENAPI.yaml
touch docs/API/ENDPOINTS.md
touch docs/SITEMAP.md
# PRD baseline file (requirements source before coding)
cp ~/.config/mosaic/templates/docs/PRD.md.template docs/PRD.md
# TASKS baseline file (canonical tracking)
cp ~/.config/mosaic/templates/docs/TASKS.md.template docs/TASKS.md
# Deployment baseline file (target/platform/runbook)
touch docs/DEPLOYMENT.md
```
Documentation root hygiene (HARD RULE):
- Keep `docs/` root clean.
- Store reports in `docs/reports/`, archived task artifacts in `docs/tasks/`, releases in `docs/releases/`, and scratchpads in `docs/scratchpads/`.
- Do not place ad-hoc report files directly under `docs/`.
---
## Step 5: Initialize Repository Labels & Milestones
```bash
# Use the init script
~/.config/mosaic/rails/bootstrap/init-repo-labels.sh
# Or manually create standard labels
~/.config/mosaic/rails/git/issue-create.sh # (labels are created on first use)
```
### Standard Labels
| Label | Color | Purpose |
|-------|-------|---------|
| `epic` | `#3E4B9E` | Large feature spanning multiple issues |
| `feature` | `#0E8A16` | New functionality |
| `bug` | `#D73A4A` | Defect fix |
| `task` | `#0075CA` | General work item |
| `documentation` | `#0075CA` | Documentation updates |
| `security` | `#B60205` | Security-related |
| `breaking` | `#D93F0B` | Breaking change |
### Initial Milestone (Hard Rule)
Create the first pre-MVP milestone at `0.0.1`.
Reserve `0.1.0` for the MVP release milestone.
```bash
~/.config/mosaic/rails/git/milestone-create.sh -t "0.0.1" -d "Pre-MVP - Foundation Sprint"
# Create when MVP scope is complete and release-ready:
~/.config/mosaic/rails/git/milestone-create.sh -t "0.1.0" -d "MVP - Minimum Viable Product"
```
---
## Step 5b: Configure Main Branch Protection (Hard Rule)
Apply equivalent settings in Gitea, GitHub, or GitLab:
1. Protect `main` from direct pushes.
2. Require pull requests to merge into `main`.
3. Require required CI/status checks to pass before merge.
4. Require code review approval before merge.
5. Allow **squash merge only** for PRs into `main` (disable merge commits and rebase merges for `main`).
This enforces one merge strategy across human and agent workflows.
---
## Step 6: Set Up CI/CD Review Pipeline
### Woodpecker CI
```bash
# Copy Codex review pipeline
mkdir -p .woodpecker/schemas
cp ~/.config/mosaic/rails/codex/woodpecker/codex-review.yml .woodpecker/
cp ~/.config/mosaic/rails/codex/schemas/*.json .woodpecker/schemas/
# Add codex_api_key secret to Woodpecker CI dashboard
```
### GitHub Actions
For GitHub repos, use the official Codex GitHub Action instead:
```yaml
# .github/workflows/codex-review.yml
uses: openai/codex-action@v1
```
### Python Package Publishing (Gitea PyPI)
If the project publishes Python packages, use Gitea's PyPI registry.
```bash
# Build and publish
python -m pip install --upgrade build twine
python -m build
python -m twine upload \
--repository-url "https://GITEA_HOST/api/packages/ORG/pypi" \
--username "$GITEA_USERNAME" \
--password "$GITEA_TOKEN" \
dist/*
```
Use the same `gitea_username` and `gitea_token` CI secrets used for container and npm publishing.
---
## Step 7: Verify Bootstrap
After bootstrapping, verify everything works:
```bash
# Check files exist
ls AGENTS.md docs/scratchpads/
ls docs/reports/qa-automation/pending docs/reports/deferred docs/tasks docs/releases
ls docs/USER-GUIDE/README.md docs/ADMIN-GUIDE/README.md docs/DEVELOPER-GUIDE/README.md
ls docs/API/OPENAPI.yaml docs/API/ENDPOINTS.md docs/SITEMAP.md
ls docs/PRD.md
ls docs/TASKS.md
# Verify AGENTS.md has required sections
grep -c "Quality Gates" AGENTS.md
grep -c "Orchestrator Integration" AGENTS.md
grep -c "Testing Approaches" AGENTS.md
grep -c "Testing Policy" AGENTS.md
grep -c "Documentation Contract" AGENTS.md
grep -c "PRD Requirement" AGENTS.md
# Verify runtime context file has required sections
if [[ -f CLAUDE.md ]]; then
grep -c "AGENTS.md" CLAUDE.md
grep -c "Conditional Documentation Loading" CLAUDE.md
grep -c "Technology Stack" CLAUDE.md
grep -c "Code Review" CLAUDE.md
elif [[ -f RUNTIME.md ]]; then
grep -c "Conditional Documentation Loading" RUNTIME.md
grep -c "Technology Stack" RUNTIME.md
grep -c "Code Review" RUNTIME.md
else
echo "Missing runtime context file (CLAUDE.md or RUNTIME.md)" >&2
exit 1
fi
# Run quality gates from AGENTS.md
# (execute the command block under "Quality Gates")
# Test Codex review (if configured)
~/.config/mosaic/rails/codex/codex-code-review.sh --help
# Verify sequential-thinking MCP remains configured
~/.config/mosaic/bin/mosaic-ensure-sequential-thinking --check
```
---
## Available Templates
### Generic Templates
| Template | Path | Purpose |
|----------|------|---------|
| `AGENTS.md.template` | `~/.config/mosaic/templates/agent/` | Primary project agent contract |
| `CLAUDE.md.template` | `~/.config/mosaic/templates/agent/` | Runtime compatibility context (Claude) |
| `DOCUMENTATION-CHECKLIST.md` | `~/.config/mosaic/templates/docs/` | Documentation completion gate |
| `PRD.md.template` | `~/.config/mosaic/templates/docs/` | Requirements source template |
| `TASKS.md.template` | `~/.config/mosaic/templates/docs/` | Canonical task and issue tracking template |
### Tech-Stack Templates
| Stack | Path | Includes |
|-------|------|----------|
| NestJS + Next.js | `~/.config/mosaic/templates/agent/projects/nestjs-nextjs/` | AGENTS.md + runtime context template |
| Django | `~/.config/mosaic/templates/agent/projects/django/` | AGENTS.md + runtime context template |
### Orchestrator Templates
| Template | Path | Purpose |
|----------|------|---------|
| `tasks.md.template` | `~/src/jarvis-brain/docs/templates/orchestrator/` | Task tracking |
| `orchestrator-learnings.json.template` | `~/src/jarvis-brain/docs/templates/orchestrator/` | Variance tracking |
| `phase-issue-body.md.template` | `~/src/jarvis-brain/docs/templates/orchestrator/` | Git provider issue body |
| `scratchpad.md.template` | `~/src/jarvis-brain/docs/templates/` | Per-task working doc |
### Variables Reference
| Variable | Description | Example |
|----------|-------------|---------|
| `${PROJECT_NAME}` | Human-readable project name | "Mosaic Stack" |
| `${PROJECT_DESCRIPTION}` | One-line description | "Multi-tenant platform" |
| `${PROJECT_DIR}` | Directory name | "mosaic-stack" |
| `${PROJECT_SLUG}` | Python package slug | "mosaic_stack" |
| `${REPO_URL}` | Git remote URL | "https://git.mosaicstack.dev/mosaic/stack" |
| `${TASK_PREFIX}` | Orchestrator task prefix | "MS" |
| `${SOURCE_DIR}` | Source code directory | "src" or "apps" |
| `${QUALITY_GATES}` | Quality gate commands | "pnpm typecheck && pnpm lint && pnpm test" |
| `${BUILD_COMMAND}` | Build command | "pnpm build" |
| `${TEST_COMMAND}` | Test command | "pnpm test" |
| `${LINT_COMMAND}` | Lint command | "pnpm lint" |
| `${TYPECHECK_COMMAND}` | Type check command | "pnpm typecheck" |
| `${FRONTEND_STACK}` | Frontend technologies | "Next.js + React" |
| `${BACKEND_STACK}` | Backend technologies | "NestJS + Prisma" |
| `${DATABASE_STACK}` | Database technologies | "PostgreSQL" |
| `${TESTING_STACK}` | Testing technologies | "Vitest + Playwright" |
| `${DEPLOYMENT_STACK}` | Deployment technologies | "Docker" |
| `${CONFIG_FILES}` | Key config files | "package.json, tsconfig.json" |
---
## Bootstrap Scripts
### init-project.sh
Full project bootstrap with interactive and flag-based modes:
```bash
~/.config/mosaic/rails/bootstrap/init-project.sh \
--name "My Project" \
--type "nestjs-nextjs" \
--repo "https://git.mosaicstack.dev/owner/repo" \
--prefix "MP" \
--description "Multi-tenant platform"
```
### init-repo-labels.sh
Initialize standard labels and the first pre-MVP milestone:
```bash
~/.config/mosaic/rails/bootstrap/init-repo-labels.sh
```
---
## Checklist
After bootstrapping, verify:
- [ ] `AGENTS.md` exists and is the primary project contract
- [ ] Runtime context file exists (`CLAUDE.md` or `RUNTIME.md`)
- [ ] `docs/scratchpads/` directory exists
- [ ] `docs/reports/qa-automation/pending` directory exists
- [ ] `docs/reports/deferred/` directory exists
- [ ] `docs/tasks/` directory exists
- [ ] `docs/releases/` directory exists
- [ ] `docs/USER-GUIDE/README.md` exists
- [ ] `docs/ADMIN-GUIDE/README.md` exists
- [ ] `docs/DEVELOPER-GUIDE/README.md` exists
- [ ] `docs/API/OPENAPI.yaml` exists
- [ ] `docs/API/ENDPOINTS.md` exists
- [ ] `docs/SITEMAP.md` exists
- [ ] `docs/PRD.md` or `docs/PRD.json` exists
- [ ] `docs/TASKS.md` exists and is ready for active tracking
- [ ] `docs/DEPLOYMENT.md` exists with target platform and rollback notes
- [ ] `sequential-thinking` MCP is configured and verification check passes
- [ ] Git labels created (epic, feature, bug, task, etc.)
- [ ] Initial pre-MVP milestone created (0.0.1)
- [ ] MVP milestone reserved for release (0.1.0)
- [ ] `main` is protected from direct pushes
- [ ] PRs into `main` are required
- [ ] Merge method for `main` is squash-only
- [ ] Quality gates run successfully
- [ ] `.env.example` exists (if project uses env vars)
- [ ] CI/CD pipeline configured (if using Woodpecker/GitHub Actions)
- [ ] Python publish path configured in CI (if project ships Python packages)
- [ ] Codex review scripts accessible (`~/.config/mosaic/rails/codex/`)

122
guides/code-review.md → guides/CODE-REVIEW.md Normal file → Executable file
View File

@@ -1,28 +1,57 @@
# Code Review Guide # Code Review Guide
## Hard Requirement
If an agent modifies source code, code review is REQUIRED before completion.
Do not mark code-change tasks done until review is completed and blockers are resolved or explicitly tracked.
If code/config/API contract/auth behavior changed and required docs are missing, this is a BLOCKER.
If tests pass but acceptance criteria are not verified by situational evidence, this is a BLOCKER.
If implementation diverges from `docs/PRD.md` or `docs/PRD.json` without PRD updates, this is a BLOCKER.
Merge strategy enforcement (HARD RULE):
- PR target for delivery is `main`.
- Direct pushes to `main` are prohibited.
- Merge to `main` MUST be squash-only.
- Use `~/.config/mosaic/rails/git/pr-merge.sh -n {PR_NUMBER} -m squash` (or PowerShell equivalent).
## Review Checklist
## Review Checklist ### 1. Correctness
- [ ] Code does what the issue/PR description says
- [ ] Code aligns with active PRD requirements
- [ ] Acceptance criteria are mapped to concrete verification evidence
- [ ] Edge cases are handled
- [ ] Error conditions are managed properly
- [ ] No obvious bugs or logic errors
### 1. Correctness ### 2. Security
- [ ] Code does what the issue/PR description says - [ ] No hardcoded secrets or credentials
- [ ] Edge cases are handled - [ ] Input validation at boundaries
- [ ] Error conditions are managed properly - [ ] SQL injection prevention (parameterized queries)
- [ ] No obvious bugs or logic errors - [ ] XSS prevention (output encoding)
- [ ] Authentication/authorization checks present
- [ ] Sensitive data not logged
- [ ] Secrets follow Vault structure (see `docs/vault-secrets-structure.md`)
### 2a. OWASP Coverage (Required)
- [ ] OWASP Top 10 categories were reviewed for change impact
- [ ] Access control checks verified on protected actions
- [ ] Cryptographic handling validated (keys, hashing, TLS assumptions)
- [ ] Injection risks reviewed for all untrusted inputs
- [ ] Security misconfiguration risks reviewed (headers, CORS, defaults)
- [ ] Dependency/component risk reviewed (known vulnerable components)
- [ ] Authentication/session flows reviewed for failure paths
- [ ] Logging/monitoring preserves detection without leaking sensitive data
### 2. Security ### 3. Testing
- [ ] No hardcoded secrets or credentials - [ ] Tests exist for new functionality
- [ ] Input validation at boundaries - [ ] Tests cover happy path AND error cases
- [ ] SQL injection prevention (parameterized queries) - [ ] Situational tests cover all impacted change surfaces (primary gate)
- [ ] XSS prevention (output encoding) - [ ] Tests validate required behavior/outcomes, not only internal implementation details
- [ ] Authentication/authorization checks present - [ ] TDD was applied when required by `~/.config/mosaic/guides/QA-TESTING.md`
- [ ] Sensitive data not logged - [ ] Coverage meets 85% minimum
- [ ] Secrets follow Vault structure (see `docs/vault-secrets-structure.md`) - [ ] Tests are readable and maintainable
- [ ] No flaky tests introduced
### 3. Testing
- [ ] Tests exist for new functionality
- [ ] Tests cover happy path AND error cases
- [ ] Coverage meets 85% minimum
- [ ] Tests are readable and maintainable
- [ ] No flaky tests introduced
### 4. Code Quality ### 4. Code Quality
- [ ] Follows Google Style Guide for the language - [ ] Follows Google Style Guide for the language
@@ -32,21 +61,27 @@
- [ ] Clear naming for variables and functions - [ ] Clear naming for variables and functions
- [ ] No dead code or commented-out code - [ ] No dead code or commented-out code
### 4a. TypeScript Strict Typing (see `typescript.md`) ### 4a. TypeScript Strict Typing (see `TYPESCRIPT.md`)
- [ ] **NO `any` types** — explicit types required everywhere - [ ] **NO `any` types** — explicit types required everywhere
- [ ] **NO lazy `unknown`** — only for error catches with immediate narrowing - [ ] **NO lazy `unknown`** — only for error catches with immediate narrowing
- [ ] **Explicit return types** on all exported/public functions - [ ] **Explicit return types** on all exported/public functions
- [ ] **Explicit parameter types** — never implicit any - [ ] **Explicit parameter types** — never implicit any
- [ ] **No type assertions** (`as Type`) — use type guards instead - [ ] **No type assertions** (`as Type`) — use type guards instead
- [ ] **No non-null assertions** (`!`) — use proper null handling - [ ] **No non-null assertions** (`!`) — use proper null handling
- [ ] **Interfaces for objects** — not inline types - [ ] **Interfaces for objects** — not inline types
- [ ] **Discriminated unions** for variant types - [ ] **Discriminated unions** for variant types
- [ ] **DTO files used at boundaries** — module/API contracts are in `*.dto.ts`, not inline payload types
### 5. Documentation ### 5. Documentation
- [ ] Complex logic has explanatory comments - [ ] Complex logic has explanatory comments
- [ ] Public APIs are documented - [ ] Required docs updated per `~/.config/mosaic/guides/DOCUMENTATION.md`
- [ ] README updated if needed - [ ] Public APIs are documented
- [ ] Breaking changes noted - [ ] Private/internal APIs are documented
- [ ] API input/output schemas are documented
- [ ] API permissions/auth requirements are documented
- [ ] Site map updates are present when navigation changed
- [ ] README updated if needed
- [ ] Breaking changes noted
### 6. Performance ### 6. Performance
- [ ] No obvious N+1 queries - [ ] No obvious N+1 queries
@@ -59,7 +94,9 @@
- [ ] No unnecessary new dependencies - [ ] No unnecessary new dependencies
- [ ] Dependency versions pinned appropriately - [ ] Dependency versions pinned appropriately
## Review Process ## Review Process
Use `~/.config/mosaic/templates/docs/DOCUMENTATION-CHECKLIST.md` whenever code/API/auth/infra changes are present.
### Getting Context ### Getting Context
```bash ```bash
@@ -94,8 +131,9 @@ Use parameterized queries instead:
This pattern appears in 3 places. A shared helper would reduce duplication. This pattern appears in 3 places. A shared helper would reduce duplication.
``` ```
## After Review ## After Review
1. Update issue with review status 1. Update issue with review status
2. If changes requested, assign back to author 2. If changes requested, assign back to author
3. If approved, note approval in issue comments 3. If approved, note approval in issue comments
4. For merges, ensure CI passes first 4. For merges, ensure CI passes first
5. Merge PR to `main` with squash strategy only

132
guides/DOCUMENTATION.md Normal file
View File

@@ -0,0 +1,132 @@
# Documentation Standard (MANDATORY)
This guide defines REQUIRED documentation behavior for all Mosaic projects.
If code, API contracts, auth, or infrastructure changes, documentation updates are REQUIRED before completion.
## Hard Rules
1. Documentation is a delivery gate. Missing required documentation is a BLOCKER.
2. `docs/PRD.md` or `docs/PRD.json` is REQUIRED as the project requirements source before coding begins.
3. API documentation is OpenAPI-first. `docs/API/OPENAPI.yaml` (or `.json`) is the canonical API contract.
4. Public and private/internal endpoints MUST be documented.
5. API input and output schemas MUST be documented.
6. API authentication and permissions MUST be documented per endpoint.
7. A current site map MUST exist at `docs/SITEMAP.md`.
8. Documentation updates MUST be committed in the same logical change set as the code/API change.
9. Generated publishing output (Docusaurus/VitePress/MkDocs artifacts) is not canonical unless the project explicitly declares it canonical.
10. `docs/` root MUST stay clean. Reports and working artifacts MUST be stored in dedicated subdirectories, not dumped at `docs/` root.
## Required Documentation Structure
```text
docs/
PRD.md (or PRD.json)
TASKS.md (active orchestrator tracking, when orchestrator is used)
SITEMAP.md
USER-GUIDE/
ADMIN-GUIDE/
DEVELOPER-GUIDE/
API/
OPENAPI.yaml
ENDPOINTS.md
scratchpads/
reports/
tasks/
releases/
templates/ (optional)
```
Minimum requirements:
- `docs/PRD.md` or `docs/PRD.json`: authoritative requirements source for implementation and testing.
- `docs/USER-GUIDE/`: End-user workflows, feature behavior, common troubleshooting.
- `docs/ADMIN-GUIDE/`: Configuration, deployment, operations, incident/recovery procedures.
- `docs/DEVELOPER-GUIDE/`: Architecture, local setup, contribution/testing workflow, design constraints.
- `docs/API/OPENAPI.yaml`: API SSOT for all HTTP endpoints.
- `docs/API/ENDPOINTS.md`: Human-readable index for API endpoints, permissions, and change notes.
- `docs/SITEMAP.md`: Navigation index for all user/admin/developer/API documentation pages.
- `docs/reports/`: Review outputs, QA automation reports, deferrals, and audit artifacts.
- `docs/tasks/`: Archived task snapshots and orchestrator learnings.
- `docs/releases/`: Release notes and release-specific documentation.
- `docs/scratchpads/`: Active task-level working notes.
## Root Hygiene Rule (MANDATORY)
Allowed root documentation files are intentionally limited:
1. `docs/PRD.md` or `docs/PRD.json`
2. `docs/TASKS.md` (active milestone only, when task orchestration is in use)
3. `docs/SITEMAP.md`
4. `docs/README.md` (optional index)
All other docs MUST be placed in scoped folders (`docs/reports/`, `docs/tasks/`, `docs/releases/`, `docs/scratchpads/`, `docs/API/`, guide books).
## Artifact Placement Rules
| Artifact Type | REQUIRED Location |
|---|---|
| Code review reports, QA reports, audits | `docs/reports/<category>/` |
| Deferred error lists / unresolved findings | `docs/reports/deferred/` |
| Archived milestone task snapshots | `docs/tasks/` |
| Orchestrator learnings JSON | `docs/tasks/orchestrator-learnings.json` |
| Release notes | `docs/releases/` |
| Active scratchpads | `docs/scratchpads/` |
## API Documentation Contract (OpenAPI-First)
For every API endpoint, documentation MUST include:
1. visibility: `public` or `private/internal`
2. method and path
3. endpoint purpose
4. request/input schema
5. response/output schema(s)
6. auth method and required permission/role/scope
7. error status codes and behavior
If OpenAPI cannot fully express an internal constraint, document it in `docs/API/ENDPOINTS.md`.
## Book/Chapter/Page Structure
Use this structure for every guide:
1. Book: one root guide folder (`USER-GUIDE`, `ADMIN-GUIDE`, `DEVELOPER-GUIDE`)
2. Chapter: one subdirectory per topic area
3. Page: one focused markdown file per concern
Required index files:
1. `docs/USER-GUIDE/README.md`
2. `docs/ADMIN-GUIDE/README.md`
3. `docs/DEVELOPER-GUIDE/README.md`
Each index file MUST link to all chapters and pages in that book.
## Situational Documentation Matrix
| Change Surface | REQUIRED Documentation Updates |
|---|---|
| New feature or behavior change | User guide + developer guide + sitemap |
| API endpoint added/changed/removed | OpenAPI + API endpoint index + sitemap |
| Auth/RBAC/permission change | API auth/permission docs + admin guide + developer guide |
| Database schema/migration change | Developer guide + admin operational notes if runbook impact |
| CI/CD or deployment change | Admin guide + developer guide |
| Incident, recovery, or security control change | Admin guide runbook + security notes + sitemap |
## Publishing Target Rule (MANDATORY)
If the user does not specify documentation publishing target, the agent MUST ask:
1. Publish in-app (embedded docs)
2. Publish on external docs platform (for example: Docusaurus, VitePress, MkDocs)
Default behavior before publishing decision:
- Keep canonical docs in-repo under `docs/`.
- Do not assume external publishing platform.
## Completion Gate
You MUST NOT declare completion until all required documentation updates are done.
Use `~/.config/mosaic/templates/docs/DOCUMENTATION-CHECKLIST.md` as the final gate.

View File

@@ -49,12 +49,12 @@ describe('ComponentName', () => {
## Code Style ## Code Style
- Follow Google JavaScript/TypeScript Style Guide - Follow Google JavaScript/TypeScript Style Guide
- **TypeScript: Follow `~/.config/mosaic/guides/typescript.md` — MANDATORY** - **TypeScript: Follow `~/.config/mosaic/guides/TYPESCRIPT.md` — MANDATORY**
- Use ESLint/Prettier configuration from project - Use ESLint/Prettier configuration from project
- Prefer functional components over class components (React) - Prefer functional components over class components (React)
- TypeScript strict mode is REQUIRED, not optional - TypeScript strict mode is REQUIRED, not optional
### TypeScript Quick Rules (see typescript.md for full guide) ### TypeScript Quick Rules (see TYPESCRIPT.md for full guide)
- **NO `any`** — define explicit types always - **NO `any`** — define explicit types always
- **NO lazy `unknown`** — only for error catches and external data with validation - **NO lazy `unknown`** — only for error catches and external data with validation
- **Explicit return types** on all exported functions - **Explicit return types** on all exported functions

View File

@@ -97,10 +97,10 @@ readinessProbe:
periodSeconds: 3 periodSeconds: 3
``` ```
## CI/CD Pipelines ## CI/CD Pipelines
### Pipeline Stages ### Pipeline Stages
1. **Lint**: Code style and static analysis 1. **Lint**: Code style and static analysis
2. **Test**: Unit and integration tests 2. **Test**: Unit and integration tests
3. **Build**: Compile and package 3. **Build**: Compile and package
4. **Scan**: Security and vulnerability scanning 4. **Scan**: Security and vulnerability scanning
@@ -109,10 +109,65 @@ readinessProbe:
### Pipeline Security ### Pipeline Security
- Use secrets management (not hardcoded) - Use secrets management (not hardcoded)
- Pin action/image versions - Pin action/image versions
- Implement approval gates for production - Implement approval gates for production
- Audit pipeline access - Audit pipeline access
## Monitoring & Logging ## Steered-Autonomous Deployment (Hard Rule)
In lights-out mode, the agent owns deployment end-to-end when deployment is in scope.
The human is escalation-only for missing access, hard policy conflicts, or irreversible risk.
### Deployment Target Selection
1. Use explicit target from `docs/PRD.md` / `docs/PRD.json` or `docs/DEPLOYMENT.md`.
2. If unspecified, infer from existing project config/integration.
3. If multiple targets exist, choose the target already wired in CI/CD and document rationale.
### Supported Targets
- **Portainer**: Deploy via configured stack webhook/API, then verify service health and container status.
- **Coolify**: Trigger deployment via Coolify API/webhook, then verify deployment status and endpoint health.
- **Vercel**: Deploy via `vercel` CLI or connected Git integration, then verify preview/production URL health.
- **Other SaaS providers**: Use provider CLI/API/runbook with the same validation and rollback gates.
### Image Tagging and Promotion (Hard Rule)
For containerized deployments:
1. Build immutable image tags: `sha-<shortsha>` and `v{base-version}-rc.{build}`.
2. Use mutable environment tags only as pointers: `testing`, optional `staging`, and `prod`.
3. Deploy by immutable digest, not by mutable tag alone.
4. Promote the exact tested digest between environments (no rebuild between testing and prod).
5. Do not use `latest` or `dev` as deployment references.
Blue-green is the default strategy for production promotion.
Canary is allowed only when automated SLO/error-rate gates and auto-rollback triggers are implemented.
### Post-Deploy Validation (REQUIRED)
1. Health endpoints return expected status.
2. Critical smoke tests pass in target environment.
3. Running version and digest match the promoted release candidate.
4. Observability signals (errors/latency) are within expected thresholds.
### Rollback Rule
If post-deploy validation fails:
1. Execute rollback/redeploy-safe path immediately.
2. Mark deployment as blocked in `docs/TASKS.md`.
3. Record failure evidence and next remediation step in scratchpad and release notes.
### Registry Retention and Cleanup
Cleanup MUST be automated.
- Keep all final release tags (`vX.Y.Z`) indefinitely.
- Keep active environment digests (`prod`, `testing`, and active blue/green slots).
- Keep recent RC tags (`vX.Y.Z-rc.N`) based on retention window.
- Remove stale `sha-*` and RC tags outside retention window if they are not actively deployed.
## Monitoring & Logging
### Logging Standards ### Logging Standards
- Use structured logging (JSON) - Use structured logging (JSON)

27
guides/MEMORY.md Normal file
View File

@@ -0,0 +1,27 @@
# Memory and Retention Rules
## Hard Rules
1. You MUST store learned operational memory in `~/.config/mosaic/memory`.
2. You MUST NOT store durable memory in runtime-native memory silos.
3. You MUST write concise, reusable learnings that help future agents.
4. You MUST track active execution state in project documentation, not ad-hoc text files.
## Runtime-Native Memory Silos (FORBIDDEN for Durable Memory)
| Runtime | Native silo (forbidden for durable memory) | Required durable location |
|---|---|---|
| Claude Code | `~/.claude/projects/*/memory/` | `~/.config/mosaic/memory/` + project `docs/` |
| Codex | Runtime session/native memory under `~/.codex/` | `~/.config/mosaic/memory/` + project `docs/` |
| OpenCode | Runtime session/native memory under `~/.config/opencode/` | `~/.config/mosaic/memory/` + project `docs/` |
Treat runtime-native memory as volatile implementation detail. Do not rely on it for long-term project continuity.
## Project Continuity Files (MANDATORY)
| File | Purpose | Location |
|---|---|---|
| `docs/PRD.md` or `docs/PRD.json` | Source of requirements for planning, coding, testing, and review | Project `docs/` |
| `docs/TASKS.md` | Canonical tracking for tasks, milestones, issues, status, and blockers | Project `docs/` |
| `docs/scratchpads/<task>.md` | Task-specific working memory and verification evidence | Project `docs/scratchpads/` |
| `AGENTS.md` | Reusable local patterns and gotchas | Any working directory |

View File

@@ -2,11 +2,11 @@
> Cross-project heuristic adjustments based on observed variance data. > Cross-project heuristic adjustments based on observed variance data.
> >
> **Note:** This file contains generic patterns only. Project-specific evidence is stored in each project's `docs/orchestrator-learnings.json`. > **Note:** This file contains generic patterns only. Project-specific evidence is stored in each project's `docs/tasks/orchestrator-learnings.json`.
## Task Type Multipliers ## Task Type Multipliers
Apply these multipliers to base estimates from `orchestrator.md`: Apply these multipliers to base estimates from `ORCHESTRATOR.md`:
| Task Type | Base Estimate | Multiplier | Confidence | Samples | Last Updated | | Task Type | Base Estimate | Multiplier | Confidence | Samples | Last Updated |
|-----------|---------------|------------|------------|---------|--------------| |-----------|---------------|------------|------------|---------|--------------|
@@ -37,7 +37,7 @@ Apply to all estimates based on task position in milestone:
Final Estimate = Base Estimate × Type Multiplier × Phase Factor × TDD Overhead Final Estimate = Base Estimate × Type Multiplier × Phase Factor × TDD Overhead
Where: Where:
- Base Estimate: From orchestrator.md task type table - Base Estimate: From ORCHESTRATOR.md task type table
- Type Multiplier: From table above (default 1.0) - Type Multiplier: From table above (default 1.0)
- Phase Factor: 1.45 / 1.25 / 1.10 based on position - Phase Factor: 1.45 / 1.25 / 1.10 based on position
- TDD Overhead: 1.20 if tests required - TDD Overhead: 1.20 if tests required
@@ -122,5 +122,5 @@ Where:
## Where to Find Project-Specific Data ## Where to Find Project-Specific Data
- **Project learnings:** `<project>/docs/orchestrator-learnings.json` - **Project learnings:** `<project>/docs/tasks/orchestrator-learnings.json`
- **Cross-project metrics:** `jarvis-brain/data/orchestrator-metrics.json` - **Cross-project metrics:** `jarvis-brain/data/orchestrator-metrics.json`

63
guides/PRD.md Normal file
View File

@@ -0,0 +1,63 @@
# PRD Requirement Guide (MANDATORY)
This guide defines how requirements are captured before coding.
## Hard Rules
1. Before coding begins, `docs/PRD.md` or `docs/PRD.json` MUST exist.
2. The PRD is the authoritative requirements source for implementation and testing.
3. The main agent MUST prepare or update the PRD using user input and available project context before implementation starts.
4. The agent MUST NOT invent requirements silently.
5. In steered autonomy mode, best-guess decisions are REQUIRED when needed; each guessed decision MUST be marked with `ASSUMPTION:` and rationale.
## PRD Format
Allowed canonical formats:
1. `docs/PRD.md`
2. `docs/PRD.json`
Either format is valid. Both may exist if one is a transformed representation of the other.
For markdown PRDs, start from `~/.config/mosaic/templates/docs/PRD.md.template`.
## Best-Guess Mode
Steered autonomy is the default operating mode.
1. Agent SHOULD fill missing decisions in the PRD without waiting for routine confirmation.
2. Agent MUST mark each guessed decision with `ASSUMPTION:` and rationale.
3. If user explicitly requests strict-confirmation mode, the agent MUST ask before unresolved decisions are finalized.
4. For high-impact security/compliance/release uncertainty, escalate only if the decision cannot be safely constrained with rollback-ready defaults.
## Minimum PRD Content
Every PRD MUST include:
1. Problem statement and objective
2. In-scope and out-of-scope
3. User/stakeholder requirements
4. Functional requirements
5. Non-functional requirements (security, performance, reliability, observability)
6. Acceptance criteria
7. Constraints and dependencies
8. Risks and open questions
9. Testing and verification expectations
10. Delivery/milestone intent
## Pre-Coding Gate
Coding MUST NOT begin until:
1. PRD file exists (`docs/PRD.md` or `docs/PRD.json`)
2. PRD has required sections
3. Unresolved decisions are captured as explicit `ASSUMPTION:` entries with rationale and planned validation
## Change Control
When requirements materially change:
1. Update PRD first.
2. Then update implementation plan/tasks.
3. Then implement code changes.
Implementation that diverges from PRD without PRD updates is a blocker.

114
guides/QA-TESTING.md Normal file
View File

@@ -0,0 +1,114 @@
# QA & Testing Guide
## Before Starting
1. Check assigned issue: `~/.config/mosaic/rails/git/issue-list.sh -a @me`
2. Create scratchpad: `docs/scratchpads/{issue-number}-{short-name}.md`
3. Review `docs/PRD.md` or `docs/PRD.json` as the requirements source.
4. Review acceptance criteria and affected change surfaces.
## Testing Policy (Hard Rules)
1. Situational testing is the PRIMARY validation gate.
2. Baseline testing is REQUIRED for all software changes.
3. TDD is risk-based and REQUIRED only for defined high-risk change types.
4. Tests MUST validate requirements and behavior, not only internal implementation details.
## Priority Order
1. Situational tests: prove requirements and real behavior on changed surfaces.
2. Baseline tests: lint/type/unit/integration safety checks.
3. TDD discipline: applied where risk justifies test-first workflow.
## Risk-Based TDD Requirement
| Change Type | TDD Requirement | Required Action |
|---|---|---|
| Bug fix | REQUIRED | Write a failing reproducer test first, then fix. |
| Security/auth/permission logic | REQUIRED | Write failing security/permission-path test first. |
| Critical business logic or data mutation rules | REQUIRED | Write failing rule/invariant test first. |
| API behavior regression | REQUIRED | Write failing contract/behavior test first. |
| Low-risk UI copy/style/layout | OPTIONAL | Add verification tests as appropriate; TDD recommended, not mandatory. |
| Mechanical refactor with unchanged behavior | OPTIONAL | Ensure regression/smoke coverage and situational evidence. |
If TDD is not required and skipped, record rationale in scratchpad.
If TDD is required and skipped, task is NOT complete.
## Baseline Test Requirements
For all software changes, run baseline checks applicable to the repo:
1. lint/static checks
2. type checks
3. unit tests for changed logic
4. integration tests for changed boundaries
## Situational Testing Matrix (Primary Gate)
| Change Surface | Required Situational Tests |
|---|---|
| Authentication/authorization | auth failure-path tests, permission boundary tests, token/session validation |
| Database schema/migrations | migration up/down validation, rollback safety, data integrity checks |
| API contract changes | backward compatibility checks, consumer-impact tests, contract tests |
| Frontend/UI workflow changes | end-to-end flow tests, accessibility sanity checks, state transition checks |
| CI/CD or deployment changes | pipeline execution validation, artifact integrity checks, rollback path check |
| Security-sensitive logic | abuse-case tests, input validation fuzzing/sanitization checks |
| Performance-critical path | baseline comparison, regression threshold checks |
## Coverage Requirements
### Minimum Standards
- Overall Coverage: 85% minimum
- Critical Paths: 95% minimum (auth, payments, data mutations)
- New Code: 90% minimum
Coverage is necessary but NOT sufficient. Passing coverage does not replace situational verification.
## Requirements-to-Evidence Mapping (Mandatory)
Before completion, map each acceptance criterion to concrete evidence.
Acceptance criteria MUST come from the active PRD.
Template:
```markdown
| Acceptance Criterion | Verification Method | Evidence |
|---|---|---|
| AC-1: ... | Situational test / baseline test / manual verification | command + result |
| AC-2: ... | ... | ... |
```
## Test Quality Rules
1. Test behavior and outcomes, not private implementation details.
2. Include failure-path and edge-case assertions for changed behavior.
3. Keep tests deterministic; no new flaky tests.
4. Keep tests isolated; no dependency on execution order.
## Anti-Gaming Rules
1. Do NOT stop at "tests pass" if acceptance criteria are not verified.
2. Do NOT write narrow tests that only satisfy assertions while missing real workflow behavior.
3. Do NOT claim completion without situational evidence for impacted surfaces.
## Reporting
QA report MUST include:
1. baseline tests run and outcomes
2. situational tests run and outcomes
3. TDD usage decision (required/applied or optional/skipped with rationale)
4. acceptance-criteria-to-evidence mapping
5. coverage results
6. residual risk notes
## Before Completing
1. Baseline tests pass.
2. Required situational tests pass.
3. TDD obligations met for required change types.
4. Acceptance criteria mapped to evidence.
5. No flaky tests introduced.
6. CI pipeline passes (if available).
7. Scratchpad updated with results.

View File

@@ -11,6 +11,44 @@ Based on Google TypeScript Style Guide with stricter enforcement.
1. **Explicit over implicit** — Always declare types, never rely on inference for public APIs 1. **Explicit over implicit** — Always declare types, never rely on inference for public APIs
2. **Specific over generic** — Use the narrowest type that works 2. **Specific over generic** — Use the narrowest type that works
3. **Safe over convenient** — Type safety is not negotiable 3. **Safe over convenient** — Type safety is not negotiable
4. **Contract-first boundaries** — Cross-module and API payloads MUST use dedicated DTO files
---
## DTO Contract (MANDATORY)
DTO files are REQUIRED for TypeScript module boundaries to preserve shared context and consistency.
Hard requirements:
1. Input and output payloads crossing module boundaries MUST be defined in `*.dto.ts` files.
2. Controller/service boundary payloads MUST use DTO types; inline object literal types are NOT allowed.
3. Public API request/response contracts MUST use DTO files and remain stable across modules.
4. Shared DTOs used by multiple modules MUST live in a shared location (for example `src/shared/dto/` or `packages/shared/dto/`).
5. ORM/entity models MUST NOT be exposed directly across module boundaries; map them to DTOs.
6. DTO changes MUST be reflected in tests and documentation when contracts change.
```typescript
// ❌ WRONG: inline payload contract at boundary
export function createUser(payload: { email: string; role: string }): Promise<User> { }
// ✅ CORRECT: dedicated DTO file contract
// user-create.dto.ts
export interface UserCreateDto {
email: string;
role: UserRole;
}
// user-response.dto.ts
export interface UserResponseDto {
id: string;
email: string;
role: UserRole;
}
// service.ts
export function createUser(payload: UserCreateDto): Promise<UserResponseDto> { }
```
--- ---

View File

@@ -1,338 +0,0 @@
# Project Bootstrap Guide
> Load this guide when setting up a new project for AI-assisted development.
## Overview
This guide covers how to bootstrap a project so AI agents (Claude, Codex, etc.) can work on it effectively. Proper bootstrapping ensures:
1. Agents understand the project structure and conventions
2. Orchestration works correctly with quality gates
3. Independent code review and security review are configured
4. Issue tracking is consistent across projects
## Quick Start
```bash
# Automated bootstrap (recommended)
~/.config/mosaic/rails/bootstrap/init-project.sh \
--name "my-project" \
--type "nestjs-nextjs" \
--repo "https://git.mosaicstack.dev/owner/repo"
# Or manually using templates
export PROJECT_NAME="My Project"
export PROJECT_DESCRIPTION="What this project does"
export TASK_PREFIX="MP"
envsubst < ~/.config/mosaic/templates/agent/CLAUDE.md.template > CLAUDE.md
envsubst < ~/.config/mosaic/templates/agent/AGENTS.md.template > AGENTS.md
```
---
## Step 1: Detect Project Type
Check what files exist in the project root to determine the type:
| File Present | Project Type | Template |
|---|---|---|
| `package.json` + `pnpm-workspace.yaml` + NestJS+Next.js | NestJS + Next.js Monorepo | `projects/nestjs-nextjs/` |
| `pyproject.toml` + `manage.py` | Django | `projects/django/` |
| `pyproject.toml` (no Django) | Python (generic) | Generic template |
| `package.json` (no monorepo) | Node.js (generic) | Generic template |
| Other | Generic | Generic template |
```bash
# Auto-detect project type
detect_project_type() {
if [[ -f "pnpm-workspace.yaml" ]] && [[ -f "turbo.json" ]]; then
# Check for NestJS + Next.js
if grep -q "nestjs" package.json 2>/dev/null && grep -q "next" package.json 2>/dev/null; then
echo "nestjs-nextjs"
return
fi
fi
if [[ -f "manage.py" ]] && [[ -f "pyproject.toml" ]]; then
echo "django"
return
fi
if [[ -f "pyproject.toml" ]]; then
echo "python"
return
fi
if [[ -f "package.json" ]]; then
echo "nodejs"
return
fi
echo "generic"
}
```
---
## Step 2: Create CLAUDE.md
The `CLAUDE.md` file is the primary configuration file for AI agents. It tells them everything they need to know about the project.
### Using a Tech-Stack Template
```bash
# Set variables
export PROJECT_NAME="My Project"
export PROJECT_DESCRIPTION="Multi-tenant SaaS platform"
export PROJECT_DIR="my-project"
export REPO_URL="https://git.mosaicstack.dev/owner/repo"
export TASK_PREFIX="MP"
# Use tech-stack-specific template if available
TYPE=$(detect_project_type)
TEMPLATE_DIR="$HOME/.config/mosaic/templates/agent/projects/$TYPE"
if [[ -d "$TEMPLATE_DIR" ]]; then
envsubst < "$TEMPLATE_DIR/CLAUDE.md.template" > CLAUDE.md
else
envsubst < "$HOME/.config/mosaic/templates/agent/CLAUDE.md.template" > CLAUDE.md
fi
```
### Using the Generic Template
```bash
# Set all required variables
export PROJECT_NAME="My Project"
export PROJECT_DESCRIPTION="What this project does"
export REPO_URL="https://git.mosaicstack.dev/owner/repo"
export PROJECT_DIR="my-project"
export SOURCE_DIR="src"
export CONFIG_FILES="pyproject.toml / package.json"
export FRONTEND_STACK="N/A"
export BACKEND_STACK="Python / FastAPI"
export DATABASE_STACK="PostgreSQL"
export TESTING_STACK="pytest"
export DEPLOYMENT_STACK="Docker"
export BUILD_COMMAND="pip install -e ."
export TEST_COMMAND="pytest tests/"
export LINT_COMMAND="ruff check ."
export TYPECHECK_COMMAND="mypy ."
export QUALITY_GATES="ruff check . && mypy . && pytest tests/"
envsubst < ~/.config/mosaic/templates/agent/CLAUDE.md.template > CLAUDE.md
```
### Required Sections
Every CLAUDE.md should contain:
1. **Project description** — One-line summary
2. **Conditional documentation loading** — Table of guides
3. **Technology stack** — What's used
4. **Repository structure** — Directory tree
5. **Development workflow** — Branch strategy, build, test
6. **Quality gates** — Commands that must pass
7. **Issue tracking** — Commit format, labels
8. **Code review** — Codex and fallback review commands
9. **Secrets management** — How secrets are handled
---
## Step 3: Create AGENTS.md
The `AGENTS.md` file contains agent-specific patterns, gotchas, and orchestrator integration details.
```bash
TYPE=$(detect_project_type)
TEMPLATE_DIR="$HOME/.config/mosaic/templates/agent/projects/$TYPE"
if [[ -d "$TEMPLATE_DIR" ]]; then
envsubst < "$TEMPLATE_DIR/AGENTS.md.template" > AGENTS.md
else
envsubst < "$HOME/.config/mosaic/templates/agent/AGENTS.md.template" > AGENTS.md
fi
```
### Living Document
AGENTS.md is a **living document**. Agents should update it when they discover:
- Reusable patterns (how similar features are built)
- Non-obvious requirements (e.g., "frontend env vars need NEXT_PUBLIC_ prefix")
- Common gotchas (e.g., "run migrations after schema changes")
- Testing approaches specific to this project
---
## Step 4: Create Directory Structure
```bash
# Create standard directories
mkdir -p docs/scratchpads
mkdir -p docs/templates
mkdir -p docs/reports
```
---
## Step 5: Initialize Repository Labels & Milestones
```bash
# Use the init script
~/.config/mosaic/rails/bootstrap/init-repo-labels.sh
# Or manually create standard labels
~/.config/mosaic/rails/git/issue-create.sh # (labels are created on first use)
```
### Standard Labels
| Label | Color | Purpose |
|-------|-------|---------|
| `epic` | `#3E4B9E` | Large feature spanning multiple issues |
| `feature` | `#0E8A16` | New functionality |
| `bug` | `#D73A4A` | Defect fix |
| `task` | `#0075CA` | General work item |
| `documentation` | `#0075CA` | Documentation updates |
| `security` | `#B60205` | Security-related |
| `breaking` | `#D93F0B` | Breaking change |
### Initial Milestone
Create the first milestone for MVP:
```bash
~/.config/mosaic/rails/git/milestone-create.sh -t "0.1.0" -d "MVP - Minimum Viable Product"
```
---
## Step 6: Set Up CI/CD Review Pipeline
### Woodpecker CI
```bash
# Copy Codex review pipeline
mkdir -p .woodpecker/schemas
cp ~/.config/mosaic/rails/codex/woodpecker/codex-review.yml .woodpecker/
cp ~/.config/mosaic/rails/codex/schemas/*.json .woodpecker/schemas/
# Add codex_api_key secret to Woodpecker CI dashboard
```
### GitHub Actions
For GitHub repos, use the official Codex GitHub Action instead:
```yaml
# .github/workflows/codex-review.yml
uses: openai/codex-action@v1
```
---
## Step 7: Verify Bootstrap
After bootstrapping, verify everything works:
```bash
# Check files exist
ls CLAUDE.md AGENTS.md docs/scratchpads/
# Verify CLAUDE.md has required sections
grep -c "Quality Gates" CLAUDE.md
grep -c "Technology Stack" CLAUDE.md
grep -c "Code Review" CLAUDE.md
# Verify quality gates run
eval "$(grep -A1 'Quality Gates' CLAUDE.md | tail -1)"
# Test Codex review (if configured)
~/.config/mosaic/rails/codex/codex-code-review.sh --help
```
---
## Available Templates
### Generic Templates
| Template | Path | Purpose |
|----------|------|---------|
| `CLAUDE.md.template` | `~/.config/mosaic/templates/agent/` | Generic project CLAUDE.md |
| `AGENTS.md.template` | `~/.config/mosaic/templates/agent/` | Generic agent context |
### Tech-Stack Templates
| Stack | Path | Includes |
|-------|------|----------|
| NestJS + Next.js | `~/.config/mosaic/templates/agent/projects/nestjs-nextjs/` | CLAUDE.md, AGENTS.md |
| Django | `~/.config/mosaic/templates/agent/projects/django/` | CLAUDE.md, AGENTS.md |
### Orchestrator Templates
| Template | Path | Purpose |
|----------|------|---------|
| `tasks.md.template` | `~/src/jarvis-brain/docs/templates/orchestrator/` | Task tracking |
| `orchestrator-learnings.json.template` | `~/src/jarvis-brain/docs/templates/orchestrator/` | Variance tracking |
| `phase-issue-body.md.template` | `~/src/jarvis-brain/docs/templates/orchestrator/` | Gitea issue body |
| `scratchpad.md.template` | `~/src/jarvis-brain/docs/templates/` | Per-task working doc |
### Variables Reference
| Variable | Description | Example |
|----------|-------------|---------|
| `${PROJECT_NAME}` | Human-readable project name | "Mosaic Stack" |
| `${PROJECT_DESCRIPTION}` | One-line description | "Multi-tenant platform" |
| `${PROJECT_DIR}` | Directory name | "mosaic-stack" |
| `${PROJECT_SLUG}` | Python package slug | "mosaic_stack" |
| `${REPO_URL}` | Git remote URL | "https://git.mosaicstack.dev/mosaic/stack" |
| `${TASK_PREFIX}` | Orchestrator task prefix | "MS" |
| `${SOURCE_DIR}` | Source code directory | "src" or "apps" |
| `${QUALITY_GATES}` | Quality gate commands | "pnpm typecheck && pnpm lint && pnpm test" |
| `${BUILD_COMMAND}` | Build command | "pnpm build" |
| `${TEST_COMMAND}` | Test command | "pnpm test" |
| `${LINT_COMMAND}` | Lint command | "pnpm lint" |
| `${TYPECHECK_COMMAND}` | Type check command | "pnpm typecheck" |
| `${FRONTEND_STACK}` | Frontend technologies | "Next.js + React" |
| `${BACKEND_STACK}` | Backend technologies | "NestJS + Prisma" |
| `${DATABASE_STACK}` | Database technologies | "PostgreSQL" |
| `${TESTING_STACK}` | Testing technologies | "Vitest + Playwright" |
| `${DEPLOYMENT_STACK}` | Deployment technologies | "Docker" |
| `${CONFIG_FILES}` | Key config files | "package.json, tsconfig.json" |
---
## Bootstrap Scripts
### init-project.sh
Full project bootstrap with interactive and flag-based modes:
```bash
~/.config/mosaic/rails/bootstrap/init-project.sh \
--name "My Project" \
--type "nestjs-nextjs" \
--repo "https://git.mosaicstack.dev/owner/repo" \
--prefix "MP" \
--description "Multi-tenant platform"
```
### init-repo-labels.sh
Initialize standard labels and MVP milestone:
```bash
~/.config/mosaic/rails/bootstrap/init-repo-labels.sh
```
---
## Checklist
After bootstrapping, verify:
- [ ] `CLAUDE.md` exists with all required sections
- [ ] `AGENTS.md` exists with patterns and quality gates
- [ ] `docs/scratchpads/` directory exists
- [ ] Git labels created (epic, feature, bug, task, etc.)
- [ ] Initial milestone created (0.1.0 MVP)
- [ ] Quality gates run successfully
- [ ] `.env.example` exists (if project uses env vars)
- [ ] CI/CD pipeline configured (if using Woodpecker/GitHub Actions)
- [ ] Codex review scripts accessible (`~/.config/mosaic/rails/codex/`)

View File

@@ -12,7 +12,7 @@ GIT PUSH
QUALITY GATES (lint, typecheck, test, audit) QUALITY GATES (lint, typecheck, test, audit)
↓ all pass ↓ all pass
BUILD (compile all packages) BUILD (compile all packages)
↓ only on main/develop/tags ↓ only on main/tags
DOCKER BUILD & PUSH (Kaniko → Gitea Container Registry) DOCKER BUILD & PUSH (Kaniko → Gitea Container Registry)
↓ all images pushed ↓ all images pushed
PACKAGE LINKING (associate images with repository in Gitea) PACKAGE LINKING (associate images with repository in Gitea)
@@ -123,10 +123,10 @@ when:
# Top-level: run quality gates on everything # Top-level: run quality gates on everything
- event: [push, pull_request, manual] - event: [push, pull_request, manual]
# Per-step: only build Docker images on main/develop/tags # Per-step: only build Docker images on main/tags
docker-build-api: docker-build-api:
when: when:
- branch: [main, develop] - branch: [main]
event: [push, manual, tag] event: [push, manual, tag]
``` ```
@@ -150,24 +150,29 @@ docker-build-SERVICE:
from_secret: gitea_username from_secret: gitea_username
GITEA_TOKEN: GITEA_TOKEN:
from_secret: gitea_token from_secret: gitea_token
RELEASE_BASE_VERSION: ${RELEASE_BASE_VERSION}
CI_COMMIT_BRANCH: ${CI_COMMIT_BRANCH} CI_COMMIT_BRANCH: ${CI_COMMIT_BRANCH}
CI_COMMIT_TAG: ${CI_COMMIT_TAG} CI_COMMIT_TAG: ${CI_COMMIT_TAG}
CI_COMMIT_SHA: ${CI_COMMIT_SHA} CI_COMMIT_SHA: ${CI_COMMIT_SHA}
CI_PIPELINE_NUMBER: ${CI_PIPELINE_NUMBER}
commands: commands:
- *kaniko_setup - *kaniko_setup
- | - |
DESTINATIONS="--destination REGISTRY/ORG/IMAGE_NAME:${CI_COMMIT_SHA:0:8}" SHORT_SHA="${CI_COMMIT_SHA:0:8}"
BUILD_ID="${CI_PIPELINE_NUMBER:-$SHORT_SHA}"
BASE_VERSION="${RELEASE_BASE_VERSION:?RELEASE_BASE_VERSION is required (example: 0.0.1)}"
DESTINATIONS="--destination REGISTRY/ORG/IMAGE_NAME:sha-$SHORT_SHA"
if [ "$CI_COMMIT_BRANCH" = "main" ]; then if [ "$CI_COMMIT_BRANCH" = "main" ]; then
DESTINATIONS="$DESTINATIONS --destination REGISTRY/ORG/IMAGE_NAME:latest" DESTINATIONS="$DESTINATIONS --destination REGISTRY/ORG/IMAGE_NAME:v${BASE_VERSION}-rc.${BUILD_ID}"
elif [ "$CI_COMMIT_BRANCH" = "develop" ]; then DESTINATIONS="$DESTINATIONS --destination REGISTRY/ORG/IMAGE_NAME:testing"
DESTINATIONS="$DESTINATIONS --destination REGISTRY/ORG/IMAGE_NAME:dev"
fi fi
if [ -n "$CI_COMMIT_TAG" ]; then if [ -n "$CI_COMMIT_TAG" ]; then
DESTINATIONS="$DESTINATIONS --destination REGISTRY/ORG/IMAGE_NAME:$CI_COMMIT_TAG" DESTINATIONS="$DESTINATIONS --destination REGISTRY/ORG/IMAGE_NAME:$CI_COMMIT_TAG"
fi fi
/kaniko/executor --context . --dockerfile PATH/TO/Dockerfile $DESTINATIONS /kaniko/executor --context . --dockerfile PATH/TO/Dockerfile $DESTINATIONS
when: when:
- branch: [main, develop] - branch: [main]
event: [push, manual, tag] event: [push, manual, tag]
depends_on: depends_on:
- build - build
@@ -184,15 +189,69 @@ docker-build-SERVICE:
### Image Tagging Strategy ### Image Tagging Strategy
Every build produces multiple tags: Tagging MUST follow a two-layer model: immutable identity tags + mutable environment tags.
Immutable tags:
| Condition | Tag | Purpose | | Condition | Tag | Purpose |
|-----------|-----|---------| |-----------|-----|---------|
| Always | `${CI_COMMIT_SHA:0:8}` | Immutable reference to exact commit | | Always | `sha-${CI_COMMIT_SHA:0:8}` | Immutable reference to exact commit |
| `main` branch | `latest` | Current production release | | `main` branch | `v{BASE_VERSION}-rc.{BUILD_ID}` | Intermediate release candidate for the active milestone |
| `develop` branch | `dev` | Current development build |
| Git tag (e.g., `v1.0.0`) | `v1.0.0` | Semantic version release | | Git tag (e.g., `v1.0.0`) | `v1.0.0` | Semantic version release |
Mutable environment tags:
| Tag | Purpose |
|-----|---------|
| `testing` | Current candidate under situational validation |
| `staging` (optional) | Pre-production validation target |
| `prod` | Current production pointer |
Hard rules:
- Do NOT use `latest` for deployment.
- Do NOT use `dev` as the primary deployment tag.
- Deployments MUST resolve to an immutable image digest.
### Digest-First Promotion (Hard Rule)
Deploy and promote by digest, not by mutable tag:
1. Build and push candidate tags (`sha-*`, `vX.Y.Z-rc.N`, `testing`).
2. Resolve the digest from `sha-*` tag.
3. Deploy that digest to testing and run situational tests.
4. If green, promote the same digest to `staging`/`prod` tags.
5. Create final semantic release tag (`vX.Y.Z`) only at milestone completion.
Example with `crane`:
```bash
DIGEST=$(crane digest REGISTRY/ORG/IMAGE:sha-${CI_COMMIT_SHA:0:8})
crane tag REGISTRY/ORG/IMAGE@${DIGEST} testing
# after situational tests pass:
crane tag REGISTRY/ORG/IMAGE@${DIGEST} prod
```
### Deployment Strategy: Blue-Green Default
- Blue-green is the default release strategy for lights-out operation.
- Canary is OPTIONAL and allowed only when automated SLO/error-rate monitoring and rollback triggers are configured.
- If canary guardrails are missing, you MUST use blue-green.
### Image Retention and Cleanup (Hard Rule)
Registry cleanup MUST be automated (daily or weekly job).
Retention policy:
- Keep all final release tags (`vX.Y.Z`) indefinitely.
- Keep digests currently referenced by `prod` and `testing` tags.
- Keep the most recent 20 RC tags (`vX.Y.Z-rc.N`) per service.
- Delete RC and `sha-*` tags older than 30 days when they are not referenced by active environments/releases.
Before deleting any image/tag:
- Verify digest is not currently deployed.
- Verify digest is not referenced by any active release/tag notes.
- Log cleanup actions in CI job output.
### Kaniko Options ### Kaniko Options
Common flags for `/kaniko/executor`: Common flags for `/kaniko/executor`:
@@ -252,7 +311,10 @@ In `docker-compose.yml`:
```yaml ```yaml
services: services:
api: api:
image: git.example.com/org/image:${IMAGE_TAG:-dev} # Preferred: pin digest produced by CI and promoted by environment
image: git.example.com/org/image@${IMAGE_DIGEST}
# Optional channel pointer for non-prod:
# image: git.example.com/org/image:${IMAGE_TAG:-testing}
``` ```
## Package Linking ## Package Linking
@@ -315,7 +377,7 @@ link-packages:
link_package "image-name-1" link_package "image-name-1"
link_package "image-name-2" link_package "image-name-2"
when: when:
- branch: [main, develop] - branch: [main]
event: [push, manual, tag] event: [push, manual, tag]
depends_on: depends_on:
- docker-build-image-1 - docker-build-image-1
@@ -350,6 +412,12 @@ Configure these in the Woodpecker UI (Settings > Secrets) or via CLI:
| `gitea_username` | Gitea username or service account | `push`, `manual`, `tag` | | `gitea_username` | Gitea username or service account | `push`, `manual`, `tag` |
| `gitea_token` | Gitea token with `package:write` scope | `push`, `manual`, `tag` | | `gitea_token` | Gitea token with `package:write` scope | `push`, `manual`, `tag` |
### Required CI Variables (Non-Secret)
| Variable | Example | Purpose |
|----------|---------|---------|
| `RELEASE_BASE_VERSION` | `0.0.1` | Base milestone version used to generate RC tags (`v0.0.1-rc.N`) |
### Setting Secrets via CLI ### Setting Secrets via CLI
```bash ```bash
@@ -554,9 +622,9 @@ security-trivy:
mkdir -p ~/.docker mkdir -p ~/.docker
echo "{\"auths\":{\"REGISTRY\":{\"username\":\"$$GITEA_USER\",\"password\":\"$$GITEA_TOKEN\"}}}" > ~/.docker/config.json echo "{\"auths\":{\"REGISTRY\":{\"username\":\"$$GITEA_USER\",\"password\":\"$$GITEA_TOKEN\"}}}" > ~/.docker/config.json
trivy image --exit-code 1 --severity HIGH,CRITICAL --ignore-unfixed \ trivy image --exit-code 1 --severity HIGH,CRITICAL --ignore-unfixed \
REGISTRY/ORG/IMAGE:$${CI_COMMIT_SHA:0:8} REGISTRY/ORG/IMAGE:sha-$${CI_COMMIT_SHA:0:8}
when: when:
- branch: [main, develop] - branch: [main]
event: [push, manual, tag] event: [push, manual, tag]
depends_on: depends_on:
- docker-build-SERVICE - docker-build-SERVICE
@@ -574,7 +642,7 @@ Docker build MUST depend on ALL quality + security steps. Trivy runs AFTER build
## Monorepo Considerations ## Monorepo Considerations
### pnpm + Turbo (Mosaic Stack pattern) ### pnpm + Turbo
```yaml ```yaml
variables: variables:
@@ -589,7 +657,7 @@ steps:
- pnpm build # Turbo handles dependency order and caching - pnpm build # Turbo handles dependency order and caching
``` ```
### npm Workspaces (U-Connect pattern) ### npm Workspaces
```yaml ```yaml
variables: variables:
@@ -684,24 +752,28 @@ steps:
from_secret: gitea_username from_secret: gitea_username
GITEA_TOKEN: GITEA_TOKEN:
from_secret: gitea_token from_secret: gitea_token
RELEASE_BASE_VERSION: ${RELEASE_BASE_VERSION}
CI_COMMIT_BRANCH: ${CI_COMMIT_BRANCH} CI_COMMIT_BRANCH: ${CI_COMMIT_BRANCH}
CI_COMMIT_TAG: ${CI_COMMIT_TAG} CI_COMMIT_TAG: ${CI_COMMIT_TAG}
CI_COMMIT_SHA: ${CI_COMMIT_SHA} CI_COMMIT_SHA: ${CI_COMMIT_SHA}
CI_PIPELINE_NUMBER: ${CI_PIPELINE_NUMBER}
commands: commands:
- *kaniko_setup - *kaniko_setup
- | - |
DESTINATIONS="--destination git.example.com/org/api:${CI_COMMIT_SHA:0:8}" SHORT_SHA="${CI_COMMIT_SHA:0:8}"
BUILD_ID="${CI_PIPELINE_NUMBER:-$SHORT_SHA}"
BASE_VERSION="${RELEASE_BASE_VERSION:?RELEASE_BASE_VERSION is required}"
DESTINATIONS="--destination git.example.com/org/api:sha-$SHORT_SHA"
if [ "$CI_COMMIT_BRANCH" = "main" ]; then if [ "$CI_COMMIT_BRANCH" = "main" ]; then
DESTINATIONS="$DESTINATIONS --destination git.example.com/org/api:latest" DESTINATIONS="$DESTINATIONS --destination git.example.com/org/api:v${BASE_VERSION}-rc.${BUILD_ID}"
elif [ "$CI_COMMIT_BRANCH" = "develop" ]; then DESTINATIONS="$DESTINATIONS --destination git.example.com/org/api:testing"
DESTINATIONS="$DESTINATIONS --destination git.example.com/org/api:dev"
fi fi
if [ -n "$CI_COMMIT_TAG" ]; then if [ -n "$CI_COMMIT_TAG" ]; then
DESTINATIONS="$DESTINATIONS --destination git.example.com/org/api:$CI_COMMIT_TAG" DESTINATIONS="$DESTINATIONS --destination git.example.com/org/api:$CI_COMMIT_TAG"
fi fi
/kaniko/executor --context . --dockerfile src/api/Dockerfile $DESTINATIONS /kaniko/executor --context . --dockerfile src/api/Dockerfile $DESTINATIONS
when: when:
- branch: [main, develop] - branch: [main]
event: [push, manual, tag] event: [push, manual, tag]
depends_on: [build] depends_on: [build]
@@ -712,24 +784,28 @@ steps:
from_secret: gitea_username from_secret: gitea_username
GITEA_TOKEN: GITEA_TOKEN:
from_secret: gitea_token from_secret: gitea_token
RELEASE_BASE_VERSION: ${RELEASE_BASE_VERSION}
CI_COMMIT_BRANCH: ${CI_COMMIT_BRANCH} CI_COMMIT_BRANCH: ${CI_COMMIT_BRANCH}
CI_COMMIT_TAG: ${CI_COMMIT_TAG} CI_COMMIT_TAG: ${CI_COMMIT_TAG}
CI_COMMIT_SHA: ${CI_COMMIT_SHA} CI_COMMIT_SHA: ${CI_COMMIT_SHA}
CI_PIPELINE_NUMBER: ${CI_PIPELINE_NUMBER}
commands: commands:
- *kaniko_setup - *kaniko_setup
- | - |
DESTINATIONS="--destination git.example.com/org/web:${CI_COMMIT_SHA:0:8}" SHORT_SHA="${CI_COMMIT_SHA:0:8}"
BUILD_ID="${CI_PIPELINE_NUMBER:-$SHORT_SHA}"
BASE_VERSION="${RELEASE_BASE_VERSION:?RELEASE_BASE_VERSION is required}"
DESTINATIONS="--destination git.example.com/org/web:sha-$SHORT_SHA"
if [ "$CI_COMMIT_BRANCH" = "main" ]; then if [ "$CI_COMMIT_BRANCH" = "main" ]; then
DESTINATIONS="$DESTINATIONS --destination git.example.com/org/web:latest" DESTINATIONS="$DESTINATIONS --destination git.example.com/org/web:v${BASE_VERSION}-rc.${BUILD_ID}"
elif [ "$CI_COMMIT_BRANCH" = "develop" ]; then DESTINATIONS="$DESTINATIONS --destination git.example.com/org/web:testing"
DESTINATIONS="$DESTINATIONS --destination git.example.com/org/web:dev"
fi fi
if [ -n "$CI_COMMIT_TAG" ]; then if [ -n "$CI_COMMIT_TAG" ]; then
DESTINATIONS="$DESTINATIONS --destination git.example.com/org/web:$CI_COMMIT_TAG" DESTINATIONS="$DESTINATIONS --destination git.example.com/org/web:$CI_COMMIT_TAG"
fi fi
/kaniko/executor --context . --dockerfile src/web/Dockerfile $DESTINATIONS /kaniko/executor --context . --dockerfile src/web/Dockerfile $DESTINATIONS
when: when:
- branch: [main, develop] - branch: [main]
event: [push, manual, tag] event: [push, manual, tag]
depends_on: [build] depends_on: [build]
@@ -763,8 +839,8 @@ steps:
} }
link_package "api" link_package "api"
link_package "web" link_package "web"
when: when:
- branch: [main, develop] - branch: [main]
event: [push, manual, tag] event: [push, manual, tag]
depends_on: depends_on:
- docker-build-api - docker-build-api
@@ -780,49 +856,130 @@ steps:
5. **Add package linking step** after all Docker builds 5. **Add package linking step** after all Docker builds
6. **Update `docker-compose.yml`** to reference registry images instead of local builds: 6. **Update `docker-compose.yml`** to reference registry images instead of local builds:
```yaml ```yaml
image: git.example.com/org/service:${IMAGE_TAG:-dev} image: git.example.com/org/service@${IMAGE_DIGEST}
``` ```
7. **Test on develop branch first** — push a small change and verify the pipeline 7. **Test on a short-lived non-main branch first** — open a PR and verify quality gates before merging to `main`
8. **Verify images appear** in Gitea Packages tab after successful pipeline 8. **Verify images appear** in Gitea Packages tab after successful pipeline
## Post-Merge CI Monitoring (Hard Rule)
For source-code delivery, completion is not allowed at "PR opened" stage.
Required sequence:
1. Merge PR to `main` (squash) via Mosaic wrapper.
2. Monitor CI to terminal status:
```bash
~/.config/mosaic/rails/git/pr-ci-wait.sh -n <PR_NUMBER>
```
3. Require green status before claiming completion.
4. If CI fails, create remediation task(s) and continue until green.
5. If monitoring command fails, report blocker with the exact failed wrapper command and stop.
Woodpecker note:
- In Gitea + Woodpecker environments, commit status contexts generally reflect Woodpecker pipeline results.
- Always include CI run/status evidence in completion report.
## Queue Guard Before Push/Merge (Hard Rule)
Before pushing a branch or merging a PR, guard against overlapping project pipelines:
```bash
~/.config/mosaic/rails/git/ci-queue-wait.sh --purpose push -B main
~/.config/mosaic/rails/git/ci-queue-wait.sh --purpose merge -B main
```
Behavior:
- If pipeline state is running/queued/pending, wait until queue clears.
- If timeout or API/auth failure occurs, treat as `blocked`, report exact failed wrapper command, and stop.
## Gitea as Unified Platform ## Gitea as Unified Platform
Gitea provides **three services in one**, eliminating the need for separate Harbor and Verdaccio deployments: Gitea provides **multiple services in one**, eliminating the need for separate registry platforms:
| Service | What Gitea Replaces | Registry URL | | Service | What Gitea Replaces | Registry URL |
|---------|---------------------|-------------| |---------|---------------------|-------------|
| **Git hosting** | GitHub/GitLab | `https://GITEA_HOST/org/repo` | | **Git hosting** | GitHub/GitLab | `https://GITEA_HOST/org/repo` |
| **Container registry** | Harbor, Docker Hub | `docker pull GITEA_HOST/org/image:tag` | | **Container registry** | Harbor, Docker Hub | `docker pull GITEA_HOST/org/image:tag` |
| **npm registry** | Verdaccio, Artifactory | `https://GITEA_HOST/api/packages/org/npm/` | | **npm registry** | Verdaccio, Artifactory | `https://GITEA_HOST/api/packages/org/npm/` |
| **PyPI registry** | Private PyPI/Artifactory | `https://GITEA_HOST/api/packages/org/pypi` |
| **Maven registry** | Nexus, Artifactory | `https://GITEA_HOST/api/packages/org/maven` |
| **NuGet registry** | Azure Artifacts, Artifactory | `https://GITEA_HOST/api/packages/org/nuget/index.json` |
| **Cargo registry** | crates.io mirrors, Artifactory | `https://GITEA_HOST/api/packages/org/cargo` |
| **Composer registry** | Private Packagist, Artifactory | `https://GITEA_HOST/api/packages/org/composer` |
| **Conan registry** | Artifactory Conan | `https://GITEA_HOST/api/packages/org/conan` |
| **Conda registry** | Anaconda Server, Artifactory | `https://GITEA_HOST/api/packages/org/conda` |
| **Generic registry** | Generic binary stores | `https://GITEA_HOST/api/packages/org/generic` |
### Additional Package Types ### Single Token, Multiple Services
Gitea also supports PyPI, Maven, NuGet, Cargo, Composer, Conan, Conda, Generic, and more. All use the same token authentication.
### Single Token, Three Services
A Gitea token with `package:write` scope handles: A Gitea token with `package:write` scope handles:
- `git push` / `git pull` - `git push` / `git pull`
- `docker push` / `docker pull` (container registry) - `docker push` / `docker pull` (container registry)
- `npm publish` / `npm install` (npm registry) - `npm publish` / `npm install` (npm registry)
- `twine upload` / `pip install` (PyPI registry)
- package operations for Maven/NuGet/Cargo/Composer/Conan/Conda/Generic registries
This means a single `gitea_token` secret in Woodpecker CI covers all CI/CD operations. This means a single `gitea_token` secret in Woodpecker CI covers all CI/CD package operations.
## Python Packages on Gitea PyPI
For Python libraries and internal packages, use Gitea's built-in PyPI registry.
### Publish (Local or CI)
```bash
python -m pip install --upgrade build twine
python -m build
python -m twine upload \
--repository-url "https://GITEA_HOST/api/packages/ORG/pypi" \
--username "$GITEA_USERNAME" \
--password "$GITEA_TOKEN" \
dist/*
```
### Install (Consumer Projects)
```bash
pip install \
--extra-index-url "https://$GITEA_USERNAME:$GITEA_TOKEN@GITEA_HOST/api/packages/ORG/pypi/simple" \
your-package-name
```
### Woodpecker Step (Python Publish)
```yaml
publish-python-package:
image: python:3.12-slim
environment:
GITEA_USERNAME:
from_secret: gitea_username
GITEA_TOKEN:
from_secret: gitea_token
commands:
- python -m pip install --upgrade build twine
- python -m build
- python -m twine upload --repository-url https://GITEA_HOST/api/packages/ORG/pypi --username "$$GITEA_USERNAME" --password "$$GITEA_TOKEN" dist/*
when:
branch: [main]
event: [push]
```
### Architecture Simplification ### Architecture Simplification
**Before (3 services):** **Before (4 services):**
``` ```
Gitea (git) + Harbor (containers) + Verdaccio (npm) Gitea (git) + Harbor (containers) + Verdaccio (npm) + Private PyPI
↓ separate auth ↓ separate auth ↓ OAuth/Authentik ↓ separate auth ↓ separate auth ↓ extra auth ↓ extra auth
3 tokens 1 robot account 1 OIDC integration multiple tokens robot/service users npm-specific token pip/twine token
3 backup targets complex RBAC group-based access fragmented access fragmented RBAC fragmented RBAC fragmented RBAC
``` ```
**After (1 service):** **After (1 service):**
``` ```
Gitea (git + containers + npm) Gitea (git + containers + npm + pypi)
single token unified secrets
1 secret in Woodpecker 1 credentials model in CI
1 backup target 1 backup target
unified RBAC via Gitea teams unified RBAC via Gitea teams
``` ```
@@ -900,5 +1057,5 @@ If a project currently uses Verdaccio (e.g., U-Connect at `npm.uscllc.net`), fol
- Link manually: Gitea UI > Packages > Select package > Link to repository - Link manually: Gitea UI > Packages > Select package > Link to repository
### Pipeline runs Docker builds on pull requests ### Pipeline runs Docker builds on pull requests
- Verify `when` clause on Docker build steps restricts to `branch: [main, develop]` - Verify `when` clause on Docker build steps restricts to `branch: [main]`
- Pull requests should only run quality gates, not build/push images - Pull requests should only run quality gates, not build/push images

203
guides/e2e-delivery.md Normal file
View File

@@ -0,0 +1,203 @@
# E2E Delivery Procedure (MANDATORY)
This guide is REQUIRED for all agent sessions.
## 0. Mode Handshake (Before Any Action)
First response MUST declare mode before tool calls or implementation steps:
1. Orchestration mission: `Now initiating Orchestrator mode...`
2. Implementation mission: `Now initiating Delivery mode...`
3. Review-only mission: `Now initiating Review mode...`
## 1. PRD Gate (Before Coding)
1. Ensure `docs/PRD.md` or `docs/PRD.json` exists before coding.
2. Load `~/.config/mosaic/guides/PRD.md`.
3. Prepare/update PRD from user input and available project context.
4. If requirements are missing:
- proceed with best-guess assumptions by default,
- mark each assumption with `ASSUMPTION:` and rationale,
- escalate only when uncertainty is high-impact and cannot be bounded safely.
5. Treat PRD as the requirement source for implementation, testing, and review.
## 1a. Tracking Gate (Before Coding)
1. For non-trivial work, `docs/TASKS.md` MUST exist before coding.
2. If `docs/TASKS.md` is missing, create it from `~/.config/mosaic/templates/docs/TASKS.md.template`.
3. Detect provider first via `~/.config/mosaic/rails/git/detect-platform.sh`.
4. For issue/PR/milestone operations, use Mosaic wrappers first (`~/.config/mosaic/rails/git/*.sh`).
5. If external git provider is available (Gitea/GitHub/GitLab), create or update issue(s) before coding.
6. Record provider issue reference(s) in `docs/TASKS.md` (example: `#123`).
7. If no external provider is available, use internal task refs in `docs/TASKS.md` (example: `TASKS:T1`).
8. Scratchpad MUST reference both task ID and issue/internal ref.
## 2. Intake and Scope
1. Define scope, constraints, and acceptance criteria.
2. Identify affected surfaces (API, DB, UI, infra, auth, CI/CD, docs).
3. Identify required guides and load them before implementation.
4. For code/API/auth/infra changes, load `~/.config/mosaic/guides/DOCUMENTATION.md`.
5. Determine budget constraints:
- if the user provided a plan limit or token budget, treat it as a HARD cap,
- if budget is unknown, derive a working budget from estimates and runtime limits, then continue autonomously.
6. Record budget assumptions and caps in the scratchpad before implementation starts.
7. Track estimated vs used tokens per logical unit and adapt strategy to remain inside budget.
8. If projected usage exceeds budget, auto-reduce scope/parallelism first; escalate only if cap still cannot be met.
## 2a. Steered Autonomy (Lights-Out)
1. Agent owns delivery end-to-end: planning, coding, testing, review, PR/repo operations, release/tag, and deployment (when in scope).
2. Human intervention is escalation-only; do not pause for routine approvals or handoffs.
3. Continue execution until completion criteria are met or an escalation trigger is hit.
## 3. Scratchpad Requirement
1. Create a task-specific scratchpad before implementation.
2. Record:
- objective
- plan
- progress checkpoints
- tests run
- risks/blockers
- final verification evidence
## 4. Embedded Execution Cycle (MANDATORY)
For implementation work, you MUST run this cycle in order:
1. `plan` - map PRD requirements to concrete implementation steps.
2. `code` - implement one logical unit.
3. `test` - run required baseline and situational checks for that unit.
4. `review` - perform independent code review on the current delta.
5. `remediate` - fix all findings and any test failures.
6. `review` - re-review remediated changes until blockers are cleared.
7. `commit` - commit only when the logical unit passes tests and review.
8. `pre-push queue guard` - before pushing, wait for running/queued project pipelines to clear: `~/.config/mosaic/rails/git/ci-queue-wait.sh --purpose push`.
9. `push` - push immediately after queue guard passes.
10. `PR integration` - if external git provider is available, create/update PR to `main` and merge with required strategy via Mosaic wrappers.
11. `pre-merge queue guard` - before merging PR, wait for running/queued project pipelines to clear: `~/.config/mosaic/rails/git/ci-queue-wait.sh --purpose merge`.
12. `CI/pipeline verification` - wait for terminal CI status and require green before completion (`~/.config/mosaic/rails/git/pr-ci-wait.sh` for PR-based workflow).
13. `issue closure` - close linked external issue (or close internal `docs/TASKS.md` task ref when provider is unavailable).
14. `greenfield situational test` - validate required user flows in a clean environment/startup path (post-merge for trunk workflow changes).
15. `deploy + post-deploy validation` - when deployment is in scope, deploy to configured target and run post-deploy health/smoke checks.
16. `repeat` - continue until all acceptance criteria are complete.
### Post-PR Hard Gate (Execute Sequentially, No Exceptions)
1. `~/.config/mosaic/rails/git/ci-queue-wait.sh --purpose merge -B main`
2. `~/.config/mosaic/rails/git/pr-merge.sh -n <PR_NUMBER> -m squash`
3. `~/.config/mosaic/rails/git/pr-ci-wait.sh -n <PR_NUMBER>`
4. `~/.config/mosaic/rails/git/issue-close.sh -i <ISSUE_NUMBER>` (or close internal `docs/TASKS.md` ref when no provider exists)
5. If any step fails: set status `blocked`, report the exact failed wrapper command, and stop.
6. Do not ask the human to perform routine merge/close operations.
7. Do not claim completion before step 4 succeeds.
### Forbidden Anti-Patterns
1. Do NOT stop at "PR created" or "PR updated".
2. Do NOT ask "should I merge?" for routine delivery PRs.
3. Do NOT ask "should I close the issue?" after merge + green CI.
If any step fails, you MUST remediate and re-run from the relevant step before proceeding.
If push-queue/merge-queue/PR merge/CI/issue closure fails, status is `blocked` (not complete) and you MUST report the exact failed wrapper command.
## 5. Testing Priority Model
Use this order of priority:
1. Situational tests are the PRIMARY gate and MUST prove changed behavior meets requirements.
2. Baseline tests are REQUIRED safety checks and MUST run for all software changes.
3. TDD is risk-based and REQUIRED only for specific high-risk change types.
## 6. Mandatory Test Baseline
For all software changes, you MUST run baseline checks applicable to the repo/toolchain:
1. lint (or equivalent static checks)
2. type checks (if language/tooling supports it)
3. unit tests for changed logic
4. integration tests for changed boundaries
## 7. Situational Testing Matrix (PRIMARY GATE)
Run additional tests based on what changed:
| Change Surface | Required Situational Tests |
|---|---|
| Authentication/authorization | auth failure-path tests, permission boundary tests, token/session validation |
| Database schema/migrations | migration up/down validation, rollback safety, data integrity checks |
| API contract changes | backward compatibility checks, consumer-impact tests, contract tests |
| Frontend/UI workflow changes | end-to-end flow tests, accessibility sanity checks, state transition checks |
| CI/CD or deployment changes | pipeline execution validation, artifact integrity checks, rollback path check |
| Security-sensitive logic | abuse-case tests, input validation fuzzing/sanitization checks |
| Performance-critical path | baseline comparison, regression threshold checks |
## 8. Risk-Based TDD Requirement
TDD is REQUIRED for:
1. bug fixes (write a reproducer test first)
2. security/auth/permission logic changes
3. critical business logic and data-mutation rules
TDD is RECOMMENDED (not mandatory) for low-risk UI, copy, styling, and mechanical refactors.
If TDD is skipped for a non-required case, record the rationale in the scratchpad.
## 9. Mandatory Code Review Gate
If you modify source code, you MUST run an independent code review before completion.
1. Use automated review tooling when available.
2. If automated tooling is unavailable, run manual review using `~/.config/mosaic/guides/CODE-REVIEW.md`.
3. Any blocker or critical finding MUST be fixed or tracked as an explicit remediation task before closure.
## 10. Mandatory Documentation Gate
For code/API/auth/infra changes, documentation updates are REQUIRED before completion.
1. Apply the standard in `~/.config/mosaic/guides/DOCUMENTATION.md`.
2. Update required docs in the same logical change set as implementation.
3. Complete `~/.config/mosaic/templates/docs/DOCUMENTATION-CHECKLIST.md`.
4. If publish platform is unspecified, ask the user to choose in-app or external platform before publishing.
5. Missing required documentation is a BLOCKER.
## 11. Completion Gate (All Required)
You MUST satisfy all items before completion:
1. Acceptance criteria met.
2. Baseline tests passed.
3. Situational tests passed (primary gate), including required greenfield situational validation.
4. PRD is current and implementation is aligned with PRD.
5. Acceptance criteria mapped to verification evidence.
6. Code review completed for source code changes.
7. Required documentation updates completed and reviewed.
8. Scratchpad updated with evidence.
9. Known risks documented.
10. No unresolved blocker hidden.
11. If deployment is in scope, deployment target, release version, and post-deploy verification evidence are documented.
12. `docs/TASKS.md` status and issue/internal references are updated to match delivered work.
13. If source code changed and external provider is available: PR merged to `main` (squash), with merge evidence recorded.
14. CI/pipeline status is terminal green for the merged PR/head commit.
15. Linked external issue is closed (or internal task ref is closed when no provider exists).
16. If any of items 13-15 fail due access/tooling, report `blocked` with exact failed wrapper command and do not claim completion.
## 12. Review and Reporting
Completion report MUST include:
1. what changed
2. PRD alignment summary
3. acceptance criteria to evidence mapping
4. what was tested (baseline + situational)
5. what was reviewed (code review scope)
6. what documentation was updated
7. command-level evidence summary
8. residual risks
9. deployment and post-deploy verification summary (if in scope)
10. explicit pass/fail status
11. tracking summary (`docs/TASKS.md` updates and issue/internal refs)
12. PR lifecycle summary (PR number, merge commit, merge method)
13. CI/pipeline summary (run/check URL, terminal status)
14. issue closure summary (issue number/ref and close evidence)

View File

@@ -1,18 +1,47 @@
# Autonomous Orchestrator Guide # Autonomous Orchestrator Guide
> Load this guide when orchestrating autonomous task completion across any project. When spawning workers, include skill loading in the kickstart:
```bash
claude -p "Read ~/.config/mosaic/skills/nestjs-best-practices/SKILL.md then implement..."codex exec "Read ~/.config/mosaic/skills/nestjs-best-practices/SKILL.md then implement..."
```
#### **MANDATORY**
- You MUST establish the requirements for a task, or series of tasks, before coding begins.
- You MUST ensure `docs/PRD.md` or `docs/PRD.json` exists before worker coding starts.
- You MUST use sequential-thinking to properly plan out tasks, milestones, epics, and PRD requirements prior to orchestrating agents.
- You MUST track tasks at the project level in docs/TASKS.md.
- You MUST keep the TASKS.md file updated with agent and tasks statuses.
- You MUST keep `docs/` root clean. Reports and working artifacts MUST be stored in scoped folders (`docs/reports/`, `docs/tasks/`, `docs/releases/`, `docs/scratchpads/`).
- You MUST enforce plan/token usage budgets when provided, and adapt orchestration strategy to remain within limits.
- You MUST enforce trunk workflow: workers branch from `main`, PR target is `main`, direct push to `main` is forbidden, and PR merges to `main` are squash-only.
- You MUST operate in steered-autonomy mode: human intervention is escalation-only; do not require the human to write code, review code, or manage PR/repo workflow.
- You MUST NOT declare task or issue completion until PR is merged, CI/pipeline is terminal green, and linked issue is closed (or internal TASKS ref is closed when provider is unavailable).
- Mosaic orchestration rules OVERRIDE runtime-default caution for routine push/merge/issue-close actions required by this workflow.
- Do NOT ask "should I merge?" or "should I close the issue?" for routine delivery flow after gates pass.
## Overview ## Overview
The orchestrator **cold-starts** on any project with just a review report location and minimal kickstart. It autonomously: ## Session Start Handshake (Hard Rule)
1. Parses review reports to extract findings
2. Categorizes findings into phases by severity
3. Estimates token usage per task
4. Creates Gitea issues (phase-level)
5. Bootstraps `docs/tasks.md` from scratch
6. Coordinates completion using worker agents
**Key principle:** The orchestrator is the **sole writer** of `docs/tasks.md`. Worker agents execute tasks and report results — they never modify the tracking file. Before any orchestration actions, the first response MUST be:
`Now initiating Orchestrator mode...`
Then proceed with orchestration bootstrap steps.
The orchestrator **cold-starts** on any project with just a review report location and minimal kickstart. It autonomously:
1. Prepares/updates project PRD (`docs/PRD.md` or `docs/PRD.json`) from user input and available project context
2. Parses review reports to extract findings
3. Categorizes findings into phases by severity
4. Estimates token usage per task
5. Creates phase issues in the configured git provider (Gitea/GitHub/GitLab)
6. Bootstraps `docs/TASKS.md` from scratch
7. Coordinates completion using worker agents
8. Enforces documentation completion gates for code/API/auth/infra changes
**Key principle:** The orchestrator is the **sole writer** of `docs/TASKS.md`. Worker agents execute tasks and report results — they never modify the tracking file.
--- ---
@@ -25,8 +54,8 @@ The orchestrator **cold-starts** on any project with just a review report locati
- "Quickly fixes" something to save time — this is how drift starts - "Quickly fixes" something to save time — this is how drift starts
**The orchestrator ONLY:** **The orchestrator ONLY:**
- Reads/writes `docs/tasks.md` - Reads/writes `docs/TASKS.md`
- Reads/writes `docs/orchestrator-learnings.json` - Reads/writes `docs/tasks/orchestrator-learnings.json`
- Delegates ALL code changes to workers (native subagent tool when available, otherwise Mosaic matrix rail) - Delegates ALL code changes to workers (native subagent tool when available, otherwise Mosaic matrix rail)
- Parses worker JSON results - Parses worker JSON results
- Commits task tracking updates (tasks.md, learnings) - Commits task tracking updates (tasks.md, learnings)
@@ -56,7 +85,7 @@ Matrix rail mode commands:
~/.config/mosaic/bin/mosaic-orchestrator-drain ~/.config/mosaic/bin/mosaic-orchestrator-drain
``` ```
In Matrix rail mode, keep `docs/tasks.md` as canonical project tracking and use In Matrix rail mode, keep `docs/TASKS.md` as canonical project tracking and use
`.mosaic/orchestrator/` for deterministic worker dispatch state. `.mosaic/orchestrator/` for deterministic worker dispatch state.
--- ---
@@ -68,7 +97,7 @@ Use templates from `jarvis-brain/docs/templates/` to scaffold tracking files:
```bash ```bash
# Set environment variables # Set environment variables
export PROJECT="project-name" export PROJECT="project-name"
export MILESTONE="M1-Feature" export MILESTONE="0.0.1"
export CURRENT_DATETIME=$(date -Iseconds) export CURRENT_DATETIME=$(date -Iseconds)
export TASK_PREFIX="PR-SEC" export TASK_PREFIX="PR-SEC"
export PHASE_ISSUE="#1" export PHASE_ISSUE="#1"
@@ -77,23 +106,41 @@ export PHASE_BRANCH="fix/security"
# Copy templates # Copy templates
TEMPLATES=~/src/jarvis-brain/docs/templates TEMPLATES=~/src/jarvis-brain/docs/templates
# Create tasks.md (then populate with findings) # Create PRD if missing (before coding begins)
envsubst < $TEMPLATES/orchestrator/tasks.md.template > docs/tasks.md [[ -f docs/PRD.md || -f docs/PRD.json ]] || cp ~/.config/mosaic/templates/docs/PRD.md.template docs/PRD.md
# Create TASKS.md (then populate with findings)
envsubst < $TEMPLATES/orchestrator/tasks.md.template > docs/TASKS.md
# Create learnings tracking # Create learnings tracking
envsubst < $TEMPLATES/orchestrator/orchestrator-learnings.json.template > docs/orchestrator-learnings.json mkdir -p docs/tasks docs/reports/deferred
envsubst < $TEMPLATES/orchestrator/orchestrator-learnings.json.template > docs/tasks/orchestrator-learnings.json
# Create review report structure (if doing new review) # Create review report structure (if doing new review)
$TEMPLATES/reports/review-report-scaffold.sh codebase-review $TEMPLATES/reports/review-report-scaffold.sh codebase-review
``` ```
Milestone versioning (HARD RULE):
- Pre-MVP milestones MUST start at `0.0.1`.
- Pre-MVP progression MUST remain in `0.0.x` (`0.0.2`, `0.0.3`, ...).
- `0.1.0` is reserved for MVP release.
- You MUST NOT start pre-MVP planning at `0.1.0`.
Branch and merge strategy (HARD RULE):
- Workers use short-lived task branches from `origin/main`.
- Worker task branches merge back via PR to `main` only.
- Direct pushes to `main` are prohibited.
- PR merges to `main` MUST use squash merge.
**Available templates:** **Available templates:**
| Template | Purpose | | Template | Purpose |
|----------|---------| |----------|---------|
| `orchestrator/tasks.md.template` | Task tracking table with schema | | `orchestrator/tasks.md.template` | Task tracking table with schema |
| `orchestrator/orchestrator-learnings.json.template` | Variance tracking | | `orchestrator/orchestrator-learnings.json.template` | Variance tracking |
| `orchestrator/phase-issue-body.md.template` | Gitea issue body | | `orchestrator/phase-issue-body.md.template` | Git provider issue body |
| `orchestrator/compaction-summary.md.template` | 60% checkpoint format | | `orchestrator/compaction-summary.md.template` | 60% checkpoint format |
| `reports/review-report-scaffold.sh` | Creates report directory | | `reports/review-report-scaffold.sh` | Creates report directory |
| `scratchpad.md.template` | Per-task working document | | `scratchpad.md.template` | Per-task working document |
@@ -104,6 +151,16 @@ See `jarvis-brain/docs/templates/README.md` for full documentation.
## Phase 1: Bootstrap ## Phase 1: Bootstrap
### Step 0: Prepare PRD (Required Before Coding)
Before creating tasks or spawning workers:
1. Ensure `docs/PRD.md` or `docs/PRD.json` exists.
2. Build/update PRD from user input and available project context.
3. If requirements are missing, proceed with best-guess assumptions by default and mark each guessed requirement with `ASSUMPTION:` in PRD.
4. Escalate only when uncertainty is high-impact and cannot be safely bounded with rollback-ready defaults.
5. Do NOT start worker coding tasks until this step is complete.
### Step 1: Parse Review Reports ### Step 1: Parse Review Reports
Review reports typically follow this structure: Review reports typically follow this structure:
@@ -169,6 +226,24 @@ Use these heuristics based on task type:
- Test requirements (+5-10K if tests needed) - Test requirements (+5-10K if tests needed)
- Documentation needs (+2-3K if docs needed) - Documentation needs (+2-3K if docs needed)
### Step 3b: Budget Guardrail (HARD RULE)
Before creating dependencies or dispatching workers:
1. Determine budget cap:
- Use explicit user plan/token cap if provided.
- If no cap is provided, derive a soft cap from estimates and runtime constraints, then continue autonomously.
2. Calculate projected total from `estimate` column and record cap in task notes/scratchpad.
3. Apply dispatch mode by budget pressure:
- `<70%` of cap projected: normal orchestration (up to 2 workers).
- `70-90%` of cap projected: conservative mode (1 worker, tighter scope, no exploratory tasks).
- `>90%` of cap projected: freeze new worker starts; triage remaining work with user.
4. If projected usage exceeds cap, first reduce scope/parallelism automatically.
If cap still cannot be met, STOP and ask user to:
- reduce scope, or
- split into phases, or
- approve a higher budget.
### Step 4: Determine Dependencies ### Step 4: Determine Dependencies
**Automatic dependency rules:** **Automatic dependency rules:**
@@ -183,9 +258,18 @@ Use these heuristics based on task type:
- `{PREFIX}-CQ-{LAST}`: Phase 3 verification - `{PREFIX}-CQ-{LAST}`: Phase 3 verification
- `{PREFIX}-TEST-{LAST}`: Phase 4 verification (final quality gates) - `{PREFIX}-TEST-{LAST}`: Phase 4 verification (final quality gates)
### Step 5: Create Gitea Issues (Phase-Level) ### Step 5: Create Phase Issues (Gitea, GitHub, or GitLab)
Create ONE issue per phase using git scripts: You MUST create ONE issue per phase in the configured external git provider.
Milestone binding rule:
- When the project is pre-MVP, issue milestones MUST use a `0.0.x` milestone.
- `0.1.0` MUST be used only for the MVP release milestone.
Provider options:
1. Gitea (preferred when available) via Mosaic helper:
```bash ```bash
~/.config/mosaic/rails/git/issue-create.sh \ ~/.config/mosaic/rails/git/issue-create.sh \
@@ -201,6 +285,7 @@ Create ONE issue per phase using git scripts:
- [ ] All critical findings remediated - [ ] All critical findings remediated
- [ ] Quality gates passing - [ ] Quality gates passing
- [ ] Required documentation updates complete
- [ ] No new regressions - [ ] No new regressions
EOF EOF
)" \ )" \
@@ -208,18 +293,44 @@ EOF
-m "{milestone-name}" -m "{milestone-name}"
``` ```
**Capture issue numbers** — you'll link tasks to these. 2. GitHub (if repository uses GitHub):
### Step 6: Create docs/tasks.md ```bash
gh issue create \
--title "Phase 1: Critical Security Fixes" \
--body-file /tmp/phase-1-body.md \
--label "security,critical" \
--milestone "{milestone-name}"
```
3. GitLab (if repository uses GitLab):
```bash
glab issue create \
--title "Phase 1: Critical Security Fixes" \
--description-file /tmp/phase-1-body.md \
--label "security,critical" \
--milestone "{milestone-name}"
```
No external provider fallback (HARD RULE):
- If Gitea/GitHub/GitLab is unavailable, you MUST track phase-level milestones and issue equivalents directly in `docs/TASKS.md`.
- In this mode, the `issue` column MUST use internal refs (example: `TASKS:P1`, `TASKS:P2`).
- You MUST keep `docs/TASKS.md` as the complete system of record for tasks, milestones, and issue status.
**Capture issue references** — you'll link tasks to these.
### Step 6: Create docs/TASKS.md
Create the file with this exact schema: Create the file with this exact schema:
```markdown ```markdown
# Tasks # Tasks
| id | status | description | issue | repo | branch | depends_on | blocks | agent | started_at | completed_at | estimate | used | | id | status | description | issue | repo | branch | depends_on | blocks | agent | started_at | completed_at | estimate | used | notes |
|---|---|---|---|---|---|---|---|---|---|---|---|---| |---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| {PREFIX}-SEC-001 | not-started | SEC-API-1: Brief description | #{N} | api | fix/security | | {PREFIX}-SEC-002 | | | | 8K | | | {PREFIX}-SEC-001 | not-started | SEC-API-1: Brief description | #{N} | api | fix/security | | {PREFIX}-SEC-002 | | | | 8K | | |
``` ```
**Column definitions:** **Column definitions:**
@@ -227,9 +338,9 @@ Create the file with this exact schema:
| Column | Format | Purpose | | Column | Format | Purpose |
|--------|--------|---------| |--------|--------|---------|
| `id` | `{PREFIX}-{CAT}-{NNN}` | Unique task ID (e.g., MS-SEC-001) | | `id` | `{PREFIX}-{CAT}-{NNN}` | Unique task ID (e.g., MS-SEC-001) |
| `status` | `not-started` \| `in-progress` \| `done` \| `failed` | Current state | | `status` | `not-started` \| `in-progress` \| `done` \| `failed` \| `blocked` \| `needs-qa` | Current state |
| `description` | `{FindingID}: Brief summary` | What to fix | | `description` | `{FindingID}: Brief summary` | What to fix |
| `issue` | `#NNN` | Gitea issue (phase-level, all tasks in phase share) | | `issue` | `#NNN` or `TASKS:Pn` | Provider issue ref (phase-level) or internal TASKS milestone ref |
| `repo` | Workspace name | `api`, `web`, `orchestrator`, etc. | | `repo` | Workspace name | `api`, `web`, `orchestrator`, etc. |
| `branch` | Branch name | `fix/security`, `fix/code-quality`, etc. | | `branch` | Branch name | `fix/security`, `fix/code-quality`, etc. |
| `depends_on` | Comma-separated IDs | Must complete first | | `depends_on` | Comma-separated IDs | Must complete first |
@@ -239,6 +350,10 @@ Create the file with this exact schema:
| `completed_at` | ISO 8601 | When work finished | | `completed_at` | ISO 8601 | When work finished |
| `estimate` | `5K`, `15K`, etc. | Predicted token usage | | `estimate` | `5K`, `15K`, etc. | Predicted token usage |
| `used` | `4.2K`, `12.8K`, etc. | Actual usage (fill on completion) | | `used` | `4.2K`, `12.8K`, etc. | Actual usage (fill on completion) |
| `notes` | free text | Review results, PR/CI/issue closure evidence, blocker commands |
Status rule:
- `done` is allowed only after PR merge + green CI + issue/ref closure for source-code tasks.
**Category prefixes:** **Category prefixes:**
- `SEC` — Security (Phase 1-2) - `SEC` — Security (Phase 1-2)
@@ -246,11 +361,21 @@ Create the file with this exact schema:
- `CQ` — Code quality (Phase 3) - `CQ` — Code quality (Phase 3)
- `TEST` — Test coverage (Phase 4) - `TEST` — Test coverage (Phase 4)
- `PERF` — Performance (Phase 3) - `PERF` — Performance (Phase 3)
- `DOC` — Documentation updates/gates
### Step 6b: Add Documentation Tasks (MANDATORY)
For each phase containing code/API/auth/infra work:
1. Add explicit documentation tasks in `docs/TASKS.md` (or include docs in phase verification tasks).
2. Require completion of `~/.config/mosaic/templates/docs/DOCUMENTATION-CHECKLIST.md`.
3. Ensure phase acceptance criteria includes documentation completion.
4. Do not mark phase complete until documentation tasks are done.
### Step 7: Commit Bootstrap ### Step 7: Commit Bootstrap
```bash ```bash
git add docs/tasks.md git add docs/TASKS.md
git commit -m "chore(orchestrator): Bootstrap tasks.md from review report git commit -m "chore(orchestrator): Bootstrap tasks.md from review report
Parsed {N} findings into {M} tasks across {P} phases. Parsed {N} findings into {M} tasks across {P} phases.
@@ -264,34 +389,61 @@ git push
``` ```
1. git pull --rebase 1. git pull --rebase
2. Read docs/tasks.md 2. Read docs/TASKS.md
3. Find next task: status=not-started AND all depends_on are done 3. Find next task: status=not-started AND all depends_on are done
4. If no task available: 4. If no task available:
- All done? → Report success, run final retrospective, STOP - All done? → Report success, run final retrospective, STOP
- Some blocked? → Report deadlock, STOP - Some blocked? → Report deadlock, STOP
5. Update tasks.md: status=in-progress, agent={identifier}, started_at={now} 5. Update tasks.md: status=in-progress, agent={identifier}, started_at={now}
6. Delegate worker task: 6. Budget gate (before dispatch):
- Compute cumulative used + remaining estimate
- If projected total > budget cap: STOP and request user decision (reduce scope/phase/increase cap)
- If projected total is 70-90% of cap: run conservative mode (single worker)
7. Delegate worker task:
- native mode: spawn worker agent via runtime subagent/task primitive - native mode: spawn worker agent via runtime subagent/task primitive
- matrix mode: enqueue/consume task in `.mosaic/orchestrator/tasks.json` and run `mosaic-orchestrator-matrix-cycle` - matrix mode: enqueue/consume task in `.mosaic/orchestrator/tasks.json` and run `mosaic-orchestrator-matrix-cycle`
7. Wait for worker completion 8. Wait for worker completion
8. Parse worker result (JSON) 9. Parse worker result (JSON)
9. **Variance check**: Calculate (actual - estimate) / estimate × 100 10. **Variance check**: Calculate (actual - estimate) / estimate × 100
- If |variance| > 50%: Capture learning (see Learning & Retrospective) - If |variance| > 50%: Capture learning (see Learning & Retrospective)
- If |variance| > 100%: Flag as CRITICAL — review task classification - If |variance| > 100%: Flag as CRITICAL — review task classification
10. **Post-Coding Review** (see Phase 2b below) 11. **Post-Coding Review** (see Phase 2b below)
11. Update tasks.md: status=done/failed/needs-qa, completed_at={now}, used={actual} 12. **Documentation Gate**: Verify required docs were updated per `~/.config/mosaic/guides/DOCUMENTATION.md`
12. **Cleanup reports**: Remove processed report files for completed task and checklist completed (`~/.config/mosaic/templates/docs/DOCUMENTATION-CHECKLIST.md`) when applicable.
13. **PR + CI + Issue Closure Gate** (HARD RULE for source-code tasks):
- Before merging, run queue guard:
`~/.config/mosaic/rails/git/ci-queue-wait.sh --purpose merge -B main`
- Ensure PR exists for the task branch (create/update via wrappers if needed):
`~/.config/mosaic/rails/git/pr-create.sh ... -B main`
- Merge via wrapper:
`~/.config/mosaic/rails/git/pr-merge.sh -n {PR_NUMBER} -m squash`
- Wait for terminal CI status:
`~/.config/mosaic/rails/git/pr-ci-wait.sh -n {PR_NUMBER}`
- Close linked issue after merge + green CI:
`~/.config/mosaic/rails/git/issue-close.sh -i {ISSUE_NUMBER}`
- If any wrapper command fails, mark task `blocked`, record the exact failed wrapper command, report blocker, and STOP.
- Do NOT stop at "PR created" or "PR merged pending CI".
- Do NOT claim completion before CI is green and issue/internal ref is closed.
14. Update tasks.md: status=done/failed/needs-qa/blocked, completed_at={now}, used={actual}
15. Recalculate budget position:
- cumulative used
- projected remaining from estimates
- total projected at completion
16. **Cleanup reports**: Remove processed report files for completed task
```bash ```bash
# Find and remove reports matching the finding ID # Find and remove reports matching the finding ID
find docs/reports/qa-automation/pending/ -name "*{finding_id}*" -delete 2>/dev/null || true find docs/reports/qa-automation/pending/ -name "*{finding_id}*" -delete 2>/dev/null || true
# If task failed, move reports to escalated/ instead # If task failed, move reports to escalated/ instead
``` ```
13. Commit + push: git add docs/tasks.md .gitignore && git commit && git push 17. Commit + push: git add docs/TASKS.md .gitignore && git commit && git push
14. If phase verification task: Run phase retrospective, clean up all phase reports 18. If phase verification task: Run phase retrospective, clean up all phase reports
15. Check context usage 19. Check context usage
16. If >= 55%: Output COMPACTION REQUIRED checkpoint, STOP, wait for user 20. If >= 55%: Output COMPACTION REQUIRED checkpoint, STOP, wait for user
17. If < 55%: Go to step 1 21. Check budget usage:
18. After user runs /compact and says "continue": Go to step 1 - If projected total > cap: STOP and request user decision before new tasks
- If projected total is 70-90% of cap: continue in conservative mode
22. If < 55% context and within budget: Go to step 1
23. After user runs /compact and says "continue": Go to step 1
``` ```
--- ---
@@ -375,7 +527,7 @@ Review the code changes on branch {branch} against {base_branch}.
- Security (OWASP Top 10, secrets, injection) - Security (OWASP Top 10, secrets, injection)
- Testing (coverage, quality) - Testing (coverage, quality)
- Code quality (complexity, duplication) - Code quality (complexity, duplication)
3. Reference: ~/.config/mosaic/guides/code-review.md 3. Reference: ~/.config/mosaic/guides/CODE-REVIEW.md
Report findings as JSON: Report findings as JSON:
```json ```json
@@ -432,26 +584,34 @@ Construct this from the task row and pass to worker via Task tool:
## Workflow ## Workflow
1. Checkout branch: `git checkout {branch} || git checkout -b {branch} develop && git pull` 1. Checkout branch: `git fetch origin && (git checkout {branch} || git checkout -b {branch} origin/main) && git rebase origin/main`
2. Read the finding details from the report 2. Read `docs/PRD.md` or `docs/PRD.json` and align implementation with PRD requirements
3. Implement the fix following existing code patterns 3. Read the finding details from the report
4. Run quality gates (ALL must pass — zero lint errors, zero type errors, all tests green): 4. Implement the fix following existing code patterns
5. Run quality gates (ALL must pass — zero lint errors, zero type errors, all tests green):
```bash ```bash
{quality_gates_command} {quality_gates_command}
``` ```
**MANDATORY:** This ALWAYS includes linting. If the project has a linter configured **MANDATORY:** This ALWAYS includes linting. If the project has a linter configured
(ESLint, Biome, ruff, etc.), you MUST run it and fix ALL violations in files you touched. (ESLint, Biome, ruff, etc.), you MUST run it and fix ALL violations in files you touched.
Do NOT leave lint warnings or errors for someone else to clean up. Do NOT leave lint warnings or errors for someone else to clean up.
5. If gates fail: Fix and retry. Do NOT report success with failures. 6. Run REQUIRED situational tests based on changed surfaces (see `~/.config/mosaic/guides/E2E-DELIVERY.md` and `~/.config/mosaic/guides/QA-TESTING.md`).
6. Commit: `git commit -m "fix({finding_id}): brief description"` 7. If task is bug fix/security/auth/critical business logic, apply REQUIRED TDD discipline per `~/.config/mosaic/guides/QA-TESTING.md`.
7. Push: `git push origin {branch}` 8. If gates or required situational tests fail: Fix and retry. Do NOT report success with failures.
8. Report result as JSON (see format below) 9. Commit: `git commit -m "fix({finding_id}): brief description"`
10. Before push, run queue guard: `~/.config/mosaic/rails/git/ci-queue-wait.sh --purpose push -B main`
11. Push: `git push origin {branch}`
12. Report result as JSON (see format below)
## Git Scripts ## Git Scripts
For issue/PR/milestone operations, use scripts (NOT raw tea/gh): For issue/PR/milestone operations, use scripts (NOT raw tea/gh):
- `~/.config/mosaic/rails/git/issue-view.sh -i {N}` - `~/.config/mosaic/rails/git/issue-view.sh -i {N}`
- `~/.config/mosaic/rails/git/pr-create.sh -t "Title" -b "Desc" -B develop` - `~/.config/mosaic/rails/git/pr-create.sh -t "Title" -b "Desc" -B main`
- `~/.config/mosaic/rails/git/ci-queue-wait.sh --purpose push|merge -B main`
- `~/.config/mosaic/rails/git/pr-merge.sh -n {PR_NUMBER} -m squash`
- `~/.config/mosaic/rails/git/pr-ci-wait.sh -n {PR_NUMBER}`
- `~/.config/mosaic/rails/git/issue-close.sh -i {N}`
Standard git commands (pull, commit, push, checkout) are fine. Standard git commands (pull, commit, push, checkout) are fine.
@@ -469,6 +629,9 @@ End your response with this JSON block:
} }
``` ```
`status=success` means "code pushed and ready for orchestrator integration gates";
it does NOT mean PR merged/CI green/issue closed.
## Post-Coding Review ## Post-Coding Review
After you complete and push your changes, the orchestrator will independently After you complete and push your changes, the orchestrator will independently
@@ -478,7 +641,7 @@ created. You do NOT need to run the review yourself — the orchestrator handles
## Rules ## Rules
- DO NOT modify docs/tasks.md - DO NOT modify docs/TASKS.md
- DO NOT claim other tasks - DO NOT claim other tasks
- Complete this single task, report results, done - Complete this single task, report results, done
```` ````
@@ -493,14 +656,14 @@ created. You do NOT need to run the review yourself — the orchestrator handles
- Compaction causes **protocol drift** — agent "remembers" gist but loses specifics - Compaction causes **protocol drift** — agent "remembers" gist but loses specifics
- Post-compaction agents may violate core rules (e.g., letting workers modify tasks.md) - Post-compaction agents may violate core rules (e.g., letting workers modify tasks.md)
- Fresh orchestrator has **100% protocol fidelity** - Fresh orchestrator has **100% protocol fidelity**
- All state lives in `docs/tasks.md` — the orchestrator is **stateless and replaceable** - All state lives in `docs/TASKS.md` — the orchestrator is **stateless and replaceable**
**At threshold (55-60%):** **At threshold (55-60%):**
1. Complete current task 1. Complete current task
2. Persist all state: 2. Persist all state:
- Update docs/tasks.md with all progress - Update docs/TASKS.md with all progress
- Update docs/orchestrator-learnings.json with variances - Update docs/tasks/orchestrator-learnings.json with variances
- Commit and push both files - Commit and push both files
3. Output **ORCHESTRATOR HANDOFF** message with ready-to-use takeover kickstart 3. Output **ORCHESTRATOR HANDOFF** message with ready-to-use takeover kickstart
4. **STOP COMPLETELY** — do not continue working 4. **STOP COMPLETELY** — do not continue working
@@ -517,8 +680,8 @@ Progress: {completed}/{total} tasks ({percentage}%)
Current phase: Phase {N} ({phase_name}) Current phase: Phase {N} ({phase_name})
State persisted: State persisted:
- docs/tasks.md ✓ - docs/TASKS.md ✓
- docs/orchestrator-learnings.json ✓ - docs/tasks/orchestrator-learnings.json ✓
## Takeover Kickstart ## Takeover Kickstart
@@ -531,8 +694,8 @@ Continue {mission_description} from existing state.
## Setup ## Setup
- Project: {project_path} - Project: {project_path}
- State: docs/tasks.md (already populated) - State: docs/TASKS.md (already populated)
- Protocol: docs/claude/orchestrator.md - Protocol: ~/.config/mosaic/guides/ORCHESTRATOR.md
- Quality gates: {quality_gates_command} - Quality gates: {quality_gates_command}
## Resume Point ## Resume Point
@@ -541,11 +704,11 @@ Continue {mission_description} from existing state.
- Progress: {completed}/{total} tasks ({percentage}%) - Progress: {completed}/{total} tasks ({percentage}%)
## Instructions ## Instructions
1. Read docs/claude/orchestrator.md for protocol 1. Read ~/.config/mosaic/guides/ORCHESTRATOR.md for protocol
2. Read docs/tasks.md to understand current state 2. Read docs/TASKS.md to understand current state
3. Continue execution from task {task_id} 3. Continue execution from task {task_id}
4. Follow Two-Phase Completion Protocol 4. Follow Two-Phase Completion Protocol
5. You are the SOLE writer of docs/tasks.md 5. You are the SOLE writer of docs/TASKS.md
--- ---
STOP: Terminate this session and spawn fresh orchestrator with the kickstart above. STOP: Terminate this session and spawn fresh orchestrator with the kickstart above.
@@ -583,7 +746,7 @@ Each major phase uses a two-phase approach to maximize completion while managing
| Architectural | Requires design change | Document and defer | | Architectural | Requires design change | Document and defer |
3. **Work priority:** Quick-win → Medium → Hard 3. **Work priority:** Quick-win → Medium → Hard
4. **Document deferrals** in `docs/deferred-errors.md`: 4. **Document deferrals** in `docs/reports/deferred/deferred-errors.md`:
```markdown ```markdown
## {PREFIX}-XXX: [Error description] ## {PREFIX}-XXX: [Error description]
- File: path/to/file.ts:123 - File: path/to/file.ts:123
@@ -608,7 +771,7 @@ Do NOT proceed to the next major phase until the current phase reaches Polish co
✅ Phase 2 Polish: 118 errors triaged ✅ Phase 2 Polish: 118 errors triaged
- 40 medium → fixed - 40 medium → fixed
- 78 low → EACH documented with rationale - 78 low → EACH documented with rationale
✅ Phase 2 Complete: Created docs/deferred-errors.md ✅ Phase 2 Complete: Created docs/reports/deferred/deferred-errors.md
→ NOW proceed to Phase 3 → NOW proceed to Phase 3
❌ WRONG: Phase 2 at 91%, "low priority acceptable", starting Phase 3 ❌ WRONG: Phase 2 at 91%, "low priority acceptable", starting Phase 3
@@ -643,7 +806,7 @@ Orchestrators capture learnings to improve future estimation accuracy.
|----------|--------| |----------|--------|
| 0-30% | Log only (acceptable) | | 0-30% | Log only (acceptable) |
| 30-50% | Flag for review | | 30-50% | Flag for review |
| 50-100% | Capture learning to `docs/orchestrator-learnings.json` | | 50-100% | Capture learning to `docs/tasks/orchestrator-learnings.json` |
| >100% | CRITICAL — review task classification, possible mismatch | | >100% | CRITICAL — review task classification, possible mismatch |
### Task Type Classification ### Task Type Classification
@@ -662,7 +825,7 @@ Classify tasks by description keywords for pattern analysis:
### Capture Learning ### Capture Learning
When |variance| > 50%, append to `docs/orchestrator-learnings.json`: When |variance| > 50%, append to `docs/tasks/orchestrator-learnings.json`:
```json ```json
{ {
@@ -708,7 +871,7 @@ Next: MS-SEC-004
### Cross-Project Learnings ### Cross-Project Learnings
Universal heuristics are maintained in `~/.config/mosaic/guides/orchestrator-learnings.md`. Universal heuristics are maintained in `~/.config/mosaic/guides/ORCHESTRATOR-LEARNINGS.md`.
After completing a milestone, review variance patterns and propose updates to the universal guide. After completing a milestone, review variance patterns and propose updates to the universal guide.
--- ---
@@ -736,7 +899,7 @@ docs/reports/qa-automation/
| Task success | Delete matching reports from `pending/` | | Task success | Delete matching reports from `pending/` |
| Task failed | Move reports to `escalated/` for investigation | | Task failed | Move reports to `escalated/` for investigation |
| Phase verification | Clean up all `pending/` reports for that phase | | Phase verification | Clean up all `pending/` reports for that phase |
| Milestone complete | Archive or delete entire `escalated/` directory | | Milestone complete | Complete release + tag workflow, then archive or delete `escalated/` directory |
**Cleanup commands:** **Cleanup commands:**
```bash ```bash
@@ -766,6 +929,11 @@ mv docs/reports/qa-automation/pending/*failing-file* docs/reports/qa-automation/
2. Skip to next unblocked task if possible 2. Skip to next unblocked task if possible
3. If all remaining tasks blocked: Report blockers, STOP 3. If all remaining tasks blocked: Report blockers, STOP
**PR/CI/Issue wrapper failure:**
1. Record task status as `blocked` in `docs/TASKS.md`.
2. Record the exact failed wrapper command (full command line) in task notes and user report.
3. STOP orchestration for that task; do not mark complete and do not silently fall back to raw provider commands.
**Git push conflict:** **Git push conflict:**
1. `git pull --rebase` 1. `git pull --rebase`
2. If auto-resolves: push again 2. If auto-resolves: push again
@@ -776,54 +944,151 @@ mv docs/reports/qa-automation/pending/*failing-file* docs/reports/qa-automation/
## Stopping Criteria ## Stopping Criteria
**ONLY stop if:** **ONLY stop if:**
1. All tasks in docs/tasks.md are `done` 1. All tasks in docs/TASKS.md are `done`
2. Critical blocker preventing progress (document and alert) 2. Critical blocker preventing progress (document and alert)
3. Context usage >= 55% — output COMPACTION REQUIRED checkpoint and wait 3. Context usage >= 55% — output COMPACTION REQUIRED checkpoint and wait
4. Absolute context limit reached AND cannot compact further 4. Absolute context limit reached AND cannot compact further
5. PRD is current and reflects delivered requirements (`docs/PRD.md` or `docs/PRD.json`)
6. Required documentation checklist is complete for applicable changes
7. For milestone completion, release + git tag steps are complete
8. For source-code tasks with external provider, merged PR evidence exists
9. For source-code tasks with external provider, CI/pipeline is terminal green
10. For linked external issues, closure is complete (or internal TASKS ref closure if no provider)
**DO NOT stop to ask "should I continue?"** — the answer is always YES. **DO NOT stop to ask "should I continue?"** — the answer is always YES.
**DO stop at 55-60%** — output the compaction checkpoint and wait for user to run `/compact`. **DO stop at 55-60%** — output the compaction checkpoint and wait for user to run `/compact`.
--- ---
## Sprint Completion Protocol ## Merge-to-Main Candidate Protocol (Container Deployments)
When all tasks in `docs/tasks.md` are `done` (or triaged as `deferred`), archive the sprint artifacts before stopping. This preserves them for post-mortems, variance calibration, and historical reference. If deployment is in scope and container images are used, every merge to `main` MUST execute this protocol:
### Archive Steps 1. Build and push immutable candidate image tags:
- `sha-<shortsha>` (always)
- `v{base-version}-rc.{build}` (for `main` merges)
- `testing` mutable pointer to the same digest
2. Resolve and record the image digest for each service.
3. Deploy by digest to testing environment (never deploy by mutable tag alone).
4. Run full situational testing against images pulled from the registry.
5. If tests pass, promote the SAME digest (no rebuild) to environment pointers (`staging`/`prod` as applicable).
6. If tests fail, rollback to last known-good digest and create remediation tasks immediately.
1. **Create archive directory** (if it doesn't exist): Hard rules:
- `latest` MUST NOT be used as a deployment reference.
- Final semantic release tags (`vX.Y.Z`) are milestone-level only.
- Intermediate checkpoints use RC image tags (`vX.Y.Z-rc.N`) and digest promotion.
---
## Milestone Completion Protocol (Release + Tag Required)
When all tasks in `docs/TASKS.md` are `done` (or triaged as `deferred`), you MUST complete release/tag operations before declaring the milestone complete.
### Required Completion Steps
1. **Prepare release metadata**:
- `milestone-name` (human-readable)
- `milestone-version` (semantic version, e.g., `0.0.3`, `0.1.0`)
- `tag` = `v{milestone-version}` (e.g., `v0.0.3`)
2. **Verify documentation gate**:
- Confirm required docs were updated per `~/.config/mosaic/guides/DOCUMENTATION.md`.
- Confirm checklist completion: `~/.config/mosaic/templates/docs/DOCUMENTATION-CHECKLIST.md`.
- If docs are incomplete, STOP and create remediation task(s) before release/tag.
3. **Create and push annotated git tag**:
```bash ```bash
mkdir -p docs/tasks/ git pull --rebase
git tag -a "v{milestone-version}" -m "Release v{milestone-version} - {milestone-name}"
git push origin "v{milestone-version}"
``` ```
2. **Move tasks.md to archive:** 4. **Create repository release** (provider-specific):
Gitea:
```bash ```bash
mv docs/tasks.md docs/tasks/{milestone-name}-tasks.md tea releases create \
--tag "v{milestone-version}" \
--title "v{milestone-version}" \
--note "Milestone {milestone-name} completed."
```
GitHub:
```bash
gh release create "v{milestone-version}" \
--title "v{milestone-version}" \
--notes "Milestone {milestone-name} completed."
```
GitLab:
```bash
glab release create "v{milestone-version}" \
--name "v{milestone-version}" \
--notes "Milestone {milestone-name} completed."
```
No external provider fallback:
- Create and push annotated tag as above.
- Create `docs/releases/v{milestone-version}.md` with release notes and include milestone completion summary.
5. **Close milestone in provider**:
- Gitea/GitHub:
```bash
~/.config/mosaic/rails/git/milestone-close.sh -t "{milestone-name}"
```
- GitLab: close milestone via provider workflow (CLI or web UI).
If provider tooling is unavailable, record milestone closure status in `docs/TASKS.md` notes.
6. **Archive sprint artifacts**:
```bash
mkdir -p docs/tasks/
mv docs/TASKS.md docs/tasks/{milestone-name}-tasks.md
mv docs/tasks/orchestrator-learnings.json docs/tasks/{milestone-name}-learnings.json
``` ```
Example: `docs/tasks/M6-AgentOrchestration-Fixes-tasks.md` Example: `docs/tasks/M6-AgentOrchestration-Fixes-tasks.md`
3. **Move learnings to archive:** 7. **Commit archive + release references**:
```bash ```bash
mv docs/orchestrator-learnings.json docs/tasks/{milestone-name}-learnings.json git add docs/tasks/ docs/releases/ 2>/dev/null || true
``` git rm docs/TASKS.md docs/tasks/orchestrator-learnings.json 2>/dev/null || true
git commit -m "chore(orchestrator): Complete {milestone-name} milestone release
4. **Commit the archive:** - Tagged: v{milestone-version}
```bash - Release published
git add docs/tasks/ - Artifacts archived to docs/tasks/"
git rm docs/tasks.md docs/orchestrator-learnings.json 2>/dev/null || true
git commit -m "chore(orchestrator): Archive {milestone-name} sprint artifacts
{completed}/{total} tasks completed, {deferred} deferred.
Archived to docs/tasks/ for post-mortem reference."
git push git push
``` ```
5. **Run final retrospective** — review variance patterns and propose updates to estimation heuristics. 8. **Run final retrospective** — review variance patterns and propose updates to estimation heuristics.
### Deployment Protocol (When In Scope)
If the milestone includes deployment, orchestrator MUST complete deployment before final completion status:
1. Determine deployment target from PRD, project config, or environment:
- `Portainer`
- `Coolify`
- `Vercel`
- other configured SaaS provider
2. Trigger deployment using provider API/CLI/webhook.
3. Deployment method MUST be digest-first:
- Resolve digest from candidate image (`sha-*` or `vX.Y.Z-rc.N`),
- deploy that digest,
- promote tags (`testing`/`staging`/`prod`) only after validation.
4. Run post-deploy verification:
- health endpoint checks,
- critical smoke tests,
- release/version verification,
- digest verification (running digest equals promoted digest).
5. Default strategy is blue-green. Canary is allowed only if automated metrics, thresholds, and rollback triggers are configured.
6. If verification fails, execute rollback/redeploy-safe path and mark milestone `blocked` until stable.
7. Record deployment evidence in milestone release notes and `docs/TASKS.md` notes, including digest and promoted tags.
8. Ensure registry cleanup is scheduled/enforced (retain release tags + active digests, purge stale RC/sha tags).
### Recovery ### Recovery
If an orchestrator starts and `docs/tasks.md` does not exist, check `docs/tasks/` for the most recent archive: If an orchestrator starts and `docs/TASKS.md` does not exist, check `docs/tasks/` for the most recent archive:
```bash ```bash
ls -t docs/tasks/*-tasks.md 2>/dev/null | head -1 ls -t docs/tasks/*-tasks.md 2>/dev/null | head -1
@@ -832,7 +1097,7 @@ ls -t docs/tasks/*-tasks.md 2>/dev/null | head -1
If found, this may indicate another session archived the file. The orchestrator should: If found, this may indicate another session archived the file. The orchestrator should:
1. Report what it found in `docs/tasks/` 1. Report what it found in `docs/tasks/`
2. Ask whether to resume from the archived file or bootstrap fresh 2. Ask whether to resume from the archived file or bootstrap fresh
3. If resuming: copy the archive back to `docs/tasks.md` and continue 3. If resuming: copy the archive back to `docs/TASKS.md` and continue
### Retention Policy ### Retention Policy
@@ -860,7 +1125,7 @@ Remediate findings from the codebase review.
- Task prefix: {PREFIX} (e.g., MS, UC) - Task prefix: {PREFIX} (e.g., MS, UC)
## Protocol ## Protocol
Read ~/.config/mosaic/guides/orchestrator.md for full instructions. Read ~/.config/mosaic/guides/ORCHESTRATOR.md for full instructions.
## Start ## Start
Bootstrap from the review report, then execute until complete. Bootstrap from the review report, then execute until complete.

View File

@@ -1,202 +0,0 @@
# QA & Testing Guide
## Before Starting
1. Check assigned issue: `~/.config/mosaic/rails/git/issue-list.sh -a @me`
2. Create scratchpad: `docs/scratchpads/{issue-number}-{short-name}.md`
3. Review existing test structure and patterns
## Test-Driven Development (TDD) Process
### The TDD Cycle
1. **Red**: Write a failing test first
2. **Green**: Write minimal code to pass
3. **Refactor**: Improve code while keeping tests green
### TDD Rules
- Never write production code without a failing test
- Write only enough test to fail
- Write only enough code to pass
- Refactor continuously
## Coverage Requirements
### Minimum Standards
- **Overall Coverage**: 85% minimum
- **Critical Paths**: 95% minimum (auth, payments, data mutations)
- **New Code**: 90% minimum
### What to Cover
- All public interfaces
- Error handling paths
- Edge cases and boundaries
- Integration points
### What NOT to Count
- Generated code
- Configuration files
- Third-party library wrappers (thin wrappers only)
## Test Categories
### Unit Tests
- Test single functions/methods in isolation
- Mock external dependencies
- Fast execution (< 100ms per test)
- No network, database, or filesystem access
```python
def test_calculate_discount_applies_percentage():
result = calculate_discount(100, 0.20)
assert result == 80
```
### Integration Tests
- Test multiple components together
- Use real databases (test containers)
- Test API contracts
- Slower execution acceptable
```python
def test_create_user_persists_to_database(db_session):
user = create_user(db_session, "test@example.com")
retrieved = get_user_by_email(db_session, "test@example.com")
assert retrieved.id == user.id
```
### End-to-End Tests
- Test complete user workflows
- Use real browser (Playwright, Cypress)
- Test critical paths only (expensive to maintain)
```javascript
test('user can complete checkout', async ({ page }) => {
await page.goto('/products');
await page.click('[data-testid="add-to-cart"]');
await page.click('[data-testid="checkout"]');
await page.fill('#email', 'test@example.com');
await page.click('[data-testid="submit-order"]');
await expect(page.locator('.order-confirmation')).toBeVisible();
});
```
## Test Structure
### Naming Convention
```
test_{what}_{condition}_{expected_result}
Examples:
- test_login_with_valid_credentials_returns_token
- test_login_with_invalid_password_returns_401
- test_get_user_when_not_found_returns_404
```
### Arrange-Act-Assert Pattern
```python
def test_add_item_to_cart_increases_count():
# Arrange
cart = Cart()
item = Item(id=1, name="Widget", price=9.99)
# Act
cart.add(item)
# Assert
assert cart.item_count == 1
assert cart.total == 9.99
```
### Test Isolation
- Each test should be independent
- Use setup/teardown for common state
- Clean up after tests
- Don't rely on test execution order
## Mocking Guidelines
### When to Mock
- External APIs and services
- Time-dependent operations
- Random number generation
- Expensive operations
### When NOT to Mock
- The code under test
- Simple data structures
- Database in integration tests
### Mock Example
```python
def test_send_notification_calls_email_service(mocker):
mock_email = mocker.patch('services.email.send')
send_notification(user_id=1, message="Hello")
mock_email.assert_called_once_with(
to="user@example.com",
subject="Notification",
body="Hello"
)
```
## Test Data Management
### Fixtures
- Use factories for complex objects
- Keep test data close to tests
- Use realistic but anonymized data
### Database Tests
- Use transactions with rollback
- Or use test containers
- Never test against production data
## Reporting
### Test Reports Should Include
- Total tests run
- Pass/fail counts
- Coverage percentage
- Execution time
- Flaky test identification
### QA Report Template
```markdown
# QA Report - Issue #{number}
## Summary
- Tests Added: X
- Tests Modified: Y
- Coverage: XX%
## Test Results
- Passed: X
- Failed: X
- Skipped: X
## Coverage Analysis
- Lines: XX%
- Branches: XX%
- Functions: XX%
## Notes
[Any observations or concerns]
```
## Commit Format
```
test(#34): Add user registration tests
- Unit tests for validation logic
- Integration tests for /api/users endpoint
- Coverage increased from 72% to 87%
Refs #34
```
## Before Completing
1. All tests pass locally
2. Coverage meets 85% threshold
3. No flaky tests introduced
4. CI pipeline passes
5. Update scratchpad with results

View File

@@ -143,6 +143,21 @@ catch {
Write-Warn "Runtime asset linking failed (non-fatal)" Write-Warn "Runtime asset linking failed (non-fatal)"
} }
try {
& "$binDir\mosaic-ensure-sequential-thinking.ps1" *>$null
Write-Ok "sequential-thinking MCP configured"
}
catch {
if ($env:MOSAIC_ALLOW_MISSING_SEQUENTIAL_THINKING -eq "1") {
Write-Warn "sequential-thinking MCP setup failed but bypassed (MOSAIC_ALLOW_MISSING_SEQUENTIAL_THINKING=1)"
}
else {
Write-Fail "sequential-thinking MCP setup failed (hard requirement)."
Write-Fail "Set MOSAIC_ALLOW_MISSING_SEQUENTIAL_THINKING=1 only for temporary bypass scenarios."
exit 1
}
}
if ($env:MOSAIC_SKIP_SKILLS_SYNC -eq "1") { if ($env:MOSAIC_SKIP_SKILLS_SYNC -eq "1") {
Write-Ok "Skills sync skipped (MOSAIC_SKIP_SKILLS_SYNC=1)" Write-Ok "Skills sync skipped (MOSAIC_SKIP_SKILLS_SYNC=1)"
} }

View File

@@ -151,6 +151,18 @@ else
warn "Runtime asset linking failed (non-fatal)" warn "Runtime asset linking failed (non-fatal)"
fi fi
if "$TARGET_DIR/bin/mosaic-ensure-sequential-thinking" >/dev/null 2>&1; then
ok "sequential-thinking MCP configured"
else
if [[ "${MOSAIC_ALLOW_MISSING_SEQUENTIAL_THINKING:-0}" == "1" ]]; then
warn "sequential-thinking MCP setup failed but bypassed (MOSAIC_ALLOW_MISSING_SEQUENTIAL_THINKING=1)"
else
fail "sequential-thinking MCP setup failed (hard requirement)."
fail "Set MOSAIC_ALLOW_MISSING_SEQUENTIAL_THINKING=1 only for temporary bypass scenarios."
exit 1
fi
fi
if [[ "${MOSAIC_SKIP_SKILLS_SYNC:-0}" == "1" ]]; then if [[ "${MOSAIC_SKIP_SKILLS_SYNC:-0}" == "1" ]]; then
ok "Skills sync skipped (MOSAIC_SKIP_SKILLS_SYNC=1)" ok "Skills sync skipped (MOSAIC_SKIP_SKILLS_SYNC=1)"
else else

View File

@@ -15,7 +15,7 @@ Profiles are runtime-neutral context packs that can be consumed by any agent run
Current runtime overlay example: Current runtime overlay example:
- `~/.config/mosaic/runtime/claude/settings-overlays/jarvis-ralph.json` - `~/.config/mosaic/runtime/claude/settings-overlays/jarvis-loop.json`
## Claude Compatibility ## Claude Compatibility

View File

@@ -9,10 +9,10 @@
# agent-lint.sh --fix-hint # Show fix commands for failures # agent-lint.sh --fix-hint # Show fix commands for failures
# #
# Checks per project: # Checks per project:
# 1. Has CLAUDE.md? # 1. Has runtime context file (CLAUDE.md or RUNTIME.md)?
# 2. Has AGENTS.md? # 2. Has AGENTS.md?
# 3. CLAUDE.md references conditional context/guides? # 3. Runtime context file references conditional context/guides?
# 4. CLAUDE.md has quality gates? # 4. Runtime context file has quality gates?
# 5. For monorepos: sub-directories have AGENTS.md? # 5. For monorepos: sub-directories have AGENTS.md?
set -euo pipefail set -euo pipefail
@@ -92,9 +92,23 @@ is_monorepo() {
(grep -q '"workspaces"' "$dir/package.json" 2>/dev/null) (grep -q '"workspaces"' "$dir/package.json" 2>/dev/null)
} }
# Check for CLAUDE.md # Resolve runtime context file (CLAUDE.md or RUNTIME.md)
check_claude_md() { runtime_context_file() {
[[ -f "$1/CLAUDE.md" ]] local dir="$1"
if [[ -f "$dir/CLAUDE.md" ]]; then
echo "$dir/CLAUDE.md"
return
fi
if [[ -f "$dir/RUNTIME.md" ]]; then
echo "$dir/RUNTIME.md"
return
fi
echo ""
}
# Check for runtime context file
check_runtime_context() {
[[ -n "$(runtime_context_file "$1")" ]]
} }
# Check for AGENTS.md # Check for AGENTS.md
@@ -104,14 +118,16 @@ check_agents_md() {
# Check conditional loading/context (references guides or conditional section) # Check conditional loading/context (references guides or conditional section)
check_conditional_loading() { check_conditional_loading() {
local claude_md="$1/CLAUDE.md" local ctx
[[ -f "$claude_md" ]] && grep -qi "agent-guides\|~/.config/mosaic/guides\|conditional.*loading\|conditional.*documentation\|conditional.*context" "$claude_md" 2>/dev/null ctx="$(runtime_context_file "$1")"
[[ -n "$ctx" ]] && grep -qi "agent-guides\|~/.config/mosaic/guides\|conditional.*loading\|conditional.*documentation\|conditional.*context" "$ctx" 2>/dev/null
} }
# Check quality gates # Check quality gates
check_quality_gates() { check_quality_gates() {
local claude_md="$1/CLAUDE.md" local ctx
[[ -f "$claude_md" ]] && grep -qi "quality.gates\|must pass before\|lint\|typecheck\|test" "$claude_md" 2>/dev/null ctx="$(runtime_context_file "$1")"
[[ -n "$ctx" ]] && grep -qi "quality.gates\|must pass before\|lint\|typecheck\|test" "$ctx" 2>/dev/null
} }
# Check monorepo sub-AGENTS.md # Check monorepo sub-AGENTS.md
@@ -152,16 +168,16 @@ lint_project() {
local name local name
name=$(basename "$dir") name=$(basename "$dir")
local has_claude has_agents has_guides has_quality mono_status local has_runtime has_agents has_guides has_quality mono_status
local score=0 max_score=4 local score=0 max_score=4
check_claude_md "$dir" && has_claude="OK" || has_claude="MISS" check_runtime_context "$dir" && has_runtime="OK" || has_runtime="MISS"
check_agents_md "$dir" && has_agents="OK" || has_agents="MISS" check_agents_md "$dir" && has_agents="OK" || has_agents="MISS"
check_conditional_loading "$dir" && has_guides="OK" || has_guides="MISS" check_conditional_loading "$dir" && has_guides="OK" || has_guides="MISS"
check_quality_gates "$dir" && has_quality="OK" || has_quality="MISS" check_quality_gates "$dir" && has_quality="OK" || has_quality="MISS"
mono_status=$(check_monorepo_sub_agents "$dir") mono_status=$(check_monorepo_sub_agents "$dir")
[[ "$has_claude" == "OK" ]] && ((score++)) || true [[ "$has_runtime" == "OK" ]] && ((score++)) || true
[[ "$has_agents" == "OK" ]] && ((score++)) || true [[ "$has_agents" == "OK" ]] && ((score++)) || true
[[ "$has_guides" == "OK" ]] && ((score++)) || true [[ "$has_guides" == "OK" ]] && ((score++)) || true
[[ "$has_quality" == "OK" ]] && ((score++)) || true [[ "$has_quality" == "OK" ]] && ((score++)) || true
@@ -171,7 +187,7 @@ lint_project() {
{ {
"project": "$name", "project": "$name",
"path": "$dir", "path": "$dir",
"claude_md": "$has_claude", "runtime_context": "$has_runtime",
"agents_md": "$has_agents", "agents_md": "$has_agents",
"conditional_loading": "$has_guides", "conditional_loading": "$has_guides",
"quality_gates": "$has_quality", "quality_gates": "$has_quality",
@@ -182,8 +198,8 @@ lint_project() {
JSONEOF JSONEOF
else else
# Color-code the status # Color-code the status
local c_claude c_agents c_guides c_quality local c_runtime c_agents c_guides c_quality
[[ "$has_claude" == "OK" ]] && c_claude="${GREEN} OK ${NC}" || c_claude="${RED} MISS ${NC}" [[ "$has_runtime" == "OK" ]] && c_runtime="${GREEN} OK ${NC}" || c_runtime="${RED} MISS ${NC}"
[[ "$has_agents" == "OK" ]] && c_agents="${GREEN} OK ${NC}" || c_agents="${RED} MISS ${NC}" [[ "$has_agents" == "OK" ]] && c_agents="${GREEN} OK ${NC}" || c_agents="${RED} MISS ${NC}"
[[ "$has_guides" == "OK" ]] && c_guides="${GREEN} OK ${NC}" || c_guides="${RED} MISS ${NC}" [[ "$has_guides" == "OK" ]] && c_guides="${GREEN} OK ${NC}" || c_guides="${RED} MISS ${NC}"
[[ "$has_quality" == "OK" ]] && c_quality="${GREEN} OK ${NC}" || c_quality="${RED} MISS ${NC}" [[ "$has_quality" == "OK" ]] && c_quality="${GREEN} OK ${NC}" || c_quality="${RED} MISS ${NC}"
@@ -193,7 +209,7 @@ JSONEOF
[[ $score -eq 4 ]] && score_color="$GREEN" [[ $score -eq 4 ]] && score_color="$GREEN"
printf " %-35s %b %b %b %b ${score_color}%d/%d${NC}" \ printf " %-35s %b %b %b %b ${score_color}%d/%d${NC}" \
"$name" "$c_claude" "$c_agents" "$c_guides" "$c_quality" "$score" "$max_score" "$name" "$c_runtime" "$c_agents" "$c_guides" "$c_quality" "$score" "$max_score"
# Show monorepo status if applicable # Show monorepo status if applicable
if [[ "$mono_status" != "N/A" && "$mono_status" != "OK" ]]; then if [[ "$mono_status" != "N/A" && "$mono_status" != "OK" ]]; then
@@ -203,7 +219,7 @@ JSONEOF
fi fi
if $VERBOSE && ! $JSON_OUTPUT; then if $VERBOSE && ! $JSON_OUTPUT; then
[[ "$has_claude" == "MISS" ]] && echo " ${DIM} CLAUDE.md missing${NC}" [[ "$has_runtime" == "MISS" ]] && echo " ${DIM} Runtime context file missing (CLAUDE.md or RUNTIME.md)${NC}"
[[ "$has_agents" == "MISS" ]] && echo " ${DIM} AGENTS.md missing${NC}" [[ "$has_agents" == "MISS" ]] && echo " ${DIM} AGENTS.md missing${NC}"
[[ "$has_guides" == "MISS" ]] && echo " ${DIM} No conditional context/loading section detected${NC}" [[ "$has_guides" == "MISS" ]] && echo " ${DIM} No conditional context/loading section detected${NC}"
[[ "$has_quality" == "MISS" ]] && echo " ${DIM} No quality gates section${NC}" [[ "$has_quality" == "MISS" ]] && echo " ${DIM} No quality gates section${NC}"
@@ -213,7 +229,7 @@ JSONEOF
fi fi
if $FIX_HINT && ! $JSON_OUTPUT; then if $FIX_HINT && ! $JSON_OUTPUT; then
if [[ "$has_claude" == "MISS" || "$has_agents" == "MISS" ]]; then if [[ "$has_runtime" == "MISS" || "$has_agents" == "MISS" ]]; then
echo " ${DIM}Fix: ~/.config/mosaic/rails/bootstrap/init-project.sh --name \"$name\" --type auto${NC}" echo " ${DIM}Fix: ~/.config/mosaic/rails/bootstrap/init-project.sh --name \"$name\" --type auto${NC}"
elif [[ "$has_guides" == "MISS" ]]; then elif [[ "$has_guides" == "MISS" ]]; then
echo " ${DIM}Fix: ~/.config/mosaic/rails/bootstrap/agent-upgrade.sh $dir --section conditional-loading${NC}" echo " ${DIM}Fix: ~/.config/mosaic/rails/bootstrap/agent-upgrade.sh $dir --section conditional-loading${NC}"
@@ -258,7 +274,7 @@ main() {
echo -e "${BOLD}Agent Configuration Audit — $(date +%Y-%m-%d)${NC}" echo -e "${BOLD}Agent Configuration Audit — $(date +%Y-%m-%d)${NC}"
echo "========================================================" echo "========================================================"
printf " %-35s %s %s %s %s %s\n" \ printf " %-35s %s %s %s %s %s\n" \
"Project" "CLAUDE" "AGENTS" "Guides" "Quality" "Score" "Project" "RUNTIME" "AGENTS" "Guides" "Quality" "Score"
echo " -----------------------------------------------------------------------" echo " -----------------------------------------------------------------------"
for dir in "${projects[@]}"; do for dir in "${projects[@]}"; do

View File

@@ -113,6 +113,19 @@ has_section() {
[[ -f "$file" ]] && grep -qi "$pattern" "$file" 2>/dev/null [[ -f "$file" ]] && grep -qi "$pattern" "$file" 2>/dev/null
} }
runtime_context_file() {
local project_dir="$1"
if [[ -f "$project_dir/CLAUDE.md" ]]; then
echo "$project_dir/CLAUDE.md"
return
fi
if [[ -f "$project_dir/RUNTIME.md" ]]; then
echo "$project_dir/RUNTIME.md"
return
fi
echo "$project_dir/CLAUDE.md"
}
backup_file() { backup_file() {
local file="$1" local file="$1"
if [[ -f "$file" ]] && ! $DRY_RUN; then if [[ -f "$file" ]] && ! $DRY_RUN; then
@@ -124,7 +137,8 @@ backup_file() {
inject_fragment() { inject_fragment() {
local project_dir="$1" local project_dir="$1"
local fragment_name="$2" local fragment_name="$2"
local claude_md="$project_dir/CLAUDE.md" local ctx_file
ctx_file="$(runtime_context_file "$project_dir")"
local fragment_file="$FRAGMENTS_DIR/$fragment_name.md" local fragment_file="$FRAGMENTS_DIR/$fragment_name.md"
if [[ ! -f "$fragment_file" ]]; then if [[ ! -f "$fragment_file" ]]; then
@@ -144,12 +158,12 @@ inject_fragment() {
*) echo "Unknown fragment: $fragment_name"; return 1 ;; *) echo "Unknown fragment: $fragment_name"; return 1 ;;
esac esac
if [[ ! -f "$claude_md" ]]; then if [[ ! -f "$ctx_file" ]]; then
echo -e " ${YELLOW}No CLAUDE.md — skipping fragment injection${NC}" echo -e " ${YELLOW}No runtime context file (CLAUDE.md/RUNTIME.md) — skipping fragment injection${NC}"
return 0 return 0
fi fi
if has_section "$claude_md" "$detect_pattern"; then if has_section "$ctx_file" "$detect_pattern"; then
echo -e " ${DIM}$fragment_name already present${NC}" echo -e " ${DIM}$fragment_name already present${NC}"
return 0 return 0
fi fi
@@ -157,10 +171,10 @@ inject_fragment() {
if $DRY_RUN; then if $DRY_RUN; then
echo -e " ${GREEN}Would inject: $fragment_name${NC}" echo -e " ${GREEN}Would inject: $fragment_name${NC}"
else else
backup_file "$claude_md" backup_file "$ctx_file"
echo "" >> "$claude_md" echo "" >> "$ctx_file"
cat "$fragment_file" >> "$claude_md" cat "$fragment_file" >> "$ctx_file"
echo "" >> "$claude_md" echo "" >> "$ctx_file"
echo -e " ${GREEN}Injected: $fragment_name${NC}" echo -e " ${GREEN}Injected: $fragment_name${NC}"
fi fi
} }
@@ -257,8 +271,8 @@ upgrade_project() {
# Always try conditional-loading (highest impact) # Always try conditional-loading (highest impact)
inject_fragment "$dir" "conditional-loading" inject_fragment "$dir" "conditional-loading"
# Try other fragments if CLAUDE.md exists # Try other fragments if runtime context exists
if [[ -f "$dir/CLAUDE.md" ]]; then if [[ -f "$dir/CLAUDE.md" || -f "$dir/RUNTIME.md" ]]; then
inject_fragment "$dir" "commit-format" inject_fragment "$dir" "commit-format"
inject_fragment "$dir" "secrets" inject_fragment "$dir" "secrets"
inject_fragment "$dir" "multi-agent" inject_fragment "$dir" "multi-agent"

View File

@@ -10,6 +10,7 @@ set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
TEMPLATE_DIR="$HOME/.config/mosaic/templates/agent" TEMPLATE_DIR="$HOME/.config/mosaic/templates/agent"
GIT_SCRIPT_DIR="$HOME/.config/mosaic/rails/git" GIT_SCRIPT_DIR="$HOME/.config/mosaic/rails/git"
SEQUENTIAL_MCP_SCRIPT="$HOME/.config/mosaic/bin/mosaic-ensure-sequential-thinking"
# Defaults # Defaults
PROJECT_NAME="" PROJECT_NAME=""
@@ -320,10 +321,14 @@ fi
if [[ "$DRY_RUN" == true ]]; then if [[ "$DRY_RUN" == true ]]; then
echo "[DRY RUN] Would create:" echo "[DRY RUN] Would create:"
echo " - Validate sequential-thinking MCP hard requirement"
echo " - CLAUDE.md (from $STACK_TEMPLATE_DIR/CLAUDE.md.template)" echo " - CLAUDE.md (from $STACK_TEMPLATE_DIR/CLAUDE.md.template)"
echo " - AGENTS.md (from $STACK_TEMPLATE_DIR/AGENTS.md.template)" echo " - AGENTS.md (from $STACK_TEMPLATE_DIR/AGENTS.md.template)"
echo " - docs/scratchpads/" echo " - docs/scratchpads/"
echo " - docs/reports/" echo " - docs/reports/qa-automation/{pending,in-progress,done,escalated}"
echo " - docs/reports/deferred/"
echo " - docs/tasks/"
echo " - docs/releases/"
echo " - docs/templates/" echo " - docs/templates/"
if [[ "$SKIP_CI" != true ]]; then if [[ "$SKIP_CI" != true ]]; then
echo " - .woodpecker/codex-review.yml" echo " - .woodpecker/codex-review.yml"
@@ -331,7 +336,8 @@ if [[ "$DRY_RUN" == true ]]; then
fi fi
if [[ "$SKIP_LABELS" != true ]]; then if [[ "$SKIP_LABELS" != true ]]; then
echo " - Standard git labels (epic, feature, bug, task, documentation, security, breaking)" echo " - Standard git labels (epic, feature, bug, task, documentation, security, breaking)"
echo " - Milestone: 0.1.0 - MVP" echo " - Milestone: 0.0.1 - Pre-MVP Foundation"
echo " - Milestone policy: 0.0.x pre-MVP, 0.1.0 for MVP release"
fi fi
if [[ "$CICD_DOCKER" == true ]]; then if [[ "$CICD_DOCKER" == true ]]; then
echo " - Docker build/push/link steps appended to .woodpecker.yml" echo " - Docker build/push/link steps appended to .woodpecker.yml"
@@ -343,6 +349,21 @@ if [[ "$DRY_RUN" == true ]]; then
exit 0 exit 0
fi fi
# Enforce sequential-thinking MCP hard requirement.
if [[ ! -x "$SEQUENTIAL_MCP_SCRIPT" ]]; then
echo "Error: Missing sequential-thinking setup helper: $SEQUENTIAL_MCP_SCRIPT" >&2
echo "Install/repair Mosaic at ~/.config/mosaic before bootstrapping projects." >&2
exit 1
fi
if "$SEQUENTIAL_MCP_SCRIPT" >/dev/null 2>&1; then
echo "Verified sequential-thinking MCP configuration"
else
echo "Error: sequential-thinking MCP setup failed (hard requirement)." >&2
echo "Run: $SEQUENTIAL_MCP_SCRIPT" >&2
exit 1
fi
# Create CLAUDE.md # Create CLAUDE.md
if [[ -f "CLAUDE.md" ]]; then if [[ -f "CLAUDE.md" ]]; then
echo "CLAUDE.md already exists — skipping (rename or delete to recreate)" echo "CLAUDE.md already exists — skipping (rename or delete to recreate)"
@@ -368,8 +389,17 @@ else
fi fi
# Create directories # Create directories
mkdir -p docs/scratchpads docs/reports docs/templates mkdir -p \
echo "Created docs/scratchpads/, docs/reports/, docs/templates/" docs/scratchpads \
docs/reports/qa-automation/pending \
docs/reports/qa-automation/in-progress \
docs/reports/qa-automation/done \
docs/reports/qa-automation/escalated \
docs/reports/deferred \
docs/tasks \
docs/releases \
docs/templates
echo "Created docs/scratchpads/, docs/reports/*, docs/tasks/, docs/releases/, docs/templates/"
# Set up CI/CD pipeline # Set up CI/CD pipeline
if [[ "$SKIP_CI" != true ]]; then if [[ "$SKIP_CI" != true ]]; then

View File

@@ -24,7 +24,7 @@ while [[ $# -gt 0 ]]; do
echo "Create standard labels and initial milestone for the current repository." echo "Create standard labels and initial milestone for the current repository."
echo "" echo ""
echo "Options:" echo "Options:"
echo " --skip-milestone Skip creating the 0.1.0 MVP milestone" echo " --skip-milestone Skip creating the 0.0.1 pre-MVP milestone"
echo " -h, --help Show this help" echo " -h, --help Show this help"
exit 0 exit 0
;; ;;
@@ -107,14 +107,16 @@ done
echo "" echo ""
# Create initial milestone # Create initial pre-MVP milestone
if [[ "$SKIP_MILESTONE" != true ]]; then if [[ "$SKIP_MILESTONE" != true ]]; then
echo "Creating initial milestone..." echo "Creating initial pre-MVP milestone..."
"$GIT_SCRIPT_DIR/milestone-create.sh" -t "0.1.0" -d "MVP - Minimum Viable Product" 2>/dev/null && \ "$GIT_SCRIPT_DIR/milestone-create.sh" -t "0.0.1" -d "Pre-MVP - Foundation Sprint" 2>/dev/null && \
echo " [created] Milestone '0.1.0 - MVP'" || \ echo " [created] Milestone '0.0.1 - Pre-MVP'" || \
echo " [skip] Milestone may already exist or creation failed" echo " [skip] Milestone may already exist or creation failed"
echo " [note] Reserve 0.1.0 for MVP release milestone"
echo "" echo ""
fi fi

View File

@@ -260,6 +260,6 @@ For best results, use `gpt-5.2-codex` or newer for strongest review accuracy.
## See Also ## See Also
- `~/.config/mosaic/guides/code-review.md` — Manual code review checklist - `~/.config/mosaic/guides/CODE-REVIEW.md` — Manual code review checklist
- `~/.config/mosaic/rails/git/` — Git helper scripts (issue/PR management) - `~/.config/mosaic/rails/git/` — Git helper scripts (issue/PR management)
- OpenAI Codex CLI docs: https://developers.openai.com/codex/cli/ - OpenAI Codex CLI docs: https://developers.openai.com/codex/cli/

247
rails/git/ci-queue-wait.ps1 Normal file
View File

@@ -0,0 +1,247 @@
# ci-queue-wait.ps1 - Wait until project CI queue is clear (no running/queued pipeline on branch head)
# Usage: .\ci-queue-wait.ps1 [-Branch main] [-TimeoutSeconds 900] [-IntervalSeconds 15] [-Purpose merge] [-RequireStatus]
[CmdletBinding()]
param(
[Alias("B")]
[string]$Branch = "main",
[Alias("t")]
[int]$TimeoutSeconds = 900,
[Alias("i")]
[int]$IntervalSeconds = 15,
[ValidateSet("push", "merge")]
[string]$Purpose = "merge",
[switch]$RequireStatus,
[Alias("h")]
[switch]$Help
)
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
. "$ScriptDir\detect-platform.ps1"
function Show-Usage {
@"
Usage: ci-queue-wait.ps1 [-Branch main] [-TimeoutSeconds 900] [-IntervalSeconds 15] [-Purpose push|merge] [-RequireStatus]
Options:
-Branch, -B BRANCH Branch head to inspect (default: main)
-TimeoutSeconds, -t SECONDS Max wait time (default: 900)
-IntervalSeconds, -i SECONDS Poll interval (default: 15)
-Purpose VALUE push or merge (default: merge)
-RequireStatus Fail if no CI status contexts are present
-Help, -h Show help
"@
}
if ($Help) {
Show-Usage
exit 0
}
if ($TimeoutSeconds -lt 1 -or $IntervalSeconds -lt 1) {
Write-Error "TimeoutSeconds and IntervalSeconds must be positive integers."
exit 1
}
function Get-RemoteHost {
$remoteUrl = git remote get-url origin 2>$null
if ([string]::IsNullOrEmpty($remoteUrl)) { return $null }
if ($remoteUrl -match "^https?://([^/]+)/") { return $Matches[1] }
if ($remoteUrl -match "^git@([^:]+):") { return $Matches[1] }
return $null
}
function Get-GiteaToken {
param([string]$Host)
if ($env:GITEA_TOKEN) { return $env:GITEA_TOKEN }
$credPath = Join-Path $HOME ".git-credentials"
if (-not (Test-Path $credPath)) { return $null }
$line = Get-Content $credPath | Where-Object { $_ -like "*$Host*" } | Select-Object -First 1
if (-not $line) { return $null }
if ($line -match 'https?://[^@]*:([^@/]+)@') {
return $Matches[1]
}
return $null
}
function Get-QueueState {
param([object]$Payload)
$pending = @("pending", "queued", "running", "waiting")
$failure = @("failure", "error", "failed")
$success = @("success")
$state = ""
if ($null -ne $Payload.state) {
$state = "$($Payload.state)".ToLowerInvariant()
}
if ($pending -contains $state) { return "pending" }
if ($failure -contains $state) { return "terminal-failure" }
if ($success -contains $state) { return "terminal-success" }
$values = @()
$statuses = @()
if ($null -ne $Payload.statuses) { $statuses = @($Payload.statuses) }
foreach ($s in $statuses) {
if ($null -eq $s) { continue }
$v = ""
if ($null -ne $s.status) { $v = "$($s.status)".ToLowerInvariant() }
elseif ($null -ne $s.state) { $v = "$($s.state)".ToLowerInvariant() }
if (-not [string]::IsNullOrEmpty($v)) { $values += $v }
}
if ($values.Count -eq 0 -and [string]::IsNullOrEmpty($state)) { return "no-status" }
if (($values | Where-Object { $pending -contains $_ }).Count -gt 0) { return "pending" }
if (($values | Where-Object { $failure -contains $_ }).Count -gt 0) { return "terminal-failure" }
if ($values.Count -gt 0 -and ($values | Where-Object { -not ($success -contains $_) }).Count -eq 0) { return "terminal-success" }
return "unknown"
}
function Print-PendingContexts {
param([object]$Payload)
$pending = @("pending", "queued", "running", "waiting")
$statuses = @()
if ($null -ne $Payload.statuses) { $statuses = @($Payload.statuses) }
if ($statuses.Count -eq 0) {
Write-Host "[ci-queue-wait] no status contexts reported"
return
}
$found = $false
foreach ($s in $statuses) {
if ($null -eq $s) { continue }
$name = if ($s.context) { $s.context } elseif ($s.name) { $s.name } else { "unknown-context" }
$value = if ($s.status) { "$($s.status)".ToLowerInvariant() } elseif ($s.state) { "$($s.state)".ToLowerInvariant() } else { "unknown" }
$target = if ($s.target_url) { $s.target_url } elseif ($s.url) { $s.url } else { "" }
if ($pending -contains $value) {
$found = $true
if ($target) {
Write-Host "[ci-queue-wait] pending: $name=$value ($target)"
}
else {
Write-Host "[ci-queue-wait] pending: $name=$value"
}
}
}
if (-not $found) {
Write-Host "[ci-queue-wait] no pending contexts"
}
}
$platform = Get-GitPlatform
$owner = Get-GitRepoOwner
$repo = Get-GitRepoName
if ([string]::IsNullOrEmpty($owner) -or [string]::IsNullOrEmpty($repo)) {
Write-Error "Could not determine repository owner/name from git remote."
exit 1
}
$headSha = $null
$host = $null
$giteaToken = $null
switch ($platform) {
"github" {
if (-not (Get-Command gh -ErrorAction SilentlyContinue)) {
Write-Error "gh CLI is required for GitHub CI queue guard."
exit 1
}
$headSha = (& gh api "repos/$owner/$repo/branches/$Branch" --jq ".commit.sha").Trim()
if ([string]::IsNullOrEmpty($headSha)) {
Write-Error "Could not resolve $Branch head SHA."
exit 1
}
Write-Host "[ci-queue-wait] platform=github purpose=$Purpose branch=$Branch sha=$headSha"
}
"gitea" {
$host = Get-RemoteHost
if ([string]::IsNullOrEmpty($host)) {
Write-Error "Could not determine remote host."
exit 1
}
$giteaToken = Get-GiteaToken -Host $host
if ([string]::IsNullOrEmpty($giteaToken)) {
Write-Error "Gitea token not found. Set GITEA_TOKEN or configure ~/.git-credentials."
exit 1
}
try {
$branchUrl = "https://$host/api/v1/repos/$owner/$repo/branches/$Branch"
$branchPayload = Invoke-RestMethod -Method Get -Uri $branchUrl -Headers @{ Authorization = "token $giteaToken" }
$headSha = ($branchPayload.commit.id | Out-String).Trim()
}
catch {
Write-Error "Could not resolve $Branch head SHA from Gitea API."
exit 1
}
if ([string]::IsNullOrEmpty($headSha)) {
Write-Error "Could not resolve $Branch head SHA."
exit 1
}
Write-Host "[ci-queue-wait] platform=gitea purpose=$Purpose branch=$Branch sha=$headSha"
}
default {
Write-Error "Unsupported platform '$platform'."
exit 1
}
}
$deadline = (Get-Date).AddSeconds($TimeoutSeconds)
while ($true) {
if ((Get-Date) -gt $deadline) {
Write-Error "Timed out waiting for CI queue to clear on $Branch after ${TimeoutSeconds}s."
exit 124
}
try {
if ($platform -eq "github") {
$statusJson = & gh api "repos/$owner/$repo/commits/$headSha/status"
$payload = $statusJson | ConvertFrom-Json
}
else {
$statusUrl = "https://$host/api/v1/repos/$owner/$repo/commits/$headSha/status"
$payload = Invoke-RestMethod -Method Get -Uri $statusUrl -Headers @{ Authorization = "token $giteaToken" }
}
}
catch {
Write-Error "Failed to query commit status for queue guard."
exit 1
}
$state = Get-QueueState -Payload $payload
Write-Host "[ci-queue-wait] state=$state purpose=$Purpose branch=$Branch"
switch ($state) {
"pending" {
Print-PendingContexts -Payload $payload
Start-Sleep -Seconds $IntervalSeconds
}
"no-status" {
if ($RequireStatus) {
Write-Error "No CI status contexts found while -RequireStatus is set."
exit 1
}
Write-Host "[ci-queue-wait] no status contexts present; proceeding."
exit 0
}
"terminal-success" { exit 0 }
"terminal-failure" { exit 0 }
"unknown" { exit 0 }
default { exit 0 }
}
}

307
rails/git/ci-queue-wait.sh Executable file
View File

@@ -0,0 +1,307 @@
#!/bin/bash
# ci-queue-wait.sh - Wait until project CI queue is clear (no running/queued pipeline on branch head)
# Usage: ci-queue-wait.sh [-B branch] [-t timeout_sec] [-i interval_sec] [--purpose push|merge] [--require-status]
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/detect-platform.sh"
BRANCH="main"
TIMEOUT_SEC=900
INTERVAL_SEC=15
PURPOSE="merge"
REQUIRE_STATUS=0
usage() {
cat <<EOF
Usage: $(basename "$0") [-B branch] [-t timeout_sec] [-i interval_sec] [--purpose push|merge] [--require-status]
Options:
-B, --branch BRANCH Branch head to inspect (default: main)
-t, --timeout SECONDS Max wait time in seconds (default: 900)
-i, --interval SECONDS Poll interval in seconds (default: 15)
--purpose VALUE Log context: push|merge (default: merge)
--require-status Fail if no CI status contexts are present
-h, --help Show this help
Examples:
$(basename "$0")
$(basename "$0") --purpose push -B main -t 600 -i 10
EOF
}
get_remote_host() {
local remote_url
remote_url=$(git remote get-url origin 2>/dev/null || true)
if [[ -z "$remote_url" ]]; then
return 1
fi
if [[ "$remote_url" =~ ^https?://([^/]+)/ ]]; then
echo "${BASH_REMATCH[1]}"
return 0
fi
if [[ "$remote_url" =~ ^git@([^:]+): ]]; then
echo "${BASH_REMATCH[1]}"
return 0
fi
return 1
}
get_gitea_token() {
local host="$1"
if [[ -n "${GITEA_TOKEN:-}" ]]; then
echo "$GITEA_TOKEN"
return 0
fi
local creds="$HOME/.git-credentials"
if [[ -f "$creds" ]]; then
local token
token=$(grep -F "$host" "$creds" 2>/dev/null | sed -n 's#https\?://[^@]*:\([^@/]*\)@.*#\1#p' | head -n 1)
if [[ -n "$token" ]]; then
echo "$token"
return 0
fi
fi
return 1
}
get_state_from_status_json() {
python3 - <<'PY'
import json
import sys
try:
payload = json.load(sys.stdin)
except Exception:
print("unknown")
raise SystemExit(0)
statuses = payload.get("statuses") or []
state = (payload.get("state") or "").lower()
pending_values = {"pending", "queued", "running", "waiting"}
failure_values = {"failure", "error", "failed"}
success_values = {"success"}
if state in pending_values:
print("pending")
raise SystemExit(0)
if state in failure_values:
print("terminal-failure")
raise SystemExit(0)
if state in success_values:
print("terminal-success")
raise SystemExit(0)
values = []
for item in statuses:
if not isinstance(item, dict):
continue
value = (item.get("status") or item.get("state") or "").lower()
if value:
values.append(value)
if not values and not state:
print("no-status")
elif any(v in pending_values for v in values):
print("pending")
elif any(v in failure_values for v in values):
print("terminal-failure")
elif values and all(v in success_values for v in values):
print("terminal-success")
else:
print("unknown")
PY
}
print_pending_contexts() {
python3 - <<'PY'
import json
import sys
try:
payload = json.load(sys.stdin)
except Exception:
print("[ci-queue-wait] unable to decode status payload")
raise SystemExit(0)
statuses = payload.get("statuses") or []
if not statuses:
print("[ci-queue-wait] no status contexts reported")
raise SystemExit(0)
pending_values = {"pending", "queued", "running", "waiting"}
found = False
for item in statuses:
if not isinstance(item, dict):
continue
name = item.get("context") or item.get("name") or "unknown-context"
value = (item.get("status") or item.get("state") or "unknown").lower()
target = item.get("target_url") or item.get("url") or ""
if value in pending_values:
found = True
if target:
print(f"[ci-queue-wait] pending: {name}={value} ({target})")
else:
print(f"[ci-queue-wait] pending: {name}={value}")
if not found:
print("[ci-queue-wait] no pending contexts")
PY
}
github_get_branch_head_sha() {
local owner="$1"
local repo="$2"
local branch="$3"
gh api "repos/${owner}/${repo}/branches/${branch}" --jq '.commit.sha'
}
github_get_commit_status_json() {
local owner="$1"
local repo="$2"
local sha="$3"
gh api "repos/${owner}/${repo}/commits/${sha}/status"
}
gitea_get_branch_head_sha() {
local host="$1"
local repo="$2"
local branch="$3"
local token="$4"
local url="https://${host}/api/v1/repos/${repo}/branches/${branch}"
curl -fsS -H "Authorization: token ${token}" "$url" | python3 -c '
import json, sys
data = json.load(sys.stdin)
commit = data.get("commit") or {}
print((commit.get("id") or "").strip())
'
}
gitea_get_commit_status_json() {
local host="$1"
local repo="$2"
local sha="$3"
local token="$4"
local url="https://${host}/api/v1/repos/${repo}/commits/${sha}/status"
curl -fsS -H "Authorization: token ${token}" "$url"
}
while [[ $# -gt 0 ]]; do
case "$1" in
-B|--branch)
BRANCH="$2"
shift 2
;;
-t|--timeout)
TIMEOUT_SEC="$2"
shift 2
;;
-i|--interval)
INTERVAL_SEC="$2"
shift 2
;;
--purpose)
PURPOSE="$2"
shift 2
;;
--require-status)
REQUIRE_STATUS=1
shift
;;
-h|--help)
usage
exit 0
;;
*)
echo "Unknown option: $1" >&2
usage >&2
exit 1
;;
esac
done
if ! [[ "$TIMEOUT_SEC" =~ ^[0-9]+$ ]] || ! [[ "$INTERVAL_SEC" =~ ^[0-9]+$ ]]; then
echo "Error: timeout and interval must be integer seconds." >&2
exit 1
fi
OWNER=$(get_repo_owner)
REPO=$(get_repo_name)
detect_platform > /dev/null
PLATFORM="${PLATFORM:-unknown}"
if [[ "$PLATFORM" == "github" ]]; then
if ! command -v gh >/dev/null 2>&1; then
echo "Error: gh CLI is required for GitHub CI queue guard." >&2
exit 1
fi
HEAD_SHA=$(github_get_branch_head_sha "$OWNER" "$REPO" "$BRANCH")
if [[ -z "$HEAD_SHA" ]]; then
echo "Error: Could not resolve ${BRANCH} head SHA." >&2
exit 1
fi
echo "[ci-queue-wait] platform=github purpose=${PURPOSE} branch=${BRANCH} sha=${HEAD_SHA}"
elif [[ "$PLATFORM" == "gitea" ]]; then
HOST=$(get_remote_host) || {
echo "Error: Could not determine remote host." >&2
exit 1
}
TOKEN=$(get_gitea_token "$HOST") || {
echo "Error: Gitea token not found. Set GITEA_TOKEN or configure ~/.git-credentials." >&2
exit 1
}
HEAD_SHA=$(gitea_get_branch_head_sha "$HOST" "$OWNER/$REPO" "$BRANCH" "$TOKEN")
if [[ -z "$HEAD_SHA" ]]; then
echo "Error: Could not resolve ${BRANCH} head SHA." >&2
exit 1
fi
echo "[ci-queue-wait] platform=gitea purpose=${PURPOSE} branch=${BRANCH} sha=${HEAD_SHA}"
else
echo "Error: Unsupported platform '${PLATFORM}'." >&2
exit 1
fi
START_TS=$(date +%s)
DEADLINE_TS=$((START_TS + TIMEOUT_SEC))
while true; do
NOW_TS=$(date +%s)
if (( NOW_TS > DEADLINE_TS )); then
echo "Error: Timed out waiting for CI queue to clear on ${BRANCH} after ${TIMEOUT_SEC}s." >&2
exit 124
fi
if [[ "$PLATFORM" == "github" ]]; then
STATUS_JSON=$(github_get_commit_status_json "$OWNER" "$REPO" "$HEAD_SHA")
else
STATUS_JSON=$(gitea_get_commit_status_json "$HOST" "$OWNER/$REPO" "$HEAD_SHA" "$TOKEN")
fi
STATE=$(printf '%s' "$STATUS_JSON" | get_state_from_status_json)
echo "[ci-queue-wait] state=${STATE} purpose=${PURPOSE} branch=${BRANCH}"
case "$STATE" in
pending)
printf '%s' "$STATUS_JSON" | print_pending_contexts
sleep "$INTERVAL_SEC"
;;
no-status)
if [[ "$REQUIRE_STATUS" -eq 1 ]]; then
echo "Error: No CI status contexts found for ${BRANCH} while --require-status is set." >&2
exit 1
fi
echo "[ci-queue-wait] no status contexts present; proceeding."
exit 0
;;
terminal-success|terminal-failure|unknown)
# Queue guard only blocks on pending/running/queued states.
exit 0
;;
*)
echo "[ci-queue-wait] unrecognized state '${STATE}', proceeding conservatively."
exit 0
;;
esac
done

View File

@@ -13,6 +13,80 @@ BODY=""
LABELS="" LABELS=""
MILESTONE="" MILESTONE=""
get_remote_host() {
local remote_url
remote_url=$(git remote get-url origin 2>/dev/null || true)
if [[ -z "$remote_url" ]]; then
return 1
fi
if [[ "$remote_url" =~ ^https?://([^/]+)/ ]]; then
echo "${BASH_REMATCH[1]}"
return 0
fi
if [[ "$remote_url" =~ ^git@([^:]+): ]]; then
echo "${BASH_REMATCH[1]}"
return 0
fi
return 1
}
get_gitea_token() {
local host="$1"
if [[ -n "${GITEA_TOKEN:-}" ]]; then
echo "$GITEA_TOKEN"
return 0
fi
local creds="$HOME/.git-credentials"
if [[ -f "$creds" ]]; then
local token
token=$(grep -F "$host" "$creds" 2>/dev/null | sed -n 's#https\?://[^@]*:\([^@/]*\)@.*#\1#p' | head -n 1)
if [[ -n "$token" ]]; then
echo "$token"
return 0
fi
fi
return 1
}
gitea_issue_create_api() {
local host repo token url payload
host=$(get_remote_host) || {
echo "Error: could not determine remote host for API fallback" >&2
return 1
}
repo=$(get_repo_info) || {
echo "Error: could not determine repo owner/name for API fallback" >&2
return 1
}
token=$(get_gitea_token "$host") || {
echo "Error: Gitea token not found for API fallback (set GITEA_TOKEN or configure ~/.git-credentials)" >&2
return 1
}
if [[ -n "$LABELS" || -n "$MILESTONE" ]]; then
echo "Warning: API fallback currently applies title/body only; labels/milestone require authenticated tea setup." >&2
fi
payload=$(TITLE="$TITLE" BODY="$BODY" python3 - <<'PY'
import json
import os
payload = {"title": os.environ["TITLE"]}
body = os.environ.get("BODY", "")
if body:
payload["body"] = body
print(json.dumps(payload))
PY
)
url="https://${host}/api/v1/repos/${repo}/issues"
curl -fsS -X POST \
-H "Authorization: token ${token}" \
-H "Content-Type: application/json" \
-d "$payload" \
"$url"
}
usage() { usage() {
cat <<EOF cat <<EOF
Usage: $(basename "$0") [OPTIONS] Usage: $(basename "$0") [OPTIONS]
@@ -78,12 +152,18 @@ case "$PLATFORM" in
eval "$CMD" eval "$CMD"
;; ;;
gitea) gitea)
CMD="tea issue create --title \"$TITLE\"" if command -v tea >/dev/null 2>&1; then
[[ -n "$BODY" ]] && CMD="$CMD --description \"$BODY\"" CMD="tea issue create --title \"$TITLE\""
[[ -n "$LABELS" ]] && CMD="$CMD --labels \"$LABELS\"" [[ -n "$BODY" ]] && CMD="$CMD --description \"$BODY\""
# tea accepts milestone by name directly (verified 2026-02-05) [[ -n "$LABELS" ]] && CMD="$CMD --labels \"$LABELS\""
[[ -n "$MILESTONE" ]] && CMD="$CMD --milestone \"$MILESTONE\"" # tea accepts milestone by name directly (verified 2026-02-05)
eval "$CMD" [[ -n "$MILESTONE" ]] && CMD="$CMD --milestone \"$MILESTONE\""
if eval "$CMD"; then
exit 0
fi
echo "Warning: tea issue create failed, trying Gitea API fallback..." >&2
fi
gitea_issue_create_api
;; ;;
*) *)
echo "Error: Could not detect git platform" >&2 echo "Error: Could not detect git platform" >&2

View File

@@ -10,6 +10,64 @@ source "$SCRIPT_DIR/detect-platform.sh"
# Parse arguments # Parse arguments
ISSUE_NUMBER="" ISSUE_NUMBER=""
get_remote_host() {
local remote_url
remote_url=$(git remote get-url origin 2>/dev/null || true)
if [[ -z "$remote_url" ]]; then
return 1
fi
if [[ "$remote_url" =~ ^https?://([^/]+)/ ]]; then
echo "${BASH_REMATCH[1]}"
return 0
fi
if [[ "$remote_url" =~ ^git@([^:]+): ]]; then
echo "${BASH_REMATCH[1]}"
return 0
fi
return 1
}
get_gitea_token() {
local host="$1"
if [[ -n "${GITEA_TOKEN:-}" ]]; then
echo "$GITEA_TOKEN"
return 0
fi
local creds="$HOME/.git-credentials"
if [[ -f "$creds" ]]; then
local token
token=$(grep -F "$host" "$creds" 2>/dev/null | sed -n 's#https\?://[^@]*:\([^@/]*\)@.*#\1#p' | head -n 1)
if [[ -n "$token" ]]; then
echo "$token"
return 0
fi
fi
return 1
}
gitea_issue_view_api() {
local host repo token url
host=$(get_remote_host) || {
echo "Error: could not determine remote host for API fallback" >&2
return 1
}
repo=$(get_repo_info) || {
echo "Error: could not determine repo owner/name for API fallback" >&2
return 1
}
token=$(get_gitea_token "$host") || {
echo "Error: Gitea token not found for API fallback (set GITEA_TOKEN or configure ~/.git-credentials)" >&2
return 1
}
url="https://${host}/api/v1/repos/${repo}/issues/${ISSUE_NUMBER}"
if command -v python3 >/dev/null 2>&1; then
curl -fsS -H "Authorization: token ${token}" "$url" | python3 -m json.tool
else
curl -fsS -H "Authorization: token ${token}" "$url"
fi
}
while [[ $# -gt 0 ]]; do while [[ $# -gt 0 ]]; do
case $1 in case $1 in
-i|--issue) -i|--issue)
@@ -41,7 +99,13 @@ detect_platform
if [[ "$PLATFORM" == "github" ]]; then if [[ "$PLATFORM" == "github" ]]; then
gh issue view "$ISSUE_NUMBER" gh issue view "$ISSUE_NUMBER"
elif [[ "$PLATFORM" == "gitea" ]]; then elif [[ "$PLATFORM" == "gitea" ]]; then
tea issue "$ISSUE_NUMBER" if command -v tea >/dev/null 2>&1; then
if tea issue "$ISSUE_NUMBER"; then
exit 0
fi
echo "Warning: tea issue view failed, trying Gitea API fallback..." >&2
fi
gitea_issue_view_api
else else
echo "Error: Unknown platform" echo "Error: Unknown platform"
exit 1 exit 1

View File

@@ -28,12 +28,12 @@ Create or list milestones on the current repository (Gitea or GitHub).
Versioning Convention: Versioning Convention:
- Features get dedicated milestones - Features get dedicated milestones
- Pre-release: 0.X.0 for breaking changes, 0.X.Y for patches - Pre-MVP milestones MUST use 0.0.x and MUST start at 0.0.1
- Post-release: X.0.0 for breaking changes - 0.1.0 is reserved for MVP release
- MVP starts at 0.1.0 - After MVP, continue semantic progression (0.1.x, 0.2.x, ...)
Options: Options:
-Title, -t TITLE Milestone title/version (e.g., "0.2.0") -Title, -t TITLE Milestone title/version (e.g., "0.0.1")
-Description, -d DESC Milestone description -Description, -d DESC Milestone description
-Due DATE Due date (YYYY-MM-DD format) -Due DATE Due date (YYYY-MM-DD format)
-List List existing milestones -List List existing milestones
@@ -41,8 +41,8 @@ Options:
Examples: Examples:
.\milestone-create.ps1 -List .\milestone-create.ps1 -List
.\milestone-create.ps1 -t "0.1.0" -d "MVP Release" .\milestone-create.ps1 -t "0.0.1" -d "Pre-MVP Foundation Sprint"
.\milestone-create.ps1 -t "0.2.0" -d "User Authentication Feature" -Due "2025-03-01" .\milestone-create.ps1 -t "0.1.0" -d "MVP Release" -Due "2025-03-01"
"@ "@
exit 1 exit 1
} }

View File

@@ -21,12 +21,12 @@ Create or list milestones on the current repository (Gitea or GitHub).
Versioning Convention: Versioning Convention:
- Features get dedicated milestones - Features get dedicated milestones
- Pre-release: 0.X.0 for breaking changes, 0.X.Y for patches - Pre-MVP milestones MUST use 0.0.x and MUST start at 0.0.1
- Post-release: X.0.0 for breaking changes - 0.1.0 is reserved for MVP release
- MVP starts at 0.1.0 - After MVP, continue semantic progression (0.1.x, 0.2.x, ...)
Options: Options:
-t, --title TITLE Milestone title/version (e.g., "0.2.0") -t, --title TITLE Milestone title/version (e.g., "0.0.1")
-d, --desc DESCRIPTION Milestone description -d, --desc DESCRIPTION Milestone description
--due DATE Due date (YYYY-MM-DD format) --due DATE Due date (YYYY-MM-DD format)
--list List existing milestones --list List existing milestones
@@ -34,8 +34,8 @@ Options:
Examples: Examples:
$(basename "$0") --list $(basename "$0") --list
$(basename "$0") -t "0.1.0" -d "MVP Release" $(basename "$0") -t "0.0.1" -d "Pre-MVP Foundation Sprint"
$(basename "$0") -t "0.2.0" -d "User Authentication Feature" --due "2025-03-01" $(basename "$0") -t "0.1.0" -d "MVP Release" --due "2025-03-01"
EOF EOF
exit 1 exit 1
} }

273
rails/git/pr-ci-wait.sh Executable file
View File

@@ -0,0 +1,273 @@
#!/bin/bash
# pr-ci-wait.sh - Wait for PR CI status to reach terminal state (GitHub/Gitea)
# Usage: pr-ci-wait.sh -n <pr_number> [-t timeout_sec] [-i interval_sec]
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/detect-platform.sh"
PR_NUMBER=""
TIMEOUT_SEC=1800
INTERVAL_SEC=15
usage() {
cat <<EOF
Usage: $(basename "$0") -n <pr_number> [-t timeout_sec] [-i interval_sec]
Options:
-n, --number NUMBER PR number (required)
-t, --timeout SECONDS Max wait time in seconds (default: 1800)
-i, --interval SECONDS Poll interval in seconds (default: 15)
-h, --help Show this help
Examples:
$(basename "$0") -n 643
$(basename "$0") -n 643 -t 900 -i 10
EOF
}
get_remote_host() {
local remote_url
remote_url=$(git remote get-url origin 2>/dev/null || true)
if [[ -z "$remote_url" ]]; then
return 1
fi
if [[ "$remote_url" =~ ^https?://([^/]+)/ ]]; then
echo "${BASH_REMATCH[1]}"
return 0
fi
if [[ "$remote_url" =~ ^git@([^:]+): ]]; then
echo "${BASH_REMATCH[1]}"
return 0
fi
return 1
}
get_gitea_token() {
local host="$1"
if [[ -n "${GITEA_TOKEN:-}" ]]; then
echo "$GITEA_TOKEN"
return 0
fi
local creds="$HOME/.git-credentials"
if [[ -f "$creds" ]]; then
local token
token=$(grep -F "$host" "$creds" 2>/dev/null | sed -n 's#https\?://[^@]*:\([^@/]*\)@.*#\1#p' | head -n 1)
if [[ -n "$token" ]]; then
echo "$token"
return 0
fi
fi
return 1
}
extract_state_from_status_json() {
python3 - <<'PY'
import json
import sys
try:
payload = json.load(sys.stdin)
except Exception:
print("unknown")
raise SystemExit(0)
state = (payload.get("state") or "").lower()
if state in {"success", "pending", "failure", "error"}:
print(state)
raise SystemExit(0)
statuses = payload.get("statuses") or []
values = []
for item in statuses:
if not isinstance(item, dict):
continue
value = (item.get("status") or item.get("state") or "").lower()
if value:
values.append(value)
if any(v in {"failure", "error"} for v in values):
print("failure")
elif values and all(v == "success" for v in values):
print("success")
elif any(v in {"pending", "running", "queued", "waiting"} for v in values):
print("pending")
else:
print("unknown")
PY
}
print_status_summary() {
python3 - <<'PY'
import json
import sys
try:
payload = json.load(sys.stdin)
except Exception:
print("[pr-ci-wait] status payload unavailable")
raise SystemExit(0)
statuses = payload.get("statuses") or []
if not statuses:
print("[pr-ci-wait] no status contexts reported yet")
raise SystemExit(0)
for item in statuses:
if not isinstance(item, dict):
continue
name = item.get("context") or item.get("name") or "unknown-context"
state = item.get("status") or item.get("state") or "unknown-state"
target = item.get("target_url") or item.get("url") or ""
if target:
print(f"[pr-ci-wait] {name}: {state} ({target})")
else:
print(f"[pr-ci-wait] {name}: {state}")
PY
}
github_get_pr_head_sha() {
gh pr view "$PR_NUMBER" --json headRefOid --jq '.headRefOid'
}
github_get_commit_status_json() {
local owner="$1"
local repo="$2"
local sha="$3"
gh api "repos/${owner}/${repo}/commits/${sha}/status"
}
gitea_get_pr_head_sha() {
local host="$1"
local repo="$2"
local token="$3"
local url="https://${host}/api/v1/repos/${repo}/pulls/${PR_NUMBER}"
curl -fsS -H "Authorization: token ${token}" "$url" | python3 -c '
import json, sys
data = json.load(sys.stdin)
print((data.get("head") or {}).get("sha", ""))
'
}
gitea_get_commit_status_json() {
local host="$1"
local repo="$2"
local token="$3"
local sha="$4"
local url="https://${host}/api/v1/repos/${repo}/commits/${sha}/status"
curl -fsS -H "Authorization: token ${token}" "$url"
}
while [[ $# -gt 0 ]]; do
case "$1" in
-n|--number)
PR_NUMBER="$2"
shift 2
;;
-t|--timeout)
TIMEOUT_SEC="$2"
shift 2
;;
-i|--interval)
INTERVAL_SEC="$2"
shift 2
;;
-h|--help)
usage
exit 0
;;
*)
echo "Unknown option: $1" >&2
usage >&2
exit 1
;;
esac
done
if [[ -z "$PR_NUMBER" ]]; then
echo "Error: PR number is required (-n)." >&2
usage >&2
exit 1
fi
if ! [[ "$TIMEOUT_SEC" =~ ^[0-9]+$ ]] || ! [[ "$INTERVAL_SEC" =~ ^[0-9]+$ ]]; then
echo "Error: timeout and interval must be integer seconds." >&2
exit 1
fi
detect_platform > /dev/null
OWNER=$(get_repo_owner)
REPO=$(get_repo_name)
START_TS=$(date +%s)
DEADLINE_TS=$((START_TS + TIMEOUT_SEC))
if [[ "$PLATFORM" == "github" ]]; then
if ! command -v gh >/dev/null 2>&1; then
echo "Error: gh CLI is required for GitHub CI status polling." >&2
exit 1
fi
HEAD_SHA=$(github_get_pr_head_sha)
if [[ -z "$HEAD_SHA" ]]; then
echo "Error: Could not resolve head SHA for PR #$PR_NUMBER." >&2
exit 1
fi
echo "[pr-ci-wait] Platform=github PR=#${PR_NUMBER} head_sha=${HEAD_SHA}"
elif [[ "$PLATFORM" == "gitea" ]]; then
HOST=$(get_remote_host) || {
echo "Error: Could not determine remote host." >&2
exit 1
}
TOKEN=$(get_gitea_token "$HOST") || {
echo "Error: Gitea token not found. Set GITEA_TOKEN or configure ~/.git-credentials." >&2
exit 1
}
HEAD_SHA=$(gitea_get_pr_head_sha "$HOST" "$OWNER/$REPO" "$TOKEN")
if [[ -z "$HEAD_SHA" ]]; then
echo "Error: Could not resolve head SHA for PR #$PR_NUMBER." >&2
exit 1
fi
echo "[pr-ci-wait] Platform=gitea host=${HOST} PR=#${PR_NUMBER} head_sha=${HEAD_SHA}"
else
echo "Error: Unsupported platform '${PLATFORM}'." >&2
exit 1
fi
while true; do
NOW_TS=$(date +%s)
if (( NOW_TS > DEADLINE_TS )); then
echo "Error: Timed out waiting for CI status on PR #$PR_NUMBER after ${TIMEOUT_SEC}s." >&2
exit 124
fi
if [[ "$PLATFORM" == "github" ]]; then
STATUS_JSON=$(github_get_commit_status_json "$OWNER" "$REPO" "$HEAD_SHA")
else
STATUS_JSON=$(gitea_get_commit_status_json "$HOST" "$OWNER/$REPO" "$TOKEN" "$HEAD_SHA")
fi
STATE=$(printf '%s' "$STATUS_JSON" | extract_state_from_status_json)
echo "[pr-ci-wait] state=${STATE} pr=#${PR_NUMBER} sha=${HEAD_SHA}"
case "$STATE" in
success)
printf '%s' "$STATUS_JSON" | print_status_summary
echo "[pr-ci-wait] CI is green for PR #$PR_NUMBER."
exit 0
;;
failure|error)
printf '%s' "$STATUS_JSON" | print_status_summary
echo "Error: CI reported ${STATE} for PR #$PR_NUMBER." >&2
exit 1
;;
pending|unknown)
sleep "$INTERVAL_SEC"
;;
*)
echo "[pr-ci-wait] Unrecognized state '${STATE}', continuing to poll..."
sleep "$INTERVAL_SEC"
;;
esac
done

47
rails/git/pr-merge.ps1 Normal file → Executable file
View File

@@ -1,5 +1,5 @@
# pr-merge.ps1 - Merge pull requests on Gitea or GitHub # pr-merge.ps1 - Merge pull requests on Gitea or GitHub
# Usage: .\pr-merge.ps1 -Number PR_NUMBER [-Method method] [-DeleteBranch] # Usage: .\pr-merge.ps1 -Number PR_NUMBER [-Method squash] [-DeleteBranch]
[CmdletBinding()] [CmdletBinding()]
param( param(
@@ -8,12 +8,13 @@ param(
[int]$Number, [int]$Number,
[Alias("m")] [Alias("m")]
[ValidateSet("merge", "squash", "rebase")] [string]$Method = "squash",
[string]$Method = "merge",
[Alias("d")] [Alias("d")]
[switch]$DeleteBranch, [switch]$DeleteBranch,
[switch]$SkipQueueGuard,
[Alias("h")] [Alias("h")]
[switch]$Help [switch]$Help
) )
@@ -29,14 +30,15 @@ Merge a pull request on the current repository (Gitea or GitHub).
Options: Options:
-Number, -n NUMBER PR number to merge (required) -Number, -n NUMBER PR number to merge (required)
-Method, -m METHOD Merge method: merge, squash, rebase (default: merge) -Method, -m METHOD Merge method: squash only (default: squash)
-DeleteBranch, -d Delete the head branch after merge -DeleteBranch, -d Delete the head branch after merge
-SkipQueueGuard Skip CI queue guard wait before merge
-Help, -h Show this help message -Help, -h Show this help message
Examples: Examples:
.\pr-merge.ps1 -n 42 # Merge PR #42 .\pr-merge.ps1 -n 42 # Merge PR #42
.\pr-merge.ps1 -n 42 -m squash # Squash merge .\pr-merge.ps1 -n 42 -m squash # Squash merge
.\pr-merge.ps1 -n 42 -m rebase -d # Rebase and delete branch .\pr-merge.ps1 -n 42 -d # Squash merge and delete branch
"@ "@
exit 1 exit 1
} }
@@ -45,27 +47,42 @@ if ($Help) {
Show-Usage Show-Usage
} }
if ($Method -ne "squash") {
Write-Error "Mosaic policy enforces squash merge only. Received '$Method'."
exit 1
}
$platform = Get-GitPlatform $platform = Get-GitPlatform
switch ($platform) { switch ($platform) {
"github" { "github" {
$cmd = @("gh", "pr", "merge", $Number) $baseRef = (& gh pr view $Number --json baseRefName --jq ".baseRefName").Trim()
switch ($Method) { if ($baseRef -ne "main") {
"merge" { $cmd += "--merge" } Write-Error "Mosaic policy allows merges only for PRs targeting 'main' (found '$baseRef')."
"squash" { $cmd += "--squash" } exit 1
"rebase" { $cmd += "--rebase" }
} }
if (-not $SkipQueueGuard) {
$timeout = if ($env:MOSAIC_CI_QUEUE_TIMEOUT_SEC) { [int]$env:MOSAIC_CI_QUEUE_TIMEOUT_SEC } else { 900 }
$interval = if ($env:MOSAIC_CI_QUEUE_POLL_SEC) { [int]$env:MOSAIC_CI_QUEUE_POLL_SEC } else { 15 }
& "$ScriptDir\ci-queue-wait.ps1" -Purpose merge -Branch $baseRef -TimeoutSeconds $timeout -IntervalSeconds $interval
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
}
$cmd = @("gh", "pr", "merge", $Number, "--squash")
if ($DeleteBranch) { $cmd += "--delete-branch" } if ($DeleteBranch) { $cmd += "--delete-branch" }
& $cmd[0] $cmd[1..($cmd.Length-1)] & $cmd[0] $cmd[1..($cmd.Length-1)]
} }
"gitea" { "gitea" {
$cmd = @("tea", "pr", "merge", $Number) if (-not $SkipQueueGuard) {
switch ($Method) { $timeout = if ($env:MOSAIC_CI_QUEUE_TIMEOUT_SEC) { [int]$env:MOSAIC_CI_QUEUE_TIMEOUT_SEC } else { 900 }
"merge" { $cmd += @("--style", "merge") } $interval = if ($env:MOSAIC_CI_QUEUE_POLL_SEC) { [int]$env:MOSAIC_CI_QUEUE_POLL_SEC } else { 15 }
"squash" { $cmd += @("--style", "squash") } & "$ScriptDir\ci-queue-wait.ps1" -Purpose merge -Branch "main" -TimeoutSeconds $timeout -IntervalSeconds $interval
"rebase" { $cmd += @("--style", "rebase") } if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
} }
$cmd = @("tea", "pr", "merge", $Number, "--style", "squash")
if ($DeleteBranch) { if ($DeleteBranch) {
Write-Warning "Branch deletion after merge may need to be done separately with tea" Write-Warning "Branch deletion after merge may need to be done separately with tea"
} }

View File

@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# pr-merge.sh - Merge pull requests on Gitea or GitHub # pr-merge.sh - Merge pull requests on Gitea or GitHub
# Usage: pr-merge.sh -n PR_NUMBER [-m method] [-d] # Usage: pr-merge.sh -n PR_NUMBER [-m squash] [-d] [--skip-queue-guard]
set -e set -e
@@ -9,8 +9,9 @@ source "$SCRIPT_DIR/detect-platform.sh"
# Default values # Default values
PR_NUMBER="" PR_NUMBER=""
MERGE_METHOD="merge" # merge, squash, rebase MERGE_METHOD="squash"
DELETE_BRANCH=false DELETE_BRANCH=false
SKIP_QUEUE_GUARD=false
usage() { usage() {
cat <<EOF cat <<EOF
@@ -20,14 +21,16 @@ Merge a pull request on the current repository (Gitea or GitHub).
Options: Options:
-n, --number NUMBER PR number to merge (required) -n, --number NUMBER PR number to merge (required)
-m, --method METHOD Merge method: merge, squash, rebase (default: merge) -m, --method METHOD Merge method: squash only (default: squash)
-d, --delete-branch Delete the head branch after merge -d, --delete-branch Delete the head branch after merge
--skip-queue-guard Skip CI queue guard wait before merge
-h, --help Show this help message -h, --help Show this help message
Examples: Examples:
$(basename "$0") -n 42 # Merge PR #42 $(basename "$0") -n 42 # Merge PR #42
$(basename "$0") -n 42 -m squash # Squash merge $(basename "$0") -n 42 -m squash # Squash merge
$(basename "$0") -n 42 -m rebase -d # Rebase and delete branch $(basename "$0") -n 42 -d # Squash merge and delete branch
$(basename "$0") -n 42 --skip-queue-guard # Skip queue guard wait
EOF EOF
exit 1 exit 1
} }
@@ -47,6 +50,10 @@ while [[ $# -gt 0 ]]; do
DELETE_BRANCH=true DELETE_BRANCH=true
shift shift
;; ;;
--skip-queue-guard)
SKIP_QUEUE_GUARD=true
shift
;;
-h|--help) -h|--help)
usage usage
;; ;;
@@ -62,37 +69,36 @@ if [[ -z "$PR_NUMBER" ]]; then
usage usage
fi fi
if [[ "$MERGE_METHOD" != "squash" ]]; then
echo "Error: Mosaic policy enforces squash merge only. Received '$MERGE_METHOD'." >&2
exit 1
fi
BASE_BRANCH="$("$SCRIPT_DIR/pr-metadata.sh" -n "$PR_NUMBER" | python3 -c 'import json, sys; print((json.load(sys.stdin).get("baseRefName") or "").strip())')"
if [[ "$BASE_BRANCH" != "main" ]]; then
echo "Error: Mosaic policy allows merges only for PRs targeting 'main' (found '$BASE_BRANCH')." >&2
exit 1
fi
if [[ "$SKIP_QUEUE_GUARD" != true ]]; then
"$SCRIPT_DIR/ci-queue-wait.sh" \
--purpose merge \
-B "$BASE_BRANCH" \
-t "${MOSAIC_CI_QUEUE_TIMEOUT_SEC:-900}" \
-i "${MOSAIC_CI_QUEUE_POLL_SEC:-15}"
fi
PLATFORM=$(detect_platform) PLATFORM=$(detect_platform)
case "$PLATFORM" in case "$PLATFORM" in
github) github)
CMD="gh pr merge $PR_NUMBER" CMD="gh pr merge $PR_NUMBER --squash"
case "$MERGE_METHOD" in
merge) CMD="$CMD --merge" ;;
squash) CMD="$CMD --squash" ;;
rebase) CMD="$CMD --rebase" ;;
*)
echo "Error: Invalid merge method '$MERGE_METHOD'" >&2
exit 1
;;
esac
[[ "$DELETE_BRANCH" == true ]] && CMD="$CMD --delete-branch" [[ "$DELETE_BRANCH" == true ]] && CMD="$CMD --delete-branch"
eval "$CMD" eval "$CMD"
;; ;;
gitea) gitea)
# tea pr merge syntax # tea pr merge syntax
CMD="tea pr merge $PR_NUMBER" CMD="tea pr merge $PR_NUMBER --style squash"
# tea merge style flags
case "$MERGE_METHOD" in
merge) CMD="$CMD --style merge" ;;
squash) CMD="$CMD --style squash" ;;
rebase) CMD="$CMD --style rebase" ;;
*)
echo "Error: Invalid merge method '$MERGE_METHOD'" >&2
exit 1
;;
esac
# Delete branch after merge if requested # Delete branch after merge if requested
if [[ "$DELETE_BRANCH" == true ]]; then if [[ "$DELETE_BRANCH" == true ]]; then

View File

@@ -46,7 +46,7 @@ Continuous loop:
~/.config/mosaic/bin/mosaic-orchestrator-run --poll-sec 10 ~/.config/mosaic/bin/mosaic-orchestrator-run --poll-sec 10
``` ```
Sync from `docs/tasks.md` to queue: Sync from `docs/TASKS.md` to queue:
```bash ```bash
~/.config/mosaic/bin/mosaic-orchestrator-sync-tasks --apply ~/.config/mosaic/bin/mosaic-orchestrator-sync-tasks --apply

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Sync docs/tasks.md rows into .mosaic/orchestrator/tasks.json.""" """Sync docs/TASKS.md rows into .mosaic/orchestrator/tasks.json."""
from __future__ import annotations from __future__ import annotations
@@ -89,7 +89,12 @@ def parse_depends(raw: str) -> list[str]:
return [x.strip() for x in raw.split(",") if x.strip()] return [x.strip() for x in raw.split(",") if x.strip()]
def build_task(row: dict[str, str], existing: dict[str, Any], runtime_default: str) -> dict[str, Any]: def build_task(
row: dict[str, str],
existing: dict[str, Any],
runtime_default: str,
source_path: str,
) -> dict[str, Any]:
task_id = row.get("id", "").strip() task_id = row.get("id", "").strip()
description = row.get("description", "").strip() description = row.get("description", "").strip()
issue = row.get("issue", "").strip() issue = row.get("issue", "").strip()
@@ -109,7 +114,7 @@ def build_task(row: dict[str, str], existing: dict[str, Any], runtime_default: s
metadata = dict(task.get("metadata") or {}) metadata = dict(task.get("metadata") or {})
metadata.update( metadata.update(
{ {
"source": "docs/tasks.md", "source": source_path,
"issue": issue, "issue": issue,
"repo": repo, "repo": repo,
"branch": branch, "branch": branch,
@@ -120,26 +125,35 @@ def build_task(row: dict[str, str], existing: dict[str, Any], runtime_default: s
def main() -> int: def main() -> int:
parser = argparse.ArgumentParser(description="Sync docs/tasks.md into .mosaic/orchestrator/tasks.json") parser = argparse.ArgumentParser(description="Sync docs/TASKS.md into .mosaic/orchestrator/tasks.json")
parser.add_argument("--repo", default=os.getcwd(), help="Repository root (default: cwd)") parser.add_argument("--repo", default=os.getcwd(), help="Repository root (default: cwd)")
parser.add_argument("--docs", default="docs/tasks.md", help="Path to tasks markdown (repo-relative)") parser.add_argument("--docs", default="docs/TASKS.md", help="Path to tasks markdown (repo-relative)")
parser.add_argument( parser.add_argument(
"--tasks-json", "--tasks-json",
default=".mosaic/orchestrator/tasks.json", default=".mosaic/orchestrator/tasks.json",
help="Path to orchestrator tasks JSON (repo-relative)", help="Path to orchestrator tasks JSON (repo-relative)",
) )
parser.add_argument("--keep-unlisted", action="store_true", help="Retain tasks already in JSON but missing from docs/tasks.md") parser.add_argument("--keep-unlisted", action="store_true", help="Retain tasks already in JSON but missing from docs/TASKS.md")
parser.add_argument("--apply", action="store_true", help="Write changes (default is dry-run)") parser.add_argument("--apply", action="store_true", help="Write changes (default is dry-run)")
args = parser.parse_args() args = parser.parse_args()
repo = pathlib.Path(args.repo).resolve() repo = pathlib.Path(args.repo).resolve()
docs_path = (repo / args.docs).resolve() docs_path = (repo / args.docs).resolve()
# Backward compatibility: fall back to legacy lowercase path when default path is absent.
if args.docs == "docs/TASKS.md" and not docs_path.exists():
legacy_docs_path = (repo / "docs/tasks.md").resolve()
if legacy_docs_path.exists():
docs_path = legacy_docs_path
tasks_path = (repo / args.tasks_json).resolve() tasks_path = (repo / args.tasks_json).resolve()
config_path = repo / ".mosaic" / "orchestrator" / "config.json" config_path = repo / ".mosaic" / "orchestrator" / "config.json"
config = load_json(config_path, {}) config = load_json(config_path, {})
runtime_default = str(config.get("worker", {}).get("runtime") or "codex") runtime_default = str(config.get("worker", {}).get("runtime") or "codex")
rows = parse_tasks_markdown(docs_path) rows = parse_tasks_markdown(docs_path)
try:
source_path = str(docs_path.relative_to(repo))
except ValueError:
source_path = str(docs_path)
existing_payload = load_json(tasks_path, {"tasks": []}) existing_payload = load_json(tasks_path, {"tasks": []})
existing_tasks = existing_payload.get("tasks", []) existing_tasks = existing_payload.get("tasks", [])
if not isinstance(existing_tasks, list): if not isinstance(existing_tasks, list):
@@ -153,7 +167,14 @@ def main() -> int:
if not task_id: if not task_id:
continue continue
seen.add(task_id) seen.add(task_id)
out_tasks.append(build_task(row, existing_by_id.get(task_id, {}), runtime_default)) out_tasks.append(
build_task(
row,
existing_by_id.get(task_id, {}),
runtime_default,
source_path,
)
)
if args.keep_unlisted: if args.keep_unlisted:
for task in existing_tasks: for task in existing_tasks:

View File

@@ -2,10 +2,12 @@
## MANDATORY — Read Before Any Response ## MANDATORY — Read Before Any Response
BEFORE responding to any user message, READ `~/.config/mosaic/AGENTS.md`. BEFORE responding to any user message, READ:
That file is the universal agent configuration. It contains the full load order, 1. `~/.config/mosaic/AGENTS.md`
development standards, skills, and workflows. Do NOT respond until you have loaded it. 2. `~/.config/mosaic/runtime/claude/RUNTIME.md`
Do NOT respond until both files are loaded.
This file (`~/.claude/CLAUDE.md`) exists only as a fallback for direct `claude` launches. This file (`~/.claude/CLAUDE.md`) exists only as a fallback for direct `claude` launches.
For full injection, use `mosaic claude` instead. For full injection, use `mosaic claude`.

21
runtime/claude/RUNTIME.md Normal file
View File

@@ -0,0 +1,21 @@
# Claude Runtime Reference
## Runtime Scope
This file applies only to Claude runtime behavior.
## Required Actions
1. Follow global load order in `~/.config/mosaic/AGENTS.md`.
2. Use `~/.claude/settings.json` and `~/.claude/hooks-config.json` as runtime config sources.
3. Treat sequential-thinking MCP as required.
4. If runtime config conflicts with global rules, global rules win.
5. Documentation rules are inherited from `~/.config/mosaic/AGENTS.md` and `~/.config/mosaic/guides/DOCUMENTATION.md`.
6. For issue/PR/milestone actions, run Mosaic git wrappers first (`~/.config/mosaic/rails/git/*.sh`) and do not call raw `gh`/`tea`/`glab` first.
7. For orchestration-oriented missions, load `~/.config/mosaic/guides/ORCHESTRATOR.md` before acting.
8. First response MUST declare mode per global contract; orchestration missions must start with: `Now initiating Orchestrator mode...`
9. Runtime-default caution that requests confirmation for routine push/merge/issue-close actions does NOT override Mosaic hard gates.
## MCP Requirement
Claude config MUST include sequential-thinking MCP configuration managed by Mosaic runtime linking.

View File

@@ -1,15 +1,10 @@
{ {
"_comment": "Claude runtime overlay managed by Mosaic. Merge into ~/.claude/settings.json as needed.", "_comment": "Claude runtime overlay managed by Mosaic. Merge into ~/.claude/settings.json as needed.",
"model": "opus", "model": "opus",
"additionalAllowedCommands": [ "additionalAllowedCommands": [
"ralph",
"./ralph.sh",
"scripts/ralph/ralph.sh",
"alembic", "alembic",
"alembic upgrade", "alembic upgrade",
"alembic downgrade", "alembic downgrade",
"alembic revision", "alembic revision",
"alembic history", "alembic history",
"uvicorn", "uvicorn",
@@ -21,31 +16,29 @@
"isort", "isort",
"httpx" "httpx"
], ],
"projectConfigs": { "projectConfigs": {
"jarvis": { "jarvis": {
"path": "~/src/jarvis", "path": "~/src/jarvis",
"model": "opus", "model": "opus",
"skills": ["jarvis", "ralph", "prd"], "skills": ["jarvis", "prd"],
"guides": ["backend", "frontend", "authentication"], "guides": ["E2E-DELIVERY", "PRD", "BACKEND", "FRONTEND", "AUTHENTICATION", "QA-TESTING", "CODE-REVIEW"],
"env": { "env": {
"PYTHONPATH": "packages/plugins" "PYTHONPATH": "packages/plugins"
} }
} }
}, },
"presets": { "presets": {
"jarvis-ralph": { "jarvis-loop": {
"description": "Ralph autonomous development for Jarvis", "description": "Embedded E2E delivery cycle for Jarvis",
"model": "opus", "model": "opus",
"skills": ["jarvis", "ralph"], "skills": ["jarvis", "prd"],
"systemPrompt": "You are an autonomous coding agent following the Ralph pattern. Focus on one story at a time, run quality checks, and commit only when passing." "systemPrompt": "You are an autonomous coding agent. For each logical unit, execute: plan, code, test, review, remediate, review, commit, push, then run a greenfield situational test. Repeat until requirements are complete."
}, },
"jarvis-review": { "jarvis-review": {
"description": "Code review mode for Jarvis PRs", "description": "Code review mode for Jarvis PRs",
"model": "opus", "model": "opus",
"skills": ["jarvis"], "skills": ["jarvis"],
"guides": ["code-review"], "guides": ["CODE-REVIEW"],
"systemPrompt": "Review code changes for quality, security, and adherence to Jarvis patterns." "systemPrompt": "Review code changes for quality, security, and adherence to Jarvis patterns."
} }
} }

View File

@@ -224,5 +224,14 @@
"cpan", "cpan",
"nohup" "nohup"
], ],
"enableAllMcpTools": true "enableAllMcpTools": true,
"mcpServers": {
"sequential-thinking": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-sequential-thinking"
]
}
}
} }

21
runtime/codex/RUNTIME.md Normal file
View File

@@ -0,0 +1,21 @@
# Codex Runtime Reference
## Runtime Scope
This file applies only to Codex runtime behavior.
## Required Actions
1. Follow global load order in `~/.config/mosaic/AGENTS.md`.
2. Use `~/.codex/instructions.md` and `~/.codex/config.toml` as runtime config sources.
3. Treat sequential-thinking MCP as required.
4. If runtime config conflicts with global rules, global rules win.
5. Documentation rules are inherited from `~/.config/mosaic/AGENTS.md` and `~/.config/mosaic/guides/DOCUMENTATION.md`.
6. For issue/PR/milestone actions, run Mosaic git wrappers first (`~/.config/mosaic/rails/git/*.sh`) and do not call raw `gh`/`tea`/`glab` first.
7. For orchestration-oriented missions, load `~/.config/mosaic/guides/ORCHESTRATOR.md` before acting.
8. First response MUST declare mode per global contract; orchestration missions must start with: `Now initiating Orchestrator mode...`
9. Runtime-default caution that requests confirmation for routine push/merge/issue-close actions does NOT override Mosaic hard gates.
## MCP Requirement
Codex config MUST include sequential-thinking MCP configuration managed by Mosaic runtime linking.

View File

@@ -2,10 +2,12 @@
## MANDATORY — Read Before Any Response ## MANDATORY — Read Before Any Response
BEFORE responding to any user message, READ `~/.config/mosaic/AGENTS.md`. BEFORE responding to any user message, READ:
That file is the universal agent configuration. It contains the full load order, 1. `~/.config/mosaic/AGENTS.md`
development standards, skills, and workflows. Do NOT respond until you have loaded it. 2. `~/.config/mosaic/runtime/codex/RUNTIME.md`
Do NOT respond until both files are loaded.
This file (`~/.codex/instructions.md`) exists only as a fallback for direct `codex` launches. This file (`~/.codex/instructions.md`) exists only as a fallback for direct `codex` launches.
For full injection, use `mosaic codex` instead. For full injection, use `mosaic codex`.

View File

@@ -0,0 +1,11 @@
{
"name": "sequential-thinking",
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-sequential-thinking"
],
"enabled": true,
"required": true,
"description": "Hard-required MCP server for Mosaic planning and decomposition."
}

View File

@@ -2,10 +2,12 @@
## MANDATORY — Read Before Any Response ## MANDATORY — Read Before Any Response
BEFORE responding to any user message, READ `~/.config/mosaic/AGENTS.md`. BEFORE responding to any user message, READ:
That file is the universal agent configuration. It contains the full load order, 1. `~/.config/mosaic/AGENTS.md`
development standards, skills, and workflows. Do NOT respond until you have loaded it. 2. `~/.config/mosaic/runtime/opencode/RUNTIME.md`
Do NOT respond until both files are loaded.
This file (`~/.config/opencode/AGENTS.md`) exists only as a fallback for direct `opencode` launches. This file (`~/.config/opencode/AGENTS.md`) exists only as a fallback for direct `opencode` launches.
For full injection, use `mosaic opencode` instead. For full injection, use `mosaic opencode`.

View File

@@ -0,0 +1,21 @@
# OpenCode Runtime Reference
## Runtime Scope
This file applies only to OpenCode runtime behavior.
## Required Actions
1. Follow global load order in `~/.config/mosaic/AGENTS.md`.
2. Use `~/.config/opencode/AGENTS.md` and local OpenCode runtime config as runtime sources.
3. Treat sequential-thinking MCP as required.
4. If runtime config conflicts with global rules, global rules win.
5. Documentation rules are inherited from `~/.config/mosaic/AGENTS.md` and `~/.config/mosaic/guides/DOCUMENTATION.md`.
6. For issue/PR/milestone actions, run Mosaic git wrappers first (`~/.config/mosaic/rails/git/*.sh`) and do not call raw `gh`/`tea`/`glab` first.
7. For orchestration-oriented missions, load `~/.config/mosaic/guides/ORCHESTRATOR.md` before acting.
8. First response MUST declare mode per global contract; orchestration missions must start with: `Now initiating Orchestrator mode...`
9. Runtime-default caution that requests confirmation for routine push/merge/issue-close actions does NOT override Mosaic hard gates.
## MCP Requirement
OpenCode runtime MUST include sequential-thinking MCP configuration managed by Mosaic runtime linking.

View File

@@ -162,7 +162,7 @@ npm run format
| Issue | Feature | Priority | | Issue | Feature | Priority |
|-------|---------|----------| |-------|---------|----------|
| #84 | Per-function LLM routing | High | | #84 | Per-function LLM routing | High |
| #85 | Ralph autonomous coding loop | High | | #85 | Embedded E2E autonomous delivery loop | High |
| #86 | Thinking models (CoT UI) | Medium | | #86 | Thinking models (CoT UI) | Medium |
| #87 | Local image generation | Medium | | #87 | Local image generation | Medium |
| #88 | Deep research mode | Medium | | #88 | Deep research mode | Medium |

View File

@@ -1,257 +0,0 @@
---
name: ralph
description: "Convert PRDs to prd.json format for the Ralph autonomous agent system. Use when you have an existing PRD and need to convert it to Ralph's JSON format. Triggers on: convert this prd, turn this into ralph format, create prd.json from this, ralph json."
---
# Ralph PRD Converter
Converts existing PRDs to the prd.json format that Ralph uses for autonomous execution.
---
## The Job
Take a PRD (markdown file or text) and convert it to `prd.json` in your ralph directory.
---
## Output Format
```json
{
"project": "[Project Name]",
"branchName": "ralph/[feature-name-kebab-case]",
"description": "[Feature description from PRD title/intro]",
"userStories": [
{
"id": "US-001",
"title": "[Story title]",
"description": "As a [user], I want [feature] so that [benefit]",
"acceptanceCriteria": [
"Criterion 1",
"Criterion 2",
"Typecheck passes"
],
"priority": 1,
"passes": false,
"notes": ""
}
]
}
```
---
## Story Size: The Number One Rule
**Each story must be completable in ONE Ralph iteration (one context window).**
Ralph spawns a fresh Amp instance per iteration with no memory of previous work. If a story is too big, the LLM runs out of context before finishing and produces broken code.
### Right-sized stories:
- Add a database column and migration
- Add a UI component to an existing page
- Update a server action with new logic
- Add a filter dropdown to a list
### Too big (split these):
- "Build the entire dashboard" - Split into: schema, queries, UI components, filters
- "Add authentication" - Split into: schema, middleware, login UI, session handling
- "Refactor the API" - Split into one story per endpoint or pattern
**Rule of thumb:** If you cannot describe the change in 2-3 sentences, it is too big.
---
## Story Ordering: Dependencies First
Stories execute in priority order. Earlier stories must not depend on later ones.
**Correct order:**
1. Schema/database changes (migrations)
2. Server actions / backend logic
3. UI components that use the backend
4. Dashboard/summary views that aggregate data
**Wrong order:**
1. UI component (depends on schema that does not exist yet)
2. Schema change
---
## Acceptance Criteria: Must Be Verifiable
Each criterion must be something Ralph can CHECK, not something vague.
### Good criteria (verifiable):
- "Add `status` column to tasks table with default 'pending'"
- "Filter dropdown has options: All, Active, Completed"
- "Clicking delete shows confirmation dialog"
- "Typecheck passes"
- "Tests pass"
### Bad criteria (vague):
- "Works correctly"
- "User can do X easily"
- "Good UX"
- "Handles edge cases"
### Always include as final criterion:
```
"Typecheck passes"
```
For stories with testable logic, also include:
```
"Tests pass"
```
### For stories that change UI, also include:
```
"Verify in browser using dev-browser skill"
```
Frontend stories are NOT complete until visually verified. Ralph will use the dev-browser skill to navigate to the page, interact with the UI, and confirm changes work.
---
## Conversion Rules
1. **Each user story becomes one JSON entry**
2. **IDs**: Sequential (US-001, US-002, etc.)
3. **Priority**: Based on dependency order, then document order
4. **All stories**: `passes: false` and empty `notes`
5. **branchName**: Derive from feature name, kebab-case, prefixed with `ralph/`
6. **Always add**: "Typecheck passes" to every story's acceptance criteria
---
## Splitting Large PRDs
If a PRD has big features, split them:
**Original:**
> "Add user notification system"
**Split into:**
1. US-001: Add notifications table to database
2. US-002: Create notification service for sending notifications
3. US-003: Add notification bell icon to header
4. US-004: Create notification dropdown panel
5. US-005: Add mark-as-read functionality
6. US-006: Add notification preferences page
Each is one focused change that can be completed and verified independently.
---
## Example
**Input PRD:**
```markdown
# Task Status Feature
Add ability to mark tasks with different statuses.
## Requirements
- Toggle between pending/in-progress/done on task list
- Filter list by status
- Show status badge on each task
- Persist status in database
```
**Output prd.json:**
```json
{
"project": "TaskApp",
"branchName": "ralph/task-status",
"description": "Task Status Feature - Track task progress with status indicators",
"userStories": [
{
"id": "US-001",
"title": "Add status field to tasks table",
"description": "As a developer, I need to store task status in the database.",
"acceptanceCriteria": [
"Add status column: 'pending' | 'in_progress' | 'done' (default 'pending')",
"Generate and run migration successfully",
"Typecheck passes"
],
"priority": 1,
"passes": false,
"notes": ""
},
{
"id": "US-002",
"title": "Display status badge on task cards",
"description": "As a user, I want to see task status at a glance.",
"acceptanceCriteria": [
"Each task card shows colored status badge",
"Badge colors: gray=pending, blue=in_progress, green=done",
"Typecheck passes",
"Verify in browser using dev-browser skill"
],
"priority": 2,
"passes": false,
"notes": ""
},
{
"id": "US-003",
"title": "Add status toggle to task list rows",
"description": "As a user, I want to change task status directly from the list.",
"acceptanceCriteria": [
"Each row has status dropdown or toggle",
"Changing status saves immediately",
"UI updates without page refresh",
"Typecheck passes",
"Verify in browser using dev-browser skill"
],
"priority": 3,
"passes": false,
"notes": ""
},
{
"id": "US-004",
"title": "Filter tasks by status",
"description": "As a user, I want to filter the list to see only certain statuses.",
"acceptanceCriteria": [
"Filter dropdown: All | Pending | In Progress | Done",
"Filter persists in URL params",
"Typecheck passes",
"Verify in browser using dev-browser skill"
],
"priority": 4,
"passes": false,
"notes": ""
}
]
}
```
---
## Archiving Previous Runs
**Before writing a new prd.json, check if there is an existing one from a different feature:**
1. Read the current `prd.json` if it exists
2. Check if `branchName` differs from the new feature's branch name
3. If different AND `progress.txt` has content beyond the header:
- Create archive folder: `archive/YYYY-MM-DD-feature-name/`
- Copy current `prd.json` and `progress.txt` to archive
- Reset `progress.txt` with fresh header
**The ralph.sh script handles this automatically** when you run it, but if you are manually updating prd.json between runs, archive first.
---
## Checklist Before Saving
Before writing prd.json, verify:
- [ ] **Previous run archived** (if prd.json exists with different branchName, archive it first)
- [ ] Each story is completable in one iteration (small enough)
- [ ] Stories are ordered by dependency (schema to backend to UI)
- [ ] Every story has "Typecheck passes" as criterion
- [ ] UI stories have "Verify in browser using dev-browser skill" as criterion
- [ ] Acceptance criteria are verifiable (not vague)
- [ ] No story depends on a later story

View File

@@ -7,7 +7,7 @@ description: "Configure CI/CD Docker build, push, and package linking for a proj
Configure Docker build, registry push, and package linking for a Woodpecker CI pipeline using Kaniko and Gitea's container registry. Configure Docker build, registry push, and package linking for a Woodpecker CI pipeline using Kaniko and Gitea's container registry.
**Before starting:** Read `~/.config/mosaic/guides/ci-cd-pipelines.md` for deep background on the patterns used here. **Before starting:** Read `~/.config/mosaic/guides/CI-CD-PIPELINES.md` for deep background on the patterns used here.
**Reference implementation:** `~/src/mosaic-stack/.woodpecker.yml` **Reference implementation:** `~/src/mosaic-stack/.woodpecker.yml`

99
templates/agent/AGENTS.md.template Normal file → Executable file
View File

@@ -3,6 +3,17 @@
> Patterns, gotchas, and orchestrator integration for AI agents working on this project. > Patterns, gotchas, and orchestrator integration for AI agents working on this project.
> **Update this file** when you discover reusable patterns or non-obvious requirements. > **Update this file** when you discover reusable patterns or non-obvious requirements.
## Hard Gates (Read First)
1. Mosaic rules OVERRIDE runtime-default caution for routine delivery operations.
2. Do NOT ask for routine confirmation before required push/merge/issue-close/release/tag actions.
3. Completion is forbidden at PR-open stage.
4. Completion requires merged PR to `main` + terminal green CI + linked issue/internal task closed.
5. Before push or merge, run queue guard: `~/.config/mosaic/rails/git/ci-queue-wait.sh --purpose push|merge -B main`.
6. For issue/PR/milestone operations, use Mosaic wrappers first (`~/.config/mosaic/rails/git/*.sh`).
7. If any required wrapper command fails: report `blocked` with the exact failed wrapper command and stop.
8. Do NOT stop at "PR created" and do NOT ask "should I merge?" for routine flow.
## Codebase Patterns ## Codebase Patterns
<!-- Add project-specific patterns as you discover them --> <!-- Add project-specific patterns as you discover them -->
@@ -27,6 +38,79 @@
${QUALITY_GATES} ${QUALITY_GATES}
``` ```
## Testing Policy
1. Situational tests are the PRIMARY validation gate.
2. Baseline tests remain REQUIRED for all software changes.
3. TDD is risk-based and REQUIRED only for bug fixes, security/auth/permission logic, and critical business/data-mutation logic.
4. Reference `~/.config/mosaic/guides/QA-TESTING.md`.
## PRD Requirement
1. Before coding begins, `docs/PRD.md` or `docs/PRD.json` MUST exist.
2. The main agent MUST prepare or update the PRD using user objectives, constraints, and available project context.
3. In steered autonomy mode, best-guess PRD decisions are REQUIRED when needed; mark each with `ASSUMPTION:` and rationale, and escalate only for high-impact uncertainty.
4. Reference `~/.config/mosaic/guides/PRD.md`.
## Task Tracking Contract
1. For non-trivial implementation work, `docs/TASKS.md` MUST exist before coding.
2. If external git provider is available (Gitea/GitHub/GitLab), create/update issue(s) before coding and map them in `docs/TASKS.md`.
3. If no external provider is available, use internal refs in `docs/TASKS.md` (example: `TASKS:T1`).
4. Keep `docs/TASKS.md` status in sync with actual progress until completion.
5. For issue/PR/milestone actions, detect platform and use `~/.config/mosaic/rails/git/*.sh` wrappers first (no raw `gh`/`tea`/`glab` as first choice).
6. If wrapper-driven merge/CI/issue-closure fails, report blocker with the exact failed wrapper command and stop (do not claim completion).
## Documentation Contract
Documentation is a hard delivery gate.
If code/API/auth/infra changes, required documentation updates MUST be completed before task closure.
Keep `docs/` root clean and store reports/artifacts in scoped folders (`docs/reports/`, `docs/tasks/`, `docs/releases/`, `docs/scratchpads/`).
Reference:
- `~/.config/mosaic/guides/DOCUMENTATION.md`
- `~/.config/mosaic/templates/docs/DOCUMENTATION-CHECKLIST.md`
## Token Budget Policy
1. If user plan or token limits are provided, they are HARD constraints.
2. Track estimated and used tokens for non-trivial execution.
3. Shift to conservative strategy when budget pressure rises (smaller scope, fewer parallel actions, reduced re-reading).
4. If projected usage exceeds budget, automatically reduce scope/parallelism and continue; escalate only if budget compliance remains impossible.
## Merge Strategy (Hard Rule)
1. Create short-lived branches from `main`.
2. Open PRs to `main` for delivery changes.
3. Do not push directly to `main`.
4. Merge PRs to `main` with squash strategy only.
5. Do not mark implementation complete until PR is merged.
6. Do not mark implementation complete until CI/pipeline status is terminal green.
7. Close linked issues/tasks only after merge + green CI.
8. Before push or merge, run CI queue guard: `~/.config/mosaic/rails/git/ci-queue-wait.sh --purpose push|merge -B main`.
## Container Release Strategy (When Applicable)
1. Use immutable image tags: `sha-<shortsha>` and `v{base-version}-rc.{build}`.
2. Use mutable environment tags only as pointers (`testing`, optional `staging`, `prod`).
3. Deploy/promote by immutable digest; do not deploy by mutable tag alone.
4. Do not use `latest` or `dev` as deployment references.
5. Use blue-green by default; use canary only with automated metrics and rollback gates.
## Steered Autonomy Contract
1. Agent owns end-to-end delivery: plan, code, test, review, remediate, commit, push, PR/repo operations, release/tag, and deployment when in scope.
2. Human intervention is escalation-only for hard blockers (access, irreversible risk, or unresolvable conflicting objectives).
3. Code review is agent-executed and REQUIRED for any source-code change.
## Mode Declaration Contract
1. First response MUST declare mode before any actions.
2. Orchestration mission: `Now initiating Orchestrator mode...`
3. Implementation mission: `Now initiating Delivery mode...`
4. Review-only mission: `Now initiating Review mode...`
## Orchestrator Integration ## Orchestrator Integration
### Task Prefix ### Task Prefix
@@ -43,14 +127,17 @@ Use `${TASK_PREFIX}` as the prefix for orchestrated tasks (e.g., `${TASK_PREFIX}
### Worker Checklist ### Worker Checklist
When completing an orchestrated task: When completing an orchestrated task:
1. Read the finding details from the report 1. Read `docs/PRD.md` or `docs/PRD.json`
2. Implement the fix following existing code patterns 2. Read the finding details from the report
3. Run quality gates (ALL must pass) 3. Implement the fix following existing code patterns
4. Commit with: `git commit -m "fix({finding_id}): brief description"` 4. Run quality gates (ALL must pass)
5. Report result as JSON to orchestrator 5. Complete required documentation updates (if applicable)
6. Commit with: `git commit -m "fix({finding_id}): brief description"`
7. Report result as JSON to orchestrator
### Post-Coding Review ### Post-Coding Review
After implementing changes, the orchestrator will run: After implementing changes, code review is REQUIRED for any source-code modification.
For orchestrated tasks, the orchestrator will run:
1. **Codex code review** — `~/.config/mosaic/rails/codex/codex-code-review.sh --uncommitted` 1. **Codex code review** — `~/.config/mosaic/rails/codex/codex-code-review.sh --uncommitted`
2. **Codex security review** — `~/.config/mosaic/rails/codex/codex-security-review.sh --uncommitted` 2. **Codex security review** — `~/.config/mosaic/rails/codex/codex-security-review.sh --uncommitted`
3. If blockers/critical findings: remediation task created 3. If blockers/critical findings: remediation task created

102
templates/agent/CLAUDE.md.template Normal file → Executable file
View File

@@ -1,4 +1,4 @@
# ${PROJECT_NAME} — Claude Code Instructions # ${PROJECT_NAME} — Runtime Compatibility Instructions
> **Project:** ${PROJECT_DESCRIPTION} > **Project:** ${PROJECT_DESCRIPTION}
> **Repository:** ${REPO_URL} > **Repository:** ${REPO_URL}
@@ -20,18 +20,21 @@ git push
## Conditional Documentation Loading ## Conditional Documentation Loading
**Read the relevant guide before starting work:** **Load `~/.config/mosaic/guides/E2E-DELIVERY.md` first, then load the relevant guide before starting work:**
| Task Type | Guide | | Task Type | Guide |
|-----------|-------| |-----------|-------|
| Bootstrapping this project | `~/.config/mosaic/guides/bootstrap.md` | | End-to-end implementation and validation | `~/.config/mosaic/guides/E2E-DELIVERY.md` |
| Orchestrating autonomous tasks | `~/.config/mosaic/guides/orchestrator.md` | | PRD creation and requirements definition | `~/.config/mosaic/guides/PRD.md` |
| Code review | `~/.config/mosaic/guides/code-review.md` | | Bootstrapping this project | `~/.config/mosaic/guides/BOOTSTRAP.md` |
| Frontend development | `~/.config/mosaic/guides/frontend.md` | | Orchestrating autonomous tasks | `~/.config/mosaic/guides/ORCHESTRATOR.md` |
| Backend/API development | `~/.config/mosaic/guides/backend.md` | | Code review | `~/.config/mosaic/guides/CODE-REVIEW.md` |
| Authentication/Authorization | `~/.config/mosaic/guides/authentication.md` | | Documentation updates and standards | `~/.config/mosaic/guides/DOCUMENTATION.md` |
| Infrastructure/DevOps | `~/.config/mosaic/guides/infrastructure.md` | | Frontend development | `~/.config/mosaic/guides/FRONTEND.md` |
| QA/Testing | `~/.config/mosaic/guides/qa-testing.md` | | Backend/API development | `~/.config/mosaic/guides/BACKEND.md` |
| Authentication/Authorization | `~/.config/mosaic/guides/AUTHENTICATION.md` |
| Infrastructure/DevOps | `~/.config/mosaic/guides/INFRASTRUCTURE.md` |
| QA/Testing | `~/.config/mosaic/guides/QA-TESTING.md` |
## Technology Stack ## Technology Stack
@@ -50,6 +53,7 @@ ${PROJECT_DIR}/
├── CLAUDE.md # This file ├── CLAUDE.md # This file
├── AGENTS.md # Agent-specific patterns and gotchas ├── AGENTS.md # Agent-specific patterns and gotchas
├── docs/ ├── docs/
│ ├── PRD.md # Requirements source (or PRD.json)
│ ├── scratchpads/ # Per-issue working documents │ ├── scratchpads/ # Per-issue working documents
│ └── templates/ # Project templates (if any) │ └── templates/ # Project templates (if any)
├── ${SOURCE_DIR}/ # Application source code ├── ${SOURCE_DIR}/ # Application source code
@@ -60,10 +64,10 @@ ${PROJECT_DIR}/
## Development Workflow ## Development Workflow
### Branch Strategy ### Branch Strategy
- `main` — Production-ready code - `main` — Protected delivery branch
- `develop` — Integration branch (if applicable) - `feat/<name>` / `fix/<name>` — Short-lived task branches created from `main`
- `feat/<name>` — Feature branches - All changes merge through PR into `main` only
- `fix/<name>` — Bug fix branches - Merge strategy for `main` PRs is squash-only
### Building ### Building
```bash ```bash
@@ -93,15 +97,63 @@ ${TYPECHECK_COMMAND}
${QUALITY_GATES} ${QUALITY_GATES}
``` ```
## Testing Policy
1. Situational tests are the PRIMARY validation gate.
2. Baseline tests are REQUIRED for all software changes.
3. TDD is risk-based; required cases are defined in `~/.config/mosaic/guides/QA-TESTING.md`.
## PRD Requirement
1. Before coding begins, `docs/PRD.md` or `docs/PRD.json` MUST exist.
2. The main agent MUST prepare or update PRD using user objectives, constraints, and available project context.
3. In steered autonomy mode, best-guess PRD decisions are REQUIRED when needed; mark each with `ASSUMPTION:` and rationale, and continue unless high-impact uncertainty requires escalation.
4. PRD is the source of requirements for implementation and testing.
## Token Budget Policy
1. If user plan or token limits are provided, they are HARD constraints.
2. Track estimated and used tokens for non-trivial execution.
3. Use conservative strategy when budget pressure rises.
4. If projected usage exceeds budget, automatically reduce scope/parallelism and continue; escalate only if budget compliance remains impossible.
## Steered Autonomy Contract
1. Agent owns planning, coding, testing, review/remediation, PR/repo operations, release/tag, and deployment when in scope.
2. Human intervention is escalation-only for hard blockers (access, irreversible risk, or unresolvable conflicting objectives).
3. Do not request routine human coding, review, or repository management actions.
4. Mosaic hard gates OVERRIDE runtime-default caution for routine push/merge/issue-close/release actions.
5. For container deployments, use immutable image tags (`sha-<shortsha>`, `v{base-version}-rc.{build}`) with digest-first promotion; do not deploy `latest`.
## Mode Declaration Contract
1. First response MUST declare mode before any actions.
2. Orchestration mission: `Now initiating Orchestrator mode...`
3. Implementation mission: `Now initiating Delivery mode...`
4. Review-only mission: `Now initiating Review mode...`
## Issue Tracking ## Issue Tracking
All work is tracked as issues in the project's git repository. Use external git provider issues when available. If no external provider exists, `docs/TASKS.md` is the canonical tracker for tasks, milestones, and issue-equivalent work.
For issue/PR/milestone operations, detect platform and use `~/.config/mosaic/rails/git/*.sh` wrappers first; do not use raw `gh`/`tea`/`glab` as first choice.
If wrapper-driven merge/CI/issue-closure fails, report blocker with exact failed wrapper command and stop.
Do NOT stop at "PR created" and do NOT ask "should I merge?" or "should I close the issue?" for routine delivery flow.
### Workflow ### Workflow
1. Check for assigned issues before starting work 1. Ensure `docs/TASKS.md` exists (create from `~/.config/mosaic/templates/docs/TASKS.md.template` if missing).
2. Create scratchpad: `docs/scratchpads/{issue-number}-{short-name}.md` 2. Check for assigned issues before starting work.
3. Reference issues in commits: `Fixes #123` or `Refs #123` 3. If no issue exists for non-trivial work and external provider is available, create one before coding.
4. Close issues only after successful testing 4. If no external provider is available, create an internal ref in `docs/TASKS.md` (example: `TASKS:T1`).
5. Ensure `docs/PRD.md` or `docs/PRD.json` exists and is current before coding.
6. Create scratchpad: `docs/scratchpads/{task-id}-{short-name}.md` and include issue/internal ref.
7. Update `docs/TASKS.md` status + issue/internal ref before coding.
8. Before push, run CI queue guard: `~/.config/mosaic/rails/git/ci-queue-wait.sh --purpose push -B main`.
9. Open PR to `main` for delivery changes (no direct push to `main`).
10. Before merge, run CI queue guard: `~/.config/mosaic/rails/git/ci-queue-wait.sh --purpose merge -B main`.
11. Merge PRs that pass required checks and review gates with squash strategy only.
12. Reference issues/internal refs in commits (`Fixes #123`, `Refs #123`, or `Refs TASKS:T1`).
13. Close issue/internal task only after testing and documentation gates pass, PR merge is complete, and CI/pipeline status is terminal green.
14. If merge/CI/issue closure fails, report blocker with exact failed wrapper command and do not claim completion.
### Labels ### Labels
Use consistent labels: `epic`, `feature`, `bug`, `task`, `documentation`, `security`, `breaking` Use consistent labels: `epic`, `feature`, `bug`, `task`, `documentation`, `security`, `breaking`
@@ -119,7 +171,8 @@ Types: `feat`, `fix`, `docs`, `test`, `refactor`, `chore`
## Code Review ## Code Review
### Independent Review (Automated) ### Independent Review (Automated)
After completing code changes, run independent reviews: If you modify source code, independent code review is REQUIRED before completion.
Run independent reviews:
```bash ```bash
# Code quality review (Codex) # Code quality review (Codex)
@@ -132,7 +185,8 @@ After completing code changes, run independent reviews:
**Fallback:** If Codex is unavailable, use Claude's built-in review skills. **Fallback:** If Codex is unavailable, use Claude's built-in review skills.
### Review Checklist ### Review Checklist
See `~/.config/mosaic/guides/code-review.md` for the full review checklist. See `~/.config/mosaic/guides/CODE-REVIEW.md` for the full review checklist.
See `~/.config/mosaic/guides/DOCUMENTATION.md` for required documentation deliverables.
## Secrets Management ## Secrets Management
@@ -149,3 +203,9 @@ When multiple agents work on this project:
1. `git pull --rebase` before editing 1. `git pull --rebase` before editing
2. `git pull --rebase` before pushing 2. `git pull --rebase` before pushing
3. If conflicts, **alert the user** — don't auto-resolve data conflicts 3. If conflicts, **alert the user** — don't auto-resolve data conflicts
## Runtime Notes
- This file is runtime-compatibility context.
- Global rules are defined in `~/.config/mosaic/AGENTS.md`.
- Runtime-specific behavior is defined in `~/.config/mosaic/runtime/<runtime>/RUNTIME.md`.

View File

@@ -2,7 +2,7 @@
> Defines what "well-configured" means for AI agent development across all coding projects. > Defines what "well-configured" means for AI agent development across all coding projects.
## CLAUDE.md — Required Sections ## Runtime Context File — Required Sections
### Tier 1 (Required — blocks audit pass) ### Tier 1 (Required — blocks audit pass)
@@ -54,10 +54,10 @@ The `agent-lint.sh` tool checks for these markers:
| Check | Pass Criteria | | Check | Pass Criteria |
|-------|---------------| |-------|---------------|
| CLAUDE.md exists | File present at project root | | Runtime context file exists | `CLAUDE.md` or `RUNTIME.md` present at project root |
| AGENTS.md exists | File present at project root | | AGENTS.md exists | File present at project root |
| Conditional context/loading | CLAUDE.md contains `~/.config/mosaic/guides` or `Conditional` + `Loading/Context` | | Conditional context/loading | Runtime context file contains `~/.config/mosaic/guides` or `Conditional` + `Loading/Context` |
| Quality gates | CLAUDE.md contains `Quality Gates` or quality commands (test, lint, typecheck) | | Quality gates | Runtime context file contains `Quality Gates` or quality commands (test, lint, typecheck) |
| Monorepo sub-agents | Each app/package dir with own manifest has AGENTS.md | | Monorepo sub-agents | Each app/package dir with own manifest has AGENTS.md |
## Fragment Sources ## Fragment Sources

View File

@@ -1,6 +1,7 @@
## Code Review ## Code Review
After completing code changes, run independent reviews: If you modify source code, independent code review is REQUIRED before completion.
Run independent reviews:
```bash ```bash
# Code quality review (Codex) # Code quality review (Codex)
@@ -11,4 +12,4 @@ After completing code changes, run independent reviews:
``` ```
**Fallback:** If Codex is unavailable, use Claude's built-in review skills. **Fallback:** If Codex is unavailable, use Claude's built-in review skills.
See `~/.config/mosaic/guides/code-review.md` for the full review checklist. See `~/.config/mosaic/guides/CODE-REVIEW.md` for the full review checklist.

View File

@@ -1,17 +1,17 @@
## Conditional Documentation Loading ## Conditional Documentation Loading
**Read the relevant guide before starting work:** **Load `~/.config/mosaic/guides/E2E-DELIVERY.md` first, then load the relevant guide before starting work:**
| Task Type | Guide | | Task Type | Guide |
|-----------|-------| |-----------|-------|
| Bootstrapping a new project | `~/.config/mosaic/guides/bootstrap.md` | | End-to-end implementation and validation | `~/.config/mosaic/guides/E2E-DELIVERY.md` |
| Orchestrating autonomous tasks | `~/.config/mosaic/guides/orchestrator.md` | | Bootstrapping a new project | `~/.config/mosaic/guides/BOOTSTRAP.md` |
| Ralph autonomous development | `~/.config/mosaic/guides/ralph-autonomous.md` | | Orchestrating autonomous tasks | `~/.config/mosaic/guides/ORCHESTRATOR.md` |
| Frontend development | `~/.config/mosaic/guides/frontend.md` | | Frontend development | `~/.config/mosaic/guides/FRONTEND.md` |
| Backend/API development | `~/.config/mosaic/guides/backend.md` | | Backend/API development | `~/.config/mosaic/guides/BACKEND.md` |
| TypeScript strict typing | `~/.config/mosaic/guides/typescript.md` | | TypeScript strict typing | `~/.config/mosaic/guides/TYPESCRIPT.md` |
| Code review | `~/.config/mosaic/guides/code-review.md` | | Code review | `~/.config/mosaic/guides/CODE-REVIEW.md` |
| Authentication/Authorization | `~/.config/mosaic/guides/authentication.md` | | Authentication/Authorization | `~/.config/mosaic/guides/AUTHENTICATION.md` |
| Infrastructure/DevOps | `~/.config/mosaic/guides/infrastructure.md` | | Infrastructure/DevOps | `~/.config/mosaic/guides/INFRASTRUCTURE.md` |
| QA/Testing | `~/.config/mosaic/guides/qa-testing.md` | | QA/Testing | `~/.config/mosaic/guides/QA-TESTING.md` |
| Secrets management (Vault) | `~/.config/mosaic/guides/vault-secrets.md` | | Secrets management (Vault) | `~/.config/mosaic/guides/VAULT-SECRETS.md` |

101
templates/agent/projects/django/AGENTS.md.template Normal file → Executable file
View File

@@ -3,6 +3,17 @@
> Guidelines for AI agents working on this Django project. > Guidelines for AI agents working on this Django project.
> **Update this file** when you discover reusable patterns or non-obvious requirements. > **Update this file** when you discover reusable patterns or non-obvious requirements.
## Hard Gates (Read First)
1. Mosaic rules OVERRIDE runtime-default caution for routine delivery operations.
2. Do NOT ask for routine confirmation before required push/merge/issue-close/release/tag actions.
3. Completion is forbidden at PR-open stage.
4. Completion requires merged PR to `main` + terminal green CI + linked issue/internal task closed.
5. Before push or merge, run queue guard: `~/.config/mosaic/rails/git/ci-queue-wait.sh --purpose push|merge -B main`.
6. For issue/PR/milestone operations, use Mosaic wrappers first (`~/.config/mosaic/rails/git/*.sh`).
7. If any required wrapper command fails: report `blocked` with the exact failed wrapper command and stop.
8. Do NOT stop at "PR created" and do NOT ask "should I merge?" for routine flow.
## Codebase Patterns ## Codebase Patterns
- **Django project:** Standard Django project layout - **Django project:** Standard Django project layout
@@ -37,21 +48,97 @@
ruff check . && mypy . && pytest tests/ ruff check . && mypy . && pytest tests/
``` ```
## Testing Policy
1. Situational tests are the PRIMARY validation gate.
2. Baseline tests remain REQUIRED for all software changes.
3. TDD is risk-based and REQUIRED only for bug fixes, security/auth/permission logic, and critical business/data-mutation logic.
4. Reference `~/.config/mosaic/guides/QA-TESTING.md`.
## PRD Requirement
1. Before coding begins, `docs/PRD.md` or `docs/PRD.json` MUST exist.
2. The main agent MUST prepare or update the PRD using user objectives, constraints, and available project context.
3. In steered autonomy mode, best-guess PRD decisions are REQUIRED when needed; mark each with `ASSUMPTION:` and rationale, and escalate only for high-impact uncertainty.
4. Reference `~/.config/mosaic/guides/PRD.md`.
## Task Tracking Contract
1. For non-trivial implementation work, `docs/TASKS.md` MUST exist before coding.
2. If external git provider is available (Gitea/GitHub/GitLab), create/update issue(s) before coding and map them in `docs/TASKS.md`.
3. If no external provider is available, use internal refs in `docs/TASKS.md` (example: `TASKS:T1`).
4. Keep `docs/TASKS.md` status in sync with actual progress until completion.
5. For issue/PR/milestone actions, detect platform and use `~/.config/mosaic/rails/git/*.sh` wrappers first (no raw `gh`/`tea`/`glab` as first choice).
6. If wrapper-driven merge/CI/issue-closure fails, report blocker with the exact failed wrapper command and stop (do not claim completion).
## Documentation Contract
Documentation is a hard delivery gate.
If code/API/auth/infra changes, required documentation updates MUST be completed before task closure.
Keep `docs/` root clean and store reports/artifacts in scoped folders (`docs/reports/`, `docs/tasks/`, `docs/releases/`, `docs/scratchpads/`).
Reference:
- `~/.config/mosaic/guides/DOCUMENTATION.md`
- `~/.config/mosaic/templates/docs/DOCUMENTATION-CHECKLIST.md`
## Token Budget Policy
1. If user plan or token limits are provided, they are HARD constraints.
2. Track estimated and used tokens for non-trivial execution.
3. Shift to conservative strategy when budget pressure rises (smaller scope, fewer parallel actions, reduced re-reading).
4. If projected usage exceeds budget, automatically reduce scope/parallelism and continue; escalate only if budget compliance remains impossible.
## Merge Strategy (Hard Rule)
1. Create short-lived branches from `main`.
2. Open PRs to `main` for delivery changes.
3. Do not push directly to `main`.
4. Merge PRs to `main` with squash strategy only.
5. Do not mark implementation complete until PR is merged.
6. Do not mark implementation complete until CI/pipeline status is terminal green.
7. Close linked issues/tasks only after merge + green CI.
8. Before push or merge, run CI queue guard: `~/.config/mosaic/rails/git/ci-queue-wait.sh --purpose push|merge -B main`.
## Container Release Strategy (When Applicable)
1. Use immutable image tags: `sha-<shortsha>` and `v{base-version}-rc.{build}`.
2. Use mutable environment tags only as pointers (`testing`, optional `staging`, `prod`).
3. Deploy/promote by immutable digest; do not deploy by mutable tag alone.
4. Do not use `latest` or `dev` as deployment references.
5. Use blue-green by default; use canary only with automated metrics and rollback gates.
## Steered Autonomy Contract
1. Agent owns end-to-end delivery: plan, code, test, review, remediate, commit, push, PR/repo operations, release/tag, and deployment when in scope.
2. Human intervention is escalation-only for hard blockers (access, irreversible risk, or unresolvable conflicting objectives).
3. Code review is agent-executed and REQUIRED for any source-code change.
## Mode Declaration Contract
1. First response MUST declare mode before any actions.
2. Orchestration mission: `Now initiating Orchestrator mode...`
3. Implementation mission: `Now initiating Delivery mode...`
4. Review-only mission: `Now initiating Review mode...`
## Orchestrator Integration ## Orchestrator Integration
### Task Prefix ### Task Prefix
Use `${TASK_PREFIX}` for orchestrated tasks (e.g., `${TASK_PREFIX}-SEC-001`). Use `${TASK_PREFIX}` for orchestrated tasks (e.g., `${TASK_PREFIX}-SEC-001`).
### Worker Checklist ### Worker Checklist
1. Read the finding details from the report 1. Read `docs/PRD.md` or `docs/PRD.json`
2. Implement the fix following existing patterns 2. Read the finding details from the report
3. Run quality gates (ALL must pass) 3. Implement the fix following existing patterns
4. Commit: `git commit -m "fix({finding_id}): brief description"` 4. Run quality gates (ALL must pass)
5. Push: `git push origin {branch}` 5. Complete required documentation updates (if applicable)
6. Report result as JSON 6. Commit: `git commit -m "fix({finding_id}): brief description"`
7. Push: `git push origin {branch}`
8. Report result as JSON
### Post-Coding Review ### Post-Coding Review
After implementing changes, the orchestrator will run: After implementing changes, code review is REQUIRED for any source-code modification.
For orchestrated tasks, the orchestrator will run:
1. **Codex code review** — `~/.config/mosaic/rails/codex/codex-code-review.sh --uncommitted` 1. **Codex code review** — `~/.config/mosaic/rails/codex/codex-code-review.sh --uncommitted`
2. **Codex security review** — `~/.config/mosaic/rails/codex/codex-security-review.sh --uncommitted` 2. **Codex security review** — `~/.config/mosaic/rails/codex/codex-security-review.sh --uncommitted`
3. If blockers/critical findings: remediation task created 3. If blockers/critical findings: remediation task created

85
templates/agent/projects/django/CLAUDE.md.template Normal file → Executable file
View File

@@ -6,11 +6,13 @@
| When working on... | Load this guide | | When working on... | Load this guide |
|---|---| |---|---|
| Bootstrapping this project | `~/.config/mosaic/guides/bootstrap.md` | | Bootstrapping this project | `~/.config/mosaic/guides/BOOTSTRAP.md` |
| Orchestrating autonomous tasks | `~/.config/mosaic/guides/orchestrator.md` | | PRD creation and requirements definition | `~/.config/mosaic/guides/PRD.md` |
| Backend/API development | `~/.config/mosaic/guides/backend.md` | | Orchestrating autonomous tasks | `~/.config/mosaic/guides/ORCHESTRATOR.md` |
| Code review | `~/.config/mosaic/guides/code-review.md` | | Backend/API development | `~/.config/mosaic/guides/BACKEND.md` |
| QA/Testing | `~/.config/mosaic/guides/qa-testing.md` | | Code review | `~/.config/mosaic/guides/CODE-REVIEW.md` |
| Documentation updates and standards | `~/.config/mosaic/guides/DOCUMENTATION.md` |
| QA/Testing | `~/.config/mosaic/guides/QA-TESTING.md` |
## Technology Stack ## Technology Stack
@@ -39,6 +41,7 @@ ${PROJECT_DIR}/
│ └── apps/ # Django applications │ └── apps/ # Django applications
├── tests/ # Test files ├── tests/ # Test files
├── docs/ ├── docs/
│ ├── PRD.md # Requirements source (or PRD.json)
│ ├── scratchpads/ # Per-issue working documents │ ├── scratchpads/ # Per-issue working documents
│ └── templates/ # Project templates │ └── templates/ # Project templates
├── pyproject.toml # Python project configuration ├── pyproject.toml # Python project configuration
@@ -49,10 +52,10 @@ ${PROJECT_DIR}/
## Development Workflow ## Development Workflow
### Branch Strategy ### Branch Strategy
- `main` — Production-ready code - `main` — Protected delivery branch
- `develop` — Integration branch (if used) - `feat/<name>` / `fix/<name>` — Short-lived task branches created from `main`
- `feat/<name>` — Feature branches - All changes merge through PR into `main` only
- `fix/<name>` — Bug fix branches - Merge strategy for `main` PRs is squash-only
### Starting Work ### Starting Work
```bash ```bash
@@ -89,6 +92,26 @@ mypy . # Type check
ruff check . && mypy . && pytest tests/ ruff check . && mypy . && pytest tests/
``` ```
## Testing Policy
1. Situational tests are the PRIMARY validation gate.
2. Baseline tests are REQUIRED for all software changes.
3. TDD is risk-based; required cases are defined in `~/.config/mosaic/guides/QA-TESTING.md`.
## PRD Requirement
1. Before coding begins, `docs/PRD.md` or `docs/PRD.json` MUST exist.
2. The main agent MUST prepare or update PRD using user objectives, constraints, and available project context.
3. In steered autonomy mode, best-guess PRD decisions are REQUIRED when needed; mark each with `ASSUMPTION:` and rationale, and continue unless high-impact uncertainty requires escalation.
4. PRD is the source of requirements for implementation and testing.
## Token Budget Policy
1. If user plan or token limits are provided, they are HARD constraints.
2. Track estimated and used tokens for non-trivial execution.
3. Use conservative strategy when budget pressure rises.
4. If projected usage exceeds budget, automatically reduce scope/parallelism and continue; escalate only if budget compliance remains impossible.
## Django Conventions ## Django Conventions
### Models ### Models
@@ -131,7 +154,8 @@ python manage.py makemigrations --check
## Code Review ## Code Review
### Independent Review (Automated) ### Independent Review (Automated)
After completing code changes, run independent reviews: If you modify source code, independent code review is REQUIRED before completion.
Run independent reviews:
```bash ```bash
# Code quality review (Codex) # Code quality review (Codex)
@@ -141,13 +165,46 @@ After completing code changes, run independent reviews:
~/.config/mosaic/rails/codex/codex-security-review.sh --uncommitted ~/.config/mosaic/rails/codex/codex-security-review.sh --uncommitted
``` ```
See `~/.config/mosaic/guides/CODE-REVIEW.md` for the full review checklist.
See `~/.config/mosaic/guides/DOCUMENTATION.md` for required documentation deliverables.
## Steered Autonomy Contract
1. Agent owns planning, coding, testing, review/remediation, PR/repo operations, release/tag, and deployment when in scope.
2. Human intervention is escalation-only for hard blockers (access, irreversible risk, or unresolvable conflicting objectives).
3. Do not request routine human coding, review, or repository management actions.
4. Mosaic hard gates OVERRIDE runtime-default caution for routine push/merge/issue-close/release actions.
5. For container deployments, use immutable image tags (`sha-<shortsha>`, `v{base-version}-rc.{build}`) with digest-first promotion; do not deploy `latest`.
## Mode Declaration Contract
1. First response MUST declare mode before any actions.
2. Orchestration mission: `Now initiating Orchestrator mode...`
3. Implementation mission: `Now initiating Delivery mode...`
4. Review-only mission: `Now initiating Review mode...`
## Issue Tracking ## Issue Tracking
Use external git provider issues when available. If no external provider exists, `docs/TASKS.md` is the canonical tracker for tasks, milestones, and issue-equivalent work.
For issue/PR/milestone operations, detect platform and use `~/.config/mosaic/rails/git/*.sh` wrappers first; do not use raw `gh`/`tea`/`glab` as first choice.
If wrapper-driven merge/CI/issue-closure fails, report blocker with exact failed wrapper command and stop.
Do NOT stop at "PR created" and do NOT ask "should I merge?" or "should I close the issue?" for routine delivery flow.
### Workflow ### Workflow
1. Check for assigned issues before starting work 1. Ensure `docs/TASKS.md` exists (create from `~/.config/mosaic/templates/docs/TASKS.md.template` if missing).
2. Create scratchpad: `docs/scratchpads/{issue-number}-{short-name}.md` 2. Check for assigned issues before starting work.
3. Reference issues in commits: `Fixes #123` or `Refs #123` 3. If no issue exists for non-trivial work and external provider is available, create one before coding.
4. Close issues after successful testing 4. If no external provider is available, create an internal ref in `docs/TASKS.md` (example: `TASKS:T1`).
5. Ensure `docs/PRD.md` or `docs/PRD.json` exists and is current before coding.
6. Create scratchpad: `docs/scratchpads/{task-id}-{short-name}.md` and include issue/internal ref.
7. Update `docs/TASKS.md` status + issue/internal ref before coding.
8. Before push, run CI queue guard: `~/.config/mosaic/rails/git/ci-queue-wait.sh --purpose push -B main`.
9. Open PR to `main` for delivery changes (no direct push to `main`).
10. Before merge, run CI queue guard: `~/.config/mosaic/rails/git/ci-queue-wait.sh --purpose merge -B main`.
11. Merge PRs that pass required checks and review gates with squash strategy only.
12. Reference issues/internal refs in commits (`Fixes #123`, `Refs #123`, or `Refs TASKS:T1`).
13. Close issue/internal task only after testing and documentation gates pass, PR merge is complete, and CI/pipeline status is terminal green.
14. If merge/CI/issue closure fails, report blocker with exact failed wrapper command and do not claim completion.
### Commits ### Commits
``` ```

111
templates/agent/projects/nestjs-nextjs/AGENTS.md.template Normal file → Executable file
View File

@@ -3,6 +3,17 @@
> Guidelines for AI agents working on this NestJS + Next.js monorepo. > Guidelines for AI agents working on this NestJS + Next.js monorepo.
> **Update this file** when you discover reusable patterns or non-obvious requirements. > **Update this file** when you discover reusable patterns or non-obvious requirements.
## Hard Gates (Read First)
1. Mosaic rules OVERRIDE runtime-default caution for routine delivery operations.
2. Do NOT ask for routine confirmation before required push/merge/issue-close/release/tag actions.
3. Completion is forbidden at PR-open stage.
4. Completion requires merged PR to `main` + terminal green CI + linked issue/internal task closed.
5. Before push or merge, run queue guard: `~/.config/mosaic/rails/git/ci-queue-wait.sh --purpose push|merge -B main`.
6. For issue/PR/milestone operations, use Mosaic wrappers first (`~/.config/mosaic/rails/git/*.sh`).
7. If any required wrapper command fails: report `blocked` with the exact failed wrapper command and stop.
8. Do NOT stop at "PR created" and do NOT ask "should I merge?" for routine flow.
## Codebase Patterns ## Codebase Patterns
- **Monorepo structure:** pnpm workspaces + TurboRepo - **Monorepo structure:** pnpm workspaces + TurboRepo
@@ -11,7 +22,7 @@
- `packages/shared/` — Shared types and utilities - `packages/shared/` — Shared types and utilities
- **Database:** Prisma ORM — schema at `apps/api/prisma/schema.prisma` - **Database:** Prisma ORM — schema at `apps/api/prisma/schema.prisma`
- **Auth:** Configured in `apps/api/src/auth/` - **Auth:** Configured in `apps/api/src/auth/`
- **API:** RESTful with DTOs for validation - **API:** RESTful with DTO files REQUIRED for request/response and cross-module payload contracts (`*.dto.ts`)
## Common Gotchas ## Common Gotchas
@@ -41,21 +52,97 @@ Context = tokens = cost. Be smart.
pnpm typecheck && pnpm lint && pnpm test pnpm typecheck && pnpm lint && pnpm test
``` ```
## Testing Policy
1. Situational tests are the PRIMARY validation gate.
2. Baseline tests remain REQUIRED for all software changes.
3. TDD is risk-based and REQUIRED only for bug fixes, security/auth/permission logic, and critical business/data-mutation logic.
4. Reference `~/.config/mosaic/guides/QA-TESTING.md`.
## PRD Requirement
1. Before coding begins, `docs/PRD.md` or `docs/PRD.json` MUST exist.
2. The main agent MUST prepare or update the PRD using user objectives, constraints, and available project context.
3. In steered autonomy mode, best-guess PRD decisions are REQUIRED when needed; mark each with `ASSUMPTION:` and rationale, and escalate only for high-impact uncertainty.
4. Reference `~/.config/mosaic/guides/PRD.md`.
## Task Tracking Contract
1. For non-trivial implementation work, `docs/TASKS.md` MUST exist before coding.
2. If external git provider is available (Gitea/GitHub/GitLab), create/update issue(s) before coding and map them in `docs/TASKS.md`.
3. If no external provider is available, use internal refs in `docs/TASKS.md` (example: `TASKS:T1`).
4. Keep `docs/TASKS.md` status in sync with actual progress until completion.
5. For issue/PR/milestone actions, detect platform and use `~/.config/mosaic/rails/git/*.sh` wrappers first (no raw `gh`/`tea`/`glab` as first choice).
6. If wrapper-driven merge/CI/issue-closure fails, report blocker with the exact failed wrapper command and stop (do not claim completion).
## Documentation Contract
Documentation is a hard delivery gate.
If code/API/auth/infra changes, required documentation updates MUST be completed before task closure.
Keep `docs/` root clean and store reports/artifacts in scoped folders (`docs/reports/`, `docs/tasks/`, `docs/releases/`, `docs/scratchpads/`).
Reference:
- `~/.config/mosaic/guides/DOCUMENTATION.md`
- `~/.config/mosaic/templates/docs/DOCUMENTATION-CHECKLIST.md`
## Token Budget Policy
1. If user plan or token limits are provided, they are HARD constraints.
2. Track estimated and used tokens for non-trivial execution.
3. Shift to conservative strategy when budget pressure rises (smaller scope, fewer parallel actions, reduced re-reading).
4. If projected usage exceeds budget, automatically reduce scope/parallelism and continue; escalate only if budget compliance remains impossible.
## Merge Strategy (Hard Rule)
1. Create short-lived branches from `main`.
2. Open PRs to `main` for delivery changes.
3. Do not push directly to `main`.
4. Merge PRs to `main` with squash strategy only.
5. Do not mark implementation complete until PR is merged.
6. Do not mark implementation complete until CI/pipeline status is terminal green.
7. Close linked issues/tasks only after merge + green CI.
8. Before push or merge, run CI queue guard: `~/.config/mosaic/rails/git/ci-queue-wait.sh --purpose push|merge -B main`.
## Container Release Strategy (When Applicable)
1. Use immutable image tags: `sha-<shortsha>` and `v{base-version}-rc.{build}`.
2. Use mutable environment tags only as pointers (`testing`, optional `staging`, `prod`).
3. Deploy/promote by immutable digest; do not deploy by mutable tag alone.
4. Do not use `latest` or `dev` as deployment references.
5. Use blue-green by default; use canary only with automated metrics and rollback gates.
## Steered Autonomy Contract
1. Agent owns end-to-end delivery: plan, code, test, review, remediate, commit, push, PR/repo operations, release/tag, and deployment when in scope.
2. Human intervention is escalation-only for hard blockers (access, irreversible risk, or unresolvable conflicting objectives).
3. Code review is agent-executed and REQUIRED for any source-code change.
## Mode Declaration Contract
1. First response MUST declare mode before any actions.
2. Orchestration mission: `Now initiating Orchestrator mode...`
3. Implementation mission: `Now initiating Delivery mode...`
4. Review-only mission: `Now initiating Review mode...`
## Orchestrator Integration ## Orchestrator Integration
### Task Prefix ### Task Prefix
Use `${TASK_PREFIX}` for orchestrated tasks (e.g., `${TASK_PREFIX}-SEC-001`). Use `${TASK_PREFIX}` for orchestrated tasks (e.g., `${TASK_PREFIX}-SEC-001`).
### Worker Checklist ### Worker Checklist
1. Read the finding details from the report 1. Read `docs/PRD.md` or `docs/PRD.json`
2. Implement the fix following existing patterns 2. Read the finding details from the report
3. Run quality gates (ALL must pass) 3. Implement the fix following existing patterns
4. Commit: `git commit -m "fix({finding_id}): brief description"` 4. Run quality gates (ALL must pass)
5. Push: `git push origin {branch}` 5. Complete required documentation updates (if applicable)
6. Report result as JSON 6. Commit: `git commit -m "fix({finding_id}): brief description"`
7. Push: `git push origin {branch}`
8. Report result as JSON
### Post-Coding Review ### Post-Coding Review
After implementing changes, the orchestrator will run: After implementing changes, code review is REQUIRED for any source-code modification.
For orchestrated tasks, the orchestrator will run:
1. **Codex code review** — `~/.config/mosaic/rails/codex/codex-code-review.sh --uncommitted` 1. **Codex code review** — `~/.config/mosaic/rails/codex/codex-code-review.sh --uncommitted`
2. **Codex security review** — `~/.config/mosaic/rails/codex/codex-security-review.sh --uncommitted` 2. **Codex security review** — `~/.config/mosaic/rails/codex/codex-security-review.sh --uncommitted`
3. If blockers/critical findings: remediation task created 3. If blockers/critical findings: remediation task created
@@ -65,15 +152,15 @@ After implementing changes, the orchestrator will run:
``` ```
1. Branch → git checkout -b feature/XX-description 1. Branch → git checkout -b feature/XX-description
2. Code → TDD: write test (RED), implement (GREEN), refactor 2. Code → Implement with required tests; use TDD where required by policy
3. Test → pnpm test (must pass) 3. Test → pnpm test (must pass)
4. Push → git push origin feature/XX-description 4. Push → git push origin feature/XX-description
5. PR → Create PR to develop (not main) 5. PR → Create PR to main
6. Review → Wait for approval or self-merge if authorized 6. Review → Wait for approval or self-merge if authorized using squash only
7. Close → Close related issues 7. Close → Close related issues
``` ```
**Never merge directly to develop without a PR.** **Never push directly to main. Always use a PR to main.**
## Key Files ## Key Files

View File

@@ -6,14 +6,16 @@
| When working on... | Load this guide | | When working on... | Load this guide |
|---|---| |---|---|
| Bootstrapping this project | `~/.config/mosaic/guides/bootstrap.md` | | Bootstrapping this project | `~/.config/mosaic/guides/BOOTSTRAP.md` |
| Orchestrating autonomous tasks | `~/.config/mosaic/guides/orchestrator.md` | | PRD creation and requirements definition | `~/.config/mosaic/guides/PRD.md` |
| Frontend development | `~/.config/mosaic/guides/frontend.md` | | Orchestrating autonomous tasks | `~/.config/mosaic/guides/ORCHESTRATOR.md` |
| Backend/API development | `~/.config/mosaic/guides/backend.md` | | Frontend development | `~/.config/mosaic/guides/FRONTEND.md` |
| Code review | `~/.config/mosaic/guides/code-review.md` | | Backend/API development | `~/.config/mosaic/guides/BACKEND.md` |
| TypeScript strict typing | `~/.config/mosaic/guides/typescript.md` | | Code review | `~/.config/mosaic/guides/CODE-REVIEW.md` |
| Authentication/Authorization | `~/.config/mosaic/guides/authentication.md` | | Documentation updates and standards | `~/.config/mosaic/guides/DOCUMENTATION.md` |
| QA/Testing | `~/.config/mosaic/guides/qa-testing.md` | | TypeScript strict typing | `~/.config/mosaic/guides/TYPESCRIPT.md` |
| Authentication/Authorization | `~/.config/mosaic/guides/AUTHENTICATION.md` |
| QA/Testing | `~/.config/mosaic/guides/QA-TESTING.md` |
## Technology Stack ## Technology Stack
@@ -47,6 +49,7 @@ ${PROJECT_DIR}/
│ ├── ui/ # Shared UI components │ ├── ui/ # Shared UI components
│ └── config/ # Shared configuration │ └── config/ # Shared configuration
├── docs/ ├── docs/
│ ├── PRD.md # Requirements source (or PRD.json)
│ ├── scratchpads/ # Per-issue working documents │ ├── scratchpads/ # Per-issue working documents
│ └── templates/ # Project templates │ └── templates/ # Project templates
├── tests/ # Integration/E2E tests ├── tests/ # Integration/E2E tests
@@ -60,15 +63,15 @@ ${PROJECT_DIR}/
## Development Workflow ## Development Workflow
### Branch Strategy ### Branch Strategy
- `main` — Stable releases only - `main` — Protected delivery branch
- `develop` — Active development (default working branch) - `feature/*` / `fix/*` — Short-lived task branches created from `main`
- `feature/*` — Feature branches from develop - All changes merge through PR into `main` only
- `fix/*` — Bug fix branches - Merge strategy for `main` PRs is squash-only
### Starting Work ### Starting Work
```bash ```bash
git checkout develop git checkout main
git pull --rebase git pull --rebase origin main
pnpm install pnpm install
``` ```
@@ -102,10 +105,31 @@ pnpm format # Prettier formatting
pnpm typecheck && pnpm lint && pnpm test pnpm typecheck && pnpm lint && pnpm test
``` ```
## Testing Policy
1. Situational tests are the PRIMARY validation gate.
2. Baseline tests are REQUIRED for all software changes.
3. TDD is risk-based; required cases are defined in `~/.config/mosaic/guides/QA-TESTING.md`.
## PRD Requirement
1. Before coding begins, `docs/PRD.md` or `docs/PRD.json` MUST exist.
2. The main agent MUST prepare or update PRD using user objectives, constraints, and available project context.
3. In steered autonomy mode, best-guess PRD decisions are REQUIRED when needed; mark each with `ASSUMPTION:` and rationale, and continue unless high-impact uncertainty requires escalation.
4. PRD is the source of requirements for implementation and testing.
## Token Budget Policy
1. If user plan or token limits are provided, they are HARD constraints.
2. Track estimated and used tokens for non-trivial execution.
3. Use conservative strategy when budget pressure rises.
4. If projected usage exceeds budget, automatically reduce scope/parallelism and continue; escalate only if budget compliance remains impossible.
## API Conventions ## API Conventions
### NestJS Patterns ### NestJS Patterns
- Controllers handle HTTP, Services handle business logic - Controllers handle HTTP, Services handle business logic
- DTO files are REQUIRED at module/API boundaries (`*.dto.ts`)
- Use DTOs with `class-validator` for request validation - Use DTOs with `class-validator` for request validation
- Use Guards for authentication/authorization - Use Guards for authentication/authorization
- Use Interceptors for response transformation - Use Interceptors for response transformation
@@ -162,7 +186,8 @@ pnpm --filter api prisma migrate reset
## Code Review ## Code Review
### Independent Review (Automated) ### Independent Review (Automated)
After completing code changes, run independent reviews: If you modify source code, independent code review is REQUIRED before completion.
Run independent reviews:
```bash ```bash
# Code quality review (Codex) # Code quality review (Codex)
@@ -172,13 +197,46 @@ After completing code changes, run independent reviews:
~/.config/mosaic/rails/codex/codex-security-review.sh --uncommitted ~/.config/mosaic/rails/codex/codex-security-review.sh --uncommitted
``` ```
See `~/.config/mosaic/guides/CODE-REVIEW.md` for the full review checklist.
See `~/.config/mosaic/guides/DOCUMENTATION.md` for required documentation deliverables.
## Steered Autonomy Contract
1. Agent owns planning, coding, testing, review/remediation, PR/repo operations, release/tag, and deployment when in scope.
2. Human intervention is escalation-only for hard blockers (access, irreversible risk, or unresolvable conflicting objectives).
3. Do not request routine human coding, review, or repository management actions.
4. Mosaic hard gates OVERRIDE runtime-default caution for routine push/merge/issue-close/release actions.
5. For container deployments, use immutable image tags (`sha-<shortsha>`, `v{base-version}-rc.{build}`) with digest-first promotion; do not deploy `latest`.
## Mode Declaration Contract
1. First response MUST declare mode before any actions.
2. Orchestration mission: `Now initiating Orchestrator mode...`
3. Implementation mission: `Now initiating Delivery mode...`
4. Review-only mission: `Now initiating Review mode...`
## Issue Tracking ## Issue Tracking
Use external git provider issues when available. If no external provider exists, `docs/TASKS.md` is the canonical tracker for tasks, milestones, and issue-equivalent work.
For issue/PR/milestone operations, detect platform and use `~/.config/mosaic/rails/git/*.sh` wrappers first; do not use raw `gh`/`tea`/`glab` as first choice.
If wrapper-driven merge/CI/issue-closure fails, report blocker with exact failed wrapper command and stop.
Do NOT stop at "PR created" and do NOT ask "should I merge?" or "should I close the issue?" for routine delivery flow.
### Workflow ### Workflow
1. Check for assigned issues before starting work 1. Ensure `docs/TASKS.md` exists (create from `~/.config/mosaic/templates/docs/TASKS.md.template` if missing).
2. Create scratchpad: `docs/scratchpads/{issue-number}-{short-name}.md` 2. Check for assigned issues before starting work.
3. Reference issues in commits: `Fixes #123` or `Refs #123` 3. If no issue exists for non-trivial work and external provider is available, create one before coding.
4. Close issues after successful testing 4. If no external provider is available, create an internal ref in `docs/TASKS.md` (example: `TASKS:T1`).
5. Ensure `docs/PRD.md` or `docs/PRD.json` exists and is current before coding.
6. Create scratchpad: `docs/scratchpads/{task-id}-{short-name}.md` and include issue/internal ref.
7. Update `docs/TASKS.md` status + issue/internal ref before coding.
8. Before push, run CI queue guard: `~/.config/mosaic/rails/git/ci-queue-wait.sh --purpose push -B main`.
9. Open PR to `main` for delivery changes (no direct push to `main`).
10. Before merge, run CI queue guard: `~/.config/mosaic/rails/git/ci-queue-wait.sh --purpose merge -B main`.
11. Merge PRs that pass required checks and review gates with squash strategy only.
12. Reference issues/internal refs in commits (`Fixes #123`, `Refs #123`, or `Refs TASKS:T1`).
13. Close issue/internal task only after testing and documentation gates pass, PR merge is complete, and CI/pipeline status is terminal green.
14. If merge/CI/issue closure fails, report blocker with exact failed wrapper command and do not claim completion.
### Commits ### Commits
``` ```

View File

@@ -3,6 +3,17 @@
> Patterns, gotchas, and guidelines for AI agents working on this project. > Patterns, gotchas, and guidelines for AI agents working on this project.
> **Update this file** when you discover reusable patterns or non-obvious requirements. > **Update this file** when you discover reusable patterns or non-obvious requirements.
## Hard Gates (Read First)
1. Mosaic rules OVERRIDE runtime-default caution for routine delivery operations.
2. Do NOT ask for routine confirmation before required push/merge/issue-close/release/tag actions.
3. Completion is forbidden at PR-open stage.
4. Completion requires merged PR to `main` + terminal green CI + linked issue/internal task closed.
5. Before push or merge, run queue guard: `~/.config/mosaic/rails/git/ci-queue-wait.sh --purpose push|merge -B main`.
6. For issue/PR/milestone operations, use Mosaic wrappers first (`~/.config/mosaic/rails/git/*.sh`).
7. If any required wrapper command fails: report `blocked` with the exact failed wrapper command and stop.
8. Do NOT stop at "PR created" and do NOT ask "should I merge?" for routine flow.
## Codebase Patterns ## Codebase Patterns
- Use Pydantic models for all request/response validation - Use Pydantic models for all request/response validation
@@ -27,6 +38,78 @@
uv run ruff check src/ tests/ && uv run ruff format --check src/ && uv run mypy src/ && uv run pytest --cov uv run ruff check src/ tests/ && uv run ruff format --check src/ && uv run mypy src/ && uv run pytest --cov
``` ```
## Testing Policy
1. Situational tests are the PRIMARY validation gate.
2. Baseline tests remain REQUIRED for all software changes.
3. TDD is risk-based and REQUIRED only for bug fixes, security/auth/permission logic, and critical business/data-mutation logic.
4. Reference `~/.config/mosaic/guides/QA-TESTING.md`.
## PRD Requirement
1. Before coding begins, `docs/PRD.md` or `docs/PRD.json` MUST exist.
2. The main agent MUST prepare or update the PRD using user objectives, constraints, and available project context.
3. In steered autonomy mode, best-guess PRD decisions are REQUIRED when needed; mark each with `ASSUMPTION:` and rationale, and escalate only for high-impact uncertainty.
4. Reference `~/.config/mosaic/guides/PRD.md`.
## Task Tracking Contract
1. For non-trivial implementation work, `docs/TASKS.md` MUST exist before coding.
2. If external git provider is available (Gitea/GitHub/GitLab), create/update issue(s) before coding and map them in `docs/TASKS.md`.
3. If no external provider is available, use internal refs in `docs/TASKS.md` (example: `TASKS:T1`).
4. Keep `docs/TASKS.md` status in sync with actual progress until completion.
5. For issue/PR/milestone actions, detect platform and use `~/.config/mosaic/rails/git/*.sh` wrappers first (no raw `gh`/`tea`/`glab` as first choice).
6. If wrapper-driven merge/CI/issue-closure fails, report blocker with the exact failed wrapper command and stop (do not claim completion).
## Documentation Contract
Documentation is a hard delivery gate.
If code/API/auth/infra changes, required documentation updates MUST be completed before task closure.
Keep `docs/` root clean and store reports/artifacts in scoped folders (`docs/reports/`, `docs/tasks/`, `docs/releases/`, `docs/scratchpads/`).
Reference:
- `~/.config/mosaic/guides/DOCUMENTATION.md`
- `~/.config/mosaic/templates/docs/DOCUMENTATION-CHECKLIST.md`
## Token Budget Policy
1. If user plan or token limits are provided, they are HARD constraints.
2. Track estimated and used tokens for non-trivial execution.
3. Shift to conservative strategy when budget pressure rises (smaller scope, fewer parallel actions, reduced re-reading).
4. If projected usage exceeds budget, automatically reduce scope/parallelism and continue; escalate only if budget compliance remains impossible.
## Merge Strategy (Hard Rule)
1. Create short-lived branches from `main`.
2. Open PRs to `main` for delivery changes.
3. Do not push directly to `main`.
4. Merge PRs to `main` with squash strategy only.
5. Do not mark implementation complete until PR is merged.
6. Do not mark implementation complete until CI/pipeline status is terminal green.
7. Close linked issues/tasks only after merge + green CI.
8. Before push or merge, run CI queue guard: `~/.config/mosaic/rails/git/ci-queue-wait.sh --purpose push|merge -B main`.
## Container Release Strategy (When Applicable)
1. Use immutable image tags: `sha-<shortsha>` and `v{base-version}-rc.{build}`.
2. Use mutable environment tags only as pointers (`testing`, optional `staging`, `prod`).
3. Deploy/promote by immutable digest; do not deploy by mutable tag alone.
4. Do not use `latest` or `dev` as deployment references.
5. Use blue-green by default; use canary only with automated metrics and rollback gates.
## Steered Autonomy Contract
1. Agent owns end-to-end delivery: plan, code, test, review, remediate, commit, push, PR/repo operations, release/tag, and deployment when in scope.
2. Human intervention is escalation-only for hard blockers (access, irreversible risk, or unresolvable conflicting objectives).
3. Code review is agent-executed and REQUIRED for any source-code change.
## Mode Declaration Contract
1. First response MUST declare mode before any actions.
2. Orchestration mission: `Now initiating Orchestrator mode...`
3. Implementation mission: `Now initiating Delivery mode...`
4. Review-only mission: `Now initiating Review mode...`
## Key Files ## Key Files
| File | Purpose | | File | Purpose |

View File

@@ -9,15 +9,17 @@
| Task Type | Guide | | Task Type | Guide |
|-----------|-------| |-----------|-------|
| Bootstrapping this project | `~/.config/mosaic/guides/bootstrap.md` | | End-to-end implementation and validation | `~/.config/mosaic/guides/E2E-DELIVERY.md` |
| Orchestrating autonomous tasks | `~/.config/mosaic/guides/orchestrator.md` | | PRD creation and requirements definition | `~/.config/mosaic/guides/PRD.md` |
| Ralph autonomous development | `~/.config/mosaic/guides/ralph-autonomous.md` | | Bootstrapping this project | `~/.config/mosaic/guides/BOOTSTRAP.md` |
| Backend/API development | `~/.config/mosaic/guides/backend.md` | | Orchestrating autonomous tasks | `~/.config/mosaic/guides/ORCHESTRATOR.md` |
| Authentication/Authorization | `~/.config/mosaic/guides/authentication.md` | | Backend/API development | `~/.config/mosaic/guides/BACKEND.md` |
| Code review | `~/.config/mosaic/guides/code-review.md` | | Authentication/Authorization | `~/.config/mosaic/guides/AUTHENTICATION.md` |
| QA/Testing | `~/.config/mosaic/guides/qa-testing.md` | | Code review | `~/.config/mosaic/guides/CODE-REVIEW.md` |
| Infrastructure/DevOps | `~/.config/mosaic/guides/infrastructure.md` | | Documentation updates and standards | `~/.config/mosaic/guides/DOCUMENTATION.md` |
| Secrets management (Vault) | `~/.config/mosaic/guides/vault-secrets.md` | | QA/Testing | `~/.config/mosaic/guides/QA-TESTING.md` |
| Infrastructure/DevOps | `~/.config/mosaic/guides/INFRASTRUCTURE.md` |
| Secrets management (Vault) | `~/.config/mosaic/guides/VAULT-SECRETS.md` |
## Technology Stack ## Technology Stack
@@ -43,6 +45,7 @@ ${PROJECT_DIR}/
│ └── ${PROJECT_SLUG}/ # Main package │ └── ${PROJECT_SLUG}/ # Main package
├── tests/ # Test files ├── tests/ # Test files
├── docs/ ├── docs/
│ ├── PRD.md # Requirements source (or PRD.json)
│ └── scratchpads/ # Per-issue working documents │ └── scratchpads/ # Per-issue working documents
├── pyproject.toml # Project configuration ├── pyproject.toml # Project configuration
└── .env.example # Environment template └── .env.example # Environment template
@@ -87,14 +90,69 @@ uv run pip-audit # Dependency vulnerabilities
uv run ruff check src/ tests/ && uv run ruff format --check src/ && uv run mypy src/ && uv run pytest --cov uv run ruff check src/ tests/ && uv run ruff format --check src/ && uv run mypy src/ && uv run pytest --cov
``` ```
## Testing Policy
1. Situational tests are the PRIMARY validation gate.
2. Baseline tests are REQUIRED for all software changes.
3. TDD is risk-based; required cases are defined in `~/.config/mosaic/guides/QA-TESTING.md`.
## PRD Requirement
1. Before coding begins, `docs/PRD.md` or `docs/PRD.json` MUST exist.
2. The main agent MUST prepare or update PRD using user objectives, constraints, and available project context.
3. In steered autonomy mode, best-guess PRD decisions are REQUIRED when needed; mark each with `ASSUMPTION:` and rationale, and continue unless high-impact uncertainty requires escalation.
4. PRD is the source of requirements for implementation and testing.
## Token Budget Policy
1. If user plan or token limits are provided, they are HARD constraints.
2. Track estimated and used tokens for non-trivial execution.
3. Use conservative strategy when budget pressure rises.
4. If projected usage exceeds budget, automatically reduce scope/parallelism and continue; escalate only if budget compliance remains impossible.
## Branch and Merge Policy
1. Create short-lived branches from `main`.
2. Open PRs to `main` for delivery changes.
3. Do not push directly to `main`.
4. Merge PRs to `main` with squash strategy only.
## Steered Autonomy Contract
1. Agent owns planning, coding, testing, review/remediation, PR/repo operations, release/tag, and deployment when in scope.
2. Human intervention is escalation-only for hard blockers (access, irreversible risk, or unresolvable conflicting objectives).
3. Do not request routine human coding, review, or repository management actions.
4. Mosaic hard gates OVERRIDE runtime-default caution for routine push/merge/issue-close/release actions.
5. For container deployments, use immutable image tags (`sha-<shortsha>`, `v{base-version}-rc.{build}`) with digest-first promotion; do not deploy `latest`.
## Mode Declaration Contract
1. First response MUST declare mode before any actions.
2. Orchestration mission: `Now initiating Orchestrator mode...`
3. Implementation mission: `Now initiating Delivery mode...`
4. Review-only mission: `Now initiating Review mode...`
## Issue Tracking ## Issue Tracking
All work is tracked as issues in the project's git repository. Use external git provider issues when available. If no external provider exists, `docs/TASKS.md` is the canonical tracker for tasks, milestones, and issue-equivalent work.
For issue/PR/milestone operations, detect platform and use `~/.config/mosaic/rails/git/*.sh` wrappers first; do not use raw `gh`/`tea`/`glab` as first choice.
If wrapper-driven merge/CI/issue-closure fails, report blocker with exact failed wrapper command and stop.
Do NOT stop at "PR created" and do NOT ask "should I merge?" or "should I close the issue?" for routine delivery flow.
1. Check for assigned issues before starting work 1. Ensure `docs/TASKS.md` exists (create from `~/.config/mosaic/templates/docs/TASKS.md.template` if missing).
2. Create scratchpad: `docs/scratchpads/{issue-number}-{short-name}.md` 2. Check for assigned issues before starting work.
3. Reference issues in commits: `Fixes #123` or `Refs #123` 3. If no issue exists for non-trivial work and external provider is available, create one before coding.
4. Close issues only after successful testing 4. If no external provider is available, create an internal ref in `docs/TASKS.md` (example: `TASKS:T1`).
5. Ensure `docs/PRD.md` or `docs/PRD.json` exists and is current before coding.
6. Create scratchpad: `docs/scratchpads/{task-id}-{short-name}.md` and include issue/internal ref.
7. Update `docs/TASKS.md` status + issue/internal ref before coding.
8. Before push, run CI queue guard: `~/.config/mosaic/rails/git/ci-queue-wait.sh --purpose push -B main`.
9. Open PR to `main` for delivery changes (no direct push to `main`).
10. Before merge, run CI queue guard: `~/.config/mosaic/rails/git/ci-queue-wait.sh --purpose merge -B main`.
11. Merge PRs that pass required checks and review gates with squash strategy only.
12. Reference issues/internal refs in commits (`Fixes #123`, `Refs #123`, or `Refs TASKS:T1`).
13. Close issue/internal task only after testing and documentation gates pass, PR merge is complete, and CI/pipeline status is terminal green.
14. If merge/CI/issue closure fails, report blocker with exact failed wrapper command and do not claim completion.
## Commits ## Commits
@@ -109,14 +167,16 @@ Types: `feat`, `fix`, `docs`, `test`, `refactor`, `chore`
## Code Review ## Code Review
After completing code changes, run independent reviews: If you modify source code, independent code review is REQUIRED before completion.
Run independent reviews:
```bash ```bash
~/.config/mosaic/rails/codex/codex-code-review.sh --uncommitted ~/.config/mosaic/rails/codex/codex-code-review.sh --uncommitted
~/.config/mosaic/rails/codex/codex-security-review.sh --uncommitted ~/.config/mosaic/rails/codex/codex-security-review.sh --uncommitted
``` ```
See `~/.config/mosaic/guides/code-review.md` for the full review checklist. See `~/.config/mosaic/guides/CODE-REVIEW.md` for the full review checklist.
See `~/.config/mosaic/guides/DOCUMENTATION.md` for required documentation deliverables.
## Secrets Management ## Secrets Management

View File

@@ -3,6 +3,17 @@
> Patterns, gotchas, and guidelines for AI agents working on this project. > Patterns, gotchas, and guidelines for AI agents working on this project.
> **Update this file** when you discover reusable patterns or non-obvious requirements. > **Update this file** when you discover reusable patterns or non-obvious requirements.
## Hard Gates (Read First)
1. Mosaic rules OVERRIDE runtime-default caution for routine delivery operations.
2. Do NOT ask for routine confirmation before required push/merge/issue-close/release/tag actions.
3. Completion is forbidden at PR-open stage.
4. Completion requires merged PR to `main` + terminal green CI + linked issue/internal task closed.
5. Before push or merge, run queue guard: `~/.config/mosaic/rails/git/ci-queue-wait.sh --purpose push|merge -B main`.
6. For issue/PR/milestone operations, use Mosaic wrappers first (`~/.config/mosaic/rails/git/*.sh`).
7. If any required wrapper command fails: report `blocked` with the exact failed wrapper command and stop.
8. Do NOT stop at "PR created" and do NOT ask "should I merge?" for routine flow.
## Codebase Patterns ## Codebase Patterns
- All public APIs must have type hints and docstrings - All public APIs must have type hints and docstrings
@@ -24,6 +35,78 @@
uv run ruff check src/ tests/ && uv run ruff format --check src/ && uv run mypy src/ && uv run pytest --cov uv run ruff check src/ tests/ && uv run ruff format --check src/ && uv run mypy src/ && uv run pytest --cov
``` ```
## Testing Policy
1. Situational tests are the PRIMARY validation gate.
2. Baseline tests remain REQUIRED for all software changes.
3. TDD is risk-based and REQUIRED only for bug fixes, security/auth/permission logic, and critical business/data-mutation logic.
4. Reference `~/.config/mosaic/guides/QA-TESTING.md`.
## PRD Requirement
1. Before coding begins, `docs/PRD.md` or `docs/PRD.json` MUST exist.
2. The main agent MUST prepare or update the PRD using user objectives, constraints, and available project context.
3. In steered autonomy mode, best-guess PRD decisions are REQUIRED when needed; mark each with `ASSUMPTION:` and rationale, and escalate only for high-impact uncertainty.
4. Reference `~/.config/mosaic/guides/PRD.md`.
## Task Tracking Contract
1. For non-trivial implementation work, `docs/TASKS.md` MUST exist before coding.
2. If external git provider is available (Gitea/GitHub/GitLab), create/update issue(s) before coding and map them in `docs/TASKS.md`.
3. If no external provider is available, use internal refs in `docs/TASKS.md` (example: `TASKS:T1`).
4. Keep `docs/TASKS.md` status in sync with actual progress until completion.
5. For issue/PR/milestone actions, detect platform and use `~/.config/mosaic/rails/git/*.sh` wrappers first (no raw `gh`/`tea`/`glab` as first choice).
6. If wrapper-driven merge/CI/issue-closure fails, report blocker with the exact failed wrapper command and stop (do not claim completion).
## Documentation Contract
Documentation is a hard delivery gate.
If code/API/auth/infra changes, required documentation updates MUST be completed before task closure.
Keep `docs/` root clean and store reports/artifacts in scoped folders (`docs/reports/`, `docs/tasks/`, `docs/releases/`, `docs/scratchpads/`).
Reference:
- `~/.config/mosaic/guides/DOCUMENTATION.md`
- `~/.config/mosaic/templates/docs/DOCUMENTATION-CHECKLIST.md`
## Token Budget Policy
1. If user plan or token limits are provided, they are HARD constraints.
2. Track estimated and used tokens for non-trivial execution.
3. Shift to conservative strategy when budget pressure rises (smaller scope, fewer parallel actions, reduced re-reading).
4. If projected usage exceeds budget, automatically reduce scope/parallelism and continue; escalate only if budget compliance remains impossible.
## Merge Strategy (Hard Rule)
1. Create short-lived branches from `main`.
2. Open PRs to `main` for delivery changes.
3. Do not push directly to `main`.
4. Merge PRs to `main` with squash strategy only.
5. Do not mark implementation complete until PR is merged.
6. Do not mark implementation complete until CI/pipeline status is terminal green.
7. Close linked issues/tasks only after merge + green CI.
8. Before push or merge, run CI queue guard: `~/.config/mosaic/rails/git/ci-queue-wait.sh --purpose push|merge -B main`.
## Container Release Strategy (When Applicable)
1. Use immutable image tags: `sha-<shortsha>` and `v{base-version}-rc.{build}`.
2. Use mutable environment tags only as pointers (`testing`, optional `staging`, `prod`).
3. Deploy/promote by immutable digest; do not deploy by mutable tag alone.
4. Do not use `latest` or `dev` as deployment references.
5. Use blue-green by default; use canary only with automated metrics and rollback gates.
## Steered Autonomy Contract
1. Agent owns end-to-end delivery: plan, code, test, review, remediate, commit, push, PR/repo operations, release/tag, and deployment when in scope.
2. Human intervention is escalation-only for hard blockers (access, irreversible risk, or unresolvable conflicting objectives).
3. Code review is agent-executed and REQUIRED for any source-code change.
## Mode Declaration Contract
1. First response MUST declare mode before any actions.
2. Orchestration mission: `Now initiating Orchestrator mode...`
3. Implementation mission: `Now initiating Delivery mode...`
4. Review-only mission: `Now initiating Review mode...`
## Key Files ## Key Files
| File | Purpose | | File | Purpose |

View File

@@ -9,12 +9,14 @@
| Task Type | Guide | | Task Type | Guide |
|-----------|-------| |-----------|-------|
| Bootstrapping this project | `~/.config/mosaic/guides/bootstrap.md` | | End-to-end implementation and validation | `~/.config/mosaic/guides/E2E-DELIVERY.md` |
| Orchestrating autonomous tasks | `~/.config/mosaic/guides/orchestrator.md` | | PRD creation and requirements definition | `~/.config/mosaic/guides/PRD.md` |
| Ralph autonomous development | `~/.config/mosaic/guides/ralph-autonomous.md` | | Bootstrapping this project | `~/.config/mosaic/guides/BOOTSTRAP.md` |
| Backend/API development | `~/.config/mosaic/guides/backend.md` | | Orchestrating autonomous tasks | `~/.config/mosaic/guides/ORCHESTRATOR.md` |
| Code review | `~/.config/mosaic/guides/code-review.md` | | Backend/API development | `~/.config/mosaic/guides/BACKEND.md` |
| QA/Testing | `~/.config/mosaic/guides/qa-testing.md` | | Code review | `~/.config/mosaic/guides/CODE-REVIEW.md` |
| Documentation updates and standards | `~/.config/mosaic/guides/DOCUMENTATION.md` |
| QA/Testing | `~/.config/mosaic/guides/QA-TESTING.md` |
## Technology Stack ## Technology Stack
@@ -37,6 +39,7 @@ ${PROJECT_DIR}/
│ └── ${PROJECT_SLUG}/ # Main package │ └── ${PROJECT_SLUG}/ # Main package
├── tests/ # Test files ├── tests/ # Test files
├── docs/ ├── docs/
│ ├── PRD.md # Requirements source (or PRD.json)
│ └── scratchpads/ # Per-issue working documents │ └── scratchpads/ # Per-issue working documents
└── pyproject.toml # Project configuration └── pyproject.toml # Project configuration
``` ```
@@ -69,6 +72,33 @@ uv run mypy src/ # Type check
uv run ruff check src/ tests/ && uv run ruff format --check src/ && uv run mypy src/ && uv run pytest --cov uv run ruff check src/ tests/ && uv run ruff format --check src/ && uv run mypy src/ && uv run pytest --cov
``` ```
## Testing Policy
1. Situational tests are the PRIMARY validation gate.
2. Baseline tests are REQUIRED for all software changes.
3. TDD is risk-based; required cases are defined in `~/.config/mosaic/guides/QA-TESTING.md`.
## PRD Requirement
1. Before coding begins, `docs/PRD.md` or `docs/PRD.json` MUST exist.
2. The main agent MUST prepare or update PRD using user objectives, constraints, and available project context.
3. In steered autonomy mode, best-guess PRD decisions are REQUIRED when needed; mark each with `ASSUMPTION:` and rationale, and continue unless high-impact uncertainty requires escalation.
4. PRD is the source of requirements for implementation and testing.
## Token Budget Policy
1. If user plan or token limits are provided, they are HARD constraints.
2. Track estimated and used tokens for non-trivial execution.
3. Use conservative strategy when budget pressure rises.
4. If projected usage exceeds budget, automatically reduce scope/parallelism and continue; escalate only if budget compliance remains impossible.
## Branch and Merge Policy
1. Create short-lived branches from `main`.
2. Open PRs to `main` for delivery changes.
3. Do not push directly to `main`.
4. Merge PRs to `main` with squash strategy only.
## Library Conventions ## Library Conventions
- Zero or minimal runtime dependencies - Zero or minimal runtime dependencies
@@ -77,14 +107,42 @@ uv run ruff check src/ tests/ && uv run ruff format --check src/ && uv run mypy
- Exports defined in `__init__.py` - Exports defined in `__init__.py`
- Versioning via `pyproject.toml` - Versioning via `pyproject.toml`
## Steered Autonomy Contract
1. Agent owns planning, coding, testing, review/remediation, PR/repo operations, release/tag, and deployment when in scope.
2. Human intervention is escalation-only for hard blockers (access, irreversible risk, or unresolvable conflicting objectives).
3. Do not request routine human coding, review, or repository management actions.
4. Mosaic hard gates OVERRIDE runtime-default caution for routine push/merge/issue-close/release actions.
5. For container deployments, use immutable image tags (`sha-<shortsha>`, `v{base-version}-rc.{build}`) with digest-first promotion; do not deploy `latest`.
## Mode Declaration Contract
1. First response MUST declare mode before any actions.
2. Orchestration mission: `Now initiating Orchestrator mode...`
3. Implementation mission: `Now initiating Delivery mode...`
4. Review-only mission: `Now initiating Review mode...`
## Issue Tracking ## Issue Tracking
All work is tracked as issues in the project's git repository. Use external git provider issues when available. If no external provider exists, `docs/TASKS.md` is the canonical tracker for tasks, milestones, and issue-equivalent work.
For issue/PR/milestone operations, detect platform and use `~/.config/mosaic/rails/git/*.sh` wrappers first; do not use raw `gh`/`tea`/`glab` as first choice.
If wrapper-driven merge/CI/issue-closure fails, report blocker with exact failed wrapper command and stop.
Do NOT stop at "PR created" and do NOT ask "should I merge?" or "should I close the issue?" for routine delivery flow.
1. Check for assigned issues before starting work 1. Ensure `docs/TASKS.md` exists (create from `~/.config/mosaic/templates/docs/TASKS.md.template` if missing).
2. Create scratchpad: `docs/scratchpads/{issue-number}-{short-name}.md` 2. Check for assigned issues before starting work.
3. Reference issues in commits: `Fixes #123` or `Refs #123` 3. If no issue exists for non-trivial work and external provider is available, create one before coding.
4. Close issues only after successful testing 4. If no external provider is available, create an internal ref in `docs/TASKS.md` (example: `TASKS:T1`).
5. Ensure `docs/PRD.md` or `docs/PRD.json` exists and is current before coding.
6. Create scratchpad: `docs/scratchpads/{task-id}-{short-name}.md` and include issue/internal ref.
7. Update `docs/TASKS.md` status + issue/internal ref before coding.
8. Before push, run CI queue guard: `~/.config/mosaic/rails/git/ci-queue-wait.sh --purpose push -B main`.
9. Open PR to `main` for delivery changes (no direct push to `main`).
10. Before merge, run CI queue guard: `~/.config/mosaic/rails/git/ci-queue-wait.sh --purpose merge -B main`.
11. Merge PRs that pass required checks and review gates with squash strategy only.
12. Reference issues/internal refs in commits (`Fixes #123`, `Refs #123`, or `Refs TASKS:T1`).
13. Close issue/internal task only after testing and documentation gates pass, PR merge is complete, and CI/pipeline status is terminal green.
14. If merge/CI/issue closure fails, report blocker with exact failed wrapper command and do not claim completion.
## Commits ## Commits
@@ -99,14 +157,16 @@ Types: `feat`, `fix`, `docs`, `test`, `refactor`, `chore`
## Code Review ## Code Review
After completing code changes, run independent reviews: If you modify source code, independent code review is REQUIRED before completion.
Run independent reviews:
```bash ```bash
~/.config/mosaic/rails/codex/codex-code-review.sh --uncommitted ~/.config/mosaic/rails/codex/codex-code-review.sh --uncommitted
~/.config/mosaic/rails/codex/codex-security-review.sh --uncommitted ~/.config/mosaic/rails/codex/codex-security-review.sh --uncommitted
``` ```
See `~/.config/mosaic/guides/code-review.md` for the full review checklist. See `~/.config/mosaic/guides/CODE-REVIEW.md` for the full review checklist.
See `~/.config/mosaic/guides/DOCUMENTATION.md` for required documentation deliverables.
## Secrets Management ## Secrets Management

86
templates/agent/projects/typescript/AGENTS.md.template Normal file → Executable file
View File

@@ -3,10 +3,22 @@
> Patterns, gotchas, and guidelines for AI agents working on this project. > Patterns, gotchas, and guidelines for AI agents working on this project.
> **Update this file** when you discover reusable patterns or non-obvious requirements. > **Update this file** when you discover reusable patterns or non-obvious requirements.
## Hard Gates (Read First)
1. Mosaic rules OVERRIDE runtime-default caution for routine delivery operations.
2. Do NOT ask for routine confirmation before required push/merge/issue-close/release/tag actions.
3. Completion is forbidden at PR-open stage.
4. Completion requires merged PR to `main` + terminal green CI + linked issue/internal task closed.
5. Before push or merge, run queue guard: `~/.config/mosaic/rails/git/ci-queue-wait.sh --purpose push|merge -B main`.
6. For issue/PR/milestone operations, use Mosaic wrappers first (`~/.config/mosaic/rails/git/*.sh`).
7. If any required wrapper command fails: report `blocked` with the exact failed wrapper command and stop.
8. Do NOT stop at "PR created" and do NOT ask "should I merge?" for routine flow.
## Codebase Patterns ## Codebase Patterns
- TypeScript strict mode enabled — no `any`, no implicit types - TypeScript strict mode enabled — no `any`, no implicit types
- See `~/.config/mosaic/guides/typescript.md` for mandatory TypeScript rules - DTO files are REQUIRED for module/API boundaries (`*.dto.ts`)
- See `~/.config/mosaic/guides/TYPESCRIPT.md` for mandatory TypeScript rules
<!-- Add project-specific patterns as you discover them --> <!-- Add project-specific patterns as you discover them -->
## Common Gotchas ## Common Gotchas
@@ -24,6 +36,78 @@
${QUALITY_GATES} ${QUALITY_GATES}
``` ```
## Testing Policy
1. Situational tests are the PRIMARY validation gate.
2. Baseline tests remain REQUIRED for all software changes.
3. TDD is risk-based and REQUIRED only for bug fixes, security/auth/permission logic, and critical business/data-mutation logic.
4. Reference `~/.config/mosaic/guides/QA-TESTING.md`.
## PRD Requirement
1. Before coding begins, `docs/PRD.md` or `docs/PRD.json` MUST exist.
2. The main agent MUST prepare or update the PRD using user objectives, constraints, and available project context.
3. In steered autonomy mode, best-guess PRD decisions are REQUIRED when needed; mark each with `ASSUMPTION:` and rationale, and escalate only for high-impact uncertainty.
4. Reference `~/.config/mosaic/guides/PRD.md`.
## Task Tracking Contract
1. For non-trivial implementation work, `docs/TASKS.md` MUST exist before coding.
2. If external git provider is available (Gitea/GitHub/GitLab), create/update issue(s) before coding and map them in `docs/TASKS.md`.
3. If no external provider is available, use internal refs in `docs/TASKS.md` (example: `TASKS:T1`).
4. Keep `docs/TASKS.md` status in sync with actual progress until completion.
5. For issue/PR/milestone actions, detect platform and use `~/.config/mosaic/rails/git/*.sh` wrappers first (no raw `gh`/`tea`/`glab` as first choice).
6. If wrapper-driven merge/CI/issue-closure fails, report blocker with the exact failed wrapper command and stop (do not claim completion).
## Documentation Contract
Documentation is a hard delivery gate.
If code/API/auth/infra changes, required documentation updates MUST be completed before task closure.
Keep `docs/` root clean and store reports/artifacts in scoped folders (`docs/reports/`, `docs/tasks/`, `docs/releases/`, `docs/scratchpads/`).
Reference:
- `~/.config/mosaic/guides/DOCUMENTATION.md`
- `~/.config/mosaic/templates/docs/DOCUMENTATION-CHECKLIST.md`
## Token Budget Policy
1. If user plan or token limits are provided, they are HARD constraints.
2. Track estimated and used tokens for non-trivial execution.
3. Shift to conservative strategy when budget pressure rises (smaller scope, fewer parallel actions, reduced re-reading).
4. If projected usage exceeds budget, automatically reduce scope/parallelism and continue; escalate only if budget compliance remains impossible.
## Merge Strategy (Hard Rule)
1. Create short-lived branches from `main`.
2. Open PRs to `main` for delivery changes.
3. Do not push directly to `main`.
4. Merge PRs to `main` with squash strategy only.
5. Do not mark implementation complete until PR is merged.
6. Do not mark implementation complete until CI/pipeline status is terminal green.
7. Close linked issues/tasks only after merge + green CI.
8. Before push or merge, run CI queue guard: `~/.config/mosaic/rails/git/ci-queue-wait.sh --purpose push|merge -B main`.
## Container Release Strategy (When Applicable)
1. Use immutable image tags: `sha-<shortsha>` and `v{base-version}-rc.{build}`.
2. Use mutable environment tags only as pointers (`testing`, optional `staging`, `prod`).
3. Deploy/promote by immutable digest; do not deploy by mutable tag alone.
4. Do not use `latest` or `dev` as deployment references.
5. Use blue-green by default; use canary only with automated metrics and rollback gates.
## Steered Autonomy Contract
1. Agent owns end-to-end delivery: plan, code, test, review, remediate, commit, push, PR/repo operations, release/tag, and deployment when in scope.
2. Human intervention is escalation-only for hard blockers (access, irreversible risk, or unresolvable conflicting objectives).
3. Code review is agent-executed and REQUIRED for any source-code change.
## Mode Declaration Contract
1. First response MUST declare mode before any actions.
2. Orchestration mission: `Now initiating Orchestrator mode...`
3. Implementation mission: `Now initiating Delivery mode...`
4. Review-only mission: `Now initiating Review mode...`
## Key Files ## Key Files
| File | Purpose | | File | Purpose |

95
templates/agent/projects/typescript/CLAUDE.md.template Normal file → Executable file
View File

@@ -9,13 +9,15 @@
| Task Type | Guide | | Task Type | Guide |
|-----------|-------| |-----------|-------|
| Bootstrapping this project | `~/.config/mosaic/guides/bootstrap.md` | | End-to-end implementation and validation | `~/.config/mosaic/guides/E2E-DELIVERY.md` |
| Orchestrating autonomous tasks | `~/.config/mosaic/guides/orchestrator.md` | | PRD creation and requirements definition | `~/.config/mosaic/guides/PRD.md` |
| Ralph autonomous development | `~/.config/mosaic/guides/ralph-autonomous.md` | | Bootstrapping this project | `~/.config/mosaic/guides/BOOTSTRAP.md` |
| Frontend development | `~/.config/mosaic/guides/frontend.md` | | Orchestrating autonomous tasks | `~/.config/mosaic/guides/ORCHESTRATOR.md` |
| TypeScript strict typing | `~/.config/mosaic/guides/typescript.md` | | Frontend development | `~/.config/mosaic/guides/FRONTEND.md` |
| Code review | `~/.config/mosaic/guides/code-review.md` | | TypeScript strict typing | `~/.config/mosaic/guides/TYPESCRIPT.md` |
| QA/Testing | `~/.config/mosaic/guides/qa-testing.md` | | Code review | `~/.config/mosaic/guides/CODE-REVIEW.md` |
| Documentation updates and standards | `~/.config/mosaic/guides/DOCUMENTATION.md` |
| QA/Testing | `~/.config/mosaic/guides/QA-TESTING.md` |
## Technology Stack ## Technology Stack
@@ -37,6 +39,7 @@ ${PROJECT_DIR}/
├── src/ # Source code ├── src/ # Source code
├── tests/ # Test files ├── tests/ # Test files
├── docs/ ├── docs/
│ ├── PRD.md # Requirements source (or PRD.json)
│ └── scratchpads/ # Per-issue working documents │ └── scratchpads/ # Per-issue working documents
└── ${CONFIG_FILES} # Configuration files └── ${CONFIG_FILES} # Configuration files
``` ```
@@ -67,14 +70,76 @@ ${TYPECHECK_COMMAND}
${QUALITY_GATES} ${QUALITY_GATES}
``` ```
## Testing Policy
1. Situational tests are the PRIMARY validation gate.
2. Baseline tests are REQUIRED for all software changes.
3. TDD is risk-based; required cases are defined in `~/.config/mosaic/guides/QA-TESTING.md`.
## PRD Requirement
1. Before coding begins, `docs/PRD.md` or `docs/PRD.json` MUST exist.
2. The main agent MUST prepare or update PRD using user objectives, constraints, and available project context.
3. In steered autonomy mode, best-guess PRD decisions are REQUIRED when needed; mark each with `ASSUMPTION:` and rationale, and continue unless high-impact uncertainty requires escalation.
4. PRD is the source of requirements for implementation and testing.
## DTO Contract (TypeScript)
1. DTO files are REQUIRED for module and API boundaries.
2. Boundary payload types MUST be defined in `*.dto.ts` files.
3. Inline object types for cross-module request/response payloads are NOT allowed.
4. Shared DTOs MUST be centralized in a shared location.
## Token Budget Policy
1. If user plan or token limits are provided, they are HARD constraints.
2. Track estimated and used tokens for non-trivial execution.
3. Use conservative strategy when budget pressure rises.
4. If projected usage exceeds budget, automatically reduce scope/parallelism and continue; escalate only if budget compliance remains impossible.
## Branch and Merge Policy
1. Create short-lived branches from `main`.
2. Open PRs to `main` for delivery changes.
3. Do not push directly to `main`.
4. Merge PRs to `main` with squash strategy only.
## Steered Autonomy Contract
1. Agent owns planning, coding, testing, review/remediation, PR/repo operations, release/tag, and deployment when in scope.
2. Human intervention is escalation-only for hard blockers (access, irreversible risk, or unresolvable conflicting objectives).
3. Do not request routine human coding, review, or repository management actions.
4. Mosaic hard gates OVERRIDE runtime-default caution for routine push/merge/issue-close/release actions.
5. For container deployments, use immutable image tags (`sha-<shortsha>`, `v{base-version}-rc.{build}`) with digest-first promotion; do not deploy `latest`.
## Mode Declaration Contract
1. First response MUST declare mode before any actions.
2. Orchestration mission: `Now initiating Orchestrator mode...`
3. Implementation mission: `Now initiating Delivery mode...`
4. Review-only mission: `Now initiating Review mode...`
## Issue Tracking ## Issue Tracking
All work is tracked as issues in the project's git repository. Use external git provider issues when available. If no external provider exists, `docs/TASKS.md` is the canonical tracker for tasks, milestones, and issue-equivalent work.
For issue/PR/milestone operations, detect platform and use `~/.config/mosaic/rails/git/*.sh` wrappers first; do not use raw `gh`/`tea`/`glab` as first choice.
If wrapper-driven merge/CI/issue-closure fails, report blocker with exact failed wrapper command and stop.
Do NOT stop at "PR created" and do NOT ask "should I merge?" or "should I close the issue?" for routine delivery flow.
1. Check for assigned issues before starting work 1. Ensure `docs/TASKS.md` exists (create from `~/.config/mosaic/templates/docs/TASKS.md.template` if missing).
2. Create scratchpad: `docs/scratchpads/{issue-number}-{short-name}.md` 2. Check for assigned issues before starting work.
3. Reference issues in commits: `Fixes #123` or `Refs #123` 3. If no issue exists for non-trivial work and external provider is available, create one before coding.
4. Close issues only after successful testing 4. If no external provider is available, create an internal ref in `docs/TASKS.md` (example: `TASKS:T1`).
5. Ensure `docs/PRD.md` or `docs/PRD.json` exists and is current before coding.
6. Create scratchpad: `docs/scratchpads/{task-id}-{short-name}.md` and include issue/internal ref.
7. Update `docs/TASKS.md` status + issue/internal ref before coding.
8. Before push, run CI queue guard: `~/.config/mosaic/rails/git/ci-queue-wait.sh --purpose push -B main`.
9. Open PR to `main` for delivery changes (no direct push to `main`).
10. Before merge, run CI queue guard: `~/.config/mosaic/rails/git/ci-queue-wait.sh --purpose merge -B main`.
11. Merge PRs that pass required checks and review gates with squash strategy only.
12. Reference issues/internal refs in commits (`Fixes #123`, `Refs #123`, or `Refs TASKS:T1`).
13. Close issue/internal task only after testing and documentation gates pass, PR merge is complete, and CI/pipeline status is terminal green.
14. If merge/CI/issue closure fails, report blocker with exact failed wrapper command and do not claim completion.
## Commits ## Commits
@@ -89,7 +154,8 @@ Types: `feat`, `fix`, `docs`, `test`, `refactor`, `chore`
## Code Review ## Code Review
After completing code changes, run independent reviews: If you modify source code, independent code review is REQUIRED before completion.
Run independent reviews:
```bash ```bash
# Code quality review (Codex) # Code quality review (Codex)
@@ -100,7 +166,8 @@ After completing code changes, run independent reviews:
``` ```
**Fallback:** If Codex is unavailable, use Claude's built-in review skills. **Fallback:** If Codex is unavailable, use Claude's built-in review skills.
See `~/.config/mosaic/guides/code-review.md` for the full review checklist. See `~/.config/mosaic/guides/CODE-REVIEW.md` for the full review checklist.
See `~/.config/mosaic/guides/DOCUMENTATION.md` for required documentation deliverables.
## Secrets Management ## Secrets Management

View File

@@ -0,0 +1,49 @@
# Documentation Completion Checklist
Use this checklist for every task that changes code, API contracts, auth, or operations.
## Required Artifacts
- [ ] `docs/PRD.md` or `docs/PRD.json` exists and is current
- [ ] `docs/USER-GUIDE/` updated as needed
- [ ] `docs/ADMIN-GUIDE/` updated as needed
- [ ] `docs/DEVELOPER-GUIDE/` updated as needed
- [ ] `docs/API/OPENAPI.yaml` (or `.json`) updated for API changes
- [ ] `docs/API/ENDPOINTS.md` updated for API changes
- [ ] `docs/SITEMAP.md` updated for navigation changes
## API Coverage
- [ ] All public endpoints are documented
- [ ] All private/internal endpoints are documented
- [ ] All API input schemas are documented
- [ ] All API output schemas are documented
- [ ] All endpoint auth/permission requirements are documented
- [ ] Error codes and failure behavior are documented
## Structural Standards (Book/Chapter/Page)
- [ ] `docs/USER-GUIDE/README.md` indexes user chapters/pages
- [ ] `docs/ADMIN-GUIDE/README.md` indexes admin chapters/pages
- [ ] `docs/DEVELOPER-GUIDE/README.md` indexes developer chapters/pages
## Docs Root Hygiene
- [ ] `docs/` root is clean and only contains canonical root docs (PRD, TASKS when active, SITEMAP, optional README) plus category directories
- [ ] Reports are under `docs/reports/<category>/` (not `docs/` root)
- [ ] Deferred findings are under `docs/reports/deferred/`
- [ ] Orchestrator learnings are under `docs/tasks/orchestrator-learnings.json`
- [ ] Release notes are under `docs/releases/`
- [ ] Archived task snapshots are under `docs/tasks/`
- [ ] Scratchpads are under `docs/scratchpads/`
## Review Gate
- [ ] Documentation changes are in the same logical change set as code/API changes
- [ ] Code review verified documentation completeness
- [ ] Missing docs were treated as blocker findings
## Publishing
- [ ] Publishing target was confirmed with user if unspecified
- [ ] Canonical source remains in-repo unless user explicitly declares otherwise

View File

@@ -0,0 +1,75 @@
# PRD: {PROJECT_OR_FEATURE_NAME}
## Metadata
- Owner: {owner}
- Date: {yyyy-mm-dd}
- Status: draft|approved|in-progress|completed
- Best-Guess Mode: true|false
## Problem Statement
{what problem is being solved and why now}
## Objectives
1. {objective-1}
2. {objective-2}
## Scope
### In Scope
1. {in-scope-item}
### Out of Scope
1. {out-of-scope-item}
## User/Stakeholder Requirements
1. {requirement}
## Functional Requirements
1. {functional-requirement}
## Non-Functional Requirements
1. Security: {requirements}
2. Performance: {requirements}
3. Reliability: {requirements}
4. Observability: {requirements}
## Acceptance Criteria
1. {ac-1}
2. {ac-2}
## Constraints and Dependencies
1. {constraint-or-dependency}
## Risks and Open Questions
1. Risk: {risk}
2. Open Question: {question}
## Testing and Verification Expectations
1. Baseline checks: {lint/type/unit/integration expectations}
2. Situational testing: {required situational checks}
3. Evidence format: {how verification will be reported}
## Milestone / Delivery Intent
1. Target milestone/version: {e.g., 0.0.2}
2. Definition of done: {completion conditions}
## Assumptions
List only if Best-Guess Mode is true.
Prefix each entry with `ASSUMPTION:`.
1. ASSUMPTION: {guessed decision and rationale}

View File

@@ -0,0 +1,17 @@
# TASKS
Canonical tracking for active work. Keep this file current.
## Rules
1. Update status as work progresses.
2. Link every non-trivial task to a provider issue (`#123`) or internal ref (`TASKS:T1`) if no provider is available.
3. Keep one row per active task.
4. Do not set `status=done` for source-code work until PR is merged, CI/pipeline is terminal green, and linked issue/ref is closed.
5. If merge/CI/issue closure fails, set `status=blocked` and record the exact failed wrapper command in `notes`.
## Tasks
| id | status | description | issue | repo | branch | depends_on | blocks | agent | started_at | completed_at | estimate | used | notes |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| T1 | not-started | Example task description | TASKS:T1 | app | feat/example | | | | | | | | |

View File

@@ -24,7 +24,7 @@ Commands:
Options: Options:
--poll-sec N Poll interval (default: 15) --poll-sec N Poll interval (default: 15)
--no-sync Skip docs/tasks.md -> orchestrator queue sync before run --no-sync Skip docs/TASKS.md -> orchestrator queue sync before run
USAGE USAGE
} }