stacklok / stacklok/toolhive-registry-server
Skill/plugin package ordering is not preserved or deterministic
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 27
- Forks
- 15
- Avg merge
- 2d 1h
- Merged PRs (30d)
- 16
Description
Split out of #861 (finding 6) because it needs a product decision before any schema work, unlike the mechanical fixes remaining in that issue.
Current behaviour
A skill/plugin's packages array is stored across two tables with no ordinal column, and reassembled by concatenation:
skill_oci_package/skill_git_package(000012_add_skills.up.sql:33-56) andplugin_oci_package/plugin_git_package(000022_add_plugins.up.sql:38-61) — neither has an ordinal/position column.- Fetch always appends OCI before Git, regardless of manifest order:
internal/service/db/impl_skills.go:135-139,:255-260,:391-395, and identicallyimpl_plugins.go:136-140,:256-261,:392-396.
So a manifest declaring [git, oci] round-trips as [oci, git]. A consumer following a "first package wins" convention gets a different artifact than the publisher declared.
Two separable problems
1. Non-determinism within each group (no decision needed). ListSkillOciPackages / ListSkillGitPackages (database/queries/skills.sql) and the plugin equivalents have no ORDER BY at all. Row order is whatever Postgres happens to return, so it can change after an update or vacuum with no data change — the same GET can return packages in a different order on successive calls. That's worth fixing regardless of the decision below; ordering by id (UUIDv7-ish, monotonic per insert batch) or by identifier would make output stable.
2. Manifest order not preserved (needs a decision). Fixing this properly means adding an ordinal column to all four package tables, populating it during sync, and merging the two result sets by ordinal on fetch.
The question
Is the order of packages in a skill/plugin manifest semantically meaningful — i.e. is it a publisher-expressed preference that consumers are entitled to rely on?
- If yes: add the ordinal column to all four tables, preserve order through sync and fetch, and document the guarantee.
- If no: fix (1) for stable output only, and document that
packagesorder is not significant so consumers select by type/identifier rather than position.
Worth answering before anyone writes the migration — (2) is four tables plus sync and fetch changes across both types, and is wasted work if the answer is "no".
Split from #861
Refs #859
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with database/queries/skills.sql, 000012_add_skills.up.sql, 000022_add_plugins.up.sql, internal/service/db/impl_skills.go, and impl_plugins.go. Determine whether manifest package order is semantically meaningful before choosing between stable per-group ordering and ordinal preservation. Done means the product decision is documented and the resulting schema, sync, fetch, and ordering work is specified.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, postgresql
- Domain
- backend, databases
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100