Skip to content

fix(shared-infra): refresh_shared_templates preserves recovered user files#3378

Open
jawwad-ali wants to merge 1 commit into
github:mainfrom
jawwad-ali:fix/refresh-templates-preserve-recovered
Open

fix(shared-infra): refresh_shared_templates preserves recovered user files#3378
jawwad-ali wants to merge 1 commit into
github:mainfrom
jawwad-ali:fix/refresh-templates-preserve-recovered

Conversation

@jawwad-ali

Copy link
Copy Markdown
Contributor

Description

refresh_shared_templates decides whether to skip an existing shared template using only:

if dst.exists() and not force:
    if rel not in tracked_files or rel in modified:
        skipped_files.append(rel); continue

It never consults manifest.is_recovered(rel) — but install_shared_infra does (its _is_managed/is_recovered gate, added by #2918). A recovered file is a pre-existing user file whose on-disk hash was adopted via record_existing(recovered=True), so it is both tracked and hash-unmodified. Both predicates above are therefore false → the file is not skipped → refresh_shared_templates overwrites the user's content with the bundled body.

Reproduced on main @ 92b7cf7: a recovered spec-template.md (# USER CUSTOM CONTENT) is replaced with # BUNDLED CONTENT v2 on a non---force refresh — the exact data-loss class #2918 fixed for install_shared_infra.

Fix

Add the is_recovered check to the skip predicate, mirroring install_shared_infra. One source file, no API change.

Testing

New test_refresh_shared_templates_preserves_recovered_user_file: records a user template as recovered, points the bundled source at a different body, calls refresh_shared_templates(force=False), asserts the user content survives. Fails before (content replaced by bundled body — verified by source-stash), passes after. uvx ruff check clean.

AI Disclosure

  • I did use AI assistance (describe below)

Found and fixed with Claude Code (Claude Fable 5) under my direction. AI diffed the refresh skip-predicate against install_shared_infra's is_recovered gate; I reproduced the overwrite, verified fail-before/pass-after, and reviewed the diff.

…files

refresh_shared_templates skipped a shared template only when it was
untracked or modified, ignoring the manifest's is_recovered marker that
install_shared_infra already honors. So a pre-existing user template
(adopted via record_existing(recovered=True), hence tracked and
hash-unmodified) was silently overwritten with bundled content on
refresh — the exact data-loss class that github#2918 fixed for
install_shared_infra. Add the is_recovered check to the skip predicate.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@jawwad-ali jawwad-ali requested a review from mnriem as a code owner July 6, 2026 20:29
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