-
Notifications
You must be signed in to change notification settings - Fork 0
327 lines (276 loc) · 10.9 KB
/
Copy pathci.yml
File metadata and controls
327 lines (276 loc) · 10.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
# Minimum-privilege default for every job in this workflow. Individual
# jobs can narrow further but cannot escalate.
permissions:
contents: read
jobs:
free-tier-compliance:
name: free-tier compliance
runs-on: ubuntu-latest
timeout-minutes: 2
steps:
- uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version-file: ".nvmrc"
# Node-only check, zero deps. PR-blocking gate that enforces the
# zero-cost-by-construction guarantee declared in COST_SAFETY.md
# and ADR-0046: no paid-tier Vercel plans, no billable SDKs, no
# leaked secrets in example files.
- name: Run free-tier compliance check
run: node scripts/check-free-tier-compliance.mjs
ci:
name: lint / typecheck / test / build
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v6
- name: Install pnpm
uses: pnpm/action-setup@v6
with:
version: 9.15.0
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version-file: ".nvmrc"
cache: "pnpm"
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Generate Prisma clients
run: |
pnpm --filter collab exec prisma generate
pnpm --filter knowledge exec prisma generate
- name: Lint
run: pnpm lint
- name: Typecheck
run: pnpm typecheck
- name: Test
run: pnpm test
- name: Build
run: pnpm build
- name: Audit dependencies (advisory)
run: pnpm audit --prod --audit-level moderate || true
continue-on-error: true
doc-drift-detect:
name: doc drift detect
runs-on: ubuntu-latest
timeout-minutes: 5
# PR-blocking guard against prose drift (ADR-0054). Asserts that
# embedded numerics (ADR count, Vitest case count, Boardly route
# count, Playwright test count) and version banners (Status (as
# of vX.Y.Z)) in markdown / TSX prose match what the actual
# codebase reports. Closes the prose-coherence gap surfaced by
# the v2-methodology hiring sim Run #4 + the manual drift audit
# ratchet (Session 262 PR #42).
steps:
- uses: actions/checkout@v6
with:
# Need git history so `git describe --tags --abbrev=0` resolves
# the latest tag in CI (default checkout depth is 1).
fetch-depth: 0
fetch-tags: true
- name: Install pnpm
uses: pnpm/action-setup@v6
with:
version: 9.15.0
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version-file: ".nvmrc"
cache: "pnpm"
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Generate Prisma clients
# Vitest invocation inside the script needs the Prisma clients
# available (the `EXPECTED ↔ schema.prisma` test imports the
# generated client).
run: |
pnpm --filter collab exec prisma generate
pnpm --filter knowledge exec prisma generate
- name: Run doc-drift-detect
run: node scripts/check-doc-drift.mjs
- name: Run ADR ref validator (axis 3, ADR-0057)
# Asserts every "ADR-NNNN" reference across docs / code resolves
# to an existing ADR file. Catches typos and dangling refs to
# ADRs that were never created or were renamed.
run: node scripts/check-adr-refs.mjs
- name: Run ADR-claim ↔ implementation cross-check (axis 7, ADR-0057)
# Asserts every load-bearing ADR claim (rate limits, env flags,
# endpoint paths, threshold constants) declared in
# `docs/adr/_claims.json` matches the actual codebase. Catches
# the "ADR says X, code does Y" drift class.
run: node scripts/check-adr-claims.mjs
- name: Run CSP coherence gate (ADR-0068 § Finding C)
# Asserts that every load-bearing CSP directive present in
# `apps/collab/next.config.ts` (`'unsafe-inline'`, `'unsafe-eval'`,
# `'strict-dynamic'`, `'wasm-unsafe-eval'`) is also mentioned in
# the README "Security headers" bullet. Closes the Run #5
# hiring-sim drift class where `'unsafe-eval'` was added to the
# live CSP but the README description never disclosed it.
run: node scripts/check-csp-coherence.mjs
knowledge-integration:
name: knowlex integration (pgvector)
runs-on: ubuntu-latest
timeout-minutes: 10
services:
postgres:
image: pgvector/pgvector:pg16
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U postgres"
--health-interval 5s
--health-timeout 3s
--health-retries 10
steps:
- uses: actions/checkout@v6
- name: Install pnpm
uses: pnpm/action-setup@v6
with:
version: 9.15.0
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version-file: ".nvmrc"
cache: "pnpm"
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Generate Knowlex Prisma client
run: pnpm --filter knowledge exec prisma generate
- name: Create knowlex database + pgvector extension
env:
PGPASSWORD: postgres
run: |
psql -h localhost -U postgres -c 'CREATE DATABASE knowlex;'
psql -h localhost -U postgres -d knowlex -c 'CREATE EXTENSION vector;'
- name: Apply migrations
env:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/knowlex
DIRECT_DATABASE_URL: postgresql://postgres:postgres@localhost:5432/knowlex
run: pnpm --filter knowledge exec prisma migrate deploy
# ADR-0051 § Drift detection deferred → option 2 (v0.5.3 ship).
#
# Background: PR #27 attempted `prisma migrate diff --from-
# migrations --to-schema --exit-code` against a shadow DB but
# surfaced a structural false positive — Prisma's declarative
# schema language has no syntax for HNSW indexes (the v0.4.x
# `20260424_hnsw` migration creates `... USING hnsw` via raw
# SQL), so `migrate diff` always reported `[-] Removed index
# on (embedding)` regardless of any schema change.
#
# This step replaces that approach with a Node script that
# introspects the post-migration DB via pg_catalog and asserts
# a known-good shape (tables, columns, indexes-by-access-method,
# extensions) declared in `prisma/expected-shape.json`. Because
# pg_catalog reports the actual physical state of the DB, HNSW
# indexes appear correctly with `amname = 'hnsw'`, sidestepping
# Prisma's representation gap entirely.
#
# Authoring contract: when a future migration adds a table /
# column / index / extension, hand-edit the manifest in the
# same PR. The script is the gate that enforces schema +
# migration + manifest stay in sync.
#
# Exit codes:
# 0 — DB shape matches manifest
# 2 — drift detected (one or more expected items missing)
# 1 — connection or query error
- name: Verify schema shape (drift detection v2 — pg_catalog assertion)
env:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/knowlex
working-directory: apps/knowledge
run: node scripts/verify-schema-shape.mjs
- name: Run integration tests
env:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/knowlex
DIRECT_DATABASE_URL: postgresql://postgres:postgres@localhost:5432/knowlex
run: pnpm --filter knowledge test:integration
a11y-knowledge:
name: knowlex a11y gate (WCAG 2.1 AA)
runs-on: ubuntu-latest
timeout-minutes: 10
# Same pgvector service as the integration job — /kb renders
# CorpusClient which calls /api/kb/stats, and that query set
# needs a live Embedding table.
services:
postgres:
image: pgvector/pgvector:pg16
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U postgres"
--health-interval 5s
--health-timeout 3s
--health-retries 10
steps:
- uses: actions/checkout@v6
- name: Install pnpm
uses: pnpm/action-setup@v6
with:
version: 9.15.0
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version-file: ".nvmrc"
cache: "pnpm"
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Generate Knowlex Prisma client
run: pnpm --filter knowledge exec prisma generate
- name: Create knowlex database + pgvector extension
env:
PGPASSWORD: postgres
run: |
psql -h localhost -U postgres -c 'CREATE DATABASE knowlex;'
psql -h localhost -U postgres -d knowlex -c 'CREATE EXTENSION vector;'
- name: Apply migrations
env:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/knowlex
DIRECT_DATABASE_URL: postgresql://postgres:postgres@localhost:5432/knowlex
run: pnpm --filter knowledge exec prisma migrate deploy
- name: Cache Playwright browsers
id: playwright-cache
uses: actions/cache@v4
with:
path: ~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-playwright-
- name: Install Playwright browser
run: |
if [ "${{ steps.playwright-cache.outputs.cache-hit }}" != "true" ]; then
pnpm --filter knowledge exec playwright install --with-deps chromium
else
pnpm --filter knowledge exec playwright install-deps chromium
fi
# E2E_BASE_URL left unset so playwright.config.ts auto-spins up
# `pnpm dev` on :3001. The a11y spec itself needs no secrets —
# /, /kb, /docs/api are all public pages — and the Gemini key is
# optional at load time (ingest / ask calls aren't exercised).
- name: Run Knowlex a11y gate
env:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/knowlex
DIRECT_DATABASE_URL: postgresql://postgres:postgres@localhost:5432/knowlex
run: pnpm --filter knowledge exec playwright test tests/smoke/a11y.spec.ts
- name: Upload Playwright report on failure
if: failure()
uses: actions/upload-artifact@v7
with:
name: knowlex-a11y-report
path: apps/knowledge/playwright-report/
retention-days: 7