Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 25 additions & 11 deletions docs/architecture/rfcs/shared-goal-authority-state-provider-v0.md
Original file line number Diff line number Diff line change
Expand Up @@ -3168,12 +3168,15 @@ provider conformance cover the consumer family. See [operation and semantic
changes](../../reference/todo-continuation-readback.md). This closes a bounded
L5/L7 gap; permanent projection delivery/recovery, D2 and D3 are still open.

D1 delivery confirmation now follows durable Markdown readback with a typed
canonical revision check. Unpinned settlement retries up to three times using
the returned complete snapshot; pinned projection never silently retargets.
Overlap, churn and confirmation outage remain pending without repeating business
commits. This qualifies the bounded delivery/retry boundary, not permanent
freshness, a background drainer, all L5 consumers or D2/D3. See the
D1 delivery confirmation follows durable Markdown readback. The TS owner now
owns latest/pinned intent and the three-attempt retry decision; Python retains
file locks, durable publication and rendering. Committed `refresh-state` and
same-Turn replay drain the existing projection path without repeating Todo or
quota mutations. Planning, missing-work diagnosis and initial delivery share a
complete canonical snapshot; the final confirmation still reads the provider.
Authoritative emptiness never falls back to stale Markdown. Legacy and preview
refresh remain unchanged. This closes the refresh recovery/diagnostic caller,
not all L5 consumers, a background worker, D2 or D3; see the
[projection contract](../../reference/protocols/active-state-structured-projection-v0.md).

**D2 — qualify exactly one local profile; independent of PostgreSQL deployment.**
Expand Down Expand Up @@ -3266,6 +3269,17 @@ or moving a helper is not by itself a package exit.
| C / L8: Whole-Goal rehearsal and cohort migration | Integrate one exact revision/profile after L2–L7; drain capture, fence old writers, verify canonical readback and projection, then rehearse fenced export/rollback. | D3 evidence packet binds lineage, cursor, source digest, command coverage and profile. Existing Goal migration requires explicit cohort approval; no per-command split authority or stale Markdown revival. |
| D / L9: New-Goal default and bounded retirement | A dedicated default-change PR makes new-Goal creation/onboarding choose the qualified local profile, including settings/readback, installer and packaged clients. Retire old business writers only as their final callers and migration window close. | L8's integrated product/rollback qualification; distinguish new Goal default from existing Goal migration. Publish compatibility/disable guidance, keep explicit provider choice, permanent rendering and validated import/export. T4 can continue after the default ships. |

**2026-09-24 reconciliation.** The count remains an estimated **5–8 complete
packages**, not a count of small fixes: (1) remaining caller/executor fences,
(2) full consumer/projection qualification, (3) SQLite D2, (4) capture and whole-Goal
migration, (5) new-Goal defaults and bounded writer retirement. This refresh
slice advances package 2 without claiming its other consumers are qualified.
SQLite #4910 added the larger measurement axes; #4224 records failed 1 MiB
receipt/scan budgets and still-missing recovery/soak evidence. #4931 is the
in-review read-proof optimization, not proof that D2 passed. Snapshot pagination
#4922 is also in review and must be qualified at its accepted head. None of
these PR statuses grants cutover or changes the selected profile.

**Cadence is evidence-based.** First reconcile the active stack, then deliver A
packages as complete operations while L6/L7 progress independently. B integrates
those contracts into complete user flows; C has one reproducible qualification
Expand Down Expand Up @@ -3327,12 +3341,12 @@ The TS owner shares durable qualification and exact receipt proof between both
paths. See [operation and acceptance](../../reference/reviewed-coordination-promotion.md).
This stage does not authorize an active Goal migration or flip a default.

For an existing claimed Goal, integrate the claim-preserving migration in #4870
with this slice, qualify the exact combined head and resolve its existing CI and
review holds. Preserve the registered owners, existing claims and leases; do not
Claim-preserving migration #4870 and reviewed cutover #4888 are merged;
shadow drain planning #4920 is also merged. Qualify their combined current head
for an existing claimed Goal rather than treating an old PR hold as current. Preserve the registered owners, existing claims and leases; do not
clear ownership to make storage migration appear ready. The saved-plan carrier
must retain migration strategy, registered-agent facts and target digest when
that extension is integrated.
must retain migration strategy, registered-agent facts and target digest during
combined qualification.

