Add CI workflow - #20
Merged
Merged
Conversation
Collaborator
Author
|
CI fails on 2 pre-existing router tests that pass on macOS but fail on Linux (float scoring tie-break differs). Not introduced by this PR — needs fixing in router.rs test expectations. |
ndizazzo
added a commit
that referenced
this pull request
Aug 20, 2026
…ntory doc
Container jobs resolve the default run: shell to sh -e {0}, not bash -e
{0} — bare-metal Linux/macOS runners default to bash, so this only changes
once a job gains a container: block. Two chunk-5b steps hit this:
- ci-web-slice.yml's ui_e2e preflight used a <<< here-string, which dash
rejects with "Syntax error: redirection unexpected".
- website-pages.yml's Stage Pages artifact used set -euo pipefail, which
dash has no -o pipefail for. This job is unreachable pre-merge
(push-to-main, path-filtered) and would have first failed on the next
main push touching website/** or crates/**, taking the Pages deploy down.
Both now declare shell: bash. Added
test_ci_workflow_container_shell_contract.py, a static sweep for bashisms
in container-job run: steps that have not declared shell: bash — same
blind spot as the ternary contract test, since actionlint's shellcheck
integration assumes bash.
Also fixes three defects in current-inventory.md's containerization
section: mesh-llm-runner-images-public-web does not exist as a separate
repo (the public web backend lives on mesh-llm-runner-images main, #20 and
#21); documents the Playwright-pin/@playwright-test coupling's actual
failure mode and the four-step cross-repo bump sequence; fixes five
table rows that were missing their Job(s) cell; and records the sh-vs-bash
property itself as a named convention.
ndizazzo
added a commit
that referenced
this pull request
Aug 20, 2026
…ntory doc
Container jobs resolve the default run: shell to sh -e {0}, not bash -e
{0} — bare-metal Linux/macOS runners default to bash, so this only changes
once a job gains a container: block. Two chunk-5b steps hit this:
- ci-web-slice.yml's ui_e2e preflight used a <<< here-string, which dash
rejects with "Syntax error: redirection unexpected".
- website-pages.yml's Stage Pages artifact used set -euo pipefail, which
dash has no -o pipefail for. This job is unreachable pre-merge
(push-to-main, path-filtered) and would have first failed on the next
main push touching website/** or crates/**, taking the Pages deploy down.
Both now declare shell: bash. Added
test_ci_workflow_container_shell_contract.py, a static sweep for bashisms
in container-job run: steps that have not declared shell: bash — same
blind spot as the ternary contract test, since actionlint's shellcheck
integration assumes bash.
Also fixes three defects in current-inventory.md's containerization
section: mesh-llm-runner-images-public-web does not exist as a separate
repo (the public web backend lives on mesh-llm-runner-images main, #20 and
#21); documents the Playwright-pin/@playwright-test coupling's actual
failure mode and the four-step cross-repo bump sequence; fixes five
table rows that were missing their Job(s) cell; and records the sh-vs-bash
property itself as a named convention.
ndizazzo
added a commit
that referenced
this pull request
Aug 20, 2026
…tes the bake install-core-tools.sh#20 bakes an exact-pinned openai into the image, but the public cpu digest pinned in ci/slices.yml predates that change (built 2026-07-22, openai landed 2026-08-19). The containerized row of smoke.yml was skipping the install on the assumption the image already had it, so Core inference smoke failed with Cannot find module 'openai'. Run it unconditionally on both rows until the digest is promoted past #20. Also records the general lesson in current-inventory.md: a pinned digest is a frozen artifact, and runner-images HEAD says nothing about what's actually inside a digest a workflow pins.
ndizazzo
added a commit
that referenced
this pull request
Aug 20, 2026
Four of the five review items; the fifth is declined below with evidence. Pin the openai npm install (smoke.yml, both call sites). The step runs with the full job environment, HF_TOKEN included, and npm lifecycle scripts inherit it, so a floating `openai` lets an unreviewed upstream release execute there -- zizmor's adhoc-packages rule flags exactly this. Pinned to 7.5.0, which is deliberately the image's own ARG OPENAI_NPM_VERSION (mesh-llm-runner-images Dockerfile:25), so that re-gating this step on job.container.id once the CPU digest is promoted past #20 becomes a no-op rather than a version swap. Drop $(( )) from the container-shell bashism sweep. Arithmetic expansion is POSIX (Shell Command Language 2.6.4) and dash evaluates it correctly (`dash -c 'x=2; echo $((x + 3))'` -> 5), so the pattern would have rejected valid sh steps and forced a spurious `shell: bash`. Replaced with an inline note so it does not get re-added; the other twelve patterns are genuine bash-only constructs and stay. Merge job-level permissions into each callee's requested scope set (test_ci_workflow_permission_contract.py). The set was built from the workflow-level block alone, which returns None for a workflow that declares its scopes only on jobs -- and line 72 then skips every caller edge for it. That is not hypothetical here: five reusable workflows (native-sdk-artifact, node-sdk-addon-artifact, sdk-smoke, static-abi-artifact, swift-sdk-artifact) declare permissions at job level only, so they were entirely invisible to the test, including their `packages: read` -- the exact scope whose missing grant produced the zero-job startup_failure this test was written to catch. Read-all/write-all still returns None (unenumerable, do not assert). Still green: the callers do grant them. Fix MD018 in current-inventory.md by writing "PR #1380" so the line no longer opens with a hash. Declined: routing setup-macos-lld's probe through a `just` recipe. AGENTS.md:67 "Always use `just`. Never build manually." is the Building section, about building mesh-llm; this is a linker sanity check that compiles a throwaway crate in RUNNER_TEMP, deliberately outside the workspace so no .cargo/config.toml target rustflags apply to it. `just` is installed at only one of the seven call sites (release.yml:252, covering :270) -- ci-platform-checks-slice.yml:117, ci-macos-host-slice.yml:118, swift-sdk-artifact.yml:174, native-sdk-artifact.yml:362, node-sdk-addon-artifact.yml:199 and release.yml:520 have no just, so the change would mean adding taiki-e/install-action to six macOS jobs to wrap two lines, directly against this PR's own thesis of removing such installs. It would also move the linker environment out of the composite that owns it and run the probe from the repo root. Inventory updated in the same change per .github/AGENTS.md: the bashism list no longer names $(( )) and says why it must not be re-added, the openai paragraph records the pin and the cross-repo bump pairing, and a new "Reusable-workflow permission chain" section documents the startup_failure class and the job-level-permissions rule. Validated: full scripts/tests suite, 489 tests, 7 skipped, OK. actionlint clean on smoke.yml.
ndizazzo
added a commit
that referenced
this pull request
Aug 20, 2026
…ntory doc
Container jobs resolve the default run: shell to sh -e {0}, not bash -e
{0} — bare-metal Linux/macOS runners default to bash, so this only changes
once a job gains a container: block. Two chunk-5b steps hit this:
- ci-web-slice.yml's ui_e2e preflight used a <<< here-string, which dash
rejects with "Syntax error: redirection unexpected".
- website-pages.yml's Stage Pages artifact used set -euo pipefail, which
dash has no -o pipefail for. This job is unreachable pre-merge
(push-to-main, path-filtered) and would have first failed on the next
main push touching website/** or crates/**, taking the Pages deploy down.
Both now declare shell: bash. Added
test_ci_workflow_container_shell_contract.py, a static sweep for bashisms
in container-job run: steps that have not declared shell: bash — same
blind spot as the ternary contract test, since actionlint's shellcheck
integration assumes bash.
Also fixes three defects in current-inventory.md's containerization
section: mesh-llm-runner-images-public-web does not exist as a separate
repo (the public web backend lives on mesh-llm-runner-images main, #20 and
#21); documents the Playwright-pin/@playwright-test coupling's actual
failure mode and the four-step cross-repo bump sequence; fixes five
table rows that were missing their Job(s) cell; and records the sh-vs-bash
property itself as a named convention.
ndizazzo
added a commit
that referenced
this pull request
Aug 20, 2026
…tes the bake install-core-tools.sh#20 bakes an exact-pinned openai into the image, but the public cpu digest pinned in ci/slices.yml predates that change (built 2026-07-22, openai landed 2026-08-19). The containerized row of smoke.yml was skipping the install on the assumption the image already had it, so Core inference smoke failed with Cannot find module 'openai'. Run it unconditionally on both rows until the digest is promoted past #20. Also records the general lesson in current-inventory.md: a pinned digest is a frozen artifact, and runner-images HEAD says nothing about what's actually inside a digest a workflow pins.
ndizazzo
added a commit
that referenced
this pull request
Aug 20, 2026
Four of the five review items; the fifth is declined below with evidence. Pin the openai npm install (smoke.yml, both call sites). The step runs with the full job environment, HF_TOKEN included, and npm lifecycle scripts inherit it, so a floating `openai` lets an unreviewed upstream release execute there -- zizmor's adhoc-packages rule flags exactly this. Pinned to 7.5.0, which is deliberately the image's own ARG OPENAI_NPM_VERSION (mesh-llm-runner-images Dockerfile:25), so that re-gating this step on job.container.id once the CPU digest is promoted past #20 becomes a no-op rather than a version swap. Drop $(( )) from the container-shell bashism sweep. Arithmetic expansion is POSIX (Shell Command Language 2.6.4) and dash evaluates it correctly (`dash -c 'x=2; echo $((x + 3))'` -> 5), so the pattern would have rejected valid sh steps and forced a spurious `shell: bash`. Replaced with an inline note so it does not get re-added; the other twelve patterns are genuine bash-only constructs and stay. Merge job-level permissions into each callee's requested scope set (test_ci_workflow_permission_contract.py). The set was built from the workflow-level block alone, which returns None for a workflow that declares its scopes only on jobs -- and line 72 then skips every caller edge for it. That is not hypothetical here: five reusable workflows (native-sdk-artifact, node-sdk-addon-artifact, sdk-smoke, static-abi-artifact, swift-sdk-artifact) declare permissions at job level only, so they were entirely invisible to the test, including their `packages: read` -- the exact scope whose missing grant produced the zero-job startup_failure this test was written to catch. Read-all/write-all still returns None (unenumerable, do not assert). Still green: the callers do grant them. Fix MD018 in current-inventory.md by writing "PR #1380" so the line no longer opens with a hash. Declined: routing setup-macos-lld's probe through a `just` recipe. AGENTS.md:67 "Always use `just`. Never build manually." is the Building section, about building mesh-llm; this is a linker sanity check that compiles a throwaway crate in RUNNER_TEMP, deliberately outside the workspace so no .cargo/config.toml target rustflags apply to it. `just` is installed at only one of the seven call sites (release.yml:252, covering :270) -- ci-platform-checks-slice.yml:117, ci-macos-host-slice.yml:118, swift-sdk-artifact.yml:174, native-sdk-artifact.yml:362, node-sdk-addon-artifact.yml:199 and release.yml:520 have no just, so the change would mean adding taiki-e/install-action to six macOS jobs to wrap two lines, directly against this PR's own thesis of removing such installs. It would also move the linker environment out of the composite that owns it and run the probe from the repo root. Inventory updated in the same change per .github/AGENTS.md: the bashism list no longer names $(( )) and says why it must not be re-added, the openai paragraph records the pin and the cross-repo bump pairing, and a new "Reusable-workflow permission chain" section documents the startup_failure class and the job-level-permissions rule. Validated: full scripts/tests suite, 489 tests, 7 skipped, OK. actionlint clean on smoke.yml.
ndizazzo
added a commit
that referenced
this pull request
Aug 20, 2026
…ntory doc
Container jobs resolve the default run: shell to sh -e {0}, not bash -e
{0} — bare-metal Linux/macOS runners default to bash, so this only changes
once a job gains a container: block. Two chunk-5b steps hit this:
- ci-web-slice.yml's ui_e2e preflight used a <<< here-string, which dash
rejects with "Syntax error: redirection unexpected".
- website-pages.yml's Stage Pages artifact used set -euo pipefail, which
dash has no -o pipefail for. This job is unreachable pre-merge
(push-to-main, path-filtered) and would have first failed on the next
main push touching website/** or crates/**, taking the Pages deploy down.
Both now declare shell: bash. Added
test_ci_workflow_container_shell_contract.py, a static sweep for bashisms
in container-job run: steps that have not declared shell: bash — same
blind spot as the ternary contract test, since actionlint's shellcheck
integration assumes bash.
Also fixes three defects in current-inventory.md's containerization
section: mesh-llm-runner-images-public-web does not exist as a separate
repo (the public web backend lives on mesh-llm-runner-images main, #20 and
#21); documents the Playwright-pin/@playwright-test coupling's actual
failure mode and the four-step cross-repo bump sequence; fixes five
table rows that were missing their Job(s) cell; and records the sh-vs-bash
property itself as a named convention.
ndizazzo
added a commit
that referenced
this pull request
Aug 20, 2026
…tes the bake install-core-tools.sh#20 bakes an exact-pinned openai into the image, but the public cpu digest pinned in ci/slices.yml predates that change (built 2026-07-22, openai landed 2026-08-19). The containerized row of smoke.yml was skipping the install on the assumption the image already had it, so Core inference smoke failed with Cannot find module 'openai'. Run it unconditionally on both rows until the digest is promoted past #20. Also records the general lesson in current-inventory.md: a pinned digest is a frozen artifact, and runner-images HEAD says nothing about what's actually inside a digest a workflow pins.
ndizazzo
added a commit
that referenced
this pull request
Aug 20, 2026
Four of the five review items; the fifth is declined below with evidence. Pin the openai npm install (smoke.yml, both call sites). The step runs with the full job environment, HF_TOKEN included, and npm lifecycle scripts inherit it, so a floating `openai` lets an unreviewed upstream release execute there -- zizmor's adhoc-packages rule flags exactly this. Pinned to 7.5.0, which is deliberately the image's own ARG OPENAI_NPM_VERSION (mesh-llm-runner-images Dockerfile:25), so that re-gating this step on job.container.id once the CPU digest is promoted past #20 becomes a no-op rather than a version swap. Drop $(( )) from the container-shell bashism sweep. Arithmetic expansion is POSIX (Shell Command Language 2.6.4) and dash evaluates it correctly (`dash -c 'x=2; echo $((x + 3))'` -> 5), so the pattern would have rejected valid sh steps and forced a spurious `shell: bash`. Replaced with an inline note so it does not get re-added; the other twelve patterns are genuine bash-only constructs and stay. Merge job-level permissions into each callee's requested scope set (test_ci_workflow_permission_contract.py). The set was built from the workflow-level block alone, which returns None for a workflow that declares its scopes only on jobs -- and line 72 then skips every caller edge for it. That is not hypothetical here: five reusable workflows (native-sdk-artifact, node-sdk-addon-artifact, sdk-smoke, static-abi-artifact, swift-sdk-artifact) declare permissions at job level only, so they were entirely invisible to the test, including their `packages: read` -- the exact scope whose missing grant produced the zero-job startup_failure this test was written to catch. Read-all/write-all still returns None (unenumerable, do not assert). Still green: the callers do grant them. Fix MD018 in current-inventory.md by writing "PR #1380" so the line no longer opens with a hash. Declined: routing setup-macos-lld's probe through a `just` recipe. AGENTS.md:67 "Always use `just`. Never build manually." is the Building section, about building mesh-llm; this is a linker sanity check that compiles a throwaway crate in RUNNER_TEMP, deliberately outside the workspace so no .cargo/config.toml target rustflags apply to it. `just` is installed at only one of the seven call sites (release.yml:252, covering :270) -- ci-platform-checks-slice.yml:117, ci-macos-host-slice.yml:118, swift-sdk-artifact.yml:174, native-sdk-artifact.yml:362, node-sdk-addon-artifact.yml:199 and release.yml:520 have no just, so the change would mean adding taiki-e/install-action to six macOS jobs to wrap two lines, directly against this PR's own thesis of removing such installs. It would also move the linker environment out of the composite that owns it and run the probe from the repo root. Inventory updated in the same change per .github/AGENTS.md: the bashism list no longer names $(( )) and says why it must not be re-added, the openai paragraph records the pin and the cross-repo bump pairing, and a new "Reusable-workflow permission chain" section documents the startup_failure class and the job-level-permissions rule. Validated: full scripts/tests suite, 489 tests, 7 skipped, OK. actionlint clean on smoke.yml.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Runs on push to main and PRs:
cargo test(122 unit tests, ~1s)cargo fmt -- --checkcargo clippy -- -D warningsUses rust-cache for fast incremental builds. No llama.cpp needed — tests are pure Rust.