# CASAN PLAN 05 — CI/CD & Release Gate > Status 2026-07-06: **CI gate MVP implemented + locally syntax/filter verified**. > A reusable local/CI gate script now exists, and a Gitea Actions workflow is > wired to run it on `main` push/PR. Package publishing/release automation is > still planned. ## Delivered | Capability | Where | Verification | |---|---|---| | One-command harness CI gate | `packages/casan-harness/scripts/bash/ci-harness-gate.sh` | `bash -n`; local suites are callable in safe order | | Safe test order | `run-casan4` runs first because it rewrites `.specify/logs`; hardening suites run after | script order | | Per-suite timeout | `CASAN_CI_STEP_TIMEOUT_SEC` protects CI from hung model/security subprocesses | full gate attempt exposed a long A6 run; timeout wrapper added | | Filtered local verification | `CASAN_CI_SUITE_FILTER='phase2-sourcegen|phase10-traceability'` | `CI_GATE_SUMMARY PASS=2 FAIL=0 SKIP=15` | | Source-gen gate included | `phase2-sourcegen-tests.sh` included | sourcegen 10/0 | | Traceability gate included | `phase10-traceability-tests.sh` included | traceability 3/0 | | Frontend runtime tests included | `npm test -w frontend` when npm is present | frontend Vitest path | | Optional Docker local-prod lab | `CASAN_CI_RUN_INFRA_LAB=1` runs `phase-prod-infra-lab-tests.sh` only when Docker Compose is available | skip-aware by default | | Gitea Actions workflow | `.gitea/workflows/harness-ci.yml` | workflow calls `ci-harness-gate.sh` | ## Gate contents Required gate: - `run-casan4-harness-tests.sh` - `adversarial-harness-tests.sh` - `phase1-track-a-tests.sh` - `phase2-track-c-tests.sh` - `phase2-sourcegen-tests.sh` - `phase3-evidence-pack-tests.sh` - `phase3-model-router-tests.sh` - `phase-h5-approval-tests.sh` - `phase-h5-infra-tests.sh` - `phase-h6-agentops-tests.sh` - `phase-c7-incident-tests.sh` - `phase-h4-multilingual-tests.sh` - `phase-c6-sandbox-tests.sh` - `phase-h4-split-inject-tests.sh` - `phase10-traceability-tests.sh` - `npm test -w frontend` when npm is available Optional gate: - `phase-prod-infra-lab-tests.sh` when `CASAN_CI_RUN_INFRA_LAB=1` and Docker Compose is available. ## Remaining work | Priority | Work | Done when | |---|---|---| | P1 | Run the workflow on the real Gitea runner | Gitea run shows green `CASAN Harness CI` on `main` | | P2 | Investigate slow/hung A6 full-gate local run | `phase1-track-a-tests.sh` A6 completes under timeout consistently on Mac/runner | | P3 | Decide Docker availability on runner | `CASAN_CI_RUN_INFRA_LAB=1` is enabled only if runner mounts Docker safely | | P4 | Package/release automation | `npm pack` or release artifact for `fpt-casan-sdd-harness` is generated and versioned | | P5 | Backend full `npm test` unblock | Prisma/MySQL-vs-SQLite test-infra mismatch is resolved or split into a proper MySQL service job | | P6 | Branch protection | Merge requires green CI gate | ## Local commands ```bash cd "$(git rev-parse --show-toplevel)" # repo root (app promoted here) bash -n packages/casan-harness/scripts/bash/ci-harness-gate.sh CASAN_CI_RUN_FRONTEND=1 CASAN_CI_RUN_INFRA_LAB=0 bash packages/casan-harness/scripts/bash/ci-harness-gate.sh CASAN_CI_RUN_INFRA_LAB=1 bash packages/casan-harness/tests/phase-prod-infra-lab-tests.sh ``` ## Notes - `backend npm test` is not part of the required CI gate yet because the current repo has a known pre-existing mismatch: `schema.prisma` is MySQL-oriented but `backend/scripts/setup-sqlite.mjs` applies migrations to SQLite. - The workflow installs Node 20 inside the Gitea job if the runner image does not already provide `node`/`npm`.