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
flowchart LR
A["用户在 jtype Card 上表达工作"] --> B["触发预览或外部事件受理"]
B --> C["记录 trigger receipt 与 provenance"]
C --> D["Cloud Run 执行并产生可见状态"]
D --> E["结果写回 Card / PR"]
D --> F["Usage 归集到 Run、Automation 与 Card"]
E --> G["用户复核、继续推进或人工处理失败"]
F --> G
Loading
Feature Loop 1:Kanban 触发事实与执行回执
Service Kanban 继续采用“一个 board 最多绑定一个 Service”的当前合同。Card
进入触发列表示把工作交给该 Service 的 Cloud Agent 执行,不表示把 jtype
Card assignee 改成某个 Agent。
产品先保证“动作之后有诚实回执”,再增加依赖组件合同的阻塞式确认:
Service Kanban 顶部明确展示触发列、Service、repository、模型和结果写回
位置;用户在拖卡前就能理解执行策略;
22 · jtype Card ↔ Agent Run 协作闭环 PRD
状态:Approved implementation contract,已完成 Kimi CLI / Grok CLI 两轮独立评审、交叉质询与最终一致性检查
关联合同:
docs/design/plugin-platform.md:Project Plugin、Service Kanban 与 Automation 合同docs/15-project-workspace-architecture.md:Project / Service 工作区信息架构docs/16-repository-navigation-and-pr-automation.md:Run 来源、幂等与 PR Automationdocs/17-jcode-device-relay.md:Device Relay 与 E2EE 边界docs/21-github-native-code-review.md:GitHub 原生 Review 与 Bot 写回Executive summary
jcode Cloud 已经拥有两个互补的产品平面:
现有闭环已经能把 Card 移入 Service 的触发列、创建
origin=kanban的 Run,并在终态把结果评论和可选完成列写回 Card。当前缺口不是“没有
Issue”,而是用户还不能在一个连续体验里可靠回答:
本 PRD 用四个可独立交付的 Feature Loop 补齐这些问题。交付顺序以事实源
优先:先建立 Kanban occurrence/receipt,再建立 provenance 投影,随后才是
Automation ledger 和 Usage。它不在 jcloud 内部复制 Issue/Comment 系统,
也不把 jtype Card assignee 伪装成 Cloud Agent 路由。
Problem Statement
用户问题
项目成员把一张 jtype Card 拖入触发列时,操作看起来仍然只是普通看板
移动。Cloud 在后台轮询并创建 Run,但用户在动作发生前后缺少一个清晰的
执行承诺:目标 Service、模型、是否已经受理、被什么依赖阻塞,以及在哪
里继续观察。
Run 详情目前能显示
api、kanban、schedule、webhook或automation来源,但来源不等于身份。系统已经有triggered_by_user_id、Webhook 外部 actor、Automation owner、Pluginruntime identity 和 provider Bot;这些信息没有收敛为一个用户可读、且不
参与越权授权的 provenance 合同。当前产品使用的 Service Plugin Kanban
路径每个 tick 都做 level scan;durable event cursor 只存在于 legacy
kanban_links路径。因此产品路径无法保留精确 transition,也只能把jtype event 中的
editedBy当作无稳定 ID 的显示文本。Automation 页面只显示最后一次 Run 和最后错误。用户无法查看一次规则为
什么匹配、是否被去重或 supersede、产生了哪个 Run、写回是否完成。Cron
只能直接创建 Run,缺少“需要团队继续协作时先创建 jtype Card”的明确输出
选择;SCM Review、Kanban 和 Cron 的输出边界也没有在同一产品语言中解释。
LLM 请求已经统一经过控制面 Proxy,但 Proxy 尚未采集 usage。用户无法按
Run、Service、Automation 或 jtype Card 查看 tokens,也无法区分 provider
报告的费用、Cloud 估算费用和完全未定价的 usage。任何看似精确但来源不明
的金额都会破坏信任。
业务后果
第二套 Work Item 真相和身份语义。
Solution
产品承诺
权威对象映射
用户闭环
Feature Loop 1:Kanban 触发事实与执行回执
Service Kanban 继续采用“一个 board 最多绑定一个 Service”的当前合同。Card
进入触发列表示把工作交给该 Service 的 Cloud Agent 执行,不表示把 jtype
Card assignee 改成某个 Agent。
产品先保证“动作之后有诚实回执”,再增加依赖组件合同的阻塞式确认:
位置;用户在拖卡前就能理解执行策略;
为每次有效进入触发列建立一个 occurrence;
触发列时,复用 claim、创建新的 occurrence 与 Run;
时,不创建新的 occurrence;
外部 jtype 路径至少在 Card 上写入带稳定 occurrence marker 的评论;
责任人、用量摘要以及打开 Run 的深链;
writeback_pending,重试成功前不显示“已完成回写”;
对象显示为 deleted/unavailable,不伪造仍可打开的链接。
jtype-board-react当前支持注入saveDocument,但没有正式的beforeSave/cancelSave合同。首期不通过 Promise rejection 模拟“取消保存”,避免把用户取消渲染为错误。阻塞式拖卡确认只有在 board package 提供明确的
pre-save/cancel hook 后才进入产品合同;此前由策略预览、触发列标记和即时
receipt 建立信任。服务器的模型、Plugin、权限、Board 和列校验始终是最终
判断。
Feature Loop 2:Run Provenance 与 Bot 身份
在 Loop 1 的 claim、occurrence 和 receipt 事实源上,把现有的触发来源、用户、
外部 actor、Automation owner、Service、Plugin runtime identity 和写回身份
收敛为一个只读 provenance 投影。
用户首屏最多看到三个身份/来源槽位:
Kanban
editedBy只有显示文本、没有稳定 actor ID 时,显示 external actor,责任降级到规则 owner 并标明
rule_owner,不声称已映射 Cloud 用户;Cloud Runner/Device、完整 attribution precision 和技术 evidence 进入
inspector;GitHub App、Gitea/GitLab Bot 或 JType Plugin identity 只在
Written back as 区域显示。
授权与责任严格分离:
triggered_by_user_id继续表示直接的 Cloud 用户发起者,并可参与已有权限和 provider credential 选择;
accountable_user_id、external actor 和 attribution source 只用于显示、审计与 usage 归集,任何授权代码不得读取它们;
originator;系统不得伪造一个 owner 作为授权人;
credential revision 授权,不等同于 provider/JType 的展示用 Bot;
Feature Loop 3:Automation 运行历史与输出边界
Automation 详情增加统一的 execution ledger:
输出模式按 Trigger/Run kind 明确限制,而不是暴露任意笛卡尔积:
run_only;或在健康的 Service Kanban 中create_cardcreate_card先创建带 occurrence 关联的 jtype Card,再由正常 Kanbanclaim 路径创建 Run。Cron dispatcher 不同时创建直接 Run,避免双执行。
缺少健康 JType Plugin、Service Kanban、模型或目标列时,本次 occurrence
记录为 blocked 并给出修复动作,不回退为
run_only。Manual Run Now 使用幂等键;重复点击返回同一个 occurrence/Run。
SCM provider webhook 继续由 Cloud 管理,不新增通用匿名 Webhook URL,不提供
raw payload 回放。
Feature Loop 4:Usage 采集、归集与可信展示
控制面所有 Cloud Model Proxy 请求都经过同一个
proxyResolvedModel路径。首期在该共享路径上以透明 observer 方式采集 OpenAI-compatible JSON 和 SSE
响应中的 usage,而不是只覆盖 Run。observer 不得缓存完整响应、改变流式
时序或阻断上游成功响应。
首期记录:
reported | partial | unavailable | parse_error。subject 分为:
run:关联 Run、Project、Service,并可经 occurrence/claim 关联Automation 与 jtype Card;
device:仅限设备调用 Cloud Model Proxy 的路径,关联 Cloud user、device、model 与 grant scope,不伪造不存在的 Project/Service;
Cloud usage 统计。
金额规则:
Estimated。revision 包含 provider/model、input/output/cache 单价、币种
和生效时间;usage event 必须引用或快照实际采用的 revision;
Run-bound usage 的聚合维度:
Device Cloud Model Proxy usage 可按 user、device、model 和 grant scope
聚合,但不混入 Project/Automation 图表。Device Relay 的 prompt、response
和 envelope 继续是 E2EE opaque data,服务端不得解析设备命名空间密文。
原始 usage event 保留 90 天,UTC 小时聚合保留到所属 Project/User 删除后的
审计保留期结束;具体天数沿用集群数据保留策略。删除 Card、Model 或
Automation 不删除已有 usage/provenance snapshot。
Personas
User Stories
Card 与执行
身份、责任与 Bot
Automation
Usage
可访问性与恢复
Product Requirements
R1 · 一项工作只有一个 Work Item 真相
R2 · 一次执行只有一个 Run 真相
R3 · 触发可预期、重复可收敛
R4 · 身份可解释、授权不混淆
R5 · 自动化可运营
R6 · Usage 诚实
run与devicesubject 保持独立归集;UX Contract
信息优先级
Run/Card/Automation 表面统一使用:
执行目标、writeback、Usage、Runner/Bot、技术 ID、event key、credential
revision 和 parser detail 进入展开区或 inspector,不与核心状态争夺首屏。
文案
空态与错误态
$0.00。Implementation Decisions
Deep module 1:Kanban transition、occurrence 与 receipt
把“Card 是否从非触发状态进入触发状态、绑定是否健康、模型是否可解析、是否
已有 claim/active occurrence”收敛为一个服务。事件消费者、bootstrap scan、
Card preview 和测试共享它。
claim 是
(automation_id, document_id)的永久关联锚点,不再承担“一生只跑一次”的语义。occurrence 表示一次有效进入触发列,使用稳定 transition event
key 幂等。首次进入创建 claim + occurrence;离开再进入复用 claim 并创建新
occurrence。active occurrence、同事件 replay、仍在列内的正文编辑不创建新
occurrence。
Plugin Service Kanban 从 level scan 迁移到 durable board event cursor,以
保留
editedBy和精确 transition。保留一次性 level scan 只用于升级或新binding 的 bootstrap;bootstrap 归因必须标为 rule-owner/unattributed,
不能猜测最后编辑者。
每个 occurrence 在尝试创建 Run 前先持久化 receipt,并以带 occurrence marker
的幂等 Card comment 投影 accepted/blocked/failed。comment 写入重试不得产生
重复可见回执。Card 删除把 external ref 标记为 unavailable,不删除事实。
jtype-board-react在正式提供 pre-save/cancel hook 后,可以在不破坏baseContentHash/baseContent乐观并发的前提下增加阻塞式确认;该能力不是前四个 Loop 的依赖。
Deep module 2:Run provenance resolver
新增一个独立 resolver,从 Run、Automation、Webhook receipt、Kanban
claim/occurrence/event、Project member 和 Plugin snapshot 生成稳定的
RunProvenance投影。HTTP handler、Card execution panel、Automation ledger和 usage aggregator 都消费同一投影,不各自复制归因瀑布。
投影至少包含:
exact | linked_external | rule_owner | unattributed。jtype
editedBy当前只有显示文本、没有稳定 actor id。它只能生成linked_external/unattributed显示快照;accountable 降级到冻结的 ruleowner。除非未来 JType 合同提供稳定 actor ref,否则不得把同名文本映射成
Cloud 用户。
Deep module 3:Automation execution ledger
用一个统一查询模型组合 Automation、occurrence/receipt、Run、output ref 和
writeback status。SCM receipt、Cron occurrence 与 Kanban claim 可以保留
各自存储,但 API 投影必须一致。
Manual trigger 接受 caller 生成的 idempotency key;
(automation_id, key)至少保留 24 小时并返回相同 occurrence/Run,occurrence 本身永久保留。
Cron occurrence key 是
(automation_id, scheduled_fire_at)。Cron
create_card用 occurrence id 派生确定性 Card path,通过现有 JTypeSaveDocument创建 Card;进程若在远端创建成功、绑定落库前崩溃,恢复流程先按 path 解析同一 Card,不能再创建第二张。occurrence 绑定 Card document
id 后,再由正常 Kanban claim/occurrence 路径创建 Run;Cron dispatcher 不
直接创建第二个 Run。恢复时若该 path 对应的 Card 已删除或不可访问,本次
occurrence 标记为 blocked,不能用同一路径重建一个看似相同的新 Work Item。
Deep module 4:Usage observer
共享
proxyResolvedModel上的 observer 支持非流式 JSON 与 SSE 的最终 usagechunk。它使用有界 parser 状态,不保留完整响应;记录失败时只存错误类别。
每个上游请求产生稳定 request id,重复完成回调不会重复累计。observer 按调用
上下文写入且只写入一个 primary subject:
run或device。一个请求即使经过设备代理也不能同时计入两类;有 Run context 时以
run为主,避免 tokens与费用双计。本地模型与 Device Relay envelope 不进入该路径。
Usage 原始事件 append-only;修正通过显式 replacement/version 处理,不对旧
数值做无来源累加。Estimated cost 关联不可变 pricing revision。聚合使用 UTC
小时桶,查看者时区只在查询时切分日期;raw event 保留 90 天,rollup 按集群
数据保留策略清理。
API contract
首期增加或扩展:
provenance与usage_summary;occurrences、receipts、Runs、writeback 和 usage;
external writeback 状态;
所有列表分页且有固定排序。错误继续使用现有 typed error envelope。API 不返回
Plugin token、provider secret、raw webhook body、LLM body 或 device envelope
明文。
Schema contract
迁移保持 append-only、idempotent。需要的逻辑实体:
snapshot;
run | devicesubject usage event;外部 actor 使用 provider + stable external id;display name 是快照。删除 Cloud
用户不删除历史 provenance。现有
triggered_by_user_id保持授权语义,不通过重命名迁移改变含义。
Authorization
Acceptance Criteria
AC1 · Kanban
output 和当前 blocker;
accepted 或 blocked receipt;
打开 Cloud 才能判断是否受理;
重复 occurrence/Run/评论;
并创建新的 occurrence/Run;
unavailable;
AC2 · Provenance
editedBy不按姓名猜测 Cloud 用户;AC3 · Automation
SaveDocument成功、Card binding 落库前崩溃,恢复后仍解析同一deterministic Card path;
面向用户的通用 Automation 列表;
AC4 · Usage
run或devicesubject;Testing Decisions
测试原则
模块测试
active occurrence、board drift 和 model gate;
binding disabled;
run/device subject;
uncosted、Card/Automation/device 聚合;
端到端测试
每个 Feature Loop 至少增加一条可独立运行的旅程:
交付验证
go test ./...;pnpm test && pnpm typecheck;zero-plaintext journey;
确认缺陷修正后再运行最终测试。
Delivery Loops and Commit Boundaries
Loop 0 · PRD
ready-for-agent;docs(product): define card-to-run collaboration contract。Loop 1 · Kanban 触发事实与执行回执
executions panel;
Loop 2 · Provenance 与 Bot 身份
Loop 3 · Automation ledger 与输出
Loop 4 · Usage
每个 Loop 都必须完成自己的设计、UI、实现、评审和测试,不能把评审或测试
统一推迟到最后。跨 Loop 的重构只有在当前 Loop 有直接产品收益时才进入该
提交。
Out of Scope
jtype-board-react提供正式 pre-save/cancel hook 前,用 rejected Promise模拟阻塞式拖卡确认;
kanban_links重新暴露为新的产品配置面;迁移期只做兼容读取;durable comment-trigger + Cloud identity contract;需要先修改 jtype 合同;
skip|queue|replace通用并发策略。Further Notes
与 Multica 的取舍
直接借鉴:
不照搬:
成功指标
首期不以“创建了多少 Automation”作为成功。关注:
发布前最后审计
批准本 PRD 前,评审必须逐项确认:
Review decision record
cursor、Kanban 回执必须先于身份 UI、board package 不支持可取消保存、
Usage 必须与 E2EE Relay 分界;
SaveDocument可支持create_card,claim 与可重复 occurrence 必须分离,
editedBy不足以建立 Cloud 身份;runtime principal 与 Bot 分离、Usage primary subject 防双计、已删除
deterministic Card 不自动重建。