What changes, and when
rainlanguage/rainix#392 adds a
codegen witness to the rainix-copy-artifacts reusable workflow. This repo's
.github/workflows/git-clean.yaml calls that workflow at @main, so the check
arrives the moment #392 merges — not when this repo chooses to adopt it. The
next push after that merge fails until a manifest is committed.
Why the check exists
rainix-copy-artifacts currency-checks committed generated sources by re-running
the codegen hooks and then git diff --exit-code. That proves the committed
content is current, but it is structurally blind to a generator that has
stopped emitting a file: the committed copy is already correct, so nothing is
rewritten, nothing differs, and the job is green over a dead emitter. Reproduced
with a control in
rainlanguage/rain.factory.deploy#35.
Seeing that needs an independent statement of which committed files are
generated. That is script/codegen-manifest.txt: one repo-relative path per line,
# comments and blank lines ignored. The witness marks every git-tracked file's
mtime before the first hook and verifys after the last, calling a file
written when it exists and its mtime moved. Any declared path nothing wrote
fails the job by name.
Why this repo is affected
Hook present: script/Build.sol. No script/codegen-manifest.txt today.
What to add
script/codegen-manifest.txt:
src/generated/candidate/AddressRegistry.sol
src/generated/candidate/MigrationRegistry.sol
src/lib/LibAddressRegistryDeploy.sol
src/lib/LibMigrationRegistryDeploy.sol
src/lib/LibAddressRegistryReleased.sol
src/lib/LibMigrationRegistryReleased.sol
src/lib/LibReleasedSuites.sol
How that was derived
script/Build.sol declares two generated contracts — AddressRegistry and
MigrationRegistry — and generatedContracts() is the only list every hook reads.
Against src/lib/LibRainDeploySnapshot.sol in this repo:
regenerateSnapshots() → writeSnapshot(..., recordRoot(), CANDIDATE, <Contract>, ...)
→ src/generated/candidate/<Contract>.sol, one per contract.
regenerateLibs() → writeAliasLib(...) → src/lib/Lib<Contract>Deploy.sol;
writeReleasedSuitesLib(...) → src/lib/Lib<Contract>Released.sol;
writeReleasedSuitesAggregate(...) → src/lib/LibReleasedSuites.sol
(RELEASED_SUITES_LIBRARY, in LIB_DIR = "src/lib").
Every one of those seven paths is committed today, and no other file under
src/generated/candidate/ or matching src/lib/Lib*{Deploy,Released}.sol is.
Deliberately excluded
src/generated/0_1_7/, 0_1_8/, 0_1_10/, 0_1_11/ — frozen release snapshots,
written only by cutRelease(), never by the run() the copy-artifacts job calls.
Declaring them would fail every run. src/lib/LibAddressRegistry.sol and
src/lib/LibMigrationRegistry.sol are hand-maintained, not emitted (the generated
alias libs are the ...Deploy.sol pair).
Reconciling against the job
The failing verify step prints the manifest that run would justify — the set
of git-tracked files the hooks actually wrote in CI. Treat that printout as the
oracle and the list above as a cross-check derived by reading the hooks. A
difference either way is information, not noise:
- listed above, absent from the printout — that emitter may already be dead, or
the file is generated by something the copy-artifacts job does not run.
- printed, absent from above — an incidental write inside the witness window
(forge build is in there), or a generated file this reading missed.
Undeclared-but-written paths are a printed note, never a failure — the check is
a subset assertion, not set equality — so a conservative first manifest is safe and
an over-eager one is not.
Adoption
One commit adding script/codegen-manifest.txt. No workflow edit and no
RAINIX_SHA bump: #392 wires the witness as a composite action resolved at
@main, so nothing in this repo pins the check's version.
Filed while tracking the org-wide adoption cost of rainlanguage/rainix#392. The
paths above were derived by reading this repo's own hooks and committed tree, not
by running the job.
What changes, and when
rainlanguage/rainix#392 adds a
codegen witness to the
rainix-copy-artifactsreusable workflow. This repo's.github/workflows/git-clean.yamlcalls that workflow at@main, so the checkarrives the moment #392 merges — not when this repo chooses to adopt it. The
next push after that merge fails until a manifest is committed.
Why the check exists
rainix-copy-artifactscurrency-checks committed generated sources by re-runningthe codegen hooks and then
git diff --exit-code. That proves the committedcontent is current, but it is structurally blind to a generator that has
stopped emitting a file: the committed copy is already correct, so nothing is
rewritten, nothing differs, and the job is green over a dead emitter. Reproduced
with a control in
rainlanguage/rain.factory.deploy#35.
Seeing that needs an independent statement of which committed files are
generated. That is
script/codegen-manifest.txt: one repo-relative path per line,#comments and blank lines ignored. The witnessmarks every git-tracked file'smtime before the first hook and
verifys after the last, calling a filewritten when it exists and its mtime moved. Any declared path nothing wrote
fails the job by name.
Why this repo is affected
Hook present:
script/Build.sol. Noscript/codegen-manifest.txttoday.What to add
script/codegen-manifest.txt:How that was derived
script/Build.soldeclares two generated contracts —AddressRegistryandMigrationRegistry— andgeneratedContracts()is the only list every hook reads.Against
src/lib/LibRainDeploySnapshot.solin this repo:regenerateSnapshots()→writeSnapshot(..., recordRoot(), CANDIDATE, <Contract>, ...)→
src/generated/candidate/<Contract>.sol, one per contract.regenerateLibs()→writeAliasLib(...)→src/lib/Lib<Contract>Deploy.sol;writeReleasedSuitesLib(...)→src/lib/Lib<Contract>Released.sol;writeReleasedSuitesAggregate(...)→src/lib/LibReleasedSuites.sol(
RELEASED_SUITES_LIBRARY, inLIB_DIR = "src/lib").Every one of those seven paths is committed today, and no other file under
src/generated/candidate/or matchingsrc/lib/Lib*{Deploy,Released}.solis.Deliberately excluded
src/generated/0_1_7/,0_1_8/,0_1_10/,0_1_11/— frozen release snapshots,written only by
cutRelease(), never by therun()the copy-artifacts job calls.Declaring them would fail every run.
src/lib/LibAddressRegistry.solandsrc/lib/LibMigrationRegistry.solare hand-maintained, not emitted (the generatedalias libs are the
...Deploy.solpair).Reconciling against the job
The failing
verifystep prints the manifest that run would justify — the setof git-tracked files the hooks actually wrote in CI. Treat that printout as the
oracle and the list above as a cross-check derived by reading the hooks. A
difference either way is information, not noise:
the file is generated by something the copy-artifacts job does not run.
(
forge buildis in there), or a generated file this reading missed.Undeclared-but-written paths are a printed note, never a failure — the check is
a subset assertion, not set equality — so a conservative first manifest is safe and
an over-eager one is not.
Adoption
One commit adding
script/codegen-manifest.txt. No workflow edit and noRAINIX_SHAbump: #392 wires the witness as a composite action resolved at@main, so nothing in this repo pins the check's version.Filed while tracking the org-wide adoption cost of rainlanguage/rainix#392. The
paths above were derived by reading this repo's own hooks and committed tree, not
by running the job.