Skip to content

fix(install): preserve refused skill files when deployment receipts are missing - #3440

Open
Tyce Herrman (TyceHerrman) wants to merge 4 commits into
microsoft:mainfrom
TyceHerrman:fix/preserve-skills-without-receipts
Open

Tyce Herrman (TyceHerrman) wants to merge 4 commits into
microsoft:mainfrom
TyceHerrman:fix/preserve-skills-without-receipts

Conversation

@TyceHerrman

@TyceHerrman Tyce Herrman (TyceHerrman) commented Nov 2, 2026 •

Copy link
Copy Markdown

Description

When a skill file has no trustworthy local deployment receipt, installation refuses to overwrite it but previously continued into stale cleanup, which could delete the refused file and report success. This change records that refusal as an error so the existing precommit outcome gate stops before cleanup and lockfile replacement. Edited files with a valid prior receipt retain their existing warning behavior.

Regression coverage exercises APM packages, native skills, and skill bundles in project and user scope, with both unchanged installed files and local edits. Repeated attempts preserve existing files and the old lockfile and return a nonzero result.

Issue and approved scope

Issue: #3422

Does this PR complete the issue, or what remains?

Fixes #3422

Related: #3391

Type of change

  • Bug fix
  • New feature
  • Documentation
  • Maintenance / refactor

Testing

  • Tested locally
  • All existing tests pass
  • Added tests for new functionality (if applicable)

Tested locally with dependencies from uv.lock on macOS arm64.

Added regression tests: 12 preservation cases covering three package formats, two scopes, and edited/unedited files.

Spec conformance (OpenAPM v0.1)

If this PR changes behaviour that an OpenAPM v0.1 req-XXX covers,
confirm the three-step ritual in the
development guide:

  • Spec edit: docs/src/content/docs/specs/openapm-v0.1.md updated
    (new/changed <a id="req-XXX"></a> anchor + prose + Appendix C
    row).
  • Manifest edit: docs/src/content/docs/specs/manifests/openapm-v0.1.requirements.yml
    updated.
  • Test edit: a @pytest.mark.req("req-XXX") test under
    tests/spec_conformance/ added or extended.
  • CONFORMANCE.{md,json} regenerated via
    uv run --extra dev python -m tests.spec_conformance.gen_statement
    and committed.
  • N/A -- this PR does not change OpenAPM-observable behaviour.

This restores file-preservation behavior without changing the lockfile schema or adding a normative requirement

@OHWONSIK

Copy link
Copy Markdown

Independent reproduction and combined-candidate validation

I tested the exact #3440 head 6e5af56c97533d798a31a2c2eb594e271c0ac764 together with the separate identity/migration change from #3439, on top of v0.35.0 (17a2fc4dfff238c7d93e55cce6ef42ffa1db928e), using disposable HOME/project roots on macOS arm64.

On unmodified v0.35.0, all 12 missing-receipt preservation cases reproduced the problem: three package forms × project/user scope × edited/unedited files. Install refused the overwrites, stale cleanup removed deployed files, and install still returned success.

The 12-case source-CLI regression group passed in the combined candidate. Its assertions cover repeated refusal attempts, nonzero install outcome, preservation of the deployed files, and preservation of the previous lockfile. With the companion migration experiment creating both v1 and v2 receipts, the missing-evidence fixture must remove both namespaces; retaining a valid v1 is a supported migration case, not absence of trustworthy evidence.

These results support keeping the cleanup repair separate and using the existing error/precommit gate before cleanup/lock replacement. They are combined-candidate source-CLI results, not an independent full-suite pass for this PR or a packaged-binary run of those 12 cases.

One companion adoption issue surfaced in #3439: fresh install with the newer candidate → source update → install with the actual unpatched 0.35.0 executable can still delete files when the new install never created legacy evidence. This PR cannot change the older executable, so that downgrade boundary needs its own migration coverage; it should not expand this cleanup fix into an identity rewrite.

No actual reboot/remount or other-OS runtime validation was performed. The intended downstream path is to validate and consume an official release containing the necessary fixes, rather than ship a separately maintained production fork.

@TyceHerrman

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Secondary-target refusal errors remain suppressed, allowing cleanup to delete files without receipts that still match their old-lock hashes.

1 open issue
What changed in this PR

This PR addresses #3422 by treating skill-file overwrite refusals caused by missing deployment receipts as errors, allowing the existing install gate to stop before stale cleanup and lockfile replacement.

Changes:

  • Escalates missing-baseline diagnostics to errors while retaining warnings for edited files with valid receipts.
  • Adds 12 regression cases covering three package formats, project and user scopes, and edited or unchanged files across repeated attempts.
File Description
tests/​integration/​test_missing_receipt_cleanup.py Adds isolated CLI checks for file preservation, unchanged lockfiles, and nonzero exit results.
src/​apm_cli/​integration/​base_integrator.py Records missing-baseline refusals as errors when a diagnostics collector is supplied.

Review effort: Balanced

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The cleanup tests can miss secondary-target diagnostic regressions because CSV ordering makes the retained Claude deployment primary in user scope, allowing primary-target errors to mask the issue.

1 open issue
1 resolved since last review

Review effort: Balanced

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The regression test’s APM_FIXED_BINARY override bypasses the canonical executable fixture, potentially testing an unrelated or frozen binary rather than the checkout under review and losing startup instrumentation.

2 open issues

Review effort: Balanced

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

A critical mismatch between refusal behavior and lifecycle test expectations causes both scope variants to fail before preservation checks, requiring human assessment of the resulting coverage gap.

No open issues 🎉

2 resolved since last review

Review effort: Balanced

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

No active review issues are recorded for the change to stop missing-receipt installation failures before cleanup and lockfile replacement.

No open issues 🎉

Review effort: Balanced

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

No active review issues are reported for the changes intended to preserve refused skill files and prior ownership records when deployment receipts are missing.

No open issues 🎉

Review effort: Balanced

This branch has not been deployed

No deployments
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.

[BUG] Update deletes unedited skill files it declined to overwrite for lack of a deployment receipt

3 participants