Skip to content

Commit 6cdb46d

Browse files
gmoonclaude
andcommitted
Add blog, CI pipeline, testing, and linting infrastructure
Blog: - Add /blog listing and /blog/<slug> post pages with inline markdown renderer - First post: "Context Engineering Needs a Knowledge Layer" - Pre-render blog routes at build time for SEO (title, meta, OG tags, canonical, noscript fallback) - Add Blog nav link to header Testing: - Set up vitest with v8 coverage provider - Unit tests for route parsing, blog data integrity, and pre-render output (29 tests) - Coverage thresholds with thresholdAutoUpdate ratchet Linting & formatting: - ESLint 9 flat config with typescript-eslint and react-hooks - Prettier (no semis, single quotes, 120 width) - Fix pre-existing lint error in ReaderPage (setState in effect) CI/CD: - Add CI workflow: format, lint, typecheck, build, test, lattice validation - Gate deploy workflow behind CI success - Consolidate GitHub Pages deploy into CI workflow with job dependencies - Add Makefile with ci target mirroring GitHub Actions pipeline Lattice: - Add CICD requirements (REQ-CICD-001 through REQ-CICD-006) - Add future web requirements (REQ-WEB-004 through REQ-WEB-008) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 6689c88 commit 6cdb46d

34 files changed

Lines changed: 4987 additions & 497 deletions

.github/workflows/ci.yml

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
ci:
14+
name: Format / Lint / Typecheck / Test
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- name: Checkout
19+
uses: actions/checkout@v4
20+
21+
- name: Setup Node.js
22+
uses: actions/setup-node@v4
23+
with:
24+
node-version: 22
25+
cache: npm
26+
27+
- name: Install dependencies
28+
run: npm ci
29+
30+
- name: Check formatting
31+
run: npm run format:check
32+
33+
- name: Lint
34+
run: npm run lint
35+
36+
- name: Typecheck
37+
run: npx tsc --noEmit
38+
39+
- name: Build
40+
run: npm run build
41+
42+
- name: Test with coverage
43+
run: npm test
44+
45+
validate-lattice:
46+
name: Validate Lattice Structure
47+
runs-on: ubuntu-latest
48+
49+
steps:
50+
- name: Checkout
51+
uses: actions/checkout@v4
52+
53+
- name: Validate YAML syntax
54+
run: |
55+
npm install -g yaml-lint
56+
find .lattice -name "*.yaml" -exec yaml-lint {} \;
57+
58+
- name: Check required fields
59+
run: |
60+
for file in $(find .lattice/requirements .lattice/theses .lattice/sources -name "*.yaml" 2>/dev/null); do
61+
echo "Checking $file..."
62+
63+
if ! grep -q "^id:" "$file"; then
64+
echo "ERROR: $file missing 'id' field"
65+
exit 1
66+
fi
67+
68+
if ! grep -q "^title:" "$file"; then
69+
echo "ERROR: $file missing 'title' field"
70+
exit 1
71+
fi
72+
73+
if ! grep -q "^status:" "$file"; then
74+
echo "ERROR: $file missing 'status' field"
75+
exit 1
76+
fi
77+
done
78+
79+
echo "All lattice nodes have required fields"
80+
81+
lattice-lint:
82+
name: Lattice Lint
83+
runs-on: ubuntu-latest
84+
85+
steps:
86+
- name: Checkout
87+
uses: actions/checkout@v4
88+
89+
- name: Install lattice
90+
run: curl -fsSL https://raw.githubusercontent.com/forkzero/lattice/main/install.sh | sh
91+
92+
- name: Run lattice lint
93+
run: lattice lint
94+
95+
- name: Smoke test - list nodes
96+
run: |
97+
lattice list requirements
98+
lattice list theses
99+
lattice list sources
100+
101+
pages:
102+
name: Deploy Lattice to GitHub Pages
103+
runs-on: ubuntu-latest
104+
needs: [ci, validate-lattice, lattice-lint]
105+
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
106+
107+
concurrency:
108+
group: pages
109+
cancel-in-progress: false
110+
111+
permissions:
112+
contents: read
113+
pages: write
114+
id-token: write
115+
116+
environment:
117+
name: github-pages
118+
url: ${{ steps.deployment.outputs.page_url }}
119+
120+
steps:
121+
- name: Checkout
122+
uses: actions/checkout@v4
123+
124+
- name: Install lattice
125+
run: curl -fsSL https://raw.githubusercontent.com/forkzero/lattice/main/install.sh | sh
126+
127+
- name: Export lattice data
128+
run: lattice export --format pages --output _site
129+
130+
- name: Upload Pages artifact
131+
uses: actions/upload-pages-artifact@v3
132+
with:
133+
path: _site
134+
135+
- name: Deploy to GitHub Pages
136+
id: deployment
137+
uses: actions/deploy-pages@v4

.github/workflows/deploy.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
name: Deploy
22

33
on:
4-
push:
4+
workflow_run:
5+
workflows: [CI]
6+
types: [completed]
57
branches: [main]
68

79
permissions:
@@ -11,6 +13,7 @@ jobs:
1113
deploy:
1214
name: Build & Deploy
1315
runs-on: ubuntu-latest
16+
if: ${{ github.event.workflow_run.conclusion == 'success' }}
1417

1518
steps:
1619
- name: Checkout

.github/workflows/pages.yml

Lines changed: 0 additions & 42 deletions
This file was deleted.

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
node_modules
22
dist
3+
coverage
4+
*.tsbuildinfo
35
*.local
46
.env
57
.env.*
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
id: REQ-CICD-001
2+
type: requirement
3+
title: Automated CI on push and pull requests
4+
body: 'All pushes and pull requests to main trigger a CI workflow in GitHub Actions. The pipeline runs in order: (1) npm ci, (2) Prettier format check, (3) ESLint, (4) TypeScript typecheck, (5) Vite build with pre-render, (6) vitest with coverage thresholds. Any failure blocks the workflow. Each step is a separate named action for clear failure attribution.'
5+
status: active
6+
version: 1.0.0
7+
created_at: 2026-02-10T05:00:00.000000+00:00
8+
created_by: agent:claude-2026-02-10
9+
requested_by: George Moon <george.moon@gmail.com>
10+
priority: P0
11+
category: CICD
12+
tags:
13+
- ci
14+
- github-actions
15+
- automation
16+
resolution:
17+
status: verified
18+
resolved_at: 2026-02-10T05:00:00.000000+00:00
19+
resolved_by: agent:claude-2026-02-10
20+
edges:
21+
derives_from:
22+
- target: THX-AI-FIRST-TOOLING
23+
version: 1.0.0
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
id: REQ-CICD-002
2+
type: requirement
3+
title: Code coverage with non-regression thresholds
4+
body: 'CI measures code coverage using vitest with the v8 provider. Thresholds are configured in vitest.config.ts for statements, branches, functions, and lines. thresholdAutoUpdate is enabled so thresholds ratchet up automatically when coverage improves — they can never decrease. CI fails if coverage drops below any threshold. Coverage is scoped to src/**/*.{ts,tsx} excluding main.tsx and test files. Reports are generated in text and lcov formats.'
5+
status: active
6+
version: 1.0.0
7+
created_at: 2026-02-10T05:00:00.000000+00:00
8+
created_by: agent:claude-2026-02-10
9+
requested_by: George Moon <george.moon@gmail.com>
10+
priority: P1
11+
category: CICD
12+
tags:
13+
- coverage
14+
- testing
15+
- quality
16+
resolution:
17+
status: verified
18+
resolved_at: 2026-02-10T05:00:00.000000+00:00
19+
resolved_by: agent:claude-2026-02-10
20+
edges:
21+
derives_from:
22+
- target: THX-AI-FIRST-TOOLING
23+
version: 1.0.0
24+
depends_on:
25+
- target: REQ-CICD-001
26+
version: 1.0.0
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
id: REQ-CICD-003
2+
type: requirement
3+
title: Lattice validation in CI
4+
body: 'CI validates the .lattice/ directory on every push and PR. Three checks run: (1) YAML syntax validation on all .lattice/*.yaml files using yaml-lint, (2) required field check — every node must have id, title, and status fields, (3) lattice lint using the lattice CLI binary installed from the forkzero/lattice release. Additionally, smoke tests run lattice list commands to verify the lattice is loadable. These checks run as a separate parallel job so failures are clearly attributed to lattice issues, not code issues.'
5+
status: active
6+
version: 1.0.0
7+
created_at: 2026-02-10T05:00:00.000000+00:00
8+
created_by: agent:claude-2026-02-10
9+
requested_by: George Moon <george.moon@gmail.com>
10+
priority: P1
11+
category: CICD
12+
tags:
13+
- lattice
14+
- validation
15+
- yaml
16+
resolution:
17+
status: verified
18+
resolved_at: 2026-02-10T05:00:00.000000+00:00
19+
resolved_by: agent:claude-2026-02-10
20+
edges:
21+
derives_from:
22+
- target: THX-AI-FIRST-TOOLING
23+
version: 1.0.0
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
id: REQ-CICD-004
2+
type: requirement
3+
title: Gated deploy to S3 and CloudFront
4+
body: 'Production deployment to S3 (forkzero-web-prod) and CloudFront invalidation only triggers after the CI workflow succeeds on main. Uses workflow_run trigger with conclusion check. The deploy workflow builds the site independently (npm ci, npm run build) then syncs dist/ to S3 with --delete flag and creates a CloudFront invalidation for all paths. AWS credentials are stored as GitHub secrets. If CI fails for any reason — lint, format, typecheck, tests, coverage, or lattice validation — no deploy occurs.'
5+
status: active
6+
version: 1.0.0
7+
created_at: 2026-02-10T05:00:00.000000+00:00
8+
created_by: agent:claude-2026-02-10
9+
requested_by: George Moon <george.moon@gmail.com>
10+
priority: P0
11+
category: CICD
12+
tags:
13+
- deploy
14+
- s3
15+
- cloudfront
16+
- gating
17+
resolution:
18+
status: verified
19+
resolved_at: 2026-02-10T05:00:00.000000+00:00
20+
resolved_by: agent:claude-2026-02-10
21+
edges:
22+
derives_from:
23+
- target: THX-AI-FIRST-TOOLING
24+
version: 1.0.0
25+
depends_on:
26+
- target: REQ-CICD-001
27+
version: 1.0.0
28+
- target: REQ-CICD-003
29+
version: 1.0.0
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
id: REQ-CICD-005
2+
type: requirement
3+
title: GitHub Pages deployment for lattice data
4+
body: 'On push to main, after CI and lattice validation pass, the pipeline exports lattice data to GitHub Pages using lattice export --format pages. The pages job depends on the ci, validate-lattice, and lattice-lint jobs. Uses actions/upload-pages-artifact and actions/deploy-pages for deployment. The exported data is consumed by the lattice reader at forkzero.ai/reader.'
5+
status: active
6+
version: 1.0.0
7+
created_at: 2026-02-10T05:00:00.000000+00:00
8+
created_by: agent:claude-2026-02-10
9+
requested_by: George Moon <george.moon@gmail.com>
10+
priority: P1
11+
category: CICD
12+
tags:
13+
- github-pages
14+
- lattice
15+
- deployment
16+
resolution:
17+
status: verified
18+
resolved_at: 2026-02-10T05:00:00.000000+00:00
19+
resolved_by: agent:claude-2026-02-10
20+
edges:
21+
derives_from:
22+
- target: THX-AI-FIRST-TOOLING
23+
version: 1.0.0
24+
depends_on:
25+
- target: REQ-CICD-001
26+
version: 1.0.0
27+
- target: REQ-CICD-003
28+
version: 1.0.0
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
id: REQ-CICD-006
2+
type: requirement
3+
title: Local CI via Makefile
4+
body: 'A Makefile provides the same quality gates locally that CI enforces remotely. The make ci target runs: install, format check, lint, typecheck, build, and test with coverage — in that order. Individual targets (make format, make lint, make test, etc.) can be run independently. make clean removes dist/ and node_modules/. Developers run make ci before pushing to catch issues before CI.'
5+
status: active
6+
version: 1.0.0
7+
created_at: 2026-02-10T05:00:00.000000+00:00
8+
created_by: agent:claude-2026-02-10
9+
requested_by: George Moon <george.moon@gmail.com>
10+
priority: P1
11+
category: CICD
12+
tags:
13+
- makefile
14+
- developer-workflow
15+
- local-ci
16+
resolution:
17+
status: verified
18+
resolved_at: 2026-02-10T05:00:00.000000+00:00
19+
resolved_by: agent:claude-2026-02-10
20+
edges:
21+
derives_from:
22+
- target: THX-AI-FIRST-TOOLING
23+
version: 1.0.0
24+
depends_on:
25+
- target: REQ-CICD-001
26+
version: 1.0.0

0 commit comments

Comments
 (0)