Skip to content

RFC: unify the Rust-TypeScript protocol contract and require complete tool policies #388

Description

@NianJiuZst

Status and contribution coordination

This is a draft design proposal for discussion, not an agreed implementation direction. The final scope, architecture, compatibility policy, and rollout should be decided with the maintainers. The associated Draft PR #389 lets us evaluate the proposal against concrete code; that prototype does not imply that the design is approved or ready to merge.

This issue is not open for implementation PRs from other contributors. Please do not submit a PR for this issue. I am maintaining the associated draft implementation while the direction is being discussed. Comments, counterexamples, and design feedback are welcome.

Why bring this up?

While tracing the CLI → daemon → extension dispatch path, I found that changing one tool's contract or behavior requires keeping several independent descriptions in sync:

  • Rust protocol structs/enums and the RPC method list.
  • Handwritten TypeScript payload types and some tool-local copies.
  • The schema export list.
  • Extension dispatch, browser-control/background-targeting/popup/remote-support classifications.
  • Daemon deadline, cancellation, and outcome-handling classifications.

Some of those rules appropriately belong to different components, but the shared facts have no single enforced source. A contributor can update one description and miss another while the individual components still appear valid.

There is a concrete drift example at the inspected main revision: Rust includes ErrorCode::UserAborted, while the handwritten TypeScript ErrorCode union omits user_aborted. Also, a TypeScript assertion such as JSON.parse(...) as ProtocolFrame does not validate the JSON received over the connection.

Source context at 3f10983c09fcd443c7420830ab984c9d409954bf:

Direction to discuss

  1. Make the Rust payload types and a method catalog authoritative for shared wire facts: method name, execution owner, browser effect, parameter type, and result type.
  2. Export schemas from those definitions and generate TypeScript types, method mappings, and browser-compatible runtime validators. Distinguish accepted input from serialized output, including defaults and optional/null handling.
  3. Require every extension-owned method to have a typed handler and an explicit extension execution policy. Require the daemon's scheduling policy to exhaustively cover its method enum.
  4. Keep component-specific decisions with their owners. Browser targeting and remote support remain extension concerns; deadlines and settlement remain daemon concerns. Shared effect classifications should come from the catalog.
  5. Add a reproducible generation command and a CI check that fails when generated files differ from the current Rust source.

What would improve?

  • Protocol fields and enum members would be maintained once instead of copied between Rust and TypeScript.
  • Adding a method would produce actionable compile errors for missing handlers or policies.
  • Invalid wire payloads could be rejected at the boundary instead of being trusted because of a type assertion.
  • Reviewers could separate a protocol change from generated output and from the deliberate behavior choices for each component.
  • Future tool additions would have a clearer, repeatable maintenance workflow.

These checks would establish synchronization and completeness, not prove that a handler performs the correct browser action or that a policy choice is semantically correct.

Questions for maintainer discussion

  • Is Rust the preferred long-term source for the shared protocol, and is the proposed catalog the right abstraction?
  • Should generation use JSON Schema/Schemars, another generator, or a different intermediate representation?
  • Which compatibility guarantees should runtime validation preserve for older peers, especially defaults, nulls, unknown fields, and result envelopes?
  • Is the proposed division between shared metadata and component-local policy appropriate?
  • Should this land in stages? In particular, an evaluation timeout/cancel acknowledgement does not establish that page JavaScript has stopped; should settlement handling be part of the policy work or a separate follow-up?
  • What browser/platform evidence and generated-code review conventions should be required before leaving Draft?

No protocol-version or rollout decision is implied by this issue.


状态与贡献协调

这是供讨论的设计草案,尚未确定最终实现方向。 最终范围、架构、兼容策略和落地方式,需要与维护者讨论决定。关联的 Draft PR #389 提供具体代码,帮助评估方案;已有原型不代表设计已经获准,也不代表可以直接合并。

本 issue 不开放给其他贡献者提交实现 PR,请不要针对本 issue 提交 PR。 讨论期间由我维护关联的草案实现。欢迎通过评论补充反例、提出问题和讨论设计。

为什么会想做这件事?

阅读 CLI → daemon → extension 的调用链时,我发现修改一个工具的协议或行为,需要同时维护多处相互独立的描述:

  • Rust 协议结构体、枚举和 RPC 方法列表。
  • 手写的 TypeScript 参数、结果类型,以及部分工具内部的重复定义。
  • Schema 导出列表。
  • 扩展中的处理函数,以及浏览器控制、后台标签页选择、弹窗跟踪、远程支持等分类。
  • Daemon 中的超时、取消与执行结果处理分类。

其中一些规则确实应该分属不同组件,但共享事实缺少统一且强制执行的来源。贡献者可能只更新其中几处,遗漏另一处,而单个组件看起来仍然没有问题。

在本次检查的 main 版本中,已经存在一个具体的不一致:Rust 定义了 ErrorCode::UserAborted,而手写的 TypeScript ErrorCode 联合类型遗漏了 user_aborted。此外,JSON.parse(...) as ProtocolFrame 这样的类型断言不会检查连接中实际收到的 JSON。

对应源码版本为 3f10983c09fcd443c7420830ab984c9d409954bf:

希望讨论的方向

  1. 以 Rust 参数/结果类型和方法目录作为共享协议信息的权威来源,统一描述方法名、执行归属、浏览器影响类别、参数类型和结果类型。
  2. 从这些定义导出 Schema,再生成 TypeScript 类型、方法映射和浏览器可用的运行时校验器。区分接收参数与发送结果的规则,明确默认值、可选字段和 null 的处理。
  3. 要求每个由扩展执行的方法都具备类型匹配的处理函数和完整的扩展执行策略;要求 daemon 的调度策略穷尽覆盖方法枚举。
  4. 组件特有的决策继续由各自负责:浏览器目标选择、远程支持由扩展维护,超时和操作结束确认由 daemon 维护;共享的影响类别从目录获取。
  5. 提供可重复执行的生成命令,并通过 CI 检查生成结果是否与当前 Rust 源码一致。

做成之后有什么好处?

  • 协议字段和枚举成员只维护一份,减少 Rust 与 TypeScript 之间的重复抄写。
  • 增加方法时,遗漏处理函数或策略会变成明确的编译错误。
  • 不符合协议的数据可以在接收边界被拒绝,避免仅凭类型断言就信任数据。
  • 评审时可以区分协议定义、生成结果,以及各组件经过主动选择的行为策略。
  • 后续增加工具时,有更清楚、可重复的维护流程。

这些检查能够保证同步与完整性,不能证明处理函数一定执行了正确的浏览器动作,也不能代替对策略语义的判断。

需要与维护者讨论的问题

  • Rust 是否适合作为共享协议的长期权威来源,方法目录是否是合适的抽象?
  • 应采用 JSON Schema/Schemars、其他生成器,还是其他中间表示?
  • 运行时校验需要为旧版本保留哪些兼容行为,尤其是默认值、null、未知字段和返回结果封装?
  • 共享元数据与组件本地策略的划分是否合理?
  • 是否分阶段落地?特别是 evaluate 的超时或取消确认,并不能证明页面 JavaScript 已停止;对应的结束确认处理应包含在本次策略调整中,还是拆为后续改动?
  • 在结束 Draft 状态之前,需要哪些浏览器/平台验证,以及怎样的生成代码评审规则?

本 issue 不预先决定协议版本和发布策略。

Activity

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions