Skip to content

record: track published GHCR container images as ENG-RELEASE-CONTAINERS - #172

Merged
localai-bot merged 1 commit into
mainfrom
row/ENG-RELEASE-CONTAINERS
Aug 8, 2026
Merged

record: track published GHCR container images as ENG-RELEASE-CONTAINERS#172
localai-bot merged 1 commit into
mainfrom
row/ENG-RELEASE-CONTAINERS

Conversation

@localai-bot

Copy link
Copy Markdown
Collaborator

Claim

Record-only. Adds ROAD-V1-CONTAINERS / ENG-RELEASE-CONTAINERS at INVENTORIED so that publishing container images to GHCR from GitHub Actions is tracked, and makes the public status pages say what does and does not exist. User-directed; issue #170 carries the public description.

No implementation. No Dockerfile, no workflow, no registry package, no image, no pull. The ENGINE_ROWS 143 → 144 bump claims a row, not a capability.

Why a separate row rather than widening ENG-RELEASE-BINARIES

The image is the binary lane's staged bundle — same bin/vllm-server, VERSION, manifest, SHA256, SBOM, provenance, licenses — so the row records that dependency explicitly and forbids the two lanes growing separate layouts. But the distribution channel is genuinely different: different artifact format, registry, tag contract, multi-arch manifest and publish flow. The accepted release-binary contract block in specs/release-binary-matrix.md is therefore untouched, and its 30-test mutation suite still passes unchanged.

