Skip to content

ci: pin the eBoot and ebuild checkouts instead of floating on master - #135

Merged
srpatcha merged 3 commits into
embeddedos-org:masterfrom
Kartikey1306:ci/pin-cross-repo-dependencies
Sep 8, 2026
Merged

srpatcha merged 3 commits into
embeddedos-org:masterfrom
Kartikey1306:ci/pin-cross-repo-dependencies

Conversation

@Kartikey1306

@Kartikey1306 Kartikey1306 commented Sep 3, 2026 •

Copy link
Copy Markdown
Contributor

What every red eos PR has in common

All 12 other open eos PRs fail EoS Full-Stack Simulation, and none of them caused it. Verified per PR rather than assumed: the same error: 'eos_image_header_t' has no member named 'reserved' on every one. The kernel job checks out embeddedos-org/eBoot at ref: master, and eBoot master does not compile — include/eos_image.h:135/142 assert offsetof(eos_image_header_t, reserved) for a member that became tlv_len + tlv_hash, and core/ed25519_verify.c redefines point_is_identity. Two pairs of PRs that merged clean and broke the build together; eBoot #94 repairs it and waits on review. Until it lands, no change to any eos PR can turn this job green — and after it lands, the next broken eBoot master does the same thing to every open PR again.

The change

Pin the two compiled-against checkouts to recorded SHAs, set in one env: block:

  • EBOOT_COMMIT = a172a6d6e1e6 — the newest eBoot master ancestor that compiles. Found by walking master backwards and building each candidate, not by reading history: abd4dab already fails (the ed25519 redefinition entered at 8a015b2, its child).
  • EBUILD_COMMIT = e5d8052f3e2c — ebuild's current master, frozen as-is. Both ebuild checkouts feed steps that are commented out (eFab does not exist), so this pin removes the float and changes nothing else.

The middleware matrix (10 repos) still floats deliberately: those jobs run each repo's own tests rather than compiling eos against them, and 10 more pins deserve their own decision.

This is the dependency rule .ai/platform.md already states — a consumer depends on a version, not on the moving head of another repo's tree. When eBoot #94 merges, bump EBOOT_COMMIT to the merge SHA; the bump is a one-line diff that gets its own CI run.

The other half: the pin must not go stale silently

