chore(build): vendor scripts/tailwindcss by pinned-checksum fetch; amend ADR 0002 #57

Open
opened 2026-09-22 16:31:15 +00:00 by gabogg · 1 comment
Owner

Spun out of #14 Candidate 4 during the grilling session of 2026-09-22. Candidate 4 is otherwise delivered — this is a reproducibility gap in what shipped.

Problem

scripts/build-css.sh:14 invokes $DIR/scripts/tailwindcss to compile app/static/css/tactical-bundle.min.css. That binary is gitignored (.gitignore:9) and is 41 MB.

So a fresh clone cannot rebuild the stylesheet. The air-gapped asset pipeline is reproducible only on machines that already happen to have the binary, which is the opposite of what the air-gap guarantee is for. The compiled bundle is committed, so the application runs — but any change to input.css or to a template's utility classes cannot be recompiled from a clean checkout.

Also: ADR 0002 is stale on two points

  • docs/adr/0002-industrial-brutalist-frontend-architecture.md:43 still lists Candidate 4 as "safely deferred". It shipped on 2026-09-10 (commit d4660b6).
  • :34 mandates a "Native Node 22 test harness (node:test, node:assert) wrapped in tests/test_frontend_modules.py". Node is therefore already a hard dev-time dependency, which contradicts #14's "zero npm, zero Node.js" framing for Candidate 4. The binding constraints are :16 ("eliminate runtime external CDN scripts") and :17 ("all CSS, icons, fonts, and scripts must be vendored and served locally") — both about runtime, not build time.

Suggested fix

Fetch by pinned checksum rather than committing 41 MB into git history permanently:

  • A script that downloads the pinned Tailwind CLI version, verifies a recorded SHA-256, and fails loudly on mismatch.
  • build-css.sh invokes it when the binary is absent.
  • Document the offline path: operators on an air-gapped host stage the verified binary manually.

git-lfs was considered and rejected — it adds infrastructure for one file. Committing the binary was rejected because git history is permanent.

Acceptance criteria

  • A fresh clone can rebuild tactical-bundle.min.css following documented steps.
  • The Tailwind CLI version and its SHA-256 are pinned in the repo; checksum mismatch fails the build.
  • The air-gapped staging path is documented.
  • ADR 0002 amended: Candidate 4 recorded as delivered, and the runtime-vs-build-time distinction stated so "zero Node.js" is not read as binding on the test harness :34 mandates.

🤖 Generated with Claude Code


Triage resolution — 2026-09-23

This resolution supersedes the suggestion that build-css.sh should download
the compiler automatically.

Initial support is Tailwind CLI 3.4.17 on Linux x86-64, matching the existing
compiler. Keep compiler upgrades and additional native build platforms separate.
Windows deployment consumes the committed CSS bundle.

Acceptance:

  • Commit the compiler version, artifact identity and SHA-256 pin.
  • Provide explicit connected setup that fetches and verifies the compiler.
  • Document manual offline staging and verify the staged binary against the
    same committed checksum. A mismatch fails setup/build rather than executing
    an unverified compiler.
  • CSS builds use the staged binary and never download it automatically.
    A missing binary produces an actionable setup error.
  • A fresh checkout can rebuild the committed CSS bundle using documented
    setup or offline staging.
  • ADR 0002 records the standalone compiler as delivered and distinguishes
    runtime asset independence from development dependencies, including Node tests.

The ADR clarification is prepared locally in this triage session; integrate it
with the implementation rather than duplicating it.

