Repository navigation
Description
Package: @objectstack/spec (packages/spec/src/integration/connector-descriptor.ts)
Found while wiring #4354's per-run summaries into connector_action.
The gap
ConnectorActionDescriptor describes an action's shape and nothing about its effect:
export interface ConnectorActionDescriptor {
readonly key: string;
readonly label: string;
readonly description?: string;
readonly inputSchema?: Record<string, unknown>;
readonly outputSchema?: Record<string, unknown>;
}So crm.push_opportunity and crm.lookup_account are indistinguishable to the runtime. Nothing in the authorable Connector schema fills this in either — registerConnector reads actions for dispatch only.
Why it matters now
#4354 makes every flow run report selected / acted, and selected > 0 AND acted = 0 over consecutive runs is the broken-sweep alert. For a connector_action the platform has to pick one of three answers, and two of them are wrong:
acted: 0understates a Salesforce create. Every healthy connector-driven sweep then trips the alert, and operators learn to ignore it — which disables the detector for the flows that really are dead.acted: 1overstates a lookup. A sweep whose only "action" is a connector read then looks busy forever, so the alert never fires. That is Surface flow run summaries (selected / acted / skipped) — a scheduled flow that does nothing is currently indistinguishable from one with nothing to do #4354's original bug restored, one layer out.- unknown is the honest one, and it is what shipped: the executor reports
metrics: { unmeasuredEffect: true }, the run summary carries anunmeasuredtally, and the documented alert becameselected > 0 AND acted = 0 AND unmeasured = 0.
That is correct but weaker than it needs to be. A connector-driven flow currently contributes no signal at all: it can neither confirm work happened nor be flagged for doing none. Every ObjectStack app whose automation runs through connectors is in that blind spot.
Proposal
Let the action declare its effect, and let the runtime count it:
export interface ConnectorActionDescriptor {
readonly key: string;
readonly label: string;
readonly description?: string;
readonly inputSchema?: Record<string, unknown>;
readonly outputSchema?: Record<string, unknown>;
/**
* What the action does upstream. `read` never mutates; `write` does.
* Absent keeps today's behaviour — the run reports the effect as uncountable.
*/
readonly effect?: 'read' | 'write';
}Then connector_action reports acted: 1 for a successful write, acted: 0 for a read, and falls back to unmeasuredEffect only when the connector declared nothing. Optional on purpose: existing connectors keep working and lose nothing, and declaring it is a strict improvement rather than a migration.
Worth considering alongside it: a count rather than a boolean, for bulk actions that report how many upstream records they touched (outputSchema often already carries one). That can follow — the read/write split is the part that unblocks the alert.
Note the ADR-0076 D12 angle: this is a machine-readable surface that is currently silent rather than wrong, which is the right failure. The proposal is to let it be accurate.
Related: #4354 (the summaries this feeds), #4347 (the silent-failure class both exist to surface).
Activity
feat(spec,service-automation): a run says when its `acted` count is i…
os-zhuang commentedon Aug 3, 2026
裁决(PM 代决,维护者可否决):按提案落地 ——
ConnectorActionDescriptor增加可选effect?: 'read' | 'write':声明write→acted:1,声明read→acted:0,不声明 → 维持unmeasuredEffect: true现状。两轴理由:
acted:0/1两个都错的答案里瞎选(一个制造误报让操作员学会忽略告警,一个让告警永不触发)。count 型效果(bulk 场景)暂不做,待真实需求。已入队待派。
Generated by Claude Code
os-zhuang commentedon Aug 6, 2026
分诊级别建议:给 ConnectorActionDescriptor 增加 reads/writes 声明面是新契约词表,创业阶段聚焦原则下需要真实业务拉动佐证与维护者拍板——建议摘
pm:queue换needs-user-decision进决策箱。交分诊座位定夺。背景:维护者 2026-08-06 拍板 spec 车道缩盘方案,见 #5837。Generated by Claude Code
os-zhuang commentedon Aug 6, 2026
标签落实(维护者 2026-08-06 指示,session_01LeEfA7CFwbJb7JJmXm2KM3):按 08-06 降级建议执行
pm:queue→needs-user-decision——ConnectorActionDescriptor 增加 reads/writes 声明面属新契约词表,创业阶段聚焦原则下需真实业务拉动佐证与拍板。Generated by Claude Code
claude commentedon Aug 7, 2026
队列管家通知:本单的 PR #6160 于
06:20:22Z被移出合并队列 —— 新签名,⛔ 未重投。签名:
ESLintjob 的 step 34Spec type-alias convention gate (ADR-0122):判读:时序碰撞,不是回归。 该门禁由 #6072(ADR-0122 第一期防回流门)引入、05:35Z 才落地,而本 PR 分支上的
ConnectorActionEffect写在那之前 ⇒ 本 PR 是新门禁上线后第一批撞上它的新增类型。需要一处代码改动(⛔ 不在队列管家授权面):加一行
export type ConnectorActionEffectParsed = z.infer<typeof ConnectorActionEffectSchema>;,或(若z.input/z.infer同型)在type-alias-convention.pin.test.ts钉住。完整签名、日志归档与门禁原文处方见 PR #6160 上的拦截评论。Generated by Claude Code
test(spec): security, ai, identity, integration, migrations, marketpl…