Skip to content

Guards the package files: list against ADR-0009 - #73

Merged
johnnyt merged 1 commit into
mainfrom
sui-2ke-assets-in-package-files
Sep 2, 2026
Merged

Guards the package files: list against ADR-0009#73
johnnyt merged 1 commit into
mainfrom
sui-2ke-assets-in-package-files

Conversation

@johnnyt

@johnnyt johnnyt commented Sep 2, 2026

Copy link
Copy Markdown
Member

Closes sui-2ke.

Provenance

Campaign 027, statifier-ui lane. Cut from origin/main at 7cbf911; one
commit, no rebase needed (origin/main had not moved at push time), so no
sibling conflict arose. A sibling sui worker may be live on lib/ and
docs/ for the wire-format decisions; this branch touches neither.

Files touched: test/packaging_test.exs (new, 58 lines). Nothing
else - mix.exs is deliberately unchanged, see below.

What this is

ADR-0009 ("JavaScript ships as source") decides that this package's JS is
delivered as source under assets/ and that "assets/ becomes public
API". mix.exs's package() files: list has never named it. Hex
packages exactly what files: names and reports nothing about what it
leaves out, so the first commit to ship JavaScript would have shipped it
into a tarball that silently omitted assets/, with the first symptom
being a host that cannot resolve the import.

Why the files: entry is not in this PR

The bead's original fix was to add assets to files:. Probed on this
branch: hex refuses to build a package whose files: names a directory
that is not on disk.

$ mix hex.build
Building statifier_ui 0.2.0
...
** (Mix) Stopping package build due to errors.
Missing files: assets

(hex 2.5.0, Elixir 1.18.3, OTP 27.3. mix hex.publish shares that code
path.) assets/ does not exist yet, so adding the entry today would break
the next release in order to prevent a later one. Committing a placeholder
assets/ was the other option and is barred: ADR-0009 names no layout for
this package's own assets tree - every assets/package.json in the record
is the host's file - so a placeholder would invent the first slice of a
declared-public-API surface, which is a contract call rather than a
packaging fix.

The bead was re-scoped to the guard only. The first JS ship (sui-wqr, or
the ADR-0008 elkjs renderer) adds the files: entry alongside its first
real asset, and this test is what makes forgetting it impossible.

The guard

test/packaging_test.exs asserts that every top-level directory an
accepted ADR declares published appears in files: once it exists on
disk
. The declared set is a tracked module attribute citing its record,
not something inferred from the filesystem, and a second test keeps that
list from being quietly emptied into a vacuous pass.

Verified in all three states:

assets/ on disk in files: result
no no green (today's state)
yes no red, message names the directory and ADR-0009
yes yes green (the state the first JS ship lands in)

The red case was produced by creating assets/index.js, running the test,
and removing it again; the green-green case by adding assets to files:
at the same time and reverting both. Neither probe is in the commit.

Changelog

No fragment. changelog.d/README.md excludes "test harness or internal
test-support changes", and nobody calling the public API can tell the
difference - the packaged tarball is byte-identical to before this PR.

ADR

No ADR touch. The record already says everything the guard relies on
("assets/ becomes public API"); the test's own header comment carries the
hex-refuses-a-missing-directory finding, which is a toolchain fact rather
than a decision.

Gate

Full mix quality green on this HEAD, attested (mix quality.verify,
data.attested: true): 880 of 880 tests, 92.8% coverage, dialyzer clean,
credo strict clean, doctor passed. The two lines are the permanent
Gettext and Sobelow skips declared in gate.not_applicable_skips.

ADR-0009 makes `assets/` public API, published with the package, but
`mix.exs`'s `files:` list never named it. Nothing catches that: hex
prints what it packages and says nothing about what it omits, so the
first commit to ship JavaScript would have shipped it into a tarball
that silently left `assets/` out.

The entry itself cannot land yet - hex refuses to build a package whose
`files:` names a directory that is not on disk ("Missing files:
assets"), so listing it today would break `mix hex.publish` in order to
prevent a later breakage. The guard is conditional instead: a directory
an accepted ADR declares published must appear in `files:` once it
exists on disk. Adding the first file under `assets/` turns the test
red unless the same commit adds the entry.

Verified in all three states: absent and unlisted (green), present and
unlisted (red, naming the directory and the ADR), present and listed
(green).

Refs: sui-2ke
@johnnyt
johnnyt merged commit 662a6f6 into main Sep 2, 2026
1 check passed
@johnnyt
johnnyt deleted the sui-2ke-assets-in-package-files branch September 2, 2026 13:55
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