Skip to content

feat: a scripted upgrade from the new release, with a smaller approval gate (0046) - #98

Merged
mauricios merged 2 commits into
mainfrom
feat/scripted-upgrade
Oct 18, 2026
Merged

mauricios merged 2 commits into
mainfrom
feat/scripted-upgrade

Conversation

@mauricios

Copy link
Copy Markdown
Contributor

Implements decision 0046 for #86.

What's here

  • scripts/upgrade.py <repo> [--dry-run] [--add-modules a,b] upgrades a project at v2.0.0 or later to the release of the tree it runs from:
    • Old and new copies: git show for the skeleton and the modules' files, and build-committed.py from each release's tree for a committed install's machinery.
    • Files: applies the per-path table: overwrite, git merge-file, add, delete, rename, or list for the developer. Conflicts are left marked.
    • Then: moves a module's old folder, runs migrations and installers, moves the pin, drops covered Bash allow rules, links the reference docs, and restamps.
    • Checks: the settings parse, and each hook's smoke test passes with CLAUDE_PLUGIN_ROOT and CLAUDE_PROJECT_DIR exported.
    • Guards: it commits nothing, and refuses a dirty tree, the default branch, and a hub's main checkout.
  • Report in the git dir (report.md and report.json): Releases, Needs you, Applied (each clean merge with its hunk count), Checks, On each machine, and Follow-ups (command, why, source, plugin, when) for /adf:upgrade records the follow-ups a release needs; /adf:wrap-up offers to start them #89.
  • adf-upgrade: scripts/adf-upgrade.sh, copied by build-plugins.sh into plugins/adf/bin/ as a framework command. It uses $ADF_FRAMEWORK, a local marketplace clone, or a bare clone cached in ~/.cache/adf/, and caches each release's tree there. It runs the new release's own script through protocol 1.
  • Migrations in scripts/migrations/ (v2.4.0/01-auto-update.py, unreleased/01-shared-services.py), each named by its CHANGELOG entry.
  • scripts/upgrade-buckets.json: the bucket taxonomy as data. The static checks keep it complete and equal to docs/UPGRADING.md.
  • /adf:upgrade: a new "The scripted upgrade" section (dry run, hand-over to the new release's skill, modules, run, judgment, one approval). "Plan before touching" becomes "Approve what needs a person", and the manual Step 4 is now "Present what needs a person".
  • Docs: docs/UPGRADING.md § The scripted upgrade, the plugin README, and the CHANGELOG.

Refinements to 0046, noted in the record

  • The wrapper keeps the release's tree in the cache instead of removing it, so the skill can read the new release's copy of itself there.
  • The ops/agent/ move uses module.json's moved_from on any upgrade instead of a v2.0.0 migration. Migrations run from OLD's own release, so a project that skipped part of its last upgrade gets it.

Tests

evals/static/test-upgrade.sh (45 checks) builds packaged and committed projects from v2.3.0 and upgrades them to this tree:

  • the dry run changes nothing;
  • the team's customizations survive;
  • the guide is split, and covered rules are dropped;
  • the migrations return done on a second run;
  • the refusals hold;
  • the wrapper runs end to end from its cache.

CI now checks out with fetch-depth: 0 for the tags. ./evals/run-evals.sh passes.

Not covered

  • A real upgrade of an adopting project through /adf:upgrade in a session (the dynamic eval in evals/dynamic/fixtures/upgrade/).
  • The first upgrade to this release still runs the old skill's manual procedure.

🤖 Generated with Claude Code

mauricios and others added 2 commits October 18, 2026 18:04
…l gate (0046)

Implements decision 0046 (#86):
- scripts/upgrade.py: builds old/new copies per install (git show for the
  skeleton and modules' files, build-committed.py from each release's tree
  for a committed install), applies the per-path table, moves a module's
  old folder (moved_from), runs migrations and installers, moves the pin,
  prunes covered Bash allow rules, links reference docs, restamps,
  smoke-tests the hooks, and writes report.md/report.json with Follow-ups.
- scripts/adf-upgrade.sh, copied by build-plugins.sh to
  plugins/adf/bin/adf-upgrade: finds a framework checkout with history,
  caches the release's tree, and runs its own script (protocol 1).
- scripts/upgrade-buckets.json: the taxonomy as data.
- scripts/migrations/: v2.4.0 autoUpdate and the unreleased guide split.
- /adf:upgrade runs the command; "Plan before touching" becomes
  "Approve what needs a person".
- evals: test-upgrade.sh, upgrade checks in check-skills.sh, full-history
  checkout in CI.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mauricios
mauricios marked this pull request as ready for review October 18, 2026 23:28
@mauricios
mauricios merged commit 5e20db3 into main Oct 18, 2026
1 check passed
@mauricios
mauricios deleted the feat/scripted-upgrade branch October 18, 2026 23: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