Skip to content

[Bug]: Bundled extensions (agent-context, git) change without extension.yml version bumps — 'extension update' reports Up to date and installed copies never get fixes #4345

Description

@CrazyBaran

Summary

specify extension update decides whether an installed extension needs updating by comparing semver versions (src/specify_cli/extensions/_commands.py, extension_update, ~line 1660):

if catalog_version > installed_version:
    ...offer update...
else:
    console.print(f"✓ {ext_id}: Up to date (v{installed_version})")

Both bundled extensions (agent-context, git) have carried version: "1.0.0" since the day they were created, while their content kept changing — including bug fixes for failures that make an extension unusable on some platforms. Any project that installed them before those fixes is told "Up to date (v1.0.0)" forever and never receives them. Nothing else catches it: the registry's manifest_hash covers the manifest (which didn't change), not the scripts.

Quantified drift (checked 2026-08-26 against main)

extensions/agent-contextversion: "1.0.0" set at extraction (#2546, 2026-05-30), never bumped since (the manifest was never touched again). Changes an installed v1.0.0 copy is missing:

extensions/gitversion: "1.0.0" set at creation (#1941, 2026-04-07), never bumped; the manifest was edited once more (#3293, 2026-07-06) and the version still stayed 1.0.0. Changes an installed v1.0.0 copy is missing:

(Methodology: commit counts via git rev-list --count <version-set-commit>..origin/main -- extensions/<id>, aggregate stats via git diff --stat, version history by inspecting extension.yml at each commit that touched it.)

Real-world impact (how we found this)

Our repo runs spec-kit 0.16.5 (2026-08-19) but had installed agent-context on 2026-06-16 — six days before the PS 5.1 fix landed in #2969 (released the same day in v0.11.5). Because the version never moved off 1.0.0, fourteen subsequent CLI releases all considered the extension current, and the after_specify/after_plan hook failed silently (warns + exit 0) on every run for two months; our CLAUDE.md context block was stuck pointing at a plan three features old. The staleness is undetectable from the client side without diffing script contents against this repo.

Workaround

Force reinstallation, which overwrites regardless of version:

specify extension add agent-context --force
specify extension add git --force

(--force = "Overwrite if already installed"; extension add refuses otherwise. Config files are preserved via the backup/restore path.)

Proposed fix

  1. Bump version: in extension.yml for both extensions now (content warrants at least a minor bump each: 1.1.0), so every installed copy finally sees an available update.
  2. Guard it in CI so this can't regress: fail a PR that changes any file under extensions/<id>/ without also changing the version: field of that extension's extension.yml. This is a small check (git diff of the PR range, per extension) that converts "please remember to bump" into a merge requirement.
  3. Optionally, belt-and-braces: make extension_update compare a content hash of the extension directory (the registry already stores a manifest_hash; extend it to cover all shipped files) so even an unbumped content change is detected as "update available".

Happy to send a PR for (1) + (2) if the approach sounds right.

Related (adjacent but distinct): #2716 discusses catalog semantics for update discovery of org-local/third-party catalogs; this issue is about bundled extensions never signalling an update at all because their source version never changes.

Generated by Fable 5 Extra

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions