Repository navigation
Description
Part of #27108 (M5). Blocked-by: #27124
Filing gate ③ (maintainer ruling). Ruled on #27108 (the ruling comment of 2026-10-28 by session_01J8VVAjRKqdoEYQ4hXxtBuf, item 2): 「代码插件要到下次启动才加载,这个问题也要解决」 → 「好,把热加载和依赖策略并进清单」 → 「同意」. This reverses the epic's Q8 (「hot reload retired with #12587 → boot activation」) for the general case; ADR-0025 v2 §3.5 step 7 gains this arm (Tier H line, the maintainer lands). ⛔ Not a claim. ⛔ No domain:*: packages/core (kernel), packages/runtime, packages/plugins/plugin-hono-server, packages/services/service-automation, service-cluster; triage sets lanes and splits.
维护者速读
装插件不重启。内核加 attach / detach:对单个插件跑依赖检查、init、start,detach 跑 destroy 并按"记账"反注销它登记过的服务、钩子、路由、任务、通道提供者、连接器工厂——这层记账包装正是 M2 的 SecurePluginContext,一层做两件事。插件 HTTP 路由不直接挂 Hono(默认 SmartRouter 首次匹配后冻结),走启动时挂好的固定前缀 + 可变分发表。加载后发 plugin:loaded,自动化服务复用 metadata:reloaded 的 reconcile 拉起"provider 刚出现"的声明式连接器,messaging 的 lazyChannelMount 已能接晚到的通道。集群里一个节点装 → 广播 → 各节点自取自装。卸载是"逻辑卸载"(ESM 不能从进程卸掉,旧模块留到重启),升级按版本化路径并排加载再 detach 旧版。三类仍须重启并在货架上标明:改登录的插件(better-auth 实例启动时构建)、数据库驱动、替换内核核心服务的插件。
Readings (at c3fb185a, re-check at dispatch)
packages/core/src/kernel.ts:350:use()after bootstrap throws "Cannot register plugins after bootstrap has started". Re-check:git grep -n "Cannot register plugins after bootstrap" origin/main -- packages/core/src/kernel.ts.packages/core/src/hot-reload.tsreloadPlugin: destroy → re-init of an already registered plugin, state strategiesmemory | none; no attach of a new plugin, no detach. Re-check:git grep -n "async reloadPlugin" origin/main -- packages/core/src/hot-reload.ts.kernel.ts:383-385:registerServicethrows on a duplicate;replaceServiceexists; nounregisterService. Hook / event unsubscription: not found by this seat — the dev establishes it first.plugin-hono-server/src/adapter.ts:643:new Hono()with the default router. Whether declarative endpoints (ADR-0121) already dispatch through a runtime-mutable table — not verified; if so, reuse it.runtime/src/http-dispatcher.ts:575:announceKernelEventexists; whether it fans out across cluster nodes — not verified.
What lands
- Kernel:
attach(plugin)/detach(name)after bootstrap; dependency check against the running set; a plugin that othersrequirescannot be detached while they are attached;destroy()contract documented (release timers, sockets, subscriptions). - Resource accounting: the
PluginContextwrapper (shared with M2) records every registration under the plugin's name and reverses them on detach;unregisterServiceand hook/event unsubscription added where missing. - Plugin route table: a fixed catch-all mounted at boot delegating to a mutable table; route ledger updated at attach/detach.
- Consumers:
plugin:loaded/plugin:unloadedkernel events; automation reconcile of declared connector instances on the provider factory appearing or vanishing; messaging lazy mount verified. - Cluster: install/uninstall announced to every node; per-node attach status on the installation record; a failing node degrades the installation visibly.
- Restart boundary: a manifest declaration for the three classes; the shelf (M4) and
os plugin installprint "restart required" for them and nothing else. - Delete the Q8 sentence in ADR-0025 v2 and the epic's milestone line in the same stroke (docs follow-up, Tier H).
Acceptance
- Attach the Stripe sample on a running single-node stack: its connector materializes, a flow dispatches, no restart; detach: the connector is gone, routes 404, services deregistered, no leaked timers (test harness asserts). Upgrade side-by-side; old version detached.
- On a two-node cluster, install on node A; node B attaches within the announce window; a deliberate failure on B marks the installation degraded naming B.
- A plugin declaring the sign-in class is refused hot attach with "restart required".
Related
#27108 (epic, ruling item 2) · #27124 (M2 — the shared wrapper) · the M4 shelf card · ADR-0025 v2 §3.5 · ADR-0097 (reconcile) · ADR-0121 (declarative endpoints) · #12587 (the retirement this reverses in part).
Generated by Claude Code
Activity
objectstack-fleet commentedon Oct 28, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: 发布并装进一个环境 | none | P④
Triage: p2 ·
domain:cloud·area:devpath· parked for the cloud PM · 2026-10-28T15:06Z⛔ Not a claim.
plugin:loadedreconcile and cluster fan-out.triage-duties.md: 「涉 cloud 任一即算」, 「被其阻」): It isBlocked-by: #27124(M2,domain:cloud), whoseSecurePluginContextit shares, and the cluster fan-out runs on hosted nodes. So the card goes to the cloud PM whole, withdomain:cloudandstatus:parked, and it is not dispatched from this repository. It is not split by lane here: the cloud PM orders it against the rest of [Epic] ADR-0025 plugin package distribution — the next development phase: M0 record v2, M1 local T0 install loop (first-party, self-signed), M2 cloud fetch + per-plugin permission enforcement, M3 third-party sandbox tier #27108.Generated by Claude Code
objectstack-fleet commentedon Oct 28, 2026
Frozen (2026-10-28T16:25Z). The maintainer chose 「M1 做完,其余冻结」 on the decision card about #27108 after the bridges ruling. That ruling is recorded on #27108, and the bridges epic is #27314. This card stays parked and is not dispatched. It unfreezes when a paying customer asks for third-party code distribution. ⛔ Not a claim.