Skip to content

Unify pluginTOMLSpec with source.PluginSpec #234

Description

@spxrogers

Problem. plugins/<id>.toml has two readers with two schemas: source.PluginSpec (internal/source/schema.go:220-275) and the CLI-private pluginTOMLSpec (internal/cli/plugin.go:72-95) — a field-for-field duplicate down to the *[]string NativeAgents pointer, with mirrored comments on both sides.

The sharper hazard is installPluginInto's preserve logic (internal/cli/plugin.go:260-289): on re-install it carries lifecycle fields forward field by field (Agents, NativeAgents, Update, Disabled). The next lifecycle field someone adds to the structs but forgets to add to that merge is silently reset to its default on every re-install/re-import — exactly the #140 bug class this code exists to prevent, and exactly the "model drifts from its artifact" failure mode CLAUDE.md's fidelity rule warns about. Nothing guards the merge the way TestNewSecretFieldGuard guards walkSecretFields.

Fix.

  • Collapse to one struct: either have the CLI use source.PluginSpec directly for its TOML I/O, or embed it. (Contrast with marketplaceTOMLSpec, whose divergence from MarketplaceSpec is real and documented — here the fields are identical.)
  • Make the preserve struct-level: start from the existing decoded spec and overwrite only the install-refreshed fields (ID, Version, ManifestSHA), so a new lifecycle field is preserved by default instead of dropped by default.
  • Alternatively/additionally, a reflective guard test that fails when the struct grows a field the preserve path doesn't classify — the pattern the secrets walker already uses.

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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions