You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
finding(runtime): scoped /api/v1/environments/:id/packages[/:id] has no dispatcher door on a plugin-hono-server-only composition after #16628 (B′ follow-up to #14503) #16781
Filed by the director seat under the #14503 step-2 ruling C′ (2026-09-08, decision batch #84): PR #16628 lands with this residue disclosed; this card carries the repair.
The residue
mountPackagesRoute (packages/runtime/src/dispatcher-plugin.ts:1306-1330) mounts /packages* at the unscoped prefix only. Scoped variants exist for automation / actions / ai (:1653-1667) — zero scoped /packages mounts. plugin-hono-server's only route into the dispatcher is setFallbackHandler (:1711), gated on isAppEndpointPath. So a host composed as plugin-hono-server + REST with enableProjectScoping: true + dispatcher, withoutcreateHonoApp, had exactly one door for scoped package reads/deletes — the REST mirror #16628 removes. After #16628: the transport's bare notFound answers. Reachable from the open-core CLI (serve.ts:2334 skips the standalone boot when shouldBootWithLibrary() is false; serve.ts:3967 forwards api.enableProjectScoping to REST :4019 and the dispatcher :4040); documented at content/docs/api/environment-routing.mdx:62-66.
Population at ruling time, all zero with firing controls (fork report #14503 comment 5571983259): in-repo production callers of ScopedEnvironmentClient.packages.* 0; Console scoped /environments/${…}/packages calls 0; source stamp readers 0. NOT MEASURED: the cloud repo's host composition.
Deliverable
A scoped mountPackagesRoute variant mirroring the existing automation / actions / ai pattern twenty lines away, so GET /api/v1/environments/:id/packages, GET …/packages/:id, DELETE …/packages/:id answer through the dispatcher on that composition — the same handler, no second implementation.
The response-shape drift the contract review of fix(rest): the dispatcher's /packages domain is the one implementation of the package read and delete routes (#14503) #16628 (5578894182, F2) measured: GET /packages answers { packages, total } but ListInstalledPackagesResponseSchema (package-api.zod.ts:71-77) requires hasMore; DELETE /packages/:id answers { success, registryRemoved, persisted } but UninstallPackageApiResponseSchema (:358-364) requires packageId; runtime ledger rows route-ledger.ts:336,339 carry no responseSchema. Reconcile to the spec (protocol is the baseline) and pin the ledger rows with responseSchema.
A test on the plugin-hono-server-only composition that reddens if the scoped door disappears again.
Acceptance control: the same request on the same composition answers ROUTE_NOT_FOUND/bare 404 before and the dispatcher's row after.
Filed by the director seat under the #14503 step-2 ruling C′ (2026-09-08, decision batch #84): PR #16628 lands with this residue disclosed; this card carries the repair.
The residue
mountPackagesRoute(packages/runtime/src/dispatcher-plugin.ts:1306-1330) mounts/packages*at the unscoped prefix only. Scoped variants exist for automation / actions / ai (:1653-1667) — zero scoped/packagesmounts.plugin-hono-server's only route into the dispatcher issetFallbackHandler(:1711), gated onisAppEndpointPath. So a host composed asplugin-hono-server+ REST withenableProjectScoping: true+ dispatcher, withoutcreateHonoApp, had exactly one door for scoped package reads/deletes — the REST mirror #16628 removes. After #16628: the transport's barenotFoundanswers. Reachable from the open-core CLI (serve.ts:2334skips the standalone boot whenshouldBootWithLibrary()is false;serve.ts:3967forwardsapi.enableProjectScopingto REST:4019and the dispatcher:4040); documented atcontent/docs/api/environment-routing.mdx:62-66.Population at ruling time, all zero with firing controls (fork report
#14503comment 5571983259): in-repo production callers ofScopedEnvironmentClient.packages.*0; Console scoped/environments/${…}/packagescalls 0;sourcestamp readers 0. NOT MEASURED: thecloudrepo's host composition.Deliverable
mountPackagesRoutevariant mirroring the existing automation / actions / ai pattern twenty lines away, soGET /api/v1/environments/:id/packages,GET …/packages/:id,DELETE …/packages/:idanswer through the dispatcher on that composition — the same handler, no second implementation.GET /packagesanswers{ packages, total }butListInstalledPackagesResponseSchema(package-api.zod.ts:71-77) requireshasMore;DELETE /packages/:idanswers{ success, registryRemoved, persisted }butUninstallPackageApiResponseSchema(:358-364) requirespackageId; runtime ledger rowsroute-ledger.ts:336,339carry noresponseSchema. Reconcile to the spec (protocol is the baseline) and pin the ledger rows withresponseSchema.plugin-hono-server-only composition that reddens if the scoped door disappears again.Acceptance control: the same request on the same composition answers
ROUTE_NOT_FOUND/bare 404 before and the dispatcher's row after.Related: #14503 (ruling C′), PR #16628, #12034 (SDK
packages.get(id, version?)retiringversion), #15859.