Skip to content

refactor(plugins): delete the retired first-party plugin block and restore upstream's plugin schema - #248

Merged
HTExplicit merged 6 commits into
mainfrom
refactor/remove-retired-plugin-panel
Oct 5, 2026
Merged

HTExplicit merged 6 commits into
mainfrom
refactor/remove-retired-plugin-panel

Conversation

@HTExplicit

Copy link
Copy Markdown
Owner

Problem

The admin Plugins page ends with a read-only block, "retired first-party plugins": seven cards and a retirement receipt. Nothing in it can be acted on. Behind it the fork keeps a startup step that retires first-party plugin installations, a wrapper that hides their rows from upstream's plugin manager, and schema only those plugins used. The owner decided the block goes as a whole, with its stored data.

Change

Backend: upstream's plugin wiring

  • Deleted: the retirement startup step (service/native_feature_bootstrap.go, repository/native_feature_bootstrap.go), the repository wrapper (repository/native_plugin_boundary.go), GET /admin/plugins/retired, and their tests.
  • repository.NewPluginRepository and admin.NewPluginHandler(manager) are wired directly, as upstream does. ProvideSettingService loses the parameter it took only for ordering.
  • Byte-identical to v0.2.13 again: handler/admin/plugin_handler.go, pkg/pluginapi/v1/manifest.schema.json, pkg/pluginapi/v1/runtime.go, internal/pkg/proxyutil/dialer.go (the fork-only proxytransport package is gone). registerPluginRoutes and the plugin manager's place in shutdown match upstream.
  • Removed with them: three response headers added for first-party plugin UIs (Cache-Control: private, no-store on plugin config, Access-Control-Allow-Origin: * and worker-src blob: on plugin UI assets), an orphan testdata file, and comments describing deleted plugin structure.

Migration 272_purge_first_party_plugins.sql

  • Deletes the seven first-party installation rows (bindings go by cascade) and settings.deplugin_retired_plugins.
  • Restores upstream's schema for the plugin tables: drops sub2api_plugin_bootstrap and sub2api_plugin_updates, the columns revision, runtime_generation, package_sha256, update_policy, the state updating, the trigger and function sub2api_plugin_revision, and the narrowed unique index on enabled bindings. sub2api_plugin_installations and sub2api_plugin_bindings are then as 229 and 230 define them.
  • Raises before changing anything when a first-party installation exists without a completed receipt entry, when another installation is in state updating, or when two enabled bindings share a scope. Each message names what resolves it.
  • Other installations and settings.admin_observability_config are not written.

Frontend: upstream's Plugins page

  • Deleted: RetiredPluginsPanel.vue, its API functions and types, its i18n keys and CSS, rawPluginConfig in the API client, and the "plugin unavailable" line in the re-auth dialog that could never show.
  • api/admin/plugins.ts, both i18n/locales/*/admin/plugins.ts and PluginsView.spec.ts are byte-identical to v0.2.13. PluginsView.vue differs only by the theme hook data-ui="plugins".

Migration 264's test recreates the objects 264 needs before running it; 264 itself is released and unchanged.

What an admin sees

  • Plugins page: the retired block is gone; the page is one screen instead of five.
  • The page description and its two labels are upstream's wording again.
  • Previewed with mock data and approved by the owner before this PR.

Rollback boundary

There is no down path. An image older than this release finds no receipt at start, runs the retirement query, reads the dropped column runtime_generation and exits. .downstream/native-domains.md has the details, including what an older image needs if 272 refuses after 270 and 271 have committed.

Outside the database

The seven plugins' package files, unpacked trees and any Redis key plugin:kv:v1:codexrip.* are removed once on the server at the release that applies 272. Production is checked read-only against 272's three refusal conditions before that release.

Verification

  • go build ./... (default and GOOS=linux); go vet ./... with no tag, -tags unit, and -tags integration on repository; wire diff clean; gofmt.
  • Schema proof: a database built from v0.2.13's migrations alone and one built from this branch's migrations list the same columns, constraints, indexes and triggers for the plugin tables.
  • TestMigration272PurgesFirstPartyPlugins (8 cases) and TestMigration264PurgesCodexRuntimePluginData (12 cases) on a throwaway PostgreSQL 18 from an empty database; 272 also applied by hand to a production-shaped database.
  • The old retirement query run against the migrated schema fails with 42703, as the rollback note states.
  • Targeted tests for the plugin handler and manager, proxy dialer, models cache; vue-tsc, check:i18n, the PluginsView spec; the changed CI selector with its contract test.
  • Three independent review lenses (deletion completeness, migrations, live behaviour), each finding verified by a second agent: 18 confirmed, 14 fixed here. The other four: the server-side cleanup and the production check above, an account-view shell in the accounts page that needs its own change, and a note that upstream's compatibility check reads the fork's -codexrip.N suffix as a pre-release.

Not run locally: golangci-lint (the local binary cannot read Go 1.27 export data), the full unit and integration suites, frontend eslint and full vitest, real model calls. CI runs the required ones.

🤖 Generated with Claude Code

Codex and others added 6 commits October 5, 2026 13:53
…ata and its schema

The read-only "retired first-party plugins" block of the admin Plugins
page is deleted as a whole: the panel, the seven retired installation
rows and the retirement receipt. Upstream's plugin management is back in
its v0.2.13 form.

Backend
- the startup step that retired first-party installations (service and
  repository), the repository wrapper that hid the seven keys from the
  plugin manager, GET /admin/plugins/retired and their tests are deleted;
- the wiring is upstream's again: repository.NewPluginRepository and
  admin.NewPluginHandler. ProvideSettingService loses the parameter that
  only ordered it after the retirement; wire_gen.go is regenerated;
- plugin_handler.go is byte-identical to v0.2.13. Three response headers
  that served the first-party plugin UIs go with it: Cache-Control on the
  two configuration interfaces (4129f63, the versioned management
  view), Access-Control-Allow-Origin on plugin UI assets (387b0a7, the
  prompt management UI) and worker-src blob: in their CSP (8a4d280, the
  account import UI).

Migration 272
- deletes the seven first-party installations with their bindings and
  the receipt, and drops the schema only they used
  (sub2api_plugin_bootstrap, sub2api_plugin_updates, four columns, the
  state 'updating', the revision trigger and function, the narrowed
  unique index), so both plugin tables are as upstream's 229 and 230
  define them;
- raises, changing nothing, on a first-party installation the receipt
  does not record as retired, on another installation in the state
  'updating' and on two enabled bindings of one scope;
- has no down path: every earlier release since v0.2.8-codexrip.5 reads
  the dropped column runtime_generation at start and exits;
- 264 is released and names the dropped objects, so its test puts 248,
  249 and 250 back before each case.

Frontend
- RetiredPluginsPanel.vue, its API function and types, its i18n keys and
  its CSS rules are deleted;
- api/admin/plugins.ts, both admin/plugins.ts locales and
  PluginsView.spec.ts are byte-identical to v0.2.13; PluginsView.vue
  keeps only the console theme hook data-ui="plugins";
- the rawPluginConfig bypass of the response interceptor (4129f63) and
  the "plugin unavailable" line of the re-authorization dialog
  (cd8c18b), which no longer had a reason, are removed.

CI and docs
- test_native_domains.sh no longer selects the deleted tests or
  ./internal/repository, where it would select nothing;
  downstream-verify.yml drops the retirement selector;
- .downstream/native-domains.md states what 272 removes, what it leaves
  and the rollback boundary.

Not in the database and left for the operator: the Redis keys
plugin:kv:v1:codexrip.* and the plugin files under <data dir>/plugins.

The deploy workflow, the release workflow and deploy/ are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… first-party plugins left in live code

Review of the retired-plugin removal found files of upstream's plugin
system that were still in their first-party form, and plugin-era code
that survived under other names.

Upstream form restored, byte for byte
- pkg/pluginapi/v1/manifest.schema.json and runtime.go. The schema
  advertised ten extensions.*.v1 capabilities and five manifest fields
  the host rejects; runtime.go carried a Connection field and an
  AdditionalServiceRegistrar hook nothing used.
- pkg/proxyutil/dialer.go. internal/proxytransport, which existed to be
  shared with plugin processes and had this one caller, is deleted. No
  caller passes a transport with Proxy set, so the SOCKS branch behaves
  as before.
- provideCleanup stops the plugin manager as a parallel step again
  instead of after all of them; wire_gen.go is regenerated. The account
  job runtime keeps its own step.
- modelsListCacheKey and InvalidateAvailableModelsCache. Cache keys have
  had two parts since the provider namespace went, so the three-part
  matching selected nothing more than upstream's does.
- the /plugins/ comments of .dockerignore and .gitignore.

Deleted
- service/testdata/plugin_contribution_buckets.json, which no test read;
- the .dockerignore exception for deploy/plugin-bundle/README.md, which
  no Dockerfile copies.

Comments and DOWNSTREAM.md no longer explain current code by the plugin
configuration or packaging that preceded it.

deploy/plugin-bundle/README.md is left: deploy/ is outside this change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Migration 272 gave one remedy, "start v0.2.13-codexrip.7 once", for three
different states of the retirement receipt. An earlier release retires
an installation only while no receipt is stored: on a receipt that is
not completed it exits at start, and once a completed one is stored it
retires nothing.

- A stored receipt that does not cover an installed first-party plugin
  now raises its own message: no release repairs it and it is resolved
  by hand. The message for a missing receipt is unchanged in substance.
  Both, and the two for other installations, name
  v0.2.13-codexrip.8, the last release before these migrations, and
  point to .downstream/native-domains.md.
- The document says what such a refusal leaves behind. Each migration
  commits on its own, so 270 and 271 are applied by then;
  v0.2.13-codexrip.8 needs Image Studio off and
  usage_billing_dedup.account_id added back on that database. The
  previous commit had removed both facts.
- It names what the seven plugins stored outside the database (package
  files, unpacked trees, Redis keys with the codexrip. prefix) instead of
  everything under the plugin directory, and says they are deleted by
  hand at the release that applies 272. The files of other plugins stay.
- It no longer describes the deleted startup retirement by negation.

Test: the three cases of an uncovered installation expect the two
messages. The assertions that a refused migration changes nothing ran
after a rollback to a savepoint and could not fail; they are removed,
since the runner's one transaction per file is what guarantees it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…aises

The test of 264 held the pattern the test of 272 took over: after the
refused migration it rolled back to a savepoint and then asserted that
nothing had changed, which holds for any migration. The assertions are
removed. That a file which raises changes nothing follows from the
runner's one transaction per file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The refusal messages of 272 cannot change once the migration is released.
They named .downstream/native-domains.md, a file whose name comes from the
plugin era and is due to change. DOWNSTREAM.md links to the same text and
keeps its name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@HTExplicit
HTExplicit merged commit de9d31a into main Oct 5, 2026
18 checks passed
@HTExplicit
HTExplicit deleted the refactor/remove-retired-plugin-panel branch October 5, 2026 08:17
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