Skip to content

runPh5: make the downstream patch an explicit input, and record provenance - #318

Open
dcasota wants to merge 1 commit into
masterfrom
staging/runsh-driveable
Open

runPh5: make the downstream patch an explicit input, and record provenance#318
dcasota wants to merge 1 commit into
masterfrom
staging/runsh-driveable

Conversation

@dcasota

@dcasota dcasota commented Aug 31, 2026

Copy link
Copy Markdown
Owner

Adapting run*.sh so an automated driver can use them, without giving up standalone use.

The actual defect

Not "two copies of a file exist". The script derives a critical input from its own location and then picks silently among candidates, so three properties are missing:

  • a caller cannot say which patch it means
  • the choice is never announced
  • divergence is never detected

On this host the two copies have drifted 78 lines apart and carry 8 vs 27 files:

/root/photonos-patches/downstream-fixes.patch                  27 files  <- applies
staging/photonos-patches/downstream-fixes.patch                 8 files  <- does not

The build used whichever sat beside the script that happened to be invoked, and the failure surfaced as patch does not apply against SPECS/linux/linux.spec:77 — which reads like a rebase problem rather than a path problem. It cost two failed builds and two wrong diagnoses before I looked at the path. The only workaround available to a driver was to stage a fake script directory, which is a symptom, not a fix.

Three changes, all additive

DOWNSTREAM_PATCH becomes an input. Set it and it wins; leave it unset and the historical search runs exactly as before, so the zero-argument standalone path is byte-identical. A caller-specified file that does not exist is a hard error rather than a silent fallback to something else.

The resolution is announced, with identity.

[runPh5_normal] downstream patch: /root/photonos-patches/downstream-fixes.patch (27 files, sha 1a2b3c4d5e6f7890)

A silent choice is precisely how the two copies diverged unnoticed.

Ambiguity is refused. Two candidates with identical content are fine. Two that differ stop the build and print both paths, file counts and hashes:

[runPh5_normal] ERROR: several downstream-fixes.patch copies exist and they DIFFER:
[runPh5_normal]   /tmp/lt/a/photonos-patches/downstream-fixes.patch (1 files, sha 195b9e406d18e616)
[runPh5_normal]   /tmp/lt/b/photonos-patches/downstream-fixes.patch (2 files, sha dfa8b1b4db4787fc)
[runPh5_normal]        Set DOWNSTREAM_PATCH=<path> to choose deliberately.

Continuing would make the artefact a coin toss.

Provenance sidecar

runPh5_normal.sh also writes <iso>.build-manifest.json beside the ISO: image type, canister mode, release branch, tree HEAD, patch path and sha256, ISO sha256, build time.

An ISO with no record of what produced it cannot be attributed to a patch set later — and a driver should not have to scrape Moved ISO to out of a log to find its own artefact.

Verification

A full build was running against the shared tree at the time, so the resolution block was exercised directly rather than by running the script:

case result
caller-specified wins, marked (caller-specified)
caller-specified but missing refuses, exit 1
two copies, differing refuses, prints both hashes
two copies, identical proceeds, names the winner
single copy as before, names it
no copy silent, unchanged

sh -n clean on both scripts.

Scope

Only runPh5_normal.sh and runPh5_pinned90.sh carry the patch-search logic; runPh4.sh, runPh5_pinned91.sh and runPh6.sh do not apply a downstream patch at all and are untouched. The manifest is currently only in runPh5_normal.sh — worth extending to the others if this shape is agreed.

Two things deliberately not done here, as they are larger decisions:

  • Named flags alongside the six positional parameters. $1..$6 is at its practical limit; --img-type/--canister/--output would extend cleanly while keeping positional as the documented quick path.
  • Collapsing the duplicate scripts. The real cure for divergence is one copy plus a symlink, rather than detecting drift after the fact. That is an environment decision rather than a code one, so this PR only makes the drift impossible to ignore.

…nance

Adapting these for an automated driver without giving up standalone use.

The problem is not that two copies of downstream-fixes.patch exist. It is
that the script DERIVES a critical input from its own location and then picks
silently among candidates, so three properties are missing: a caller cannot
say which patch it means, the choice is never announced, and divergence is
never detected. The two copies on this host have drifted 78 lines apart and
carry 8 vs 27 files; the build simply used whichever sat beside the script
that happened to be invoked, and the failure surfaced as
"patch does not apply" against SPECS/linux/linux.spec:77 - which reads like
a rebase problem rather than a path problem. The only workaround available to
a driver was to stage a fake script directory.

Three changes, all additive:

  DOWNSTREAM_PATCH is now an input. Set it and it wins; leave it unset and
  the historical search runs exactly as before, so the zero-argument
  standalone path is byte-identical. A missing caller-specified file is a
  hard error rather than a silent fallback.

  The resolution is announced, with identity:
    [runPh5_normal] downstream patch: /root/photonos-patches/... (27 files, sha 1a2b3c...)
  A silent choice is how the two copies diverged unnoticed in the first place.

  Ambiguity is refused. Two candidates with identical content are fine; two
  that differ stop the build and print both paths, file counts and hashes,
  because continuing would make the artefact a coin toss.

runPh5_normal.sh additionally writes <iso>.build-manifest.json next to the
ISO: image type, canister mode, tree HEAD, patch path and sha256, ISO sha256
and build time. An ISO with no record of what produced it cannot be
attributed to a patch set later, and a driver should not have to scrape
"Moved ISO to" out of a log to find its own artefact.

Verified by exercising the resolution block directly, since a full build was
running against the shared tree at the time:
  caller-specified wins; caller-specified but missing refuses; two differing
  copies refuse and print both hashes; two identical copies proceed and name
  the winner; a single copy behaves as before; no copy stays silent.

Signed-off-by: Daniel Casota <dcasota@gmail.com>
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