CI
Purpose and document map
This guide describes implemented workflows, job dependencies, artifacts, deployment-related jobs, and the limits of automated enforcement. Sections 1–13 define pipeline mechanics. Section 14 maps the Definition of Done to those mechanisms and manual review; it does not redefine completion policy.
Test-level selection belongs in test-strategy.md, local commands in development.md, container behavior in docker.md, and authoritative completion requirements in the Definition of Done.
Security-sensitive fixture configuration
The coverage and Docker validation jobs explicitly select local Mocking Bird mail with a synthetic fixture sender/recipient. Hosted staging migration jobs do not enable it or receive provider keys. No mail preview or capture is uploaded as a CI artifact.
Password-recovery browser tests use fixed per-project synthetic recipients and the local Mocking
Bird preview only. APP_PUBLIC_URL is the host Vite origin in host E2E and the localhost gateway in
Docker E2E. No real provider request, recovery preview, raw credential, trace, or successful-run
Playwright report is persisted. Local success does not verify hosted sender/domain setup, TLS,
provider acceptance, or inbox delivery.
The canonical Docker command explicitly enables the developer frontend build and local mock backend
for the desktop/mobile console journey. Normal pnpm build retains the default disabled flag, and
unit/route-variant tests separately prove the page declaration and backend endpoints are absent.
Hosted migration configuration never receives the mock flags or synthetic recipients.
Authentication fixtures are synthetic and created only inside the guarded E2E lifecycle. CI does not
contain a default production credential and does not provision users during backend startup or the
normal database seed. Coverage and Docker jobs exercise the real PostgreSQL session/user path; the
limiter remains intentionally in-process for this milestone. The only user provisioning in CI is the
explicitly manual, non-gating staging-user-provisioning.yml dispatch described in
§13.1.
1. Rules
CI is authoritative for automated gate outcomes. The Definition of Done combines those outcomes with acceptance and review evidence. Proportional local validation does not waive any CI gate. Never weaken, skip, or make checks non-blocking merely to obtain a green run.
2. Implemented workflows
.github/workflows/ci.yml: seven validation jobs and one conditional staging migration job. It runs on pull requests and pushes tomain..github/workflows/cloudflare-pages.yml: separate documentation publishing on main pushes and manual dispatch. It rebuilds from source, not a CI artifact..github/workflows/supply-chain-diagnostics.yml: weekly Monday 06:00 UTC plus manual dispatch. It checks external documentation links, rebuilds application images, and collects informational redacted dependency, container, and license inventories into a 7-daysupply-chain-diagnosticsartifact (never a merge gate)..github/workflows/staging-user-provisioning.yml: manual dispatch only. It runs the canonicalpnpm user:createagainst the staging database to provision one permanent operator account. It is never a gate, deploy, or migration step; see §13.1.
Jobs select Node major 24 and pnpm 10.34.5, use checkout/frozen install, and invoke root package scripts. See §14 for exact enforcement and human-review limits. No application registry publishing or production deployment job exists.
3. Contract summary
Every validation job: checkout -> Node 24/pnpm 10.34.5 -> frozen install
Stage 1: quality | test | build | docs | supply-chain (parallel)
Stage 2: validate-docker | coverage (after all five stage-1 jobs pass)
Trusted main push only: staging-migrate (after all seven validation jobs pass)
The eight canonical checks include dependency installation, which is a step in each job rather than a separate status check. PRs require all seven validation jobs; trusted main runs additionally require migration success. Publishing is separate.
4. Canonical checks
| Check | Command | Job |
|---|---|---|
| 1. Install | pnpm install --frozen-lockfile |
Every job |
| 2. Static quality | pnpm quality |
quality |
| 3. Fast tests | pnpm test |
test |
| 4. Production build | pnpm build |
build |
| 5. Docker system | pnpm validate:docker |
validate-docker |
| 6. Coverage | pnpm test:coverage |
coverage |
| 7. Documentation | pnpm docs:build |
docs |
| 8. Supply chain | pnpm security:dependencies + pnpm secrets:check + pnpm containers:lint + pnpm db:check |
supply-chain |
4.1 Docker validation contents
validate:docker runs in its own foodtruck-order-validate Compose project on separate ports, so
the containers/volume it removes are never the development ones; it then builds/starts with bounded
readiness, runs backend real-database integration/API tests, then Docker-mode Chromium E2E. The
exact root script/prerequisites are in Docker §6.8.
4.2 Test coverage mapping
test runs Node artifact-contract tests and frontend/backend fast suites, including OpenAPI
route-surface tests. validate-docker exercises real repository/PostgreSQL, real HTTP integration,
and the complete browser path through Compose. coverage reruns instrumented frontend and aggregate
backend suites. build independently proves host production compilation; Docker separately compiles
source into images.
4.3 Static checks
quality builds db to resolve backend/E2E type-aware lint imports, then runs formatting, ESLint,
all-workspace typecheck, locale parity, tracked Markdown links, scoped spelling, architectural
boundaries, tracked-file hygiene, mechanical specification traceability, and OpenAPI/TypeDoc
documentation gates. All are offline; CI never reformats files. Scope/exclusions and 100-column
Markdown wrapping are in development §13.
4.4 Complementary execution
Each ordinary test tier runs in its appropriate environment. Instrumented coverage intentionally
repeats application suites to enforce the coverage policy. Dev-mode pnpm e2e, pnpm test:all, and
extra per-workspace test invocations are not CI gates. Do not add redundant local reruns after
canonical validation passes without a change or unresolved concern.
4.5 Strict coverage policy
The coverage job uses Vitest v8 and fails below 100% statements, lines, functions, or branches globally or per-file in configured frontend/backend sources. Backend coverage aggregates fast and real-database suites. Scope and justified exclusions are authoritative in testing §4.1. There is no db-package or E2E source-coverage threshold. Coverage does not replace acceptance tests or adequate assertions.
5. Dependencies and isolation
quality, test, build, docs, and supply-chain are independent after their own installation.
coverage and validate-docker explicitly need all five jobs. This stage ordering is the actual
workflow's fail-fast policy, not a technical dependency of Docker compilation on host outputs.
staging-migrate needs all seven validation jobs.
Docker validation destroys its Compose project state and publishes ports; do not run two instances
or coverage/database services sharing those ports on one runner. Actions jobs run on separate
ubuntu-latest runners, so stage-2 jobs do not share Compose state or databases.
6. Environment
Every job selects the same toolchain and CI=true. CI also supplies the checked-out
${{ github.sha }} as the allowlisted public APP_BUILD_SHA, so host and Compose frontend builds
display the same short revision. Only validate-docker creates a root .env from .env.example,
installs Chromium with Linux dependencies, and starts the application through Compose. Its
PostgreSQL is Compose-managed.
coverage uses a GitHub Actions postgres:17.5-alpine service and job-scoped local DATABASE_URL;
it does not create a root .env or run application containers. The test helpers initialize
dedicated databases. Static/test/build/docs jobs need no PostgreSQL. staging-migrate uses its
separate Neon secret (§13).
Missing Docker, browser/system dependencies, unhealthy PostgreSQL, or inaccessible gateway/database fails the relevant job; it must not silently skip tests. The browser gateway preflight only checks reachability; assertions check the actual message workflow.
7. Reproducibility
Frozen installs reproduce lockfile resolutions. CI uses fresh checkouts and no configured artifact
downloads or dependency/browser caches. Docker builds from source, excluding host
outputs/configuration. Clean Compose volumes and dedicated test databases provide known data. No
test retries are configured; application query retry is not a test retry. Playwright uses
forbidOnly in CI and disables dev-server reuse; focused/skipped Vitest tests remain a review gap
(§14).
Node is selected by major and base images by tags (node:24-alpine, nginx:1.29-alpine,
postgres:17.5-alpine), not immutable digests/patches. Reproducible project inputs do not imply
upstream tags or hosted runner images can never change.
Job timeouts are 10 minutes for quality/test/build/staging migration, 15 for docs/coverage, and 20 for Docker. Compose readiness is bounded at 300 seconds. Investigate failures rather than retrying until green; infrastructure reruns must still provide successful evidence for the delivered revision.
8. Failure and merge policy
Root commands propagate non-zero exits. Build preflight and upload failures also fail their producer jobs. Any failed validation job makes validation fail; missing/pending/cancelled required jobs are not successful. On trusted main pushes, staging migration must also succeed. An intentional PR migration skip is valid.
All seven validation jobs and their install steps are mandatory before merge. The recorded hosting constraint is private GitHub Free without private branch protection; there is no repository aggregate merge gate. Enforce the policy operationally by reviewing the revision/run and actual required conclusions. Hosted plan/settings were not independently re-audited by this documentation audit.
9. Artifact contract
9.1 Producing runs
Artifacts come from fresh checkouts, frozen installs, and canonical producing commands. Uploads persist outputs from that same run; artifact presence alone is not proof of overall CI success. Outputs are ignored locally and never committed.
9.2 Application output
pnpm build compiles db → frontend → backend. Before its first application upload, the build job
requires these non-empty files:
packages/db/dist/index.js
packages/db/dist/index.d.ts
frontend/dist/index.html
backend/dist/server.js
It uploads separate db-dist, frontend-dist, and backend-dist artifacts from those workspace
dist/ directories. Db includes compiled JS/declarations/source maps; frontend includes
HTML/JS/CSS/assets; backend includes compiled server code. These are inspection/possible deployment
inputs, not self-contained releases: backend runtime still needs production dependencies and the db
package. E2E has no build output.
9.3 Docker images
Backend, frontend, database tooling, and gateway images are built and used by validate-docker and
discarded with the runner. No image archive, registry push, release tag, or image deployment is
performed. PostgreSQL is an upstream base image, not a project artifact.
9.4 Reports and documentation
frontend-coverage:frontend/coverage/, successful coverage job.backend-coverage:backend/coverage/, successful aggregate coverage job.docs-site:docs-site/, successful docs job; project/API/reference HTML.playwright-report:tests/e2e/playwright-report/andtests/e2e/test-results/, failure-only Docker diagnostics if files exist. Current default Playwright configuration does not explicitly enable an HTML reporter; do not promise an HTML report on every failure. Existing attachments/test-results may be uploaded.
No JUnit/Sonar report or coverage-percentage badge output is generated. Tests prove their assertions through exit codes; coverage additionally enforces thresholds.
9.5 Not deliverables
Dependencies/pnpm store, PostgreSQL volumes/test databases, local .env, browser binaries,
TypeScript build caches, and Compose runtime logs are not successful build artifacts. Logs may be
used as diagnostics without masking a failed check.
9.6 Out of scope
No application registry/package publishing, production environment provisioning, or application deployment exists in CI. Existing staging migration and Cloudflare documentation publishing are implemented exceptions, not future work. No OS/Node matrix or dev-mode E2E job exists.
9.7 Contract changes
The persisted set is the six successful outputs plus optional failure-only playwright-report. New
persisted outputs require documenting purpose, producing command/path, naming, format, retention,
failure behavior, and deployment versus inspection use. Production image publishing remains
separately specified work.
9.8 Upload behavior
All uploads use actions/upload-artifact@v4 and seven-day retention. Successful build/docs/coverage
uploads use if: success() and if-no-files-found: error. Docker diagnostics use if: failure()
and if-no-files-found: warn: missing diagnostics do not add a failure, but upload-service errors
still fail the step. Producer jobs have contents: read plus actions: write; other jobs keep
read-only repository permissions. Uploads are blocking, not a replacement for their producing gates.
Already uploaded files can remain available after a later step fails.
9.9 Verification and download
pnpm test:ci, included in pnpm test, checks artifact definitions/setup and runs the application
preflight against complete/missing/empty fixtures. It does not contact the upload service. Hosted
producer success establishes upload success; inspect changed artifact semantics as needed. Routine
downloads are not required for every unchanged output.
In Actions → CI → run → Artifacts, the ZIP downloads contain each source directory's contents. Successful runs supply all six outputs until retention expires; failed Docker runs can supply diagnostics when files exist. Use the same revision/run's job conclusions and artifact evidence, not an older run or a workflow badge alone.
10. Workflow identifiers and badges
Required validation identifiers are quality, test, build, docs, coverage, and
validate-docker; conditional release identifier is staging-migrate. README has native CI and
documentation-publishing workflow badges only. There are no current per-job shields.io badges or
percentage badges to maintain.
11. CI and Docker relationship
Docker validation is the full packaged-system check. Host install/quality/fast tests/ build/docs and coverage use native tooling; coverage's PostgreSQL is a service container. Tests run from the runner against the application, not inside runtime images. The Docker workflow leaves its stack running locally; ephemeral CI discards it with the runner. Sources and canonical commands are the same in both environments.
12. Documentation publishing
12.1 Gates
quality includes local Markdown links/spelling plus OpenAPI/TypeDoc checks; test includes
OpenAPI route-surface and documentation-gate fixture tests; docs builds the complete site, runs
pnpm docs:site:check, and only then uploads it for inspection.
12.2 Site generation
pnpm docs:build cleans docs-site/, generates Swagger UI and TypeDoc, and renders Markdown/raw
sources. pnpm docs:site:check then requires the landing/project/API/reference/raw outputs and
validates all generated local links/fragments. Tool choices and public API boundaries are
authoritative in documentation.md. CI's docs artifact is not consumed by
publishing.
12.3 Documentation coverage
TypeDoc validates missing comments, exports, and symbol links in configured public entry points
(backend, frontend, and the shared db package; see typedoc.json). Validation warnings — the
documentation-coverage gate — are treated as errors; warnings originating in third-party .d.ts
comments reached through documented types (for example Redux Toolkit's) are advisory and do not fail
the build. Redocly validates the OpenAPI document; its configured advisories are not equivalent to
blocking errors (currently one accepted advisory: no 4xx on the fixed liveness reply GET /health,
see redocly.yaml). Neither TypeDoc nor Redocly judges prose meaning or catches an untested
response mismatch. Tracked Markdown and generated-site links are separate blocking checks.
Candidates to make mandatory (blocking) during the Phase 8 CI work, in rough order of value:
- Make Redocly advisories blocking once the
GET /healthadvisory is resolved (document a real 4xx if the endpoint gains one, or scope the rule when Redocly supports path-scoped severities). - Response-schema conformance: assert actual response bodies against the OpenAPI schemas for the documented endpoints, not only the route surface (today only methods/paths are compared, see §12.4).
12.4 Route contract
The backend fast suite compares public Fastify methods/paths with OpenAPI and excludes implicit HEAD. CORS's runtime OPTIONS behavior is not a separately declared public operation. HTTP behavior/schema semantics require explicit API tests.
12.5 Cloudflare Pages
cloudflare-pages.yml runs quality → fast tests → complete docs build → wrangler Direct Upload to
foodtruck-order-docs, with Node 24/pnpm 10.34.5/frozen install. Wrangler 4.131.1 runs via isolated
pnpm dlx, not a workspace/global dependency. Only CLOUDFLARE_API_TOKEN and
CLOUDFLARE_ACCOUNT_ID repository secrets authenticate publishing. Workflow permissions are
contents: read; no GitHub Environment is used. Main pushes and manual dispatch trigger it;
production branch selection is explicitly --branch=main. Its Cloudflare project must have matching
production-branch settings.
Cloudflare hosts generated static files and does not clone/build source. A concurrency group serializes uploads without cancelling active deployments. Earlier step failure prevents upload. Publishing is independent of the full CI validation workflow and does not explicitly wait for its Docker/coverage/build jobs; operational merge policy supplies prior validation. Manual dispatch must target a reviewed revision.
13. Neon staging migrations and Render deployment
The recorded external setup uses Render staging services linked to main with After CI Checks Pass,
and a Neon staging database. This repository defines their migration gate, not provisioning or
guaranteed hosted check-discovery behavior. Verify those external settings/results in the target
systems before claiming them.
On a trusted push to refs/heads/main in adamrudolf-becube/foodtruck-order, staging-migrate
waits for all seven validation jobs, installs the pinned tooling, and runs pnpm db:migrate. Only
that step receives STAGING_DATABASE_URL as DATABASE_URL. PRs, feature pushes, and forks skip it
and receive no staging secret. There is no pull_request_target, workflow_run, GitHub
Environment, seed/reset, secret upload, or application deployment step.
Create/use a repository Actions secret, not an environment secret. Missing/invalid connection or migration failure fails the job. No build is needed for drizzle-kit. Staging seed is deliberately manual; migrated empty state can return message 404. Never bypass a failed migration with a manual application deployment.
The expected sequence is PR validation → trusted main validation → migration → all detected checks passing → Render deploys. Cloudflare's separately detected check can also affect Render readiness. Verify discovery/timing and served revision on a real run; local tests do not establish them. Manual Render deployment is outside this automatic contract.
Render service environment is also outside the GitHub workflow. Before deploying a revision that
requires hosted sessions, configure the backend service with DEPLOYMENT_ENV=staging (or
production), a stable provider-held SESSION_SECRET of at least 32 characters, and
PUBLIC_BROWSER_ORIGIN set to the exact public frontend origin. Set CORS_ALLOWED_ORIGINS to that
same origin when the frontend and backend origins differ. The repository's .env.example and the
GitHub STAGING_DATABASE_URL secret do not populate Render environment variables. The complete
runtime checklist, same-site domain requirement, and post-deploy cookie verification are in
development §6.1.
Migration concurrency serializes the shared database without cancelling an active run; pending runs may be replaced and order is not FIFO. Keep migrations compatible with currently deployed code. CI neither serializes Render deployments nor rolls back a schema change if application deployment later fails. Target TLS, health/smoke, and upgrade compatibility follow development §6.1.
13.1 Manual staging user provisioning
staging-user-provisioning.yml provisions one permanent staging account on demand. It exists
because the repository host cannot open a PostgreSQL connection to the hosted staging database
(outbound TCP 5432 is blocked; only 443 and 22 are reachable), while GitHub-hosted runners have
unrestricted egress. It is a transport for an existing repository command, not a new provisioning
mechanism: the job runs the canonical pnpm user:create from
development §"User provisioning",
so validation, normalization, Argon2id hashing, and persistence stay exactly the same as a local
run. tests/ci/staging-provisioning.test.mjs enforces its safety contract.
Trigger and behavior:
workflow_dispatchis the only trigger. No push, pull request, schedule, or repository event can run it, so it can never become an automatic gate, deploy, or migration step.- The job is additionally skipped unless the repository is
adamrudolf-becube/foodtruck-order, so a fork cannot provision against the project's secrets. - Inputs are
emailanddisplay_nameonly. The passphrase is read from the repository secretSTAGING_USER_PASSWORD, never from an input, argument, or echoed value, because dispatch inputs and run logs are readable by anyone who can read the repository or the run. - The three values are passed through the environment and piped to standard input as the documented
non-interactive contract (email, display name, password). The passphrase is never in
argv. - The job builds
@foodtruck-order/dbfirst, becausepnpm user:createloads that workspace through its compileddistentrypoint, which a fresh checkout does not contain. - It never migrates, seeds, or resets. Schema changes remain the trusted-main
staging-migrateresponsibility, so provision only after a successful migration. - A
staging-database-provisioningconcurrency group withcancel-in-progress: falseserializes runs against each other. It is a distinct group fromstaging-database-migrations; both write the same shared database, so avoid dispatching one while a migration is running. pnpm user:createalready fails nonzero for a duplicate address or a policy-short passphrase, so a green run means the account exists and a red run is safe to retry after correcting the inputs.
The repository operator supplies STAGING_USER_PASSWORD out of band. Rotate it after use, or prefer
changing the account passphrase through /settings on the running application. Successful login
still requires the hosted SESSION_SECRET, PUBLIC_BROWSER_ORIGIN, and APP_PUBLIC_URL values
from §13; provisioning a row does not prove
those.
14. Definition of Done validation mapping
This section is an enforcement map. The Definition of Done owns the requirements; each entry below identifies the command, workflow, artifact, or human review that supplies evidence and makes any automation gap explicit.
This maps the ten mandatory checklist items in the
Definition of Done to the
mechanisms present in the repository. It describes enforcement, not the outcome of a particular
hosted run. The main workflow is .github/workflows/ci.yml; job identifiers below refer to that
workflow.
Automatic means a configured command fails on a detected violation. Partial means automation
checks only part of the requirement; review is still required. Human-only means the requirement
needs judgment and has no acceptance gate in the repository. Local availability does not mean every
command must be run locally for every change: follow the DoD's proportional validation rules. AI
agents must still execute pnpm quality locally.
14.1 Every mandatory requirement
The item numbers identify the checklist's current order; descriptions identify what is being checked if the checklist is later reordered.
1. Implementation and applicable specification acceptance complete
- Automatic check / command: Partial: existing automated tests prove their assertions
through
pnpm test,pnpm test:integration, andpnpm e2e:docker;pnpm traceability:checkmechanically proves every scenario is declared once, carries an evidence declaration, appears in an epic index, and names no undefined ID in a test. No command proves that the referenced evidence actually satisfies an acceptance criterion. - Local mechanism: Run affected suites; review the implementation and each applicable specification's acceptance criteria.
- CI mechanism:
test,validate-docker,coverage, and blockingtraceability:checkinsidequalityexecute the tests and the mechanical index rules. - Human verification required: Yes: map every acceptance criterion to test or other evidence; confirm required behavior has no placeholders and all needed layers are delivered.
2. Scope, architecture, technology stack, and significant decisions respected
- Automatic check / command: Human-only for architectural compliance:
pnpm lintchecks import hygiene/types/hooks/a11y, not permitted layer dependencies or the meaning of code. - Local mechanism: Review the diff, imports, workspace dependencies, and significant decisions against architecture/techstack; record the result.
- CI mechanism:
qualityprovides general static checks only. No architecture-boundary or technology-choice gate exists. - Human verification required: Yes: verify HTTP/application/persistence/frontend boundaries, scope, justified technology changes, and whether an ADR is needed and sufficient.
3. Appropriate automated tests and bug regression coverage
- Automatic check / command: Partial:
pnpm testexecutes CI artifact tests plus frontend/backend fast tests;pnpm test:integration,pnpm e2e:docker, andpnpm test:coveragecover the other tiers and configured coverage scope. - Local mechanism: Select and run affected tests at the lowest appropriate levels; record why no new test is needed where applicable.
- CI mechanism:
test,validate-docker, andcoveragefail on executed-test failures;coverageenforces configured 100% thresholds. - Human verification required: Yes: check test level, assertions, acceptance coverage, regression reproduction, and justified exclusions. Passing coverage cannot establish test adequacy.
4. Static quality, including local AI-agent execution
- Automatic check / command: Automatic for configured checks:
pnpm qualitybuilds db, checks formatting/lint/types, and runs OpenAPI/TypeDoc checks. Human-only for proof of local execution. - Local mechanism: Same command; local execution is mandatory for AI agents.
- CI mechanism:
qualityruns the same command; the separate publishing workflow also runs it. - Human verification required: Yes for the local execution record and semantic documentation quality. No additional manual TypeScript/format/lint pass is needed after these checks pass.
5. All required CI validation succeeds for the delivered revision
- Automatic check / command: Partial: Actions records checkout revision, steps, and job conclusions; command/upload failures fail jobs and dependent jobs wait for success.
- Local mechanism: Equivalent scripts are available, but local results cannot establish hosted CI success.
- CI mechanism: All seven validation jobs and their frozen installs run on PRs/main pushes.
Trusted main pushes additionally require
staging-migrate(§13); it deliberately skips on PRs. - Human verification required: Yes: verify the run matches the delivered revision/event and every required job actually succeeded. There is no repository aggregate gate requiring all jobs before merge; merge enforcement is operational (§8).
6. Required artifacts produced and persisted
- Automatic check / command: Automatic within each producer:
pnpm build,pnpm docs:build,pnpm test:coverage; application output preflight; blockingactions/upload-artifact@v4steps.pnpm test:cichecks upload definitions and preflight fixtures. - Local mechanism: Build/report generation and artifact-contract tests run locally. Hosted upload persistence is not tested by local commands.
- CI mechanism:
build,docs, andcoverageupload the six successful artifacts;validate-dockeruploads optional failure diagnostics only. - Human verification required: Yes for same-run evidence and changed artifact semantics: successful producer jobs establish upload success; inspect changed contents where needed. Routine downloads of every unchanged artifact are not required.
7. Documentation/handover accurate; generated output excluded; migration files committed
- Automatic check / command: Partial:
pnpm docs:check, route-contract tests inpnpm test, andpnpm docs:buildcheck API surface, configured public API comments, and generation..gitignorereduces accidental output commits but is not a tracked-file check. - Local mechanism: Review affected guides, public comments, migration files, current-state, handover, and the final/staged file list.
- CI mechanism:
quality,test, anddocscheck the automated subset. No gate checks prose accuracy, required handover updates, or forbidden tracked output. - Human verification required: Yes: verify meaning, consistency, update applicability, no placeholder comments, required migration SQL/journal, and absence of committed generated output.
8. Focused diff, no secrets/machine-specific prerequisites, reproducibility
- Automatic check / command: Partial:
pnpm install --frozen-lockfile,pnpm build,pnpm docs:build, andpnpm validate:dockerexercise clean setup/build/runtime paths..gitignore/.dockerignoreprotect normal workflows but do not detect secrets in tracked code or all host assumptions. - Local mechanism: Run affected reproducibility checks; inspect the final diff, file list, manifests, configuration, and container definitions.
- CI mechanism: Frozen installs in each job;
build,docs, andvalidate-dockerrun on fresh checkouts. No repository secret-scanning gate is configured. - Human verification required: Yes: inspect tracked changes for secrets, unrelated edits, hard-coded environment values, and undocumented prerequisites outside exercised paths.
9. No known unresolved blocking issues
- Automatic check / command: Partial: all configured quality/test/build/Docker/artifact checks expose the failures they detect.
- Local mechanism: Investigate failures and review known issues against acceptance criteria.
- CI mechanism: Required jobs fail on their detected blockers. CI does not classify issue tracker entries or untested defects.
- Human verification required: Yes: reconcile acceptance evidence, failures, missing verification, and known limitations; document why any remaining issue is non-blocking.
10. Accurate completion report and explicit unverified checks
- Automatic check / command: Human-only: logs, job conclusions, and artifacts are supporting evidence; no report-schema or truthfulness gate exists.
- Local mechanism: Use the DoD report record in the PR/change report and AI handover.
- CI mechanism: Logs/artifacts provide evidence, but no job validates the completion report.
- Human verification required: Yes: check scope, acceptance evidence, actual local execution, revision/run, artifact evidence, N/A reasons, limitations, and next action. Missing hosted evidence must be reported as Ready for CI or Blocked as appropriate.
14.2 Concrete technical checks
These are the technical mechanisms behind the mandatory checklist, including checks that become relevant through its applicability guidance. Each command is available locally; only the documented affected subset needs local execution. All normal CI validation gates remain mandatory even for documentation changes.
Reproducible dependency installation
- Local command / implementation:
pnpm install --frozen-lockfilewith the pinned Node/pnpm toolchain. - CI execution: Every job, before validation.
- Limit / remaining review: Verifies manifest/lockfile consistency and install success, not whether a new dependency or technology is justified.
Formatting
- Local command / implementation:
pnpm format:checkinsidepnpm quality;.prettierrc.json/.prettierignore. - CI execution:
quality. - Limit / remaining review: Applies to covered files; exclusions remain documented in development §13.
Lint
- Local command / implementation:
pnpm lintinsidepnpm quality;eslint.config.js. - CI execution:
quality. - Limit / remaining review: Strict JS/TS checks; no full architecture dependency rule or standalone Dockerfile/shell/nginx/SQL lint.
Type checking
- Local command / implementation:
pnpm typecheckinsidepnpm quality; checks db, frontend, backend, and E2E workspaces. - CI execution:
quality. - Limit / remaining review: Type correctness does not prove runtime acceptance.
Unit/component/module and frontend integration tests
- Local command / implementation:
pnpm test:unitor affected workspace tests.pnpm testaddspnpm test:cibefore that suite. - CI execution:
test; frontend/backend suites also run instrumented incoverage. - Limit / remaining review: Review selects appropriate behavior and assertions. Frontend integration tests use the real frontend layers with controlled external HTTP.
Real PostgreSQL integration tests
- Local command / implementation:
pnpm test:integration; backendvitest.integration.config.ts, dedicated migrated test databases. - CI execution: Inside
validate-docker; also backend aggregatecoverage. - Limit / remaining review: Requires real PostgreSQL. Assertions cover existing repository/database paths, not every possible schema or migration upgrade.
HTTP/API contract behavior
- Local command / implementation: Backend fast suite
(
pnpm --filter @foodtruck-order/backend test:unit) covers HTTP injection andopenapi-contract.test.ts;pnpm test:integrationcovers real HTTP/service/repository/PostgreSQL. - CI execution:
test,validate-docker, and aggregatecoverage. - Limit / remaining review: Route-surface equality is automatic; request/response/error semantics depend on explicit API test assertions. No universal OpenAPI response-schema conformance gate exists.
Browser E2E
- Local command / implementation:
pnpm e2e:dockeragainst Compose, normally throughpnpm validate:docker.pnpm e2eis optional dev-mode feedback. - CI execution: Only Docker-mode E2E in
validate-docker; PlaywrightforbidOnlyis enabled in CI. The shared desktop/mobile specs include the blocking axe WCAG A/AA baseline and focused responsive, focus, reduced-motion, and target-size behavior; no redundant E2E job exists. - Limit / remaining review: Review ensures important changed workflows are represented and real boundaries are exercised. Axe cannot establish full WCAG conformance or physical phone, virtual-keyboard, zoom, visual-contrast, and screen-reader usability; record those through the manual review protocol. Failure-only Playwright artifacts retain the existing contract, and tests use synthetic data with reset fragments removed before diagnostics.
Aggregate production code coverage
- Local command / implementation:
pnpm test:coverage; frontendvitest.config.tsand backendvitest.coverage.config.ts. - CI execution:
coverage, with a PostgreSQL service. - Limit / remaining review: 100% statements/lines/functions/branches globally and per-file for configured frontend/backend sources (§4.5). Does not cover all db-package code, process bootstrap, or static assets, and does not enforce E2E source coverage.
Production builds
- Local command / implementation:
pnpm build; compiles db → frontend → backend using workspace build scripts. - CI execution:
build; Docker images separately compile from source invalidate-docker. - Limit / remaining review: E2E is typechecked, not built. A successful build is not deployment or acceptance evidence by itself.
Docker builds, startup, migrations/seed, and real communication
- Local command / implementation:
pnpm validate:docker: clean isolated volume → Compose build/start/wait → integration → Docker E2E. - CI execution:
validate-docker. - Limit / remaining review: Initialization and exercised runtime path are checked. Changed runtime overrides, migration reruns, or upgrades from an existing schema need targeted evidence when not covered.
Dependency vulnerabilities
- Local command / implementation:
pnpm security:dependencies(scripts/security-dependencies.mjsoverpnpm audit --audit-level high --json); narrow expiring entries live insupply-chain/audit-exceptions.json. - CI execution: Blocking
supply-chain. - Limit / remaining review: High/critical advisories block; lower severities are informational in the weekly diagnostics. Network/audit-service failure fails verification. Review triages by deliberate dependency update and compatibility testing, not automatic upgrades.
Secret material
- Local command / implementation:
pnpm secrets:check(pinned Gitleaks container over tracked working-tree files); CI scans PR history with full checkout history plus the merge base. - CI execution: Blocking
supply-chain; weekly full-history redacted scan in diagnostics. - Limit / remaining review: Findings are redacted before console/report output and never uploaded raw. A real finding blocks and requires credential rotation, not scanner suppression. Hosted push-protection coverage is not assumed.
Dockerfile quality
- Local command / implementation:
pnpm containers:lint(pinned Hadolint across backend/frontend/db/gateway Dockerfiles. - CI execution: Blocking
supply-chain. - Limit / remaining review: Fixes preserve Node 24/pnpm frozen install/workspace deploy/user entrypoint behavior; generic image-digest advice is not forced onto the deliberate mutable base-tag policy.
Migration consistency
- Local command / implementation:
pnpm db:check(actualdrizzle-kit generatein an isolated temporary copy; never mutates tracked files). - CI execution: Blocking
supply-chain. - Limit / remaining review: Detects pending generated changes and untracked migration output.
Fresh/upgrade/rerun behavior remains proved by real integration tests inside
validate:docker.
OpenAPI and intentional public TypeScript documentation
- Local command / implementation:
pnpm docs:checkinsidepnpm quality; Redocly and TypeDoc. - CI execution:
quality; route-surface test intest. - Limit / remaining review: TypeDoc detects missing comments/invalid symbol links in configured entry points, not whether comments are meaningful. Redocly advisories are not blocking errors.
Locale, Markdown-link, and spelling resources
- Local command / implementation:
pnpm i18n:check,pnpm docs:links:check, andpnpm spellcheck, all insidepnpm quality; shared locale parity, marked token/anchor handling, and pinned CSpell dictionaries/configuration. - CI execution: Blocking
quality; fixture failures inpnpm test:ci. - Limit / remaining review: Exact keys/non-empty/interpolation compatibility are mechanical; translation quality and prose meaning remain human review. Offline quality does not contact external sites.
Architecture boundaries and tracked repository hygiene
- Local command / implementation:
pnpm architecture:checkuses ESLint import/global restrictions;pnpm repository:checkevaluates Git's tracked inventory while allowing committed Drizzle SQL/journal files. - CI execution: Blocking
quality; positive/negative fixtures inpnpm test:ci. - Limit / remaining review: The rules encode current concrete boundaries, not generic semantic architecture or secret detection. Gitleaks remains the separate secrets gate.
Mechanical specification traceability
- Local command / implementation:
pnpm traceability:checkrunsscripts/traceability-check.mjsover Git-tracked files: story scenario headings with their- **Evidence:**declarations, journey headings, the epic scenario-to-evidence index tables, and bracketed[MVP-…]IDs in tracked test files.--reportprints the generated per-scenario index without writing a second documentation surface. - CI execution: Blocking
quality; valid/duplicate/dangling/missing-evidence/index fixtures and a real-corpus run inpnpm test:ci. - Limit / remaining review: ID existence, uniqueness, and index presence are mechanical. Whether
the named evidence proves a scenario, whether the chosen test level is right, and whether
assertions are meaningful stay review responsibilities; no scenario is required to have browser
E2E. One narrow documented exclusion applies:
tests/ci/traceability.test.mjsis not itself scanned for declared IDs, because its fixtures intentionally use synthetic IDs that no story defines.
Generated documentation site
- Local command / implementation:
pnpm docs:buildgenerates Swagger UI, TypeDoc, and rendered Markdown, thenpnpm docs:site:checkverifies required non-empty outputs and local generated links/fragments (including raw Markdown heading fragments). - CI execution:
docs, then blockingdocs-siteupload. - Limit / remaining review: Source and output links are checked; prose correctness, external availability, and the semantic quality of API/reference text remain review responsibilities.
Application/report artifact presence and uploads
- Local command / implementation: Producers above; application preflight checks four non-empty
entry files (§9.2);
pnpm test:cichecks workflow contract/fixtures. - CI execution: Blocking uploads in
build,docs, andcoverage. - Limit / remaining review: Docs/coverage uploads fail when no files exist, but no equivalent completeness preflight checks every report/site file. Hosted service results must come from the producing run.
Publishing and staging are event/scope-dependent additions, not extra local application test tiers.
staging-migrate runs pnpm db:migrate only on trusted main pushes after validation;
.github/workflows/cloudflare-pages.yml runs quality/fast tests/site generation and deployment on
main/manual dispatch. Neither proves Render deployment timing, the served revision, or all target
health/smoke criteria. Verify those externally when deployment is in scope (§13).
Periodic supply-chain diagnostics
- Local command / implementation:
pnpm supply-chain:diagnostics(scripts/supply-chain-diagnostics.mjs): all-severity audit inventory, full-history redacted secret scan, Trivy inventory of freshly built images, andpnpm licenses listlicense inventory. Scanner execution failures fail; Trivy/license findings are informational (no arbitrary denylist without a licensing decision). - CI execution: Weekly Monday 06:00 UTC plus manual
supply-chain-diagnostics.yml; 7-daysupply-chain-diagnosticsartifact undersupply-chain/reports/, separate from the six mandatory application artifacts. - Limit / remaining review: Informational findings are not security/compliance proof. Review keeps raw secret findings and mail previews out of uploaded reports and preserves failure-only Playwright diagnostics.
The same weekly/manual workflow runs pnpm docs:links:external with bounded timeouts and one retry
before inventory collection. HTTP 4xx targets are reported as broken; timeouts, rate limits, 5xx,
DNS/TLS, and other provider/network failures are reported as unavailable. Either outcome fails that
diagnostics execution visibly, but the command is absent from PR/offline quality.
14.3 Enforcement gaps and required manual evidence
The configured mechanical gates above have concrete commands/workflow steps. The following limitations remain; none is silently treated as automatically verified. A manual review/result in the DoD completion record is the current validation mechanism where automation is absent. This mapping adds no new gates and does not assert that the hosted repository settings were audited.
Architectural enforcement remains deliberately narrow
- Affected requirement: DoD 2: responsibilities and semantic coupling extend beyond imports.
- Current mechanism / follow-up: ESLint blocks the concrete frontend/backend/db, application/domain implementation, and presentation API-bypass paths. Reviewer still inspects responsibilities, dependency direction, composition, and significant ADR changes.
Hosted push-protection coverage is not assumed
- Affected requirement: DoD 8:
.gitignorecannot reject secrets in tracked files. - Current mechanism / follow-up: Blocking Gitleaks in
supply-chain(tracked working tree locally, PR history in CI) plus the weekly full-history redacted diagnostics scan. Review changed tracked code/configuration for credentials and secret material. Hosted secret scanning/push protection was not verified; do not assume it covers this gap.
Tracked generated-output policy is path-based
- Affected requirement: DoD 7: new output naming can fall outside known policy paths.
- Current mechanism / follow-up:
repository:checkrejects tracked dist, coverage, docs-site, browser reports, local env, and sensitive-preview paths while allowing migration SQL/journal. Review still identifies new tool output categories and extends the policy when introduced.
No automatic required-job merge enforcement in repository configuration
- Affected requirement: DoD 5: a person can merge without a complete green run.
- Current mechanism / follow-up: Observe §8's operational merge policy and inspect all required conclusions for the delivered revision. There is no aggregate validation job; private GitHub Free branch-protection availability is a documented constraint.
No semantic test-adequacy gate
- Affected requirement: DoD 1 and 3: executing tests and reaching 100% coverage can miss acceptance criteria or weak assertions.
- Current mechanism / follow-up:
pnpm traceability:checkproves the mechanical half — every scenario is declared once, carries an evidence declaration, appears in an epic index exactly once, and no test declares an undefined ID. Reviewer still maps applicable criteria to evidence and examines regression tests/test levels, mocks, coverage exclusions, and skip/only usage. Playwright rejectsonlyin CI, but there is no equivalent configured Vitest-wide focused/skipped-test prohibition. Do not automate semantic acceptance or test adequacy as a checklist-presence test.
Documentation semantic quality and external availability remain non-PR review
- Affected requirement: DoD 7 and 6: link resolution/completeness cannot establish accurate prose or provider availability.
- Current mechanism / follow-up: Offline source links and generated output are blocking; external links run weekly/manually. Review changed prose and affected generated pages. A provider outage is not converted into a PR failure.
Clean-schema validation does not exercise every migration upgrade/runtime variant
- Affected requirement: DoD 1, 3, and 8 when schema/configuration changes trigger additional requirements.
- Current mechanism / follow-up: Provide targeted integration or documented
upgrade/rerun/configuration results for the affected path. Existing
validate:dockeris still the baseline; the change author adds relevant tests when behavior warrants them.
No semantic documentation, handover, report, local-execution, or blocker-classification gate
- Affected requirement: DoD 4's execution evidence and DoD 7, 9, and 10.
- Current mechanism / follow-up: Human checks the accuracy/completeness of records and reconciles them with logs and acceptance evidence. These are intentional judgment requirements, not reasons to add automation that merely demands a Markdown edit or checkbox.
For a review decision, record pass, fail, not applicable with reason, or not verified for the applicable checks and human reviews. Technical gaps remain visible even when manual evidence satisfies a particular change. Required missing verification cannot be converted to N/A. Once affected local checks have passed, obtain hosted results for the delivered revision rather than rerunning every available command manually.