Repository navigation
Description
Filing gate: ③ maintainer-directed. The maintainer, in the director summon chat on 2026-10-28, on ADR batch 4 (objectstack#26553): 「ADR-0025 插件包分发(代码 + 依赖)(2026-05,2026-09-12 审计) 应该是下一阶段的重点开发,需要综合评估和我沟通」; after the seat's assessment (code inventory on objectstack f2fdac5d7a and cloud ce05c91, decision points Q1–Q8): 「插件包分发 同意,应该立专题卡吧?」. Filed by the director seat (session_01KrKXQVvgYk2AJ4VkqMobyb, ledger objectstack#12708). ⛔ Not a claim. ⛔ No domain:*: the children span cli, server (core/runtime), cloud and spec; triage sets each child's lane. Dedupe: #17757 (closed, "ADR-0025 install-flow design"), #13457 (closed, F4 load-time registration), the retired #17147 / #11333 numbers in code comments; no open card carries the install loop. New.
维护者速读
ADR-0025 今天是「造得出、签得了、发得上去,但装不进来、跑不起来、拦不住」:供给侧(.osplugin 格式、os plugin build/sign/publish、云端审核与反签、安装时授权同意)完整;需求侧从 §3.5 第 4 步起不存在——没有 os plugin install、没有 .osplugin 加载器、云端没有 blob 下载路由、授权集只登记不拦截(pin test 钉着)、信任层 T0/T1/T2 只是枚举。本专题按你同意的席位倾向分四期(M0–M3),每期立子卡;M0 先改记录,再按 v2 开工。
The decisions this epic carries (the maintainer's 「同意」 to the seat's inclinations, 2026-10-28)
| # | Question | Decision |
|---|---|---|
| Q1 first consumer | who does the next phase close the loop for | first-party drivers / connectors (T0, self-signed); the cloud plugins/connector-stripe sample is the acceptance case; third parties wait for M3 |
| Q2 local-first | local install before cloud fetch | local first (os plugin install ./x.osplugin, ADR-0016 §9 parity); the cloud blob download route follows in M2 |
| Q3 trust tier | which tiers in M1 | T0 only (node, first-party / verified), with the tier dispatch point left in the loader for T1 in M3 |
| Q4 enforcement | per-plugin SecurePluginContext |
M2, before any third-party load; services + hooks are enforced; the fs / network classes keep their schema and get their enforce-or-remove decision in M3 (no production call surface today) |
| Q5 registry | sys_plugin* vs sys_package* |
accept the fold into sys_package*; v2 rewrites §3.8 |
| Q6 dependencies | manifest-deps | drop it; bundled only (ADR-0049 enforce-or-remove; build-side half with zero installers) |
| Q7 §3.10 #4 / #5 | RLS-scoped grants, secret-refs | secret-refs only, when the first real connector needs them (M3); RLS-scoped grants stay a design note |
| Q8 §7 open questions | key rotation, widening UX, hot vs boot, T2 RPC, dependency conflicts | widening UX = the shipped 409 re-consent, not activated before consent; hot reload retired with #12587 → boot activation; key rotation, T2 RPC and dependency conflicts deferred to M3 |
Milestones (each a child card; Blocked-by: chains as listed)
- M0 — ADR-0025 v2 (
docs/adr/**, Tier H, one PR). Rewrite the four stale sections (§3.8 registry →sys_package*; §3.4 endpoint/cloud/packages; §3.3 esbuild; §3.10 L1 = script bodies + QuickJS, already live), fold Q1–Q8 in, split §3.5 steps 4–7 into dispatchable sub-steps, and set the status line: Accepted — narrowed to Phase 1 + consent + the M0–M3 plan. Authoring is open to every seat; the director seat drafts it unless triage routes otherwise. - M1 — local T0 install loop (
Blocked-by:M0). (a)os plugin install ./x.osplugin: whole-artifact Ed25519 verification against the host's trusted keys (verifyPluginArtifact, today 0 callers) + per-fileintegrityre-verification at unpack, materialize to<OS_HOME>/plugins/<env>/<id>/<version>/, write the installation record,--trust-unsigneddev override; (b) the loader: scan installed plugins at boot, dynamic-importdist/index.mjs, reuseplugin-loader.tsdependency ordering, tier dispatch point (T0 only), disable/uninstall through the package disable-state store; (c) Stripe sample as the e2e acceptance; (d) delete the "NOT RE-VERIFIED AT UNPACK" / "noos plugin install" self-descriptions the code carries today. Lanes:cli,server. ⛔ M1 is first-party / self-signed only and is not listed in any marketplace surface. - M2 — cloud fetch + enforcement (
Blocked-by:M1). (a) cloudGET …/artifactserves the.ospluginblob with publisher + platform signatures;os plugin install <id>@<version>walks resolve → compat → consent → download; (b) per-pluginSecurePluginContextscoped to the granted set for services and hooks (PluginContextwrap at §3.5 step 7), deletegranted-permissions-not-enforced.pin.test.tsand thePluginDisclosure.tsx:148sentence in the same PR. Lanes:cloud,server. - M3 — third-party tier (
Blocked-by:M2). T1 dispatch to QuickJS forruntime:'sandbox'; publish-side secret / vulnerability scan; secret-refs to the settings/KV store; thefs/networkenforce-or-remove decision; key rotation, T2 RPC and dependency-conflict answers. Lanes:cloud,server,spec.
Risks the children inherit
- M1's T0 is "author code in the host process": hard-limited to first-party / self-signed; written into v2 as a ⛔.
- Every landed step deletes its matching "NOT ENFORCED" / "not verified" self-description and pin; leaving one makes the gates red and the record false.
- Scope: UI plugins (ADR-0026, Deferred) and the declarative connector sub-path (ADR-0023/0024) stay out;
.ospluginserves plugins that need npm dependencies or host APIs.
Done-when
- M0 v2 merged; ADR-0025's status line reads Accepted (narrowed) with the M1–M3 plan.
- M1: a self-signed
.osplugininstalls locally, loads at boot, runs the Stripe sample end to end, disables cleanly. - M2: the same plugin installs from the cloud registry and a denied service/hook call is refused and logged.
- M3: an unverified publisher's
runtime:'sandbox'plugin runs under QuickJS; the pin tests and self-descriptions listed above are gone.
Related
ADR-0025 (record), ADR-0019 §Out-of-scope (the "load-bearing wall"), ADR-0016 §9 (local-first), ADR-0049 (enforce-or-remove), #26553 (ADR batch 4 ruling), #17757 (closed design card), #13457 (F4 registration), cloud plugins/connector-stripe.
Activity
objectstack-fleet commentedon Oct 28, 2026
Children · director seat · 2026-10-28T06:02Z
docs/adr/**, Tier H;pm:queue, p1; the director seat drafts the PR unless triage routes it).Blocked-by:chain M1 → M2 → M3 as the body lists).Ruling of record: objectstack#26553 comment 6461953053 (ADR-0025 → A narrowed + this programme). ⛔ Not a claim.
objectstack-fleet commentedon Oct 28, 2026
M0 landed · director seat · 2026-10-28T06:58Z
PR #27118 (ADR-0025 v2) merged 2026-10-28T06:56Z (main
07d18e6927); #27110 closedcompleted. The record now carries the Q1–Q8 decisions in §4, the §3.5 M1/M2 split, the §3.6/§3.7 phasing and the §7 answers, so the M1–M3 children can be written against it. The director seat files M1 (local T0 install loop,cli+server), M2 (cloud fetch + enforcement,cloud+server) and M3 (third-party tier) next, eachBlocked-by:its predecessor andPart of #27108; triage grades and sets each lane. ⛔ Not a claim.objectstack-fleet commentedon Oct 28, 2026
Children filed · director seat · 2026-10-28T07:01Z
07d18e6927).cli+server;pm:queuep1).Blocked-by: #27123;pm:queuep1).Blocked-by: #27124;pm:queuep1).Triage grades each child, sets its lane(s) and may split by lane. ⛔ Not a claim.
objectstack-fleet commentedon Oct 28, 2026
Ruling · four additions to this epic · 2026-10-28T14:31Z
Maintainer rulings (objectstack session
session_01J8VVAjRKqdoEYQ4hXxtBuf, 2026-10-28, verbatim, not translated), reached in the session thread after the seat put the four open items to the maintainer directly: 「插件应该支持从应用市场安装才是合理的」 · 「代码插件要到下次启动才加载,这个问题也要解决」 · 「好,把热加载和依赖策略并进清单」 · on the four-item table below, 「同意」. ⛔ Not a claim; the epic PM integrates these into the milestone chain. The children M4 / M5 / the SDK-contract card are filed by this seat on these rulings and name this comment.manage_platform_settings, listsartifact_kind: 'plugin'versions and installs them through the M2 path.PluginContextsubset), a conformance testkit, the peer-dependency build check;objectstack-ai/pluginsas the first-party home, the narrowed DingTalk plugin (per-user push channel + user mapping, sign-in via an identity broker) as its first resident.group/isolatedenvironments (the cloud console's own) install no plugin from the shelf; only an environment with a dedicated runtime does. Same shape as the credential ruling on #27230 (S1).Dependency policy (no new decision; acceptance additions). Q6 stands (bundled only; native addons refused in M1). M3's publish-side scan owes three more checks, to be written into the M3 card when it is filed: an SBOM emitted by
os plugin buildand stored on the version; a licence allowlist refusing copyleft dependencies at publish (bundling is redistribution); an artifact size cap. Plugins are also told, in the author handbook, to prefer the platform'sfetch/cryptoover vendor SDKs.Chain after these: M0 ✅ → M1 #27123 (in flight) → M2 #27124 → SDK contract (new) → M3 (to file) → M4 shelf (new) → M5 hot attach (new).
Generated by Claude Code
objectstack-fleet commentedon Oct 28, 2026
Cross-reference · sibling epic #27293 · 2026-10-28T14:52Z
#27293 「Marketplace and connector auto-shelf」 is the second epic the maintainer agreed to today (「是否建议立专题卡统一处理。」 → 「同意」, session
session_01J8VVAjRKqdoEYQ4hXxtBuf). Division of labour: this epic is code plugins (install, load, enforce, shelf, hot attach); #27293 is zero-code integrations (openapi/mcp hardening #26709, outbound OAuth #26702, request signing #26710, administrator credentials #27237 / #27238, author recipes #27223 and handbook #27240, the first shelf of connector apps). Two touch points, each named on both epics: code-bearing integrations (DingTalk per-user push, WeCom, Feishu) go through #27287's SDK contract here, not there; M4's shelf and E4 share the listingpackageTypeenum change — whichever lands first adds both values. ⛔ Not a claim.Generated by Claude Code
objectstack-fleet commentedon Oct 28, 2026
Ruling · #27108 after the bridges decision · 2026-10-28T16:22Z
Maintainer rulings (cloud project thread, 2026-10-28, verbatim, not translated): on the decision card 「插件专题 #27108 在中转方案之后怎么处理?」 the maintainer chose 「M1 做完,其余冻结」 (16:18Z), after choosing bridges over vendor plugins for DingTalk / WeCom / Feishu (16:10Z–16:16Z thread, epic #27314). ⛔ Not a claim.
plugin-dingtalkis not the first resident of an external plugins repository. DingTalk, WeCom and Feishu go through bridges (objectstack-ai/bridges, epic #27314).M1 note for slice 2: its acceptance names cloud
plugins/connector-stripe, which is closed-source in the private cloud repository (README.md:8,package.json"license": "UNLICENSED"), so objectstack CI cannot build it. Use an open fixture plugin for the objectstack e2e; the Stripe e2e runs in cloud CI after the pin carries M1.M1 note for slice 2 (Docker-deployed Enterprise): the EE image declares
VOLUME ["/data"]withOS_HOME=/data(cloudapps/objectos-ee/Dockerfile:565-585), so a plugin installed at image build time into<OS_HOME>/plugins/is hidden once the volume mounts. Customers who bake plugins into a derived image (FROM objectos-ee:x, Kubernetes, immutable deploys) need the loader to also scan a read-only plugin directory outsideOS_HOME(e.g.OS_PLUGINS_DIR), with the same signature re-verification at boot. Runtime install into the/datavolume (docker compose exec app os plugin install …, then restart) works as designed.Generated by Claude Code