From 19e001222974106fc905ce0d4b118e21442b9f68 Mon Sep 17 00:00:00 2001 From: huangruiteng <14976749+huangruiteng@users.noreply.github.com> Date: Sat, 12 Sep 2026 12:55:35 +0800 Subject: [PATCH 1/3] docs: define layered human-confirmed domain operations Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com> --- docs/architecture/rfcs/README.md | 6 + .../human-confirmed-domain-operations-v0.md | 266 ++++++++++++++++++ 2 files changed, 272 insertions(+) create mode 100644 docs/architecture/rfcs/human-confirmed-domain-operations-v0.md diff --git a/docs/architecture/rfcs/README.md b/docs/architecture/rfcs/README.md index 783110d6f3..30d94bb7c9 100644 --- a/docs/architecture/rfcs/README.md +++ b/docs/architecture/rfcs/README.md @@ -48,6 +48,12 @@ changes. ## Control-Plane Kernel, State, And Migration +- [Human-confirmed domain operations v0](human-confirmed-domain-operations-v0.md) + - **RFC status:** Draft. + - **Delivery on `main`:** Proposal only. + - **Current boundary:** Separates generic authenticated interaction, optional + financial execution and venue adapters. Defines shared frontend/Lark + confirmation and automatic outcomes; no runtime or trading permission added. - [Agent Loop Effect Interpreter v0](agent-loop-effect-interpreter-v0.md) ([中文版](agent-loop-effect-interpreter-v0.zh-CN.md)) - **RFC status:** Accepted. diff --git a/docs/architecture/rfcs/human-confirmed-domain-operations-v0.md b/docs/architecture/rfcs/human-confirmed-domain-operations-v0.md new file mode 100644 index 0000000000..67cb00010e --- /dev/null +++ b/docs/architecture/rfcs/human-confirmed-domain-operations-v0.md @@ -0,0 +1,266 @@ +# RFC: Human-confirmed domain operations (v0) + +- **RFC status:** Draft +- **Delivery maturity:** Proposal +- **Authors / owners:** LoopX maintainers and optional domain-provider maintainers +- **Created:** 2026-09-12 +- **Last normative revision:** 2026-09-12 +- **Implementation baseline:** `72e557586` +- **Related contracts:** [Extensions](../../reference/extensions.md), + [Effect interpreter](agent-loop-effect-interpreter-v0.md) + +Sections 1–11 define the proposed contract, not shipped commands. Section 12 +records unresolved implementation choices. This document changes no runtime, +default permission, configuration or user entry point. + +## 1. Decision summary + +Use three semantic layers, without requiring three repositories: + +| Layer | Responsibility | Proposed code owner | +| --- | --- | --- | +| LoopX interaction | Authenticated human action, immutable request binding, execution claim, original-conversation return and shared presentation | Existing public typed-action, chat and Lark owners | +| Financial domain | Order intent, financial validation, aggregate exposure reservation, order/fill accounting and financial presentation | Optional public finance execution package | +| Venue adapter | Venue products, precision, account modes, API authentication, order submission and venue reconciliation | Independently installed Aqua/Hyperliquid, Futu or other adapter | + +Research methods remain in research providers. A strategy proposes an order; +it does not gain execution authority by passing a research gate. Enabling a +research capability must not install credentials or enable trading. + +The public finance execution package is a proposed sibling distribution under +`packages/`, not an addition to the existing value-discovery evaluator's +permissions. No new built-in finance capability or package name is registered +by this RFC. Implement the first real consumer before extracting a general +plugin framework. + +## 2. Problem and invariants + +An operator should receive an exact operation card, click once, and receive the +outcome in that conversation. “Forwarded to an agent” does not establish human +confirmation, execution, or a venue fill. + +Invariants: + +- Only the trusted interaction ingress can attest to the human click. An agent + cannot synthesize confirmation through tool arguments or model output. +- The confirmed digest binds all effect-bearing terms, their version, the + displayed projection, executor revision and destination account reference. +- Changing a material term creates a new request. Execution may select only + values explicitly permitted by the confirmed bounds. +- Delivery retries cannot submit operations. Submission ambiguity requires + reconciliation, not a fresh request or blind retry. +- Frontend and Lark read the same request and outcome projection. +- Core remains authoritative for Goal/Todo state; venue evidence remains + authoritative for orders and fills. Neither chat prose nor a local claim + proves a financial effect. + +## 3. Scope and non-goals + +First scope: one immutable, explicitly user-confirmed operation, one registered +executor, automatic receipt and terminal/ambiguous result delivery. Demonstrate +with a simulated financial adapter before real credentials are configured. + +This does not turn ordinary Goal steering into a confirmation workflow. Existing +persistent permissions for reading, coordination and reporting remain separate. +No arbitrary tool-name/kwargs execution, shell command in a card, global workflow +DAG, autonomous trading loop, transfer service or cross-venue portfolio engine. + +## 4. Audited current owners + +| Current code | Verified boundary | +| --- | --- | +| `loopx/chat_action_store.py` | Request digest, idempotency, state-checked proposals; built-in Goal/Todo actions only; `failed` is currently retryable | +| `loopx/chat_actions.py` | Validates and applies built-in actions; local API invocation does not prove a human financial confirmation | +| `loopx/extensions/lark/event_collector.py` | Collector currently selects `im.message.receive_v1`; text readiness is not card-callback readiness | +| `loopx/capabilities/manager_context/roundtrip.py` | Original-conversation return, receipt persistence and transport retry; context delegation is not transaction authority | +| `apps/presentation/dashboard/src/data/chat.ts` | Typed-action schema paired with existing chat action details and controls | +| `packages/loopx-finance-value-discovery/extension.toml` | Optional public research evaluator, permissions empty; research presentation surface, no execution contract | + +Reuse these owners through explicit typed extensions. Do not silently append a +financial `apply` case to a generic local HTTP endpoint, or inherit retryable +`failed` behavior for an unknown external submission. + +## 5. Architecture and single ownership + +### LoopX interaction layer + +Core owns the operation envelope: operation ID, schema version, domain/adapter +binding, immutable payload reference and digest, projection digest, expiry, +authorized audience, source session/message/request, verified confirmation +receipt, dispatch claim and outcome reference. Financial payload semantics are +opaque to Core; a hash is binding metadata, not a replacement for displayed +terms. + +Extend the typed-action owner rather than creating a second proposal database. +If its authority has migrated by implementation time, use that canonical owner; +do not introduce another Python authority beside it. Reuse envelope, identity +and journal primitives where their lifecycle fits. Goal quota/Todo admission +must never mint permission to execute a financial operation. + +Core validates the registered domain contract and invokes only an admitted +executor with a fixed operation kind and schema revision. Models may prepare +proposals and read receipts. The effectful entry point accepts a consumed, +server-issued confirmation receipt; no `confirmed: true` escape hatch. + +For Lark, prefer the existing bot transport with `card.action.trigger`. Verify +app/tenant provenance at the transport owner, then operator, chat, original +message, action, digest and expiry. For web, use authenticated owner identity +and origin/CSRF protection against the same authority. An opaque ID, loopback +address, forwarded card or matching display name alone is insufficient. + +### Financial domain layer + +The optional finance package owns the canonical financial payload and financial +outcome reducer. It does not own a competing confirmation ledger. Domain records +are keyed by the Core operation ID and immutable financial payload digest. + +Order terms include venue/product/asset identity, account reference, side, +quantity and units, order type, price bounds, time-in-force, reduce-only, +margin/leverage settings, fee caps and units, optional protective orders, +expiry and evidence time. Decimal quantities must preserve precision. + +Account-wide constraints require one reservation authority for all operations +using that account. Checking each card independently is insufficient: concurrent +confirmations could exceed the same remaining budget. The domain reserves +capacity atomically after a Core claim and before submission, accounts for +existing positions/open orders and rejects stale or incomplete account coverage. +Unknown submissions retain their reservation until reconciliation. A process +restart cannot reset the budget. External trades require refreshed account +observations; a local ledger cannot prevent activity through another client. + +Preflight checks financial invariants against fresh venue observations. If +precision adjustment, fees, account mode or other material terms would change +outside confirmed bounds, it rejects the operation and requests a new card. +It does not silently edit the confirmed payload. Quantities are not increased +to meet a venue minimum without a new confirmation. + +Domain outcomes distinguish accepted, resting, partial fill, full fill, +rejected, cancelled and unknown. Entry and protective orders have separate +results. Fees, funding, capital flows, rebates and PnL remain separate; missing +fee evidence is unknown, not zero. Research evidence can explain a proposed +order, but never substitutes for execution evidence. + +### Venue adapter layer + +Each adapter declares supported products/order types, minimums/precision, +fee semantics, account modes, authentication requirements, client-ID support +and reconciliation limits. It implements bounded discovery/read/preflight, +submission and reconciliation operations using the platform's official API or +SDK. It never performs a silent fallback to another venue or product. + +An Aqua-facing adapter must distinguish Aqua product/builder policy from the +underlying venue protocol; “Hyperliquid supports it” does not establish Aqua +terms, fee attribution or account initialization. A Futu adapter must distinguish +quote access from trading permission, security lot rules, trading sessions, +account region and OpenD unlock requirements. Sharing a normalized contract does +not make these products interchangeable. + +The adapter stores credentials in a separately configured private credential +facility. It returns normalized evidence plus bounded references to raw venue +receipts. It cannot change Core grants, user budgets or strategy decisions. +Withdrawals, deposits, key grants and leverage/account-mode changes are not +implicit side effects of an order adapter. + +## 6. Lifecycle and failure semantics + +Proposed interaction lifecycle: + +`prepared → awaiting_confirmation → claimed → outcome_observed` + +Cancellation and expiry may terminate an unclaimed request. After claim, Core +tracks dispatch and delivery separately from the domain's execution state. +The executor durably records a stable client order ID and attempt before network +submission. Timeout/crash after dispatch yields `submission_unknown`; reconcile +that original ID before any further effect. A local lock cannot promise exactly +one venue fill. If the venue cannot resolve ambiguity, retain unknown and report +it automatically. + +The receipt contains operation ID, domain/adapter revision, confirmed digest, +attempt/client/venue IDs, evidence time, coverage and normalized outcome. The +frontend and Lark consume one versioned projection; they do not independently +recompute fill state. Intermediate updates may update the same operation card. +Return one bounded final conclusion through existing manager roundtrip; do not +overwrite its immutable conclusion for each fill. Subsequent monitoring is a +separate linked workflow. + +## 7. Alternatives and privacy + +- A parameterized tool alone is insufficient: it lacks durable human identity, + request binding, ambiguous-submission recovery and transport-independent + receipts. A tool can be the proposal/readback interface to this contract. +- A venue-specific bot containing confirmation, risk and API logic duplicates + the next platform's infrastructure. Keep transport and finance semantics apart. +- A universal Core finance engine places exchange rules and financial authority + in the wrong owner. Generic cards consume domain-owned fields and validators. +- A separate domain database may store payloads, reservations and receipts, but + must not store its own writable Goal progress or independent confirmation. + +Reusable protocol, checks, methods and adapters can be public. Repository +visibility is independent from semantic layer. Account IDs, actual orders, +limits, personal strategies, group bindings, credentials and raw private data +remain in ignored local storage. Sharing code never grants access to an account. + +## 8. Migration and rollback + +Feature off by default. Existing Goal/Todo actions and read-only finance +installations retain their behavior and permissions. Mixed-version hosts reject +unsupported operation/schema revisions explicitly. Disabling an adapter blocks +new proposals/submissions while retaining readable receipts and reconciliation +for claimed operations. Uninstallation must not discard outstanding-order or +unknown-submission records. Revoke credentials only through explicit user setup; +removing a package does not cancel venue orders. + +## 9. Validation and user entry points + +| Claim | Required evidence | Boundary | +| --- | --- | --- | +| Exact operation | Alter each effect-bearing field, digest, expiry and executor revision | Changed requests cannot reuse confirmation | +| Authenticated click | Wrong app/tenant/operator/chat/message; forwarded card; forged local request | No execution; actionable feedback | +| One claim | Concurrent web/Lark clicks and restart replay | One claim; one original client ID | +| Aggregate limit | Two simultaneous orders both fit alone but exceed shared capacity | At most valid reserved capacity submits | +| Ambiguous submission | Venue accepts, response lost, process restarts | Read-only reconciliation, no blind resubmit | +| Financial outcome | Partial fill, protection failure, currency mismatch, duplicated fills, missing history | Explicit uncertainty and correct accounting | +| Automatic return | Lost delivery then restart | Same request receives outcome; no new execution | +| Product completeness | Existing chat detail and Lark card against same backend, desktop/mobile, packaged frontend | Status, terms, disabled controls and failures agree | +| Feature off | Existing actions and both research providers | No behavior or permission change | + +Simulated results must be visibly marked on every surface. Passing simulation +does not establish platform callback configuration, credential readiness or live +trade acceptance. Live acceptance requires an actual human click and matched +venue evidence; the development agent must not manufacture either. + +## 10. Operations + +Expose callback health separately from text-listener health. Distinguish pending +confirmation, expired, dispatch unknown, receipt pending and delivery failed. +Do not expose callback tokens, signer data or raw sensitive errors in groups. +Surface unsupported product/mode and incomplete account coverage before offering +an executable confirmation. Keep a bounded reconciliation and delivery worker; +reuse existing supervision instead of a dedicated business automation prompt. + +## 11. Delivery plan + +| Milestone | Cohesive delivery | Exit evidence | +| --- | --- | --- | +| M1 | Extend generic typed-action owner, authenticated Lark callback and existing frontend details with one simulated finance consumer | Same request confirmed once across both entries; result auto-return; feature-off parity | +| M2 | Public finance contract/reducer/reservation owner plus isolated Aqua adapter; live still disabled | Precision/cost/mode and concurrent-budget checks; installed conformance and read-only account qualification | +| M3 | User configures credentials and confirms one exact order | Matched real submission/fill/reconciliation/return evidence; no mock claimed as live | +| M4 | Second venue adapter only when a real caller needs it | Same conformance contract, documented unsupported features and platform-specific checks | + +M1 spans UI and backend; do not split it into a completed backend PR and forgotten +frontend work. Keep draft cross-repository PR dependencies explicit. First +extract the actual shared seam, not a speculative adapter framework. + +## 12. Open implementation decisions + +1. **Canonical action owner:** re-audit typed authority at implementation time; + extend its existing storage/transaction owner. Maintainer-owned M1 decision. +2. **Public finance package identity:** recommend a separate optional execution + distribution to keep research installation read-only. Confirm naming and + admission only with the M1/M2 real caller; no registry entry in this RFC. +3. **Venue distribution:** a collaboration repository may host adapters in + independent packages. Verify license, permission isolation and installation; + do not append signing to an existing quote collector. Adapter maintainer M2. +4. **Deployment qualification:** verify the actual Lark app callback and + authenticated web-owner mechanism. A healthy event process alone is not + evidence that either user path works. Required before M1 acceptance. From c01757691cc74de1c2b4955c3873915b0cfa5bcd Mon Sep 17 00:00:00 2001 From: huangruiteng <14976749+huangruiteng@users.noreply.github.com> Date: Sat, 12 Sep 2026 13:17:58 +0800 Subject: [PATCH 2/3] docs: add Chinese RFC mirror and governance check Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com> --- docs/architecture/rfcs/README.md | 1 + docs/architecture/rfcs/TEMPLATE.md | 7 +- .../human-confirmed-domain-operations-v0.md | 4 + ...an-confirmed-domain-operations-v0.zh-CN.md | 217 ++++++++++++++++++ examples/docs-governance-smoke.py | 39 ++++ 5 files changed, 266 insertions(+), 2 deletions(-) create mode 100644 docs/architecture/rfcs/human-confirmed-domain-operations-v0.zh-CN.md diff --git a/docs/architecture/rfcs/README.md b/docs/architecture/rfcs/README.md index 30d94bb7c9..5ce1f8bf2a 100644 --- a/docs/architecture/rfcs/README.md +++ b/docs/architecture/rfcs/README.md @@ -49,6 +49,7 @@ changes. ## Control-Plane Kernel, State, And Migration - [Human-confirmed domain operations v0](human-confirmed-domain-operations-v0.md) + ([中文版](human-confirmed-domain-operations-v0.zh-CN.md)) - **RFC status:** Draft. - **Delivery on `main`:** Proposal only. - **Current boundary:** Separates generic authenticated interaction, optional diff --git a/docs/architecture/rfcs/TEMPLATE.md b/docs/architecture/rfcs/TEMPLATE.md index 27705306c2..5cb746c47c 100644 --- a/docs/architecture/rfcs/TEMPLATE.md +++ b/docs/architecture/rfcs/TEMPLATE.md @@ -7,12 +7,15 @@ - **Last normative revision:** YYYY-MM-DD - **Implementation baseline:** `` or not applicable - **Related contracts:** -- **Language mirror:** +- **Language mirror:** [中文版](https://github.com/huangruiteng/loopx/blob/main/docs/architecture/rfcs/.zh-CN.md) ## Document map and maintenance contract State which sections are normative, which are current implementation facts, -and which are historical evidence. Use this default: +and which are historical evidence. Use this default. Every new RFC must ship an +English document and a `.zh-CN.md` semantic mirror; a language +link is required in both documents. Keep the two versions synchronized when +normative sections change: - Sections 1-10 are the durable design and acceptance contract. - Section 11 is the normative delivery plan. diff --git a/docs/architecture/rfcs/human-confirmed-domain-operations-v0.md b/docs/architecture/rfcs/human-confirmed-domain-operations-v0.md index 67cb00010e..fde35fc9e1 100644 --- a/docs/architecture/rfcs/human-confirmed-domain-operations-v0.md +++ b/docs/architecture/rfcs/human-confirmed-domain-operations-v0.md @@ -8,6 +8,10 @@ - **Implementation baseline:** `72e557586` - **Related contracts:** [Extensions](../../reference/extensions.md), [Effect interpreter](agent-loop-effect-interpreter-v0.md) +- **Language mirror:** [中文版](human-confirmed-domain-operations-v0.zh-CN.md) + +The English and Chinese versions are semantic mirrors. Update both when changing +the contract; a difference in their requirements or boundaries is a defect. Sections 1–11 define the proposed contract, not shipped commands. Section 12 records unresolved implementation choices. This document changes no runtime, diff --git a/docs/architecture/rfcs/human-confirmed-domain-operations-v0.zh-CN.md b/docs/architecture/rfcs/human-confirmed-domain-operations-v0.zh-CN.md new file mode 100644 index 0000000000..54f5ce2755 --- /dev/null +++ b/docs/architecture/rfcs/human-confirmed-domain-operations-v0.zh-CN.md @@ -0,0 +1,217 @@ +# RFC:用户确认的垂域操作(v0) + +- **RFC 状态:** 草稿 +- **交付成熟度:** 提案 +- **作者 / 负责人:** LoopX 维护者与可选垂域 provider 维护者 +- **创建日期:** 2026-09-12 +- **最近规范修订:** 2026-09-12 +- **实现基线:** `72e557586` +- **相关契约:** [扩展](../../reference/extensions.md)、 + [Effect interpreter](agent-loop-effect-interpreter-v0.md) +- **语言镜像:** [English](human-confirmed-domain-operations-v0.md) + +中英文版本互为语义镜像。修改契约时须同步更新两版;要求或边界不一致即为缺陷。 + +第 1–11 节定义拟议契约,并非已发布的命令。第 12 节记录尚未解决的实现选择。 +本文不修改运行时、默认权限、配置或用户入口。 + +## 1. 决策摘要 + +按语义划分三层,不要求拆成三个仓库: + +| 层 | 职责 | 建议代码归属 | +| --- | --- | --- | +| LoopX 交互层 | 经认证的用户操作、不可变请求绑定、执行认领、原会话回传与共享展示 | 现有公开 typed-action、chat 和 Lark 模块 | +| 金融垂域层 | 订单意图、金融校验、总敞口额度预留、订单/成交核算与金融展示 | 可选的公开 finance 执行包 | +| 交易平台适配层 | 平台产品、精度、账户模式、API 认证、订单提交与平台对账 | 独立安装的 Aqua/Hyperliquid、Futu 或其他 adapter | + +研究方法仍属于研究 provider。策略可以提出订单,但不能因通过研究门禁而获得执行权限。 +开启研究 capability 不得安装凭据或开启交易。 + +公开 finance 执行包拟作为 `packages/` 下的独立同级发行包,而不是扩展现有 +value-discovery evaluator 的权限。本文不注册新的内置 finance capability 或包名。 +先实现第一个真实消费者,再提取通用插件框架。 + +## 2. 问题与不变量 + +用户应收到内容明确的操作卡,点击一次后,在该会话自动收到结果。 +“已转交 Agent”不能证明用户已确认、操作已执行或平台已有成交。 + +必须保持以下不变量: + +- 只有可信交互入口能证明用户点击。Agent 不能通过工具参数或模型输出伪造确认。 +- 确认摘要绑定所有影响实际操作的条款、条款版本、展示投影、执行器版本及目标账户引用。 +- 重要条款变化必须创建新请求。执行只能在已确认边界明确允许的值中选择。 +- 消息投递重试不能提交操作。提交结果不明确时必须对账,不能创建新请求或盲目重试。 +- 前端和飞书读取同一份请求与结果投影。 +- Core 仍是 Goal/Todo 状态的权威来源,平台证据仍是订单和成交的权威来源。 + 聊天文字和本地执行认领都不能证明金融操作实际发生。 + +## 3. 范围与非目标 + +首批范围:一个不可变、经用户明确确认的操作,一个已注册执行器,以及自动回执和 +终态或不确定结果的投递。在配置真实凭据之前,先用模拟金融 adapter 演示完整流程。 + +这不会把普通 Goal steering 改成逐次确认流程。现有读取、协调和汇报的持久权限保持独立。 +不支持任意工具名/kwargs 执行、卡片内 shell 命令、全局工作流 DAG、自主交易循环、 +划转服务或跨平台组合引擎。 + +## 4. 已核查的现有职责归属 + +| 当前代码 | 已核实边界 | +| --- | --- | +| `loopx/chat_action_store.py` | 请求摘要、幂等、带状态检查的提案;仅支持内置 Goal/Todo 动作;当前 `failed` 可重试 | +| `loopx/chat_actions.py` | 校验和应用内置动作;调用本地 API 不能证明用户确认了金融操作 | +| `loopx/extensions/lark/event_collector.py` | 当前 collector 选择 `im.message.receive_v1`;文字监听就绪不等于卡片回调就绪 | +| `loopx/capabilities/manager_context/roundtrip.py` | 原会话回传、回执持久化与传输重试;上下文委托不授予交易权限 | +| `apps/presentation/dashboard/src/data/chat.ts` | 与现有聊天动作详情和控件配套的 typed-action schema | +| `packages/loopx-finance-value-discovery/extension.toml` | 可选公开研究 evaluator,权限为空;提供研究展示面,没有执行契约 | + +通过明确的类型化扩展复用上述模块。不要在通用本地 HTTP 入口偷偷增加金融 `apply` +分支,也不要让结果未知的外部提交继承 `failed` 可重试的行为。 + +## 5. 架构与唯一权威 + +### LoopX 交互层 + +Core 管理操作信封:操作 ID、schema 版本、垂域/adapter 绑定、不可变载荷引用及摘要、 +展示投影摘要、有效期、授权受众、来源会话/消息/请求、已核验确认回执、派发认领及结果引用。 +Core 不解释金融载荷语义;哈希是用于绑定的元数据,不能替代向用户展示的条款。 + +扩展现有 typed-action 权威模块,不另建提案数据库。如果实现时其权威已经迁移, +应使用届时的规范权威来源,不要在旁边再建一套 Python 权威。 +信封、身份和日志原语的生命周期适用时应予以复用。Goal quota/Todo 准入绝不能授予 +执行金融操作的权限。 + +Core 校验已注册的垂域契约,仅调用已准入、操作类型和 schema 版本固定的执行器。 +模型可以准备提案和读取回执。产生实际操作的入口只接受服务端签发并被消费的确认回执, +不提供 `confirmed: true` 这样的绕过参数。 + +飞书优先复用现有机器人传输与 `card.action.trigger`。传输层先核验应用/租户来源, +再核验操作者、群、原消息、动作、摘要及有效期。Web 入口使用已认证的 owner 身份与 +origin/CSRF 防护,并访问同一个权威来源。只有不透明 ID、回环地址、转发卡片或相同 +显示名称,都不足以建立确认。 + +### 金融垂域层 + +可选 finance 包负责规范金融载荷和金融结果 reducer,不另建竞争性的确认账本。 +垂域记录以 Core 操作 ID 和不可变金融载荷摘要为键。 + +订单条款包括平台/产品/资产标识、账户引用、方向、数量及单位、订单类型、价格边界、 +订单有效方式(time-in-force)、只减仓(reduce-only)、保证金/杠杆设置、费用上限及单位、 +可选保护单、有效期和证据时间。十进制数量必须保留精度。 + +账户级约束要求该账户的所有操作共用一个额度预留权威。单独校验每张卡不够: +并发确认可能共同突破同一份剩余额度。Core 完成认领后、提交订单前,垂域原子地预留额度, +计入已有持仓和未完成订单,并拒绝过期或覆盖不完整的账户信息。 +结果未知的提交保留其额度,直至对账完成。进程重启不能重置预算。 +账户通过其他客户端发生交易时,需要刷新账户观察;本地账本不能阻止其他客户端的操作。 + +提交前检查使用最新平台观察校验金融不变量。如果精度调整、费用、账户模式或其他重要 +条款将超出已确认边界,则拒绝操作并要求新卡片,而不是静默编辑已确认载荷。 +未经新确认,不得为满足平台最低订单要求而增加数量。 + +垂域结果区分已受理、挂单中、部分成交、全部成交、拒单、已撤销和未知。 +入场单与保护单分别记录结果。费用、资金费、资金流动、返佣和 PnL 分别核算; +没有费用证据表示未知,不表示零。研究证据可以解释订单提案,但不能替代执行证据。 + +### 交易平台适配层 + +每个 adapter 声明支持的产品/订单类型、最低要求/精度、费用语义、账户模式、认证要求、 +客户端订单 ID 支持和对账边界。它使用平台官方 API 或 SDK,执行有界的发现、读取、 +提交前检查、提交与对账操作,不得静默切换到另一平台或产品。 + +面向 Aqua 的 adapter 必须区分 Aqua 产品/builder 政策与底层平台协议; +“Hyperliquid 支持”不能证明 Aqua 条款、费用归属或账户初始化条件。 +Futu adapter 必须区分行情访问与交易权限,并处理证券手数规则、交易时段、账户地区及 +OpenD 解锁要求。共享标准化契约不意味着这些产品可以相互替换。 + +adapter 将凭据保存在单独配置的私有凭据设施中,返回标准化证据和指向原始平台回执的 +有界引用。它不能修改 Core 授权、用户预算或策略决策。提现、入金、密钥授权以及 +杠杆/账户模式修改,都不是订单 adapter 隐含允许的副作用。 + +## 6. 生命周期与失败语义 + +拟议的交互生命周期: + +`prepared → awaiting_confirmation → claimed → outcome_observed` + +尚未认领的请求可因取消或过期而终止。认领后,Core 分别跟踪派发和结果投递, +不把它们与垂域执行状态混为一谈。执行器在网络提交之前,持久记录稳定的客户端订单 ID +及提交尝试。派发后超时或崩溃记为 `submission_unknown`;任何后续实际操作前, +先按原 ID 对账。本地锁无法保证平台恰好成交一次。平台不能消除歧义时,保留未知状态 +并自动汇报。 + +回执包含操作 ID、垂域/adapter 版本、已确认摘要、提交尝试/客户端/平台 ID、证据时间、 +覆盖范围与标准化结果。前端和飞书消费同一份带版本投影,不各自重新计算成交状态。 +中间进展可以更新同一操作卡。通过现有 manager roundtrip 回传一次有界最终结论, +不要为每次成交覆盖其不可变结论。后续监测是独立且关联的工作流。 + +## 7. 替代方案与隐私 + +- 只有参数化工具还不够:它缺少持久的用户身份、请求绑定、提交歧义恢复和独立于传输的 + 回执。工具可以作为本契约的提案与读回接口。 +- 将确认、风控和 API 逻辑都放进单个平台机器人,会在接入下一个平台时重复建设。 + 应分离传输与金融语义。 +- 通用 Core 金融引擎会把交易规则和金融权威放错位置。通用卡片应消费垂域拥有的字段和 + 校验器。 +- 独立垂域数据库可以保存载荷、额度预留与回执,但不能保存另一份可写 Goal 进度或 + 独立确认记录。 + +可复用的协议、校验、方法和 adapter 可以公开。仓库可见性独立于语义分层。 +账户 ID、真实订单、额度、个人策略、群绑定、凭据和原始私有数据留在被忽略的本地存储。 +共享代码不授予账户访问权限。 + +## 8. 迁移与回滚 + +功能默认关闭。现有 Goal/Todo 动作和只读 finance 安装保留原行为及权限。 +混合版本宿主明确拒绝不支持的操作/schema 版本。禁用 adapter 会阻止新提案/提交, +但保留已认领操作的回执读取与对账。卸载不得丢弃未完成订单或提交结果未知的记录。 +凭据撤销仅通过用户明确配置完成;删除软件包不会撤销平台订单。 + +## 9. 验证与用户入口 + +| 验证主张 | 所需证据 | 边界 | +| --- | --- | --- | +| 精确操作绑定 | 逐一修改影响操作的字段、摘要、有效期和执行器版本 | 变化后的请求不能复用确认 | +| 点击身份认证 | 错误应用/租户/操作者/群/消息;转发卡片;伪造本地请求 | 不执行,并提供可采取行动的反馈 | +| 唯一认领 | Web/飞书并发点击与重启重放 | 一次认领;同一个原始客户端订单 ID | +| 总额度约束 | 两个订单单独都符合额度,同时执行却超过总额度 | 提交量不超过有效预留额度 | +| 提交歧义 | 平台受理、响应丢失、进程重启 | 只读对账,不盲目重提 | +| 金融结果 | 部分成交、保护失败、币种不匹配、重复成交、历史缺失 | 明确不确定性,正确核算 | +| 自动回传 | 投递丢失后重启 | 原请求收到结果,不产生新执行 | +| 产品完整性 | 现有聊天详情与飞书卡接同一后端,覆盖桌面/移动端及打包前端 | 状态、条款、禁用控件和失败反馈一致 | +| 功能关闭 | 现有动作与两个研究 provider | 行为和权限不变 | + +模拟结果必须在每个展示面明显标注。模拟通过不能证明平台回调已配置、凭据已就绪或 +实盘交易已验收。实盘验收需要真实用户点击与匹配的平台证据;开发 Agent 不得伪造任一项。 + +## 10. 运行要求 + +卡片回调健康与文字监听健康分别展示。区分待确认、已过期、派发结果未知、回执待到达和 +投递失败。不要在群里暴露回调 token、签名器数据或原始敏感错误。 +提供可执行确认之前,应展示不支持的产品/模式和账户覆盖不完整的问题。 +保留有界的对账与投递 worker;复用现有进程监督机制,而非专用业务 automation 提示词。 + +## 11. 交付计划 + +| 里程碑 | 完整交付内容 | 出口证据 | +| --- | --- | --- | +| M1 | 扩展通用 typed-action 权威、经认证的飞书回调和现有前端详情,并接入一个模拟金融消费者 | 同一请求跨两个入口只确认一次;自动回传结果;功能关闭时行为一致 | +| M2 | 公开金融契约/reducer/额度预留权威及隔离的 Aqua adapter;实盘仍关闭 | 精度/成本/模式与并发预算检查;安装后的契约一致性验证及只读账户资格核验 | +| M3 | 用户配置凭据并确认一笔精确订单 | 匹配的真实提交/成交/对账/回传证据;不把 mock 声称为实盘 | +| M4 | 只有真实调用方需要时才接入第二个平台 adapter | 同一契约一致性验证,记录不支持的功能和平台特定检查 | + +M1 同时涵盖 UI 与后端,不要拆成“后端 PR 已完成”而遗忘前端配套。 +明确草稿跨仓库 PR 的依赖。先提取实际共用的接缝,不构建推测性的 adapter 框架。 + +## 12. 待定实现决策 + +1. **规范动作权威:** 实现时重新核查类型化权威,扩展其现有存储/事务模块。 + 由维护者在 M1 决定。 +2. **公开 finance 包身份:** 建议独立可选的执行发行包,保持研究安装只读。 + 结合 M1/M2 的真实调用方确认命名和准入;本文不新增注册项。 +3. **平台发行方式:** 协作仓库可用独立包托管 adapter。核验许可证、权限隔离和安装方式, + 不把签名加入现有行情采集器。由 adapter 维护者在 M2 决定。 +4. **部署资格:** 核实真实飞书应用回调和 Web owner 身份认证机制。 + 事件进程健康本身不能证明任一用户路径可用。M1 验收前必须完成。 diff --git a/examples/docs-governance-smoke.py b/examples/docs-governance-smoke.py index 85dc836c60..e8e437a874 100644 --- a/examples/docs-governance-smoke.py +++ b/examples/docs-governance-smoke.py @@ -99,6 +99,25 @@ "update-notes/README.md": "dated progress notes; catalog-only entry", } +# These RFCs predate the bilingual RFC rule. New and modified RFCs must carry +# a same-basename Chinese mirror; keep this legacy list explicit until each is +# migrated rather than silently weakening the invariant. +RFC_BILINGUAL_LEGACY_ALLOWLIST = { + "agent-im-openviking-collaboration-v0.md", + "benchmark-study-upload-dashboard-v0.md", + "goal-usage-token-cost-v0.md", + "provider-neutral-turn-start-inbox-hook-v0.md", + "single-owner-local-daemon-v0.md", + # Existing mirrors that predate reciprocal language links. + "cross-session-memory-substrate-v0.md", + "desktop-execution-frontends-v0.md", + "goal-channel-collaboration-v0.md", + "obelisk-session-evidence-provider-v0.md", + "post-outcome-memory-utility-attribution-v0.md", + "goal-direction-baseline-v0.md", + "harness-selection-dsh-pi-v0.md", +} + # Stable README advanced-docs entry links under docs/ that must stay reachable. STABLE_README_DOCS_ENTRY_LINKS = ( "operations/README.md", @@ -164,6 +183,25 @@ def iter_relative_md_targets(text: str) -> list[str]: return targets +def check_rfc_language_mirrors() -> None: + """Require bilingual mirrors for new RFCs and validate reciprocal links.""" + rfc_dir = DOCS / "architecture" / "rfcs" + for english in sorted(rfc_dir.glob("*.md")): + if english.name in {"README.md", "TEMPLATE.md"} or english.name.endswith(".zh-CN.md"): + continue + if english.name in RFC_BILINGUAL_LEGACY_ALLOWLIST: + continue + chinese = english.with_name(f"{english.stem}.zh-CN.md") + if not chinese.exists(): + raise AssertionError(f"RFC missing required Chinese mirror: {english.name}") + english_text = english.read_text(encoding="utf-8") + chinese_text = chinese.read_text(encoding="utf-8") + assert chinese.name in english_text, f"RFC missing English -> Chinese link: {english.name}" + assert english.name in chinese_text, f"RFC missing Chinese -> English link: {chinese.name}" + assert "semantic mirror" in english_text.lower(), english.name + assert "语义镜像" in chinese_text, chinese.name + + def mkdocs_nav_paths(mkdocs_text: str) -> set[str]: assert "\nnav:\n" in mkdocs_text or mkdocs_text.startswith("nav:\n"), mkdocs_text nav_body = mkdocs_text.split("nav:", 1)[1] @@ -814,6 +852,7 @@ def main() -> int: ]: assert required in compact_multi_agent_product_recipe, required + check_rfc_language_mirrors() print("docs-governance-smoke ok") return 0 From c46068508b05a3adc3e59d23e0c0193ddbd617df Mon Sep 17 00:00:00 2001 From: huangruiteng <14976749+huangruiteng@users.noreply.github.com> Date: Sat, 12 Sep 2026 13:26:08 +0800 Subject: [PATCH 3/3] docs: map the first confirmed operation slice Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com> --- .../human-confirmed-domain-operations-v0.md | 20 +++++++++++++++++++ ...an-confirmed-domain-operations-v0.zh-CN.md | 16 +++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/docs/architecture/rfcs/human-confirmed-domain-operations-v0.md b/docs/architecture/rfcs/human-confirmed-domain-operations-v0.md index fde35fc9e1..bd49f9911d 100644 --- a/docs/architecture/rfcs/human-confirmed-domain-operations-v0.md +++ b/docs/architecture/rfcs/human-confirmed-domain-operations-v0.md @@ -187,6 +187,26 @@ Return one bounded final conclusion through existing manager roundtrip; do not overwrite its immutable conclusion for each fill. Subsequent monitoring is a separate linked workflow. +### M1 implementation map + +The first implementation must be reviewed as one cross-entrypoint slice: + +- extend the canonical typed-action owner behind `loopx/chat_action_store.py` + and `loopx/chat_actions.py` only with a provider-neutral operation envelope; +- add a separate authenticated `card.action.trigger` consumer beside the + text-only path in `loopx/extensions/lark/event_collector.py`, preserving the + existing WebSocket supervision and callback acknowledgement contract; +- add the operation projection to the existing chat data/details path in + `apps/presentation/dashboard/src/data/chat.ts` and its owning view, rather + than a second order store or a local-only page; +- put the simulated financial consumer and its order/result schemas in the + optional finance execution distribution, with no exchange or signer calls; +- use `manager_context` only for the original-conversation result return and + delivery retry. It must not become the confirmation or financial ledger. + +M1 is incomplete if any of the frontend, Lark, simulated consumer, or receipt +recovery parts is missing. A backend-only PR must be labelled partial. + ## 7. Alternatives and privacy - A parameterized tool alone is insufficient: it lacks durable human identity, diff --git a/docs/architecture/rfcs/human-confirmed-domain-operations-v0.zh-CN.md b/docs/architecture/rfcs/human-confirmed-domain-operations-v0.zh-CN.md index 54f5ce2755..43a27b32cc 100644 --- a/docs/architecture/rfcs/human-confirmed-domain-operations-v0.zh-CN.md +++ b/docs/architecture/rfcs/human-confirmed-domain-operations-v0.zh-CN.md @@ -147,6 +147,22 @@ adapter 将凭据保存在单独配置的私有凭据设施中,返回标准化 中间进展可以更新同一操作卡。通过现有 manager roundtrip 回传一次有界最终结论, 不要为每次成交覆盖其不可变结论。后续监测是独立且关联的工作流。 +### M1 实现接缝 + +首个实现必须作为一个跨入口完整切片共同审阅: + +- 只在 `loopx/chat_action_store.py` 和 `loopx/chat_actions.py` 背后的规范 + typed-action 权威中扩展垂域无关的操作信封; +- 在 `loopx/extensions/lark/event_collector.py` 的文字监听路径旁增加独立、 + 经认证的 `card.action.trigger` 消费者,保持现有 WebSocket 监督和回调确认契约; +- 在 `apps/presentation/dashboard/src/data/chat.ts` 及其所属视图接入操作投影, + 不另建订单存储或只在本地页面实现; +- 在可选 finance 执行发行包中放模拟金融消费者及订单/结果 schema,不调用交易平台或签名器; +- `manager_context` 只负责原会话结果回传和投递重试,不能成为确认账本或金融账本。 + +如果缺少前端、飞书、模拟消费者或回执恢复中的任一部分,M1 都是不完整的; +仅完成后端的 PR 必须明确标记为 partial。 + ## 7. 替代方案与隐私 - 只有参数化工具还不够:它缺少持久的用户身份、请求绑定、提交歧义恢复和独立于传输的