Skip to content

fix(store): prune rows whose file is now scanned under a new id - #177

Merged
RealZST merged 1 commit into
mainfrom
fix/stale-reassigned-rows
Nov 1, 2026
Merged

RealZST merged 1 commit into
mainfrom
fix/stale-reassigned-rows

Conversation

@RealZST

@RealZST RealZST commented Nov 1, 2026

Copy link
Copy Markdown
Owner

Problem

After upgrading to v1.15.1, users who had installed skills with a quoted frontmatter name (name: "imagegen") from the marketplace saw them listed twice: "imagegen" and imagegen.

#173 changed how the name is read, which changes the id derived from it, so the next scan reports the same file under a new id. The old row was a marketplace install with install_meta whose file was still on disk, and the stale-row rules in store/sync.rs treated that as a momentary scan gap and kept it forever. Only rows with install_meta were affected; quoted skills that came with an agent or were cloned by hand were pruned and replaced normally.

Fix

  • A file the scan now reports for the same agent under another id counts as reassigned, not as a scan gap: the old row is pruned. Matching is on kind, agent and path, and only for skills and plugins, since MCP/hook rows share their config file and a skill in a shared directory has one row per agent.
  • The pruned row's install_meta moves to the row that took the file over, unless that row already has its own, so provenance and update checks survive.
  • The two copies of the stale-prune loop (full sync and per-agent sync) are replaced by one shared helper; behaviour on every other path is unchanged.

Verification

  • New tests cover the reassignment, the no-overwrite rule for existing install_meta, the store-held disabled exemption under reassignment, and that a shared-directory skill is not treated as reassigned (the other agent's provenance stays put).
  • Released v1.15.1 binary vs this build against a copy of a real 1015-row database: the old binary keeps the 5 quoted rows; this build removes exactly those 5, carries marketplace provenance to the two rows that lacked it, leaves rows that already had their own untouched, and a second run changes nothing.
  • cargo test --workspace, clippy and cargo fmt --check clean.

🤖 Generated with Claude Code

An extension's id is derived from its name, so a change in how a skill's
name is read (#173 stripped the quotes from `name: "imagegen"`) makes the
next scan report the same file under a new id. The old row survived
forever: it was a marketplace install with install_meta whose file was
of course still on disk, which the stale-row rules read as a momentary
scan gap. Users upgrading saw both `"imagegen"` and `imagegen` listed.

A file the scan now reports for the same agent under another id is a
reassignment, not a scan gap: the old row goes, and its install_meta
moves to the row that took the file over unless that row already has
its own, so provenance and update checks survive. Only skills and
plugins qualify, where one file is one extension; MCP/hook rows share
their config file and a skill in a shared directory has one row per
agent, so matching is on kind, agent and path.

The two copies of the stale-prune loop (full sync and per-agent sync)
are replaced by one shared helper.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@RealZST
RealZST merged commit e044022 into main Nov 1, 2026
4 checks passed
@RealZST
RealZST deleted the fix/stale-reassigned-rows branch November 1, 2026 14:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant