Repository navigation
refactor: remove what the first-party plugin era left in live code - #250
Merged
Merged
Conversation
…ackage Both packages had one user, the service package, and existed because their contents once crossed a plugin boundary. Nothing an admin, a user or an API client can observe changes. - The model capacity structs, the two switch setting structs and the Codex client identity are defined next to the code that uses them. JSON tags and stored formats are unchanged. The handler builds the setting structs from the service package. - The Codex client identity is one struct with its own methods; the conversions between three copies of the same type are gone. Building a User-Agent still checks the identity and the version and still returns the same errors. - Reasoning recovery reads the upstream payload and the request body directly. The four carrier structs between collecting facts and deciding are gone. The order of the checks and the reason strings are the same. - validOfficialCatalogCapacity repeated validModelContextTokens and is removed. - The account traffic telemetry types (the decision table, the observation policy and the counter snapshot) move unchanged. - CI: the selector script that ran ./internal/codexruntime is removed together with its workflow step and its assertions in the contract test. The tests it selected run in the required test job. The contract test also loses the assertions that only named files deleted earlier. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… they are "native" and "legacy" in these names described the move out of plugins, not the settings themselves. - readNativeSwitchSetting is readSwitchSetting. Its three errors no longer say "native": "settings repository is unavailable", "cannot read setting <key>" and "invalid setting <key>". They appear only in the process output when the server fails to start. - LegacyAdminObservabilityConfig is defaultAdminObservabilityConfig: it is the deploy-time default read from gateway.account_traffic_telemetry_disabled. - EffectiveAdminObservabilityConfig reads the switches itself instead of forwarding to a second function, and the holder is no longer called an override. - LoadAdminObservabilityConfig loses a branch for a nil service that the read above it already returns from. - Tests: native_setting_load_test.go is setting_switch_load_test.go, and four test names lose the word. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…talog lookup's input guard Two shapes left from calls that used to cross a plugin boundary. - GET /admin/ops/errors/:id/diagnostics was a method of AccountHandler that took the OpsHandler as an argument and used nothing of its own receiver. It is OpsHandler.GetCodexErrorDiagnostics, registered like the routes around it. Path, headers, status codes and bodies are the same. - lookupOfficialModelCatalog validated its candidates as if they came over an RPC: at most 16, at most 512 bytes each, none blank. Its one caller, LookupOfficialModelContextCapacity, passes at most five candidates that each passed validModelContextID, so none of these checks could fail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…count responses Every admin account response carried an account_view_facts object (version, status, plan, privacy_mode) that was built for the plugin account views. Nothing reads it: the frontend only declared its type. - service.AccountViewFactsV1 and AccountViewFactsFromAccount are removed with the test that covered only them. accountConsoleStatus and accountConsolePlan stay; the account filters and facets use them. - dto.Account starts with ID again, as upstream does, and dto.AccountListItem loses the same field. - The frontend Account type loses the declaration. Observable change: the admin account JSON (full and list form) no longer has the account_view_facts key. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… writes AccountJobItem.Action and AccountJobItemSeed.Action had one writer, the plugin operation job, which no longer exists. Both seed constructors leave the field empty, so every item row stores '' and the JSON key, being omitempty, was never sent. - The two Go fields are removed. - The repository no longer names the column: the item insert, the item column list and the retry seed query drop it. admin_account_job_items.action stays in the database with its NOT NULL DEFAULT '', so inserts keep working and an older image can still write to the table. - The frontend AccountJobItem type loses the declaration. - account_job_repo_test.go also loses a trailing blank line gofmt rejected. No migration. Nothing an admin or an API client can observe changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… the test plan The account test plan was shaped to be shared with a provider plugin: it stated a wire platform and a schema version. The wire platform was always the account's own platform and the version was always 1. Backend - accountTestPlanView loses WirePlatform and SchemaVersion. - ordinaryAccountTestPlan is buildAccountTestPlan. basicAccountTestPlan, its one helper, is folded into it. The plans are byte for byte what they were in the four remaining fields; the server still orders the models and picks each mode's default. Frontend - isOpenAIAccount in both AccountTestModal components is upstream's props.account?.platform === 'openai' again, and so is the check in supportsOpenAIImageTest. isOpenAIOAuthAccount no longer tests the platform twice. - AccountTestPlanView and validateAccountTestPlan lose the two fields. - AccountAvailableModel loses nine fields the server never sends and nothing reads: live_upstream_id, base_context_window, codex_context_window, endpoints, source_revision, verified, alias_target, managed, public_model. Tests - The two cases written against a "cindy" account platform are removed; that platform does not exist. - AccountTestModal.policyPlan.spec.ts is AccountTestModal.testPlan.spec.ts and uses an OpenAI account and the "default" mode the server sends. The downstream-verify workflow lists the new name. - TestAccountTestPlanCoreSelectionSmallMatrix is TestAccountTestPlanModelOrderAndDefaults. Observable change: the response of GET /admin/accounts/:id/models ?view=account-test-plan-v1 no longer has wire_platform and schema_version. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
When an account is edited, the OpenAI protocol modes the admin did not touch
keep their stored encoding. That behaviour stays. The code that implements it
was the remainder of the plugin-era "account edit contract" and still carried
its names and shapes.
Backend
- account_edit_codec.go is openai_apikey_protocol_modes.go.
openAIAPIKeyOwnedExtraForUpdate and applyAccountEditOwned are
openAIAPIKeyProtocolModesForUpdate and applyOpenAIAPIKeyProtocolModes.
- accountEditRawValue, a present/value pair with JSON tags nothing serialised,
is gone: the resolved modes are a plain map, and a key missing from it is a
key to remove. The branch for a key that was "not owned" could not be taken
and is removed.
- The seven protected keys, openai_prompt_cache_key_mode among them, and the
point in UpdateAccount where they are resolved and applied are unchanged.
- New test TestUpdateAccountKeepsOmittedOpenAIAPIKeyProtocolModes pins the
behaviour through UpdateAccount. It passed before this change and passes
after it.
Frontend
- utils/accountEditCodec.ts is utils/openaiProtocolModeEdits.ts, and
types/accountEdit.ts is folded into it: the value unions are derived from
the table of modes instead of being written twice.
- AccountEditChangesV1 is OpenAIProtocolModeEdits. An edit is the chosen value
itself; the { op: 'set' | 'clear' } wrapper is gone because 'clear' was
never produced and only threw.
- applyCoreAccountModeChanges is applyOpenAIProtocolModeEdits; in
EditAccountModal coreModeChanges and recordAccountMode are protocolModeEdits
and recordProtocolModeEdit.
- The spec follows the file name and keeps its assertions. Its one test of
buildModelMappingObject moves to useModelWhitelist.spec.ts, where that
function is tested. The downstream-verify workflow lists the new name.
Nothing an admin or an API client can observe changes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rder Four upstream files differed from v0.2.13 in places no fork feature needs: - middleware/group_model_allowlist.go: the GroupModelAllowlist comment described a rejection of reserved internal selectors that no longer exists. The code under it is upstream's fast path, and the comment is upstream's again. - handler/setting_handler.go: the NewSettingHandler comment is back. - service/settings_view.go: the blank line before the model fallback fields is back. - service/setting_service.go: "sync" is back at upstream's place in the import block. No code changes. What still differs from upstream in these files is live fork code: the flat theme flag, the refusal recovery settings and their cache, the tolerant JSON body read and the wildcard model route. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
codexClientIdentity.buildUserAgent checked the identity and the version again and returned an error that every send path carried upwards. The check dates from the time the builder sat behind a plugin boundary. Inside the service package it cannot fail: - The version comes only from resolveCodexOutboundIdentity. It is either the built-in constant or a value NormalizeCodexClientVersion accepted, with the same expression and the same length limit the builder applied. - The identity comes only from Account.CodexClientIdentity. It is either a stored value that passed valid() when it was read, or a derived one, and the derivation can only produce identities that pass valid(). So the builder is UserAgent again, a plain formatter, and resolveCodexOutboundIdentityForAccount and enforceCodexIdentityHeadersForAccount return no error, as they did before the plugin era. Gone with it: errCodexClientVersionInvalid, the second copy of the version expression, the error branches on the send paths (account test, usage probe, alpha search, models manifest, token refresh, upstream models, the shared header finalizer), the two readers that discarded the error, and the account-test message "Codex client identity is invalid", which could never be shown. Tests: the case that relaxed the version expression to force the error is replaced by one that hands the resolver an invalid version and checks that the account still goes out as itself with the built-in version. The check that the builder refuses a bad profile becomes a check that a stored identity failing the schema check is not used, and that every branch of the derivation passes it. Call sites in tests are back to their one-line form. No request changes what it sends or when it fails. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…er reach applyOpenAIProtocolModeEdits checked each edit against the table of allowed values and refused a Responses mode on an account that is not an API-key account. Both checks threw, and neither can be reached: - The edits come only from recordProtocolModeEdit in EditAccountModal, which checks the value against the same table before it records it, and the parameter type admits no other value. - The Responses mode select is rendered only for an OpenAI API-key account, and the recorded edits are cleared whenever the dialog opens or the account, its platform or its type changes. The function has one caller and no spec covers either throw. The type parameter stays: it still picks the OAuth key for the WebSocket mode. Four cases in EditAccountModal.spec.ts were titled with the retired account.edit slot name and its vocabulary. Each title now says what the case checks. No assertion changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- utils/accountTestModels.ts: the comment about presentation, a data contract and provider rules described the test plan that was shared with a provider plugin, and it sat above a function it did not describe. Removed. - service/codex_error_diagnostics.go and its test: both comments explained that a count limit and an account filter do not apply any more. They now state what the projection returns. Comments only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s them When the plugin-era fields were deleted from the two account literals, the fields next to them stayed where they were: OpenCodeGoUsage at the end of AccountFromServiceShallow instead of after OllamaCloudUsage, and ManagementFolder and Tags at the head of AccountListItemFromAccount, which made gofmt re-align upstream's first line. OpenCodeGoUsage is back at upstream's position, and ManagementFolder and Tags follow the proxy fields as they do in the Account literal. mappers.go now differs from v0.2.13 only by added lines. Both literals are keyed and hold the same pairs as before, so they build the same values and the JSON is unchanged. dto/types.go is not touched: moving the OpenCodeGoUsage field there would change the key order of the account JSON. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…trigger accountTestPlan refused a nil account and an account without an id with "account test target is unavailable". Its one caller, GetAvailableModels, reaches it only after GetAccount returned without an error, and the account repository returns an account or an error, never neither. The plain model list in the same handler uses the account without such a check, as upstream does. The check dates from the commit that shared the plan with a provider plugin. No test covers it and no response changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…p upstream's field order UpdateAccountRequest.UnmarshalJSON only rejected "provider_edit": null, a field that no longer exists; upstream has no such method. Account's OpenCodeGoUsage is back where upstream declares it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AccountUsageCell built its cache key from the account-view context, and the details drawer was the only place that still provided one. Outside the drawer the key was a constant prefix on the account id. Inside it the key carried the drawer's open counter, so every open queried usage again, never reused what a card or compact row had just loaded, and left one more entry in the module cache. The cache and the in-flight request map are keyed by the account id again, as they were before cd8c18b: - Reopening an account within five minutes shows the cached usage. - The drawer, the cards, the compact rows and the mobile table share one entry per account, in both directions. - The page's refresh button and the cell's own query buttons still force a request. The drawer keys its usage cell on the account id. When it goes straight from one account to another, the cell and the probe cells inside it are rebuilt: the new account loads on its own and a late answer for the previous one ends in an unmounted instance. Until now the cell was reused. An account that is not OpenAI OAuth kept the previous account's usage on screen, and if that account's request was still running the loading state never ended, because loadUsage resets it only for the account it started with. That check in loadUsage is unchanged. Every usage cell is now keyed by account id (table rows, cards, compact rows, the drawer), so it has no case left to catch. The view argument of the cell's getUsage calls, the cancellation it threw for a changed view and the watcher on the context key go with the context. The watcher could not fire: nothing reactive changed when the drawer changed account. Two cases in AccountDetailsDrawer.spec.ts cover the key and the shared cache. Both fail on the previous code. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The statistics dialog, the scheduled-tests panel and the re-authorization dialog discard an answer that arrives after the dialog was closed or moved to another account. They did it through useAccountViewOperation, a composable left from the plugin account views. Its view snapshot is always empty and its "available" flag is always true, so only its operation counter did anything. - AccountStatsModal and ScheduledTestsPanel use the guard upstream has in TempUnschedStatusModal: a request version that the show/account watcher advances in its cleanup and that is compared when the answer arrives. The panel's two loaders read one version without advancing it, so the reload after a create and the results of an expanded plan do not cancel each other, as before. The composable also refused a request for a closed dialog; the panel keeps that for the one handler a click can still reach while the dialog fades out, toggleExpand. - ReAuthAccountModal already had its own revision counter and isCurrent check. The view snapshot, the "available" checks, the inert binding and the watcher that reset the OAuth clients go; none of them could trigger. canExchangeCode and handleGenerateUrl are upstream's again. The latter also loses a show check: it runs only on the flow component's event, and an unmounted child emits nothing. What an admin sees does not change. A closed or re-targeted dialog still ignores the old answer, shows no error for it and keeps the current loading state, and re-authorization still never writes one account's credentials to another. Each dialog gets a small spec for this; none had one. All three pass on the previous code as well. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
useAccountViewContext.ts and accountViewClient.ts threaded a "view" through the admin account API, the probe cells and the account dialogs. Nothing has produced a view since the plugin account views were removed (9f7b08d), so every wrapper passed straight through to apiClient and adminAPI.accounts. Removed: - both files; - the view parameter of 60 functions in api/admin/accounts.ts and of reviewDuplicates, accountViewClient(view) in favour of apiClient, accountAPIForView with its argument table, and scheduledTestsForView; - readWithAccountView around the requests of the Ollama Cloud and OpenAI quota cells; - scopedAccounts() in the bulk edit, edit and test dialogs, and in the test dialog the "available" checks, the bound request config and the axios cancel check (its request is a fetch); - the header's injected page title, which nothing provided; - AccountConsoleFacets.view_preset_counts, which nothing sends or reads. Back to upstream v0.2.13 byte for byte: api/admin/cnProviders.ts, grok.ts and scheduledTests.ts, CNProviderBalanceCell.vue, CNProviderQuotaCell.vue, GrokQuotaProbeCell.vue, TempUnschedStatusModal.vue and its spec. The spec's vue-i18n mock had been widened only because the component loaded the account-view client. No request, response or screen changes. In the details drawer the probe cells relied on the view to drop an answer for a previous account; the drawer rebuilds them per account instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ally - README.md, README_CN.md, README_JA.md: Go 1.27.0, as go.mod and upstream say. - docs/channel-monitor-v2-safe-defaults.md: the three Markdown hard line breaks. - frontend/src/api/admin/index.ts: the plugin type export on six lines. - AppSidebar.vue: no comma after the last admin nav item. - AccountTableFilters.vue: upstream's file. The fork mounts AccountConsoleFilters instead and has no production reference to it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…and three dead ends - AccountTasksView.vue had no route and no importer since the account page took over the operation history; its spec and its seven locale keys go with it. - 33 more locale keys the fork added are read by no source file. They are removed from both locales; accountConsoleLocales.spec.ts no longer pins the text of one of them. - useAccountTestPrompt writes localStorage itself again. The window event it sent through utils/browserPreferences.ts was heard only by its own module, which stored the value it had just set. - AccountActionMenu no longer emits resource-complete: nothing listens. - accountOperationIdempotency.ts loses captureAccountOperationSession, which has no caller. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
For an OpenAI OAuth account the usage endpoint answers through getOpenAIUsage, which builds quota_windows and fills five_hour and seven_day only from them. A response with those two fields and no quota_windows therefore does not exist. The helper that rebuilt windows from them for such a response is deleted and the usage cell reads quota_windows. Fifteen tests fed the cell that response and went through the helper. Their fixtures now carry quota_windows next to five_hour and seven_day, as the server's response does; no assertion changed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tsconfig.json is upstream's again, and vite.config.ts differs only by the SUB2API_ARTIFACT_BUILD switch. The removed paths, dedupe and 'vue' alias served sources outside frontend/, which no longer exist; 'vue' still resolves to dist/vue.runtime.esm-bundler.js for the client build. vitest.config.ts loses fs.allow, dedupe and the 'vue' alias. With all four of its added entries removed, the full unit suite differs in three SubscriptionPlanCard tests only: they assert translated text, and the runtime-only vue-i18n returns the key without __INTLIFY_JIT_COMPILATION__. That entry stays. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ntries Both were redirects to the account page kept for old bookmarks; those addresses now reach the 404 page. The account page no longer opens the operation history for ?operations=history, a query only the /admin/tasks redirect produced. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Select.vue differs from upstream only by the #overlay-root teleport and the console theme's dropdown anchor. The interactionDisabled alias of props.disabled is gone, and so are the four checks that closed an open dropdown and refused its options once the select became disabled; an open dropdown now stays open in that case, as upstream's does. Select.disabled.spec.ts tested only those checks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ost" Three sentences of the continuation diagnostics named the gateway "the host" (宿主). They now state what happened: a bounded recovery request was dispatched, replay is not allowed after semantic output, recovery across sources is not allowed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- CodexRuntime.native.spec.ts becomes CodexRuntime.spec.ts; its suite and its diagnostics test no longer say "native". - SettingsView.spec.ts: the mocks and the test of the observability settings and the model catalog no longer say "native". - features/account-jobs/__tests__/integrationSurface.spec.ts moves next to the layout it mounts, as AppLayout.accountTaskDrawer.spec.ts, and stops asserting that a removed header button is absent. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PromptAuditView.vue is upstream v0.2.13 plus the console theme's page hook (data-ui="prompt-audit-page" on the root); viewModel.ts and PromptAuditView.spec.ts are upstream's bytes. EventWorkspace.vue keeps its one theme hook (data-ui="log-table"). What the page did beyond upstream is gone with it: - the save bar sticking to the end of the content column: it is fixed to the window's bottom again, from the sidebar to the right edge; - reconcileSavedDraft: a save's response replaces the draft, so edits made while the save was in flight are dropped; - the request generations of the event list and the event detail: the response that arrives last is shown, also when it is the older one; - the generation that tied a filter-deletion preview to its criteria and to the open dialog: a late preview is shown after the criteria changed, and a one-click deletion goes ahead after the dialog was closed; - the unmount guard: a request that fails after leaving the page still raises its error toast. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The console theme's rule for the save bar selected the sticky bar the fork's page had (div.sticky.bottom-0 after the page root). Upstream's bar is fixed to the window's bottom, so the rule matched nothing and the bar showed upstream's translucent fill, blur and drop shadow under the theme. The rule now selects upstream's bar and keeps what it drew before: the surface fill on the structural line, no shadow; the blur behind the now opaque fill is switched off as for the header row. Upstream starts the bar at its own 16rem sidebar (lg:left-64). The theme's sidebar is clamp(13rem, 20vw, 15rem) wide, so from 1024px the bar starts at the shell's sidebar width instead; without this it began 16px to 48px right of the sidebar's edge. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The per-account traffic counters had writers only. Every OpenAI gateway entry point counted its forwarded attempts in Redis, and the one reader, GET /admin/accounts/:id/traffic-telemetry, was never called by any page. Removed: - the Begin and Finish calls at the seven entry points: Responses, Messages, Chat Completions, Embeddings, Images, alpha search and the Responses WebSocket; - the observer, its Redis cache with the Lua script, the outcome decision table and its rules, and the snapshot handler with its route; - the wire providers (wire_gen.go regenerated); - OpenAIForwardResult.UpstreamTerminalStatus with its three WebSocket writers: only the outcome classifier read it; - the tests of all of the above. The six HTTP forward closures are upstream's bytes again. Slot release and every other call around a forward keep their order; each forwarded attempt makes two Redis round trips fewer. The telemetry switch in the observability settings and gateway.account_traffic_telemetry_disabled switch nothing after this commit; the next one removes them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ts config option
With the traffic counters gone the telemetry switch switched nothing.
- The observability settings hold the flat theme switch only. GET and PUT
/admin/settings/observability carry {"theme_enabled": <boolean>}; a PUT
that still sends telemetry_enabled is refused like any unknown key. The
settings panel loses the telemetry checkbox and the sentence that
described the counters. The theme checkbox and its save are unchanged.
- gateway.account_traffic_telemetry_disabled is no longer a config key. The
files under deploy/ still name it; the server ignores the variable.
- Migration 273 removes telemetry_enabled from the stored
admin_observability_config row. The reader of that row is strict and a
key it does not know stops startup. theme_enabled keeps its value.
- What was left of admin_observability.go, the switch holder and
FlatThemeEnabled, moves into setting_admin_observability.go. The decoder
test moves to setting_switch_load_test.go with a two-switch type of its
own, so it still shows that an omitted switch keeps its default.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… loadUsage cd8c18b made loadUsage remember the account id it started with and drop the response when the cell showed another account by then. That could happen while the details drawer reused one cell for whichever account it displayed. Every render site now keys the cell by account id: DataTable rows by row-key="id" (plain rows, windowed rows, stacked cells and mobile cards), the card grid and the compact list by the key of their v-for, and the drawer by :key on the cell itself. An instance is never given a second account, so the comparison was always true. The three conditions are upstream's again: if (!unmounted.value). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fe89731 defined __INTLIFY_JIT_COMPILATION__ for vitest so that plugin UI tests rendered translated text, and 6cd89ee rewrote the assertions of SubscriptionPlanCard.spec.ts to that text. Without the define the runtime-only vue-i18n build returns the message key, which is what upstream's spec asserts. Both files are upstream v0.2.13's bytes again. SubscriptionPlanCard.spec.ts is the only spec that gives a real vue-i18n instance messages to render, so no other spec depends on the define. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…f loadRecent Only AccountTasksView passed kind and page_size to the store's loadRecent, and that page was deleted in 07f50b2. The callers that are left, the history dialog and the store's own refresh, pass a page and a status at most. loadRecent takes { page, status } now and always asks for the page size the server last reported. The list keeps one status filter instead of a filters object, and AccountJobListParams no longer offers kind. The store, layout and API specs follow. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The bulk bar offered "Review Duplicates" for 2 to 100 selected accounts, but #206 (71f056d) deleted the handlers, the routes POST /admin/accounts/duplicates/review and /merge, and the job kinds account_duplicate_review and account_duplicate_merge. The button could only end in a failed request. Removed: the button and its event, handleDuplicateReview and the two kinds named in the accounts page's job watcher, the two API functions with their request and metadata types, the two store actions, the merge form of AccountOperationProgress, the spec cases and mock members for all of these, and in both locales bulkActions.duplicateReview, accountTasks.duplicate.* and the two kind labels. The kind labels go as well because no stored job can still carry those kinds: nothing has been able to create one since v0.2.8-codexrip.9, and the job runtime deletes every job 24 hours after it finishes (AccountJobResultTTL). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ired page and status The store's refreshDrawer has had no caller in the application since 175007b (#189); only the store spec called it. 82cce35 counted it as a caller of loadRecent and kept the call without arguments for it: the default parameter, the own-property check on status and the fall back to the page last shown. refreshDrawer and its export are deleted. loadRecent takes { page, status } and both are required. The two callers in the application, the history dialog and openDrawer, already pass both; their requests are unchanged. The store spec follows: - every loadRecent call names its page and status; - the case that refreshed without arguments now asks for another page and status and still expects the page size the server last reported; - the 404 case reaches its last assertion through the poller instead of refreshDrawer: one tick after the detail request answered 404, the cleared selection must not be fetched again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
activeCount fed the header's task badge. 5d74264 removed the badge and nothing in the application has read the count since; two specs still did. The computed and its export are deleted. The five assertions in the store spec and the task drawer spec read the length of activeJobs, the list the count was taken from. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GET /admin/account-jobs read a kind query parameter and passed it, with a creator id that was always 0, through AccountJobService.List to the repository, which could add kind and created_by conditions to the query. The tasks page was the one caller that sent kind; 07f50b2 deleted the page and 82cce35 removed kind from the frontend's list parameters. The handler has passed 0 for the creator since the route was added, so the created_by condition never applied. List takes the status, the page and the page size in the handler call, the service, the repository interface, the repository and the two test stubs. For the requests the application sends, the SQL text and its arguments are what they were: "1=1", or "1=1 AND status=$1". Observable change: a kind query parameter on this route is ignored. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ance With traffic telemetry gone the panel has one switch, the flat theme. Its title and load-failure text no longer mention observations. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The first-party plugin system is gone (#229–#248), but code shaped by it still ran: two backend packages named after the old extension API, carrier structs that once crossed a plugin boundary, a frontend "account view" skeleton whose view object is always empty, a telemetry writer whose only reader was a deleted plugin UI, legacy redirects, a button whose backend was deleted, and an error path that cannot trigger. The owner's rule is that a retired feature leaves nothing behind.
Change
Backend
internal/nativeapiandinternal/codexruntimeare folded into their only user,service. The aliasextensionv1, the four recovery carrier structs and the three identity-conversion layers are gone. Reasoning recovery keeps its decision order and reason strings; fix(openai): move to the next account when the stripped retry fails for the account's own reason #249's code is untouched.ErrInvalidVersionand its propagation through the send paths are removed. The version and identity it rejected are validated where they are produced.Begin/Finishcall sites, the observer, its Redis cache and Lua script, the decision table,GET /admin/accounts/:id/traffic-telemetry, the settings switch andgateway.account_traffic_telemetry_disabled. Six HTTP forwarding closures are byte-identical to v0.2.13 again.273_purge_account_traffic_telemetry_switch.sqlremovestelemetry_enabledfromsettings.admin_observability_configand keepstheme_enabled. The decoder stays strict.account_view_factson account responses, the job itemaction,wire_platformandschema_versionon the account test plan, the job list'skindandcreated_byfilters, a request decoder for the removedprovider_editfield.test_native_domains.sh, its workflow step and its contract assertions go with the packages they selected; the same tests run undermake test-unit.Frontend
useAccountViewContext.ts,accountViewClient.ts, theviewparameter on 60 API functions,accountAPIForView). Eight files are byte-identical to v0.2.13 again. The stats dialog, the scheduled-tests panel and the re-auth dialog keep discarding late answers through a local guard, as upstream does inTempUnschedStatusModal./admin/tasksand/admin/cindy-accountsare removed, with the?operations=historyhandling only the redirect produced.Select.vue, the plugin-era resolver entries and the vitest config are upstream's; orphan page, unread locale keys and dead exports are deleted.Not in this PR
deploy/**still namesGATEWAY_ACCOUNT_TRAFFIC_TELEMETRY_DISABLEDin six files; the application ignores it. It goes with the deploy pipeline cleanup.What an admin sees
/admin/tasksand/admin/cindy-accountsshow the 404 page.API clients
account_view_facts. The account test plan view has nowire_platformorschema_version.GET /admin/accounts/:id/traffic-telemetryis gone.GET/PUT /admin/settings/observabilitycarries onlytheme_enabled.GET /admin/account-jobsignoreskind.Verification
go build ./...(default andGOOS=linux);go vet ./...with no tag,-tags unit,-tags integrationon repository, service and handler;wire diffclean; gofmt.vue-tsc,check:i18n, eslint on changed files, the full vitest suite.Known failures that exist on main and are not touched here:
TestOllamaProbeCallback_StaleLongDoesNotOverrideNewShortand, at times,TestAntigravityCompatHandlerRepeatsPreContentKeepalive(timer-sensitive on Windows);groupModelAllowlist.spec.ts"accepts wildcards at any position".Not run locally: golangci-lint (the local binary cannot read Go 1.27 export data), the full integration suite, real model calls.
🤖 Generated with Claude Code