The remaining default-on program is still approximately **5–8 cohesive PR
packages**, with scope rather than line counts determining the split: caller /
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2464,10 +2464,12 @@ route planner 本身仍不授予权限。CLI 将已提交回执交给既有 jour
- caller 迁走后才删除旧 projection repair/receipt 路径。退出条件是可复核的
freshness/readback 和可操作修复路径,不能只证明成功渲染过一次。

D1 交付确认现于 Markdown 耐久读回后核对 canonical revision。未固定版本的结算
最多追赶三次,复用返回的完整快照;固定版本不擅自换目标。并发、持续变化及确认故障
保留 pending,不重做业务提交。这闭合有界交付/重试,不代表永久新鲜度、后台 drain、
全部 L5 或 D2/D3;见[投影合同](../../reference/protocols/active-state-structured-projection-v0.md)。
D1 的最新/固定版本意图和三次追赶决定收口到 TS;Python 保留文件锁、耐久落盘与
渲染。已提交的 `refresh-state` 及同 Turn 重试通过现有投影路径恢复显示,不重做 Todo
或 quota 变更。规划、缺失工作诊断及首次渲染复用完整 canonical 快照,耐久写后仍读
provider 确认;权威空集合不回退到陈旧 Markdown。Legacy 与预览行为保持不变。
这关闭刷新恢复/诊断调用方,不代表全部 L5、后台 drain 或 D2/D3 完成;
见[投影合同](../../reference/protocols/active-state-structured-projection-v0.md)。

**D2 — 资格化一个本地 profile,不等待 PostgreSQL 部署。**

Expand Down Expand Up @@ -2532,6 +2534,12 @@ D1 交付确认现于 Markdown 耐久读回后核对 canonical revision。未固
| C/L8:整 Goal 演练与分组迁移 | L2–L7 后汇合一个精确 revision/profile;drain capture、fence 旧 writer、回读 canonical 与投影、演练 fenced export/rollback。 | D3 包绑定 lineage、cursor、source digest、命令覆盖和 profile;已有 Goal 分组迁移需明确批准,不能按命令拆 authority 或复活旧 Markdown。 |
| D/L9:新 Goal 默认与有界退役 | 单独 default-change PR 让新建/onboarding 选择合格本地 profile,配齐 settings/readback、installer 和打包客户端;最后 caller 与迁移窗口退出才删除旧业务 writer。 | L8 整体产品/回滚资格;区分新 Goal 默认和已有 Goal 迁移。发布兼容/停用说明,保留显式 provider、永久 renderer 和合法 import/export。T4 可在默认启用后继续收尾。 |

**2026-09-24 基线核对。** 保留 claim 的 #4870、reviewed cutover #4888、shadow drain
规划 #4920 已合并,后续应验收组合 head,不继续沿用旧的 PR hold。快照分页 #4922、
SQLite 读取证明优化 #4931 仍在评审。#4910 已加入更大测量轴;#4224 实测 1 MiB
receipt/scan 超预算,恢复和自然时间资格仍有缺项,不能将优化 PR 当成 D2 通过。
本次刷新恢复推进下述 consumer/投影包,但没有把其他调用方或默认切换标记完成。

**开发节奏以证据推进。** 先核对在途 stack,再按完整操作交付 A;L6/L7 可独立推进。
B 汇合为完整用户流程,C 形成一次可复现资格检查点,D 用独立 PR 修改默认。
按当前已合并边界,剩余 caller/executor 约 1–2 个包,consumer/投影 1 个,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1869,8 +1869,11 @@ Canonical single-Todo and full-source reads now have one read-only TypeScript
module, separate from mutation orchestration and sharing the provider opening
boundary. Projection delivery composes a revision confirmation with the existing
full-source read; ordinary callers retain their response shape. Python owns
physical Markdown durability/retry, not the current-head comparison. Three-attempt
recovery and pinned-intent preservation use the existing journal-backed path;
physical Markdown durability and rendering. TS owns current-head comparison,
latest/pinned intent and bounded retry. Committed refresh and same-Turn recovery
reuse that path, with one complete planning snapshot also owning missing-work
diagnostics. This removes Python retry/admission policy and the promoted record's
second Markdown-based Todo diagnosis;
no new RPC method, durable ACK or provider default. The stronger confirmation
costs one additional read on a stable delivery. Full L5/D1 qualification, D2 and
cutover remain open; see the [projection contract](../../reference/protocols/active-state-structured-projection-v0.md).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1436,6 +1436,15 @@ transaction 只能靠削弱既有行为才能通过 invariant/recovery/performan
实测交付记录存于[逐条 ledger](ledger/typescript-control-plane-migration-v0/)。
每条记录说明已交付边界及剩余验收缺口;上方 T1–T4 检查点仍是当前迁移计划。

### Canonical 显示确认与刷新恢复

TS 拥有 canonical revision 比较、最新/固定版本意图及三次重试上限;Python 继续执行
文件锁、耐久落盘和 Markdown 渲染。已提交刷新与同 Turn 重试复用这一恢复路径,规划
快照同时供应缺失工作诊断和初始显示,删除 Python 的重试决策及晋升后从旧 Markdown
再判断 Todo 数量的路径。没有增加 RPC 方法或持久 ACK,正常恢复增加一次确认读取。
这是 T3/D1 的刷新调用方闭合;其他 consumer、D2 与整 Goal 切换仍需独立资格。
见[投影合同](../../reference/protocols/active-state-structured-projection-v0.md)。

### Reviewed coordination cutover ownership

Saved-plan execution and fenced recovery now share the TypeScript promotion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,47 @@ from facts; old wire `effective` hints are accepted but cannot override them.
有效租约,未过期但持有人失去资格时返回原因,不自动续租、转移或清理。
读取不提供写授权;release 的 key/version 门禁与幂等、CAS 规则保持不变。

### Refresh recovery and authoritative diagnostics

After promotion, a successful non-preview `refresh-state` now attempts Todo
projection delivery, including recovery of a previously committed same-Turn
writeback. CLI and Turn use the same path. Legacy refresh and preview remain
non-repairing; rejected admission does not acquire a display-write opportunity.
A provider or display failure after the refresh commit is `projection_delivery=pending`,
not a failed or repeated business write. JSON and Markdown responses disclose
that distinction. Retry the original Turn, or use `todo project-markdown` with a
fresh provider revision; do not repeat Todo completion or quota spend.

The planner retains its complete canonical snapshot for delivery rather than
immediately reading it again. The renderer still confirms authority after
durable file readback. TS returns a typed `next_action=retry|finish`; only
latest-head intent may retry an overlap, and no fourth attempt is admitted.
Pinned explicit projection preserves its requested revision. These are internal,
co-deployed request fields, not persisted request bytes or new receipt versions.
Existing receipts and provider formats are unchanged.

The refresh record's missing-work diagnosis also uses the same canonical Todo
summary. Stale Markdown cannot fabricate a missing-task warning or hide a truly
empty canonical group. Markdown remains the source of independent narrative.
Delivery can catch up to a newer provider revision without rewriting the earlier
refresh record or pretending its original planning snapshot was newer.

Recovery adds real rendering, file durability and confirmation work to committed
promoted refreshes. It is not a free read or a claim of lower latency. The normal
path shares the planning read and adds one confirmation read; same-Turn replay
loads the current head before repairing. Missing display recovers only Todo
sections, with the existing private-validation digest and source-ownership
checks. It cannot reconstruct independent Goal narrative or bypass an
unavailable private validation declaration. No timer, new outbox, persistent ACK,
provider default or active-Goal migration is introduced.

中文:已晋升 Goal 的非预览 `refresh-state` 和同 Turn 重试现在会恢复 Todo 显示。
业务成功、显示 pending 分别报告;只重试显示,不重新完成 Todo 或扣费。规划、缺失工作
诊断与投影起点复用完整 canonical 快照,权威空集合不回退到旧 Markdown;耐久写入后
仍读取 provider 确认,由 TS 统一决定是否追赶以及三次上限。Legacy、预览与拒绝请求
不获得新的显示写入。这个默认行为变化只影响已晋升 Goal,增加了渲染和耐久确认成本;
不改变默认 provider。缺失文件仅恢复 Todo 区域,不能恢复独立 Goal 叙述。

## Migration Path

The projector accepts complete legacy records and native `TodoDomainRecord`
Expand All @@ -273,8 +314,8 @@ one provider transaction. After that commit, the Python compatibility adapter
renders the latest head under the Markdown lock and durably reads it back. A
renderer/write failure leaves typed `pending` delivery
evidence without reversing or hiding the canonical commit. A later successful
mutation or `todo project-markdown --execute` replays the current head
idempotently. This is projection recovery, not a second authority path.
mutation, committed `refresh-state` (including same-Turn replay), or
`todo project-markdown --execute` replays the current head idempotently. This is projection recovery, not a second authority path.
The ordinary state writer and projection writer share durable atomic publication.
Missing-display recovery uses create-only publication and cannot overwrite a
concurrently restored document. When bytes already match, execution still syncs
Expand Down Expand Up @@ -303,7 +344,8 @@ only the internal projection readback request opts into confirmation metadata.

The TypeScript read owner validates complete canonical data and compares the
host's durable readback revision with the same loaded head. Python retains
Markdown ownership, durability, bounded IO retry and rendering. A missing
Markdown ownership, physical durability and rendering. The TypeScript confirmation
owns latest-head versus pinned intent and the three-attempt retry decision. A missing
confirmation from a downlevel runtime cannot be treated as delivery success.
The normal successful execution adds one provider read; each caught-up attempt
reuses the already returned full snapshot. This is a freshness cost, not a
Expand Down
4 changes: 3 additions & 1 deletion loopx/control_plane/coordination/local_authority.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,9 @@ def read_canonical_todos_if_promoted(
if (not isinstance(confirmation, Mapping)
or confirmation.get("provider_revision") != projection_readback["provider_revision"]
or confirmation.get("observed_provider_revision") != payload.get("provider_revision")
or confirmation.get("status") not in {"pending", "delivered", "current"}):
or confirmation.get("status") not in {"pending", "delivered", "current"}
or confirmation.get("next_action") not in {"retry", "finish"}
or (confirmation.get("next_action") == "retry" and confirmation.get("status") != "pending")):
raise LocalCoordinationAuthorityUnavailable(
"canonical projection confirmation is missing or invalid",
code="local_authority_projection_confirmation_invalid", payload=payload,
Expand Down
46 changes: 36 additions & 10 deletions loopx/control_plane/todos/projection_delivery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,24 +26,50 @@ export function isProjectionDelivery(value: unknown): value is TodoProjectionDel
export interface ProjectionReadback {
provider_revision: string;
changed: boolean;
attempt: number;
target: "pinned" | "latest";
}

export function decodeProjectionReadback(value: unknown): ProjectionReadback {
if (value === null || typeof value !== "object" || Array.isArray(value)) {
throw new TypeError("projection_readback must be an object");
}
const row = value as Record<string, unknown>;
if (Object.keys(row).length !== 2 || typeof row.provider_revision !== "string" ||
if (Object.keys(row).length !== 4 || typeof row.provider_revision !== "string" ||
!row.provider_revision.trim() || row.provider_revision !== row.provider_revision.trim() ||
typeof row.changed !== "boolean") throw new TypeError("invalid projection_readback");
return {provider_revision: row.provider_revision, changed: row.changed};
typeof row.changed !== "boolean" ||
typeof row.attempt !== "number" || !Number.isSafeInteger(row.attempt) || row.attempt < 1 ||
row.attempt > 3 || (row.target !== "pinned" && row.target !== "latest")) throw new TypeError("invalid projection_readback");
return {provider_revision: row.provider_revision, changed: row.changed,
attempt: row.attempt, target: row.target};
}

export function confirmProjectionReadback(readback: ProjectionReadback, observedRevision: string) {
return {
provider_revision: readback.provider_revision,
observed_provider_revision: observedRevision,
status: readback.provider_revision === observedRevision
? (readback.changed ? "delivered" : "current") : "pending",
} satisfies {provider_revision: string; observed_provider_revision: string; status: TodoProjectionDelivery};
/** One policy for mutation delivery, refresh recovery and explicit projection.
* The display lock does not lock provider commits. Only a latest-head request
* may follow an overlap; exact-revision requests must remain pinned.
*/
export type ProjectionConfirmation = {
provider_revision: string;
observed_provider_revision: string;
} & (
| {status: "delivered" | "current"; next_action: "finish"}
| {status: "pending"; next_action: "retry" | "finish";
reason_code: "todo_projection_revision_advanced"; retryable: true;
retry_business_mutation: false; recommended_action: string}
);

export function confirmProjectionReadback(
readback: ProjectionReadback, observedRevision: string,
): ProjectionConfirmation {
const basis = {provider_revision: readback.provider_revision,
observed_provider_revision: observedRevision};
if (readback.provider_revision === observedRevision) {
return {...basis, status: readback.changed ? "delivered" : "current", next_action: "finish"};
}
return {...basis, status: "pending",
next_action: readback.target === "latest" && readback.attempt < 3 ? "retry" : "finish",
reason_code: "todo_projection_revision_advanced", retryable: true,
retry_business_mutation: false,
recommended_action: "Read the current provider revision with todo list, then retry todo project-markdown for that revision.",
};
}
Loading
Loading