tests/agent_publish.rs is red on main (36356ed): 9 of 24 cases fail, all from one root cause. They are quarantined with #[ignore] so the target can join the checks.st2 gate (which currently runs 13 of 54 integration targets); this issue tracks repairing them and removing the #[ignore]s.
Root cause (single)
Every failing case builds a single-agent catalog — agents/host/worker holding valid_spec(false) (tests/agent_publish.rs:17-19, no supervisor) — and then publishes valid_spec(true) (retired #true) over it.
st2 agent publish validates the whole catalog before committing. validate.rs:557-578 requires exactly one counted root per host, and supervisor_chain::is_counted_root (src/supervisor_chain.rs:43-45) excludes retired declarations. So retiring the host's only agent leaves found 0 and publication is refused:
Error: candidate fails full-catalog validation
Caused by:
catalog fails full validation:
. [root-count]: host 'host' must declare exactly one root agent; found 0
The five timed out waiting for … failures are the same refusal one level down: the forked publisher child exits on the refusal before it can create the ready/lock-attempt file that wait_for_path (tests/agent_publish.rs:1554-1564, 2s deadline) is polling. The two assertion mismatches are the same refusal leaving the incumbent bytes / staging untouched.
The newer #486 cases in the same file already declare a root (seat() at :1345-1352 emits supervisor "host.root" alongside an agents/host/root seat) and pass. The old fixtures predate the root-count rule.
Failures (release, cargo test --release --no-fail-fast --test agent_publish -- --test-threads=1, 15 passed / 9 failed)
| test |
line |
failure |
cas_rejects_stale_writers_and_preserves_resources |
221 |
:251 — [root-count] … found 0 |
retirement_cannot_commit_between_reconcile_discovery_and_launch |
1189 |
:1286 — [root-count] … found 0 |
publish_post_commit_generation_failure_is_fenced_and_recovered |
791 |
:819 — left retired #false, right retired #true |
spec_publish_crash_stages_only_in_the_control_plane |
723 |
:750 — left None, right Some(6) |
concurrent_publishers_serialize_and_only_one_wins_the_cas |
1107 |
:1557 — timed out waiting for …/first-publisher-lock-attempt |
control_directory_swap_cannot_redirect_publication_staging |
963 |
:1557 — timed out waiting for …/ready |
intermediate_host_swap_cannot_redirect_publication_outside_the_catalog |
1017 |
:1557 — timed out waiting for …/ready |
success_receipt_requires_exact_locked_readback |
859 |
:1557 — timed out waiting for …/readback-ready |
success_receipt_requires_locked_full_catalog_readmission |
908 |
:1557 — timed out waiting for …/readmission-ready |
Reproduced twice, byte-identical set: once with HOME=$(mktemp -d) and once with a stable HOME, so these are deterministic, not load-sensitive flakes. Also reproduced independently at main@7d6a3c4 in a separate worktree (see the #486 lane report).
Suggested repair
Give each fixture a real org chart instead of a lone agent: an agents/host/root seat with no supervisor, and valid_spec declaring supervisor "host.root" so worker is not itself the counted root. Then retiring worker leaves the host's root slot filled and each case tests what it was written to test.
Two cases need care because the extra seat changes what the catalog contains, not just whether it validates:
spec_publish_crash_stages_only_in_the_control_plane asserts an exact staged-entry count (Some(6)).
publish_post_commit_generation_failure_is_fenced_and_recovered asserts post-commit generation recovery.
Re-derive those two expectations from the new fixture rather than adjusting the number until it passes.
Acceptance
cargo test --release --test agent_publish -- --test-threads=1 reports 24 passed / 0 failed / 0 ignored, and the nine #[ignore = "https://github.com/compoundingtech/st2/issues/<this>"] attributes are gone. The target is already in checks.st2's cargoTestFlags, so nix build .#st2 covers it.
Posted on behalf of @schickling
| field |
value |
agent_identity |
dev3.direct.omp.43sz6ujq |
session |
dev3.43sz6ujq |
agent_persona |
generalist |
agent_supervisor |
unavailable |
agent_tool |
OMP |
agent_tool_version |
18.1.7 |
agent_runtime |
OMP 18.1.7 |
tooling_profile |
dotfiles@39a19af |
tests/agent_publish.rsis red onmain(36356ed): 9 of 24 cases fail, all from one root cause. They are quarantined with#[ignore]so the target can join thechecks.st2gate (which currently runs 13 of 54 integration targets); this issue tracks repairing them and removing the#[ignore]s.Root cause (single)
Every failing case builds a single-agent catalog —
agents/host/workerholdingvalid_spec(false)(tests/agent_publish.rs:17-19, nosupervisor) — and then publishesvalid_spec(true)(retired #true) over it.st2 agent publishvalidates the whole catalog before committing.validate.rs:557-578requires exactly one counted root per host, andsupervisor_chain::is_counted_root(src/supervisor_chain.rs:43-45) excludes retired declarations. So retiring the host's only agent leavesfound 0and publication is refused:The five
timed out waiting for …failures are the same refusal one level down: the forked publisher child exits on the refusal before it can create the ready/lock-attempt file thatwait_for_path(tests/agent_publish.rs:1554-1564, 2s deadline) is polling. The two assertion mismatches are the same refusal leaving the incumbent bytes / staging untouched.The newer
#486cases in the same file already declare a root (seat()at:1345-1352emitssupervisor "host.root"alongside anagents/host/rootseat) and pass. The old fixtures predate the root-count rule.Failures (release,
cargo test --release --no-fail-fast --test agent_publish -- --test-threads=1, 15 passed / 9 failed)cas_rejects_stale_writers_and_preserves_resources:251—[root-count]…found 0retirement_cannot_commit_between_reconcile_discovery_and_launch:1286—[root-count]…found 0publish_post_commit_generation_failure_is_fenced_and_recovered:819— leftretired #false, rightretired #truespec_publish_crash_stages_only_in_the_control_plane:750— leftNone, rightSome(6)concurrent_publishers_serialize_and_only_one_wins_the_cas:1557— timed out waiting for…/first-publisher-lock-attemptcontrol_directory_swap_cannot_redirect_publication_staging:1557— timed out waiting for…/readyintermediate_host_swap_cannot_redirect_publication_outside_the_catalog:1557— timed out waiting for…/readysuccess_receipt_requires_exact_locked_readback:1557— timed out waiting for…/readback-readysuccess_receipt_requires_locked_full_catalog_readmission:1557— timed out waiting for…/readmission-readyReproduced twice, byte-identical set: once with
HOME=$(mktemp -d)and once with a stableHOME, so these are deterministic, not load-sensitive flakes. Also reproduced independently atmain@7d6a3c4in a separate worktree (see the #486 lane report).Suggested repair
Give each fixture a real org chart instead of a lone agent: an
agents/host/rootseat with nosupervisor, andvalid_specdeclaringsupervisor "host.root"soworkeris not itself the counted root. Then retiringworkerleaves the host's root slot filled and each case tests what it was written to test.Two cases need care because the extra seat changes what the catalog contains, not just whether it validates:
spec_publish_crash_stages_only_in_the_control_planeasserts an exact staged-entry count (Some(6)).publish_post_commit_generation_failure_is_fenced_and_recoveredasserts post-commit generation recovery.Re-derive those two expectations from the new fixture rather than adjusting the number until it passes.
Acceptance
cargo test --release --test agent_publish -- --test-threads=1reports 24 passed / 0 failed / 0 ignored, and the nine#[ignore = "https://github.com/compoundingtech/st2/issues/<this>"]attributes are gone. The target is already inchecks.st2'scargoTestFlags, sonix build .#st2covers it.Posted on behalf of @schickling
agent_identitysessionagent_personaagent_supervisoragent_toolagent_tool_versionagent_runtimetooling_profile