From e3ec3e32e5f60cde075b72777b294f942893e7de Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Sat, 21 Feb 2026 09:55:34 -0600 Subject: [PATCH] chore: sync local Mosaic changes --- AGENTS.md | 780 ++++-------------- AUDIT-2026-02-17-framework-consistency.md | 2 +- README.md | 39 +- SOUL.md | 50 ++ bin/mosaic | 204 ++++- bin/mosaic-bootstrap-repo | 13 +- bin/mosaic-doctor | 64 +- bin/mosaic-doctor.ps1 | 81 +- bin/mosaic-ensure-sequential-thinking | 262 ++++++ bin/mosaic-ensure-sequential-thinking.ps1 | 114 +++ bin/mosaic-link-runtime-assets | 6 +- bin/mosaic-link-runtime-assets.ps1 | 7 +- bin/mosaic-sync-skills | 34 + bin/mosaic.ps1 | 164 +++- .../{authentication.md => AUTHENTICATION.md} | 0 guides/{backend.md => BACKEND.md} | 19 +- guides/BOOTSTRAP.md | 486 +++++++++++ guides/{code-review.md => CODE-REVIEW.md} | 122 ++- guides/DOCUMENTATION.md | 132 +++ guides/{frontend.md => FRONTEND.md} | 4 +- .../{infrastructure.md => INFRASTRUCTURE.md} | 71 +- guides/MEMORY.md | 27 + ...learnings.md => ORCHESTRATOR-LEARNINGS.md} | 8 +- guides/PRD.md | 63 ++ guides/QA-TESTING.md | 114 +++ guides/{typescript.md => TYPESCRIPT.md} | 38 + guides/{vault-secrets.md => VAULT-SECRETS.md} | 0 guides/bootstrap.md | 338 -------- guides/ci-cd-pipelines.md | 253 ++++-- guides/e2e-delivery.md | 203 +++++ guides/orchestrator.md | 447 ++++++++-- guides/qa-testing.md | 202 ----- install.ps1 | 15 + install.sh | 12 + profiles/README.md | 2 +- rails/bootstrap/agent-lint.sh | 56 +- rails/bootstrap/agent-upgrade.sh | 34 +- rails/bootstrap/init-project.sh | 38 +- rails/bootstrap/init-repo-labels.sh | 12 +- rails/codex/README.md | 2 +- rails/git/ci-queue-wait.ps1 | 247 ++++++ rails/git/ci-queue-wait.sh | 307 +++++++ rails/git/issue-create.sh | 92 ++- rails/git/issue-view.sh | 66 +- rails/git/milestone-create.ps1 | 12 +- rails/git/milestone-create.sh | 12 +- rails/git/pr-ci-wait.sh | 273 ++++++ rails/git/pr-merge.ps1 | 47 +- rails/git/pr-merge.sh | 58 +- rails/orchestrator-matrix/README.md | 2 +- .../controller/tasks_md_sync.py | 35 +- runtime/claude/CLAUDE.md | 10 +- runtime/claude/RUNTIME.md | 21 + .../{jarvis-ralph.json => jarvis-loop.json} | 23 +- runtime/claude/settings.json | 11 +- runtime/codex/RUNTIME.md | 21 + runtime/codex/instructions.md | 10 +- runtime/mcp/SEQUENTIAL-THINKING.json | 11 + runtime/opencode/AGENTS.md | 10 +- runtime/opencode/RUNTIME.md | 21 + skills-local/jarvis/SKILL.md | 2 +- skills-local/ralph/SKILL.md | 257 ------ skills-local/setup-cicd/SKILL.md | 2 +- templates/agent/AGENTS.md.template | 99 ++- templates/agent/CLAUDE.md.template | 102 ++- templates/agent/SPEC.md | 8 +- templates/agent/fragments/code-review.md | 5 +- .../agent/fragments/conditional-loading.md | 24 +- .../agent/projects/django/AGENTS.md.template | 101 ++- .../agent/projects/django/CLAUDE.md.template | 85 +- .../projects/nestjs-nextjs/AGENTS.md.template | 111 ++- .../projects/nestjs-nextjs/CLAUDE.md.template | 96 ++- .../python-fastapi/AGENTS.md.template | 83 ++ .../python-fastapi/CLAUDE.md.template | 92 ++- .../python-library/AGENTS.md.template | 83 ++ .../python-library/CLAUDE.md.template | 86 +- .../projects/typescript/AGENTS.md.template | 86 +- .../projects/typescript/CLAUDE.md.template | 95 ++- templates/docs/DOCUMENTATION-CHECKLIST.md | 49 ++ templates/docs/PRD.md.template | 75 ++ templates/docs/TASKS.md.template | 17 + .../repo/scripts/agent/orchestrator-daemon.sh | 2 +- 82 files changed, 5398 insertions(+), 1969 deletions(-) mode change 100644 => 100755 AGENTS.md create mode 100644 SOUL.md create mode 100755 bin/mosaic-ensure-sequential-thinking create mode 100755 bin/mosaic-ensure-sequential-thinking.ps1 rename guides/{authentication.md => AUTHENTICATION.md} (100%) rename guides/{backend.md => BACKEND.md} (89%) create mode 100755 guides/BOOTSTRAP.md rename guides/{code-review.md => CODE-REVIEW.md} (58%) mode change 100644 => 100755 create mode 100644 guides/DOCUMENTATION.md rename guides/{frontend.md => FRONTEND.md} (92%) rename guides/{infrastructure.md => INFRASTRUCTURE.md} (58%) create mode 100644 guides/MEMORY.md rename guides/{orchestrator-learnings.md => ORCHESTRATOR-LEARNINGS.md} (93%) create mode 100644 guides/PRD.md create mode 100644 guides/QA-TESTING.md rename guides/{typescript.md => TYPESCRIPT.md} (87%) rename guides/{vault-secrets.md => VAULT-SECRETS.md} (100%) delete mode 100644 guides/bootstrap.md create mode 100644 guides/e2e-delivery.md delete mode 100644 guides/qa-testing.md create mode 100644 rails/git/ci-queue-wait.ps1 create mode 100755 rails/git/ci-queue-wait.sh create mode 100755 rails/git/pr-ci-wait.sh mode change 100644 => 100755 rails/git/pr-merge.ps1 create mode 100644 runtime/claude/RUNTIME.md rename runtime/claude/settings-overlays/{jarvis-ralph.json => jarvis-loop.json} (59%) create mode 100644 runtime/codex/RUNTIME.md create mode 100644 runtime/mcp/SEQUENTIAL-THINKING.json create mode 100644 runtime/opencode/RUNTIME.md delete mode 100644 skills-local/ralph/SKILL.md mode change 100644 => 100755 templates/agent/AGENTS.md.template mode change 100644 => 100755 templates/agent/CLAUDE.md.template mode change 100644 => 100755 templates/agent/projects/django/AGENTS.md.template mode change 100644 => 100755 templates/agent/projects/django/CLAUDE.md.template mode change 100644 => 100755 templates/agent/projects/nestjs-nextjs/AGENTS.md.template mode change 100644 => 100755 templates/agent/projects/nestjs-nextjs/CLAUDE.md.template mode change 100644 => 100755 templates/agent/projects/python-fastapi/AGENTS.md.template mode change 100644 => 100755 templates/agent/projects/python-fastapi/CLAUDE.md.template mode change 100644 => 100755 templates/agent/projects/python-library/AGENTS.md.template mode change 100644 => 100755 templates/agent/projects/python-library/CLAUDE.md.template mode change 100644 => 100755 templates/agent/projects/typescript/AGENTS.md.template mode change 100644 => 100755 templates/agent/projects/typescript/CLAUDE.md.template create mode 100644 templates/docs/DOCUMENTATION-CHECKLIST.md create mode 100644 templates/docs/PRD.md.template create mode 100644 templates/docs/TASKS.md.template diff --git a/AGENTS.md b/AGENTS.md old mode 100644 new mode 100755 index c0db5a8..7e69fc9 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,633 +1,147 @@ -# Mosaic Global Agent Standards - -This is the universal agent configuration file for the Mosaic framework. -It applies to ALL agent sessions regardless of runtime (Claude, Codex, OpenCode, etc.). - -Canonical location: `~/.config/mosaic/AGENTS.md` - -## MANDATORY — Read Before Any Response - -BEFORE responding to any user message, READ these files in order: - -1. `~/.config/mosaic/SOUL.md` (identity and behavioral contract) -2. `~/.config/mosaic/STANDARDS.md` (machine-wide standards) -3. Project-local `AGENTS.md` (project operations and workflows) - -Do NOT respond to the user until you have loaded all three. - ---- - -# Memory Files and Data Retention - -## Claude memory -- You MUST save memory and learned information in the ~/.config/mosaic/memory dir -- 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 - ---- - -# Universal Development Standards - -## Core Principles -- Think critically. Don't just agree—suggest better approaches when appropriate. -- Quality over speed. No workarounds; implement proper solutions. -- No deprecated or unsupported packages. - -## Skills System - -**Skills are available in `~/.config/mosaic/skills/`.** Skills are instruction packages that provide domain expertise from `mosaic/agent-skills` plus local Mosaic skills. - -**Load a skill by reading its SKILL.md:** -``` -Read ~/.config/mosaic/skills//SKILL.md -``` - -### Skill Dispatch Table — Load the right skills for your task - -| Task Type | Skills to Load | Notes | -|-----------|---------------|-------| -| **NestJS development** | `nestjs-best-practices` | 40 rules, 10 categories | -| **Next.js / React** | `next-best-practices`, `vercel-react-best-practices` | RSC, async, performance | -| **React components** | `vercel-composition-patterns`, `shadcn-ui` | shadcn note: uses Tailwind v4 | -| **Vue / Nuxt** | `vue-best-practices`, `nuxt`, `pinia`, `vue-router-best-practices` | antfu conventions | -| **Vite / Vitest** | `vite`, `vitest` | Build + test tooling | -| **FastAPI / Python** | `fastapi`, `python-performance-optimization` | Pydantic v2, async SQLAlchemy | -| **Architecture** | `architecture-patterns` | Clean, Hexagonal, DDD | -| **Authentication** | `better-auth-best-practices`, `email-and-password-best-practices`, `two-factor-authentication-best-practices` | Better-Auth patterns | -| **UI / Styling** | `tailwind-design-system`, `ui-animation`, `web-design-guidelines` | Tailwind v4 | -| **Frontend design** | `frontend-design`, `brand-guidelines`, `canvas-design` | Design principles | -| **TDD / Testing** | `test-driven-development`, `webapp-testing`, `vue-testing-best-practices` | Red-Green-Refactor | -| **Linting** | `lint` | Zero-tolerance — detect linter, fix ALL violations, never disable rules | -| **Code review** | `pr-reviewer`, `code-review-excellence`, `verification-before-completion` | Platform-aware (Gitea/GitHub) | -| **Debugging** | `systematic-debugging` | Structured methodology | -| **Git workflow** | `finishing-a-development-branch`, `using-git-worktrees` | Branch + worktree patterns | -| **Document generation** | `pdf`, `docx`, `pptx`, `xlsx` | LibreOffice-based | -| **Writing / Comms** | `doc-coauthoring`, `internal-comms`, `copywriting`, `copy-editing` | | -| **Marketing** | `marketing-ideas`, `content-strategy`, `social-content`, `email-sequence` | 139 ideas across 14 categories | -| **SEO** | `seo-audit`, `programmatic-seo`, `schema-markup` | Technical + content SEO | -| **CRO / Conversion** | `page-cro`, `form-cro`, `signup-flow-cro`, `onboarding-cro` | Conversion optimization | -| **Pricing / Business** | `pricing-strategy`, `launch-strategy`, `competitor-alternatives` | SaaS focus | -| **Ads / Growth** | `paid-ads`, `analytics-tracking`, `ab-test-setup`, `referral-program` | | -| **Agent building** | `create-agent`, `ai-sdk`, `proactive-agent`, `dispatching-parallel-agents` | WAL Protocol, parallel workers | -| **Agent workflow** | `executing-plans`, `writing-plans`, `brainstorming` | Plan → execute | -| **Skill authoring** | `writing-skills`, `skill-creator` | TDD-based skill creation | -| **MCP servers** | `mcp-builder` | Model Context Protocol | -| **Generative art** | `algorithmic-art`, `theme-factory`, `slack-gif-creator` | | -| **Web artifacts** | `web-artifacts-builder` | Self-contained HTML | -| **CI/CD setup** | `setup-cicd` | Docker build/push pipeline | -| **Jarvis Brain** | `jarvis` | Brain repo context | -| **PRD creation** | `prd` | Generate PRDs | -| **Ralph development** | `ralph` | Autonomous dev agent | -| **Orchestration** | `kickstart` | `/kickstart [milestone\|issue\|task]` — launches orchestrator | - -### For Orchestrator / Programmatic Workers - -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..." -``` - -For Ralph prd.json stories, add a `skills` field: -```json -{ "id": "US-001", "skills": ["nestjs-best-practices", "test-driven-development"], ... } -``` - -### Fresh Machine Setup -```bash -npx skills add https://git.mosaicstack.dev/mosaic/agent-skills.git --agent claude-code -``` - -## Ralph Autonomous Development - -For autonomous feature development, use the Ralph pattern. Each iteration is a fresh context with persistent memory. - -### The Ralph Loop -``` -1. Read prd.json → Find highest priority story where passes: false -2. Read progress.txt → Check "Codebase Patterns" section first -3. Read AGENTS.md files → Check directory-specific patterns -4. Implement ONLY the single assigned story -5. Run quality checks (typecheck, lint, test) -6. Commit ONLY if all checks pass -7. Update prd.json → Set passes: true for completed story -8. Append learnings to progress.txt -9. Update AGENTS.md if reusable patterns discovered -10. Loop → Next story -``` - -### Memory Files -| File | Purpose | Location | -|------|---------|----------| -| `prd.json` | Task list with passes: true/false | Project root or scripts/ralph/ | -| `progress.txt` | Learnings between iterations | Same as prd.json | -| `AGENTS.md` | Directory-specific patterns | Any directory in repo | - -### Running Ralph -```bash -# Automated loop -./scripts/ralph/ralph.sh 10 - -# Manual single story -claude -p "Implement US-001 from prd.json following Ralph pattern" -``` - -### Creating New Features -1. Create PRD: `Load the prd skill and create a PRD for [feature]` -2. Convert to Ralph: `Load the ralph skill and convert tasks/prd-[name].md to prd.json` -3. Run Ralph: `./scripts/ralph/ralph.sh` - -**For full Ralph guide:** `~/.config/mosaic/guides/ralph-autonomous.md` - -## Project-Local AGENTS.md Pattern - -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.** - -```markdown -# Example AGENTS.md - -## 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//` (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 # List pipelines -woodpecker pipeline info # Pipeline details -woodpecker pipeline create # Trigger pipeline -woodpecker pipeline stop # Cancel pipeline -woodpecker pipeline start # Restart pipeline -woodpecker pipeline approve # Approve blocked -``` - -**Logs:** -```bash -woodpecker log show # View logs -woodpecker log show # Specific step -``` - -**Repositories:** -```bash -woodpecker repo ls # List repos -woodpecker repo add # Activate for CI -woodpecker repo rm # Deactivate -woodpecker repo repair # Repair webhooks -``` - -**Secrets:** -```bash -woodpecker secret ls # List secrets -woodpecker secret add -n KEY -v val # Add secret -woodpecker secret rm -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 -``` -(#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 "" > 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 -``` +# Mosaic Global Agent Contract + +Canonical file: `~/.config/mosaic/AGENTS.md` + +This file defines the mandatory behavior for all Mosaic agent runtimes. + +## MANDATORY Load Order (No Exceptions) + +Before responding to any user message, you MUST read these files in order: + +1. `~/.config/mosaic/SOUL.md` +2. `~/.config/mosaic/STANDARDS.md` +3. `~/.config/mosaic/AGENTS.md` +4. `~/.config/mosaic/guides/E2E-DELIVERY.md` +5. Project-local `AGENTS.md` (if present) +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` + +If any required file is missing, you MUST stop and report the missing file. + +## CRITICAL HARD GATES (Read First) + +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. +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`. +7. For issue/PR/milestone operations, you MUST use Mosaic wrappers first (`~/.config/mosaic/rails/git/*.sh`). +8. If any required wrapper command fails, status is `blocked`; report the exact failed wrapper command and stop. +9. Do NOT stop at "PR created". Do NOT ask "should I merge?" Do NOT ask "should I close the issue?". + +## Non-Negotiable Operating Rules + +1. You MUST create and maintain a task-specific scratchpad for every non-trivial task. +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`. +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. +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. +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. +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. +13. You MUST NOT use workarounds that bypass quality gates. +14. You MUST NOT hardcode secrets. +15. You MUST NOT use deprecated or unsupported dependencies. +16. When a milestone is completed, you MUST create and push a release tag and publish a repository release. +17. For every non-trivial implementation task, you MUST create or update `docs/TASKS.md` before coding and keep it current through completion. +18. You MUST keep `docs/` root clean and place reports/artifacts in scoped folders per `~/.config/mosaic/guides/DOCUMENTATION.md`. +19. For TypeScript codebases, DTO files are REQUIRED for module/API boundaries (`*.dto.ts`). +20. You MUST honor user plan/token budgets: monitor estimated vs used tokens and adjust execution strategy to stay within limits. +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. +22. You MUST own project execution end-to-end: planning, coding, testing, review, remediation, PR/repo operations, release/tag, and deployment when in scope. +23. Human intervention is escalation-only; do not ask the human to perform routine coding, review, or repository management work. +24. Deployment ownership is REQUIRED when deployment is in scope and target access is configured. +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. +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:` internal refs in `docs/TASKS.md`. +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. +28. Direct `gh`/`tea`/`glab` commands are forbidden as first choice when a Mosaic wrapper exists; use raw commands only as documented fallback. +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. +30. At session start, you MUST declare the operating mode in your first response before any tool calls or implementation steps. +31. For orchestration-oriented missions, the first line MUST be exactly: `Now initiating Orchestrator mode...` +32. For non-orchestrator implementation missions, the first line MUST be exactly: `Now initiating Delivery mode...` +33. For explicit review-only missions, the first line MUST be exactly: `Now initiating Review mode...` +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. +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. +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`. + +## Mode Declaration Protocol (Hard Rule) + +At session start, declare one mode before any actions: + +1. Orchestration mission: `Now initiating Orchestrator mode...` +2. Implementation mission: `Now initiating Delivery mode...` +3. Review-only mission: `Now initiating Review mode...` + +## Steered Autonomy Escalation Triggers + +Only interrupt the human when one of these is true: + +1. Missing credentials or platform access blocks progress. +2. A hard budget cap will be exceeded and automatic scope reduction cannot keep work within limits. +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. + +## Conditional Guide Loading + +Load additional guides when the task requires them. + +| Task | Required Guide | +|---|---| +| Project bootstrap | `~/.config/mosaic/guides/BOOTSTRAP.md` | +| PRD creation and requirements definition | `~/.config/mosaic/guides/PRD.md` | +| Orchestration flow | `~/.config/mosaic/guides/ORCHESTRATOR.md` | +| Frontend changes | `~/.config/mosaic/guides/FRONTEND.md` | +| Backend/API changes | `~/.config/mosaic/guides/BACKEND.md` | +| Documentation changes or any code/API/auth/infra change | `~/.config/mosaic/guides/DOCUMENTATION.md` | +| Authentication/authorization | `~/.config/mosaic/guides/AUTHENTICATION.md` | +| CI/CD changes | `~/.config/mosaic/guides/CI-CD-PIPELINES.md` | +| Infrastructure/DevOps | `~/.config/mosaic/guides/INFRASTRUCTURE.md` | +| Code review work | `~/.config/mosaic/guides/CODE-REVIEW.md` | +| TypeScript strict typing | `~/.config/mosaic/guides/TYPESCRIPT.md` | +| QA and test strategy | `~/.config/mosaic/guides/QA-TESTING.md` | +| Secrets and vault usage | `~/.config/mosaic/guides/VAULT-SECRETS.md` | +| Orchestrator estimation heuristics | `~/.config/mosaic/guides/ORCHESTRATOR-LEARNINGS.md` | +| Shared memory patterns | `~/.config/mosaic/guides/MEMORY.md` | + +## Embedded Delivery Cycle (Hard Rule) + +- 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. + +## Sequential-Thinking MCP (Hard Requirement) + +- `sequential-thinking` MCP server is REQUIRED for Mosaic operation. +- Installation and configuration are managed by Mosaic bootstrap and runtime linking. +- If sequential-thinking is unavailable, you MUST report the failure and stop planning-intensive execution. + +## Skills Policy + +- Use only the minimum required skills for the active task. +- Do not load unrelated skills. +- Follow skill trigger rules from the active runtime instruction layer. + +## Session Closure Requirement + +Before closing any implementation task: + +1. Confirm required tests passed. +2. Confirm situational tests passed (primary gate). +3. Confirm implementation is aligned to the active `docs/PRD.md` or `docs/PRD.json`. +4. Confirm acceptance criteria are mapped to verification evidence. +5. If source code changed, confirm independent code review passed. +6. Confirm required documentation updates were completed and reviewed. +7. Update scratchpad with decisions, results, and open risks. +8. Provide explicit completion evidence. +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). +11. Confirm linked issue is closed (or internal `docs/TASKS.md` equivalent is closed when no provider exists). +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. diff --git a/AUDIT-2026-02-17-framework-consistency.md b/AUDIT-2026-02-17-framework-consistency.md index cb99368..7dde5e5 100644 --- a/AUDIT-2026-02-17-framework-consistency.md +++ b/AUDIT-2026-02-17-framework-consistency.md @@ -100,7 +100,7 @@ The following legacy references remain in `mosaic-bootstrap` by design and are n - `README.md` - `profiles/README.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. diff --git a/README.md b/README.md index d8629e6..c7636d0 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ The installer will: - Install the framework to `~/.config/mosaic/` - Add `~/.config/mosaic/bin` to your PATH - Sync runtime adapters and skills +- Install and configure sequential-thinking MCP (hard requirement) - Run a health audit - Detect existing installs and prompt to keep or overwrite local files - 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) ├── SOUL.md ← User identity (generated by mosaic init) ├── 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.) ├── guides/ ← Operational guides ├── 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/RUNTIME.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-local/ ← Local cross-runtime skills └── 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 | |--------------|-------------------| -| `mosaic claude` | `--append-system-prompt` with AGENTS.md content | -| `mosaic codex` | Copies AGENTS.md to `~/.codex/instructions.md` before launch | -| `mosaic opencode` | Copies AGENTS.md to `~/.config/opencode/AGENTS.md` before launch | -| `claude` (direct) | `~/.claude/CLAUDE.md` thin pointer → "READ AGENTS.md" | -| `codex` (direct) | `~/.codex/instructions.md` thin pointer → "READ AGENTS.md" | -| `opencode` (direct) | `~/.config/opencode/AGENTS.md` thin pointer → "READ AGENTS.md" | +| `mosaic claude` | `--append-system-prompt` with composed runtime contract (`AGENTS.md` + runtime reference) | +| `mosaic codex` | Writes composed runtime contract to `~/.codex/instructions.md` before launch | +| `mosaic opencode` | Writes composed runtime contract to `~/.config/opencode/AGENTS.md` before launch | +| `claude` (direct) | `~/.claude/CLAUDE.md` thin pointer → load AGENTS + runtime reference | +| `codex` (direct) | `~/.codex/instructions.md` thin pointer → load AGENTS + runtime reference | +| `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 @@ -178,6 +189,7 @@ The installer pushes thin runtime adapters as regular files (not symlinks): - `~/.claude/settings.json`, `hooks-config.json`, `context7-integration.md` - `~/.config/opencode/AGENTS.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: @@ -185,6 +197,17 @@ Re-sync manually: ~/.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 Attach any repository to the Mosaic standards layer: diff --git a/SOUL.md b/SOUL.md new file mode 100644 index 0000000..e8baddb --- /dev/null +++ b/SOUL.md @@ -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 .` + +## 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. diff --git a/bin/mosaic b/bin/mosaic index f856af5..7e331ab 100755 --- a/bin/mosaic +++ b/bin/mosaic @@ -3,16 +3,19 @@ set -euo pipefail # mosaic — Unified agent launcher and management CLI # -# AGENTS.md is the single source of truth for all agent sessions. -# The launcher injects it into every runtime consistently. +# AGENTS.md is the global policy source for all agent sessions. +# The launcher injects a composed runtime contract (AGENTS + runtime reference). # # Usage: -# mosaic claude [args...] Launch Claude Code with AGENTS.md injected -# mosaic opencode [args...] Launch OpenCode with AGENTS.md injected -# mosaic codex [args...] Launch Codex with AGENTS.md injected +# mosaic claude [args...] Launch Claude Code with runtime contract injected +# mosaic opencode [args...] Launch OpenCode with runtime contract injected +# mosaic codex [args...] Launch Codex with runtime contract injected +# mosaic yolo [args...] Launch runtime in dangerous-permissions mode +# mosaic --yolo [args...] Alias for yolo # mosaic init [args...] Generate SOUL.md interactively # mosaic doctor [args...] Health audit # mosaic sync [args...] Sync skills +# mosaic seq [subcommand] sequential-thinking MCP management (check/fix/start) # mosaic bootstrap Bootstrap a repo # mosaic upgrade release Upgrade installed Mosaic release # mosaic upgrade check Check release upgrade status (no changes) @@ -28,14 +31,20 @@ mosaic $VERSION — Unified agent launcher Usage: mosaic [args...] Agent Launchers: - claude [args...] Launch Claude Code with AGENTS.md injected - opencode [args...] Launch OpenCode with AGENTS.md injected - codex [args...] Launch Codex with AGENTS.md injected + claude [args...] Launch Claude Code with runtime contract injected + opencode [args...] Launch OpenCode with runtime contract injected + codex [args...] Launch Codex with runtime contract injected + yolo [args...] Dangerous mode for claude|codex|opencode + --yolo [args...] Alias for yolo Management: init [args...] Generate SOUL.md (agent identity contract) doctor [args...] Audit runtime state and detect drift sync [args...] Sync skills from canonical source + seq [subcommand] sequential-thinking MCP management: + check [--runtime ] [--strict] + fix [--runtime ] + start bootstrap Bootstrap a repo with Mosaic standards upgrade [mode] [args] Upgrade release (default) or project files upgrade check Check release upgrade status (no changes) @@ -83,14 +92,79 @@ check_runtime() { fi } -# Ensure AGENTS.md is present at the runtime's native config path. -# Used for runtimes that don't support CLI prompt injection. +check_sequential_thinking() { + 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() { - local src="$MOSAIC_HOME/AGENTS.md" - local dst="$1" + local runtime="$1" + local dst="$2" + local tmp + tmp="$(mktemp)" mkdir -p "$(dirname "$dst")" - if ! cmp -s "$src" "$dst" 2>/dev/null; then - cp "$src" "$dst" + build_runtime_prompt "$runtime" > "$tmp" + if ! cmp -s "$tmp" "$dst" 2>/dev/null; then + mv "$tmp" "$dst" + else + rm -f "$tmp" fi } @@ -100,12 +174,13 @@ launch_claude() { check_agents_md check_soul check_runtime "claude" + check_sequential_thinking "claude" # Claude supports --append-system-prompt for direct injection - local agents_content - agents_content="$(cat "$MOSAIC_HOME/AGENTS.md")" + local runtime_prompt + runtime_prompt="$(build_runtime_prompt "claude")" echo "[mosaic] Launching Claude Code..." - exec claude --append-system-prompt "$agents_content" "$@" + exec claude --append-system-prompt "$runtime_prompt" "$@" } launch_opencode() { @@ -113,9 +188,10 @@ launch_opencode() { check_agents_md check_soul check_runtime "opencode" + check_sequential_thinking "opencode" - # OpenCode reads from ~/.config/opencode/AGENTS.md — copy canonical version there - ensure_runtime_config "$HOME/.config/opencode/AGENTS.md" + # OpenCode reads from ~/.config/opencode/AGENTS.md + ensure_runtime_config "opencode" "$HOME/.config/opencode/AGENTS.md" echo "[mosaic] Launching OpenCode..." exec opencode "$@" } @@ -125,13 +201,69 @@ launch_codex() { check_agents_md check_soul check_runtime "codex" + check_sequential_thinking "codex" - # Codex reads from ~/.codex/instructions.md — copy canonical version there - ensure_runtime_config "$HOME/.codex/instructions.md" + # Codex reads from ~/.codex/instructions.md + ensure_runtime_config "codex" "$HOME/.codex/instructions.md" echo "[mosaic] Launching 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 run_init() { check_mosaic_home @@ -148,6 +280,34 @@ run_sync() { 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() { check_mosaic_home exec "$MOSAIC_HOME/bin/mosaic-bootstrap-repo" "$@" @@ -214,9 +374,11 @@ case "$command" in claude) launch_claude "$@" ;; opencode) launch_opencode "$@" ;; codex) launch_codex "$@" ;; + yolo|--yolo) launch_yolo "$@" ;; init) run_init "$@" ;; doctor) run_doctor "$@" ;; sync) run_sync "$@" ;; + seq) run_seq "$@" ;; bootstrap) run_bootstrap "$@" ;; upgrade) run_upgrade "$@" ;; release-upgrade) run_release_upgrade "$@" ;; diff --git a/bin/mosaic-bootstrap-repo b/bin/mosaic-bootstrap-repo index 19cec36..0a10cd3 100755 --- a/bin/mosaic-bootstrap-repo +++ b/bin/mosaic-bootstrap-repo @@ -72,11 +72,15 @@ if [[ ! -f "$TARGET_DIR/AGENTS.md" ]]; then cat > "$TARGET_DIR/AGENTS.md" <<'AGENTS_EOF' # Agent Guidelines -## Standards Load Order +## Required Load Order -1. `~/.config/mosaic/STANDARDS.md` -2. `AGENTS.md` (this file) -3. `.mosaic/repo-hooks.sh` +1. `~/.config/mosaic/SOUL.md` +2. `~/.config/mosaic/STANDARDS.md` +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.md` +7. `.mosaic/repo-hooks.sh` ## Session Lifecycle @@ -95,6 +99,7 @@ bash scripts/agent/session-end.sh - Add project constraints and workflows here. - Implement hook functions in `.mosaic/repo-hooks.sh`. +- Scratchpads are mandatory for non-trivial tasks. AGENTS_EOF echo "[mosaic] Wrote: $TARGET_DIR/AGENTS.md" else diff --git a/bin/mosaic-doctor b/bin/mosaic-doctor index 8c7fd18..aabb80a 100755 --- a/bin/mosaic-doctor +++ b/bin/mosaic-doctor @@ -90,6 +90,39 @@ check_runtime_file_copy() { 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() { local p="$1" [[ -e "$p" ]] || return 0 @@ -122,6 +155,7 @@ expect_dir "$MOSAIC_HOME/templates/agent" expect_dir "$MOSAIC_HOME/skills" expect_dir "$MOSAIC_HOME/skills-local" 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-projects" 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-consume" 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/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). 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 # 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_paths=( diff --git a/bin/mosaic-doctor.ps1 b/bin/mosaic-doctor.ps1 index 844f96c..7fe6fc1 100644 --- a/bin/mosaic-doctor.ps1 +++ b/bin/mosaic-doctor.ps1 @@ -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 { param([string]$Path) 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-local") 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-projects") 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-consume") 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\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 $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") } -# OpenCode runtime adapter -Check-RuntimeFileCopy (Join-Path $MosaicHome "runtime\opencode\AGENTS.md") (Join-Path $env:USERPROFILE ".config\opencode\AGENTS.md") +# OpenCode/Codex runtime contract checks +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 $legacyPaths = @( diff --git a/bin/mosaic-ensure-sequential-thinking b/bin/mosaic-ensure-sequential-thinking new file mode 100755 index 0000000..ef1a6d0 --- /dev/null +++ b/bin/mosaic-ensure-sequential-thinking @@ -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})" diff --git a/bin/mosaic-ensure-sequential-thinking.ps1 b/bin/mosaic-ensure-sequential-thinking.ps1 new file mode 100755 index 0000000..f252184 --- /dev/null +++ b/bin/mosaic-ensure-sequential-thinking.ps1 @@ -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" diff --git a/bin/mosaic-link-runtime-assets b/bin/mosaic-link-runtime-assets index a910a2a..6aa253d 100755 --- a/bin/mosaic-link-runtime-assets +++ b/bin/mosaic-link-runtime-assets @@ -62,7 +62,7 @@ legacy_paths=( "$HOME/.claude/presets/domains" "$HOME/.claude/presets/tech-stacks" "$HOME/.claude/presets/workflows" - "$HOME/.claude/presets/jarvis-ralph.json" + "$HOME/.claude/presets/jarvis-loop.json" ) for p in "${legacy_paths[@]}"; do @@ -93,5 +93,9 @@ if [[ -f "$codex_adapter" ]]; then copy_file_managed "$codex_adapter" "$HOME/.codex/instructions.md" 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] Canonical source: $MOSAIC_HOME" diff --git a/bin/mosaic-link-runtime-assets.ps1 b/bin/mosaic-link-runtime-assets.ps1 index 2c150f5..c83652c 100644 --- a/bin/mosaic-link-runtime-assets.ps1 +++ b/bin/mosaic-link-runtime-assets.ps1 @@ -70,7 +70,7 @@ $legacyPaths = @( (Join-Path $env:USERPROFILE ".claude\presets\domains"), (Join-Path $env:USERPROFILE ".claude\presets\tech-stacks"), (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) { @@ -102,5 +102,10 @@ if (Test-Path $codexSrc) { 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] Canonical source: $MosaicHome" diff --git a/bin/mosaic-sync-skills b/bin/mosaic-sync-skills index 68abc18..0757632 100755 --- a/bin/mosaic-sync-skills +++ b/bin/mosaic-sync-skills @@ -121,6 +121,38 @@ link_skill_into_target() { 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 mkdir -p "$target" @@ -131,6 +163,8 @@ for target in "${link_targets[@]}"; do continue fi + prune_stale_links_in_target "$target" + while IFS= read -r -d '' skill; do link_skill_into_target "$skill" "$target" done < <(find "$MOSAIC_SKILLS_DIR" -mindepth 1 -maxdepth 1 -type d -print0) diff --git a/bin/mosaic.ps1 b/bin/mosaic.ps1 index 943db54..87e9836 100644 --- a/bin/mosaic.ps1 +++ b/bin/mosaic.ps1 @@ -1,12 +1,14 @@ # mosaic.ps1 — Unified agent launcher and management CLI (Windows) # -# AGENTS.md is the single source of truth for all agent sessions. -# The launcher injects it into every runtime consistently. +# AGENTS.md is the global policy source for all agent sessions. +# The launcher injects a composed runtime contract (AGENTS + runtime reference). # # Usage: -# mosaic claude [args...] Launch Claude Code with AGENTS.md injected -# mosaic opencode [args...] Launch OpenCode with AGENTS.md injected -# mosaic codex [args...] Launch Codex with AGENTS.md injected +# mosaic claude [args...] Launch Claude Code with runtime contract injected +# mosaic opencode [args...] Launch OpenCode with runtime contract injected +# mosaic codex [args...] Launch Codex with runtime contract injected +# mosaic yolo [args...] Launch runtime in dangerous-permissions mode +# mosaic --yolo [args...] Alias for yolo # mosaic init [args...] Generate SOUL.md interactively # mosaic doctor [args...] Health audit # mosaic sync [args...] Sync skills @@ -22,9 +24,11 @@ mosaic $Version - Unified agent launcher Usage: mosaic [args...] Agent Launchers: - claude [args...] Launch Claude Code with AGENTS.md injected - opencode [args...] Launch OpenCode with AGENTS.md injected - codex [args...] Launch Codex with AGENTS.md injected + claude [args...] Launch Claude Code with runtime contract injected + opencode [args...] Launch OpenCode with runtime contract injected + codex [args...] Launch Codex with runtime contract injected + yolo [args...] Dangerous mode for claude|codex|opencode + --yolo [args...] Alias for yolo Management: 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 { - param([string]$Dst) - $src = Join-Path $MosaicHome "AGENTS.md" + param( + [ValidateSet("claude", "codex", "opencode")] + [string]$Runtime, + [string]$Dst + ) + $parent = Split-Path $Dst -Parent 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 { "" } 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-Soul Assert-Runtime "claude" + Assert-SequentialThinking # 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..." & claude --append-system-prompt $agentsContent @remaining } @@ -112,8 +238,9 @@ switch ($command) { Assert-AgentsMd Assert-Soul Assert-Runtime "opencode" + Assert-SequentialThinking # 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..." & opencode @remaining } @@ -122,11 +249,18 @@ switch ($command) { Assert-AgentsMd Assert-Soul Assert-Runtime "codex" + Assert-SequentialThinking # 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..." & codex @remaining } + "yolo" { + Invoke-Yolo -YoloArgs $remaining + } + "--yolo" { + Invoke-Yolo -YoloArgs $remaining + } "init" { Assert-MosaicHome & (Join-Path $MosaicHome "bin\mosaic-init.ps1") @remaining diff --git a/guides/authentication.md b/guides/AUTHENTICATION.md similarity index 100% rename from guides/authentication.md rename to guides/AUTHENTICATION.md diff --git a/guides/backend.md b/guides/BACKEND.md similarity index 89% rename from guides/backend.md rename to guides/BACKEND.md index 6931282..8099008 100644 --- a/guides/backend.md +++ b/guides/BACKEND.md @@ -47,7 +47,7 @@ - Use project's established auth pattern - Validate tokens on every request - Check permissions before operations -- See `~/.config/mosaic/guides/authentication.md` for details +- See `~/.config/mosaic/guides/AUTHENTICATION.md` for details ## Testing Requirements (TDD) 1. Write tests BEFORE implementation @@ -73,18 +73,19 @@ class TestResourceEndpoint: ## Code Style - 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 - Keep functions focused and small - Document complex business logic -### TypeScript Quick Rules (see typescript.md for full guide) -- **NO `any`** — define explicit types always -- **NO lazy `unknown`** — only for error catches and external data with validation -- **Explicit return types** on all exported functions -- **Explicit parameter types** always -- **Interface for DTOs** — never inline object types -- **Typed errors** — use custom error classes +### TypeScript Quick Rules (see TYPESCRIPT.md for full guide) +- **NO `any`** — define explicit types always +- **NO lazy `unknown`** — only for error catches and external data with validation +- **Explicit return types** on all exported functions +- **Explicit parameter types** always +- **DTO files are REQUIRED** for module/API boundaries (`*.dto.ts`) +- **Interface for DTOs** — never inline object types +- **Typed errors** — use custom error classes ## Performance - Use database connection pooling diff --git a/guides/BOOTSTRAP.md b/guides/BOOTSTRAP.md new file mode 100755 index 0000000..478fda7 --- /dev/null +++ b/guides/BOOTSTRAP.md @@ -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/`) diff --git a/guides/code-review.md b/guides/CODE-REVIEW.md old mode 100644 new mode 100755 similarity index 58% rename from guides/code-review.md rename to guides/CODE-REVIEW.md index aa2e95c..e96679a --- a/guides/code-review.md +++ b/guides/CODE-REVIEW.md @@ -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 -- [ ] Code does what the issue/PR description says -- [ ] Edge cases are handled -- [ ] Error conditions are managed properly -- [ ] No obvious bugs or logic errors +### 2. Security +- [ ] No hardcoded secrets or credentials +- [ ] Input validation at boundaries +- [ ] SQL injection prevention (parameterized queries) +- [ ] 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 -- [ ] No hardcoded secrets or credentials -- [ ] Input validation at boundaries -- [ ] SQL injection prevention (parameterized queries) -- [ ] XSS prevention (output encoding) -- [ ] Authentication/authorization checks present -- [ ] Sensitive data not logged -- [ ] Secrets follow Vault structure (see `docs/vault-secrets-structure.md`) - -### 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 +### 3. Testing +- [ ] Tests exist for new functionality +- [ ] Tests cover happy path AND error cases +- [ ] Situational tests cover all impacted change surfaces (primary gate) +- [ ] Tests validate required behavior/outcomes, not only internal implementation details +- [ ] TDD was applied when required by `~/.config/mosaic/guides/QA-TESTING.md` +- [ ] Coverage meets 85% minimum +- [ ] Tests are readable and maintainable +- [ ] No flaky tests introduced ### 4. Code Quality - [ ] Follows Google Style Guide for the language @@ -32,21 +61,27 @@ - [ ] Clear naming for variables and functions - [ ] No dead code or commented-out code -### 4a. TypeScript Strict Typing (see `typescript.md`) -- [ ] **NO `any` types** — explicit types required everywhere -- [ ] **NO lazy `unknown`** — only for error catches with immediate narrowing -- [ ] **Explicit return types** on all exported/public functions -- [ ] **Explicit parameter types** — never implicit any -- [ ] **No type assertions** (`as Type`) — use type guards instead -- [ ] **No non-null assertions** (`!`) — use proper null handling -- [ ] **Interfaces for objects** — not inline types -- [ ] **Discriminated unions** for variant types +### 4a. TypeScript Strict Typing (see `TYPESCRIPT.md`) +- [ ] **NO `any` types** — explicit types required everywhere +- [ ] **NO lazy `unknown`** — only for error catches with immediate narrowing +- [ ] **Explicit return types** on all exported/public functions +- [ ] **Explicit parameter types** — never implicit any +- [ ] **No type assertions** (`as Type`) — use type guards instead +- [ ] **No non-null assertions** (`!`) — use proper null handling +- [ ] **Interfaces for objects** — not inline types +- [ ] **Discriminated unions** for variant types +- [ ] **DTO files used at boundaries** — module/API contracts are in `*.dto.ts`, not inline payload types -### 5. Documentation -- [ ] Complex logic has explanatory comments -- [ ] Public APIs are documented -- [ ] README updated if needed -- [ ] Breaking changes noted +### 5. Documentation +- [ ] Complex logic has explanatory comments +- [ ] Required docs updated per `~/.config/mosaic/guides/DOCUMENTATION.md` +- [ ] Public APIs are documented +- [ ] 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 - [ ] No obvious N+1 queries @@ -59,7 +94,9 @@ - [ ] No unnecessary new dependencies - [ ] 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 ```bash @@ -94,8 +131,9 @@ Use parameterized queries instead: This pattern appears in 3 places. A shared helper would reduce duplication. ``` -## After Review -1. Update issue with review status -2. If changes requested, assign back to author -3. If approved, note approval in issue comments -4. For merges, ensure CI passes first +## After Review +1. Update issue with review status +2. If changes requested, assign back to author +3. If approved, note approval in issue comments +4. For merges, ensure CI passes first +5. Merge PR to `main` with squash strategy only diff --git a/guides/DOCUMENTATION.md b/guides/DOCUMENTATION.md new file mode 100644 index 0000000..252f5cd --- /dev/null +++ b/guides/DOCUMENTATION.md @@ -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//` | +| 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. diff --git a/guides/frontend.md b/guides/FRONTEND.md similarity index 92% rename from guides/frontend.md rename to guides/FRONTEND.md index 509330c..a0eb6c3 100644 --- a/guides/frontend.md +++ b/guides/FRONTEND.md @@ -49,12 +49,12 @@ describe('ComponentName', () => { ## Code Style - 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 - Prefer functional components over class components (React) - 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 lazy `unknown`** — only for error catches and external data with validation - **Explicit return types** on all exported functions diff --git a/guides/infrastructure.md b/guides/INFRASTRUCTURE.md similarity index 58% rename from guides/infrastructure.md rename to guides/INFRASTRUCTURE.md index 45f68ec..0f1439b 100644 --- a/guides/infrastructure.md +++ b/guides/INFRASTRUCTURE.md @@ -97,10 +97,10 @@ readinessProbe: periodSeconds: 3 ``` -## CI/CD Pipelines - -### Pipeline Stages -1. **Lint**: Code style and static analysis +## CI/CD Pipelines + +### Pipeline Stages +1. **Lint**: Code style and static analysis 2. **Test**: Unit and integration tests 3. **Build**: Compile and package 4. **Scan**: Security and vulnerability scanning @@ -109,10 +109,65 @@ readinessProbe: ### Pipeline Security - Use secrets management (not hardcoded) - Pin action/image versions -- Implement approval gates for production -- Audit pipeline access - -## Monitoring & Logging +- Implement approval gates for production +- Audit pipeline access + +## 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-` 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 - Use structured logging (JSON) diff --git a/guides/MEMORY.md b/guides/MEMORY.md new file mode 100644 index 0000000..40541f5 --- /dev/null +++ b/guides/MEMORY.md @@ -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/.md` | Task-specific working memory and verification evidence | Project `docs/scratchpads/` | +| `AGENTS.md` | Reusable local patterns and gotchas | Any working directory | diff --git a/guides/orchestrator-learnings.md b/guides/ORCHESTRATOR-LEARNINGS.md similarity index 93% rename from guides/orchestrator-learnings.md rename to guides/ORCHESTRATOR-LEARNINGS.md index 24974b5..c1b0ca3 100644 --- a/guides/orchestrator-learnings.md +++ b/guides/ORCHESTRATOR-LEARNINGS.md @@ -2,11 +2,11 @@ > 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 -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 | |-----------|---------------|------------|------------|---------|--------------| @@ -37,7 +37,7 @@ Apply to all estimates based on task position in milestone: Final Estimate = Base Estimate × Type Multiplier × Phase Factor × TDD Overhead 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) - Phase Factor: 1.45 / 1.25 / 1.10 based on position - TDD Overhead: 1.20 if tests required @@ -122,5 +122,5 @@ Where: ## Where to Find Project-Specific Data -- **Project learnings:** `/docs/orchestrator-learnings.json` +- **Project learnings:** `/docs/tasks/orchestrator-learnings.json` - **Cross-project metrics:** `jarvis-brain/data/orchestrator-metrics.json` diff --git a/guides/PRD.md b/guides/PRD.md new file mode 100644 index 0000000..bf3540b --- /dev/null +++ b/guides/PRD.md @@ -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. diff --git a/guides/QA-TESTING.md b/guides/QA-TESTING.md new file mode 100644 index 0000000..ffeaf8e --- /dev/null +++ b/guides/QA-TESTING.md @@ -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. diff --git a/guides/typescript.md b/guides/TYPESCRIPT.md similarity index 87% rename from guides/typescript.md rename to guides/TYPESCRIPT.md index 7fcc27e..9c019c2 100644 --- a/guides/typescript.md +++ b/guides/TYPESCRIPT.md @@ -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 2. **Specific over generic** — Use the narrowest type that works 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 { } + +// ✅ 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 { } +``` --- diff --git a/guides/vault-secrets.md b/guides/VAULT-SECRETS.md similarity index 100% rename from guides/vault-secrets.md rename to guides/VAULT-SECRETS.md diff --git a/guides/bootstrap.md b/guides/bootstrap.md deleted file mode 100644 index e109020..0000000 --- a/guides/bootstrap.md +++ /dev/null @@ -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/`) diff --git a/guides/ci-cd-pipelines.md b/guides/ci-cd-pipelines.md index ac46043..27f9c0a 100644 --- a/guides/ci-cd-pipelines.md +++ b/guides/ci-cd-pipelines.md @@ -12,7 +12,7 @@ GIT PUSH QUALITY GATES (lint, typecheck, test, audit) ↓ all pass BUILD (compile all packages) - ↓ only on main/develop/tags + ↓ only on main/tags DOCKER BUILD & PUSH (Kaniko → Gitea Container Registry) ↓ all images pushed PACKAGE LINKING (associate images with repository in Gitea) @@ -123,10 +123,10 @@ when: # Top-level: run quality gates on everything - 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: when: - - branch: [main, develop] + - branch: [main] event: [push, manual, tag] ``` @@ -150,24 +150,29 @@ docker-build-SERVICE: from_secret: gitea_username GITEA_TOKEN: from_secret: gitea_token + RELEASE_BASE_VERSION: ${RELEASE_BASE_VERSION} CI_COMMIT_BRANCH: ${CI_COMMIT_BRANCH} CI_COMMIT_TAG: ${CI_COMMIT_TAG} CI_COMMIT_SHA: ${CI_COMMIT_SHA} + CI_PIPELINE_NUMBER: ${CI_PIPELINE_NUMBER} commands: - *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 - DESTINATIONS="$DESTINATIONS --destination REGISTRY/ORG/IMAGE_NAME:latest" - elif [ "$CI_COMMIT_BRANCH" = "develop" ]; then - DESTINATIONS="$DESTINATIONS --destination REGISTRY/ORG/IMAGE_NAME:dev" + DESTINATIONS="$DESTINATIONS --destination REGISTRY/ORG/IMAGE_NAME:v${BASE_VERSION}-rc.${BUILD_ID}" + DESTINATIONS="$DESTINATIONS --destination REGISTRY/ORG/IMAGE_NAME:testing" fi if [ -n "$CI_COMMIT_TAG" ]; then DESTINATIONS="$DESTINATIONS --destination REGISTRY/ORG/IMAGE_NAME:$CI_COMMIT_TAG" fi /kaniko/executor --context . --dockerfile PATH/TO/Dockerfile $DESTINATIONS when: - - branch: [main, develop] + - branch: [main] event: [push, manual, tag] depends_on: - build @@ -184,15 +189,69 @@ docker-build-SERVICE: ### 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 | |-----------|-----|---------| -| Always | `${CI_COMMIT_SHA:0:8}` | Immutable reference to exact commit | -| `main` branch | `latest` | Current production release | -| `develop` branch | `dev` | Current development build | +| Always | `sha-${CI_COMMIT_SHA:0:8}` | Immutable reference to exact commit | +| `main` branch | `v{BASE_VERSION}-rc.{BUILD_ID}` | Intermediate release candidate for the active milestone | | 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 Common flags for `/kaniko/executor`: @@ -252,7 +311,10 @@ In `docker-compose.yml`: ```yaml services: 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 @@ -315,7 +377,7 @@ link-packages: link_package "image-name-1" link_package "image-name-2" when: - - branch: [main, develop] + - branch: [main] event: [push, manual, tag] depends_on: - 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_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 ```bash @@ -554,9 +622,9 @@ security-trivy: mkdir -p ~/.docker echo "{\"auths\":{\"REGISTRY\":{\"username\":\"$$GITEA_USER\",\"password\":\"$$GITEA_TOKEN\"}}}" > ~/.docker/config.json 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: - - branch: [main, develop] + - branch: [main] event: [push, manual, tag] depends_on: - docker-build-SERVICE @@ -574,7 +642,7 @@ Docker build MUST depend on ALL quality + security steps. Trivy runs AFTER build ## Monorepo Considerations -### pnpm + Turbo (Mosaic Stack pattern) +### pnpm + Turbo ```yaml variables: @@ -589,7 +657,7 @@ steps: - pnpm build # Turbo handles dependency order and caching ``` -### npm Workspaces (U-Connect pattern) +### npm Workspaces ```yaml variables: @@ -684,24 +752,28 @@ steps: from_secret: gitea_username GITEA_TOKEN: from_secret: gitea_token + RELEASE_BASE_VERSION: ${RELEASE_BASE_VERSION} CI_COMMIT_BRANCH: ${CI_COMMIT_BRANCH} CI_COMMIT_TAG: ${CI_COMMIT_TAG} CI_COMMIT_SHA: ${CI_COMMIT_SHA} + CI_PIPELINE_NUMBER: ${CI_PIPELINE_NUMBER} commands: - *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 - DESTINATIONS="$DESTINATIONS --destination git.example.com/org/api:latest" - elif [ "$CI_COMMIT_BRANCH" = "develop" ]; then - DESTINATIONS="$DESTINATIONS --destination git.example.com/org/api:dev" + DESTINATIONS="$DESTINATIONS --destination git.example.com/org/api:v${BASE_VERSION}-rc.${BUILD_ID}" + DESTINATIONS="$DESTINATIONS --destination git.example.com/org/api:testing" fi if [ -n "$CI_COMMIT_TAG" ]; then DESTINATIONS="$DESTINATIONS --destination git.example.com/org/api:$CI_COMMIT_TAG" fi /kaniko/executor --context . --dockerfile src/api/Dockerfile $DESTINATIONS when: - - branch: [main, develop] + - branch: [main] event: [push, manual, tag] depends_on: [build] @@ -712,24 +784,28 @@ steps: from_secret: gitea_username GITEA_TOKEN: from_secret: gitea_token + RELEASE_BASE_VERSION: ${RELEASE_BASE_VERSION} CI_COMMIT_BRANCH: ${CI_COMMIT_BRANCH} CI_COMMIT_TAG: ${CI_COMMIT_TAG} CI_COMMIT_SHA: ${CI_COMMIT_SHA} + CI_PIPELINE_NUMBER: ${CI_PIPELINE_NUMBER} commands: - *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 - DESTINATIONS="$DESTINATIONS --destination git.example.com/org/web:latest" - elif [ "$CI_COMMIT_BRANCH" = "develop" ]; then - DESTINATIONS="$DESTINATIONS --destination git.example.com/org/web:dev" + DESTINATIONS="$DESTINATIONS --destination git.example.com/org/web:v${BASE_VERSION}-rc.${BUILD_ID}" + DESTINATIONS="$DESTINATIONS --destination git.example.com/org/web:testing" fi if [ -n "$CI_COMMIT_TAG" ]; then DESTINATIONS="$DESTINATIONS --destination git.example.com/org/web:$CI_COMMIT_TAG" fi /kaniko/executor --context . --dockerfile src/web/Dockerfile $DESTINATIONS when: - - branch: [main, develop] + - branch: [main] event: [push, manual, tag] depends_on: [build] @@ -763,8 +839,8 @@ steps: } link_package "api" link_package "web" - when: - - branch: [main, develop] + when: + - branch: [main] event: [push, manual, tag] depends_on: - docker-build-api @@ -780,49 +856,130 @@ steps: 5. **Add package linking step** after all Docker builds 6. **Update `docker-compose.yml`** to reference registry images instead of local builds: ```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 +## 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 + ``` +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 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 | |---------|---------------------|-------------| | **Git hosting** | GitHub/GitLab | `https://GITEA_HOST/org/repo` | | **Container registry** | Harbor, Docker Hub | `docker pull GITEA_HOST/org/image:tag` | | **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 - -Gitea also supports PyPI, Maven, NuGet, Cargo, Composer, Conan, Conda, Generic, and more. All use the same token authentication. - -### Single Token, Three Services +### Single Token, Multiple Services A Gitea token with `package:write` scope handles: - `git push` / `git pull` - `docker push` / `docker pull` (container 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 -**Before (3 services):** +**Before (4 services):** ``` -Gitea (git) + Harbor (containers) + Verdaccio (npm) - ↓ separate auth ↓ separate auth ↓ OAuth/Authentik - 3 tokens 1 robot account 1 OIDC integration - 3 backup targets complex RBAC group-based access +Gitea (git) + Harbor (containers) + Verdaccio (npm) + Private PyPI + ↓ separate auth ↓ separate auth ↓ extra auth ↓ extra auth + multiple tokens robot/service users npm-specific token pip/twine token + fragmented access fragmented RBAC fragmented RBAC fragmented RBAC ``` **After (1 service):** ``` -Gitea (git + containers + npm) - ↓ single token - 1 secret in Woodpecker +Gitea (git + containers + npm + pypi) + ↓ unified secrets + 1 credentials model in CI 1 backup target 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 ### 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 diff --git a/guides/e2e-delivery.md b/guides/e2e-delivery.md new file mode 100644 index 0000000..f494b1d --- /dev/null +++ b/guides/e2e-delivery.md @@ -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 -m squash` +3. `~/.config/mosaic/rails/git/pr-ci-wait.sh -n ` +4. `~/.config/mosaic/rails/git/issue-close.sh -i ` (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) diff --git a/guides/orchestrator.md b/guides/orchestrator.md index 93d7c6e..d93849d 100644 --- a/guides/orchestrator.md +++ b/guides/orchestrator.md @@ -1,18 +1,47 @@ # 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 -The orchestrator **cold-starts** on any project with just a review report location and minimal kickstart. It autonomously: -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 +## Session Start Handshake (Hard Rule) -**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 **The orchestrator ONLY:** -- Reads/writes `docs/tasks.md` -- Reads/writes `docs/orchestrator-learnings.json` +- Reads/writes `docs/TASKS.md` +- Reads/writes `docs/tasks/orchestrator-learnings.json` - Delegates ALL code changes to workers (native subagent tool when available, otherwise Mosaic matrix rail) - Parses worker JSON results - Commits task tracking updates (tasks.md, learnings) @@ -56,7 +85,7 @@ Matrix rail mode commands: ~/.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. --- @@ -68,7 +97,7 @@ Use templates from `jarvis-brain/docs/templates/` to scaffold tracking files: ```bash # Set environment variables export PROJECT="project-name" -export MILESTONE="M1-Feature" +export MILESTONE="0.0.1" export CURRENT_DATETIME=$(date -Iseconds) export TASK_PREFIX="PR-SEC" export PHASE_ISSUE="#1" @@ -77,23 +106,41 @@ export PHASE_BRANCH="fix/security" # Copy templates TEMPLATES=~/src/jarvis-brain/docs/templates -# Create tasks.md (then populate with findings) -envsubst < $TEMPLATES/orchestrator/tasks.md.template > docs/tasks.md +# Create PRD if missing (before coding begins) +[[ -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 -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) $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:** | Template | Purpose | |----------|---------| | `orchestrator/tasks.md.template` | Task tracking table with schema | | `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 | | `reports/review-report-scaffold.sh` | Creates report directory | | `scratchpad.md.template` | Per-task working document | @@ -104,6 +151,16 @@ See `jarvis-brain/docs/templates/README.md` for full documentation. ## 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 Review reports typically follow this structure: @@ -169,6 +226,24 @@ Use these heuristics based on task type: - Test requirements (+5-10K if tests 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 **Automatic dependency rules:** @@ -183,9 +258,18 @@ Use these heuristics based on task type: - `{PREFIX}-CQ-{LAST}`: Phase 3 verification - `{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 ~/.config/mosaic/rails/git/issue-create.sh \ @@ -201,6 +285,7 @@ Create ONE issue per phase using git scripts: - [ ] All critical findings remediated - [ ] Quality gates passing +- [ ] Required documentation updates complete - [ ] No new regressions EOF )" \ @@ -208,18 +293,44 @@ EOF -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: ```markdown # Tasks -| id | status | description | issue | repo | branch | depends_on | blocks | agent | started_at | completed_at | estimate | used | -|---|---|---|---|---|---|---|---|---|---|---|---|---| -| {PREFIX}-SEC-001 | not-started | SEC-API-1: Brief description | #{N} | api | fix/security | | {PREFIX}-SEC-002 | | | | 8K | | +| 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 | | | ``` **Column definitions:** @@ -227,9 +338,9 @@ Create the file with this exact schema: | Column | Format | Purpose | |--------|--------|---------| | `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 | -| `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. | | `branch` | Branch name | `fix/security`, `fix/code-quality`, etc. | | `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 | | `estimate` | `5K`, `15K`, etc. | Predicted token usage | | `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:** - `SEC` — Security (Phase 1-2) @@ -246,11 +361,21 @@ Create the file with this exact schema: - `CQ` — Code quality (Phase 3) - `TEST` — Test coverage (Phase 4) - `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 ```bash -git add docs/tasks.md +git add docs/TASKS.md git commit -m "chore(orchestrator): Bootstrap tasks.md from review report Parsed {N} findings into {M} tasks across {P} phases. @@ -264,34 +389,61 @@ git push ``` 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 4. If no task available: - All done? → Report success, run final retrospective, STOP - Some blocked? → Report deadlock, STOP 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 - matrix mode: enqueue/consume task in `.mosaic/orchestrator/tasks.json` and run `mosaic-orchestrator-matrix-cycle` -7. Wait for worker completion -8. Parse worker result (JSON) -9. **Variance check**: Calculate (actual - estimate) / estimate × 100 +8. Wait for worker completion +9. Parse worker result (JSON) +10. **Variance check**: Calculate (actual - estimate) / estimate × 100 - If |variance| > 50%: Capture learning (see Learning & Retrospective) - If |variance| > 100%: Flag as CRITICAL — review task classification -10. **Post-Coding Review** (see Phase 2b below) -11. Update tasks.md: status=done/failed/needs-qa, completed_at={now}, used={actual} -12. **Cleanup reports**: Remove processed report files for completed task +11. **Post-Coding Review** (see Phase 2b below) +12. **Documentation Gate**: Verify required docs were updated per `~/.config/mosaic/guides/DOCUMENTATION.md` + 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 # Find and remove reports matching the finding ID find docs/reports/qa-automation/pending/ -name "*{finding_id}*" -delete 2>/dev/null || true # If task failed, move reports to escalated/ instead ``` -13. 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 -15. Check context usage -16. If >= 55%: Output COMPACTION REQUIRED checkpoint, STOP, wait for user -17. If < 55%: Go to step 1 -18. After user runs /compact and says "continue": Go to step 1 +17. Commit + push: git add docs/TASKS.md .gitignore && git commit && git push +18. If phase verification task: Run phase retrospective, clean up all phase reports +19. Check context usage +20. If >= 55%: Output COMPACTION REQUIRED checkpoint, STOP, wait for user +21. Check budget usage: + - 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) - Testing (coverage, quality) - Code quality (complexity, duplication) -3. Reference: ~/.config/mosaic/guides/code-review.md +3. Reference: ~/.config/mosaic/guides/CODE-REVIEW.md Report findings as JSON: ```json @@ -432,26 +584,34 @@ Construct this from the task row and pass to worker via Task tool: ## Workflow -1. Checkout branch: `git checkout {branch} || git checkout -b {branch} develop && git pull` -2. Read the finding details from the report -3. Implement the fix following existing code patterns -4. Run quality gates (ALL must pass — zero lint errors, zero type errors, all tests green): +1. Checkout branch: `git fetch origin && (git checkout {branch} || git checkout -b {branch} origin/main) && git rebase origin/main` +2. Read `docs/PRD.md` or `docs/PRD.json` and align implementation with PRD requirements +3. Read the finding details from the report +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 {quality_gates_command} ``` **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. 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. Commit: `git commit -m "fix({finding_id}): brief description"` -7. Push: `git push origin {branch}` -8. Report result as JSON (see format below) +6. Run REQUIRED situational tests based on changed surfaces (see `~/.config/mosaic/guides/E2E-DELIVERY.md` and `~/.config/mosaic/guides/QA-TESTING.md`). +7. If task is bug fix/security/auth/critical business logic, apply REQUIRED TDD discipline per `~/.config/mosaic/guides/QA-TESTING.md`. +8. If gates or required situational tests fail: Fix and retry. Do NOT report success with failures. +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 For issue/PR/milestone operations, use scripts (NOT raw tea/gh): - `~/.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. @@ -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 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 -- DO NOT modify docs/tasks.md +- DO NOT modify docs/TASKS.md - DO NOT claim other tasks - 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 - Post-compaction agents may violate core rules (e.g., letting workers modify tasks.md) - 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%):** 1. Complete current task 2. Persist all state: - - Update docs/tasks.md with all progress - - Update docs/orchestrator-learnings.json with variances + - Update docs/TASKS.md with all progress + - Update docs/tasks/orchestrator-learnings.json with variances - Commit and push both files 3. Output **ORCHESTRATOR HANDOFF** message with ready-to-use takeover kickstart 4. **STOP COMPLETELY** — do not continue working @@ -517,8 +680,8 @@ Progress: {completed}/{total} tasks ({percentage}%) Current phase: Phase {N} ({phase_name}) State persisted: -- docs/tasks.md ✓ -- docs/orchestrator-learnings.json ✓ +- docs/TASKS.md ✓ +- docs/tasks/orchestrator-learnings.json ✓ ## Takeover Kickstart @@ -531,8 +694,8 @@ Continue {mission_description} from existing state. ## Setup - Project: {project_path} -- State: docs/tasks.md (already populated) -- Protocol: docs/claude/orchestrator.md +- State: docs/TASKS.md (already populated) +- Protocol: ~/.config/mosaic/guides/ORCHESTRATOR.md - Quality gates: {quality_gates_command} ## Resume Point @@ -541,11 +704,11 @@ Continue {mission_description} from existing state. - Progress: {completed}/{total} tasks ({percentage}%) ## Instructions -1. Read docs/claude/orchestrator.md for protocol -2. Read docs/tasks.md to understand current state +1. Read ~/.config/mosaic/guides/ORCHESTRATOR.md for protocol +2. Read docs/TASKS.md to understand current state 3. Continue execution from task {task_id} 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. @@ -583,7 +746,7 @@ Each major phase uses a two-phase approach to maximize completion while managing | Architectural | Requires design change | Document and defer | 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 ## {PREFIX}-XXX: [Error description] - 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 - 40 medium → fixed - 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 ❌ 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) | | 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 | ### Task Type Classification @@ -662,7 +825,7 @@ Classify tasks by description keywords for pattern analysis: ### Capture Learning -When |variance| > 50%, append to `docs/orchestrator-learnings.json`: +When |variance| > 50%, append to `docs/tasks/orchestrator-learnings.json`: ```json { @@ -708,7 +871,7 @@ Next: MS-SEC-004 ### 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. --- @@ -736,7 +899,7 @@ docs/reports/qa-automation/ | Task success | Delete matching reports from `pending/` | | Task failed | Move reports to `escalated/` for investigation | | 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:** ```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 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:** 1. `git pull --rebase` 2. If auto-resolves: push again @@ -776,54 +944,151 @@ mv docs/reports/qa-automation/pending/*failing-file* docs/reports/qa-automation/ ## Stopping Criteria **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) 3. Context usage >= 55% — output COMPACTION REQUIRED checkpoint and wait 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 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-` (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 - 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 - 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` -3. **Move learnings to archive:** +7. **Commit archive + release references**: ```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:** - ```bash - git add 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." + - Tagged: v{milestone-version} + - Release published + - Artifacts archived to docs/tasks/" 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 -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 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: 1. Report what it found in `docs/tasks/` 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 @@ -860,7 +1125,7 @@ Remediate findings from the codebase review. - Task prefix: {PREFIX} (e.g., MS, UC) ## Protocol -Read ~/.config/mosaic/guides/orchestrator.md for full instructions. +Read ~/.config/mosaic/guides/ORCHESTRATOR.md for full instructions. ## Start Bootstrap from the review report, then execute until complete. diff --git a/guides/qa-testing.md b/guides/qa-testing.md deleted file mode 100644 index 4b230f0..0000000 --- a/guides/qa-testing.md +++ /dev/null @@ -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 diff --git a/install.ps1 b/install.ps1 index d8423df..063e1a2 100644 --- a/install.ps1 +++ b/install.ps1 @@ -143,6 +143,21 @@ catch { 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") { Write-Ok "Skills sync skipped (MOSAIC_SKIP_SKILLS_SYNC=1)" } diff --git a/install.sh b/install.sh index 3fd4a37..44340f9 100755 --- a/install.sh +++ b/install.sh @@ -151,6 +151,18 @@ else warn "Runtime asset linking failed (non-fatal)" 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 ok "Skills sync skipped (MOSAIC_SKIP_SKILLS_SYNC=1)" else diff --git a/profiles/README.md b/profiles/README.md index 5c43691..632e0c9 100644 --- a/profiles/README.md +++ b/profiles/README.md @@ -15,7 +15,7 @@ Profiles are runtime-neutral context packs that can be consumed by any agent run Current runtime overlay example: -- `~/.config/mosaic/runtime/claude/settings-overlays/jarvis-ralph.json` +- `~/.config/mosaic/runtime/claude/settings-overlays/jarvis-loop.json` ## Claude Compatibility diff --git a/rails/bootstrap/agent-lint.sh b/rails/bootstrap/agent-lint.sh index 6e08ab3..d2947f0 100755 --- a/rails/bootstrap/agent-lint.sh +++ b/rails/bootstrap/agent-lint.sh @@ -9,10 +9,10 @@ # agent-lint.sh --fix-hint # Show fix commands for failures # # Checks per project: -# 1. Has CLAUDE.md? +# 1. Has runtime context file (CLAUDE.md or RUNTIME.md)? # 2. Has AGENTS.md? -# 3. CLAUDE.md references conditional context/guides? -# 4. CLAUDE.md has quality gates? +# 3. Runtime context file references conditional context/guides? +# 4. Runtime context file has quality gates? # 5. For monorepos: sub-directories have AGENTS.md? set -euo pipefail @@ -92,9 +92,23 @@ is_monorepo() { (grep -q '"workspaces"' "$dir/package.json" 2>/dev/null) } -# Check for CLAUDE.md -check_claude_md() { - [[ -f "$1/CLAUDE.md" ]] +# Resolve runtime context file (CLAUDE.md or RUNTIME.md) +runtime_context_file() { + 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 @@ -104,14 +118,16 @@ check_agents_md() { # Check conditional loading/context (references guides or conditional section) check_conditional_loading() { - local claude_md="$1/CLAUDE.md" - [[ -f "$claude_md" ]] && grep -qi "agent-guides\|~/.config/mosaic/guides\|conditional.*loading\|conditional.*documentation\|conditional.*context" "$claude_md" 2>/dev/null + local ctx + 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() { - local claude_md="$1/CLAUDE.md" - [[ -f "$claude_md" ]] && grep -qi "quality.gates\|must pass before\|lint\|typecheck\|test" "$claude_md" 2>/dev/null + local ctx + 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 @@ -152,16 +168,16 @@ lint_project() { local name 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 - 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_conditional_loading "$dir" && has_guides="OK" || has_guides="MISS" check_quality_gates "$dir" && has_quality="OK" || has_quality="MISS" mono_status=$(check_monorepo_sub_agents "$dir") - [[ "$has_claude" == "OK" ]] && ((score++)) || true + [[ "$has_runtime" == "OK" ]] && ((score++)) || true [[ "$has_agents" == "OK" ]] && ((score++)) || true [[ "$has_guides" == "OK" ]] && ((score++)) || true [[ "$has_quality" == "OK" ]] && ((score++)) || true @@ -171,7 +187,7 @@ lint_project() { { "project": "$name", "path": "$dir", - "claude_md": "$has_claude", + "runtime_context": "$has_runtime", "agents_md": "$has_agents", "conditional_loading": "$has_guides", "quality_gates": "$has_quality", @@ -182,8 +198,8 @@ lint_project() { JSONEOF else # Color-code the status - local c_claude c_agents c_guides c_quality - [[ "$has_claude" == "OK" ]] && c_claude="${GREEN} OK ${NC}" || c_claude="${RED} MISS ${NC}" + local c_runtime c_agents c_guides c_quality + [[ "$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_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}" @@ -193,7 +209,7 @@ JSONEOF [[ $score -eq 4 ]] && score_color="$GREEN" 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 if [[ "$mono_status" != "N/A" && "$mono_status" != "OK" ]]; then @@ -203,7 +219,7 @@ JSONEOF fi 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_guides" == "MISS" ]] && echo " ${DIM} No conditional context/loading section detected${NC}" [[ "$has_quality" == "MISS" ]] && echo " ${DIM} No quality gates section${NC}" @@ -213,7 +229,7 @@ JSONEOF fi 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}" elif [[ "$has_guides" == "MISS" ]]; then 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 "========================================================" printf " %-35s %s %s %s %s %s\n" \ - "Project" "CLAUDE" "AGENTS" "Guides" "Quality" "Score" + "Project" "RUNTIME" "AGENTS" "Guides" "Quality" "Score" echo " -----------------------------------------------------------------------" for dir in "${projects[@]}"; do diff --git a/rails/bootstrap/agent-upgrade.sh b/rails/bootstrap/agent-upgrade.sh index 6c30acb..09f4ba1 100755 --- a/rails/bootstrap/agent-upgrade.sh +++ b/rails/bootstrap/agent-upgrade.sh @@ -113,6 +113,19 @@ has_section() { [[ -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() { local file="$1" if [[ -f "$file" ]] && ! $DRY_RUN; then @@ -124,7 +137,8 @@ backup_file() { inject_fragment() { local project_dir="$1" 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" if [[ ! -f "$fragment_file" ]]; then @@ -144,12 +158,12 @@ inject_fragment() { *) echo "Unknown fragment: $fragment_name"; return 1 ;; esac - if [[ ! -f "$claude_md" ]]; then - echo -e " ${YELLOW}No CLAUDE.md — skipping fragment injection${NC}" + if [[ ! -f "$ctx_file" ]]; then + echo -e " ${YELLOW}No runtime context file (CLAUDE.md/RUNTIME.md) — skipping fragment injection${NC}" return 0 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}" return 0 fi @@ -157,10 +171,10 @@ inject_fragment() { if $DRY_RUN; then echo -e " ${GREEN}Would inject: $fragment_name${NC}" else - backup_file "$claude_md" - echo "" >> "$claude_md" - cat "$fragment_file" >> "$claude_md" - echo "" >> "$claude_md" + backup_file "$ctx_file" + echo "" >> "$ctx_file" + cat "$fragment_file" >> "$ctx_file" + echo "" >> "$ctx_file" echo -e " ${GREEN}Injected: $fragment_name${NC}" fi } @@ -257,8 +271,8 @@ upgrade_project() { # Always try conditional-loading (highest impact) inject_fragment "$dir" "conditional-loading" - # Try other fragments if CLAUDE.md exists - if [[ -f "$dir/CLAUDE.md" ]]; then + # Try other fragments if runtime context exists + if [[ -f "$dir/CLAUDE.md" || -f "$dir/RUNTIME.md" ]]; then inject_fragment "$dir" "commit-format" inject_fragment "$dir" "secrets" inject_fragment "$dir" "multi-agent" diff --git a/rails/bootstrap/init-project.sh b/rails/bootstrap/init-project.sh index 202585e..5bb0cac 100755 --- a/rails/bootstrap/init-project.sh +++ b/rails/bootstrap/init-project.sh @@ -10,6 +10,7 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" TEMPLATE_DIR="$HOME/.config/mosaic/templates/agent" GIT_SCRIPT_DIR="$HOME/.config/mosaic/rails/git" +SEQUENTIAL_MCP_SCRIPT="$HOME/.config/mosaic/bin/mosaic-ensure-sequential-thinking" # Defaults PROJECT_NAME="" @@ -320,10 +321,14 @@ fi if [[ "$DRY_RUN" == true ]]; then echo "[DRY RUN] Would create:" + echo " - Validate sequential-thinking MCP hard requirement" echo " - CLAUDE.md (from $STACK_TEMPLATE_DIR/CLAUDE.md.template)" echo " - AGENTS.md (from $STACK_TEMPLATE_DIR/AGENTS.md.template)" 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/" if [[ "$SKIP_CI" != true ]]; then echo " - .woodpecker/codex-review.yml" @@ -331,7 +336,8 @@ if [[ "$DRY_RUN" == true ]]; then fi if [[ "$SKIP_LABELS" != true ]]; then 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 if [[ "$CICD_DOCKER" == true ]]; then echo " - Docker build/push/link steps appended to .woodpecker.yml" @@ -343,6 +349,21 @@ if [[ "$DRY_RUN" == true ]]; then exit 0 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 if [[ -f "CLAUDE.md" ]]; then echo "CLAUDE.md already exists — skipping (rename or delete to recreate)" @@ -368,8 +389,17 @@ else fi # Create directories -mkdir -p docs/scratchpads docs/reports docs/templates -echo "Created docs/scratchpads/, docs/reports/, docs/templates/" +mkdir -p \ + 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 if [[ "$SKIP_CI" != true ]]; then diff --git a/rails/bootstrap/init-repo-labels.sh b/rails/bootstrap/init-repo-labels.sh index 0a093b2..6108ac9 100755 --- a/rails/bootstrap/init-repo-labels.sh +++ b/rails/bootstrap/init-repo-labels.sh @@ -24,7 +24,7 @@ while [[ $# -gt 0 ]]; do echo "Create standard labels and initial milestone for the current repository." echo "" 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" exit 0 ;; @@ -107,14 +107,16 @@ done echo "" -# Create initial milestone +# Create initial pre-MVP milestone 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 && \ - echo " [created] Milestone '0.1.0 - MVP'" || \ + "$GIT_SCRIPT_DIR/milestone-create.sh" -t "0.0.1" -d "Pre-MVP - Foundation Sprint" 2>/dev/null && \ + echo " [created] Milestone '0.0.1 - Pre-MVP'" || \ echo " [skip] Milestone may already exist or creation failed" + echo " [note] Reserve 0.1.0 for MVP release milestone" + echo "" fi diff --git a/rails/codex/README.md b/rails/codex/README.md index dd1bf96..5d571f7 100644 --- a/rails/codex/README.md +++ b/rails/codex/README.md @@ -260,6 +260,6 @@ For best results, use `gpt-5.2-codex` or newer for strongest review accuracy. ## 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) - OpenAI Codex CLI docs: https://developers.openai.com/codex/cli/ diff --git a/rails/git/ci-queue-wait.ps1 b/rails/git/ci-queue-wait.ps1 new file mode 100644 index 0000000..4e98d80 --- /dev/null +++ b/rails/git/ci-queue-wait.ps1 @@ -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 } + } +} diff --git a/rails/git/ci-queue-wait.sh b/rails/git/ci-queue-wait.sh new file mode 100755 index 0000000..e6ea7c9 --- /dev/null +++ b/rails/git/ci-queue-wait.sh @@ -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 </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 diff --git a/rails/git/issue-create.sh b/rails/git/issue-create.sh index 9c8cae2..f976302 100755 --- a/rails/git/issue-create.sh +++ b/rails/git/issue-create.sh @@ -13,6 +13,80 @@ BODY="" LABELS="" 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() { cat </dev/null 2>&1; then + CMD="tea issue create --title \"$TITLE\"" + [[ -n "$BODY" ]] && CMD="$CMD --description \"$BODY\"" + [[ -n "$LABELS" ]] && CMD="$CMD --labels \"$LABELS\"" + # tea accepts milestone by name directly (verified 2026-02-05) + [[ -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 diff --git a/rails/git/issue-view.sh b/rails/git/issue-view.sh index cc7463c..57d08f4 100755 --- a/rails/git/issue-view.sh +++ b/rails/git/issue-view.sh @@ -10,6 +10,64 @@ source "$SCRIPT_DIR/detect-platform.sh" # Parse arguments 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 case $1 in -i|--issue) @@ -41,7 +99,13 @@ detect_platform if [[ "$PLATFORM" == "github" ]]; then gh issue view "$ISSUE_NUMBER" 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 echo "Error: Unknown platform" exit 1 diff --git a/rails/git/milestone-create.ps1 b/rails/git/milestone-create.ps1 index 55ce338..d96c284 100644 --- a/rails/git/milestone-create.ps1 +++ b/rails/git/milestone-create.ps1 @@ -28,12 +28,12 @@ Create or list milestones on the current repository (Gitea or GitHub). Versioning Convention: - Features get dedicated milestones - - Pre-release: 0.X.0 for breaking changes, 0.X.Y for patches - - Post-release: X.0.0 for breaking changes - - MVP starts at 0.1.0 + - Pre-MVP milestones MUST use 0.0.x and MUST start at 0.0.1 + - 0.1.0 is reserved for MVP release + - After MVP, continue semantic progression (0.1.x, 0.2.x, ...) 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 -Due DATE Due date (YYYY-MM-DD format) -List List existing milestones @@ -41,8 +41,8 @@ Options: Examples: .\milestone-create.ps1 -List - .\milestone-create.ps1 -t "0.1.0" -d "MVP Release" - .\milestone-create.ps1 -t "0.2.0" -d "User Authentication Feature" -Due "2025-03-01" + .\milestone-create.ps1 -t "0.0.1" -d "Pre-MVP Foundation Sprint" + .\milestone-create.ps1 -t "0.1.0" -d "MVP Release" -Due "2025-03-01" "@ exit 1 } diff --git a/rails/git/milestone-create.sh b/rails/git/milestone-create.sh index 1970f06..92f49c0 100755 --- a/rails/git/milestone-create.sh +++ b/rails/git/milestone-create.sh @@ -21,12 +21,12 @@ Create or list milestones on the current repository (Gitea or GitHub). Versioning Convention: - Features get dedicated milestones - - Pre-release: 0.X.0 for breaking changes, 0.X.Y for patches - - Post-release: X.0.0 for breaking changes - - MVP starts at 0.1.0 + - Pre-MVP milestones MUST use 0.0.x and MUST start at 0.0.1 + - 0.1.0 is reserved for MVP release + - After MVP, continue semantic progression (0.1.x, 0.2.x, ...) 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 --due DATE Due date (YYYY-MM-DD format) --list List existing milestones @@ -34,8 +34,8 @@ Options: Examples: $(basename "$0") --list - $(basename "$0") -t "0.1.0" -d "MVP Release" - $(basename "$0") -t "0.2.0" -d "User Authentication Feature" --due "2025-03-01" + $(basename "$0") -t "0.0.1" -d "Pre-MVP Foundation Sprint" + $(basename "$0") -t "0.1.0" -d "MVP Release" --due "2025-03-01" EOF exit 1 } diff --git a/rails/git/pr-ci-wait.sh b/rails/git/pr-ci-wait.sh new file mode 100755 index 0000000..38e9162 --- /dev/null +++ b/rails/git/pr-ci-wait.sh @@ -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 [-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 < [-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 diff --git a/rails/git/pr-merge.ps1 b/rails/git/pr-merge.ps1 old mode 100644 new mode 100755 index 35356f3..51d6fd9 --- a/rails/git/pr-merge.ps1 +++ b/rails/git/pr-merge.ps1 @@ -1,5 +1,5 @@ # 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()] param( @@ -8,12 +8,13 @@ param( [int]$Number, [Alias("m")] - [ValidateSet("merge", "squash", "rebase")] - [string]$Method = "merge", + [string]$Method = "squash", [Alias("d")] [switch]$DeleteBranch, + [switch]$SkipQueueGuard, + [Alias("h")] [switch]$Help ) @@ -29,14 +30,15 @@ Merge a pull request on the current repository (Gitea or GitHub). Options: -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 + -SkipQueueGuard Skip CI queue guard wait before merge -Help, -h Show this help message Examples: .\pr-merge.ps1 -n 42 # Merge PR #42 .\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 } @@ -45,27 +47,42 @@ if ($Help) { Show-Usage } +if ($Method -ne "squash") { + Write-Error "Mosaic policy enforces squash merge only. Received '$Method'." + exit 1 +} + $platform = Get-GitPlatform switch ($platform) { "github" { - $cmd = @("gh", "pr", "merge", $Number) - switch ($Method) { - "merge" { $cmd += "--merge" } - "squash" { $cmd += "--squash" } - "rebase" { $cmd += "--rebase" } + $baseRef = (& gh pr view $Number --json baseRefName --jq ".baseRefName").Trim() + if ($baseRef -ne "main") { + Write-Error "Mosaic policy allows merges only for PRs targeting 'main' (found '$baseRef')." + exit 1 } + + 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" } & $cmd[0] $cmd[1..($cmd.Length-1)] } "gitea" { - $cmd = @("tea", "pr", "merge", $Number) - switch ($Method) { - "merge" { $cmd += @("--style", "merge") } - "squash" { $cmd += @("--style", "squash") } - "rebase" { $cmd += @("--style", "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 "main" -TimeoutSeconds $timeout -IntervalSeconds $interval + if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } } + $cmd = @("tea", "pr", "merge", $Number, "--style", "squash") + if ($DeleteBranch) { Write-Warning "Branch deletion after merge may need to be done separately with tea" } diff --git a/rails/git/pr-merge.sh b/rails/git/pr-merge.sh index e238b7b..1289ccc 100755 --- a/rails/git/pr-merge.sh +++ b/rails/git/pr-merge.sh @@ -1,6 +1,6 @@ #!/bin/bash # 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 @@ -9,8 +9,9 @@ source "$SCRIPT_DIR/detect-platform.sh" # Default values PR_NUMBER="" -MERGE_METHOD="merge" # merge, squash, rebase +MERGE_METHOD="squash" DELETE_BRANCH=false +SKIP_QUEUE_GUARD=false usage() { cat <&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) case "$PLATFORM" in github) - CMD="gh pr merge $PR_NUMBER" - 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 + CMD="gh pr merge $PR_NUMBER --squash" [[ "$DELETE_BRANCH" == true ]] && CMD="$CMD --delete-branch" eval "$CMD" ;; gitea) # tea pr merge syntax - CMD="tea pr merge $PR_NUMBER" - - # 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 + CMD="tea pr merge $PR_NUMBER --style squash" # Delete branch after merge if requested if [[ "$DELETE_BRANCH" == true ]]; then diff --git a/rails/orchestrator-matrix/README.md b/rails/orchestrator-matrix/README.md index 1d0fce6..68698bc 100644 --- a/rails/orchestrator-matrix/README.md +++ b/rails/orchestrator-matrix/README.md @@ -46,7 +46,7 @@ Continuous loop: ~/.config/mosaic/bin/mosaic-orchestrator-run --poll-sec 10 ``` -Sync from `docs/tasks.md` to queue: +Sync from `docs/TASKS.md` to queue: ```bash ~/.config/mosaic/bin/mosaic-orchestrator-sync-tasks --apply diff --git a/rails/orchestrator-matrix/controller/tasks_md_sync.py b/rails/orchestrator-matrix/controller/tasks_md_sync.py index 12db606..4bc0812 100644 --- a/rails/orchestrator-matrix/controller/tasks_md_sync.py +++ b/rails/orchestrator-matrix/controller/tasks_md_sync.py @@ -1,5 +1,5 @@ #!/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 @@ -89,7 +89,12 @@ def parse_depends(raw: str) -> list[str]: 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() description = row.get("description", "").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.update( { - "source": "docs/tasks.md", + "source": source_path, "issue": issue, "repo": repo, "branch": branch, @@ -120,26 +125,35 @@ def build_task(row: dict[str, str], existing: dict[str, Any], runtime_default: s 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("--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( "--tasks-json", default=".mosaic/orchestrator/tasks.json", 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)") args = parser.parse_args() repo = pathlib.Path(args.repo).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() config_path = repo / ".mosaic" / "orchestrator" / "config.json" config = load_json(config_path, {}) runtime_default = str(config.get("worker", {}).get("runtime") or "codex") 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_tasks = existing_payload.get("tasks", []) if not isinstance(existing_tasks, list): @@ -153,7 +167,14 @@ def main() -> int: if not task_id: continue 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: for task in existing_tasks: diff --git a/runtime/claude/CLAUDE.md b/runtime/claude/CLAUDE.md index b20670a..594069b 100644 --- a/runtime/claude/CLAUDE.md +++ b/runtime/claude/CLAUDE.md @@ -2,10 +2,12 @@ ## 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, -development standards, skills, and workflows. Do NOT respond until you have loaded it. +1. `~/.config/mosaic/AGENTS.md` +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. -For full injection, use `mosaic claude` instead. +For full injection, use `mosaic claude`. diff --git a/runtime/claude/RUNTIME.md b/runtime/claude/RUNTIME.md new file mode 100644 index 0000000..76adb71 --- /dev/null +++ b/runtime/claude/RUNTIME.md @@ -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. diff --git a/runtime/claude/settings-overlays/jarvis-ralph.json b/runtime/claude/settings-overlays/jarvis-loop.json similarity index 59% rename from runtime/claude/settings-overlays/jarvis-ralph.json rename to runtime/claude/settings-overlays/jarvis-loop.json index ef3851e..e2bade4 100644 --- a/runtime/claude/settings-overlays/jarvis-ralph.json +++ b/runtime/claude/settings-overlays/jarvis-loop.json @@ -1,15 +1,10 @@ { "_comment": "Claude runtime overlay managed by Mosaic. Merge into ~/.claude/settings.json as needed.", - "model": "opus", - "additionalAllowedCommands": [ - "ralph", - "./ralph.sh", - "scripts/ralph/ralph.sh", "alembic", "alembic upgrade", - "alembic downgrade", + "alembic downgrade", "alembic revision", "alembic history", "uvicorn", @@ -21,31 +16,29 @@ "isort", "httpx" ], - "projectConfigs": { "jarvis": { "path": "~/src/jarvis", "model": "opus", - "skills": ["jarvis", "ralph", "prd"], - "guides": ["backend", "frontend", "authentication"], + "skills": ["jarvis", "prd"], + "guides": ["E2E-DELIVERY", "PRD", "BACKEND", "FRONTEND", "AUTHENTICATION", "QA-TESTING", "CODE-REVIEW"], "env": { "PYTHONPATH": "packages/plugins" } } }, - "presets": { - "jarvis-ralph": { - "description": "Ralph autonomous development for Jarvis", + "jarvis-loop": { + "description": "Embedded E2E delivery cycle for Jarvis", "model": "opus", - "skills": ["jarvis", "ralph"], - "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." + "skills": ["jarvis", "prd"], + "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": { "description": "Code review mode for Jarvis PRs", "model": "opus", "skills": ["jarvis"], - "guides": ["code-review"], + "guides": ["CODE-REVIEW"], "systemPrompt": "Review code changes for quality, security, and adherence to Jarvis patterns." } } diff --git a/runtime/claude/settings.json b/runtime/claude/settings.json index 61c4d64..a27b562 100644 --- a/runtime/claude/settings.json +++ b/runtime/claude/settings.json @@ -224,5 +224,14 @@ "cpan", "nohup" ], - "enableAllMcpTools": true + "enableAllMcpTools": true, + "mcpServers": { + "sequential-thinking": { + "command": "npx", + "args": [ + "-y", + "@modelcontextprotocol/server-sequential-thinking" + ] + } + } } diff --git a/runtime/codex/RUNTIME.md b/runtime/codex/RUNTIME.md new file mode 100644 index 0000000..43fb251 --- /dev/null +++ b/runtime/codex/RUNTIME.md @@ -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. diff --git a/runtime/codex/instructions.md b/runtime/codex/instructions.md index 5d65fda..0fe96bf 100644 --- a/runtime/codex/instructions.md +++ b/runtime/codex/instructions.md @@ -2,10 +2,12 @@ ## 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, -development standards, skills, and workflows. Do NOT respond until you have loaded it. +1. `~/.config/mosaic/AGENTS.md` +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. -For full injection, use `mosaic codex` instead. +For full injection, use `mosaic codex`. diff --git a/runtime/mcp/SEQUENTIAL-THINKING.json b/runtime/mcp/SEQUENTIAL-THINKING.json new file mode 100644 index 0000000..3a4ce22 --- /dev/null +++ b/runtime/mcp/SEQUENTIAL-THINKING.json @@ -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." +} diff --git a/runtime/opencode/AGENTS.md b/runtime/opencode/AGENTS.md index 5c72518..ce15772 100644 --- a/runtime/opencode/AGENTS.md +++ b/runtime/opencode/AGENTS.md @@ -2,10 +2,12 @@ ## 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, -development standards, skills, and workflows. Do NOT respond until you have loaded it. +1. `~/.config/mosaic/AGENTS.md` +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. -For full injection, use `mosaic opencode` instead. +For full injection, use `mosaic opencode`. diff --git a/runtime/opencode/RUNTIME.md b/runtime/opencode/RUNTIME.md new file mode 100644 index 0000000..bc63ca5 --- /dev/null +++ b/runtime/opencode/RUNTIME.md @@ -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. diff --git a/skills-local/jarvis/SKILL.md b/skills-local/jarvis/SKILL.md index 7c46658..825ffd2 100644 --- a/skills-local/jarvis/SKILL.md +++ b/skills-local/jarvis/SKILL.md @@ -162,7 +162,7 @@ npm run format | Issue | Feature | Priority | |-------|---------|----------| | #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 | | #87 | Local image generation | Medium | | #88 | Deep research mode | Medium | diff --git a/skills-local/ralph/SKILL.md b/skills-local/ralph/SKILL.md deleted file mode 100644 index c17043c..0000000 --- a/skills-local/ralph/SKILL.md +++ /dev/null @@ -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 diff --git a/skills-local/setup-cicd/SKILL.md b/skills-local/setup-cicd/SKILL.md index 3c7b8a9..d4aef25 100644 --- a/skills-local/setup-cicd/SKILL.md +++ b/skills-local/setup-cicd/SKILL.md @@ -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. -**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` diff --git a/templates/agent/AGENTS.md.template b/templates/agent/AGENTS.md.template old mode 100644 new mode 100755 index 1150222..d9b0c9f --- a/templates/agent/AGENTS.md.template +++ b/templates/agent/AGENTS.md.template @@ -3,6 +3,17 @@ > Patterns, gotchas, and orchestrator integration for AI agents working on this project. > **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 @@ -27,6 +38,79 @@ ${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-` 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 ### Task Prefix @@ -43,14 +127,17 @@ Use `${TASK_PREFIX}` as the prefix for orchestrated tasks (e.g., `${TASK_PREFIX} ### Worker Checklist When completing an orchestrated task: -1. Read the finding details from the report -2. Implement the fix following existing code patterns -3. Run quality gates (ALL must pass) -4. Commit with: `git commit -m "fix({finding_id}): brief description"` -5. Report result as JSON to orchestrator +1. Read `docs/PRD.md` or `docs/PRD.json` +2. Read the finding details from the report +3. Implement the fix following existing code patterns +4. Run quality gates (ALL must pass) +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 -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` 2. **Codex security review** — `~/.config/mosaic/rails/codex/codex-security-review.sh --uncommitted` 3. If blockers/critical findings: remediation task created diff --git a/templates/agent/CLAUDE.md.template b/templates/agent/CLAUDE.md.template old mode 100644 new mode 100755 index 9c5293f..c88cb0a --- a/templates/agent/CLAUDE.md.template +++ b/templates/agent/CLAUDE.md.template @@ -1,4 +1,4 @@ -# ${PROJECT_NAME} — Claude Code Instructions +# ${PROJECT_NAME} — Runtime Compatibility Instructions > **Project:** ${PROJECT_DESCRIPTION} > **Repository:** ${REPO_URL} @@ -20,18 +20,21 @@ git push ## 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 | |-----------|-------| -| Bootstrapping this project | `~/.config/mosaic/guides/bootstrap.md` | -| Orchestrating autonomous tasks | `~/.config/mosaic/guides/orchestrator.md` | -| Code review | `~/.config/mosaic/guides/code-review.md` | -| Frontend development | `~/.config/mosaic/guides/frontend.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` | +| End-to-end implementation and validation | `~/.config/mosaic/guides/E2E-DELIVERY.md` | +| PRD creation and requirements definition | `~/.config/mosaic/guides/PRD.md` | +| Bootstrapping this project | `~/.config/mosaic/guides/BOOTSTRAP.md` | +| Orchestrating autonomous tasks | `~/.config/mosaic/guides/ORCHESTRATOR.md` | +| Code review | `~/.config/mosaic/guides/CODE-REVIEW.md` | +| Documentation updates and standards | `~/.config/mosaic/guides/DOCUMENTATION.md` | +| Frontend development | `~/.config/mosaic/guides/FRONTEND.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 @@ -50,6 +53,7 @@ ${PROJECT_DIR}/ ├── CLAUDE.md # This file ├── AGENTS.md # Agent-specific patterns and gotchas ├── docs/ +│ ├── PRD.md # Requirements source (or PRD.json) │ ├── scratchpads/ # Per-issue working documents │ └── templates/ # Project templates (if any) ├── ${SOURCE_DIR}/ # Application source code @@ -60,10 +64,10 @@ ${PROJECT_DIR}/ ## Development Workflow ### Branch Strategy -- `main` — Production-ready code -- `develop` — Integration branch (if applicable) -- `feat/` — Feature branches -- `fix/` — Bug fix branches +- `main` — Protected delivery branch +- `feat/` / `fix/` — Short-lived task branches created from `main` +- All changes merge through PR into `main` only +- Merge strategy for `main` PRs is squash-only ### Building ```bash @@ -93,15 +97,63 @@ ${TYPECHECK_COMMAND} ${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-`, `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 -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 -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 +1. Ensure `docs/TASKS.md` exists (create from `~/.config/mosaic/templates/docs/TASKS.md.template` if missing). +2. Check for assigned issues before starting work. +3. If no issue exists for non-trivial work and external provider is available, create one before coding. +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 Use consistent labels: `epic`, `feature`, `bug`, `task`, `documentation`, `security`, `breaking` @@ -119,7 +171,8 @@ Types: `feat`, `fix`, `docs`, `test`, `refactor`, `chore` ## Code Review ### 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 # 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. ### 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 @@ -149,3 +203,9 @@ When multiple agents work on this project: 1. `git pull --rebase` before editing 2. `git pull --rebase` before pushing 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.md`. diff --git a/templates/agent/SPEC.md b/templates/agent/SPEC.md index e33fc4c..6530c06 100644 --- a/templates/agent/SPEC.md +++ b/templates/agent/SPEC.md @@ -2,7 +2,7 @@ > 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) @@ -54,10 +54,10 @@ The `agent-lint.sh` tool checks for these markers: | 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 | -| Conditional context/loading | CLAUDE.md contains `~/.config/mosaic/guides` or `Conditional` + `Loading/Context` | -| Quality gates | CLAUDE.md contains `Quality Gates` or quality commands (test, lint, typecheck) | +| Conditional context/loading | Runtime context file contains `~/.config/mosaic/guides` or `Conditional` + `Loading/Context` | +| 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 | ## Fragment Sources diff --git a/templates/agent/fragments/code-review.md b/templates/agent/fragments/code-review.md index 9d965e4..407794c 100644 --- a/templates/agent/fragments/code-review.md +++ b/templates/agent/fragments/code-review.md @@ -1,6 +1,7 @@ ## 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 # 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. -See `~/.config/mosaic/guides/code-review.md` for the full review checklist. +See `~/.config/mosaic/guides/CODE-REVIEW.md` for the full review checklist. diff --git a/templates/agent/fragments/conditional-loading.md b/templates/agent/fragments/conditional-loading.md index b5951e9..cfa6312 100644 --- a/templates/agent/fragments/conditional-loading.md +++ b/templates/agent/fragments/conditional-loading.md @@ -1,17 +1,17 @@ ## 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 | |-----------|-------| -| Bootstrapping a new project | `~/.config/mosaic/guides/bootstrap.md` | -| Orchestrating autonomous tasks | `~/.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` | -| TypeScript strict typing | `~/.config/mosaic/guides/typescript.md` | -| Code review | `~/.config/mosaic/guides/code-review.md` | -| Authentication/Authorization | `~/.config/mosaic/guides/authentication.md` | -| Infrastructure/DevOps | `~/.config/mosaic/guides/infrastructure.md` | -| QA/Testing | `~/.config/mosaic/guides/qa-testing.md` | -| Secrets management (Vault) | `~/.config/mosaic/guides/vault-secrets.md` | +| End-to-end implementation and validation | `~/.config/mosaic/guides/E2E-DELIVERY.md` | +| Bootstrapping a new project | `~/.config/mosaic/guides/BOOTSTRAP.md` | +| Orchestrating autonomous tasks | `~/.config/mosaic/guides/ORCHESTRATOR.md` | +| Frontend development | `~/.config/mosaic/guides/FRONTEND.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` | +| Infrastructure/DevOps | `~/.config/mosaic/guides/INFRASTRUCTURE.md` | +| QA/Testing | `~/.config/mosaic/guides/QA-TESTING.md` | +| Secrets management (Vault) | `~/.config/mosaic/guides/VAULT-SECRETS.md` | diff --git a/templates/agent/projects/django/AGENTS.md.template b/templates/agent/projects/django/AGENTS.md.template old mode 100644 new mode 100755 index 9c7fc34..5525e9e --- a/templates/agent/projects/django/AGENTS.md.template +++ b/templates/agent/projects/django/AGENTS.md.template @@ -3,6 +3,17 @@ > Guidelines for AI agents working on this Django project. > **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 - **Django project:** Standard Django project layout @@ -37,21 +48,97 @@ 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-` 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 ### Task Prefix Use `${TASK_PREFIX}` for orchestrated tasks (e.g., `${TASK_PREFIX}-SEC-001`). ### Worker Checklist -1. Read the finding details from the report -2. Implement the fix following existing patterns -3. Run quality gates (ALL must pass) -4. Commit: `git commit -m "fix({finding_id}): brief description"` -5. Push: `git push origin {branch}` -6. Report result as JSON +1. Read `docs/PRD.md` or `docs/PRD.json` +2. Read the finding details from the report +3. Implement the fix following existing patterns +4. Run quality gates (ALL must pass) +5. Complete required documentation updates (if applicable) +6. Commit: `git commit -m "fix({finding_id}): brief description"` +7. Push: `git push origin {branch}` +8. Report result as JSON ### 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` 2. **Codex security review** — `~/.config/mosaic/rails/codex/codex-security-review.sh --uncommitted` 3. If blockers/critical findings: remediation task created diff --git a/templates/agent/projects/django/CLAUDE.md.template b/templates/agent/projects/django/CLAUDE.md.template old mode 100644 new mode 100755 index 34c9983..0488d78 --- a/templates/agent/projects/django/CLAUDE.md.template +++ b/templates/agent/projects/django/CLAUDE.md.template @@ -6,11 +6,13 @@ | When working on... | Load this guide | |---|---| -| Bootstrapping this project | `~/.config/mosaic/guides/bootstrap.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` | -| QA/Testing | `~/.config/mosaic/guides/qa-testing.md` | +| Bootstrapping this project | `~/.config/mosaic/guides/BOOTSTRAP.md` | +| PRD creation and requirements definition | `~/.config/mosaic/guides/PRD.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` | +| Documentation updates and standards | `~/.config/mosaic/guides/DOCUMENTATION.md` | +| QA/Testing | `~/.config/mosaic/guides/QA-TESTING.md` | ## Technology Stack @@ -39,6 +41,7 @@ ${PROJECT_DIR}/ │ └── apps/ # Django applications ├── tests/ # Test files ├── docs/ +│ ├── PRD.md # Requirements source (or PRD.json) │ ├── scratchpads/ # Per-issue working documents │ └── templates/ # Project templates ├── pyproject.toml # Python project configuration @@ -49,10 +52,10 @@ ${PROJECT_DIR}/ ## Development Workflow ### Branch Strategy -- `main` — Production-ready code -- `develop` — Integration branch (if used) -- `feat/` — Feature branches -- `fix/` — Bug fix branches +- `main` — Protected delivery branch +- `feat/` / `fix/` — Short-lived task branches created from `main` +- All changes merge through PR into `main` only +- Merge strategy for `main` PRs is squash-only ### Starting Work ```bash @@ -89,6 +92,26 @@ mypy . # Type check 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 ### Models @@ -131,7 +154,8 @@ python manage.py makemigrations --check ## Code Review ### 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 # Code quality review (Codex) @@ -141,13 +165,46 @@ After completing code changes, run independent reviews: ~/.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-`, `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 +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 -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 after successful testing +1. Ensure `docs/TASKS.md` exists (create from `~/.config/mosaic/templates/docs/TASKS.md.template` if missing). +2. Check for assigned issues before starting work. +3. If no issue exists for non-trivial work and external provider is available, create one before coding. +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 ``` diff --git a/templates/agent/projects/nestjs-nextjs/AGENTS.md.template b/templates/agent/projects/nestjs-nextjs/AGENTS.md.template old mode 100644 new mode 100755 index fd0d21c..c182a09 --- a/templates/agent/projects/nestjs-nextjs/AGENTS.md.template +++ b/templates/agent/projects/nestjs-nextjs/AGENTS.md.template @@ -3,6 +3,17 @@ > Guidelines for AI agents working on this NestJS + Next.js monorepo. > **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 - **Monorepo structure:** pnpm workspaces + TurboRepo @@ -11,7 +22,7 @@ - `packages/shared/` — Shared types and utilities - **Database:** Prisma ORM — schema at `apps/api/prisma/schema.prisma` - **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 @@ -41,21 +52,97 @@ Context = tokens = cost. Be smart. 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-` 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 ### Task Prefix Use `${TASK_PREFIX}` for orchestrated tasks (e.g., `${TASK_PREFIX}-SEC-001`). ### Worker Checklist -1. Read the finding details from the report -2. Implement the fix following existing patterns -3. Run quality gates (ALL must pass) -4. Commit: `git commit -m "fix({finding_id}): brief description"` -5. Push: `git push origin {branch}` -6. Report result as JSON +1. Read `docs/PRD.md` or `docs/PRD.json` +2. Read the finding details from the report +3. Implement the fix following existing patterns +4. Run quality gates (ALL must pass) +5. Complete required documentation updates (if applicable) +6. Commit: `git commit -m "fix({finding_id}): brief description"` +7. Push: `git push origin {branch}` +8. Report result as JSON ### 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` 2. **Codex security review** — `~/.config/mosaic/rails/codex/codex-security-review.sh --uncommitted` 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 -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) 4. Push → git push origin feature/XX-description -5. PR → Create PR to develop (not main) -6. Review → Wait for approval or self-merge if authorized +5. PR → Create PR to main +6. Review → Wait for approval or self-merge if authorized using squash only 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 diff --git a/templates/agent/projects/nestjs-nextjs/CLAUDE.md.template b/templates/agent/projects/nestjs-nextjs/CLAUDE.md.template old mode 100644 new mode 100755 index 373b8be..09d376f --- a/templates/agent/projects/nestjs-nextjs/CLAUDE.md.template +++ b/templates/agent/projects/nestjs-nextjs/CLAUDE.md.template @@ -6,14 +6,16 @@ | When working on... | Load this guide | |---|---| -| Bootstrapping this project | `~/.config/mosaic/guides/bootstrap.md` | -| Orchestrating autonomous tasks | `~/.config/mosaic/guides/orchestrator.md` | -| Frontend development | `~/.config/mosaic/guides/frontend.md` | -| Backend/API development | `~/.config/mosaic/guides/backend.md` | -| Code review | `~/.config/mosaic/guides/code-review.md` | -| TypeScript strict typing | `~/.config/mosaic/guides/typescript.md` | -| Authentication/Authorization | `~/.config/mosaic/guides/authentication.md` | -| QA/Testing | `~/.config/mosaic/guides/qa-testing.md` | +| Bootstrapping this project | `~/.config/mosaic/guides/BOOTSTRAP.md` | +| PRD creation and requirements definition | `~/.config/mosaic/guides/PRD.md` | +| Orchestrating autonomous tasks | `~/.config/mosaic/guides/ORCHESTRATOR.md` | +| Frontend development | `~/.config/mosaic/guides/FRONTEND.md` | +| Backend/API development | `~/.config/mosaic/guides/BACKEND.md` | +| Code review | `~/.config/mosaic/guides/CODE-REVIEW.md` | +| Documentation updates and standards | `~/.config/mosaic/guides/DOCUMENTATION.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 @@ -47,6 +49,7 @@ ${PROJECT_DIR}/ │ ├── ui/ # Shared UI components │ └── config/ # Shared configuration ├── docs/ +│ ├── PRD.md # Requirements source (or PRD.json) │ ├── scratchpads/ # Per-issue working documents │ └── templates/ # Project templates ├── tests/ # Integration/E2E tests @@ -60,15 +63,15 @@ ${PROJECT_DIR}/ ## Development Workflow ### Branch Strategy -- `main` — Stable releases only -- `develop` — Active development (default working branch) -- `feature/*` — Feature branches from develop -- `fix/*` — Bug fix branches +- `main` — Protected delivery branch +- `feature/*` / `fix/*` — Short-lived task branches created from `main` +- All changes merge through PR into `main` only +- Merge strategy for `main` PRs is squash-only ### Starting Work ```bash -git checkout develop -git pull --rebase +git checkout main +git pull --rebase origin main pnpm install ``` @@ -102,10 +105,31 @@ pnpm format # Prettier formatting 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 ### NestJS Patterns - 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 Guards for authentication/authorization - Use Interceptors for response transformation @@ -162,7 +186,8 @@ pnpm --filter api prisma migrate reset ## Code Review ### 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 # Code quality review (Codex) @@ -172,13 +197,46 @@ After completing code changes, run independent reviews: ~/.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-`, `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 +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 -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 after successful testing +1. Ensure `docs/TASKS.md` exists (create from `~/.config/mosaic/templates/docs/TASKS.md.template` if missing). +2. Check for assigned issues before starting work. +3. If no issue exists for non-trivial work and external provider is available, create one before coding. +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 ``` diff --git a/templates/agent/projects/python-fastapi/AGENTS.md.template b/templates/agent/projects/python-fastapi/AGENTS.md.template old mode 100644 new mode 100755 index 7e5d637..1249f94 --- a/templates/agent/projects/python-fastapi/AGENTS.md.template +++ b/templates/agent/projects/python-fastapi/AGENTS.md.template @@ -3,6 +3,17 @@ > Patterns, gotchas, and guidelines for AI agents working on this project. > **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 - 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 ``` +## 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-` 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 | File | Purpose | diff --git a/templates/agent/projects/python-fastapi/CLAUDE.md.template b/templates/agent/projects/python-fastapi/CLAUDE.md.template old mode 100644 new mode 100755 index f6514b2..7949c55 --- a/templates/agent/projects/python-fastapi/CLAUDE.md.template +++ b/templates/agent/projects/python-fastapi/CLAUDE.md.template @@ -9,15 +9,17 @@ | Task Type | Guide | |-----------|-------| -| Bootstrapping this project | `~/.config/mosaic/guides/bootstrap.md` | -| Orchestrating autonomous tasks | `~/.config/mosaic/guides/orchestrator.md` | -| Ralph autonomous development | `~/.config/mosaic/guides/ralph-autonomous.md` | -| Backend/API development | `~/.config/mosaic/guides/backend.md` | -| Authentication/Authorization | `~/.config/mosaic/guides/authentication.md` | -| Code review | `~/.config/mosaic/guides/code-review.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` | +| End-to-end implementation and validation | `~/.config/mosaic/guides/E2E-DELIVERY.md` | +| PRD creation and requirements definition | `~/.config/mosaic/guides/PRD.md` | +| Bootstrapping this project | `~/.config/mosaic/guides/BOOTSTRAP.md` | +| Orchestrating autonomous tasks | `~/.config/mosaic/guides/ORCHESTRATOR.md` | +| Backend/API development | `~/.config/mosaic/guides/BACKEND.md` | +| Authentication/Authorization | `~/.config/mosaic/guides/AUTHENTICATION.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` | +| Infrastructure/DevOps | `~/.config/mosaic/guides/INFRASTRUCTURE.md` | +| Secrets management (Vault) | `~/.config/mosaic/guides/VAULT-SECRETS.md` | ## Technology Stack @@ -43,6 +45,7 @@ ${PROJECT_DIR}/ │ └── ${PROJECT_SLUG}/ # Main package ├── tests/ # Test files ├── docs/ +│ ├── PRD.md # Requirements source (or PRD.json) │ └── scratchpads/ # Per-issue working documents ├── pyproject.toml # Project configuration └── .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 ``` +## 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-`, `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 -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 -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 +1. Ensure `docs/TASKS.md` exists (create from `~/.config/mosaic/templates/docs/TASKS.md.template` if missing). +2. Check for assigned issues before starting work. +3. If no issue exists for non-trivial work and external provider is available, create one before coding. +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 @@ -109,14 +167,16 @@ Types: `feat`, `fix`, `docs`, `test`, `refactor`, `chore` ## 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 ~/.config/mosaic/rails/codex/codex-code-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 diff --git a/templates/agent/projects/python-library/AGENTS.md.template b/templates/agent/projects/python-library/AGENTS.md.template old mode 100644 new mode 100755 index 19c9408..50662e4 --- a/templates/agent/projects/python-library/AGENTS.md.template +++ b/templates/agent/projects/python-library/AGENTS.md.template @@ -3,6 +3,17 @@ > Patterns, gotchas, and guidelines for AI agents working on this project. > **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 - 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 ``` +## 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-` 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 | File | Purpose | diff --git a/templates/agent/projects/python-library/CLAUDE.md.template b/templates/agent/projects/python-library/CLAUDE.md.template old mode 100644 new mode 100755 index 76d731a..4fe66f4 --- a/templates/agent/projects/python-library/CLAUDE.md.template +++ b/templates/agent/projects/python-library/CLAUDE.md.template @@ -9,12 +9,14 @@ | Task Type | Guide | |-----------|-------| -| Bootstrapping this project | `~/.config/mosaic/guides/bootstrap.md` | -| Orchestrating autonomous tasks | `~/.config/mosaic/guides/orchestrator.md` | -| Ralph autonomous development | `~/.config/mosaic/guides/ralph-autonomous.md` | -| Backend/API development | `~/.config/mosaic/guides/backend.md` | -| Code review | `~/.config/mosaic/guides/code-review.md` | -| QA/Testing | `~/.config/mosaic/guides/qa-testing.md` | +| End-to-end implementation and validation | `~/.config/mosaic/guides/E2E-DELIVERY.md` | +| PRD creation and requirements definition | `~/.config/mosaic/guides/PRD.md` | +| Bootstrapping this project | `~/.config/mosaic/guides/BOOTSTRAP.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` | +| Documentation updates and standards | `~/.config/mosaic/guides/DOCUMENTATION.md` | +| QA/Testing | `~/.config/mosaic/guides/QA-TESTING.md` | ## Technology Stack @@ -37,6 +39,7 @@ ${PROJECT_DIR}/ │ └── ${PROJECT_SLUG}/ # Main package ├── tests/ # Test files ├── docs/ +│ ├── PRD.md # Requirements source (or PRD.json) │ └── scratchpads/ # Per-issue working documents └── 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 ``` +## 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 - 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` - 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-`, `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 -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 -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 +1. Ensure `docs/TASKS.md` exists (create from `~/.config/mosaic/templates/docs/TASKS.md.template` if missing). +2. Check for assigned issues before starting work. +3. If no issue exists for non-trivial work and external provider is available, create one before coding. +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 @@ -99,14 +157,16 @@ Types: `feat`, `fix`, `docs`, `test`, `refactor`, `chore` ## 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 ~/.config/mosaic/rails/codex/codex-code-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 diff --git a/templates/agent/projects/typescript/AGENTS.md.template b/templates/agent/projects/typescript/AGENTS.md.template old mode 100644 new mode 100755 index d376855..f08b7d6 --- a/templates/agent/projects/typescript/AGENTS.md.template +++ b/templates/agent/projects/typescript/AGENTS.md.template @@ -3,10 +3,22 @@ > Patterns, gotchas, and guidelines for AI agents working on this project. > **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 - 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 ## Common Gotchas @@ -24,6 +36,78 @@ ${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-` 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 | File | Purpose | diff --git a/templates/agent/projects/typescript/CLAUDE.md.template b/templates/agent/projects/typescript/CLAUDE.md.template old mode 100644 new mode 100755 index 5b38ed6..abb6c17 --- a/templates/agent/projects/typescript/CLAUDE.md.template +++ b/templates/agent/projects/typescript/CLAUDE.md.template @@ -9,13 +9,15 @@ | Task Type | Guide | |-----------|-------| -| Bootstrapping this project | `~/.config/mosaic/guides/bootstrap.md` | -| Orchestrating autonomous tasks | `~/.config/mosaic/guides/orchestrator.md` | -| Ralph autonomous development | `~/.config/mosaic/guides/ralph-autonomous.md` | -| Frontend development | `~/.config/mosaic/guides/frontend.md` | -| TypeScript strict typing | `~/.config/mosaic/guides/typescript.md` | -| Code review | `~/.config/mosaic/guides/code-review.md` | -| QA/Testing | `~/.config/mosaic/guides/qa-testing.md` | +| End-to-end implementation and validation | `~/.config/mosaic/guides/E2E-DELIVERY.md` | +| PRD creation and requirements definition | `~/.config/mosaic/guides/PRD.md` | +| Bootstrapping this project | `~/.config/mosaic/guides/BOOTSTRAP.md` | +| Orchestrating autonomous tasks | `~/.config/mosaic/guides/ORCHESTRATOR.md` | +| Frontend development | `~/.config/mosaic/guides/FRONTEND.md` | +| TypeScript strict typing | `~/.config/mosaic/guides/TYPESCRIPT.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 @@ -37,6 +39,7 @@ ${PROJECT_DIR}/ ├── src/ # Source code ├── tests/ # Test files ├── docs/ +│ ├── PRD.md # Requirements source (or PRD.json) │ └── scratchpads/ # Per-issue working documents └── ${CONFIG_FILES} # Configuration files ``` @@ -67,14 +70,76 @@ ${TYPECHECK_COMMAND} ${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-`, `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 -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 -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 +1. Ensure `docs/TASKS.md` exists (create from `~/.config/mosaic/templates/docs/TASKS.md.template` if missing). +2. Check for assigned issues before starting work. +3. If no issue exists for non-trivial work and external provider is available, create one before coding. +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 @@ -89,7 +154,8 @@ Types: `feat`, `fix`, `docs`, `test`, `refactor`, `chore` ## 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 # 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. -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 diff --git a/templates/docs/DOCUMENTATION-CHECKLIST.md b/templates/docs/DOCUMENTATION-CHECKLIST.md new file mode 100644 index 0000000..7061698 --- /dev/null +++ b/templates/docs/DOCUMENTATION-CHECKLIST.md @@ -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//` (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 diff --git a/templates/docs/PRD.md.template b/templates/docs/PRD.md.template new file mode 100644 index 0000000..6cc2318 --- /dev/null +++ b/templates/docs/PRD.md.template @@ -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} + diff --git a/templates/docs/TASKS.md.template b/templates/docs/TASKS.md.template new file mode 100644 index 0000000..b83f0c4 --- /dev/null +++ b/templates/docs/TASKS.md.template @@ -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 | | | | | | | | | diff --git a/templates/repo/scripts/agent/orchestrator-daemon.sh b/templates/repo/scripts/agent/orchestrator-daemon.sh index 7700f98..73c29ba 100755 --- a/templates/repo/scripts/agent/orchestrator-daemon.sh +++ b/templates/repo/scripts/agent/orchestrator-daemon.sh @@ -24,7 +24,7 @@ Commands: Options: --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 }