Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ const unavailable: DelegationPreflight = {
turn_route: null,
authority_ready: false,
authority_reason: "Goal acceptance requires an existing canonical authority",
authority_state: "promotion_required",
authority_next_action: "preview_reviewed_goal_authority_promotion",
promotion_from_surface_allowed: false,
executor: null,
effects: {
host_invoked: false,
Expand All @@ -26,6 +29,9 @@ for (const [zh, expectedLabel, expectedBoundary] of [
if (!html.includes(expectedLabel)) throw new Error(`missing state label: ${expectedLabel}`);
if (!html.includes("Goal acceptance requires an existing canonical authority")) throw new Error("missing authority reason");
if (!html.includes(expectedBoundary)) throw new Error(`missing boundary copy: ${expectedBoundary}`);
if (!html.includes(zh ? "下一步:预览整 Goal 协调 Authority 晋级" : "Next: preview whole-Goal coordination-authority promotion")) {
throw new Error("missing reviewed promotion next action");
}
if (/Local launch prerequisites met|本机启动条件已满足/.test(html)) throw new Error("rendered launchable copy for unavailable authority");
}
if (Object.values(unavailable.effects).some(Boolean)) throw new Error("authority-unavailable response must report zero effects");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ export type DelegationPreflight = {
turn_route: string | null;
authority_ready: boolean;
authority_reason: string | null;
authority_state: "promotion_required" | "unavailable" | "promoted";
authority_next_action: "preview_reviewed_goal_authority_promotion" | "repair_canonical_authority" | "none";
promotion_from_surface_allowed: false;
executor: {host: string; available: boolean | null; reason: string | null; profile: string | null} | null;
effects: {host_invoked: boolean; state_written: boolean; quota_spent: boolean; scheduler_acknowledged: boolean};
};
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ const capabilityCopy: Record<WorkspaceLocale, Record<string, LocalizedCopy>> = {
displayName: "Local authority shadow",
description: "Observes post-commit Todo and task-lease state through the shared authority contract without taking write authority.",
},
coordination_runtime_shadow: {
displayName: "Coordination runtime shadow",
description: "Captures transaction-bound Todo and task-lease mutations for reviewed whole-Goal coordination-authority promotion.",
},
multi_subagent: {
displayName: "Adaptive child capacity",
description: "Sets bounded child-agent capacity and the public-safe responsibility domains in which parallel work may be delegated.",
Expand Down Expand Up @@ -102,6 +106,10 @@ const capabilityCopy: Record<WorkspaceLocale, Record<string, LocalizedCopy>> = {
displayName: "本地 Authority 影子观测",
description: "通过共享 Authority contract 观测提交后的 Todo 与 task lease 状态,但不取得写入权。",
},
coordination_runtime_shadow: {
displayName: "协调 Runtime 影子",
description: "捕获事务绑定的 Todo 与 task lease 变更,为经评审的整 Goal 协调 Authority 晋级提供证据。",
},
multi_subagent: {
displayName: "自适应子 Agent 容量",
description: "限定子 Agent 容量与可公开的职责域,只有落在这些边界内的工作才能并行委派。",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,15 @@ export function DelegationPreflightStatus({check, zh}: {check: DelegationPreflig
const disclaimer = check.state === "authority_unavailable"
? (zh ? "未检查或启动执行器" : "No executor was inspected or launched")
: (zh ? "不代表正在执行" : "Does not mean executing");
const authorityAction = check.authority_next_action === "preview_reviewed_goal_authority_promotion"
? (zh ? "下一步:预览整 Goal 协调 Authority 晋级" : "Next: preview whole-Goal coordination-authority promotion")
: check.authority_next_action === "repair_canonical_authority"
? (zh ? "下一步:修复规范 Authority 读回" : "Next: repair canonical authority readback")
: null;
return <p role="status">
{zh ? labels[check.state].zh : labels[check.state].en}
{detail ? ` · ${detail}` : ""}
{authorityAction ? ` · ${authorityAction}` : ""}
{` · ${disclaimer}`}
</p>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,7 @@ assert.match(capabilityWorkbench, /configuration_editor\.writable_scopes\.length
assert.match(capabilityWorkbench, /orderCapabilitiesForPresentation\(capabilities, locale\)/, "Machine and Goal catalogs use one presentation-order policy");
for (const capabilityId of [
"change_quality_qualification",
"coordination_runtime_shadow",
"explore_graph",
"explore_harness",
"lark_event_inbox",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1782,20 +1782,35 @@ promote the shadow or make a coordination decision.
The administrative caller is explicit and preview-first:

```bash
loopx configure-goal --goal-id <goal-id> \
--coordination-runtime-shadow-file --execute
loopx coordination-shadow inspect --goal-id <goal-id>
loopx coordination-shadow bootstrap --goal-id <goal-id>
loopx coordination-shadow bootstrap --goal-id <goal-id> --execute
loopx coordination-shadow qualify --goal-id <goal-id> \
--minimum-operations 3 \
--require-event-kind todo_claim \
--require-event-kind task_lease_acquire
loopx coordination-shadow promote --goal-id <goal-id> \
--minimum-operations 3 \
--require-event-kind todo_claim
loopx coordination-shadow promote --goal-id <goal-id> \
--minimum-operations 3 \
--require-event-kind todo_claim --execute
loopx coordination-shadow rollback --goal-id <goal-id> \
--provider-revision <revision-from-inspect> --execute
```

It derives the compact projection from the current canonical Todo and
task-lease views, reports only counts and digests, and requires `--execute`
before invoking bootstrap. A successful write is immediately read back through
before invoking bootstrap or promotion. `promote` is effect-free without
`--execute`; its preview returns the exact qualified revision, projection
digest, writer-fence identity, and rollback identity. Apply holds the shared
maintenance and legacy source locks while it revalidates the source snapshot,
qualifies the exact shadow lineage, engages the durable writer fence, commits
the canonical head, and reads back the promotion receipt. v0 rejects a Goal
whose already-qualified mode is not `hard_lease`; promotion never changes that
mode as a side effect. A successful write is immediately read back through
the typed parity inspection. The command remains unavailable unless the exact
goal-level `file_v0` shadow opt-in is active.

Expand Down Expand Up @@ -1857,10 +1872,24 @@ uses that answer yet. Promotion still requires an atomic provider-first read
flip together with legacy-writer fencing; a fallback to Markdown after that
flip would recreate split authority and is forbidden.

The provider-first read flip and fencing every legacy coordination writer
remain mandatory evidence for the separately reviewed local canonical
promotion. Remote NoKV/PostgreSQL shadowing therefore remains Stage 3 and
cannot use this default-off hook as authority.
The reviewed operator path now makes the provider-first read flip and legacy
writer fence one TypeScript-owned cutover transaction; it is never called from
a read, delegation, frontend, or Lark path. A real Goal still needs its own
exact qualification, quiescent `hard_lease` transition, preview, explicit
apply, restart readback, and managed-worker acceptance before that Goal may be
called promoted. Remote NoKV/PostgreSQL shadowing therefore remains Stage 3
and cannot use this default-off hook as authority.

Read-only consumers now share an explicit authority-transition projection.
Managed-delegation preflight and its packaged Dashboard view distinguish
`promotion_required`, `unavailable`, and `promoted`, and publish a typed next
action without starting a Turn or executor. The Goal Channel projection used
by Lark exposes the same state while its existing `mode=read_only` and truth
contract keep `projection_is_writable=false` and `write_authority=none`. Its
renderer derives the matching next action for operators; only the reviewed
TypeScript preview may prove readiness. This closes the explanatory path
without turning Chat or Lark into a second promotion owner or duplicating the
same source and authority facts in every status payload.

The next Stage 2C implementation slice adds the TypeScript cutover kernel but
does not yet change the default runtime. One pure reducer now derives the
Expand All @@ -1882,10 +1911,11 @@ task-lease acquire/renew/transfer/release check the same fence while holding the
lease lock. The absent-fence path remains a zero-runtime-call compatibility
path; a present, unreadable, or invalid fence fails closed. The promotion
orchestrator must acquire those same two legacy locks before engaging the fence,
so no legacy write can pass its check and commit after cutover. Provider-first
CLI routing and the lock-owning promotion operation remain the next slice; until
they land, this integration deliberately blocks split-brain writes rather than
silently falling back.
so no legacy write can pass its check and commit after cutover. The lock-owning
`coordination-shadow promote` path now lands that slice. The remaining
acceptance work is per-Goal qualification and product projection, not a second
Python promotion state machine; an interrupted fence without exact canonical
readback fails closed for operator recovery rather than silently falling back.

The Todo collection-read slice routes `loopx todo list` to `FileAuthorityStore`
only after the durable fence exists. It reuses the same filtering, ordering,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1426,19 +1426,32 @@ promotion shadow,也不能参与协调决策。
管理面 caller 是显式且 preview-first 的:

```bash
loopx configure-goal --goal-id <goal-id> \
--coordination-runtime-shadow-file --execute
loopx coordination-shadow inspect --goal-id <goal-id>
loopx coordination-shadow bootstrap --goal-id <goal-id>
loopx coordination-shadow bootstrap --goal-id <goal-id> --execute
loopx coordination-shadow qualify --goal-id <goal-id> \
--minimum-operations 3 \
--require-event-kind todo_claim \
--require-event-kind task_lease_acquire
loopx coordination-shadow promote --goal-id <goal-id> \
--minimum-operations 3 \
--require-event-kind todo_claim
loopx coordination-shadow promote --goal-id <goal-id> \
--minimum-operations 3 \
--require-event-kind todo_claim --execute
loopx coordination-shadow rollback --goal-id <goal-id> \
--provider-revision <revision-from-inspect> --execute
```

它从当前 canonical Todo 与 task-lease view 派生紧凑 projection,只报告计数与摘要,
并要求 `--execute` 才调用 bootstrap。写入成功后会立即通过 typed parity inspection
并要求 `--execute` 才调用 bootstrap 或 promotion。`promote` 未带 `--execute` 时零写入;
preview 返回精确的 qualified revision、projection digest、writer-fence identity 和
rollback identity。apply 会在同一段 maintenance 与 legacy source 锁生命周期内重新
验证 source snapshot、资格化精确 shadow lineage、engage 持久 writer fence、提交
canonical head,并读回 promotion receipt。v0 会拒绝尚未资格化为 `hard_lease` 的 Goal,
且绝不会把 handoff mode 变化藏在 promotion 副作用中。写入成功后会立即通过 typed parity inspection
读回。除非目标开启精确的 goal-level `file_v0` shadow opt-in,否则该命令不可执行。

promotion 前 rollback 带精确 revision fence,且不删除数据。TypeScript 会把命中的
Expand Down Expand Up @@ -1486,9 +1499,21 @@ Todo 读取,尚无 lifecycle 或 settlement 调用方消费这个答案。正
把 provider-first read flip 与 legacy-writer fencing 作为同一个受审原子边界;flip 后
回退 Markdown 会重新制造双权威,因此禁止。

后续仍需完成 provider-first read flip,并 fence 全部 legacy coordination writer;这些
仍是独立评审的本地 canonical promotion 的强制证据。因此 NoKV/PostgreSQL 远端 shadow
仍属于 Stage 3,不能把这个默认关闭的 hook 当作 authority。
受评审的 operator path 现在把 provider-first read flip 与 legacy writer fence 收进同一
个 TypeScript-owned cutover transaction;任何 read、delegation、frontend 或 Lark 路径
都不能隐式调用它。真实 Goal 仍必须分别完成精确 qualification、静止态 `hard_lease`
切换、preview、显式 apply、重启读回和 managed-worker acceptance,之后才能宣称该 Goal
已经 promoted。因此 NoKV/PostgreSQL 远端 shadow 仍属于 Stage 3,不能把这个默认关闭的
hook 当作 authority。

只读消费者现在复用一份显式的 authority-transition 投影。managed delegation preflight
及其打包 Dashboard 展示会区分 `promotion_required`、`unavailable` 与 `promoted`,并给出
typed next action,但不会启动 Turn 或执行器。Lark 使用的 Goal Channel 投影遵守同一边界,
继续通过现有 `mode=read_only` 与 truth contract 声明
`projection_is_writable=false`、`write_authority=none`,renderer 再为 operator 派生对应的
next action。只有经评审的 TypeScript preview 才能证明 readiness。这补齐了解释链路,
同时不会在每份 status payload 重复相同的来源/权限事实,也不会把 Chat 或 Lark 变成
第二个 promotion owner。

下一块 Stage 2C 实现加入了 TypeScript cutover kernel,但尚未改变默认 runtime。
同一个纯 reducer 从一次 Todo/lease mutation 派生 projection、event 与 receipt;显式
Expand All @@ -1506,8 +1531,10 @@ fail-closed write-check hook;promotion 可按 operation receipt 重放,provi
时检查同一个 fence。fence 不存在时保持零 runtime 调用的默认兼容路径;fence 存在、
不可读或不合法时一律 fail closed。后续 promotion orchestrator 必须先取得这两把 legacy
lock,再 engage fence,从而保证不存在某次 legacy write 已通过检查、却在 cutover 后才
提交。provider-first CLI 路由和持锁 promotion operation 仍是下一切片;在它们落地前,
本集成选择阻断 split-brain 写入,而不会静默回退。
提交。持锁的 `coordination-shadow promote` 路径现在完成了这一切片。剩余验收属于逐
Goal 的 qualification 与产品投影,而不是第二套 Python promotion state machine;若
发生 fence 已写入但 canonical readback 不成立的中断,会 fail closed 等待 operator
recovery,绝不静默回退。

Todo collection-read 切片只在 durable fence 已存在时把 `loopx todo list` 路由到
`FileAuthorityStore`。它与 legacy 路径复用同一套过滤、排序、resume 和 summary
Expand Down
2 changes: 1 addition & 1 deletion examples/shared-goal-authority-e2e/mutants.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ def command(self) -> list[str]:
"tests/control_plane_ts/shadow_management.test.ts", 'management manifest hash'),
Case('management_phase', ((COORDINATION + "shadow_management.ts", replacement('operation.kind !== kind || !phases.includes(String(operation.phase))', 'operation.kind !== kind')),),
"tests/control_plane_ts/shadow_management.test.ts", 'management phase validation'),
Case('management_goal_binding', ((COORDINATION + "shadow_management.ts", replacement('value.goal_id !== goal || ', '')),),
Case('management_goal_binding', ((COORDINATION + "shadow_management.ts", replacement(' || value.goal_id !== goal\n || ', '\n || ')),),
"tests/control_plane_ts/shadow_management.test.ts", 'management goal binding'),
Case('management_candidate_lineage', ((COORDINATION + "shadow_management.ts", replacement('candidate.capture_lineage_id !== expectedLineage', 'false')),),
"tests/control_plane_ts/shadow_management.test.ts", 'rollback refuses a different valid candidate lineage'),
Expand Down
5 changes: 5 additions & 0 deletions loopx/capabilities/configuration_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,11 @@ def capability_configuration_editor(
"writable_scopes": ["goal"],
"fields": [_field("enabled", "Enabled", "boolean")],
},
"coordination_runtime_shadow": {
"supported_scopes": ["goal"],
"writable_scopes": ["goal"],
"fields": [_field("enabled", "Enabled", "boolean")],
},
"lark_kanban_heartbeat_sync": {
"supported_scopes": ["goal"],
"writable_scopes": ["goal"],
Expand Down
9 changes: 9 additions & 0 deletions loopx/chat_goal_configuration_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,12 @@ def _local_authority_shadow_options(config: Mapping[str, Any]) -> dict[str, Any]
return {"clear_local_authority_shadow": True}


def _coordination_runtime_shadow_options(config: Mapping[str, Any]) -> dict[str, Any]:
if _boolean_configuration("coordination_runtime_shadow", config, "enabled"):
return {"coordination_runtime_shadow_file": True}
return {"clear_coordination_runtime_shadow": True}


def _goal_capability_options(
capability_id: str,
configuration: Mapping[str, Any] | None,
Expand Down Expand Up @@ -181,6 +187,7 @@ def _goal_capability_options(
"pull_request_review": {"wait_for_ci", "review_priority"},
"change_quality_qualification": {"enabled", "safe_fix", "strict_receipt"},
"local_authority_shadow": {"enabled"},
"coordination_runtime_shadow": {"enabled"},
"lark_kanban_heartbeat_sync": {"enabled"},
"periodic_report": {"enabled", "profile_preset", "route_ref", "timezone", "schedule"},
"reward_memory": {"config_path", "enabled_agents"},
Expand Down Expand Up @@ -234,6 +241,8 @@ def _goal_capability_options(
return _change_quality_options(config)
if capability_id == "local_authority_shadow":
return _local_authority_shadow_options(config)
if capability_id == "coordination_runtime_shadow":
return _coordination_runtime_shadow_options(config)
return {
"lark_kanban_heartbeat_sync": _boolean_configuration(
capability_id, config, "enabled"
Expand Down
Loading
Loading