fix(agent-publish): accept the in-place agent.kdl.candidate spec source - #354
Merged
schickling merged 1 commit intoAug 28, 2026
Merged
Conversation
…urce `st2 agent digest --spec` and `st2 agent publish --spec` gated the source on `path.extension() == "kdl"` and reported the refusal as "published spec must be canonical KDL". Two problems follow from that. The message names the wrong cause. It points at KDL syntax, so a caller with a perfectly canonical declaration re-reads the KDL looking for a formatting fault that does not exist. FB-460 records that costing a full bisection per seat. The requirement also contradicts the prescribed authoring workflow. `axe agent check` requires the candidate in place at `<catalog>/agents/<host>/<identity>/agent.kdl.candidate`, whose extension is `candidate`, so the same bytes that satisfy the check step cannot be digested or published. The workaround was to keep a second copy of the same bytes outside the catalog, which is exactly the drift hazard the candidate workflow exists to prevent. Accept `agent.kdl.candidate` alongside `*.kdl`, and name the rejected path and the accepted names in the error. The gate still keeps legacy TOML/JSON declarations out of publication, and the bytes are still strictly parsed as canonical KDL immediately afterwards. agent-identity: dev3.dotfiles.fb-batch1.st2.worker agent-persona: worker agent-supervisor: dev3.dotfiles-lead agent-tool: Claude Code agent-tool-version: 2.1.237 agent-runtime: Claude Code 2.1.237 tooling-profile: dotfiles@e78784a
schickling-assistant
marked this pull request as ready for review
August 26, 2026 20:25
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
st2 agent digest --specandst2 agent publish --specgated the source file onpath.extension() == "kdl"and reported the refusal aspublished spec must be canonical KDL.That message names the wrong cause, and the requirement contradicts the prescribed authoring
workflow:
axe agent checkrequires the candidate in place at<catalog>/agents/<host>/<identity>/agent.kdl.candidate, whose extension iscandidate. So thesame bytes that satisfy the check step could not be digested or published, and the workaround was
to keep a second copy of them outside the catalog — the drift hazard the candidate workflow exists
to prevent.
This accepts
agent.kdl.candidatealongside*.kdl, and makes the error name the rejected pathand the accepted names. The gate still keeps legacy TOML/JSON declarations out of publication, and
the bytes are still strictly parsed as canonical KDL immediately afterwards.
Feedback row: FB-460 (friction, 4 occurrences) —
https://app.notion.com/p/st2-agent-digest-publish-reject-any-spec-file-not-named-literally-agent-kdl-with-the-message-publis-3b0e3d41f4a38124bc8ef3f73eb25d5f
Changed lines: 80 (72 insertions, 8 deletions) across 2 files —
src/agent_publish.rs,tests/agent_publish.rs.Reproduction — before (main @ 19485cf)
One spec, four file names, identical bytes:
C and D are controls. They show the discriminator is the file extension alone — not the location.
FB-460's occurrence-4 note concluded the rule was "location-conditional"; that reading is wrong,
because every passing example in it happened to end in
.kdl.Reproduction — after (this branch)
Same digest for the candidate and the
.kdlcopy, so the candidate is now a first-class source.Tests
Two regression tests were added and both were confirmed failure-capable: with the tests in place
and
src/agent_publish.rsreverted to main, both fail with the old error.Without the fix:
With the fix:
cargo fmt --checkreports no diff in either file this PR touches.Pre-existing failure, not introduced here
The full
--test agent_publishsuite has one unrelated failure that also reproduces on a cleanmain @ 19485cf (run twice, same result):
(
19 filtered outon clean main vs21on this branch is this PR's two added tests.)Deliberately out of scope
FB-460's occurrence 4 also notes that
st2 agent publish --bundlerefuses when the target directoryexists without an
agent.kdl. That refusal is a deliberate create-only guard inpublish()(
bundle target directory already exists without agent.kdl), not the same root cause, and relaxingit is a design decision rather than a bug fix. Left untouched.
CI attribution
mainat 19485cf is green in CI (Nixworkflow, run forfeat(otel): tracing facade …, conclusionsuccess). The failure above therefore reproduces onclean main on the machine this branch was developed on, not in CI — treat it as
environment-specific to that host rather than as a broken upstream test.
nix flake checkalso doesnot gate
cargo fmt --checkorclippy(flake.nix:258), so the pre-existing formatting drift onmain is not a CI concern either.
Posted on behalf of @schickling
agent_identityagent_personaagent_supervisoragent_toolagent_tool_versionagent_runtimetooling_profile