Skip to content

agent publish: 9 quarantined tests fail on a single-agent fixture that the root-count rule now refuses #498

Description

@schickling-assistant

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:catalogCatalog structure, declarations, transactions, and admission · Set: manualarea:ciCI workflows, gates, and test infrastructure · Set: manualorigin:agentFiled or primarily produced by an AI agent · Set: manualtype:bugSomething broken or a regression · Set: manual

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions