Files
stack/.woodpecker/ci.yml
Jason Woltje 244290d64d feat(framework): P6 docs + compliance matrix + resident-budget CI (#606)
R9 + R10 of the Constitution alpha (in-repo deliverables):

- framework/CONTRIBUTING.md: layer model, operator-hygiene/PII prohibition,
  dedup rule, resident budget, dual-installer parity rule, adding-a-harness,
  re-contamination rule, harness x gate compliance matrix (hook-parity gap
  marked as tracked-v2), known-limitations (DESIGN §9 residuals), PR checklist.
- check-resident-budget.sh: line-count ceiling over framework-owned resident
  files (CONSTITUTION + AGENTS + each runtime/*/RUNTIME.md), with --self-test;
  replaces the crude inline ci.yml loop. Wired blocking in .woodpecker/ci.yml.

Composer unit test (R9) already runs via pnpm test; verify-sanitized.sh (P1)
already wired. Sanitization + budget + prettier all green.

Remaining for the mission close: aiguide reconcile (separate repo) + the alpha
tag (Lead cuts after full DoD §8 green + all phases merged; P5 #605 pending).

Refs #606, #542

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EsgTQzV5YUGk1JtCLP4B83
2026-06-21 21:18:40 -05:00

98 lines
2.9 KiB
YAML

variables:
- &node_image 'node:22-alpine'
- &enable_pnpm 'corepack enable'
when:
- event: [push, pull_request, manual]
# Turbo remote cache (turbo.mosaicstack.dev) is configured via Woodpecker
# repository-level environment variables (TURBO_API, TURBO_TEAM, TURBO_TOKEN).
# This avoids from_secret which is blocked on pull_request events.
# If the env vars aren't set, turbo falls back to local cache only.
steps:
install:
image: *node_image
commands:
- corepack enable
- apk add --no-cache python3 make g++
- pnpm install --frozen-lockfile
# Blocking gate: public framework package must contain no operator-specific
# personal data or private $HOME defaults. Runs early (no node_modules needed).
sanitization:
image: *node_image
commands:
- apk add --no-cache bash
- bash packages/mosaic/framework/tools/quality/scripts/verify-sanitized.sh
# Resident line-count ceiling over framework-owned resident files
# (Constitution + dispatcher + each RUNTIME.md slice). See DESIGN §7 / R9.
- bash packages/mosaic/framework/tools/quality/scripts/check-resident-budget.sh --self-test
- bash packages/mosaic/framework/tools/quality/scripts/check-resident-budget.sh
typecheck:
image: *node_image
commands:
- *enable_pnpm
- pnpm typecheck
depends_on:
- install
- sanitization
# lint, format, and test are independent — run in parallel after typecheck
lint:
image: *node_image
commands:
- *enable_pnpm
- pnpm lint
depends_on:
- typecheck
format:
image: *node_image
commands:
- *enable_pnpm
- pnpm format:check
depends_on:
- typecheck
test:
image: *node_image
environment:
# Avoid the namespace-level Woodpecker DB service named "postgres".
# The Kubernetes backend exposes service containers by step name.
DATABASE_URL: postgresql://mosaic:mosaic@ci-postgres:5432/mosaic
commands:
- *enable_pnpm
# Install postgresql-client for pg_isready
- apk add --no-cache postgresql-client
# Wait up to 60s for CI postgres to be ready; fail fast if it never comes up.
- |
ready=0
for i in $(seq 1 60); do
if pg_isready -h ci-postgres -p 5432 -U mosaic; then
ready=1
break
fi
echo "Waiting for ci-postgres ($i/60)..."
sleep 1
done
if [ "$ready" -ne 1 ]; then
echo "ci-postgres did not become ready" >&2
exit 1
fi
# Run migrations (DATABASE_URL is set in environment above)
- pnpm --filter @mosaicstack/db run db:migrate
# Run all tests
- pnpm test
depends_on:
- typecheck
services:
ci-postgres:
image: pgvector/pgvector:pg17
environment:
POSTGRES_USER: mosaic
POSTGRES_PASSWORD: mosaic
POSTGRES_DB: mosaic