A pin alone makes the trade worse in one direction. Today an eBoot master that does not compile turns 12 eos PRs red — loud, attributable, useless. With the pin it turns nothing red, and eos stops being able to see it at all. The pin would then sit at a172a6d indefinitely, because nothing would ever ask, while it silently drops the 6 eBoot commits that follow it (#57, #76, #87, #91, #92, #93 — real security fixes among them).

So the pin ships with .github/workflows/upstream-drift.yml, which builds eBoot at master and compares both pins against their master:

  • Its own workflow file, on a schedule (17 6 * * *) and workflow_dispatch — never pull_request. A PR must not be red for a break it did not cause; that is the entire point of the pin. The first draft was a job inside eos-simulation.yml guarded by if: github.event_name == 'schedule' — and the run showed it on the PR as a SKIPPED check. A required-check gate that treats any non-success as a failure, which is the design in ci: add one job branch protection can require #121, would trip on exactly that. Its own file removes it from PR runs entirely, rather than relying on every future gate to remember to exempt it.
  • Not continue-on-error. A job that reports success over a failure is the fail-open shape this repo keeps filing against (.ai/reviewer.md; the aggregating gates in ci: add one job branch protection can require #121). This one is free to fail honestly because it gates nothing.
  • Failing is reserved for "upstream does not build." A pin merely behind a healthy master is a ::warning:: plus a step-summary row — actionable, not broken.
  • The pins are read out of eos-simulation.yml, not copied. A second copy of a SHA is a second thing to forget. The read demands a 40-character hex value and fails closed if it cannot find one, so a renamed or reformatted key stops the job rather than letting it silently check a pin of "".
  • The failure message is scoped to steps.eboot.outcome, so a checkout, apt or pin-read failure cannot report itself as evidence about eBoot's master. The summary states plainly that eBoot is built and ebuild is only compared, rather than implying both were checked.

Net effect: an eos PR can no longer go red for another repository's break, and an upstream break is still loud — on a run that blocks nobody and names the repository responsible.

Validation of the drift job (before pushing)

Run against the real repositories, not reasoned about:

case result
eBoot @ a172a6d (the pin), host build rc=0, 0 errors
eBoot @ 22d8f8b (master), host build rc=2 — no member named 'reserved' at eos_image.h:135 and :142, the same defect CI reports
pin extraction, real workflow file both SHAs read; the eBoot one resolves to #86's merge
pin extraction, key renamed to EBOOT_SHA fails closed, rc=1
pin extraction, value unquoted and shortened fails closed, rc=1
drift logic, pin 6 behind a healthy master "behind by 6" warning, no failure
drift logic, pin absent from master "not an ancestor" warning, exit 0 under set -e
drift logic, pin equal to master no warning
both workflow YAMLs parse; drift has 8 steps ✓
eos on this branch: cmake --build / ctest / pytest rc=0 / 39 of 39 / 15 of 15, with the new workflow file present

The first draft of the missing-pin branch printed pinned pin not found on master commit(s) behind — caught by running that branch rather than reading it, and rewritten into its own message.

Validation of the pin (before pushing)

check result
eBoot@master, job's own config (qemu_arm64, VERIFY_STAGE1=OFF, Release, cross) fails — the exact eos_image.h assert errors from the job log
eBoot@a172a6d, same config, full build rc=0, every target
Both pinned SHAs reachable from their repos' master ✓
Workflow YAML parses; diff is the env block + three ref: lines ✓

The live test is this PR's own simulation run: it uses this branch's workflow, so it should go green while every master-based PR stays red on that job. If it does not, the pin is wrong and this PR should not merge.

Findings labels: the two eBoot master defects and the walk to a172a6d are Verified (built locally, negative and positive controls); the claim that a merged eBoot #94 stays green under this job is Inferred until its SHA exists to pin.

…removed

`CI — eos` and `Python Unit Tests` are red on master (769191a), and both
fail for one reason:

    these suites exist in tests/ but no add_executable() in
    tests/CMakeLists.txt builds them, so they never run:
    ['test_crypto_ed25519_loworder.c']

3aa8644 (embeddedos-org#93, "remove duplicate test targets from tests/CMakeLists.txt")
removed all four lines that build and register
test_crypto_ed25519_loworder. It was not a duplicate — there was exactly
one registration before that commit, and it took it.

What stopped running is the suite that guards embeddedos-org#101: Ed25519 rejecting
low-order public keys. A low-order key makes every term of the
verification equation collapse to the identity regardless of the
message, so a signature of all zeros verifies against any content at
all. The fix is still in services/crypto/src/ed25519_verify.c and still
correct; nothing has been checking it since embeddedos-org#93 merged, and nothing
would have noticed if a later change had removed it too.

Restored verbatim from 3aa8644^, in its original position before
test_crypto_sha512. No other file changes.

The guard that caught this is test_cmake_test_registration.py, added
recently. It did exactly its job — this is the first thing it found.

Verified:
  test_cmake_test_registration.py    -> 5 passed (1 failed on master)
  pytest tests/                      -> 15 passed (14 passed 1 failed on master)
  test_crypto_ed25519_loworder       -> 5/5 tests passed
  ctest                              -> 39/39 passed (master builds 38)

@srpatcha srpatcha left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review — eos#135 "ci: pin the eBoot and ebuild checkouts instead of floating on master"

head: 9628c9a author: Kartikey1306 ci: fail (2 checks — unrelated, see below)

Verdict: Correct, minimal, and the diagnosis holds — I reproduced it independently
before reading the PR body. The pinned eBoot SHA builds and eBoot master does not. The
remaining questions are about what the pin gives up, not whether it is right.

Findings

# Severity File:line Finding Recommended fix
1 Medium .github/workflows/eos-simulation.yml:41 The pin removes the false red, and with it the only signal eos had that eBoot master had stopped compiling. After this merges, eBoot master can break and stay broken without eos noticing until someone bumps EBOOT_COMMIT — at which point the breakage is discovered late and attributed to the bump. The problem being solved is that the signal was attached to the wrong thing (every PR), not that the signal was unwanted. Add a schedule:-triggered job that runs the same kernel build against embeddedos-org/eBoot@master and is not a required check. Nightly red there names the real owner; PR checks stay green. Roughly ten lines, reusing the existing job with a different ref:.
2 Low .github/workflows/eos-simulation.yml:16 Nothing detects that EBOOT_COMMIT has gone stale. The comment says to bump it when eBoot#94 lands, which is a human promise with no reminder attached; the pin was six commits behind eBoot master when I checked. Six months from now the number is silently ancient and the simulation job is testing an integration nobody ships. The scheduled job in finding 1 can carry this: assert the pin is still an ancestor of eBoot master, and fail (or open an issue) once it falls more than N commits or D days behind.
3 Low .github/workflows/eos-simulation.yml:247-248 The 10-repo middleware matrix still uses ref: master. The body's justification is sound — those legs run each repo's own tests rather than compiling eos against them — but the failure mode it is exposed to is the same one this PR exists to remove: a middleware repo's master breaks, and eos PRs go red for a cause no eos change introduced. All ten legs happen to be green on this head, so this is exposure, not a current defect. No change needed now. When it bites, apply the same treatment rather than re-deriving the argument.
4 Low PR body The body says "the live test is this PR's own simulation run … If it does not [go green], the pin is wrong and this PR should not merge", but does not report the outcome. From checks.txt, the simulation-family jobs are green — QEMU ARM64 simulation (13 TCs), Full-stack integration summary, Cross-compile ARM64 kernel. Stating that closes the loop the body opens. Add the result to the body.

Architecture conformance

Conforms, and improves conformance. .ai/platform.md states the rule directly:
"A consumer depends on a component with a version range, never on a git URL or a path into
another repo's tree." Master design §10 says the same — "Repositories should not be the
dependency API." Floating on ref: master is the extreme case of the thing both prohibit;
a recorded SHA is a genuine step toward the rule even though it does not reach it.

One thing worth recording, because it explains why the author could not do better and
because it is a defect in another repo: .github/STANDARDS.md ("Release model") already
prescribes the mechanism a consumer should use — pin to a vX.Y.Z tag, or track the
release branch, which sync-release-branch.yml is supposed to force-update on every
release tag. That mechanism is currently broken for eBoot: refs/heads/release points
at fa2b3b1, which is v1.5.0, while v3.0.1 exists at 35ed483. The release branch
has not tracked a release tag in some time, and v3.0.1 itself dates from 2026-05-16 —
far behind the API this workflow compiles against. So ref: release and ref: v3.0.1
were both unusable here, and the raw SHA is the defensible choice. That is an eBoot
release-automation bug, not an eos one; it should be filed there.

No layering violation. This is CI configuration, and §5.1's rule that eBuild "understands
the complete graph but is not a runtime dependency" is untouched — nothing here becomes a
runtime dependency.

What I verified

Independently, before reading the PR body, and reaching the same conclusion:

  • origin/master of eBoot (22d8f8b) does not compile. Extracted to a scratch
    directory and configured with eBoot's own CI host settings: include/eos_image.h:135
    and :142 assert offsetof/sizeof on a reserved member that tlv_len + tlv_hash
    replaced, and core/ed25519_verify.c:338 redefines point_is_identity already defined
    at :281.

  • The pinned a172a6d6e1e66877413ed546401a65ee4f4f90db does compile:

    cmake -S . -B b -DCMAKE_BUILD_TYPE=Release -DEBLDR_VERIFY_STAGE1=OFF && cmake --build b
    -> PINNED_SHA_BUILD_OK
    

    Neither defect is present at that SHA (0 stale reserved asserts vs 2 on master;
    1 definition of point_is_identity vs 2 on master).

  • Both pinned SHAs exist and are ancestors of their repositories' masters. a172a6d is
    6 commits behind eBoot master; e5d8052 is ebuild master's own tip.

  • env is available to jobs.<id>.steps.*.with, so ref: ${{ env.EBOOT_COMMIT }}
    resolves. No other cross-repo checkout in the eos workflow tree is left floating except
    the middleware matrix at line 247 (finding 3) and the two commented-out eFab blocks.

CI state

Two checks fail on this head, and neither is caused by this PR — a change to
eos-simulation.yml cannot affect either:

  • Build & Test (Linux x86_64) — fail
  • Run Python tests — fail

Both fail on the same assertion, and it is worth reading:

tests/unit/test_cmake_test_registration.py::test_every_c_suite_is_built_or_listed
AssertionError: these suites exist in tests/ but no add_executable() in
tests/CMakeLists.txt builds them, so they never run:
['test_crypto_ed25519_loworder.c']

So an Ed25519 low-order-key suite is present in eos tests/ and is compiled by nothing —
a security suite that silently collects nothing, which is exactly the failure mode
.ai/security.md ("Fail closed") names. The meta-test is working correctly by failing.
Recent master runs show Python Unit Tests and CI — eos already failing, so this is a
master condition, not a PR regression. Open PR eos#127 ("fix(build): restore the
low-order Ed25519 suite that #93 removed") covers it
, so per the review policy I have
opened no fix PR. #127 should merge; it unblocks the whole open queue.

Proposed changes

  1. Merge as is — the change is correct and the alternative is eleven PRs that cannot go
    green.
  2. Add the scheduled unpinned job (findings 1 and 2) as a follow-up, in the same PR that
    bumps EBOOT_COMMIT after eBoot#94 lands. That bump is the natural moment: it is when
    someone is already looking at this file.
  3. File the stale release branch against eBoot separately.

Not checked

  • I did not run the workflow. GitHub Actions was not executed here; the env-in-with
    resolution and the job's overall behaviour are read from the YAML and from the reported
    check results, not observed. The PR's own green simulation run is the evidence that
    matters and it is present in checks.txt.
  • I did not verify that eBoot#94's eventual merge SHA will build under this job. It
    does not exist yet. The PR body labels this Inferred, which is the correct label.
  • I did not root-cause test_crypto_ed25519_loworder.c's removal or confirm that the
    suite passes once registered — only that it is unbuilt and that eos#127 claims to
    restore it.
  • Not examined: whether the 10 middleware matrix legs are required checks for merge, which
    decides how much finding 3 actually costs.

Automated architecture review of 9628c9a6f134 — scheduled, model claude-opus-5, checked against the EmbeddedOS Master Design v2.0. Advisory only: this reviewer never approves, requests changes, or merges. Reply here to discuss or push back — a wrong finding is a bug worth reporting.

Every open eos pull request is currently red on `EoS Full-Stack Simulation`,
and none of them caused it. The kernel job checks out embeddedos-org/eBoot at
`ref: master`, and eBoot master does not compile: include/eos_image.h:135 and
:142 static-assert offsetof(eos_image_header_t, reserved) for a member that
became tlv_len + tlv_hash, and core/ed25519_verify.c redefines
point_is_identity -- two pairs of PRs that each merged clean and broke the
build together. eBoot embeddedos-org#94 repairs it and waits on review; until it lands, no
change to any eos PR can make this job pass, and after it lands the next
broken eBoot master does the same thing again.

A floating `ref: master` makes every eos PR's CI depend on the moment-to-
moment state of another repository's default branch. Pinning the two
compiled-against checkouts makes the job a function of this repository plus
two recorded SHAs -- red means the PR broke something, green means it did not,
and a cross-repo bump is a reviewable one-line diff with CI on it.

  EBOOT_COMMIT  a172a6d6e1e6  the newest eBoot master ancestor that compiles;
                found by walking master back and building each candidate.
                Its child 8a015b2 already carries the ed25519 redefinition.
  EBUILD_COMMIT e5d8052f3e2c  ebuild's current master, frozen as-is. Both of
                its checkouts feed steps that are commented out (eFab does
                not exist), so this pin only removes the float.

The middleware matrix (10 repos) still floats; it runs those repos' own
tests rather than compiling eos against them, and 10 more pins deserve their
own decision. When eBoot embeddedos-org#94 merges, bump EBOOT_COMMIT to the merge SHA.

Verified before pushing, master vs pin under the job's own configuration
(-DEBLDR_BOARD=qemu_arm64 -DEBLDR_VERIFY_STAGE1=OFF -DCMAKE_BUILD_TYPE=Release,
cross-compile mode): eBoot@master fails at the eos_image.h asserts, the exact
error in the job log; eBoot@a172a6d builds every target, rc=0. Both pinned
SHAs verified reachable from their repos' master. Workflow parses; the three
`ref:` edits and the env block are the whole diff. This PR's own simulation
run is the live test: it uses this branch's workflow and should go green
while every master-based PR stays red.
@Kartikey1306
Kartikey1306 force-pushed the ci/pin-cross-repo-dependencies branch from 9628c9a to 001128d Compare September 4, 2026 06:06
@Kartikey1306

Copy link
Copy Markdown
Contributor Author

Rebased onto #127 (001128d) rather than carrying a fourth copy of the test_crypto_ed25519_loworder registration hunk — #127 is the anchor for that fix and this respects the requested merge order (#127 first, then this fast-forwards). The two checks that were red here (Python Unit Tests, CI — eos Build & Test) failed on master's missing registration, not on the pin; verified locally on the rebased branch before pushing: 11/11 Python unit tests including the registration guard, full C build, ctest 39/39. The simulation job was already green on the previous head — the pin doing its job — and should stay green here.

@srpatcha srpatcha left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review — eos#135 "ci: pin the eBoot and ebuild checkouts instead of floating on master"

head: 001128d author: Kartikey1306 ci: pass (25/25)

Verdict: The right change, correctly implemented and empirically green — this is the
fix an existing architecture proposal in this repo asked for by name. Two things it should
carry before merge: a way to notice when the pin goes stale, and a sentence recording why
a bare SHA was used where the org standard names a tag or release.

The premise still holds as of this run. eBoot origin/master (22d8f8b) has two
definitions of static int point_is_identity(gf p[4]) in core/ed25519_verify.c, at
lines 281 and 338 — a hard redefinition error, so the tree does not compile. a172a6d is
an ancestor of eBoot master, six commits back, and a descendant of v3.0.1. All verified
locally against the fetched eBoot clone.

CI settles the mechanical questions: Cross-compile ARM64 kernel (the job that performs
the pinned checkout) passes in 47s, QEMU ARM64 simulation (13 TCs) passes, and
Full-stack integration summary passes. That confirms ${{ env.EBOOT_COMMIT }} resolves
inside a step-level with: and that a172a6d builds under the job's own configuration.

tests/CMakeLists.txt registers test_crypto_ed25519_loworder, whose source exists on
origin/master at tests/test_crypto_ed25519_loworder.c but appears in no add_test
there — a low-order-point rejection test that has never run. The rebase rationale and
merge order are already covered in the PR thread and are not repeated here.

Findings

# Severity File:line Finding Recommended fix
1 Medium .github/workflows/eos-simulation.yml:12–19 The pin has no staleness signal. Once eBoot master compiles again, nothing in this repo notices that EBOOT_COMMIT is behind, and the full-stack simulation goes on certifying eos against an eBoot that predates 8a015b2 (#92 Ed25519 subgroup check), abd4dab (#93 authenticated TLV anti-rollback), bbd997a (#87 sign the whole .efw header rather than four fields) and 32723b3 (#76 application-slot boundary hardening). Today that costs nothing, because the alternative is a job that cannot build at all. After eBoot #94 lands it becomes a silently narrowing integration test, and the only thing scheduled to catch it is a human remembering the comment. Add a non-required scheduled job — nightly.yml and weekly.yml already exist here — that runs the build-kernel steps with ref: master for eBoot and reports without gating. Cheap, and it converts "somebody bumps this" into a signal. A second option, complementary: fail the job when git rev-list --count $EBOOT_COMMIT..origin/master in the checked-out eBoot exceeds a stated threshold, so the pin has to be re-justified rather than merely inherited.
2 Low .github/workflows/eos-simulation.yml:18–19 Pinning by bare commit SHA is outside the three targets .github/STANDARDS.md documents for a consumer ("a specific vX.Y.Z tag", "the release branch", "the master branch"), and the PR does not say why. It is the correct call here — origin/release in eBoot is fa2b3b1 dated 2026-05-28, 53 commits behind this pin and 59 behind master, so pinning release would test a three-month-old bootloader; and eBoot's tag sequence is non-monotonic (v3.0.1 is dated 2026-05-16 and is an ancestor of v1.5.0, dated 2026-05-28), so "the newest tag" is ambiguous in that repo. But a reader six months from now sees an unexplained hex string against a standard that names three other options. Extend the existing env: comment with one line: the released refs were evaluated and rejected, release is 53 commits behind, tag ordering in eBoot is inconsistent, so a recorded SHA is the only ref that both compiles and carries the fixes this job needs. The upstream repair belongs in eBoot, not here.
3 Low PR body, "What every red eos PR has in common" Half the stated diagnosis no longer reproduces. The body cites include/eos_image.h:135/142 asserting offsetof(eos_image_header_t, reserved); on eBoot master today those asserts read offsetof(..., tlv_len) == 62 and offsetof(..., tlv_hash) == 64 and agree with the struct at lines 53–54 — repaired by bbd997a (#87). The surviving break is only the point_is_identity redefinition. The conclusion is unaffected; the evidence trail is now half-wrong, which matters because the next person to re-derive the pin will check the header first and find nothing. Update the body (or add a comment) to name the single remaining cause.
4 Low PR body, "The change" The rule cited does not quite say what the change does. .ai/platform.md reads: a consumer "depends on a component with a version range, never on a git URL or a path into another repo's tree. A PR that reaches across repos by path is a finding." This job still consumes eBoot by actions/checkout of a git repository; pinning narrows the blast radius without satisfying the rule. That is not a defect in this PR — the master design defines no cross-repo CI binding at all, which is exactly the gap an addendum appended this run records. Cite it as "the direction .ai/platform.md points" rather than as a rule this change satisfies.

Architecture conformance

Conforms; and it implements a recorded position rather than inventing one.

  • §5.1 (architectural law). No runtime dependency changes. eos and eBoot are both
    Tier 1 — Foundation (§21), and boot sits below the kernel, so compiling eBoot inside an
    eos full-stack simulation runs down-tier, not up. The two ebuild checkouts feed steps
    that are commented out (eFab does not exist), so §5.1's "eBuild … is not a runtime
    dependency" is not touched.
  • §21. Both repos are Tier 1; no code moves between repositories, so §21.1's split
    policy is not engaged.
  • §23.2 (compatibility contract). Lists EoS API, ABI, Driver API, eBuild project
    format, package format, firmware format and board definitions. None of them binds a
    cross-repository source checkout — which is why this PR has to invent its own mechanism.
  • .ai/autoreview/proposals/2026-09.md, 2026-09-03, "§5.1 governs runtime dependencies
    and says nothing about build- or CI-time ones": its migration note ends "Do the eBoot
    pin first — it is the one currently failing, and it unblocks five open pull requests
    immediately." This PR is that step. Its one divergence from that proposal is the released
    ref, which is finding 2, and which the proposal itself flagged as the part that "cannot be
    done blind."

The deliberately-unpinned middleware matrix at line 239 (ref: master across ten repos)
is consistent with the PR body and is left for a separate decision. That decision matters:
those ten are higher-tier products gating a Tier-1 foundation repo, which is the §5.1
inversion expressed through CI. It is correctly out of scope here.

Proposed changes

  1. Extend the env: comment per finding 2 — one sentence on why a SHA, with the 53-commit
    figure. No behaviour change.
  2. Correct the diagnosis in the body per finding 3.
  3. Add the drift job (finding 1). Smallest version that works: a
    schedule:-triggered workflow that reuses build-kernel's steps with
    ref: master for eBoot, continue-on-error off but not listed as a required check, so
    it reports without gating anyone's PR.
  4. Merge order is already agreed in the thread; nothing to add.

Not checked

  • eBoot was not built at a172a6d here. That claim rests on this PR's green
    Cross-compile ARM64 kernel job, which is stronger evidence than a local build, but it
    is CI's result and not mine.
  • The non-compilation of eBoot master was established by reading the two
    point_is_identity definitions in origin/master:core/ed25519_verify.c, not by
    attempting a build.
  • eBoot #94's contents were not reviewed, so whether bumping to its merge SHA will hold is
    unknown from here — as the PR body itself labels it.
  • The ten-repo middleware matrix was not exercised; only confirmed unchanged by this diff.
  • test_crypto_ed25519_loworder was not run. It is registered by this diff and the C build
    and Host Tests (x86_64) are green, which shows it compiles and the suite passes; I did
    not verify that the test actually rejects a low-order point.

Automated architecture review of 001128d8909c — scheduled, model claude-opus-5, checked against the EmbeddedOS Master Design v2.0. Advisory only: this reviewer never approves, requests changes, or merges. Reply here to discuss or push back — a wrong finding is a bug worth reporting.

@Kartikey1306

Copy link
Copy Markdown
Contributor Author

Verified the pin independently and it is correct. One gap worth closing before
this lands.

The pinned commit is genuinely known-good

Compiling a TU that does nothing but include the header, against each ref:

a172a6d6 (EBOOT_COMMIT)  errors: 0
22d8f8b  (eBoot master)  errors: 2

So the pin is not "some commit that happened to be green", it is on the correct
side of the break. Confirmed the breakage boundary too, which is worth having
in writing since the comment references it:

abd4dab  #93  removed uint8_t reserved[30]        errors: 0
bbd997a  #87  added offsetof(..., reserved)       errors: 2   <- breaks here

That is my merged #87, landed on a base where reserved still existed. The
comment in this PR is accurate about the cause.

This is the fix for twelve PRs

EoS Full-Stack Simulation is currently the only failing check across every
open eos PR — #114 #115 #116 #117 #118 #119 #121 #122 #126 #127 #129 #134 — and
this branch is green on that job. Nothing else is red anywhere in the queue.

One gap: nothing tests eBoot master any more

eos-simulation.yml is the only workflow in this repo that references eBoot.
After this change, it is pinned — so eBoot's master can rot indefinitely and eos
finds out only when someone bumps EBOOT_COMMIT, by which time the bump is a
large, unattributed merge rather than a one-commit regression.

The comment says "when eBoot #94 lands, bump EBOOT_COMMIT to that merge and CI
will say whether it holds", which is the right procedure — but nothing prompts
it, and nothing fails if it never happens.

Concretely, this is the difference between decoupling and not looking. The
usual shape is to keep both:

  • pull requests build the pinned ref, so a contributor is never blocked by
    another repository — what this PR does, and it is right;
  • a scheduled run builds master, so drift is still caught loudly and
    lands on whoever broke it rather than on the next person to bump.

That would be a second job in nightly.yml reusing this one's steps with
ref: master. I am happy to write it as a follow-up rather than push it into
your PR — say which you prefer.

Without it, my worry is that this PR's own argument gets used later to justify
never revisiting the pin, and "pinned" quietly becomes "stale".

Not a finding, since I checked before raising it

I was going to flag the tests/CMakeLists.txt hunk as yet another copy of the
test_crypto_ed25519_loworder registration — gh pr diff shows it as added
here. It is not a duplicate: git merge-base --is-ancestor confirms this branch
is stacked on #127, so the hunk is inherited rather than re-added. Recording
that because the same check flags #119 and #122, which do carry their own
copies, and I am fixing those separately.

Kartikey1306 added a commit to Kartikey1306/eos that referenced this pull request Sep 4, 2026
Every open eos pull request is currently red on `EoS Full-Stack Simulation`,
and none of them caused it. The kernel job checks out embeddedos-org/eBoot at
`ref: master`, and eBoot master does not compile: include/eos_image.h:135 and
:142 static-assert offsetof(eos_image_header_t, reserved) for a member that
became tlv_len + tlv_hash, and core/ed25519_verify.c redefines
point_is_identity -- two pairs of PRs that each merged clean and broke the
build together. eBoot embeddedos-org#94 repairs it and waits on review; until it lands, no
change to any eos PR can make this job pass, and after it lands the next
broken eBoot master does the same thing again.

A floating `ref: master` makes every eos PR's CI depend on the moment-to-
moment state of another repository's default branch. Pinning the two
compiled-against checkouts makes the job a function of this repository plus
two recorded SHAs -- red means the PR broke something, green means it did not,
and a cross-repo bump is a reviewable one-line diff with CI on it.

  EBOOT_COMMIT  a172a6d6e1e6  the newest eBoot master ancestor that compiles;
                found by walking master back and building each candidate.
                Its child 8a015b2 already carries the ed25519 redefinition.
  EBUILD_COMMIT e5d8052f3e2c  ebuild's current master, frozen as-is. Both of
                its checkouts feed steps that are commented out (eFab does
                not exist), so this pin only removes the float.

The middleware matrix (10 repos) still floats; it runs those repos' own
tests rather than compiling eos against them, and 10 more pins deserve their
own decision. When eBoot embeddedos-org#94 merges, bump EBOOT_COMMIT to the merge SHA.

Verified before pushing, master vs pin under the job's own configuration
(-DEBLDR_BOARD=qemu_arm64 -DEBLDR_VERIFY_STAGE1=OFF -DCMAKE_BUILD_TYPE=Release,
cross-compile mode): eBoot@master fails at the eos_image.h asserts, the exact
error in the job log; eBoot@a172a6d builds every target, rc=0. Both pinned
SHAs verified reachable from their repos' master. Workflow parses; the three
`ref:` edits and the env block are the whole diff. This PR's own simulation
run is the live test: it uses this branch's workflow and should go green
while every master-based PR stays red.

Carried onto this branch from embeddedos-org#135 (001128d) so this PR's own simulation
job runs against a buildable eBoot: each pull request executes its own copy
of the workflow, so the fix greens a PR only once its branch contains it.
Byte-identical to embeddedos-org#135's commit -- git drops it as already-upstream the
moment embeddedos-org#135 merges. The pin itself is embeddedos-org#135's to review.
Kartikey1306 added a commit to Kartikey1306/eos that referenced this pull request Sep 4, 2026
Every open eos pull request is currently red on `EoS Full-Stack Simulation`,
and none of them caused it. The kernel job checks out embeddedos-org/eBoot at
`ref: master`, and eBoot master does not compile: include/eos_image.h:135 and
:142 static-assert offsetof(eos_image_header_t, reserved) for a member that
became tlv_len + tlv_hash, and core/ed25519_verify.c redefines
point_is_identity -- two pairs of PRs that each merged clean and broke the
build together. eBoot embeddedos-org#94 repairs it and waits on review; until it lands, no
change to any eos PR can make this job pass, and after it lands the next
broken eBoot master does the same thing again.

A floating `ref: master` makes every eos PR's CI depend on the moment-to-
moment state of another repository's default branch. Pinning the two
compiled-against checkouts makes the job a function of this repository plus
two recorded SHAs -- red means the PR broke something, green means it did not,
and a cross-repo bump is a reviewable one-line diff with CI on it.

  EBOOT_COMMIT  a172a6d6e1e6  the newest eBoot master ancestor that compiles;
                found by walking master back and building each candidate.
                Its child 8a015b2 already carries the ed25519 redefinition.
  EBUILD_COMMIT e5d8052f3e2c  ebuild's current master, frozen as-is. Both of
                its checkouts feed steps that are commented out (eFab does
                not exist), so this pin only removes the float.

The middleware matrix (10 repos) still floats; it runs those repos' own
tests rather than compiling eos against them, and 10 more pins deserve their
own decision. When eBoot embeddedos-org#94 merges, bump EBOOT_COMMIT to the merge SHA.

Verified before pushing, master vs pin under the job's own configuration
(-DEBLDR_BOARD=qemu_arm64 -DEBLDR_VERIFY_STAGE1=OFF -DCMAKE_BUILD_TYPE=Release,
cross-compile mode): eBoot@master fails at the eos_image.h asserts, the exact
error in the job log; eBoot@a172a6d builds every target, rc=0. Both pinned
SHAs verified reachable from their repos' master. Workflow parses; the three
`ref:` edits and the env block are the whole diff. This PR's own simulation
run is the live test: it uses this branch's workflow and should go green
while every master-based PR stays red.

Carried onto this branch from embeddedos-org#135 (001128d) so this PR's own simulation
job runs against a buildable eBoot: each pull request executes its own copy
of the workflow, so the fix greens a PR only once its branch contains it.
Byte-identical to embeddedos-org#135's commit -- git drops it as already-upstream the
moment embeddedos-org#135 merges. The pin itself is embeddedos-org#135's to review.
Kartikey1306 added a commit to Kartikey1306/eos that referenced this pull request Sep 4, 2026
Every open eos pull request is currently red on `EoS Full-Stack Simulation`,
and none of them caused it. The kernel job checks out embeddedos-org/eBoot at
`ref: master`, and eBoot master does not compile: include/eos_image.h:135 and
:142 static-assert offsetof(eos_image_header_t, reserved) for a member that
became tlv_len + tlv_hash, and core/ed25519_verify.c redefines
point_is_identity -- two pairs of PRs that each merged clean and broke the
build together. eBoot embeddedos-org#94 repairs it and waits on review; until it lands, no
change to any eos PR can make this job pass, and after it lands the next
broken eBoot master does the same thing again.

A floating `ref: master` makes every eos PR's CI depend on the moment-to-
moment state of another repository's default branch. Pinning the two
compiled-against checkouts makes the job a function of this repository plus
two recorded SHAs -- red means the PR broke something, green means it did not,
and a cross-repo bump is a reviewable one-line diff with CI on it.

  EBOOT_COMMIT  a172a6d6e1e6  the newest eBoot master ancestor that compiles;
                found by walking master back and building each candidate.
                Its child 8a015b2 already carries the ed25519 redefinition.
  EBUILD_COMMIT e5d8052f3e2c  ebuild's current master, frozen as-is. Both of
                its checkouts feed steps that are commented out (eFab does
                not exist), so this pin only removes the float.

The middleware matrix (10 repos) still floats; it runs those repos' own
tests rather than compiling eos against them, and 10 more pins deserve their
own decision. When eBoot embeddedos-org#94 merges, bump EBOOT_COMMIT to the merge SHA.

Verified before pushing, master vs pin under the job's own configuration
(-DEBLDR_BOARD=qemu_arm64 -DEBLDR_VERIFY_STAGE1=OFF -DCMAKE_BUILD_TYPE=Release,
cross-compile mode): eBoot@master fails at the eos_image.h asserts, the exact
error in the job log; eBoot@a172a6d builds every target, rc=0. Both pinned
SHAs verified reachable from their repos' master. Workflow parses; the three
`ref:` edits and the env block are the whole diff. This PR's own simulation
run is the live test: it uses this branch's workflow and should go green
while every master-based PR stays red.

Carried onto this branch from embeddedos-org#135 (001128d) so this PR's own simulation
job runs against a buildable eBoot: each pull request executes its own copy
of the workflow, so the fix greens a PR only once its branch contains it.
Byte-identical to embeddedos-org#135's commit -- git drops it as already-upstream the
moment embeddedos-org#135 merges. The pin itself is embeddedos-org#135's to review.
Kartikey1306 added a commit to Kartikey1306/eos that referenced this pull request Sep 4, 2026
Every open eos pull request is currently red on `EoS Full-Stack Simulation`,
and none of them caused it. The kernel job checks out embeddedos-org/eBoot at
`ref: master`, and eBoot master does not compile: include/eos_image.h:135 and
:142 static-assert offsetof(eos_image_header_t, reserved) for a member that
became tlv_len + tlv_hash, and core/ed25519_verify.c redefines
point_is_identity -- two pairs of PRs that each merged clean and broke the
build together. eBoot embeddedos-org#94 repairs it and waits on review; until it lands, no
change to any eos PR can make this job pass, and after it lands the next
broken eBoot master does the same thing again.

A floating `ref: master` makes every eos PR's CI depend on the moment-to-
moment state of another repository's default branch. Pinning the two
compiled-against checkouts makes the job a function of this repository plus
two recorded SHAs -- red means the PR broke something, green means it did not,
and a cross-repo bump is a reviewable one-line diff with CI on it.

  EBOOT_COMMIT  a172a6d6e1e6  the newest eBoot master ancestor that compiles;
                found by walking master back and building each candidate.
                Its child 8a015b2 already carries the ed25519 redefinition.
  EBUILD_COMMIT e5d8052f3e2c  ebuild's current master, frozen as-is. Both of
                its checkouts feed steps that are commented out (eFab does
                not exist), so this pin only removes the float.

The middleware matrix (10 repos) still floats; it runs those repos' own
tests rather than compiling eos against them, and 10 more pins deserve their
own decision. When eBoot embeddedos-org#94 merges, bump EBOOT_COMMIT to the merge SHA.

Verified before pushing, master vs pin under the job's own configuration
(-DEBLDR_BOARD=qemu_arm64 -DEBLDR_VERIFY_STAGE1=OFF -DCMAKE_BUILD_TYPE=Release,
cross-compile mode): eBoot@master fails at the eos_image.h asserts, the exact
error in the job log; eBoot@a172a6d builds every target, rc=0. Both pinned
SHAs verified reachable from their repos' master. Workflow parses; the three
`ref:` edits and the env block are the whole diff. This PR's own simulation
run is the live test: it uses this branch's workflow and should go green
while every master-based PR stays red.

Carried onto this branch from embeddedos-org#135 (001128d) so this PR's own simulation
job runs against a buildable eBoot: each pull request executes its own copy
of the workflow, so the fix greens a PR only once its branch contains it.
Byte-identical to embeddedos-org#135's commit -- git drops it as already-upstream the
moment embeddedos-org#135 merges. The pin itself is embeddedos-org#135's to review.
Kartikey1306 added a commit to Kartikey1306/eos that referenced this pull request Sep 4, 2026
Every open eos pull request is currently red on `EoS Full-Stack Simulation`,
and none of them caused it. The kernel job checks out embeddedos-org/eBoot at
`ref: master`, and eBoot master does not compile: include/eos_image.h:135 and
:142 static-assert offsetof(eos_image_header_t, reserved) for a member that
became tlv_len + tlv_hash, and core/ed25519_verify.c redefines
point_is_identity -- two pairs of PRs that each merged clean and broke the
build together. eBoot embeddedos-org#94 repairs it and waits on review; until it lands, no
change to any eos PR can make this job pass, and after it lands the next
broken eBoot master does the same thing again.

A floating `ref: master` makes every eos PR's CI depend on the moment-to-
moment state of another repository's default branch. Pinning the two
compiled-against checkouts makes the job a function of this repository plus
two recorded SHAs -- red means the PR broke something, green means it did not,
and a cross-repo bump is a reviewable one-line diff with CI on it.

  EBOOT_COMMIT  a172a6d6e1e6  the newest eBoot master ancestor that compiles;
                found by walking master back and building each candidate.
                Its child 8a015b2 already carries the ed25519 redefinition.
  EBUILD_COMMIT e5d8052f3e2c  ebuild's current master, frozen as-is. Both of
                its checkouts feed steps that are commented out (eFab does
                not exist), so this pin only removes the float.

The middleware matrix (10 repos) still floats; it runs those repos' own
tests rather than compiling eos against them, and 10 more pins deserve their
own decision. When eBoot embeddedos-org#94 merges, bump EBOOT_COMMIT to the merge SHA.

Verified before pushing, master vs pin under the job's own configuration
(-DEBLDR_BOARD=qemu_arm64 -DEBLDR_VERIFY_STAGE1=OFF -DCMAKE_BUILD_TYPE=Release,
cross-compile mode): eBoot@master fails at the eos_image.h asserts, the exact
error in the job log; eBoot@a172a6d builds every target, rc=0. Both pinned
SHAs verified reachable from their repos' master. Workflow parses; the three
`ref:` edits and the env block are the whole diff. This PR's own simulation
run is the live test: it uses this branch's workflow and should go green
while every master-based PR stays red.

Carried onto this branch from embeddedos-org#135 (001128d) so this PR's own simulation
job runs against a buildable eBoot: each pull request executes its own copy
of the workflow, so the fix greens a PR only once its branch contains it.
Byte-identical to embeddedos-org#135's commit -- git drops it as already-upstream the
moment embeddedos-org#135 merges. The pin itself is embeddedos-org#135's to review.
Kartikey1306 added a commit to Kartikey1306/eos that referenced this pull request Sep 4, 2026
Every open eos pull request is currently red on `EoS Full-Stack Simulation`,
and none of them caused it. The kernel job checks out embeddedos-org/eBoot at
`ref: master`, and eBoot master does not compile: include/eos_image.h:135 and
:142 static-assert offsetof(eos_image_header_t, reserved) for a member that
became tlv_len + tlv_hash, and core/ed25519_verify.c redefines
point_is_identity -- two pairs of PRs that each merged clean and broke the
build together. eBoot embeddedos-org#94 repairs it and waits on review; until it lands, no
change to any eos PR can make this job pass, and after it lands the next
broken eBoot master does the same thing again.

A floating `ref: master` makes every eos PR's CI depend on the moment-to-
moment state of another repository's default branch. Pinning the two
compiled-against checkouts makes the job a function of this repository plus
two recorded SHAs -- red means the PR broke something, green means it did not,
and a cross-repo bump is a reviewable one-line diff with CI on it.

  EBOOT_COMMIT  a172a6d6e1e6  the newest eBoot master ancestor that compiles;
                found by walking master back and building each candidate.
                Its child 8a015b2 already carries the ed25519 redefinition.
  EBUILD_COMMIT e5d8052f3e2c  ebuild's current master, frozen as-is. Both of
                its checkouts feed steps that are commented out (eFab does
                not exist), so this pin only removes the float.

The middleware matrix (10 repos) still floats; it runs those repos' own
tests rather than compiling eos against them, and 10 more pins deserve their
own decision. When eBoot embeddedos-org#94 merges, bump EBOOT_COMMIT to the merge SHA.

Verified before pushing, master vs pin under the job's own configuration
(-DEBLDR_BOARD=qemu_arm64 -DEBLDR_VERIFY_STAGE1=OFF -DCMAKE_BUILD_TYPE=Release,
cross-compile mode): eBoot@master fails at the eos_image.h asserts, the exact
error in the job log; eBoot@a172a6d builds every target, rc=0. Both pinned
SHAs verified reachable from their repos' master. Workflow parses; the three
`ref:` edits and the env block are the whole diff. This PR's own simulation
run is the live test: it uses this branch's workflow and should go green
while every master-based PR stays red.

Carried onto this branch from embeddedos-org#135 (001128d) so this PR's own simulation
job runs against a buildable eBoot: each pull request executes its own copy
of the workflow, so the fix greens a PR only once its branch contains it.
Byte-identical to embeddedos-org#135's commit -- git drops it as already-upstream the
moment embeddedos-org#135 merges. The pin itself is embeddedos-org#135's to review.
Kartikey1306 added a commit to Kartikey1306/eos that referenced this pull request Sep 4, 2026
Every open eos pull request is currently red on `EoS Full-Stack Simulation`,
and none of them caused it. The kernel job checks out embeddedos-org/eBoot at
`ref: master`, and eBoot master does not compile: include/eos_image.h:135 and
:142 static-assert offsetof(eos_image_header_t, reserved) for a member that
became tlv_len + tlv_hash, and core/ed25519_verify.c redefines
point_is_identity -- two pairs of PRs that each merged clean and broke the
build together. eBoot embeddedos-org#94 repairs it and waits on review; until it lands, no
change to any eos PR can make this job pass, and after it lands the next
broken eBoot master does the same thing again.

A floating `ref: master` makes every eos PR's CI depend on the moment-to-
moment state of another repository's default branch. Pinning the two
compiled-against checkouts makes the job a function of this repository plus
two recorded SHAs -- red means the PR broke something, green means it did not,
and a cross-repo bump is a reviewable one-line diff with CI on it.

  EBOOT_COMMIT  a172a6d6e1e6  the newest eBoot master ancestor that compiles;
                found by walking master back and building each candidate.
                Its child 8a015b2 already carries the ed25519 redefinition.
  EBUILD_COMMIT e5d8052f3e2c  ebuild's current master, frozen as-is. Both of
                its checkouts feed steps that are commented out (eFab does
                not exist), so this pin only removes the float.

The middleware matrix (10 repos) still floats; it runs those repos' own
tests rather than compiling eos against them, and 10 more pins deserve their
own decision. When eBoot embeddedos-org#94 merges, bump EBOOT_COMMIT to the merge SHA.

Verified before pushing, master vs pin under the job's own configuration
(-DEBLDR_BOARD=qemu_arm64 -DEBLDR_VERIFY_STAGE1=OFF -DCMAKE_BUILD_TYPE=Release,
cross-compile mode): eBoot@master fails at the eos_image.h asserts, the exact
error in the job log; eBoot@a172a6d builds every target, rc=0. Both pinned
SHAs verified reachable from their repos' master. Workflow parses; the three
`ref:` edits and the env block are the whole diff. This PR's own simulation
run is the live test: it uses this branch's workflow and should go green
while every master-based PR stays red.

Carried onto this branch from embeddedos-org#135 (001128d) so this PR's own simulation
job runs against a buildable eBoot: each pull request executes its own copy
of the workflow, so the fix greens a PR only once its branch contains it.
Byte-identical to embeddedos-org#135's commit -- git drops it as already-upstream the
moment embeddedos-org#135 merges. The pin itself is embeddedos-org#135's to review.
@Kartikey1306

Copy link
Copy Markdown
Contributor Author

For the record: I have carried this branch's pin commit (001128d8), byte-identical, onto seven of my open PRs — #114, #115, #116, #117, #118, #127, #129 — because each pull request executes its own copy of the workflow, so the fix greens a PR only once its branch contains it. Each carry is disclosed in its commit message, and being patch-identical, git drops every copy as already-upstream the moment this merges — no restack needed. The pin itself stays this PR's to review; nothing was changed in the carried copies.

(#121, #122, #126 and #134 do not carry it — those branches have your newer work on them and are yours to update.)

Independent confirmation for the review, since I had bisected before reading this PR: walking eBoot master back and building each candidate locally gives the same answer — every commit from 8a015b2 (#92) up fails (point_is_identity redefinition, then the reserved asserts), and a172a6d is the newest ancestor that compiles. Same SHA this pin records.

The pin in the previous commit stops an eBoot or ebuild master that does not
compile from turning every eos pull request red. It also stops that break
being visible from here at all, which on its own is the worse half of the
trade: the next upstream breakage would be silent instead of loud, and the
pin would sit at a172a6d indefinitely because nothing would ever ask -- while
quietly dropping the six eBoot commits that follow it.

`.github/workflows/upstream-drift.yml` is the other half. It builds eBoot at
master and compares both pins against their master, so an upstream break
still surfaces, on a run that blocks no pull request and names the repository
responsible.

Design choices, each one avoiding a defect this repo has been filing against:

  Its own file, schedule + workflow_dispatch only. The first draft was a job
  inside eos-simulation.yml guarded by `if: github.event_name == 'schedule'`.
  That works, but the run showed it on the PR as a SKIPPED check -- and a
  required-check gate that treats any non-success as a failure, which is the
  design in embeddedos-org#121, would trip on exactly that. Moving it out removes the check
  from PR runs entirely rather than relying on every future gate to exempt it.

  Not `continue-on-error`. A job reporting success over a failure is the
  fail-open shape we keep finding in aggregating gates. This one may fail
  honestly precisely because it gates nothing.

  Failing is reserved for "upstream does not build". A pin merely behind a
  healthy master is a warning: actionable, not broken.

  The pins are read out of eos-simulation.yml, not copied. A second copy of a
  SHA is a second thing to forget. The read demands a 40-character hex value
  and fails closed if it cannot find one, so a renamed or reformatted key
  stops the job instead of silently letting it check a pin of "".

  The failure message is scoped to the build step's own outcome, so a
  checkout, apt or pin-read failure cannot report itself as evidence about
  eBoot's master. The summary says eBoot is built and ebuild is only
  compared, rather than implying both were checked.

Verified by execution, not by reading:

  eBoot @ a172a6d (the pin)   host build rc=0, 0 errors
  eBoot @ 22d8f8b (master)    host build rc=2, "no member named 'reserved'
                              in 'eos_image_header_t'" at eos_image.h:135
                              and :142 -- the same defect CI reports, so the
                              pin is demonstrably the difference

  pin extraction, run against the real file and two mutations of it:
    real workflow                -> both SHAs read correctly, and the eBoot
                                    one resolves to embeddedos-org#86's merge
    key renamed to EBOOT_SHA     -> fails closed, rc=1
    value unquoted and shortened -> fails closed, rc=1

  drift logic, run against the real repositories:
    pin 6 behind healthy master  -> "behind by 6" warning, no failure
    pin absent from master       -> "not an ancestor" warning, exit 0 under
                                    set -e (the first draft printed "pinned
                                    pin not found on master commit(s)")
    pin equal to master          -> no warning

  eos on this branch: cmake build rc=0, ctest 39/39, pytest 15/15 with the
  new workflow file present, test_crypto_ed25519_loworder registered and
  passing.

When eBoot embeddedos-org#94 lands, bump EBOOT_COMMIT to that merge; this job is what will
say whether it holds.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@srpatcha srpatcha left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review — eos#135 "ci: pin the eBoot and ebuild checkouts instead of floating on master"

head: f34edb3 author: Kartikey1306 ci: pass (Cross-compile ARM64 kernel green at 06:41:27Z on this head, red on the two unpinned PRs minutes earlier)

Verdict: Correct diagnosis, correct pin, and the second half — shipping the drift job with the pin rather than after it — is the right instinct and is what makes this mergeable rather than a decoupling that hides the problem. I verified the substance independently rather than reading the tables: eBoot master (22d8f8b) genuinely does not compile, the pinned a172a6d is on the good side of the break, and the drift job builds with the same runner image and the same cmake flags as the job it speaks for. Three things are worth fixing before this lands: the 146 new lines of drift logic are executed by no pull request, nothing stops eos-simulation.yml from quietly floating again while the drift job keeps reporting on pins that no longer control anything, and the headline claim is broader than the diff.

Findings

# Severity File:line Finding Recommended fix
1 Medium .github/workflows/upstream-drift.yml:23-26 The workflow never runs on a pull request, so all 146 new lines get no CI execution before merge and none after until the 06:17 UTC nightly. That is the same defect the same author fixed in eos#129 for eosim-sanity.yml — "schedule- and dispatch-only, so a pull request editing it produced no run of it at all … the only evidence for the change was whatever the author did locally" — and #129's own history shows what that costs: the first real run of that workflow found three more blockers that no amount of reading had revealed. The reason given here, "a PR must not be red for a break it did not cause", is sound but applies only to the eBoot master build step. It does not apply to the pin-read regex, the unknown-ancestor branch, the step-summary table, or the steps.eboot.outcome scoping — which is where all the new shell is, and which is exercised only by the author's local table. Rename EBOOT_COMMIT in eos-simulation.yml and nothing notices until tomorrow morning. Split the job. validate-pins — checkout eos, read the pins, checkout eBoot and ebuild, report drift; no apt, no upstream build — triggers on pull_request: paths: ['.github/workflows/upstream-drift.yml', '.github/workflows/eos-simulation.yml']. build-upstream — the apt install and the eBoot master build — stays schedule/dispatch-only. A PR that renames a pin then fails on its own change, no PR can be reddened by eBoot's health, and the drift table appears on exactly the PR that bumps a pin, which is when it is most useful.
2 Medium .github/workflows/upstream-drift.yml:55-72 The one-source-of-truth read is one-directional. upstream-drift.yml reads the pins out of eos-simulation.yml and fails closed if it cannot find a 40-hex value — good, and the two negative cases in the validation table are the right ones. But nothing checks the converse: eos-simulation.yml can be edited back to ref: master for either checkout while the env: block keeps both SHAs, and the drift job will go on reading them, reporting "pinned 6 commits behind" and passing — reporting on pins that no longer control anything. That is a check whose subject can be removed without the check noticing, which is the shape this repo keeps filing against. In the same step, after reading the pins, assert the invariant: if grep -nE 'repository: embeddedos-org/(eBoot|ebuild)' -A2 "$wf" | grep -q 'ref: master'; then echo "::error::…"; exit 1; fi (or a small yq/python check over the two jobs). Three lines, and the pin becomes an enforced invariant instead of a convention. This is also what makes the recorded design rule's "stated exception" checkable rather than aspirational.
3 Low .github/workflows/eos-simulation.yml:16-19 The pin's record names the wrong repair and no owner. The comment says "eBoot #94 repairs it … when eBoot #94 lands, bump EBOOT_COMMIT to that merge", while this PR's body and your own comments on #127 and #129 name eBoot#97 ("Repair opened as eBoot#97"). One of the two is wrong and the wrong one is the one a future maintainer will read. There is also no named owner: a scheduled workflow's failure notification lands on whoever last touched the file, which is an accident of git history. And the record does not say which released refs were evaluated — which matters, because .github/STANDARDS.md names a vX.Y.Z tag as the recommended pin and a bare SHA is outside the documented set, so the next reader will "fix" it. I checked, and the SHA is right: eBoot's newest tag v3.0.1 (35ed483, 2026-05-16) would build — include/eos_image.h:37 still has reserved[30] and no assert on a missing member — but it does not contain a172a6d (eBoot#86), the fix that rejects public keys outside the prime-order subgroup, so pinning the released tag would pin eos's CI to an eBoot that still accepts a low-order-key forgery. Correct the PR number, name an owner, and add the one sentence about v3.0.1. That is exactly the record the 2026-09-04 addendum asks a SHA pin to carry, and this PR is what triggered it.
4 Low .github/workflows/eos-simulation.yml:248; PR body, "Net effect" "An eos PR can no longer go red for another repository's break" is stronger than the diff. test-middleware still checks out ten repositories at ref: master (eAI, eNI, eosllm, eDB, eBrowser, eIPC, eOffice, EoStudio, EoSim, eApps), the workflow triggers on pull_request: branches: [master], and those ten jobs report on every eos PR — so the same failure mode survives for ten of the thirteen cross-repo checkouts in this file. The body does disclose the deferral and gives a reasonable reason; the summary sentence does not carry it, and neither does the drift workflow, whose name ("Upstream drift") is broader than its scope (its own step summary is honest: eBoot is built, ebuild is only compared, and the ten are absent). Narrow the claim to eBoot and ebuild, and say in the same breath that the middleware matrix is the remaining exposure. Whether the ten get pinned, moved to a non-required workflow, or left alone is its own decision, but a reader should not have to reconstruct that the guarantee covers 3 of 13.

Architecture conformance

Conforms, and it is the implementation of a rule this reviewer already proposed. §5.1 as extended to CI-time dependencies: eos (Tier 1) consuming eBoot and ebuild (both Tier 1) is sibling-tier, so the direction was never the problem — only the ref. .ai/platform.md's "a consumer depends on a component with a version range, never on a git URL or a path into another repo's tree" is the nearest existing statement and this change moves toward it without being able to satisfy it, because no component/version mechanism exists for a CI checkout yet. §21 tier placement: Tier-1 eos infrastructure. .github/STANDARDS.md "Release model" is the rule the SHA departs from, deliberately and for a reason I verified (finding 3).

Both halves of this PR are already covered by recorded proposals, so no new proposal is appended: .ai/autoreview/proposals/2026-09.md, 2026-09-03 "§5.1 governs runtime dependencies and says nothing about build- or CI-time ones, so one repository's trunk decides whether another's pull requests can be green" (the pin), and the 2026-09-04 addendum "'pin a released ref' has no answer when no released ref is usable" — triggered by this PR — whose two proposed bullets are precisely (a) a SHA as a stated exception carrying the refs evaluated, the lift condition and a named owner, and (b) "every pinned cross-repository dependency has a non-required scheduled job that exercises the same build against the dependency's default branch. Pinning removes the noise from the critical path; it must not also remove the signal." upstream-drift.yml is that job. Findings 2 and 3 are the gap between what the file does and what that addendum asks it to carry.

Verified in this review

  • eBoot master does not compile, from the source rather than by attribution: at 22d8f8b the struct carries tlv_len (include/eos_image.h:53) and tlv_hash (:54) where reserved[30] was, while EOS_IMG_STATIC_ASSERT(offsetof(eos_image_header_t, reserved) == 62) (:135) and sizeof(((eos_image_header_t *)0)->reserved) == 30 (:142) survived the merge — the exact two errors in the eos ARM64 job log.
  • The pin is on the good side of the break: at a172a6d (include/eos_image.h:37) reserved[30] is present and no assert references a member it lacks.
  • The drift job really does build the same configuration it speaks for. I compared them rather than taking the comment's word: both runs-on: ubuntu-22.04, both -DCMAKE_TOOLCHAIN_FILE=toolchains/aarch64-linux-gnu.cmake -DEBLDR_BOARD=qemu_arm64 -DEBLDR_VERIFY_STAGE1=OFF -DCMAKE_BUILD_TYPE=Release, and the same gcc-aarch64-linux-gnu / binutils-aarch64-linux-gnu / libc6-dev-arm64-cross / cmake / ninja-build packages (drift omits only qemu and pytest, which the eBoot build does not use). So "a pass here means the pin can be bumped to this master" holds — it would not have if the drift job had used ubuntu-latest.
  • The pin works, measured against the control. Cross-compile ARM64 kernel completed success on this head at 06:41:27Z and on #127/#129 (which carry the same pin) at 06:37:18Z / 06:37:45Z, and failure on #119 at 06:35:46Z and on #122 — the two heads still on ref: master. Same merge base for four of the five, six minutes apart.
  • Your stacking claim holds. git diff pr-127 pr-135 is .github/workflows/upstream-drift.yml and nothing else, so this branch is exactly #127 plus the drift workflow and the tests/CMakeLists.txt hunk is inherited, not a fourth copy. #127 first then this fast-forwarding is arranged correctly. Note the consequence, which is a merge-order matter rather than a defect: #127 is a strict subset of this PR, and the same pin commit is also on #129, so only one of the three can land as written.
  • shell/step wiring: the Say what a failure here means step is correctly scoped to steps.eboot.outcome == 'failure', so an apt or pin-read failure cannot report itself as evidence about eBoot's master, and the job still fails on the build step's own non-zero. The if git cat-file -e guard and the behind="unknown" branch do exit 0 under the default bash -e -o pipefail, as the body claims.

Not checked

  • Nothing was built or run. No compiler, no cmake, no workflow execution from here. The eBoot findings above are source inspection of the specific asserts that fail; I did not compile eBoot at either ref, so I can say the known breakage is present at master and absent at a172a6d, not that a172a6d builds clean. Your 0-errors / 2-errors table and the bisect to 8a015b2 are neither confirmed nor disputed.
  • upstream-drift.yml has never executed anywhere. Its ten-row validation table is local and unreproduced here. Given finding 1, its first real execution will be the nightly after merge; the pin-read regex against a reformatted eos-simulation.yml, and the not an ancestor path after a force-push, are the two cases most likely to behave differently in the runner than in a local shell.
  • EBUILD_COMMIT (e5d8052f…) was not examined at all — the ebuild clone under the working root is dirty, so the sync step left it untouched and that commit is not in the local object store. The body's argument that it "changes nothing else" because both ebuild checkouts feed commented-out eFab steps is plausible from the workflow text (test-cad-pipeline checks ebuild out and its CAD step is commented) but I did not confirm nothing else in those jobs uses the tree.
  • The claim that all 12 other open eos PRs fail this job for this reason was spot-checked on two (#119, #122) and not on the other ten.
  • Whether a scheduled-workflow failure actually reaches a human here. GitHub's default routes it to the last editor of the workflow file; no CODEOWNERS entry, issue-filing step, or notification target is configured, so "loud" currently means "loud in the Actions tab". That is the ownership half of finding 3 and it is not something this diff can be said to have solved.

Automated architecture review of f34edb343ab3 — scheduled, model claude-opus-5, checked against the EmbeddedOS Master Design v2.0. Advisory only: this reviewer never approves, requests changes, or merges. Reply here to discuss or push back — a wrong finding is a bug worth reporting.

srpatcha pushed a commit that referenced this pull request Sep 8, 2026
* fix(build): restore the low-order Ed25519 suite that #93 removed

`CI — eos` and `Python Unit Tests` are red on master (769191a), and both
fail for one reason:

    these suites exist in tests/ but no add_executable() in
    tests/CMakeLists.txt builds them, so they never run:
    ['test_crypto_ed25519_loworder.c']

3aa8644 (#93, "remove duplicate test targets from tests/CMakeLists.txt")
removed all four lines that build and register
test_crypto_ed25519_loworder. It was not a duplicate — there was exactly
one registration before that commit, and it took it.

What stopped running is the suite that guards #101: Ed25519 rejecting
low-order public keys. A low-order key makes every term of the
verification equation collapse to the identity regardless of the
message, so a signature of all zeros verifies against any content at
all. The fix is still in services/crypto/src/ed25519_verify.c and still
correct; nothing has been checking it since #93 merged, and nothing
would have noticed if a later change had removed it too.

Restored verbatim from 3aa8644^, in its original position before
test_crypto_sha512. No other file changes.

The guard that caught this is test_cmake_test_registration.py, added
recently. It did exactly its job — this is the first thing it found.

Verified:
  test_cmake_test_registration.py    -> 5 passed (1 failed on master)
  pytest tests/                      -> 15 passed (14 passed 1 failed on master)
  test_crypto_ed25519_loworder       -> 5/5 tests passed
  ctest                              -> 39/39 passed (master builds 38)

* chore(tests): drop the unused assert.h include from test_net.c

Retitles and reduces this PR to what it still does, per the review.

Both repairs it was opened for have landed on master by other routes:
net/src/net_posix.c is byte-identical to origin/master, and master's default
configuration builds clean. Against current master the branch's only real
content was this one line -- and merging it as it stood would have *reverted*
646 lines that landed since, including #120's pkg trust anchor,
tests/test_pkg_trust_anchor.c and tests/unit/test_cmake_test_registration.py.
Reset to master and re-applied the one surviving change rather than leave a
stale branch that still looks mergeable.

The include is genuinely unused: tests/test_net.c has zero assert() calls and
uses its own CHECK() macro at 22 call sites. Worth correcting the record, per
finding 2: #124 added it one commit ago as "the missing assert.h include that
broke master", and the file had no assert() at #124's parent either. What
fixed that link error was the assert() -> CHECK() conversion already on
master; the include was never load-bearing, so removing it changes nothing
except the next reader's understanding.

Stacked on #127, which restores the test_crypto_ed25519_loworder registration
master is currently red on.

Verified:
  pytest tests/    15 passed
  ctest            39/39 PASS

Refs #116, #124

* ci: pin the eBoot and ebuild checkouts instead of floating on master

Every open eos pull request is currently red on `EoS Full-Stack Simulation`,
and none of them caused it. The kernel job checks out embeddedos-org/eBoot at
`ref: master`, and eBoot master does not compile: include/eos_image.h:135 and
:142 static-assert offsetof(eos_image_header_t, reserved) for a member that
became tlv_len + tlv_hash, and core/ed25519_verify.c redefines
point_is_identity -- two pairs of PRs that each merged clean and broke the
build together. eBoot #94 repairs it and waits on review; until it lands, no
change to any eos PR can make this job pass, and after it lands the next
broken eBoot master does the same thing again.

A floating `ref: master` makes every eos PR's CI depend on the moment-to-
moment state of another repository's default branch. Pinning the two
compiled-against checkouts makes the job a function of this repository plus
two recorded SHAs -- red means the PR broke something, green means it did not,
and a cross-repo bump is a reviewable one-line diff with CI on it.

  EBOOT_COMMIT  a172a6d6e1e6  the newest eBoot master ancestor that compiles;
                found by walking master back and building each candidate.
                Its child 8a015b2 already carries the ed25519 redefinition.
  EBUILD_COMMIT e5d8052f3e2c  ebuild's current master, frozen as-is. Both of
                its checkouts feed steps that are commented out (eFab does
                not exist), so this pin only removes the float.

The middleware matrix (10 repos) still floats; it runs those repos' own
tests rather than compiling eos against them, and 10 more pins deserve their
own decision. When eBoot #94 merges, bump EBOOT_COMMIT to the merge SHA.

Verified before pushing, master vs pin under the job's own configuration
(-DEBLDR_BOARD=qemu_arm64 -DEBLDR_VERIFY_STAGE1=OFF -DCMAKE_BUILD_TYPE=Release,
cross-compile mode): eBoot@master fails at the eos_image.h asserts, the exact
error in the job log; eBoot@a172a6d builds every target, rc=0. Both pinned
SHAs verified reachable from their repos' master. Workflow parses; the three
`ref:` edits and the env block are the whole diff. This PR's own simulation
run is the live test: it uses this branch's workflow and should go green
while every master-based PR stays red.

Carried onto this branch from #135 (001128d) so this PR's own simulation
job runs against a buildable eBoot: each pull request executes its own copy
of the workflow, so the fix greens a PR only once its branch contains it.
Byte-identical to #135's commit -- git drops it as already-upstream the
moment #135 merges. The pin itself is #135's to review.
@srpatcha
srpatcha merged commit bf52cc7 into embeddedos-org:master Sep 8, 2026
30 checks passed
srpatcha pushed a commit that referenced this pull request Sep 8, 2026
* fix(build): restore the low-order Ed25519 suite that #93 removed

`CI — eos` and `Python Unit Tests` are red on master (769191a), and both
fail for one reason:

    these suites exist in tests/ but no add_executable() in
    tests/CMakeLists.txt builds them, so they never run:
    ['test_crypto_ed25519_loworder.c']

3aa8644 (#93, "remove duplicate test targets from tests/CMakeLists.txt")
removed all four lines that build and register
test_crypto_ed25519_loworder. It was not a duplicate — there was exactly
one registration before that commit, and it took it.

What stopped running is the suite that guards #101: Ed25519 rejecting
low-order public keys. A low-order key makes every term of the
verification equation collapse to the identity regardless of the
message, so a signature of all zeros verifies against any content at
all. The fix is still in services/crypto/src/ed25519_verify.c and still
correct; nothing has been checking it since #93 merged, and nothing
would have noticed if a later change had removed it too.

Restored verbatim from 3aa8644^, in its original position before
test_crypto_sha512. No other file changes.

The guard that caught this is test_cmake_test_registration.py, added
recently. It did exactly its job — this is the first thing it found.

Verified:
  test_cmake_test_registration.py    -> 5 passed (1 failed on master)
  pytest tests/                      -> 15 passed (14 passed 1 failed on master)
  test_crypto_ed25519_loworder       -> 5/5 tests passed
  ctest                              -> 39/39 passed (master builds 38)

* chore: untrack the sanitizer build trees committed in #110

bsan/ and bsan2/ are CMake build directories. They reached master in
8a2d835 (#110) — 1441 files, 12.2 MB, four compiled object files, and
two CMakeCache.txt holding absolute paths from the machine that ran the
sanitizer build. Nothing in the repository refers to either directory.

They are mine, and they are the same mistake as the .coverage database
that #75 carried to master and #79 had to remove: `git add -A` in a tree
with a build directory whose name no ignore pattern matched. .gitignore
already lists build/, _build/, build-*/, build_coverage/,
build_qemu_arm64/ and build_sim/ — every one of them added after being
committed once. Widened to cover bsan*/ so this name cannot come back.

Removed with `git rm -r --cached`, so anyone with a local sanitizer
build keeps it; it is simply no longer tracked.

Contents only — no source, build or CI file is touched, and the tree
builds and tests exactly as before:
  -DEOS_BUILD_TESTS=ON -DEOS_PRODUCT=vbox_test + ctest -> 34/34 passed

* chore: collapse the redundant bsan ignore patterns, and say what untracking does not do

Answers the review on #117.

Finding 1 (Low) -- bsan*/ already matches bsan/ and bsan2/, so those two lines
were dead the moment the third was written. This file's stated problem is that
it accumulates one redundant entry per incident; adding two more while fixing
that is the wrong direction. Verified the single pattern still covers all
three shapes: bsan/, bsan2/ and bsan99/ are each ignored with only bsan*/
present.

Finding 2 (Low) -- the body read as though the trees were gone. They are only
untracked going forward: the 12.2 MB and the absolute paths stay in history at
8a2d835 permanently, and every clone still downloads them. Said so in the PR
body rather than leaving the next reader to work it out. No history rewrite is
proposed -- the reviewer scanned all 1441 blobs for credential-shaped content
and found none, the only disclosure being a public GitHub handle, so a rewrite
would cost every consumer a re-clone for no security benefit.

Verified:
  pytest tests/                                 15 passed
  bsan/, bsan2/, bsan99/ with only bsan*/       all three ignored
  git status --short                            clean

Refs #117

* ci: pin the eBoot and ebuild checkouts instead of floating on master

Every open eos pull request is currently red on `EoS Full-Stack Simulation`,
and none of them caused it. The kernel job checks out embeddedos-org/eBoot at
`ref: master`, and eBoot master does not compile: include/eos_image.h:135 and
:142 static-assert offsetof(eos_image_header_t, reserved) for a member that
became tlv_len + tlv_hash, and core/ed25519_verify.c redefines
point_is_identity -- two pairs of PRs that each merged clean and broke the
build together. eBoot #94 repairs it and waits on review; until it lands, no
change to any eos PR can make this job pass, and after it lands the next
broken eBoot master does the same thing again.

A floating `ref: master` makes every eos PR's CI depend on the moment-to-
moment state of another repository's default branch. Pinning the two
compiled-against checkouts makes the job a function of this repository plus
two recorded SHAs -- red means the PR broke something, green means it did not,
and a cross-repo bump is a reviewable one-line diff with CI on it.

  EBOOT_COMMIT  a172a6d6e1e6  the newest eBoot master ancestor that compiles;
                found by walking master back and building each candidate.
                Its child 8a015b2 already carries the ed25519 redefinition.
  EBUILD_COMMIT e5d8052f3e2c  ebuild's current master, frozen as-is. Both of
                its checkouts feed steps that are commented out (eFab does
                not exist), so this pin only removes the float.

The middleware matrix (10 repos) still floats; it runs those repos' own
tests rather than compiling eos against them, and 10 more pins deserve their
own decision. When eBoot #94 merges, bump EBOOT_COMMIT to the merge SHA.

Verified before pushing, master vs pin under the job's own configuration
(-DEBLDR_BOARD=qemu_arm64 -DEBLDR_VERIFY_STAGE1=OFF -DCMAKE_BUILD_TYPE=Release,
cross-compile mode): eBoot@master fails at the eos_image.h asserts, the exact
error in the job log; eBoot@a172a6d builds every target, rc=0. Both pinned
SHAs verified reachable from their repos' master. Workflow parses; the three
`ref:` edits and the env block are the whole diff. This PR's own simulation
run is the live test: it uses this branch's workflow and should go green
while every master-based PR stays red.

Carried onto this branch from #135 (001128d) so this PR's own simulation
job runs against a buildable eBoot: each pull request executes its own copy
of the workflow, so the fix greens a PR only once its branch contains it.
Byte-identical to #135's commit -- git drops it as already-upstream the
moment #135 merges. The pin itself is #135's to review.
srpatcha pushed a commit that referenced this pull request Sep 8, 2026
* fix(build): restore the low-order Ed25519 suite that #93 removed

`CI — eos` and `Python Unit Tests` are red on master (769191a), and both
fail for one reason:

    these suites exist in tests/ but no add_executable() in
    tests/CMakeLists.txt builds them, so they never run:
    ['test_crypto_ed25519_loworder.c']

3aa8644 (#93, "remove duplicate test targets from tests/CMakeLists.txt")
removed all four lines that build and register
test_crypto_ed25519_loworder. It was not a duplicate — there was exactly
one registration before that commit, and it took it.

What stopped running is the suite that guards #101: Ed25519 rejecting
low-order public keys. A low-order key makes every term of the
verification equation collapse to the identity regardless of the
message, so a signature of all zeros verifies against any content at
all. The fix is still in services/crypto/src/ed25519_verify.c and still
correct; nothing has been checking it since #93 merged, and nothing
would have noticed if a later change had removed it too.

Restored verbatim from 3aa8644^, in its original position before
test_crypto_sha512. No other file changes.

The guard that caught this is test_cmake_test_registration.py, added
recently. It did exactly its job — this is the first thing it found.

Verified:
  test_cmake_test_registration.py    -> 5 passed (1 failed on master)
  pytest tests/                      -> 15 passed (14 passed 1 failed on master)
  test_crypto_ed25519_loworder       -> 5/5 tests passed
  ctest                              -> 39/39 passed (master builds 38)

* ci: pin the eBoot and ebuild checkouts instead of floating on master

Every open eos pull request is currently red on `EoS Full-Stack Simulation`,
and none of them caused it. The kernel job checks out embeddedos-org/eBoot at
`ref: master`, and eBoot master does not compile: include/eos_image.h:135 and
:142 static-assert offsetof(eos_image_header_t, reserved) for a member that
became tlv_len + tlv_hash, and core/ed25519_verify.c redefines
point_is_identity -- two pairs of PRs that each merged clean and broke the
build together. eBoot #94 repairs it and waits on review; until it lands, no
change to any eos PR can make this job pass, and after it lands the next
broken eBoot master does the same thing again.

A floating `ref: master` makes every eos PR's CI depend on the moment-to-
moment state of another repository's default branch. Pinning the two
compiled-against checkouts makes the job a function of this repository plus
two recorded SHAs -- red means the PR broke something, green means it did not,
and a cross-repo bump is a reviewable one-line diff with CI on it.

  EBOOT_COMMIT  a172a6d6e1e6  the newest eBoot master ancestor that compiles;
                found by walking master back and building each candidate.
                Its child 8a015b2 already carries the ed25519 redefinition.
  EBUILD_COMMIT e5d8052f3e2c  ebuild's current master, frozen as-is. Both of
                its checkouts feed steps that are commented out (eFab does
                not exist), so this pin only removes the float.

The middleware matrix (10 repos) still floats; it runs those repos' own
tests rather than compiling eos against them, and 10 more pins deserve their
own decision. When eBoot #94 merges, bump EBOOT_COMMIT to the merge SHA.

Verified before pushing, master vs pin under the job's own configuration
(-DEBLDR_BOARD=qemu_arm64 -DEBLDR_VERIFY_STAGE1=OFF -DCMAKE_BUILD_TYPE=Release,
cross-compile mode): eBoot@master fails at the eos_image.h asserts, the exact
error in the job log; eBoot@a172a6d builds every target, rc=0. Both pinned
SHAs verified reachable from their repos' master. Workflow parses; the three
`ref:` edits and the env block are the whole diff. This PR's own simulation
run is the live test: it uses this branch's workflow and should go green
while every master-based PR stays red.

Carried onto this branch from #135 (001128d) so this PR's own simulation
job runs against a buildable eBoot: each pull request executes its own copy
of the workflow, so the fix greens a PR only once its branch contains it.
Byte-identical to #135's commit -- git drops it as already-upstream the
moment #135 merges. The pin itself is #135's to review.
srpatcha pushed a commit that referenced this pull request Sep 8, 2026
…rd it (#114)

* fix(build): restore the low-order Ed25519 suite that #93 removed

`CI — eos` and `Python Unit Tests` are red on master (769191a), and both
fail for one reason:

    these suites exist in tests/ but no add_executable() in
    tests/CMakeLists.txt builds them, so they never run:
    ['test_crypto_ed25519_loworder.c']

3aa8644 (#93, "remove duplicate test targets from tests/CMakeLists.txt")
removed all four lines that build and register
test_crypto_ed25519_loworder. It was not a duplicate — there was exactly
one registration before that commit, and it took it.

What stopped running is the suite that guards #101: Ed25519 rejecting
low-order public keys. A low-order key makes every term of the
verification equation collapse to the identity regardless of the
message, so a signature of all zeros verifies against any content at
all. The fix is still in services/crypto/src/ed25519_verify.c and still
correct; nothing has been checking it since #93 merged, and nothing
would have noticed if a later change had removed it too.

Restored verbatim from 3aa8644^, in its original position before
test_crypto_sha512. No other file changes.

The guard that caught this is test_cmake_test_registration.py, added
recently. It did exactly its job — this is the first thing it found.

Verified:
  test_cmake_test_registration.py    -> 5 passed (1 failed on master)
  pytest tests/                      -> 15 passed (14 passed 1 failed on master)
  test_crypto_ed25519_loworder       -> 5/5 tests passed
  ctest                              -> 39/39 passed (master builds 38)

* test: stop building test_net_mock, which covers nothing, and say what the guard checks

Reduces this PR to what it still contributes, and answers the review.

The four registrations it opened with have landed on master by other routes --
test_mpu_validate, test_e2e, test_hal_stm32f4 and the registration guard are
all there. Merging the branch as it stood would have reverted 505 lines that
landed since, including #120's pkg trust anchor. Reset onto #127 and kept only
what is still true.

Finding 1 (Medium) -- test_net_mock was registered with no
target_link_libraries and includes no EmbeddedOS header. Its mock_net_*
functions are called directly rather than standing in for eos_net_*, so no
change to net/ can make it fail: 614 lines asserting a mock against itself.
Registering it added a green ctest entry covering nothing, which is precisely
the failure mode the guard in this same commit exists to surface -- and the
guard's own NOT_BUILT policy is where it belongs. Listed there with the reason,
including what would make it worth building: driving the real eos_net_* API
against the mock transport, which is what its docblock already claims it does.

Finding 2 (Low) -- documented the guard's limit where the policy is defined.
It checks that every suite is built and registered with ctest. It does not
check that a suite reaches the code it is named after, and a file that links
nothing satisfies it completely. Worth stating next to NOT_BUILT, because that
is the list someone reaches for when the guard fires.

Findings 3 and 4 are moot at this head: the test_mpu_validate comment and
test_net_mock's vestigial assert.h include both belonged to hunks that are
either upstream or removed here.

Verified:
  pytest tests/     15 passed
  ctest             38/38 PASS
    (test_net_mock is no longer among them; the count is unchanged from
    master because #127, which this is stacked on, adds
    test_crypto_ed25519_loworder -- a suite that does exercise real code.)

Refs #114

* ci: pin the eBoot and ebuild checkouts instead of floating on master

Every open eos pull request is currently red on `EoS Full-Stack Simulation`,
and none of them caused it. The kernel job checks out embeddedos-org/eBoot at
`ref: master`, and eBoot master does not compile: include/eos_image.h:135 and
:142 static-assert offsetof(eos_image_header_t, reserved) for a member that
became tlv_len + tlv_hash, and core/ed25519_verify.c redefines
point_is_identity -- two pairs of PRs that each merged clean and broke the
build together. eBoot #94 repairs it and waits on review; until it lands, no
change to any eos PR can make this job pass, and after it lands the next
broken eBoot master does the same thing again.

A floating `ref: master` makes every eos PR's CI depend on the moment-to-
moment state of another repository's default branch. Pinning the two
compiled-against checkouts makes the job a function of this repository plus
two recorded SHAs -- red means the PR broke something, green means it did not,
and a cross-repo bump is a reviewable one-line diff with CI on it.

  EBOOT_COMMIT  a172a6d6e1e6  the newest eBoot master ancestor that compiles;
                found by walking master back and building each candidate.
                Its child 8a015b2 already carries the ed25519 redefinition.
  EBUILD_COMMIT e5d8052f3e2c  ebuild's current master, frozen as-is. Both of
                its checkouts feed steps that are commented out (eFab does
                not exist), so this pin only removes the float.

The middleware matrix (10 repos) still floats; it runs those repos' own
tests rather than compiling eos against them, and 10 more pins deserve their
own decision. When eBoot #94 merges, bump EBOOT_COMMIT to the merge SHA.

Verified before pushing, master vs pin under the job's own configuration
(-DEBLDR_BOARD=qemu_arm64 -DEBLDR_VERIFY_STAGE1=OFF -DCMAKE_BUILD_TYPE=Release,
cross-compile mode): eBoot@master fails at the eos_image.h asserts, the exact
error in the job log; eBoot@a172a6d builds every target, rc=0. Both pinned
SHAs verified reachable from their repos' master. Workflow parses; the three
`ref:` edits and the env block are the whole diff. This PR's own simulation
run is the live test: it uses this branch's workflow and should go green
while every master-based PR stays red.

Carried onto this branch from #135 (001128d) so this PR's own simulation
job runs against a buildable eBoot: each pull request executes its own copy
of the workflow, so the fix greens a PR only once its branch contains it.
Byte-identical to #135's commit -- git drops it as already-upstream the
moment #135 merges. The pin itself is #135's to review.
srpatcha added a commit that referenced this pull request Sep 8, 2026
* fix(build): restore the low-order Ed25519 suite that #93 removed

`CI — eos` and `Python Unit Tests` are red on master (769191a), and both
fail for one reason:

    these suites exist in tests/ but no add_executable() in
    tests/CMakeLists.txt builds them, so they never run:
    ['test_crypto_ed25519_loworder.c']

3aa8644 (#93, "remove duplicate test targets from tests/CMakeLists.txt")
removed all four lines that build and register
test_crypto_ed25519_loworder. It was not a duplicate — there was exactly
one registration before that commit, and it took it.

What stopped running is the suite that guards #101: Ed25519 rejecting
low-order public keys. A low-order key makes every term of the
verification equation collapse to the identity regardless of the
message, so a signature of all zeros verifies against any content at
all. The fix is still in services/crypto/src/ed25519_verify.c and still
correct; nothing has been checking it since #93 merged, and nothing
would have noticed if a later change had removed it too.

Restored verbatim from 3aa8644^, in its original position before
test_crypto_sha512. No other file changes.

The guard that caught this is test_cmake_test_registration.py, added
recently. It did exactly its job — this is the first thing it found.

Verified:
  test_cmake_test_registration.py    -> 5 passed (1 failed on master)
  pytest tests/                      -> 15 passed (14 passed 1 failed on master)
  test_crypto_ed25519_loworder       -> 5/5 tests passed
  ctest                              -> 39/39 passed (master builds 38)

* fix(pkg): refuse a source download that cannot be verified

eos_fetch_source() compared the archive against its expected digest only
when one was supplied:

    if (expected_hash && expected_hash[0]) { ...compare... }

so calling it without a digest downloaded the archive and extracted it
having compared it against nothing -- and returned EOS_OK, which is what a
verified fetch also returns. The caller cannot tell the two apart, and the
argument is an ordinary optional parameter of a public function declared
in pkg/include/eos/package.h.

Refuse instead, before the network is touched. Git URLs stay exempt: a
clone carries its own object hashes.

ebuild made the same change to PackageFetcher.fetch() for the same reason
(embeddedos-org/ebuild#67) -- omitting one field bought an unverified
download there too.

tests/test_pkg_fetch.c is new; the function had no tests. Every case is
offline by construction, because returning before the network is touched
is the property under test: each archive form this fetcher extracts is
refused without a digest, an empty digest is refused rather than treated
as absent, an unsafe URL still fails as unsafe rather than as a checksum
error, and an empty URL is still the no-op it was.

39/39. Against the unfixed fetcher the suite fails on its first assertion.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(pkg): honour the digest on the git path too, and anchor is_git_url

Answers the review on #115. The tarball half of this PR was correct; the
identical defect was still live one branch over.

Finding 1 (High) -- the guard read `if (is_tarball(url) && ...)`, so a git URL
passed it with a digest and without one, and fetch_git() then never looked at
expected_hash. A caller that pinned a revision got EOS_OK and the content with
nothing compared -- verbatim the property this PR's own body names as the
defect: "the caller cannot tell the two apart, because both return EOS_OK."

fetch_git() now takes the pin and compares it against the commit the clone
actually landed on (`git -C <dest> rev-parse HEAD`), failing EOS_ERR_CHECKSUM
on a mismatch or if HEAD cannot be read.

Finding 3 (Medium) -- the exemption's stated reason was "a clone carries its
own object hashes". That is true and does not support the exemption: object
hashes prove the transfer was not corrupted, not that the content is the
content that was reviewed. `git clone --depth 1` takes whatever the default
branch points at when it runs, so an unpinned git source is exactly the moving
input this function exists to refuse. The pre-network guard now covers git as
well, naming "commit" rather than "SHA-256" in the message.

  Behaviour change worth stating plainly: a git source with no pinned commit
  is now refused where it used to be cloned. No recipe in this repository uses
  a git source, so nothing in-tree changes, but an out-of-tree recipe relying
  on an unpinned clone will need a commit added.

Finding 2 (Medium) -- is_git_url() was `strstr(url, ".git") != NULL`, an
unanchored substring test. It matched any host under *.github.io, including
this organisation's own pages, and any archive whose path contained ".git" --
https://example.com/.github/release.tar.gz took the git branch and skipped the
tarball digest check entirely. Now anchored: ".git" at end of string or before
/, # or ?, plus the git:// and git@ schemes.

Finding 4 (Low) -- "every archive form this fetcher extracts is covered" named
three of four; .zip was missing. Added, and the claim narrowed to what it
asserts.

Verified:
  ctest                                     39/39 PASS
  test_pkg_fetch                            7/7 PASS
  the new tests against the pre-fix fetcher: the git cases FAIL, so they
    discriminate rather than restate the fix
  no .git recipe in-tree (grep over *.yaml/*.yml) so the stricter git rule
    breaks nothing here

Refs #115

* ci: pin the eBoot and ebuild checkouts instead of floating on master

Every open eos pull request is currently red on `EoS Full-Stack Simulation`,
and none of them caused it. The kernel job checks out embeddedos-org/eBoot at
`ref: master`, and eBoot master does not compile: include/eos_image.h:135 and
:142 static-assert offsetof(eos_image_header_t, reserved) for a member that
became tlv_len + tlv_hash, and core/ed25519_verify.c redefines
point_is_identity -- two pairs of PRs that each merged clean and broke the
build together. eBoot #94 repairs it and waits on review; until it lands, no
change to any eos PR can make this job pass, and after it lands the next
broken eBoot master does the same thing again.

A floating `ref: master` makes every eos PR's CI depend on the moment-to-
moment state of another repository's default branch. Pinning the two
compiled-against checkouts makes the job a function of this repository plus
two recorded SHAs -- red means the PR broke something, green means it did not,
and a cross-repo bump is a reviewable one-line diff with CI on it.

  EBOOT_COMMIT  a172a6d6e1e6  the newest eBoot master ancestor that compiles;
                found by walking master back and building each candidate.
                Its child 8a015b2 already carries the ed25519 redefinition.
  EBUILD_COMMIT e5d8052f3e2c  ebuild's current master, frozen as-is. Both of
                its checkouts feed steps that are commented out (eFab does
                not exist), so this pin only removes the float.

The middleware matrix (10 repos) still floats; it runs those repos' own
tests rather than compiling eos against them, and 10 more pins deserve their
own decision. When eBoot #94 merges, bump EBOOT_COMMIT to the merge SHA.

Verified before pushing, master vs pin under the job's own configuration
(-DEBLDR_BOARD=qemu_arm64 -DEBLDR_VERIFY_STAGE1=OFF -DCMAKE_BUILD_TYPE=Release,
cross-compile mode): eBoot@master fails at the eos_image.h asserts, the exact
error in the job log; eBoot@a172a6d builds every target, rc=0. Both pinned
SHAs verified reachable from their repos' master. Workflow parses; the three
`ref:` edits and the env block are the whole diff. This PR's own simulation
run is the live test: it uses this branch's workflow and should go green
while every master-based PR stays red.

Carried onto this branch from #135 (001128d) so this PR's own simulation
job runs against a buildable eBoot: each pull request executes its own copy
of the workflow, so the fix greens a PR only once its branch contains it.
Byte-identical to #135's commit -- git drops it as already-upstream the
moment #135 merges. The pin itself is #135's to review.

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Srikanth Patchava <srikanth.patchava@outlook.com>
srpatcha added a commit that referenced this pull request Sep 8, 2026
…rtos (#118)

* fix(build): restore the low-order Ed25519 suite that #93 removed

`CI — eos` and `Python Unit Tests` are red on master (769191a), and both
fail for one reason:

    these suites exist in tests/ but no add_executable() in
    tests/CMakeLists.txt builds them, so they never run:
    ['test_crypto_ed25519_loworder.c']

3aa8644 (#93, "remove duplicate test targets from tests/CMakeLists.txt")
removed all four lines that build and register
test_crypto_ed25519_loworder. It was not a duplicate — there was exactly
one registration before that commit, and it took it.

What stopped running is the suite that guards #101: Ed25519 rejecting
low-order public keys. A low-order key makes every term of the
verification equation collapse to the identity regardless of the
message, so a signature of all zeros verifies against any content at
all. The fix is still in services/crypto/src/ed25519_verify.c and still
correct; nothing has been checking it since #93 merged, and nothing
would have noticed if a later change had removed it too.

Restored verbatim from 3aa8644^, in its original position before
test_crypto_sha512. No other file changes.

The guard that caught this is test_cmake_test_registration.py, added
recently. It did exactly its job — this is the first thing it found.

Verified:
  test_cmake_test_registration.py    -> 5 passed (1 failed on master)
  pytest tests/                      -> 15 passed (14 passed 1 failed on master)
  test_crypto_ed25519_loworder       -> 5/5 tests passed
  ctest                              -> 39/39 passed (master builds 38)

* fix(build): declare the dependency where it belongs, and make the pop-back structural

Answers the review on #118.

Finding 1 (Medium) -- systems/src/firmware.c includes eos/backend.h and calls
eos_backend_find(), but eos_systems linked only eos_core and eos_toolchains;
the dependency was satisfied at each consumer instead, so every future user of
eos_systems had to rediscover it. eos_systems now declares it, and
eos_backends comes off the test_firmware line.

Finding 2 (Medium) -- backends/include was added to the global
include_directories(), putting a build-orchestration header on the include
path of every target in the tree, eos_kernel and eos_hal included. Nothing
then stops kernel or HAL code acquiring a dependency master design 5.1
forbids. Taken the reviewer's version rather than a narrower one: the header
moves to include/eos/backend.h -- replacing the stale copy that caused the
original shadowing -- backends/include is gone, and both the global entry and
backends' own target_include_directories with it. include/ stays the single
public-header contract, and the shadow is now structurally impossible rather
than merely resolved.

Finding 3 (Medium) -- the pop-back fired only for seven literal keys, which
made it a second authority on what a `system` child key is, kept in step with
`case SEC_SYSTEM:` by hand and by nothing else. Add an eighth key there and
the swallow returns for it silently. Now structural: every descendant of a
system sub-section sits at indent >= 2 and list items `continue` earlier, so
indent <= 1 is exactly the condition. Same behaviour on every config under
examples/, and it cannot drift.

Finding 4 (Low) -- applied the same structural guard to
SEC_TOOLCHAIN_LINUX/SEC_TOOLCHAIN_RTOS, which popped back for one sibling and
none respectively. A `target:` at toolchain's own indent written after the
linux:/rtos: blocks landed in toolchain.rtos_target instead of
toolchain.target. Not reachable by any config in examples/ today, which is
why it had not bitten.

Also dropped the test_crypto_ed25519_loworder registration hunk; this branch
is stacked on #127, which is the copy to keep.

NOT fixed, and confirmed while testing: finding 5, `system.entry` is parsed by
nothing -- no branch in `case SEC_SYSTEM:` and no field on EosSystemConfig --
while six shipped configs set it. examples/multicore-amp/eos.yaml sets
`entry: main.c` and `eos info` reports nothing for it. Same failure mode, but
it needs a new struct field and a decision about what consumes it, so it is a
follow-up rather than something to fold in here.

Verified:
  ctest                    40/40 PASS
  pytest tests/            15 passed
  eos info, in examples/industrial-gateway:
      kind: hybrid / kernel provider: buildroot / RTOS targets (1)
    which is the parser fix visible end to end -- RTOS targets reads 0 before
    it. examples/multicore-amp reports 0, correctly: that config has no rtos
    list at all.

Refs #118

* ci: pin the eBoot and ebuild checkouts instead of floating on master

Every open eos pull request is currently red on `EoS Full-Stack Simulation`,
and none of them caused it. The kernel job checks out embeddedos-org/eBoot at
`ref: master`, and eBoot master does not compile: include/eos_image.h:135 and
:142 static-assert offsetof(eos_image_header_t, reserved) for a member that
became tlv_len + tlv_hash, and core/ed25519_verify.c redefines
point_is_identity -- two pairs of PRs that each merged clean and broke the
build together. eBoot #94 repairs it and waits on review; until it lands, no
change to any eos PR can make this job pass, and after it lands the next
broken eBoot master does the same thing again.

A floating `ref: master` makes every eos PR's CI depend on the moment-to-
moment state of another repository's default branch. Pinning the two
compiled-against checkouts makes the job a function of this repository plus
two recorded SHAs -- red means the PR broke something, green means it did not,
and a cross-repo bump is a reviewable one-line diff with CI on it.

  EBOOT_COMMIT  a172a6d6e1e6  the newest eBoot master ancestor that compiles;
                found by walking master back and building each candidate.
                Its child 8a015b2 already carries the ed25519 redefinition.
  EBUILD_COMMIT e5d8052f3e2c  ebuild's current master, frozen as-is. Both of
                its checkouts feed steps that are commented out (eFab does
                not exist), so this pin only removes the float.

The middleware matrix (10 repos) still floats; it runs those repos' own
tests rather than compiling eos against them, and 10 more pins deserve their
own decision. When eBoot #94 merges, bump EBOOT_COMMIT to the merge SHA.

Verified before pushing, master vs pin under the job's own configuration
(-DEBLDR_BOARD=qemu_arm64 -DEBLDR_VERIFY_STAGE1=OFF -DCMAKE_BUILD_TYPE=Release,
cross-compile mode): eBoot@master fails at the eos_image.h asserts, the exact
error in the job log; eBoot@a172a6d builds every target, rc=0. Both pinned
SHAs verified reachable from their repos' master. Workflow parses; the three
`ref:` edits and the env block are the whole diff. This PR's own simulation
run is the live test: it uses this branch's workflow and should go green
while every master-based PR stays red.

Carried onto this branch from #135 (001128d) so this PR's own simulation
job runs against a buildable eBoot: each pull request executes its own copy
of the workflow, so the fix greens a PR only once its branch contains it.
Byte-identical to #135's commit -- git drops it as already-upstream the
moment #135 merges. The pin itself is #135's to review.

---------

Co-authored-by: Srikanth Patchava <srikanth.patchava@outlook.com>
srpatcha pushed a commit that referenced this pull request Sep 8, 2026
…129)

* fix(build): restore the low-order Ed25519 suite that #93 removed

`CI — eos` and `Python Unit Tests` are red on master (769191a), and both
fail for one reason:

    these suites exist in tests/ but no add_executable() in
    tests/CMakeLists.txt builds them, so they never run:
    ['test_crypto_ed25519_loworder.c']

3aa8644 (#93, "remove duplicate test targets from tests/CMakeLists.txt")
removed all four lines that build and register
test_crypto_ed25519_loworder. It was not a duplicate — there was exactly
one registration before that commit, and it took it.

What stopped running is the suite that guards #101: Ed25519 rejecting
low-order public keys. A low-order key makes every term of the
verification equation collapse to the identity regardless of the
message, so a signature of all zeros verifies against any content at
all. The fix is still in services/crypto/src/ed25519_verify.c and still
correct; nothing has been checking it since #93 merged, and nothing
would have noticed if a later change had removed it too.

Restored verbatim from 3aa8644^, in its original position before
test_crypto_sha512. No other file changes.

The guard that caught this is test_cmake_test_registration.py, added
recently. It did exactly its job — this is the first thing it found.

Verified:
  test_cmake_test_registration.py    -> 5 passed (1 failed on master)
  pytest tests/                      -> 15 passed (14 passed 1 failed on master)
  test_crypto_ed25519_loworder       -> 5/5 tests passed
  ctest                              -> 39/39 passed (master builds 38)

* ci: finish the EoSim fix — a tag that exists, and no wheel anywhere

`Simulation Test` and `EoSim Sanity` are both red on master. #106 fixed
this class in eosim-sanity.yml but did not reach every site.

simulation-test.yml still pins EOSIM_VERSION: "0.1.0". EoSim has no
v0.1.0 tag — its releases run v1.0.0 to v3.0.1 — so every run failed at
the clone:

    fatal: Remote branch v0.1.0 not found in upstream origin

Bumped to 1.5.0, the release marked Latest and the one eosim-sanity.yml
already pins.

eosim-sanity.yml still installs a wheel on its Windows and macOS legs:

    ERROR: HTTP error 404 while getting
    .../releases/download/v1.5.0/eosim-1.5.0-py3-none-any.whl

No EoSim release ships a wheel, so that URL 404s at any version — the
version bump alone could never fix these two. The other three jobs in
the same workflow already install from a clone; these two were missed.
Converted to the same clone + `pip install -e`.

Verified, against the real remote rather than from the error message:

    wheel URL                       -> HTTP 404
    git ls-remote --tags | v0.1.0   -> 0 matches
    git ls-remote --tags | v1.5.0   -> 1 match
    clone v1.5.0 + pip install -e   -> rc 0
    eosim --version                 -> eosim, version 2.0.0
    eosim doctor                    -> rc 0

(The v1.5.0 tag reporting version 2.0.0 is EoSim's own inconsistency,
not a wrong pin — v1.5.0 is what its releases page marks Latest.)

Both files still parse as YAML. Stacked on the #127 registration fix so
this branch's CI is not red for an unrelated reason.

* ci(eosim): pin the commit, assert the version pip resolved, and let the workflow test itself

Answers the review on #129. The two diagnoses in the previous commit hold --
there is no v0.1.0 tag and no EoSim release ships a Python artifact -- and
this addresses what the replacement pin did not.

Finding 1 (High) -- `EOSIM_VERSION: "1.5.0"` is a label, not a version.
Re-verified against the remote rather than taken from the review:

  tag      commit    committed    commit subject             pyproject  __init__
  v1.5.0   7dec3460  2026-05-27   "production-ready v1.4.0"    3.0.1      3.0.1
  v3.0.1   b297ec26  2026-05-16   "v3.0.1 — unified ..."       3.0.1      2.0.0

v1.5.0 is the release GitHub marks Latest and the newest tag by commit date,
tags a commit whose own message claims v1.4.0, and installs a dist declaring
3.0.1. A reader of `EOSIM_VERSION: "1.5.0"` would believe eos is simulated
against EoSim 1.5.0. It is not, and nothing in the file would reveal that.

Both workflows now pin `EOSIM_COMMIT` to the full SHA that tag resolves to
today, with the table above in the env block and the date it was checked.
Not v3.0.1 instead: its `__init__.py` says 2.0.0, so it is only marginally
less confusing. A SHA cannot be moved under us; the comment says to go back to
a tag once EoSim's tags mean something.

Finding 3 (Medium) -- `eosim --version` cannot detect a wrong install.
EoSim hardcodes it (`eosim/cli/main.py:49`,
`@click.version_option(version="2.0.0")`), confirmed by reading that file at
v1.5.0, so it prints 2.0.0 from every tag -- which is exactly why the previous
commit could record the version oddity as a curiosity rather than as a failed
pin. All three sites now also assert `importlib.metadata.version("eosim")`
against `EOSIM_EXPECTED_DIST`, which is the only version the commit pin
controls.

Finding 4 (Medium) -- this PR could not be validated by CI and was not: both
workflows were schedule- and dispatch-only, so neither appeared in this head's
checks and all 25 green ones were other workflows. Added
`pull_request: paths:` on both files listing both files, so a change to either
now runs both. `workflow_dispatch` on the fork is not available to me --
GitHub resolves the workflow on the fork's default branch and returns 404 --
so this trigger is the evidence that is actually obtainable, and it applies to
every future change to these files rather than to this one only.

Finding 2 (High) -- after this, nothing in the org exercises a published EoSim
artifact, and none exists. Verified independently: 13 releases whose assets
are promo .mp4 files, a manifest.json and EoSim-guide.pdf; no wheel or sdist
at any tag; `https://pypi.org/pypi/eosim/json` returns 404. Converting to a
clone is right -- a permanent 404 is not a useful red -- but it would also
make the gap green and invisible, which is the "verification whose result is
discarded" shape.

So `published-artifact-watch` runs on every execution, checks the releases and
PyPI, and says out loud that the packaging debt is open. It cannot fail the
workflow, deliberately: it is a tracking signal, not a gate on someone else's
repo. It emits a `::notice::` the day an artifact appears, which is when it
should be deleted and the installs pointed at it. The debt is also stated in
the PR body rather than left implied, and raised against EoSim.

Finding 5 (Low) -- `/tmp/EoSim` was hardcoded in the two jobs that run on
windows-latest and macos-latest, where the Windows job sets no `shell:` and
gets pwsh. Now `${{ runner.temp }}/EoSim` everywhere.

Finding 6 (Low) -- dropped `-e`. Nothing needs an editable install, it is
further from what a developer does in a workflow meant to prove the install
works, and it made the dist-metadata assertion depend on the clone staying
put. Changed at all five sites, not two, so they are consistent.

Also, while in this file: `sanity-gate` had the fail-open shape --
`needs:` five jobs, tested `install-validate` alone, then printed "All EoSim
sanity checks passed". Replaced with the `toJSON(needs)` body, which cannot
fall out of step with `needs:`, and the new job is included in it.

Verified:
  ctest                                       39/39 PASS
  pytest tests/                               15 passed
  both workflows parse, and structurally:
    pull_request paths list this file           both
    EOSIM_VERSION gone from every code line     both
    EOSIM_COMMIT is a full 40-char sha          both
    no /tmp/EoSim literal, no `pip install -e`  both
    every `git clone --filter` has a matching `checkout --detach`
    three importlib.metadata assertions
    sanity-gate needs == every other job in the file
  the SHA resolves: refs/tags/v1.5.0 -> tag object 978f215f -> commit
    7dec3460cba76083b6645eb4a867e39aa2af97df

  NOT RUN: neither workflow. `workflow_dispatch` on the fork returns 404
  because GitHub resolves it on the fork's default branch. The
  `pull_request: paths:` trigger should make both run on this PR for the
  first time -- that will be the first execution either has ever had, and I
  will report what it shows rather than predicting it.

Finding 7 (Low): still stacked on #127; the tests/CMakeLists.txt hunk goes
when that lands.

Refs #129

* ci(eosim): copy platforms/ in every job that runs a simulation

The first real execution of these workflows -- which the pull_request trigger
added in the previous commit made possible -- failed, and showed the next
blocker behind the missing v0.1.0 tag:

    FileNotFoundError: [Errno 2] No such file or directory:
      '/opt/hostedtoolcache/Python/3.12.14/x64/lib/python3.12/site-packages/platforms'

on all three Guest OS Install legs and all seven Nested Simulation platforms.

platforms/ is data, not package data: eosim/cli/main.py sets PLATFORMS_DIR to
<site-packages>/platforms while the wheel ships only
eosim/platforms/__init__.py. None of the five jobs that run eosim copied it,
so none of them could ever have worked. A tag that exists was necessary and
not sufficient, exactly as the review said.

  Worth recording: this is also what the dropped `pip install -e` was
  accidentally papering over in the jobs that had a copy elsewhere. With an
  editable install eosim.__file__ points into the clone, so PLATFORMS_DIR
  landed beside the checked-out platforms/ by luck. A plain install is the
  right thing and it made the real dependency visible.

install-validate went green in that run and the tracking job reported the
packaging debt as intended; the failures were confined to the jobs that
actually boot a platform.

Verified:
  both workflows parse; all five eosim-running jobs now copy platforms/
  the run that produced the error: 33783625398 (EoSim Sanity), first
  execution this workflow has ever had

Refs #129

* ci(eosim): run the bash steps in bash, including on the Windows legs

Second real execution, after the platforms/ fix: ubuntu and macOS now pass
Install & Validate; all three windows-latest legs fail.

    Install & Validate (windows-latest, Python 3.12)
      #   FileNotFoundError: .../site-packages/platforms
      ##[error]Process completed with exit code 1

The give-away is the leading `#` in that line: pwsh echoed my comment as a
command. install-validate is a matrix over ubuntu/windows/macos and set no
`shell:`, so on the Windows legs it got the runner default, where
`VAR=$(...)`, `cp -r` and a leading `#` are all wrong. windows-sanity had
the same gap.

`shell: bash` on the six run steps in the two Windows-capable jobs. This is
the same defect the review raised as finding 5 for the hardcoded /tmp path --
${{ runner.temp }} fixed where the clone goes, and this fixes what interprets
the script.

Worth stating plainly: none of this was visible before the pull_request
trigger. Two runs have now found two blockers behind the missing v0.1.0 tag --
platforms/ never copied in any job, and bash steps running under pwsh -- in a
workflow that had never executed once. The trigger is doing more work than the
pin.

Verified:
  parses; no run step in a windows-capable job is left without a shell
  run 33784349071: ubuntu + macOS Install & Validate green, windows red
    with the error above

Refs #129

* ci(sim): run the bash steps in bash on the Windows leg too

Third run. EoSim Sanity is green -- 23/23 jobs, the first green run that
workflow has ever had. Simulation Test has one failure left,
`Cross-Platform (windows-latest)`, and it is the same defect I fixed in
eosim-sanity.yml one commit ago and did not apply here:

    Cross-Platform (windows-latest)  Install EoSim from source
      # fails with FileNotFoundError.
      ##[error]Process completed with exit code 1

pwsh echoing a `#` comment as a command. The cross-platform matrix includes
windows-latest and its two run steps set no `shell:`.

Refs #129

* ci(eosim): one install recipe, gates that refuse empty input, and a watch that stops posing as a check

Answers the overnight review on #129.

Finding 3 (Low, and the structural one) -- the five-line install recipe was
copy-pasted at seven sites across two workflows, and the PR's own history
shows the cost: -e dropped "at all five sites, not two", runner.temp at all
of them, shell: bash at several, each a separate round because each site was
a separate edit. Now .github/actions/install-eosim owns it -- clone at the
pinned commit, install, stage platforms/, assert the dist version -- and all
seven sites are a four-line `uses:`. The platforms/ workaround and the
version assertion get one place to be deleted from when EoSim fixes its
packaging. The triplicated inline importlib.metadata assert is gone with it.

Finding 5 (Low), folded into the composite -- SITE_PACKAGES comes from
sysconfig.get_paths()["purelib"], which needs no import and cannot be
shadowed, matching eBoot's copy of the workaround instead of solving the same
problem a second way.

Finding 1 (Medium) -- the inline gate accepted nothing as everything: an
empty RESULTS printed "All EoSim sanity jobs succeeded." and exited 0, and
null produced a raw jq error, where eos#121's extracted ci-gate-check.sh
refuses both. Both gates now refuse empty/null input with a diagnosis before
jq runs, under set -euo pipefail, and carry a note to become a call to #121's
script once it is on master so the two cannot drift.

  Reproduced the review's side-by-side on the hardened body:
      ""      rc=1  gate received no results to check   (was rc=0 PASS)
      null    rc=1  gate received no results to check   (was raw jq error)
      {}      rc=0  PASS   -- shared with #121's script; reported there, and
      []      rc=0  PASS      unreachable here: needs has five entries
      skipped rc=1  FAIL: a: skipped
      success rc=0  PASS

Also applied to simulation-test.yml's Simulation Gate, which still had the
original fail-open shape -- needs: [simulate, cross-platform], a test of
`simulate` alone, then "All simulation tests passed". Same toJSON(needs)
body, same guards.

Finding 4 (Low) -- published-artifact-watch could not fail and sat in
sanity-gate's needs under a name that made a green tick assert a deficiency.
Now "EoSim artifact publication (informational)", schedule/dispatch only, out
of the gate: pull requests no longer carry a permanently-green status about
another repository's release process, and the debt still gets said out loud
every night.

Finding 6 (Low) -- simulation-test's EOSIM_COMMIT comment argued tag
selection for what is now a SHA; it now states the actual reason (EoSim's tag
names do not identify their contents) and gains the EOSIM_EXPECTED_DIST the
composite asserts.

Finding 2 (Medium) is a two-line change in eos#121's registry, not here --
both workflows need NOT_REQUIRED entries with a paths-filter reason once both
PRs land, or #121's classification test fails. Posted on both threads with
the exact entries; not folded in, because that registry lives on #121's
branch and this PR must not carry another PR's hunks.

Verified locally before push:
  all three YAML files parse
  composite referenced at 7 sites; zero inline clone/install/copy remnants
  eosim-sanity gate needs == every job except itself and the informational
    watch; sim gate iterates toJSON(needs), no single-dependency branch
  the five-input table above, executed
  the workflows themselves: this push's pull_request run is the test, and I
  will report what it shows rather than predict it.

Refs #129

* ci: pin the eBoot and ebuild checkouts instead of floating on master

Every open eos pull request is currently red on `EoS Full-Stack Simulation`,
and none of them caused it. The kernel job checks out embeddedos-org/eBoot at
`ref: master`, and eBoot master does not compile: include/eos_image.h:135 and
:142 static-assert offsetof(eos_image_header_t, reserved) for a member that
became tlv_len + tlv_hash, and core/ed25519_verify.c redefines
point_is_identity -- two pairs of PRs that each merged clean and broke the
build together. eBoot #94 repairs it and waits on review; until it lands, no
change to any eos PR can make this job pass, and after it lands the next
broken eBoot master does the same thing again.

A floating `ref: master` makes every eos PR's CI depend on the moment-to-
moment state of another repository's default branch. Pinning the two
compiled-against checkouts makes the job a function of this repository plus
two recorded SHAs -- red means the PR broke something, green means it did not,
and a cross-repo bump is a reviewable one-line diff with CI on it.

  EBOOT_COMMIT  a172a6d6e1e6  the newest eBoot master ancestor that compiles;
                found by walking master back and building each candidate.
                Its child 8a015b2 already carries the ed25519 redefinition.
  EBUILD_COMMIT e5d8052f3e2c  ebuild's current master, frozen as-is. Both of
                its checkouts feed steps that are commented out (eFab does
                not exist), so this pin only removes the float.

The middleware matrix (10 repos) still floats; it runs those repos' own
tests rather than compiling eos against them, and 10 more pins deserve their
own decision. When eBoot #94 merges, bump EBOOT_COMMIT to the merge SHA.

Verified before pushing, master vs pin under the job's own configuration
(-DEBLDR_BOARD=qemu_arm64 -DEBLDR_VERIFY_STAGE1=OFF -DCMAKE_BUILD_TYPE=Release,
cross-compile mode): eBoot@master fails at the eos_image.h asserts, the exact
error in the job log; eBoot@a172a6d builds every target, rc=0. Both pinned
SHAs verified reachable from their repos' master. Workflow parses; the three
`ref:` edits and the env block are the whole diff. This PR's own simulation
run is the live test: it uses this branch's workflow and should go green
while every master-based PR stays red.

Carried onto this branch from #135 (001128d) so this PR's own simulation
job runs against a buildable eBoot: each pull request executes its own copy
of the workflow, so the fix greens a PR only once its branch contains it.
Byte-identical to #135's commit -- git drops it as already-upstream the
moment #135 merges. The pin itself is #135's to review.
Kartikey1306 added a commit to Kartikey1306/eos that referenced this pull request Sep 14, 2026
Every open eos pull request is currently red on `EoS Full-Stack Simulation`,
and none of them caused it. The kernel job checks out embeddedos-org/eBoot at
`ref: master`, and eBoot master does not compile: include/eos_image.h:135 and
:142 static-assert offsetof(eos_image_header_t, reserved) for a member that
became tlv_len + tlv_hash, and core/ed25519_verify.c redefines
point_is_identity -- two pairs of PRs that each merged clean and broke the
build together. eBoot embeddedos-org#94 repairs it and waits on review; until it lands, no
change to any eos PR can make this job pass, and after it lands the next
broken eBoot master does the same thing again.

A floating `ref: master` makes every eos PR's CI depend on the moment-to-
moment state of another repository's default branch. Pinning the two
compiled-against checkouts makes the job a function of this repository plus
two recorded SHAs -- red means the PR broke something, green means it did not,
and a cross-repo bump is a reviewable one-line diff with CI on it.

  EBOOT_COMMIT  a172a6d6e1e6  the newest eBoot master ancestor that compiles;
                found by walking master back and building each candidate.
                Its child 8a015b2 already carries the ed25519 redefinition.
  EBUILD_COMMIT e5d8052f3e2c  ebuild's current master, frozen as-is. Both of
                its checkouts feed steps that are commented out (eFab does
                not exist), so this pin only removes the float.

The middleware matrix (10 repos) still floats; it runs those repos' own
tests rather than compiling eos against them, and 10 more pins deserve their
own decision. When eBoot embeddedos-org#94 merges, bump EBOOT_COMMIT to the merge SHA.

Verified before pushing, master vs pin under the job's own configuration
(-DEBLDR_BOARD=qemu_arm64 -DEBLDR_VERIFY_STAGE1=OFF -DCMAKE_BUILD_TYPE=Release,
cross-compile mode): eBoot@master fails at the eos_image.h asserts, the exact
error in the job log; eBoot@a172a6d builds every target, rc=0. Both pinned
SHAs verified reachable from their repos' master. Workflow parses; the three
`ref:` edits and the env block are the whole diff. This PR's own simulation
run is the live test: it uses this branch's workflow and should go green
while every master-based PR stays red.

Carried onto this branch from embeddedos-org#135 (001128d) so this PR's own simulation
job runs against a buildable eBoot: each pull request executes its own copy
of the workflow, so the fix greens a PR only once its branch contains it.
Byte-identical to embeddedos-org#135's commit -- git drops it as already-upstream the
moment embeddedos-org#135 merges. The pin itself is embeddedos-org#135's to review.
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.

2 participants