What the row records

  • Lanes cuda (one fat image, every supported SM), vulkan, cpu (adaptive baseline); rocm blocked-preview tracking its binary channel (ROCm (AMD GPU) backend #41, ROCm: -O0 RmsNorm triggers a CLR HostcallListener teardown deadlock #132).
  • Tags one package, lane in the tag: ghcr.io/mudler/vllm.cpp:<version>-cuda / -vulkan / -cpu, moving :latest-cuda / :latest-vulkan / :latest-cpu, bare :latest aliasing cpu. Version tags immutable.
  • Arch every lane a linux/amd64 + linux/arm64 manifest on native runners, not QEMU. The gate hardware this project is measured on is aarch64 throughout — GB10 sm_121a, Thor sm_110 (Jetson AGX Thor (sm_110), CUDA 13.2: 32B NVFP4 serves, first throughput datapoints, and a Tekken tokenizer blocker #168), Orin sm_87 — and an emulated CUDA build does not finish inside a runner's lifetime.
  • Payload the bundle and nothing else. No weights, no Python, no PyTorch, no compiler, no build tree.
  • Boundaries the GPU driver and container runtime stay on the host. Metal and MLX are recorded NOT-CONTAINERIZABLE rather than deferred: there is no macOS container runtime and no Metal passthrough into a Linux VM, so those lanes can only ever be static binaries. Written as a boundary so it does not get re-opened as pending work.

Under POL-SPIKE-FIRST the row cannot advance until specs/container-images.md exists.

STATUS.md ratchet

The new status line is paid for out of the page, as the ratchet requires. The Tier-A1 fold paragraph was a run-by-run log of a 2026-07-30 branch — down to a literal commit <this>, NOT pushed — on a page whose contract is one binding current-state line per capability. It collapses to its binding result plus pointers; the run detail was already in .agents/benchmark-record.md, .agents/state.md and the fold-plan spec, so nothing is lost, only de-duplicated.

The unflattering parts stay on the page deliberately: only OLMo-2 has a committed golden, Granite and StableLM skip rather than gate, dflash and deepseek_v2 are build-verified only. Ratchet lowered 279130 → 276960 (measured 276945).

Gates

Run on a worktree pinned at 994cd8d4, then re-run after rebasing onto da0a9d8d:

  • check-agent-record.py → ENGINE=144
  • test_agent_record.py 13/13, test_doc_checkpoint.py 40/40
  • test_check_public_doc_tables.py, test_check_readme_structure.py
  • check-release-binary-contract.py + 30-test mutation suite
  • check-policy.py, check-protocol-consistency.py, check-env-doc.py, check-model-checklist.py
  • check-commit-trailers.py and check-doc-checkpoint.py over the commit range

All OK. No code compiled or run — this change touches no compiled source.

User-directed: alongside the downloadable archives in ENG-RELEASE-BINARIES
(#117, PR #141), publish container images to GHCR from GitHub Actions.
Issue #170 carries the public description.

The image is not a second packaging format. It ships exactly the staged
tree the release-binary matrix already defines - bin/vllm-server, VERSION,
manifest, SHA256, SBOM, provenance, licenses - with ENTRYPOINT vllm-server
and nothing else in it. If the two lanes grow separate layouts that is a
bug, so the row records the dependency explicitly: the staging tree and
install rule are owed by ENG-RELEASE-BINARIES and do not exist yet.

One package, lane in the tag: ghcr.io/mudler/vllm.cpp:<version>-cuda /
-vulkan / -cpu, moving :latest-cuda / :latest-vulkan / :latest-cpu, bare
:latest aliasing cpu. Version tags immutable. rocm is recorded
blocked-preview tracking its binary channel (#41, #132).

Every lane is a linux/amd64 + linux/arm64 multi-arch manifest built on
native runners rather than QEMU. arm64 is not a courtesy here: the gate
hardware this project is measured on is aarch64 throughout - GB10
sm_121a, Thor sm_110 (#168), Orin sm_87 - and an emulated CUDA build does
not finish inside a runner's lifetime.

Metal and MLX are recorded NOT-CONTAINERIZABLE, not deferred. There is no
macOS container runtime and no Metal passthrough into a Linux VM, so those
lanes can only ever be static binaries. Writing it as a boundary keeps it
from being re-opened as pending work later.

The accepted release-binary contract block is deliberately untouched: this
is a separate distribution channel with its own artifact format, registry,
tag contract and publish flow, so it gets its own row and its own future
spike rather than widening a design that has already been reviewed and is
guarded by a 30-test mutation suite.

Entered at INVENTORIED with planned: specs/container-images.md. Under
POL-SPIKE-FIRST the row cannot advance until that spike exists; no image,
workflow or registry package is claimed by the ENGINE_ROWS 143 -> 144 bump.

docs/STATUS.md and docs/BENCHMARKS.md carry the line the doc-checkpoint
gate requires. The STATUS line is paid for out of the page, as its ratchet
demands: the Tier-A1 fold paragraph was a run-by-run log of a 2026-07-30
branch, down to a literal "commit <this>, NOT pushed", on a page whose
contract is one binding current-state line per capability. It collapses to
its binding result plus pointers, and the run detail was already in
.agents/benchmark-record.md, .agents/state.md and the fold-plan spec. The
unflattering parts stay on the page on purpose - only OLMo-2 has a
committed golden, Granite and StableLM skip rather than gate, dflash and
deepseek_v2 are build-verified only. Ratchet lowered 279130 -> 276960.

Gates: check-agent-record (ENGINE=144), test_agent_record 13/13,
test_doc_checkpoint 40/40, check-release-binary-contract,
check-readme-structure, check-public-doc-tables, check-policy,
check-protocol-consistency, check-commit-trailers, check-doc-checkpoint -
all OK on a worktree pinned at 994cd8d.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: Claude-Code:claude-opus-5 [Claude Code]
@localai-bot
localai-bot merged commit b97fc1d into main Aug 8, 2026
9 of 11 checks passed
@mudler
mudler deleted the row/ENG-RELEASE-CONTAINERS branch August 8, 2026 22:40
mudler added a commit that referenced this pull request Aug 8, 2026
Landing a PR with `gh pr merge --merge` breaks two gates, and it has now
happened three times in a row on main: c3db780 (#172, mine), 3e5072d
(#174), and the trailer half on da0a9d8 (#157).

check-role-discipline.py inspects every commit in the pushed range and
wants each to name its row/<ROW-ID> branch or its PR as (#N). GitHub's
squash-merge writes (#N) into the subject for free. A --merge landing
leaves the content commit with the subject it had on the branch, which
names neither, so POL-PR-REQUIRED reports "reached main without a
reviewed row/* PR" about a commit that came from exactly such a PR.

check-commit-trailers.py reads the same range, and GitHub's generated
"Merge pull request #N from ..." message carries no
FOLLOWING_AGENTS_PROTOCOL paragraph and no trailers, so
POL-COMMIT-TRAILERS fails on the merge commit itself.

Both gates are scoped over github.event.before..github.sha and each run's
before is the previous run's sha, so no later run re-covers a range that
already went red. That is the part worth writing down: the failure is not
repairable after the push except by rewriting published history or
waiving it, and it is invisible at PR time because the PR is checked
against its own base.

Documented in CONTRIBUTING.md rather than .agents/workflow.md because
that file is 7 bytes under its 12288-byte procedure budget, and every
paragraph of its non-generated prose is load-bearing; buying room by
trimming it would cost more than this note is worth. CONTRIBUTING.md is
also where a contributor with merge rights actually looks.

This is documentation, not a guard. The permanent fix is a repository
setting - allow squash only, disable merge commits - which needs admin
and is left to the owner.

No record row, no capability claim, no code. Every tree-scoped gate on
main was already green before this change; main's red runs come entirely
from the diff-scoped range gates described above.

Gates: check-policy, check-protocol-consistency, check-agent-record,
check-readme-structure, check-public-doc-tables, check-role-discipline,
check-doc-checkpoint and check-commit-trailers over the range - all OK on
a worktree pinned at 80b0880.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: Claude-Code:claude-opus-5 [Claude Code]
localai-bot added a commit that referenced this pull request Aug 8, 2026
Two fixes for a main branch that has been red for several landings.

1) CONTRIBUTING.md documents the landing rule. Landing a PR with
`gh pr merge --merge` breaks two gates, and it happened three times in a
row: c3db780 (#172, mine), 3e5072d (#174), and the trailer half on
da0a9d8 (#157). check-role-discipline.py inspects every commit in the
pushed range and wants each to name its row branch or its PR number,
which squash-merge writes into the subject for free and --merge does not.
check-commit-trailers.py reads the same range, and GitHub's generated
merge-commit message carries no FOLLOWING_AGENTS_PROTOCOL paragraph and
no trailers. Both gates are scoped over before..sha, and each run's
before is the previous run's sha, so no later run re-covers a range that
already went red: the failure is not repairable after the push, and it is
invisible at PR time because a PR is checked against its own base.
Documented in CONTRIBUTING.md rather than .agents/workflow.md because
that file sits 7 bytes under its 12288-byte procedure budget.

2) tests/scripts/test_agent_role.py is unbroken under a pull_request
checkout. test_landed_detached_commit_remains_strict_without_pending_
evidence asserts a decision in main() -- a violation on a landed commit
with no pending evidence is strict rather than a REPORT -- but it
obtained that violation by relying on the real HEAD to be one. Under a
pull_request event GitHub checks out the synthetic refs/pull/N/merge
commit; inspect() then sees two parents, so arrives_via_row_pr() scans
the PR's own commit bodies with a pattern that matches a bare #123
anywhere. Any PR whose message cites an issue or PR number stopped being
a violation, main() returned 0, and the test failed 0 != 1. It now feeds
main() a fixed violation, with a regression case pinning that a message
mentioning a PR number cannot flip the decision again.

Proven on a reconstructed synthetic merge, the exact shape CI checks out:
RED, the old test on that checkout gave AssertionError: 0 != 1 across 41
tests, the same failure CI reported; GREEN, the new test on the SAME
checkout gave 42 tests OK. Confirmed in real CI on this PR: agent-record
now passes.

Not changed: the reference pattern matching a bare #123 anywhere also
means a direct push whose message merely mentions an issue satisfies
POL-PR-REQUIRED. That is a real hole, but tightening a policy gate is a
separate reviewed decision, not a CI repair. The permanent fix for the
merge-method half is a repository setting -- allow squash only, disable
merge commits -- which needs admin.

Gates: check-agent-record (ENGINE=144), check-role-discipline,
check-policy, check-protocol-consistency, check-readme-structure,
check-public-doc-tables, test_agent_role 42/42, test_agent_onboard, plus
check-commit-trailers and check-doc-checkpoint over the range.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: Claude-Code:claude-opus-5 [Claude Code]
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