Spun out of #14 Candidate 4 during the grilling session of 2026-09-22. Candidate 4 is otherwise **delivered** — this is a reproducibility gap in what shipped. ## Problem `scripts/build-css.sh:14` invokes `$DIR/scripts/tailwindcss` to compile `app/static/css/tactical-bundle.min.css`. That binary is **gitignored** (`.gitignore:9`) and is 41 MB. So **a fresh clone cannot rebuild the stylesheet.** The air-gapped asset pipeline is reproducible only on machines that already happen to have the binary, which is the opposite of what the air-gap guarantee is for. The compiled bundle is committed, so the application runs — but any change to `input.css` or to a template's utility classes cannot be recompiled from a clean checkout. ## Also: ADR 0002 is stale on two points - `docs/adr/0002-industrial-brutalist-frontend-architecture.md:43` still lists Candidate 4 as "safely deferred". It shipped on 2026-09-10 (commit `d4660b6`). - `:34` **mandates** a "Native Node 22 test harness (`node:test`, `node:assert`) wrapped in `tests/test_frontend_modules.py`". Node is therefore already a hard dev-time dependency, which contradicts #14's "zero npm, zero Node.js" framing for Candidate 4. The binding constraints are `:16` ("eliminate runtime external CDN scripts") and `:17` ("all CSS, icons, fonts, and scripts must be vendored and served locally") — both about **runtime**, not build time. ## Suggested fix Fetch by **pinned checksum** rather than committing 41 MB into git history permanently: - A script that downloads the pinned Tailwind CLI version, verifies a recorded SHA-256, and fails loudly on mismatch. - `build-css.sh` invokes it when the binary is absent. - Document the offline path: operators on an air-gapped host stage the verified binary manually. git-lfs was considered and rejected — it adds infrastructure for one file. Committing the binary was rejected because git history is permanent. ## Acceptance criteria - [ ] A fresh clone can rebuild `tactical-bundle.min.css` following documented steps. - [ ] The Tailwind CLI version and its SHA-256 are pinned in the repo; checksum mismatch fails the build. - [ ] The air-gapped staging path is documented. - [x] ADR 0002 amended: Candidate 4 recorded as delivered, and the runtime-vs-build-time distinction stated so "zero Node.js" is not read as binding on the test harness `:34` mandates. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- ### Triage resolution — 2026-09-23 This resolution supersedes the suggestion that `build-css.sh` should download the compiler automatically. Initial support is **Tailwind CLI 3.4.17 on Linux x86-64**, matching the existing compiler. Keep compiler upgrades and additional native build platforms separate. Windows deployment consumes the committed CSS bundle. Acceptance: - [ ] Commit the compiler version, artifact identity and SHA-256 pin. - [ ] Provide explicit connected setup that fetches and verifies the compiler. - [ ] Document manual offline staging and verify the staged binary against the same committed checksum. A mismatch fails setup/build rather than executing an unverified compiler. - [ ] CSS builds use the staged binary and never download it automatically. A missing binary produces an actionable setup error. - [ ] A fresh checkout can rebuild the committed CSS bundle using documented setup or offline staging. - [x] ADR 0002 records the standalone compiler as delivered and distinguishes runtime asset independence from development dependencies, including Node tests. The ADR clarification is prepared locally in this triage session; integrate it with the implementation rather than duplicating it.
Author
Owner

ADR 0002 criteria met by PR #63 (2026-09-23).

PR #63 lands the ADR 0002 clarification: Candidate 4 is recorded as delivered (d4660b6, 2026-09-10), the air-gap claim is narrowed to runtime assets, and the Node test harness is stated as still required. Provisioning is referenced back to this issue. Both ADR checkboxes are now ticked.

This supersedes the note "integrate it with the implementation rather than duplicating it": the ADR text is no longer part of this issue's deliverable. Only the pinned-checksum provisioning of Tailwind CLI 3.4.17 (Linux x86-64) remains. If that work changes what the ADR says about provisioning, update the single sentence that points here.

**ADR 0002 criteria met by PR #63** (2026-09-23). PR #63 lands the ADR 0002 clarification: Candidate 4 is recorded as delivered (`d4660b6`, 2026-09-10), the air-gap claim is narrowed to runtime assets, and the Node test harness is stated as still required. Provisioning is referenced back to this issue. Both ADR checkboxes are now ticked. This supersedes the note "integrate it with the implementation rather than duplicating it": the ADR text is no longer part of this issue's deliverable. Only the pinned-checksum provisioning of Tailwind CLI 3.4.17 (Linux x86-64) remains. If that work changes what the ADR says about provisioning, update the single sentence that points here.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
gabogg/hikcentral#57
No description provided.