Skip to content

T-ENG03: make the webapp data bundles deterministic - #37

Open
emmanuelgjr wants to merge 1 commit into
mainfrom
fix/T-ENG03-deterministic-webapp-build
Open

T-ENG03: make the webapp data bundles deterministic#37
emmanuelgjr wants to merge 1 commit into
mainfrom
fix/T-ENG03-deterministic-webapp-build

Conversation

@emmanuelgjr

Copy link
Copy Markdown
Contributor
Plan ID: ENG-03            Ticket: T-ENG03            Wave: W4
Constraints honored: C2 (determinism only — no structural/route/layout/logo change), C1 (no names), C4 (no mapping content touched)
Files touched: scripts/generate.js, scripts/generate.test.mjs, .github/workflows/validate.yml, CONTRIBUTING.md,
               docs/data.js, docs/backlinks.js, docs/frameworks-registry.js, docs/incidents.js (8 files)
Deliberately NOT changed: no entry JSON, no mapping row, no count, no webapp HTML/CSS/JS logic; Pages source left as main:/docs
Human decisions/approvals needed: C2 approval — this PR regenerates docs/*.js (header lines only, see diff)
Verify:
  $ node scripts/generate.js && node scripts/generate.js && git diff --exit-code -- data/entries data/backlinks.json docs/*.js
  clean (header-only diff vs main is the intended change)
  $ npm test          → 51 tests, 51 pass (3 consecutive runs)
  $ node scripts/validate.js
  Summary: 0 error(s), 84 warning(s), 312 passed  ✓ Validation PASSED
  $ npm run stats:check   → data/stats.json current; README.md current
  $ actionlint / zizmor .github/workflows/validate.yml → clean
Baseline before/after: 0 err / 84 warn → 0 err / 84 warn

What was non-deterministic

Only one thing: each of the four docs/*.js bundles opened with // Generated: <today's date>. Everything else the generator emits is stable run-to-run (the existing generating twice produces byte-identical output test already proved that — on the same day).

That single line had a bigger consequence than untidy diffs: since #30, the Generator reproducibility CI job and the committed entries match a fresh generation unit test both diff docs/data.js against a fresh run. Both could only pass on the day the bundles were last committed. They were green on 2026-08-28 because every merge that day regenerated them; the next push on a later day would have failed on main with no code change.

Changes

  • scripts/generate.js — the four // Generated: lines are gone. The // Source: header now reads the version from package.json (v4.0.0) instead of a hard-coded v1.5.2 that had been stale for three majors.
  • scripts/generate.test.mjs — new test: no bundle header may name a run or carry a date.
  • .github/workflows/validate.yml — the reproducibility job now diffs every generated artefact: data/backlinks.json, docs/backlinks.js and docs/frameworks-registry.js were previously outside the check.
  • CONTRIBUTING.md — a "Generated files" section: which files are generated, the determinism requirement, and the npm run build / npm test / git diff --exit-code loop.

On "prefer generating them in the Pages deploy workflow"

There is no Pages deploy workflow: Pages is configured as build_type: legacy, source main:/docs (checked via gh api .../pages). Switching to a workflow-based deploy means changing the repository's Pages settings and adding a deploy workflow — a maintainer/infrastructure decision, not a determinism fix — so this PR keeps the bundles committed and says so in CONTRIBUTING. Happy to draft that workflow as a follow-up if wanted.

Observed, not changed

node --test runs the suite files in parallel, and generate.test.mjs rewrites data/entries/ while exports.test.mjs reads them. One run in ~6 produced a transient OSCAL component definition carries at least one implemented requirement failure; the same run passes in isolation and on pristine main. Pre-existing and out of scope here; noted for a follow-up (serialize the suites or have the exports test snapshot its input).

🤖 Generated with Claude Code

https://claude.ai/code/session_0147wBugcuzLkswKPqgofcke

Every docs/*.js bundle carried a `// Generated: <today>` header. Nothing
else in the generator output varies between runs, so that one line was
the whole reason a regenerate on a different day showed four dirty
files — and, since #30, the reason the Generator reproducibility job and
the `committed entries match a fresh generation` test could only pass on
the day the bundles were last committed.

- generate.js: drop the run-date lines; the Source header now reads the
  version from package.json instead of a hard-coded, stale `v1.5.2`.
- generate.test.mjs: assert no bundle header names a run or carries a date.
- validate.yml: the reproducibility job now diffs every generated
  artefact (backlinks.json, backlinks.js, frameworks-registry.js too).
- CONTRIBUTING.md: document the build contract — generated files, the
  determinism requirement, and why the bundles are committed (Pages
  serves docs/ from main; no deploy workflow exists).

Determinism only. No structural, route, layout or logo change (C2).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0147wBugcuzLkswKPqgofcke
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant