Skip to content

Symposium & Dial9: A plugin reference's declared version is accepted and ignored #289

Description

@Fluzko

Part of #294.

Depends on: nothing.

What happens

A chained plugin reference can declare a version: source.cargo = { name = "x", version = "=1.2.3" }. It is parsed, validated as a real version requirement, stored, and then never read. The resolver enqueues the reference without it, so the crate resolves as though no version had been given.

This is already known: md/rfds/registry-centric-plugins/README.md records it under future work as "chained-edge version enforcement", and describes the intended behaviour as comparing the resolved version against the recorded requirement and warning or skipping on mismatch. So this issue is a request to schedule that, plus one thing the future-work note does not cover.

plugin validate reports such a manifest green, with no warning. The tool actively tells the author they are fine about a field that does nothing. Whatever is decided about enforcement, accepting a field that is discarded is worth fixing on its own, and it is the part that bit a real crate author, because the crate-author documentation recommends this field for versioning skills separately from the library, which is exactly what it cannot do.

A note on how not to implement it

The RFD's direction (compare the already-resolved version) avoids a trap. If the requirement were instead pushed into the resolver, it would skip the fast path used for crates the workspace has already resolved and fall through to a registry lookup. A pinned reference to a crate developed locally and not published would then install nothing at all: zero skills, exit zero, no error, the failure recorded only in the log. That is a monorepo's own layout. It would also reach the network, which costs the per-event hook path its offline guarantee.

How to see it

# needs: cargo-agents, network, and an isolated SYMPOSIUM_HOME. Create the directories
# yourself; nothing below does.
#
# mkdir -p /tmp/iso /tmp/reg/d9
# /tmp/iso/config.toml: the [[registry]] entry is required. Without it `sync` never
# reads /tmp/reg and installs nothing, even though `plugin validate` below is happy:
#
#   [defaults]
#   symposium-recommendations = false
#   user-plugins = false
#
#   [[agent]]
#   name = "claude"
#
#   [[registry]]
#   name = "local"
#   path = "/tmp/reg"
#   auto-update = false
#
# /tmp/reg/d9/SYMPOSIUM.toml:
#
#   name = "d9"
#   depends-on = ["dial9-tokio-telemetry"]
#   [[plugins]]
#   source.cargo = { name = "dial9-viewer", version = "=0.3.13" }
#
# and a consumer project depending on dial9-tokio-telemetry

SYMPOSIUM_HOME=/tmp/iso cargo agents plugin validate /tmp/reg
# -> d9 (plugin)     green, with no warning that the version will be ignored

SYMPOSIUM_HOME=/tmp/iso cargo agents sync
ls .claude/skills | grep -c dial9
# -> 10, the newest set. 6 would mean the pin had been honoured:
#    dial9-viewer 0.3.13 ships 6 skills and 0.5.0 ships 10.

Done when

  • A declared version is either enforced or rejected at validation time. Accepting a field that is then discarded is the defect, independently of which way it is resolved.
  • If enforced: the resolved version is compared against the requirement, without losing the fast path for crates the workspace has already resolved, and without adding a network call to the per-event hook path. A test covers a locally developed, unpublished crate.
  • The crate-author documentation stops recommending the field for something it cannot do, or starts being true. (Tracked in Symposium & Dial9: Documentation contradicts the code in eight statements #293.)

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

    No labels
    No labels

    Type

    No type

    Projects

    • Status
      Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions