Skip to content

Commit 2e1e632

Browse files
authored
Merge pull request #4994 from loopx-project/codex/leased-continuation-0924
fix(coordination): continue leased Todos across explicit Agent handoff
2 parents 6d29882 + f4e6eeb commit 2e1e632

19 files changed

Lines changed: 655 additions & 125 deletions

‎docs/architecture/rfcs/cross-session-memory-substrate-v0.md‎

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
Stage A shipped in [#4094](https://github.com/huangruiteng/loopx/pull/4094), merge `2ebd921ee989f7c696a7214ba1176d3bd5de6fb3`. The historical filename does not imply that a generic memory substrate shipped. The [capable manager and semantic handoff RFC](capable-manager-semantic-handoff-v0.md#513-integrate-shipped-explicit-continuation-4094) includes this implementation in its M2/M3 refactor scope. That successor remains proposed; this document remains the shipped CLI compatibility and authority reference until its replacement qualifies.
66

7-
Reuse rich/legacy context and the existing note validator/claim transfer boundary. Receiver acceptance of a suggestion is distinct from `handoff adopt` ownership mutation. Stage A's note is replaceable current Todo state, not a private immutable history. The successor maps authorized context to a recoverable brief, references current work, and supplies general assessment/result/automatic-return relations without adding a memory ledger or copying claim authority. CLI `prepare/inspect/adopt` remains usable during migration; frontend/Lark and automatic host continuation must be qualified separately. Same-host, registered-agent, lease-free restrictions continue to apply to this adapter, not every general request. See successor §5.13 for mappings, migration conditions and retained negative cases.
7+
Reuse rich/legacy context and the existing note validator/claim transfer boundary. Receiver acceptance of a suggestion is distinct from `handoff adopt` ownership mutation. Stage A's note is replaceable current Todo state, not a private immutable history. The successor maps authorized context to a recoverable brief, references current work, and supplies general assessment/result/automatic-return relations without adding a memory ledger or copying claim authority. CLI `prepare/inspect/adopt` remains usable during migration; frontend/Lark and automatic host continuation must be qualified separately. Same-host and registered-agent restrictions continue to apply to this adapter, not every general request. Leased execution uses the explicit transfer path below. See successor §5.13 for mappings, migration conditions and retained negative cases.
88

99
The successor [§5.7](capable-manager-semantic-handoff-v0.md#57-session-and-product-continuity) now distinguishes same-session resume, same-Agent session replacement and cross-Agent takeover. Only the last may require this adapter’s ownership mutation. Automatic brief capture, source-loss recovery, executable-session fencing and original-route result return are explicit future integration work; optional Obelisk recall supplies missing historical evidence, not a replacement transfer grant.
1010

@@ -32,8 +32,7 @@ require a different product layer beyond this control-plane primitive.
3232
## Ownership and placement
3333

3434
The existing Todo coordination boundary owns current execution state, stable
35-
Todo IDs, revision checks and claim/lease decisions. The built-in local
36-
`file_v0` authority supplies persistence; no new capability, provider, database,
35+
Todo IDs, revision checks and claim/lease decisions. The selected canonical File/SQLite authority supplies persistence; no new capability, provider, database,
3736
index, discovery API, recovery service or ownership protocol is introduced.
3837
The CLI is a host adapter to that TypeScript boundary.
3938

@@ -44,11 +43,12 @@ nor grants permission to index a workspace or read source-reference bodies.
4443

4544
## First usable path
4645

47-
Prerequisites: an **already explicitly promoted local file authority**, an open,
48-
active agent Todo claimed by a registered agent, and no lease on that Todo.
49-
The existing metadata writer cannot prove lease-bearing updates, so Stage A
50-
rejects hard-lease goals and lease-bearing Todos. It never promotes authority,
51-
changes handoff mode, releases another owner's work or falls back to Markdown.
46+
Prerequisites: an **already explicitly promoted canonical authority** and an
47+
open, active Agent Todo claimed by a registered Agent. Lease-free adoption
48+
retains the existing claim transaction. Hard-lease work requires the exact
49+
current execution proof; ownership moves only through the existing atomic
50+
`task-lease transfer --transfer-claim` command. This adapter never promotes a
51+
Goal, changes its handoff mode or falls back to Markdown.
5252

5353
The user explicitly hands a Todo from one session to another session of a
5454
**different registered agent on the same host**. The source writes a revision-
@@ -105,6 +105,51 @@ ID, invokes the existing claim transaction and reads back current authority.
105105
A same-owner claim may correctly be a no-op; it does not create a Todo or
106106
manufacture a new lease.
107107

108+
## Leased execution continuation
109+
110+
Prepare while the sender still owns the claim and lease. Pass the current
111+
`--task-lease-idempotency-key` and `--task-lease-expected-version` pair to prepare.
112+
Use actual readback versions; the example assumes source version 3.
113+
114+
```bash
115+
loopx handoff prepare --goal-id demo --todo-id todo_a \
116+
--agent-id agent-a --session-id source-session --operation-id prepare-context \
117+
--expected-revision "$SOURCE_REVISION" --from-context ./handoff-context.json \
118+
--task-lease-idempotency-key execution-a --task-lease-expected-version 3
119+
loopx task-lease transfer --goal-id demo --todo-id todo_a --owner agent-a \
120+
--idempotency-key execution-a --expected-version 3 --new-owner agent-b \
121+
--new-idempotency-key execution-b --ttl-seconds 600 --transfer-claim
122+
loopx handoff inspect --goal-id demo --todo-id todo_a \
123+
--agent-id agent-b --session-id target-session --workspace . \
124+
--task-lease-idempotency-key execution-b --task-lease-expected-version 4
125+
loopx handoff adopt --goal-id demo --todo-id todo_a \
126+
--agent-id agent-b --session-id target-session --operation-id accept-context \
127+
--expected-revision "$TARGET_REVISION" --workspace . \
128+
--task-lease-idempotency-key execution-b --task-lease-expected-version 4
129+
```
130+
131+
Inspect remains read-only without proof, but cannot report `can_adopt=true`
132+
for leased work without current execution authority. Transfer carries a note
133+
forward only when it was valid before the authorized claim change; it updates
134+
that note's owner-bound fingerprint in the same CAS. Changed work requirements
135+
and previously stale notes remain stale. Arbitrary metadata edits cannot
136+
rebind a note. An already-committed historical transfer is replayed unchanged.
137+
138+
Leased adopt seals a context receipt bound to Agent, session, note, revision and
139+
lease proof. It does not transfer, acquire or renew a lease. Its `adoption`
140+
result has `changed=false`; `current_authority_verified` additionally requires
141+
fresh authority readback. The old lease-free result retains its `claim` field.
142+
Historical receipts never override a released/expired lease, a different owner,
143+
changed requirements or a Goal acceptance hold. Session IDs remain provenance,
144+
not host authentication or grants to execute external tools.
145+
146+
Prepare/adopt deliver current canonical Todo state to the existing Markdown
147+
projection. Display failure returns `projection_delivery=pending` with
148+
`retry_business_mutation=false`; repair the local display inputs and retry the
149+
same operation or use `todo project-markdown`. Inspect never writes a display.
150+
The feature does not create frontend/Lark controls or launch a target session;
151+
it is an explicit CLI workflow, not automatic manager-to-worker delegation.
152+
108153
## Rich handoff context
109154

110155
The `--from-context` flag accepts a JSON file with structured handoff context:
@@ -176,7 +221,7 @@ The focused test runs separate source and target Python CLI processes against
176221
a disposable real file authority, plus restart, lost acknowledgment, failed
177222
write, missing artifact, stale revision, changed owner, completed Todo, rich
178223
context, and legacy backward-compat cases. Existing claim/update suites cover
179-
default behavior and lease rejection.
224+
default behavior and rejection of missing, stale or foreign execution proofs.
180225

181226
```sh
182227
node --experimental-strip-types --test tests/control_plane_ts/todo_continuation.test.ts

‎docs/architecture/rfcs/cross-session-memory-substrate-v0.zh-CN.md‎

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
Stage A 已在 [#4094](https://github.com/huangruiteng/loopx/pull/4094) 以 `2ebd921ee989f7c696a7214ba1176d3bd5de6fb3` 合并。历史文件名不表示通用 memory substrate 已交付。[强能力管家与语义交接 RFC](capable-manager-semantic-handoff-v0.zh-CN.md#513-整合已交付的显式接续4094) 将本实现纳入 M2/M3 重构范围。后继方案仍是提案;替代路径验收前,本文继续作为已交付 CLI 兼容性及权威边界参考。
66

7-
复用 rich/legacy context、既有 note validator 与 claim transfer 边界。接收方接受建议不同于 `handoff adopt` 修改所有权。Stage A note 是可覆盖的当前 Todo 状态,不是私有不可变历史。后继方案将有权限的上下文映射为可恢复 brief,引用当前工作,补齐通用 assessment/result/自动回传关系,不新增 memory ledger 或复制 claim authority。迁移期间 CLI `prepare/inspect/adopt` 保持可用;前端/飞书及自动宿主续接单独验收。同机、注册 Agent、无 lease 限制继续适用于此 adapter,不约束所有通用请求。映射、迁移条件和保留负例见后继 §5.13。
7+
复用 rich/legacy context、既有 note validator 与 claim transfer 边界。接收方接受建议不同于 `handoff adopt` 修改所有权。Stage A note 是可覆盖的当前 Todo 状态,不是私有不可变历史。后继方案将有权限的上下文映射为可恢复 brief,引用当前工作,补齐通用 assessment/result/自动回传关系,不新增 memory ledger 或复制 claim authority。迁移期间 CLI `prepare/inspect/adopt` 保持可用;前端/飞书及自动宿主续接单独验收。同机、注册 Agent 限制继续适用于此 adapter,不约束所有通用请求;带租约工作使用下述显式转移路径。映射、迁移条件和保留负例见后继 §5.13。
88

99
后继 [§5.7](capable-manager-semantic-handoff-v0.zh-CN.md#57-会话与产品连续性) 明确区分原会话恢复、同 Agent 换 session、跨 Agent 接管,只有后者可能需要本 adapter 的所有权变更。自动 brief 捕获、来源消失恢复、执行 session fencing、回原入口报结论是明确的后续集成工作;可选 Obelisk recall 只补缺失历史证据,不替代 transfer grant。
1010

@@ -27,17 +27,17 @@ inspect、验证并 adopt Todo。不实现自动上下文捕获、agent 无关
2727
## 实现分工
2828

2929
当前状态、稳定 Todo ID、revision 和 claim/lease 仍归现有 Todo coordination
30-
边界所有;持久化复用内置 `file_v0` authority。CLI 只做宿主适配,状态规则由
30+
边界所有;持久化复用选定的 canonical File/SQLite authority。CLI 只做宿主适配,状态规则由
3131
TypeScript 执行。不新增 capability、数据库、memory store、索引、发现、恢复
3232
服务或所有权协议。历史检索与长期记忆复用可选 `decision_context` /
3333
`agent_turn_recall` provider;本流程不调用它们,也不依赖它们可用。
3434

3535
## 可运行入口和范围
3636

37-
需要已显式提升为本地 file authority 的 goal,以及由注册 agent 持有的
38-
open、active、无 lease Todo。现有说明写入不能证明 lease 执行实例权限,
39-
所以阶段 A 明确拒绝 hard-lease goal 和带 lease 的 Todo;不会隐式提升、
40-
切换模式、释放别人的任务或回退读取 Markdown。
37+
需要已显式晋升的 canonical authority,以及注册 Agent 持有的 open、active Todo。
38+
无租约接力继续复用原 claim 事务。带租约工作必须提供当前执行 key/version,
39+
所有权通过既有 `task-lease transfer --transfer-claim` 原子转移;本入口不晋升
40+
Goal、不改 handoff mode、不回退到 Markdown。
4141

4242
用户在同一宿主上显式 handoff 给另一个注册 agent。源会话将 revision 保护的
4343
接续说明(传统 rationale 或 rich context)写入现有 Todo note;目标会话读取
@@ -144,7 +144,7 @@ Todo 投影的可见边界,没有独立 memory ACL;不得写入凭据或原
144144

145145
薄测试使用隔离真实 file authority,分别运行源、目标 Python CLI 进程,覆盖
146146
正常重启、丢失确认、写入失败、artifact 缺失、revision 改变、他人接管、已完成、
147-
rich context 及传统向后兼容等场景。既有 claim/update 回归覆盖默认行为与 lease 拒绝。
147+
rich context 及传统向后兼容等场景。既有 claim/update 回归覆盖默认行为与缺失、过期、错误执行证明的拒绝。
148148

149149
```sh
150150
node --experimental-strip-types --test tests/control_plane_ts/todo_continuation.test.ts
@@ -157,5 +157,25 @@ node --experimental-strip-types --test tests/control_plane_ts/todo_continuation.
157157
缺少 typed invariant 而被拒绝。
158158

159159
跨 agent transfer 已通过 typed transfer grant 在本交付中实现,由 handoff 流程
160-
(prepare/inspect/adopt)独占发起,普通 claim 无法构造该 grant。lease-bearing
161-
Todo 的 transfer 留待现有所有权边界支持后再扩展,不在本次交付中另造协议。
160+
(prepare/inspect/adopt)独占发起,普通 claim 无法构造该 grant。带租约 Todo 的转移由既有 task-lease lifecycle 所有,adopt 不复制这份权限。
161+
162+
163+
## 带租约的接力与显示恢复
164+
165+
完整可运行命令见[英文镜像的租约流程](cross-session-memory-substrate-v0.md#leased-execution-continuation)。
166+
源 Agent 先凭当前 `--task-lease-idempotency-key` / `--task-lease-expected-version`
167+
和 provider revision 准备上下文,再执行 `task-lease transfer --transfer-claim`。
168+
接收 Agent 用新 key/version inspect,取回当前 revision 后 adopt。版本号必须来自实际读回。
169+
170+
- inspect 无执行证明也能读取上下文,但带租约工作不会得到 `can_adopt=true`。
171+
- 原子 transfer 只延续转移前仍有效的 note,并在同一 CAS 内重绑定 owner 摘要。
172+
已过时的 note、变化的任务要求不会被重新认证;普通 metadata 写入不能重绑定。
173+
- 带租约 adopt 记录绑定 Agent、session、note、revision 和执行证明的 receipt,
174+
不申请、续期或转移租约。返回 `adoption.changed=false`;无租约路径保留 `claim`。
175+
当前权限必须重新读回,历史回执不能越过过期/释放的租约、换主、任务变化或验收 hold。
176+
- prepare/adopt 将当前 canonical Todo 投递至既有 Markdown 投影。显示失败保留
177+
已提交结果,返回 `projection_delivery=pending`、`retry_business_mutation=false`。
178+
修复本地显示输入后可重试同一操作,或运行 `todo project-markdown`;inspect 不写投影。
179+
180+
session ID 仍是来源说明,不是宿主认证或外部工具授权。这是显式 CLI 接力,
181+
没有新增前端/飞书入口、自动启动目标会话或自动 manager/worker 派工能力。
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Explicit leased continuation closes a canonical CLI gap
2+
3+
For #4574 G1/G2 and the shared-authority L2/L3 program, the explicit handoff
4+
caller still rejected every hard-lease Todo even though metadata updates and
5+
atomic claim/lease transfer already owned the necessary execution proof. It
6+
also left committed prepare/adopt state waiting for Markdown delivery.
7+
8+
The same-host CLI now composes those existing owners: prepare with current
9+
proof, transfer claim and lease atomically, then receive context under the new
10+
execution proof. Transfer rebinds only a note valid against its original work
11+
facts. Leased adoption writes a context receipt without changing claim/lease;
12+
receipt replay is separately checked against current execution and acceptance.
13+
Python retains host file IO and projection delivery; the closed context schema
14+
and lease/claim decisions stay in TS. The lease-free path remains compatible.
15+
16+
The [operating contract](../../cross-session-memory-substrate-v0.md#leased-execution-continuation)
17+
describes proof flags, retry/readback and the explicit host/session boundary.
18+
This is not automatic delegation, host launch, independent result acceptance,
19+
external-effect fencing or completion of the manager handoff RFC. No new UI
20+
control is required for this existing CLI-only workflow. Existing Todo display
21+
consumers receive the same record schema via permanent projection.
22+
23+
## Remaining local-default program
24+
25+
Retain the conditional **5–8 cohesive packages**, including integration of
26+
already-open prerequisites. This completes one real caller path within L2/L3
27+
and fixes its display delivery; it does not retire either entire package.
28+
SQLite remains the long-lived default candidate, File the reference/explicit
29+
profile. “New Goal default”, “migrate existing Goals” and “delete all Python”
30+
are separate outcomes.
31+
32+
| Package | Estimate | Observable completion |
33+
| --- | --- | --- |
34+
| Remaining CLI/Turn/Chat callers and actual effects | 1–2 | Close the command matrix, exact execution proof and external-effect boundary; remove each replaced Python business rule with its last caller. |
35+
| Consumer and permanent projection integration | 1 | Full readback/pagination and display recovery through affected packaged entry points; stale or missing Markdown cannot become authority. |
36+
| SQLite D2 qualification, contributor-owned #4224/#4931 | 1–2 | Capacity/receipt/scan budgets, crash/restore/upgrade, platform coverage, consumer lag and at least ten genuinely elapsed days of soak. |
37+
| Source capture plus whole-Goal migration | 1–2 | Sustained mixed writers and event-only coverage, drain/fence/readback, cohort rehearsal and recoverable export/rollback. |
38+
| Default selection and legacy writer retirement | 1 | New-Goal creation/settings/install choose the qualified profile; explicit choices survive; obsolete business writers retire after migration windows close. |
39+
40+
These are delivery packages, not a prediction that five more arbitrary small
41+
PRs finish migration. The elapsed soak cannot be replaced by accelerated tests.
42+
PostgreSQL shares typed command semantics and real backend conformance, but
43+
service authentication, tenant isolation, operations, restore/failover and
44+
capacity remain an independent medium-term qualification. Permanent Markdown
45+
rendering, import/export and host adapters are not duplicate business owners.

0 commit comments

Comments
 (0)