Skip to content

feat(upgrade): honest provenance for partial upgrades - #38

Merged
DanMat merged 1 commit into
mainfrom
feat/upgrade-partial-provenance
Aug 2, 2026
Merged

feat(upgrade): honest provenance for partial upgrades#38
DanMat merged 1 commit into
mainfrom
feat/upgrade-partial-provenance

Conversation

@DanMat

@DanMat DanMat commented Aug 2, 2026

Copy link
Copy Markdown
Owner

What

After a partial packkit upgrade --apply — one that preserves user edits or leaves conflicts unresolved — the written packkit.json no longer implies the project is a fresh scaffold of the new version.

Why

Previously buildUpgradeWrite copied the freshly-generated packkit.json (new version + new baseline) whenever provenance was outdated, even if changed files/scripts/deps/fields were deliberately left unapplied. A host reading provenance couldn't tell "fully upgraded" from "upgrade ran, but half of it was preserved."

How

packkit.json now records what actually happened:

  • version (generatedWith) stays at the original scaffold version — an upgrade is not a re-scaffold.
  • lastUpgradeCheckedWith / lastUpgradeAppliedWith record the upgrade version.
  • upgradeStatus is current only when nothing was left unresolved, otherwise partial with an unresolvedChanges count.

The baseline still advances to the new generated state, so preserved edits are correctly recognized as customizations on the next upgrade (not re-flagged as template drift). All new fields are additive — existing packkit.json files remain valid, and repeated upgrades keep the original generatedWith.

Documented in types/embedded.d.ts (UpgradeStatus, UpgradeProvenance) and README.

Tests

  • Partial-apply scenario asserts version unchanged, upgradeStatus: 'partial', and a positive unresolvedChanges.
  • New full-apply (replace-changed everywhere) test asserts upgradeStatus: 'current' with no count.
  • 112 tests pass; lint clean.

🤖 Generated with Claude Code

After an --apply that preserves user edits or leaves conflicts, packkit.json
no longer implies the project is a fresh scaffold of the new version. The
written provenance now records what actually happened:

- version (generatedWith) is left at the original scaffold version;
- lastUpgradeCheckedWith / lastUpgradeAppliedWith record the upgrade version;
- upgradeStatus is 'current' only when nothing was left unresolved, else
  'partial' with an unresolvedChanges count.

The baseline still advances to the new generated state so preserved edits are
correctly recognized as customizations on the next upgrade. Fields are additive,
so existing packkit.json files stay valid. Documented in types and README.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@DanMat
DanMat merged commit bf27f3c into main Aug 2, 2026
5 checks passed
@DanMat
DanMat deleted the feat/upgrade-partial-provenance branch August 2, 2026 14:00
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