Files
josh 8ace3db7b4 docs(01-07): complete ci-workflow plan + Phase 1 closure metadata
- 01-07-ci-workflow-SUMMARY.md: structural enforcement map, Phase 2/8 handoff notes, threat T-01-08 mitigation confirmed
- 01-VALIDATION.md: per-task table populated (12/13 green, 01-05-T2 partial — checkpoint:human-verify awaiting north-star image curation); status flipped to executed
- ROADMAP.md: progress table marks Phase 1 as 7/7 with 01-05 partial annotation
- STATE.md: position advanced to Plan 7 of 7 complete; performance trend; Plan 01-05 Task 2 explicitly tracked as the only outstanding deliverable; next action = human curation pass then /gsd-verify-work
- REQUIREMENTS.md: PIPE-06 marked complete (CI workflow runs Vitest on every push/PR)
2026-05-09 00:00:23 -04:00

15 KiB
Raw Permalink Blame History


phase: 01-foundations-and-doctrine plan: 07 subsystem: ci tags: [ci, github-actions, pipe-06, minimum-viable, solo-dev, no-ceremony]

Dependency graph

requires:

  • phase: 01 plan: 01 provides: package.json with ci script chaining lint + test + validate:assets + build; package-lock.json (committed); Node 22 baseline
  • phase: 01 plan: 02 provides: npm run lint green (ESLint flat config + boundaries plugin, --max-warnings 0)
  • phase: 01 plan: 03 provides: npm test green (save layer — checksum, envelope, migrations, db, snapshots, persist, round-trip)
  • phase: 01 plan: 04 provides: npm test green (content loader) + npm run build green (Vite-native content pipeline)
  • phase: 01 plan: 05 provides: npm run validate:assets exits 0 (Task 1 validator merged; Task 2 north-star images partial — validator passes with 0 assets which is valid)
  • phase: 01 plan: 06 provides: npm test green (doctrine.test.ts via extended vitest include glob) provides:
  • .github/workflows/ci.yml — single-job GitHub Actions workflow (49 lines including load-bearing comments) running npm ci + npm run ci on push to main and pull_request to main; ubuntu-latest; Node 22; actions/setup-node@v4 with cache:'npm'; timeout-minutes:10 affects:
  • "Phase 2: when economy tests + Playwright e2e (PIPE-07) land, they go through the same npm run ci script — the workflow file does NOT need to change. If Phase 2 wants Playwright on CI, add npx playwright install --with-deps chromium before the npm run ci step and update the ci script in package.json to include && npm run e2e."
  • "Phase 8: visual regression testing (PIPE-04) will likely require a separate workflow file (matrix runs against multiple OSes / heavier runtime) since it's a different cost profile from this single-job lint/test workflow. Do not bolt it onto ci.yml."
  • "Every Phase 1 success criterion is now structurally enforced on every commit going forward: CORE-10 (Plan 02 lint), CORE-04..09 (Plan 03 + Plan 06 doctrine.test.ts), PIPE-01 (Plan 04 loader.test.ts + build), PIPE-03/AEST-08/AEST-09 (Plan 05 validate:assets + test), PIPE-05 (Plan 06 doctrine.test.ts), PIPE-06 (this workflow), CORE-01 smoke (build)."
  • "Phase 1 partial item: Plan 05 Task 2 (1020 north-star reference images) still awaits human curation. The validator passes when 0 assets are present ([provenance] all 0 assets carry valid provenance.); the CI workflow does NOT depend on the images being present, so it ships green today and will continue to be green once the images land (each carrying a valid sidecar)."

Tech tracking

tech-stack: added: [] # no new deps; pure CI configuration patterns: - "Minimum-viable CI per CONTEXT user pushback: one job, one OS (ubuntu-latest), one Node version (22), no third-party actions beyond actions/checkout@v4 + actions/setup-node@v4. The workflow's purpose is to refuse merges that break the local npm run ci, nothing more." - "CI script as single source of truth: the workflow runs npm run ci, defined in package.json by Plan 01 as npm run lint && npm run test && npm run validate:assets && npm run build. Adding new gates (e.g., e2e in Phase 2) is done by editing package.json scripts.ci, NOT by editing the workflow file. The workflow stays stable across all future phases." - "Cache discipline (RESEARCH CI Pitfall A): actions/setup-node@v4 with cache: 'npm' caches ~/.npm keyed by package-lock.json, never node_modules/ directly. Caching node_modules/ is the canonical CI footgun (transitive deps go stale silently)." - "Lockfile-strict install: npm ci (not npm install) refuses to run if package.json and package-lock.json drift. This is the standard mitigation for solo-dev supply-chain risk in Phase 1 (T-01-08, see plan threat model). npm audit as a CI step deferred to Phase 8 launch polish if surface area grows." - "Comment-as-doc: the workflow file's leading 18-line comment block enumerates what is deliberately omitted (OS matrix, Node-version matrix, test reporters, Codecov, release automation, notification integrations) so a future contributor reading the file knows the omissions are intentional design decisions, not oversights. Per CONTEXT D-07/D-08 doctrine-as-rationale pattern."

key-files: created: - .github/workflows/ci.yml (49 lines: 18-line header comment block + 4-line name/on declaration + 27-line jobs.ci definition with 4 steps) modified: []

key-decisions:

  • "Workflow stays at 49 lines (slightly over the 20-line target from RESEARCH Open Question #4) because the leading comment block is load-bearing context — it explains why the omissions are there so a future contributor reading the file does not 'helpfully' add a matrix or Codecov upload that would violate CONTEXT user pushback. The actual YAML logic is ~27 lines."
  • "Node 22 chosen (not 20) per RESEARCH § Environment Availability: 'Node 22 ideal for native crypto.hash; Node ≥ 20 required for recursive readdir; the validator uses readdir without recursive but Node 22 is the modern baseline.' Single-version (no matrix) per CONTEXT user pushback against ceremony."
  • "ubuntu-latest only (no Windows / macOS matrix). PIPE-04 visual regression testing is Phase 8; cross-OS coverage of the idle game itself belongs there, not here. Plan 0106 deliverables are all platform-agnostic (TypeScript, Node, npm)."
  • "Triggers limited to push to main and pull_request to main. No tag-based release triggers (no releases until Phase 2 ships Season 1 per ROADMAP). No schedule triggers (no cron/canary needs in Phase 1)."
  • "timeout-minutes: 10 chosen as a sensible ceiling: local npm run ci runs in ~5s (lint) + ~2.5s (test) + ~0.1s (validator) + ~0.7s (build) = well under 10s for the script proper; with npm ci install (~3060s on fresh CI) the realistic full run is ~12min. 10min ceiling catches stuck runs without false-positives on slow GitHub runners."
  • "Workflow does NOT depend on Plan 05 Task 2 (north-star images). The validator passes with 0 assets ([provenance] all 0 assets carry valid provenance.); when human curation lands the images, the validator will continue to pass (each new asset will carry a sidecar by definition of the curation gate). This means Phase 1's CI is shippable now even with Plan 05 partial."

requirements-completed: [PIPE-06]

Metrics

duration: 2min completed: 2026-05-09

Phase 1 Plan 07: CI Workflow Summary

Single-job .github/workflows/ci.yml (49 lines) runs npm ci + npm run ci on push to main and PR to main; Node 22, ubuntu-latest, actions/setup-node@v4 with cache: 'npm', 10-minute timeout. Local npm run ci exits 0 (lint clean, 53 tests pass across 12 files, validator green, build green). PIPE-06 structurally enforced; every Phase 1 automated check now runs on every commit going forward.

Performance

  • Plan duration: ~2 min (single-task plan; the YAML structure was specified verbatim in the plan)
  • Local npm run ci runtime (immediately before commit):
    • lint: <1s (clean, no warnings, --max-warnings=0)
    • test: 2.37s (53 tests / 12 files, all passing)
    • validate:assets: <0.5s (0 assets, all valid)
    • build: 0.66s (tsc -b + vite build)
    • Total: ~5s (well under the 30s feedback-latency target from VALIDATION.md)
  • Expected CI runtime on GitHub: ~12 min (dominated by npm ci install on fresh runner; the test/lint/build steps remain ~5s)

What Was Built

.github/workflows/ci.yml (49 lines)

The full file:

# Phase 1 — minimum-viable CI per RESEARCH Open Question #4 + CONTEXT user pushback
# against ceremonial workflows (.planning/phases/01-foundations-and-doctrine/01-CONTEXT.md).
#
# On every push to main and every pull request:
#   - npm ci (lockfile-strict install — refuses on package.json drift)
#   - npm run ci (lint + test + validate-assets + build, defined in package.json)
#
# This single job satisfies PIPE-06: Vitest tests run on every CI build.
# Phase 2+ economy tests flow through the same `npm run ci` chain — no workflow change
# is needed when more tests are added.
#
# Deliberately omitted (per CONTEXT user pushback against ceremony):
#   - OS matrix (Linux only is fine; PIPE-04 visual regression testing is Phase 8)
#   - Node-version matrix (one supported version is enough for solo-dev)
#   - Test reporters / Codecov uploads (no coverage requirement in Phase 1)
#   - Release automation (no releases until Phase 2 ships Season 1)
#   - Notification integrations (the project owner reads GitHub directly)

name: ci

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  ci:
    name: lint + test + validate-assets + build
    runs-on: ubuntu-latest
    timeout-minutes: 10

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Node 22
        uses: actions/setup-node@v4
        with:
          node-version: '22'
          # Per RESEARCH CI Pitfall A: cache ~/.npm based on package-lock.json,
          # NEVER cache node_modules/ directly (transitive deps go stale).
          cache: 'npm'

      - name: Install dependencies (lockfile-strict)
        run: npm ci

      - name: Run CI suite
        run: npm run ci

Acceptance Criteria — All 11 Pass

# Criterion Result
1 .github/workflows/ci.yml exists OK
2 Workflow runs npm run ci OK
3 Uses actions/setup-node@v4 with cache: 'npm' OK
4 Does NOT cache node_modules/ directly (RESEARCH CI Pitfall A) OK
5 Uses Node 22 OK
6 Runs npm ci (lockfile-strict) before npm run ci (line 46 < line 49) OK
7 Triggers on push to main AND pull_request to main (branches: [main] count = 2) OK
8 Has sensible timeout-minutes (10) OK
9 Locally npm run ci exits 0 (proves workflow will be green) OK
10 Contains comments explaining what was deliberately omitted OK
11 Single-job, single-matrix-entry, no third-party actions beyond checkout + setup-node OK

Deviations from Plan

None — plan executed exactly as written.

The plan documented the YAML verbatim and the file was authored to match. Pre-flight npm run ci was green; post-write acceptance checks all passed; no Rule 1/2/3 fixes needed.

Authentication Gates

None. CI workflow files require no auth to author or commit; GitHub validates the YAML on push (will happen on the user's next push, not gated on this plan).

Phase 1 Closure — Structural Enforcement Map

With .github/workflows/ci.yml landed, every Phase 1 success criterion is now enforced on every commit:

Success Criterion Enforcement Plan Source
1. Game scaffold builds (CORE-01) npm run build (smoke) Plan 01 + Plan 04
2. Round-trip save test passes (CORE-04..09) npm test (12 test files / 53 tests / save layer covers checksum, envelope, migrations, db, snapshots, persist, round-trip) Plan 03
3a. CI fails if src/sim/ imports src/render//src/ui/ (CORE-10) npm run lint (boundaries plugin) Plan 02
3b. CI fails if /content/** violates Zod schema (PIPE-01) npm test (loader.test.ts) + npm run build (Vite content pipeline build-time) Plan 04
3c. CI fails if any AI asset is missing provenance (PIPE-03, AEST-08, AEST-09) npm run validate:assets + npm test (validate-assets.test.ts) Plan 05 (Task 1 done; Task 2 awaits curation — validator passes with 0 assets which is valid)
4. Anti-FOMO + Season 7 end-state docs exist (PIPE-05, UX-13) npm test (doctrine.test.ts — 8 assertions across 2 docs) Plan 06
5. North-star reference set + curation gate (AEST-08, AEST-09) Validator + sidecar gate landed; 1020 images await human curation (Plan 05 Task 2 — checkpoint:human-verify) Plan 05 (partial)
(Cross-cutting) PIPE-06: Vitest runs on every CI build .github/workflows/ci.yml runs npm run ci on push + PR This plan

Phase 1 Open Item Tracking

  • Plan 05 Task 2 (north-star images): Awaits human curation per the checkpoint. The CI workflow ships green today because the validator passes with 0 assets ([provenance] all 0 assets carry valid provenance.). When the user curates and commits the 1020 images, each will carry a valid sidecar by definition of the curation gate, and the validator will continue to pass — no changes to ci.yml needed.

Phase 2 Handoff Notes

When Phase 2 lands:

  1. Adding economy tests: Drop new *.test.ts files anywhere in the repo's existing vitest include glob (src/**/*.test.ts, scripts/**/*.test.ts). They will run automatically as part of npm testnpm run ci → CI workflow. No workflow file change needed.

  2. Adding Playwright e2e (PIPE-07): Two changes:

    • In package.json: extend scripts.ci to include && npm run e2e (or chain it however Phase 2 prefers).
    • In .github/workflows/ci.yml: add a new step before Run CI suite:
      - name: Install Playwright browsers
        run: npx playwright install --with-deps chromium
      
      This is the canonical pattern for Playwright on GitHub Actions ubuntu-latest. No matrix needed for Phase 2; visual regression matrix is Phase 8.
  3. Phase 8 visual regression testing (PIPE-04): Likely warrants a separate workflow file (e.g., .github/workflows/visual-regression.yml) — different cost profile (multi-OS matrix, snapshot uploads, possibly nightly schedule). Do NOT bolt it onto ci.yml; keep ci.yml as the fast PR-blocking gate.

Threat Model — T-01-08 Mitigation Confirmed

The plan's threat model called out T-01-08 (npm install supply-chain compromise via transitive dep) with disposition mitigate. The mitigation is in place:

  • package-lock.json is committed (Plan 01).
  • .github/workflows/ci.yml uses npm ci (not npm install), which refuses to run if package.json and package-lock.json drift.
  • This is the standard solo-dev supply-chain mitigation per RESEARCH § Security Domain.
  • npm audit as a CI step deferred to Phase 8 launch polish if surface area grows (deliberately deferred to keep Phase 1 minimum-viable per CONTEXT user pushback).

Threat Flags

None. The workflow file introduces no new network endpoints, auth paths, file access patterns, or schema changes at trust boundaries. It only invokes existing npm commands that were already in scope.

Self-Check: PASSED

  • File exists: FOUND .github/workflows/ci.yml
  • Commit exists: FOUND 609d582 (ci(01-07): minimum-viable GitHub Actions workflow running npm run ci on push + PR (PIPE-06))
  • All 11 acceptance criteria from PLAN green (see "Acceptance Criteria" table above)
  • Pre-flight npm run ci exit 0 (lint clean / 53 tests pass / validator OK / build OK)
  • No deletions in commit
  • No unintended untracked files (only pre-existing .claude/ local config)