publish-dev-base red on main: stale WARD_VERSION, swagger-lock vs ward doctor, dep-bump gate deadlock #452
Labels
No labels
burndown-2026-06
coherence-core
consult
headless
interactive
P0
P1
P2
P3
P4
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
coilyco-flight-deck/agentic-os#452
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
publish-dev-base is red on every main push, and the dep-bump loop that should prevent it is gate-blocked
Found while landing aos#450 (codex pin bump). The
publish-imagepath inrelease.ymlhas been failing on main (runs 986/jobs/2 atd5079cc, and the push before it), so landed Dockerfile bumps - including aos#450'sCODEX_VERSION0.144.1 - never reach the published:latest. Three stacked causes, in dependency order:docker/dev-base/core/DockerfilepinsARG WARD_VERSION=0.567.0while ward is at v0.596.0. The in-imageCLIGUARD_NO_SANDBOX=1 ward doctorgate fails at 0.567.0 because that ward predates the split.wardbundle layout (it wantsward-kdl.defaults.kdl/ward-kdl.fleet.kdl/ward-kdl.forgejo.guardfile.kdl).WARD_VERSIONalone cannot go green either. aos#435 removedforgejo.swagger.lock.jsonfrom the repo and from the ward-specs bundle tarball, but every current ward release still hard-requires it in a bundle config source (bundleForgejoSpecLockPathincmd/ward/configsource.go, verified failing on v0.584.0 and a source-built v0.596.0, and still present at ward main HEAD). Doctor failsops bundle: read spec lock. Either ward drops or soft-fails the lock requirement for bundles (then bumpWARD_VERSIONhere), or the bundle restores the lock. Needs a ward-side decision - this half likely wants a ward issue.scripts/dep-bump.py applyrewrites only DockerfileARGlines, whiletests/test_dev_base_image.pyhard-pins every managedARGdefault as a string literal (test_split_tiers_keep_their_managed_arg_defaults, plusARG WARD_VERSION=0.567.0intest_core_tier_keeps_the_hidden_ward_builder_stage). The daily auto-bump commit therefore always fails the pytest gate it runs before pushing, and every pin silently drifts - exactly the incident class the auto-bump was built to close (docs/dev-base-auto-bump.md, agentic-os#272). Fix by makingapplyrewrite the test pins in the same commit, or by deriving the test expectations from the Dockerfiles instead of literals.Acceptance
publish-dev-basegoes green on a main push, and the built:latestships codex 0.144.1 (or newer) - completing aos#450's acceptance.Refs: aos#450, aos#435, docs/dev-base-auto-bump.md,
docker/dev-base/core/Dockerfile,scripts/dep-bump.py,tests/test_dev_base_image.py.Prevention for this class filed as #454: run the dev-base docker build + in-image
ward doctoron PRs as a build-only validation step, so a stale WARD_VERSION / swagger-lock desync / pin drift fails the PR instead of going red on main. This issue stays scoped to makingpublish-dev-basegreen now; #454 shifts the check left so it does not recur.WARD-TRIAGE: #452 P3 consult
triage details
method: tooling-issue-prioritization
P0 candidate: no
score: 3
mode: consult
confidence: no
tier: P3
labels: P3 consult
reason: Red CI blocking published :latest is the clear next thing, but the gate-blocked dep-bump deadlock needs a design call and the fix touches the externally-visible publish path.
— Claude (she/her), via
ward agentFresh data from the #454 run (claude-linux-6dfbe4beef5b-da08-she-her): PR #456 now builds the dev-base family on every PR through a shared
actions/dev-base-buildcomposite, and its first run reproduced this incident pre-merge, so the prevention half is in place. Updated version matrix, each entry verified by running that ward's doctor against the current.ward/bundle (source-built where needed):ward-kdl.*filenames, as diagnosed above.forgejo.swagger.lock.json(removed by aos#435). Verified on a source-built v0.604.0:FAIL ops bundle: read spec lock.ward.bundle.kdlops manifest first (ops { forgejo "guardfile.forgejo.kdl" }, parsed fail-closed incmd/ward/configsource.go), and with that manifest present still hard-require the swagger lock. Verified on v0.605.0.bundleForgejoSpecLockPath = "forgejo.swagger.lock.json"is still read unconditionally bybuildForgejoOps, so no unreleased fix is waiting either.Conclusion unchanged but sharper: bumping
WARD_VERSIONalone cannot go green at any released tag, and the ward-side half maps to ward#1064 (bundle loading independent of consumer KDL filenames, with ward#1080/ward#1082 pushing the same direction). The run deliberately did not addward.bundle.kdlto.ward/since that is the file-shape churn ward#1080 complains about. Once ward ships the lock-independence, the aos-side close-out is the pin bump plus thetest_dev_base_image.pyliteral sync (bullet 3 above), and PR #456'sci / build-dev-basecheck will confirm the fix on its own PR.Re-verified 2026-07-11 after the pytest gate was unblocked (aos#471)
The gate half of this is now fixed and merged:
ci / gate,mirror-to-github,release / test, andplan-releaseare all green on main (run 1055).publish-dev-basetherefore runs now instead of being skipped, which exposes the remaining half.The swagger-lock cause listed above is resolved -
.ward/forgejo.swagger.lock.jsonis present andward doctorno longer complains about it. The live failure set is different, and I pulled the actual step log (run 1055, job 2, step 7) to confirm:That is the stale
WARD_VERSION=0.567.0pin, exactly as this issue says: 0.567.0 predates the bundle rename (8a04260).But bumping the pin alone is still not enough
I ran
ward doctorfrom v0.626.0 and from ward main HEAD against the current bundle. Both give the same three different failures:Per Kai, aos is the correct state and ward/cli-guard adapt to it. So all three are ward-side gaps:
burndownanywhere in its source;repos {}accepts onlyrepo-authority(cmd/ward/smartdefaults.go). Tracked as ward#1105.guardfile- cli-guard main already supports this (case "guardfile"inpkg/fleetconfig, added byf6063aa, 2026-07-10). ward just pins an older cli-guard (v0.85.1-0.20260709002015). Blocker: cli-guard removed the legacycli/dispatchpackage in05e8b78(2026-07-09), before the guardfile support landed, and ward still imports it. So ward cannot reach a cli-guard with guardfile support without first migrating offcli/dispatch. There is no tag with both. Filed separately.ops.forgejo.kdlandguardfile.forgejo.read.kdlintentionally carrygit.example.com/example*//example/forgejo/api-token(their comments say the real values belong to the selected bundle, not the baked default). ward's doctor placeholder check has to stop rejecting them.Order to green
cli-guard dispatch migration in ward -> bump cli-guard -> teach ward
burndown-> relax the doctor placeholder check -> release ward -> bumpARG WARD_VERSIONhere and the hard-pinned literal intests/test_dev_base_image.py(the dep-bump deadlock this issue already calls out).Until then the published image stays at v0.245.0 (ward v0.529.0 inside). It is pullable and ward does run in it - just stale.
State after the 2026-07-12 stability session
ARG WARD_VERSIONis at 0.629.0 (aos#474), andward doctorpasses against the current.wardbundle - verified locally and by release run 1063 (manual) going green end to end.tests/test_dev_base_image.pynow derives managed-ARG values from the Dockerfiles (names stay the contract), so the daily auto-bump no longer fails its own pytest gate (aos#474).Release run 1078 (a push-triggered main release carrying today''s batch) is in flight; if it lands green, the original acceptance ("publish-dev-base goes green on a main push") is met and this can close.