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
2 changes: 1 addition & 1 deletion docs/architecture/rfcs/loopx-overall-roadmap-v0.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ P0 blocks correctness or continuity in the current user journey. P1 enables repe
| **S4 Runtime/host/daemon · P0/P1** | Attached/managed, Turn, broker, runtime connectors and Desktop repairs exist; registration does not establish executable capacity | Qualify multi-Turn supervision for one real supported combination; restart/cancel/drain/stop retain work and fence old executors. Then expand host parity, unique service-profile ownership, clean installation and upgrades; show unsupported adapter capabilities |
| **S5 Frontend, Lark and human interaction · P0/P1** | Local chat, settings, proposals and partial Goal Channel verticals exist; Goal Overview, Tasks, the W1 work map, usage, acceptance readback and lifecycle stop ship as separate regions without one page owner; shared audience/session/work readback needs qualification | One journey spans settings, work graph, handoff, blockers, cost, corrections, artifacts and return. **Page:** the [Goal workspace](goal-workspace-surface-v0.md) composes that journey per Goal over shared typed projections: a persistent masthead with scoped Stop, vitals with one meaning per figure (named window and coverage, unknown is not zero), work grouped by owner, results and an all-work rail. M1–M2 come first, after first-screen preview approval. **Cases:** reconnect/repeated-click/stale/original-route. **Realtime IM** reuses Chat/Turn: isolate independent conversations on one listener, then qualify ordinary DM onboarding, explicit role selection, busy-session admission, provisional progress, media and exact permission callbacks through [the shared operational contract](capable-manager-semantic-handoff-v0.md#10-operational-contract). **Team:** [Live team workspace](live-team-workspace-v0.md) makes exchange, revision and original-coordinator continuation visible. Its [Work-scale map track](live-team-workspace-v0.md#11-delivery-order-and-relationship-to-aggressive-r2-progress) draws each Goal's typed Todo relations first (W1, the Goal workspace's Map lens), then live state and outputs on the same nodes. Then intelligent review, keyboard accessibility and a launcher-only command palette, bilingual terminology, actionable errors and offline degradation; interrupt only for actual decisions |
| **S6 Materials, evidence, memory and learning · P1** | Authority registry, material lifecycle/frontier, decision context, reward memory and turn recall exist; explicit project material packets and source-verifier gates are implemented, while private source initialization/Core binding and ordinary-conversation adoption remain unqualified; direction baseline and parts of attribution remain proposed | Connect material revision→same-Agent read→decision reference→artifact/outcome. Expose expiry/revocation/source loss and forgetting policy. Handoff preserves decision-relevant summaries and authorized artifacts; qualify OpenViking/Obelisk as optional providers. Prove causal utility with controls, not relevance alone |
| **S7 Budget, scheduling and fleet scale · P0 observation/P1–P2 expansion** | Quota/scheduler and partial usage aggregates exist; full provider cost, distributed reservations and hundred-Agent concurrency need evidence | Separate configured budget, admission, consumption and estimates; unknown is not zero and replay cannot double-charge. R7 pagination/bounded summaries and [complete-history transport](typescript-control-plane-migration-v0.md), including refresh/replay/single-debit evidence beyond the RPC limit; provider/host limits, fairness, backpressure, event wake and isolation; report registration/activity/throughput and cost per accepted outcome separately. Receipt-backed semantic progress closes its original host Turn without completing an open/waiting Todo; File/SQLite guard replay preserves verified writeback when a later dependency wait changes the frontier and covers automatic quiet writeback during a receipt-owned retry, preserving independent work and monitor clocks. [Full quota and TurnEnvelope](../../reference/protocols/turn-envelope-v0.md) retain the original executable settlement command and single debit. Follow [the quota settlement contract](../../quota-allocation.md#receipt-backed-settlement-progress). Cross-Todo continuation isolation and live host backoff/readback remain separate acceptance; this bounded repair does not qualify fleet scale or host latency. |
| **S7 Budget, scheduling and fleet scale · P0 observation/P1–P2 expansion** | Quota/scheduler and partial usage aggregates exist; full provider cost, distributed reservations and hundred-Agent concurrency need evidence | Separate configured budget, admission, consumption and estimates; unknown is not zero and replay cannot double-charge. R7 pagination/bounded summaries and [complete-history transport](typescript-control-plane-migration-v0.md), including refresh/replay/single-debit evidence beyond the RPC limit; provider/host limits, fairness, backpressure, event wake and isolation; report registration/activity/throughput and cost per accepted outcome separately. Receipt-backed semantic progress closes its original host Turn without completing an open/waiting Todo; File/SQLite guard replay preserves verified writeback when a later dependency wait changes the frontier and covers automatic quiet writeback during a receipt-owned retry, preserving independent work and monitor clocks. [Full quota and TurnEnvelope](../../reference/protocols/turn-envelope-v0.md) retain the original executable settlement command and single debit. Follow [the quota settlement contract](../../quota-allocation.md#receipt-backed-settlement-progress). File/SQLite CLI coverage also rejects an original Turn’s step write into a newly selected Todo, preserves that Todo’s step/CAS and dependencies, and settles the original writeback once. Installed adoption, live Host waiting-state cadence/readback and fleet scale remain separate acceptance. |
| **S8 Capabilities, extensions and domain integration · P1/P2** | Capability catalog, extension lifecycle, hooks, engineering/research/content/office capabilities and computer-use contracts exist | First exercise the shared control plane with existing issue-fix/PR-review and material/research callers. Every provider has readiness/version/permissions/default-off/uninstall/rollback/isolation and real-entry evidence. New domain effects start with one simulated operation, not a marketplace or workflow DSL |
| **S9 Identity, authority, privacy and trust · continuous P0/P1–P2 remote** | Public/private scope, capability gates, fencing and confirmation contracts belong to existing owners | R1/R3 cover sender/audience/artifact scope and stale authority; R6 authenticates tenant/Goal/actor/host, rotation/revocation and least privilege. Qualify credential custody, untrusted tool/document inputs, dependency supply chain, audit retention/deletion and vulnerability response through real paths; roles/messages/memory mint no write authority |
| **S10 Reliability, diagnostics and operations · P0/P1** | Recovery/canary, read-only diagnostics prototype and DSH event adapter exist; C0/C1, overhead and full operations qualification are open | Failure classification→observable state→recovery drill→regression prevention; process/storage/network/delivery failures and data growth. Accepted Chat requests must settle even when runtime preparation fails before dispatch; qualify missing runtime assets, stop races and recovery without replay under [the shared conversation operational contract](capable-manager-semantic-handoff-v0.md#10-operational-contract). A context/provider read returning after the stop wait must honor the persisted Turn and exact Session claim: no late provider dispatch or handoff, even when a fresh request has completed. This bounded GQ08 repair does not certify upstream interrupt fidelity or effects already admitted elsewhere. Use [bounded repair lookup and targeted diagnostics](../../../skills/loopx-self-repair/references/targeted-diagnostics.md) to reduce redundant reads above the provider boundary; measure backend-specific cold/warm reads, writes and lock waits separately. Freeze SLO/RPO/RTO/capacity/retention boundaries and measure before qualification. Lark transport backpressure and drain retain the App consumer lease; unpersisted buffered lines are not accepted work or completion receipts. Runbooks include upgrade, restore, stop and human takeover; test counts do not prove recovery |
Expand Down
17 changes: 17 additions & 0 deletions docs/reference/protocols/turn-envelope-v0.md
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,23 @@ ineligible/rejected choice still replays the receipt without mutation; a
first-call rejection reports
`heartbeat_receipt.status=not_committed` and writes no receipt event.

A receipt-bound `refresh-state --next-action` must refine that original Turn's
Goal, Agent and Todo. If waiting or completion makes the current selector choose
another Todo, the existing typed recommendation owner rejects the step before
appending a run; even the other Todo's fresh read basis cannot retarget the
original writeback. Finish the original writeback without `--next-action`, then
select subsequent work through a fresh guard. A matching bound step records
`settlement_alignment=exact`; ordinary unbound steps retain `not_applicable`.
This changes the previous acceptance of a mismatched task-step write, without
clearing dependencies, altering Todo authority or granting another Turn.

中文:绑定回执的 `refresh-state --next-action` 必须属于原 Turn 的 Goal、Agent
和 Todo。原任务等待或完成后,即使当前选择器已选中另一个 Todo,且提供其最新
read basis,同一 TS recommendation owner 仍在追加 run 前拒绝跨任务步骤。
先去掉 `--next-action` 完成原写回,再通过 fresh guard 选择后续工作。匹配步骤保留
`settlement_alignment=exact`,无 Turn 绑定的普通步骤仍为 `not_applicable`。
本项修复此前错误接受的跨任务写入,不清依赖、不改变 Todo 权威或授予新 Turn。

For an eligible explicit choice deferred solely by runnable autonomous replan,
the typed qualifier adds `inline_reentry_allowed=true`. After durably retaining
that choice, the CLI now executes one same-Turn guard reentry and returns its
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Source I/O for the existing TS recommendation owner; no task write authority."""
from __future__ import annotations

from collections.abc import Iterator
from collections.abc import Iterator, Mapping
from contextlib import ExitStack, contextmanager
from pathlib import Path
from typing import Any
Expand Down Expand Up @@ -76,6 +76,7 @@ def latest_bound_recommendation(runs: list[dict[str, Any]], agent_id: str) -> di
def lane_recommendation_context(source: dict[str, Any], *, agent_id: str | None,
selected_todo: dict[str, Any] | None, task: dict[str, Any] | None,
prior_resolution: dict[str, Any] | None = None, write: dict[str, Any] | None = None,
settlement_identity: Mapping[str, Any] | None = None,
) -> dict[str, Any]:
# Reuse the existing frontier's semantic fact vocabulary. Display indexes,
# selection reasons and bounded text decorations are not task revisions.
Expand All @@ -85,6 +86,7 @@ def lane_recommendation_context(source: dict[str, Any], *, agent_id: str | None,
result = effect_runtime_result("work_item.refresh_recommendation.lane", {
**source, "agent_id": agent_id, "selected_todo": selected_todo,
"task_facts": facts, "prior_resolution": prior_resolution, "write": write,
"settlement_identity": dict(settlement_identity) if settlement_identity is not None else None,
})
except EffectRuntimeRejected as error:
raise ValueError(str(error)) from error
Expand Down
1 change: 1 addition & 0 deletions loopx/control_plane/work_items/refresh_recommendation.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ def resolve_refresh_recommendation(
context = lane_recommendation_context(source_context, agent_id=agent_id,
selected_todo=selected, task=task,
prior_resolution=latest_bound_recommendation(runs or [], agent_id),
settlement_identity=settlement_identity,
write={"text": next_step, "expected_basis": next_step_basis} if next_step else None)
if next_step:
resolved = context["resolution"]
Expand Down
11 changes: 10 additions & 1 deletion loopx/control_plane/work_items/refresh_recommendation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,23 @@ export function resolveLaneRecommendation(value: unknown): JsonObject {
if (!actor || !agents.includes(actor)) {
return reject("next_action_actor_unregistered", "Next Action requires a registered --agent-id");
}
// The current selector may legitimately choose B after receipt-bound A
// starts waiting or completes. A's writeback cannot create B's step receipt,
// even with a fresh B basis. Ordinary writes have no settlement binding.
const settlement = settlementIdentity(request.settlement_identity);
if (settlement && (settlement.goal_id !== goalId || settlement.agent_id !== actor ||
settlement.todo_id !== selected?.todo_id)) {
return reject("next_action_task_unavailable",
"Next Action does not match the original Turn's Goal, agent and Todo; finish the original Turn writeback without --next-action, then select the next Todo through a fresh guard");
}
if (expected && expected !== basis) {
return reject("next_action_basis_conflict", "Next Action task or lane read basis changed; reread status and rejudge before retrying");
}
if (!runnable || !taskFacts || taskFacts.todo_id !== selected?.todo_id) {
return reject("next_action_task_unavailable", "No selected eligible advancement Todo for this agent; update or select work through the existing Todo route");
}
const resolution: JsonObject = {
...recommendation(text, "agent_lane_step", "agent_lane", "not_applicable", selected),
...recommendation(text, "agent_lane_step", "agent_lane", settlement ? "exact" : "not_applicable", selected),
goal_id: goalId, agent_id: actor, todo_basis: taskBasis, source_revision: sourceRevision,
read_basis: basis, step_revision: digest([basis, text]),
};
Expand Down
Loading
Loading