Skip to content

ADR-0025 SDK contract — the three public seams external plugins build on (messaging channel provider, identity-object writes, PluginContext subset), a conformance testkit, the peer-dependency build check, and the objectstack-ai/plugins repository #27287

Open

Description

@objectstack-fleet

Part of #27108 (between M2 and M3). Blocked-by: #27123

Filing gate ③ (maintainer ruling). Ruled on #27108 (the ruling comment of 2026-10-28 by session_01J8VVAjRKqdoEYQ4hXxtBuf, item 3): the maintainer's 「是否建议剩下的非标准协议的都由第三方插件仓库维护。发布为平台插件。」 and 「同意」 on the seat's answer (external repository, conditional on a public SDK contract first). ⛔ Not a claim. ⛔ No domain:*: packages/spec (contract types), packages/core / services (seams), packages/cli (build check), plus a new repository; triage sets lanes.

维护者速读

外仓插件能活的前提是它只碰公开、版本化的接缝。本卡把三个接缝定成公开 SDK:messaging 的通道提供者(registerChannelProvider,email 通道为参照)、身份对象写入(通讯录同步经数据服务写 sys_user / 业务单元 / 岗位,按 SCIM"外部目录为真源"的语义)、PluginContext 的公开子集;配一个一致性测试包(起最小内核、装插件、断言接缝行为)和构建检查(@objectstack/* 外置为 peer dependency、拒原生模块——M1 已加、SBOM 与许可证白名单——M3 验收)。然后建 objectstack-ai/plugins 仓:仓模板、每夜对平台 next 金丝雀、第一个住户是钉钉收窄版(按人推送通道 + 用户映射;登录走身份代理,免登等"外部身份建会话"API 另裁)。不公开的接缝:任何创建登录会话的路径(人工地板),等单独裁决。

What lands

  1. @objectstack/plugin-sdk (or the equivalent export surface in @objectstack/core / @objectstack/spec): the three seams as typed, versioned contracts with a compatibility statement per minor; everything else on PluginContext is explicitly internal.
  2. @objectstack/plugin-testkit: boots a minimal kernel with the messaging and data services, installs a plugin under test, asserts channel registration, identity writes under the operator gate, and that the plugin touches no internal API (a lint over its imports).
  3. Build check in os plugin build: @objectstack/* externalized as peer deps, refusal otherwise; the native-addon refusal from M1 reused.
  4. The objectstack-ai/plugins repository: template (AGENTS.md, CI against platform next, testkit wiring, changesets), one package plugin-dingtalk scoped to a per-user push channel provider and a sys_user ↔ dingtalk userId mapping object, with the sign-in and in-app silent login explicitly out (identity broker route documented).
  5. Docs: the plugin author handbook section "what you may depend on".

Acceptance

  • plugin-dingtalk builds in the external repository with the testkit green, installs through M1/M2 on a dedicated-runtime environment, and delivers an approval notification to a mapped DingTalk user with a deep link back to the record.
  • A plugin importing an internal path fails the testkit lint with the public alternative named.

Related

#27108 (epic, ruling item 3) · #27123 (M1) · #27124 (M2) · ADR-0025 v2 §3.3 / §3.10 #2 · ADR-0022 (channels) · ADR-0029 D1 · #27230 (credential S1, same posture rule).


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: 可对外的 API | none | P④

    Triage: p1 · domain:cloud · area:devpath · parked for the cloud PM · 2026-10-28T15:06Z

    ⛔ Not a claim.


    Generated by Claude Code

  2. added
    area:devpathThe road — create, dev, verify, publish/install, connect an agent, iterate
    domain:cloudTouches cloud: the whole card is the cloud PM's (repo:cloud seat); no objectstack lane claims it
    priority:p1High: required for production / M2
    status:parkedParked — exempt from the PM sweep and half-state patrol until its owner migrates it (e.g. cloud PM)
    on Oct 28, 2026
  3. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    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.

  4. added
    pm:queueReady for the PM dispatch loop
    repo:cloudCard routed whole to the cloud PM: needs cloud code, a producer or a fact (cloud owns it to closure)
    and removed
    status:parkedParked — exempt from the PM sweep and half-state patrol until its owner migrates it (e.g. cloud PM)
    on Nov 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratedomain:cloudTouches cloud: the whole card is the cloud PM's (repo:cloud seat); no objectstack lane claims itenhancementNew feature or requestpm:queueReady for the PM dispatch looppriority:p1High: required for production / M2repo:cloudCard routed whole to the cloud PM: needs cloud code, a producer or a fact (cloud owns it to closure)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions