Skip to content

feat(install-targets): generic plan-diff retirement for all install targets (#1412) - #4

Open
kunaaaalcodes wants to merge 7 commits into
mainfrom
feat/generic-plan-retirements-v2
Open

kunaaaalcodes wants to merge 7 commits into
mainfrom
feat/generic-plan-retirements-v2

Conversation

@kunaaaalcodes

@kunaaaalcodes kunaaaalcodes commented Sep 11, 2026

Copy link
Copy Markdown
Owner

Summary

Generalizes the OpenCode-only planRetirements hook (added in Fmarzochi#1411) into a default planGenericRetirements that every install target inherits. When a file leaves an install plan, the copy an earlier install wrote is now cleaned up on the next install/auto-update.

Identity rules (from Fmarzochi#1411)

  • Only regular files with no linked ancestor and byte-identical content to the source are actually deleted.
  • Sources no longer in the repository are reported and left in place (report-and-leave).
  • Only copy-file operations are diffed; merge-json and hook have no retirement counterpart yet (open follow-up).
  • Directory-shaped scaffold entries shield every file materialized underneath them.
  • OpenCode keeps its own narrower planRetirements, unaffected by this change.

Component Type

  • Core Engine / Orchestrator

Validation

  • node tests/run-all.js passes locally (install-targets suite: 150 tests, including 2 new).
  • ESLint clean on changed files.
  • CHANGELOG.md and docs/ROADMAP.md entries added.

Checklist

  • All commits carry Signed-off-by
  • Local tests pass
  • Markdownlint passes
  • PR changes fewer than 150 code files
  • Preserves EGC identity and formatting

…argets (Fmarzochi#1412)

Signed-off-by: Kunal Jaiswal <kunaaaalcodes@gmail.com>
…8.30

Signed-off-by: Kunal Jaiswal <kunaaaalcodes@gmail.com>
@github-actions

Copy link
Copy Markdown

Thank you for your contribution to EGC!

Please sign our Contributor License Agreement to get this PR merged.

Read .github/CLA.md, then post the comment below:

I have read the CLA Document and I hereby sign the CLA.


I have read the CLA Document and I hereby sign the CLA.


You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.

kunaaaalcodes and others added 5 commits September 11, 2026 18:20
…d root and protects shared destinations (Fmarzochi#1412)

Signed-off-by: Kunal Jaiswal <kunaaaalcodes@gmail.com>
…a second managed root in the apply, and prove renames by content (Fmarzochi#1412)

Review round on the generic plan-diff retirement:

- A destination is a candidate only when the module that recorded it is
  still part of the current plan and the file no longer belongs to it. A
  targeted --modules install or a narrower profile leaves the files of the
  modules it did not select where they are, instead of retiring everything
  outside the new plan.
- The managed roots an adapter declares (Amp's plugin config directory next
  to its skills root) ride along in the plan, and the apply checks each
  candidate against the root it belongs to: the linked-ancestor walk and the
  empty-parent climb stay inside that root, and a candidate under the
  second root is no longer dropped on the floor after being planned.
- A recorded source that is gone because the file was renamed or moved in
  the package is retired when the bytes on disk match a file the plan
  copies today, hashed once per plan and only when a candidate needs it;
  a missing source that matches nothing stays, listed nowhere.
- No repoRoot means identities cannot be compared: nothing is retired
  instead of guessing the working directory.
- The retirement planner is split into small helpers (recorded copies,
  state reading, candidate boundaries) under the complexity limit.
- The @opencode-ai/plugin bump is taken out of this change: it is
  unrelated to Fmarzochi#1412, turned the SDK into a runtime dependency of the
  published egc-universal package and pulled 23 packages into its lockfile.
- CHANGELOG and comments without the double hyphen as a separator.

Tests: the subset install (module not selected keeps its files, no
modules and no repoRoot retire nothing), the managed roots carried by
planInstallTargetScaffold, a second root on the apply side, and the
content match for a renamed source. Proven on a real machine with a
synthetic home: a full install followed by a minimal one retires nothing;
a skill directory renamed in the package is listed by the dry run,
removed by the apply, replaced by its new copy and recorded as such.

Signed-off-by: Felipe Marzochi <fmarzochi@gmail.com>
… be read (Fmarzochi#1412)

A sibling adapter sharing the root (codex, goose and openhands under
~/.agents) may still own a candidate destination. A sibling with no state
file owns nothing; a sibling whose state exists but cannot be read or
parsed may own any of them, so the planner now retires nothing until that
state can be trusted again, instead of treating it as empty. Tests cover
the absent, malformed and unreadable sibling states.

Signed-off-by: Felipe Marzochi <fmarzochi@gmail.com>
…ngs to (Fmarzochi#1412)

The linked-ancestor check bounded its walk by the target root, so a
destination under a second root an adapter declares (Amp's plugin config
directory) was only checked at the destination itself: a link planted
above it in that root was never seen. The preflight and the apply now
pick the managed root each destination falls under and walk that root;
the legacy layout migration stays limited to the target root, where it
lived, and a link under a second root is refused outright. Test covers
the root lookup, the refusal and the empty migration list.

Signed-off-by: Felipe Marzochi <fmarzochi@gmail.com>
…state absent (Fmarzochi#1412)

The presence probe followed links and folded every lookup failure into
"missing", so a dangling link at a sibling's state path, or a parent that
cannot be inspected, read as no state at all and let retirement proceed.
The path is now probed with lstat: nothing there is absent, anything else
is a state that cannot be trusted and retires nothing. Tests cover the
dangling link and the sealed parent.

Signed-off-by: Felipe Marzochi <fmarzochi@gmail.com>
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.

2 participants