feat: rename rails/ to tools/ and add service tool suites

Rename the `rails/` directory to `tools/` for agent discoverability —
agents frequently failed to locate helper scripts due to the non-intuitive
directory name. Add backward-compat symlink `rails/ → tools/`.

New tool suites:
- Authentik: auth-token, user-list, user-create, group-list, app-list,
  flow-list, admin-status (8 scripts)
- Coolify: team-list, project-list, service-list, service-status, deploy,
  env-set (7 scripts)
- Woodpecker: pipeline-list, pipeline-status, pipeline-trigger (3 stubs)
- GLPI: session-init, computer-list, ticket-list, ticket-create, user-list
  (6 scripts)
- Health: stack-health.sh — stack-wide connectivity check

Infrastructure:
- Shared credential loader at tools/_lib/credentials.sh
- install.sh creates symlink + chmod on tool scripts
- All ~253 rails/ path references updated across 68+ files

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-22 11:51:39 -06:00
parent 248db8935c
commit 80c3680ccb
158 changed files with 2481 additions and 213 deletions

View File

@@ -1,7 +1,7 @@
# Authentication & Authorization Guide
## Before Starting
1. Check assigned issue: `~/.config/mosaic/rails/git/issue-list.sh -a @me`
1. Check assigned issue: `~/.config/mosaic/tools/git/issue-list.sh -a @me`
2. Review existing auth implementation in codebase
3. Review Vault secrets structure: `docs/vault-secrets-structure.md`
@@ -115,6 +115,41 @@ class TestAuthentication:
pass
```
## Authentik SSO Administration
Authentik is the identity provider for the Mosaic Stack. Use the Authentik tool suite for administration.
### Tool Suite
```bash
# System health
~/.config/mosaic/tools/authentik/admin-status.sh
# User management
~/.config/mosaic/tools/authentik/user-list.sh
~/.config/mosaic/tools/authentik/user-create.sh -u <username> -n <name> -e <email>
# Group and app management
~/.config/mosaic/tools/authentik/group-list.sh
~/.config/mosaic/tools/authentik/app-list.sh
~/.config/mosaic/tools/authentik/flow-list.sh
```
### Registering an OAuth Application
1. Create an OAuth2 provider in Authentik admin (Applications > Providers)
2. Create an application linked to the provider (Applications > Applications)
3. Configure redirect URIs for the application
4. Store client_id and client_secret in Vault: `secret-{env}/{service}/oauth/authentik/`
5. Verify with: `~/.config/mosaic/tools/authentik/app-list.sh`
### API Reference
- Base URL: `https://auth.diversecanvas.com`
- API prefix: `/api/v3/`
- OpenAPI schema: `/api/v3/schema/`
- Auth: Bearer token (obtained via `auth-token.sh`)
## Common Vulnerabilities to Avoid
1. **Broken Authentication**

View File

@@ -1,7 +1,7 @@
# Backend Development Guide
## Before Starting
1. Check assigned issue: `~/.config/mosaic/rails/git/issue-list.sh -a @me`
1. Check assigned issue: `~/.config/mosaic/tools/git/issue-list.sh -a @me`
2. Create scratchpad: `docs/scratchpads/{issue-number}-{short-name}.md`
3. Review API contracts and database schema

View File

@@ -19,7 +19,7 @@ This guide covers how to bootstrap a project so AI agents (Claude, Codex, etc.)
```bash
# Automated bootstrap (recommended)
~/.config/mosaic/rails/bootstrap/init-project.sh \
~/.config/mosaic/tools/bootstrap/init-project.sh \
--name "my-project" \
--type "nestjs-nextjs" \
--repo "https://git.mosaicstack.dev/owner/repo"
@@ -240,10 +240,10 @@ Documentation root hygiene (HARD RULE):
```bash
# Use the init script
~/.config/mosaic/rails/bootstrap/init-repo-labels.sh
~/.config/mosaic/tools/bootstrap/init-repo-labels.sh
# Or manually create standard labels
~/.config/mosaic/rails/git/issue-create.sh # (labels are created on first use)
~/.config/mosaic/tools/git/issue-create.sh # (labels are created on first use)
```
### Standard Labels
@@ -264,10 +264,10 @@ 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"
~/.config/mosaic/tools/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"
~/.config/mosaic/tools/git/milestone-create.sh -t "0.1.0" -d "MVP - Minimum Viable Product"
```
---
@@ -293,8 +293,8 @@ This enforces one merge strategy across human and agent workflows.
```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/
cp ~/.config/mosaic/tools/codex/woodpecker/codex-review.yml .woodpecker/
cp ~/.config/mosaic/tools/codex/schemas/*.json .woodpecker/schemas/
# Add codex_api_key secret to Woodpecker CI dashboard
```
@@ -366,7 +366,7 @@ fi
# (execute the command block under "Quality Gates")
# Test Codex review (if configured)
~/.config/mosaic/rails/codex/codex-code-review.sh --help
~/.config/mosaic/tools/codex/codex-code-review.sh --help
# Verify sequential-thinking MCP remains configured
~/.config/mosaic/bin/mosaic-ensure-sequential-thinking --check
@@ -434,7 +434,7 @@ fi
Full project bootstrap with interactive and flag-based modes:
```bash
~/.config/mosaic/rails/bootstrap/init-project.sh \
~/.config/mosaic/tools/bootstrap/init-project.sh \
--name "My Project" \
--type "nestjs-nextjs" \
--repo "https://git.mosaicstack.dev/owner/repo" \
@@ -447,7 +447,7 @@ Full project bootstrap with interactive and flag-based modes:
Initialize standard labels and the first pre-MVP milestone:
```bash
~/.config/mosaic/rails/bootstrap/init-repo-labels.sh
~/.config/mosaic/tools/bootstrap/init-repo-labels.sh
```
---
@@ -483,4 +483,4 @@ After bootstrapping, verify:
- [ ] `.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/`)
- [ ] Codex review scripts accessible (`~/.config/mosaic/tools/codex/`)

View File

@@ -12,7 +12,7 @@ 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).
- Use `~/.config/mosaic/tools/git/pr-merge.sh -n {PR_NUMBER} -m squash` (or PowerShell equivalent).
## Review Checklist
@@ -101,7 +101,7 @@ Use `~/.config/mosaic/templates/docs/DOCUMENTATION-CHECKLIST.md` whenever code/A
### Getting Context
```bash
# List the issue being addressed
~/.config/mosaic/rails/git/issue-list.sh -i {issue-number}
~/.config/mosaic/tools/git/issue-list.sh -i {issue-number}
# View the changes
git diff main...HEAD

View File

@@ -1,7 +1,7 @@
# Frontend Development Guide
## Before Starting
1. Check assigned issue in git repo: `~/.config/mosaic/rails/git/issue-list.sh -a @me`
1. Check assigned issue in git repo: `~/.config/mosaic/tools/git/issue-list.sh -a @me`
2. Create scratchpad: `docs/scratchpads/{issue-number}-{short-name}.md`
3. Review existing components and patterns in the codebase

View File

@@ -1,7 +1,7 @@
# Infrastructure & DevOps Guide
## Before Starting
1. Check assigned issue: `~/.config/mosaic/rails/git/issue-list.sh -a @me`
1. Check assigned issue: `~/.config/mosaic/tools/git/issue-list.sh -a @me`
2. Create scratchpad: `docs/scratchpads/{issue-number}-{short-name}.md`
3. Review existing infrastructure configuration
@@ -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,65 +109,96 @@ readinessProbe:
### Pipeline Security
- Use secrets management (not hardcoded)
- Pin action/image versions
- 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-<shortsha>` and `v{base-version}-rc.{build}`.
2. Use mutable environment tags only as pointers: `testing`, optional `staging`, and `prod`.
3. Deploy by immutable digest, not by mutable tag alone.
4. Promote the exact tested digest between environments (no rebuild between testing and prod).
5. Do not use `latest` or `dev` as deployment references.
Blue-green is the default strategy for production promotion.
Canary is allowed only when automated SLO/error-rate gates and auto-rollback triggers are implemented.
### Post-Deploy Validation (REQUIRED)
1. Health endpoints return expected status.
2. Critical smoke tests pass in target environment.
3. Running version and digest match the promoted release candidate.
4. Observability signals (errors/latency) are within expected thresholds.
### Rollback Rule
If post-deploy validation fails:
1. Execute rollback/redeploy-safe path immediately.
2. Mark deployment as blocked in `docs/TASKS.md`.
3. Record failure evidence and next remediation step in scratchpad and release notes.
### Registry Retention and Cleanup
Cleanup MUST be automated.
- Keep all final release tags (`vX.Y.Z`) indefinitely.
- Keep active environment digests (`prod`, `testing`, and active blue/green slots).
- Keep recent RC tags (`vX.Y.Z-rc.N`) based on retention window.
- Remove stale `sha-*` and RC tags outside retention window if they are not actively deployed.
## Monitoring & Logging
- 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 `~/.config/mosaic/tools/portainer/stack-redeploy.sh`, then verify with `stack-status.sh`.
- **Coolify**: Deploy via `~/.config/mosaic/tools/coolify/deploy.sh -u <uuid>`, then verify with `service-status.sh`.
- **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.
### Coolify API Operations
```bash
# List projects and services
~/.config/mosaic/tools/coolify/project-list.sh
~/.config/mosaic/tools/coolify/service-list.sh
# Check service status
~/.config/mosaic/tools/coolify/service-status.sh -u <uuid>
# Set env vars (takes effect on next deploy)
~/.config/mosaic/tools/coolify/env-set.sh -u <uuid> -k KEY -v VALUE
# Deploy
~/.config/mosaic/tools/coolify/deploy.sh -u <uuid>
```
**Known Coolify Limitations:**
- FQDN updates on compose sub-apps not supported via API (DB workaround required)
- Compose files must be base64-encoded in `docker_compose_raw` field
- Magic variables (`SERVICE_FQDN_*`) require list-style env syntax, not dict-style
- Rate limit: 200 requests per interval
### Stack Health Check
Verify all infrastructure services are reachable:
```bash
~/.config/mosaic/tools/health/stack-health.sh
```
### Image Tagging and Promotion (Hard Rule)
For containerized deployments:
1. Build immutable image tags: `sha-<shortsha>` and `v{base-version}-rc.{build}`.
2. Use mutable environment tags only as pointers: `testing`, optional `staging`, and `prod`.
3. Deploy by immutable digest, not by mutable tag alone.
4. Promote the exact tested digest between environments (no rebuild between testing and prod).
5. Do not use `latest` or `dev` as deployment references.
Blue-green is the default strategy for production promotion.
Canary is allowed only when automated SLO/error-rate gates and auto-rollback triggers are implemented.
### Post-Deploy Validation (REQUIRED)
1. Health endpoints return expected status.
2. Critical smoke tests pass in target environment.
3. Running version and digest match the promoted release candidate.
4. Observability signals (errors/latency) are within expected thresholds.
### Rollback Rule
If post-deploy validation fails:
1. Execute rollback/redeploy-safe path immediately.
2. Mark deployment as blocked in `docs/TASKS.md`.
3. Record failure evidence and next remediation step in scratchpad and release notes.
### Registry Retention and Cleanup
Cleanup MUST be automated.
- Keep all final release tags (`vX.Y.Z`) indefinitely.
- Keep active environment digests (`prod`, `testing`, and active blue/green slots).
- Keep recent RC tags (`vX.Y.Z-rc.N`) based on retention window.
- Remove stale `sha-*` and RC tags outside retention window if they are not actively deployed.
## Monitoring & Logging
### Logging Standards
- Use structured logging (JSON)

View File

@@ -2,7 +2,7 @@
## Before Starting
1. Check assigned issue: `~/.config/mosaic/rails/git/issue-list.sh -a @me`
1. Check assigned issue: `~/.config/mosaic/tools/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.

View File

@@ -870,7 +870,7 @@ Required sequence:
1. Merge PR to `main` (squash) via Mosaic wrapper.
2. Monitor CI to terminal status:
```bash
~/.config/mosaic/rails/git/pr-ci-wait.sh -n <PR_NUMBER>
~/.config/mosaic/tools/git/pr-ci-wait.sh -n <PR_NUMBER>
```
3. Require green status before claiming completion.
4. If CI fails, create remediation task(s) and continue until green.
@@ -885,8 +885,8 @@ Woodpecker note:
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
~/.config/mosaic/tools/git/ci-queue-wait.sh --purpose push -B main
~/.config/mosaic/tools/git/ci-queue-wait.sh --purpose merge -B main
```
Behavior:

View File

@@ -25,8 +25,8 @@ First response MUST declare mode before tool calls or implementation steps:
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`).
3. Detect provider first via `~/.config/mosaic/tools/git/detect-platform.sh`.
4. For issue/PR/milestone operations, use Mosaic wrappers first (`~/.config/mosaic/tools/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`).
@@ -73,11 +73,11 @@ For implementation work, you MUST run this cycle in order:
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`.
8. `pre-push queue guard` - before pushing, wait for running/queued project pipelines to clear: `~/.config/mosaic/tools/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).
11. `pre-merge queue guard` - before merging PR, wait for running/queued project pipelines to clear: `~/.config/mosaic/tools/git/ci-queue-wait.sh --purpose merge`.
12. `CI/pipeline verification` - wait for terminal CI status and require green before completion (`~/.config/mosaic/tools/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.
@@ -85,10 +85,10 @@ For implementation work, you MUST run this cycle in order:
### Post-PR Hard Gate (Execute Sequentially, No Exceptions)
1. `~/.config/mosaic/rails/git/ci-queue-wait.sh --purpose merge -B main`
2. `~/.config/mosaic/rails/git/pr-merge.sh -n <PR_NUMBER> -m squash`
3. `~/.config/mosaic/rails/git/pr-ci-wait.sh -n <PR_NUMBER>`
4. `~/.config/mosaic/rails/git/issue-close.sh -i <ISSUE_NUMBER>` (or close internal `docs/TASKS.md` ref when no provider exists)
1. `~/.config/mosaic/tools/git/ci-queue-wait.sh --purpose merge -B main`
2. `~/.config/mosaic/tools/git/pr-merge.sh -n <PR_NUMBER> -m squash`
3. `~/.config/mosaic/tools/git/pr-ci-wait.sh -n <PR_NUMBER>`
4. `~/.config/mosaic/tools/git/issue-close.sh -i <ISSUE_NUMBER>` (or close internal `docs/TASKS.md` ref when no provider exists)
5. If any step fails: set status `blocked`, report the exact failed wrapper command, and stop.
6. Do not ask the human to perform routine merge/close operations.
7. Do not claim completion before step 4 succeeds.

View File

@@ -272,7 +272,7 @@ Provider options:
1. Gitea (preferred when available) via Mosaic helper:
```bash
~/.config/mosaic/rails/git/issue-create.sh \
~/.config/mosaic/tools/git/issue-create.sh \
-t "Phase 1: Critical Security Fixes" \
-b "$(cat <<'EOF'
## Findings
@@ -412,15 +412,15 @@ git push
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`
`~/.config/mosaic/tools/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`
`~/.config/mosaic/tools/git/pr-create.sh ... -B main`
- Merge via wrapper:
`~/.config/mosaic/rails/git/pr-merge.sh -n {PR_NUMBER} -m squash`
`~/.config/mosaic/tools/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}`
`~/.config/mosaic/tools/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}`
`~/.config/mosaic/tools/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.
@@ -463,10 +463,10 @@ Run review when the worker's result includes code changes (commits). Skip for ta
cd {project_path}
# Code quality review
~/.config/mosaic/rails/codex/codex-code-review.sh -b {base_branch} -o /tmp/review-{task_id}.json
~/.config/mosaic/tools/codex/codex-code-review.sh -b {base_branch} -o /tmp/review-{task_id}.json
# Security review
~/.config/mosaic/rails/codex/codex-security-review.sh -b {base_branch} -o /tmp/security-{task_id}.json
~/.config/mosaic/tools/codex/codex-security-review.sh -b {base_branch} -o /tmp/security-{task_id}.json
```
### Step 2: Parse Review Results
@@ -599,19 +599,19 @@ Construct this from the task row and pass to worker via Task tool:
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`
10. Before push, run queue guard: `~/.config/mosaic/tools/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 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}`
- `~/.config/mosaic/tools/git/issue-view.sh -i {N}`
- `~/.config/mosaic/tools/git/pr-create.sh -t "Title" -b "Desc" -B main`
- `~/.config/mosaic/tools/git/ci-queue-wait.sh --purpose push|merge -B main`
- `~/.config/mosaic/tools/git/pr-merge.sh -n {PR_NUMBER} -m squash`
- `~/.config/mosaic/tools/git/pr-ci-wait.sh -n {PR_NUMBER}`
- `~/.config/mosaic/tools/git/issue-close.sh -i {N}`
Standard git commands (pull, commit, push, checkout) are fine.
@@ -1035,7 +1035,7 @@ When all tasks in `docs/TASKS.md` are `done` (or triaged as `deferred`), you MUS
5. **Close milestone in provider**:
- Gitea/GitHub:
```bash
~/.config/mosaic/rails/git/milestone-close.sh -t "{milestone-name}"
~/.config/mosaic/tools/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.