From 2fb4292b5d7f5410685398c5e3b2d2e9176f0d17 Mon Sep 17 00:00:00 2001 From: Deep Kumar Singh Kushwah Date: Mon, 13 Jul 2026 12:12:37 +0530 Subject: [PATCH 1/2] =?UTF-8?q?ci:=20Gate=200=20pipeline=20=E2=80=94=20bui?= =?UTF-8?q?ld,=20typecheck,=20tests,=20eval=20gate,=20scorecard=20artifact?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Step 0.4 (TRACKER). ubuntu-latest, pnpm-cached, 15-min timeout, concurrency-cancelled. Scorecard uploaded on every run (pass or fail). Threshold ratchet rule documented in the workflow header: raising eval/thresholds.json is free, lowering requires PR-body justification. Full step sequence verified locally (frozen install, build, typecheck, 24 tests, eval gate OK). Co-Authored-By: Claude Fable 5 --- .github/workflows/ci.yml | 57 ++++++++++++++++++++++++++++++++++++++++ TRACKER.md | 6 ++--- 2 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..d97954d --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,57 @@ +# CodeRadar CI — the Gate 0 pipeline. +# +# Every PR must pass: build (strict TS), typecheck, unit tests, and the eval +# gate (eval/thresholds.json). The scorecard is uploaded as an artifact on +# every run, pass or fail, so regressions are inspectable. +# +# Threshold ratchet rule (docs/testing-strategy.md): eval/thresholds.json +# values may be RAISED in any PR; LOWERING one requires a written +# justification in the PR body. Thresholds never loosen silently. + +name: CI + +on: + push: + branches: [main, development] + pull_request: + +concurrency: + group: ci-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + ci: + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - uses: actions/checkout@v4 + + - uses: pnpm/action-setup@v4 # reads the packageManager field + + - uses: actions/setup-node@v4 + with: + node-version: 22 + cache: pnpm + + - name: Install + run: pnpm install --frozen-lockfile + + - name: Build (strict TS) + run: pnpm build + + - name: Typecheck + run: pnpm typecheck + + - name: Unit tests + run: pnpm test + + - name: Eval gate + run: node eval/dist/run.js + + - name: Upload scorecard + if: always() + uses: actions/upload-artifact@v4 + with: + name: eval-scorecard + path: eval/scorecard.json + if-no-files-found: ignore diff --git a/TRACKER.md b/TRACKER.md index 74f1c6c..3149476 100644 --- a/TRACKER.md +++ b/TRACKER.md @@ -5,8 +5,8 @@ ## Status - **Current phase:** 0 — Foundations -- **Next step:** 0.4 — CI pipeline -- **Done:** 0.1, 0.2, 0.3 +- **Next step:** 1.1 — Endpoint resolution (constants, templates, patterns) +- **Done:** 0.1, 0.2, 0.3, 0.4 - **Gates passed:** none yet (Gate 0 completes with 0.4) ## What CodeRadar is @@ -76,7 +76,7 @@ The v0.1 schema is definition-only, which is *wrong* for C1 — fix before build - CLI: `scan` records commit SHA (via `git rev-parse`, `dirty` from `git status`). **Accept:** round-trip test (scan → save → load → deep-equal); schema drift test; `coderadar scan` output includes SHA. -### [ ] 0.4 CI pipeline +### [x] 0.4 CI pipeline **Failure modes:** D1, process **Build:** GitHub Actions workflow: install (pnpm cache) → build → typecheck → vitest unit tests → `pnpm eval` → upload scorecard as artifact. Threshold ratchet rule documented in the workflow file header (raising OK; lowering needs PR-body justification). **Accept:** CI green on a PR; a deliberately broken fixture in a test branch turns it red. **Gate 0 passes.** From c9f3059df7fc14a8b52df17719ad10883e8ee04a Mon Sep 17 00:00:00 2001 From: Deep Kumar Singh Kushwah Date: Mon, 13 Jul 2026 12:14:05 +0530 Subject: [PATCH 2/2] =?UTF-8?q?test:=20deliberately=20broken=20fixture=20?= =?UTF-8?q?=E2=80=94=20must=20turn=20CI=20red=20(throwaway)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- eval/fixtures/a4-generic-text/golden.json | 56 +++++++++++++++++++---- 1 file changed, 48 insertions(+), 8 deletions(-) diff --git a/eval/fixtures/a4-generic-text/golden.json b/eval/fixtures/a4-generic-text/golden.json index fdadced..a754d64 100644 --- a/eval/fixtures/a4-generic-text/golden.json +++ b/eval/fixtures/a4-generic-text/golden.json @@ -3,16 +3,56 @@ "note": "Generic text collisions: 'Save' appears in three components. A lone generic term must yield an honest ambiguous (with a disambiguation question), never a coin-flip ok. Adding one distinctive term must resolve it.", "expect": { "components": [ - { "name": "SettingsForm", "instances": 0 }, - { "name": "ProfileForm", "instances": 0 }, - { "name": "BillingForm", "instances": 0 } + { + "name": "SettingsForm", + "instances": 0 + }, + { + "name": "ProfileForm", + "instances": 0 + }, + { + "name": "BillingForm", + "instances": 0 + } ], "queries": [ - { "terms": ["Save"], "status": "ambiguous" }, - { "terms": ["Save", "Card number"], "status": "ok", "top": "BillingForm" }, - { "terms": ["Save", "Notification preferences"], "status": "ok", "top": "SettingsForm" }, - { "terms": ["Save", "Display name"], "status": "ok", "top": "ProfileForm" }, - { "terms": ["Purchase history"], "status": "declined" } + { + "terms": [ + "Save" + ], + "status": "ambiguous" + }, + { + "terms": [ + "Save", + "Card number" + ], + "status": "ok", + "top": "SettingsForm" + }, + { + "terms": [ + "Save", + "Notification preferences" + ], + "status": "ok", + "top": "SettingsForm" + }, + { + "terms": [ + "Save", + "Display name" + ], + "status": "ok", + "top": "ProfileForm" + }, + { + "terms": [ + "Purchase history" + ], + "status": "declined" + } ] } }