refactor(dev-base): pin aosguard to a release instead of compiling it in-image #1096

Closed
coilyco-ops wants to merge 1 commit from aos/claude/wt57-pin-aos-bundle into main
Owner

aosguard was the only thing the image built from this repo's tree. Everything
else, internal and third-party, is a pinned release download with a SHA256
check: ward, specgen, aos, agent-compose, and seventeen others.

That single exception is what made .specgen, agentic_os, and
aos-cli/repositories build contexts, and docker/** never watched them.

Why the filter was not the bug

promote.yml is unfiltered, so a guardfile change reached release and looked
landed while dev-base-publish matched none of its paths and :release kept
the older binary. Nothing failed.

Widening the filter (#1094, closed) was the wrong fix: it charges an hour-long
rebuild to every guardfile edit. The right fix is for the image to stop
depending on the tree at all.

What replaces it

The release train already publishes everything the image assembled by hand.
aos-bundle-linux-<arch>.tar.gz carries:

bin/aos                                    <- was a separate pinned download
bin/aosguard                               <- was compiled in-image from .specgen
share/aos/aosguard-skill/...               <- was generated in-image by specgen
share/aos/python/agentic_os/*              <- was the `aosguard-python` context
share/aos/repositories/substrate-repos.txt <- was the `repo-lists` context

One verified fetch replaces all of it. All three non-docker contexts are gone
from the Dockerfile, docker-bake.hcl, dev-base-check.sh, and
publish-image.sh. The bake contexts block now holds only inter-target
references, no source paths.

Effects

  • docker/** is a complete filter rather than an accidentally narrow one. A
    guardfile edit costs no rebuild, and updating CI's aosguard is one ARG bump.
  • The image drops the in-image specgen compile.
  • aosguard --version reports a real version instead of the literal string
    dev-base, so a CI job can say which aosguard it has.
  • Pinned at 0.212.0, the release carrying aosguard ops telegram alert, so
    this also delivers #1093 to CI.

One behaviour change, deliberate

The image's site-packages narrows from 21 agentic_os modules to the 5
operator ones the bundle ships. I checked before accepting that: the image only
ever imports forgejo_actions_list, _logs, and _rerun, and all three import
cleanly with only the bundle present (their sole intra-package dependency,
forgejo_actions_web, is bundled). verify-common.sh exercises exactly one of
them.

The other 16 are validator modules that a pinned pre-commit hook must import
from its own rev, which is the isolation aos#771 asked for and
verify-common.sh already tests with a sentinel. Shipping them was leakage.

Verification

Against the real published artifact, not assumptions:

  • every path the RUN block references exists in the tarball
  • the SHA256SUMS grep-and-verify flow returns aos-bundle-linux-amd64.tar.gz: OK
  • the bundled substrate-repos.txt is byte-identical to the tree copy it replaces
  • bake --print resolves with the contexts removed
  • 534 tests pass, including a new guard asserting the image compiles nothing
    from the tree and that no removed context reappears in either file

No Docker daemon in my session, so buildx --check could not run. The PR gate
covers that, and dev-base-pr.yml will now actually exercise it since this diff
touches docker/**.

aosguard was the only thing the image built from this repo's tree. Everything else, internal and third-party, is a pinned release download with a SHA256 check: ward, specgen, aos, agent-compose, and seventeen others. That single exception is what made `.specgen`, `agentic_os`, and `aos-cli/repositories` build contexts, and `docker/**` never watched them. ## Why the filter was not the bug `promote.yml` is unfiltered, so a guardfile change reached `release` and looked landed while `dev-base-publish` matched none of its paths and `:release` kept the older binary. Nothing failed. Widening the filter (#1094, closed) was the wrong fix: it charges an hour-long rebuild to every guardfile edit. The right fix is for the image to stop depending on the tree at all. ## What replaces it The release train already publishes everything the image assembled by hand. `aos-bundle-linux-<arch>.tar.gz` carries: ``` bin/aos <- was a separate pinned download bin/aosguard <- was compiled in-image from .specgen share/aos/aosguard-skill/... <- was generated in-image by specgen share/aos/python/agentic_os/* <- was the `aosguard-python` context share/aos/repositories/substrate-repos.txt <- was the `repo-lists` context ``` One verified fetch replaces all of it. All three non-docker contexts are gone from the Dockerfile, `docker-bake.hcl`, `dev-base-check.sh`, and `publish-image.sh`. The bake `contexts` block now holds only inter-target references, no source paths. ## Effects * `docker/**` is a complete filter rather than an accidentally narrow one. A guardfile edit costs no rebuild, and updating CI's aosguard is one ARG bump. * The image drops the in-image specgen compile. * `aosguard --version` reports a real version instead of the literal string `dev-base`, so a CI job can say which aosguard it has. * Pinned at `0.212.0`, the release carrying `aosguard ops telegram alert`, so this also delivers #1093 to CI. ## One behaviour change, deliberate The image's site-packages narrows from 21 `agentic_os` modules to the 5 operator ones the bundle ships. I checked before accepting that: the image only ever imports `forgejo_actions_list`, `_logs`, and `_rerun`, and all three import cleanly with only the bundle present (their sole intra-package dependency, `forgejo_actions_web`, is bundled). `verify-common.sh` exercises exactly one of them. The other 16 are validator modules that a pinned pre-commit hook must import from its own rev, which is the isolation `aos#771` asked for and `verify-common.sh` already tests with a sentinel. Shipping them was leakage. ## Verification Against the real published artifact, not assumptions: * every path the RUN block references exists in the tarball * the SHA256SUMS grep-and-verify flow returns `aos-bundle-linux-amd64.tar.gz: OK` * the bundled `substrate-repos.txt` is byte-identical to the tree copy it replaces * `bake --print` resolves with the contexts removed * 534 tests pass, including a new guard asserting the image compiles nothing from the tree and that no removed context reappears in either file No Docker daemon in my session, so `buildx --check` could not run. The PR gate covers that, and `dev-base-pr.yml` will now actually exercise it since this diff touches `docker/**`.
refactor(dev-base): pin aosguard to a release instead of compiling it in-image
Some checks failed
ci / ward-doctor (pull_request) Successful in 14s
ci / aos-cli-tests (pull_request) Successful in 22s
ci / gate (pull_request) Successful in 55s
dev-base-pr / build (pull_request) Failing after 15m21s
e704240444
aosguard was the only thing the image built from this repo's tree. Every other
tool, internal and third-party, is a pinned release download with a SHA256
check: ward, specgen, aos, agent-compose, and seventeen others. That single
exception is what made `.specgen`, `agentic_os`, and `aos-cli/repositories`
build contexts, and the `docker/**` path filter never watched them.

The consequence was silent. `promote.yml` is unfiltered, so a guardfile change
reached the release branch and looked landed while `dev-base-publish` matched
none of its paths and `:release` kept the older binary. Nothing failed. Widening
the filter was the wrong fix, since it would charge an hour-long rebuild to
every guardfile edit.

The release train already publishes everything the image assembled by hand.
`aos-bundle-linux-<arch>.tar.gz` carries bin/aos, bin/aosguard, the generated
aosguard skill, the operator Python modules, and the repo lists. So the image
now fetches and verifies one bundle, and all three non-docker contexts are gone
from the Dockerfile, docker-bake.hcl, dev-base-check.sh, and publish-image.sh.

Effects:

* `docker/**` becomes a complete filter rather than an accidentally narrow one.
  A guardfile edit costs no rebuild, and updating CI's aosguard is one ARG bump.
* The image drops the in-image specgen compile.
* `aosguard --version` reports a real version instead of the literal `dev-base`,
  so a CI job can say which aosguard it has.
* The image's site-packages narrows from 21 agentic_os modules to the 5 operator
  ones. Verified the image only ever imports forgejo_actions_list, _logs, and
  _rerun, and that those import cleanly with only the bundle present. This is
  the isolation aos#771 asked for: the other 16 are validator modules a pinned
  hook must import from its own rev.

Pinned at 0.212.0, which is the release carrying `aosguard ops telegram alert`,
so this also delivers #1093 to CI.

Verified against the real published artifact: every path the RUN block
references exists in the tarball, the SHA256SUMS grep-and-verify flow returns
OK, and the bundled substrate-repos.txt is byte-identical to the tree copy it
replaces. `bake --print` resolves with the contexts removed. 534 tests pass.
No Docker daemon here, so `buildx --check` could not run.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Kai Siren <coilysiren@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
coilysiren closed this pull request 2026-08-18 15:39:03 +00:00
Some checks failed
ci / ward-doctor (pull_request) Successful in 14s
ci / aos-cli-tests (pull_request) Successful in 22s
ci / gate (pull_request) Successful in 55s
dev-base-pr / build (pull_request) Failing after 15m21s

Pull request closed

Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
coilyco-flight-deck/agentic-os!1096
No description provided.