Skip to content

script/Build.sol declares no codegen paths, so rainix's codegen witness will be a silent no-op here #245

Closed as not planned

Description

@thedavidmeister

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.

Activity

  1. thedavidmeister commented on Oct 5, 2026

    @thedavidmeister
    ContributorAuthor

    Rewritten: the mechanism changed and the consequence is the opposite of what
    this issue said.

    What was wrong

    This issue said rainix#392 reads script/codegen-manifest.txt, and that
    git-clean here "goes red the moment #392 merges".

    Neither holds. #392 (still open, created 2026-09-20) has no manifest file at
    all. The generator declares its own paths on stdout —
    rainix-codegen owns <path> and rainix-codegen wrote <path> — and the
    workflow tees that into a log the new codegen-declaration action reads. Its
    description says why: "Only the generator knows which paths it owns rather than
    deliberately leaves frozen, so it declares them on stdout."

    And it ends: "A repo whose hooks declare nothing is a no-op."

    The actual item

    script/Build.sol declares nothing. So when #392 merges, nothing here goes red
    — the witness is simply inert, and git-clean stays green while providing none
    of the coverage the witness exists to add.

    That is the same shape as the blindness #392 was built for
    (rain.factory.deploy#35): a check that is green because it has no subject. One
    level up, and silent, so nothing will prompt us.

    What to do

    script/Build.sol emits rainix-codegen owns <path> for each path its hooks
    own, and rainix-codegen wrote <path> when it writes one. generatedContracts()
    is already the single list every hook reads, so the declaration derives from it
    rather than being a second list to keep in step — which is the whole point of
    the stdout form over a committed manifest.

    The paths, from generatedContracts():

    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
    

    src/lib/LibRainDeploy.sol is tracked and hand-written, not generated, so it is
    not declared.

    Timing

    #392 is unmerged, and nothing breaks when it merges, so there is no deadline —
    only an absence that will not announce itself.

  2. changed the title [-]Add script/codegen-manifest.txt: git-clean goes red when rainlanguage/rainix#392 merges[/-] [+]script/Build.sol declares no codegen paths, so rainix's codegen witness will be a silent no-op here[/+] on Oct 5, 2026
  3. thedavidmeister commented on Oct 5, 2026

    @thedavidmeister
    ContributorAuthor

    Closing — there is no issue here.

    rainix#392 is unmerged, so the witness does not exist to adopt. When it does
    merge, nothing here breaks and nothing here gets worse: this repo keeps exactly
    the coverage it has today. What is missing is an upstream capability not yet
    taken up, and rainix#392 being open is what tracks that.

    My comment above rewrote this from an obsolete premise into a thinner one rather
    than concluding it should not exist. The correction to the premise stands and is
    worth keeping on the record — #392 reads a stdout declaration rather than
    script/codegen-manifest.txt, and a repo that declares nothing is a no-op, so
    the "git-clean goes red when #392 merges" claim in the title and body was wrong
    — but the conclusion drawn from it was not a reason for an issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions