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
20 changes: 20 additions & 0 deletions docs/architecture/rfcs/typescript-control-plane-migration-v0.md
Original file line number Diff line number Diff line change
Expand Up @@ -1536,6 +1536,26 @@ and receipt identity remain intact. This corrects misleading CLI JSON readback
for peer-scoped gates; it does not migrate the remaining route or primary-action
builders, reserve recommendations, or complete T3/D1–D3.

**Base quota admission composition.** `quota/run_decision.ts` now owns the
ordered capability, workspace, automation, replan, terminal, inbox and coordinator
overlays that produce the base run decision. The Python classifier and its two
action helpers are retired; the existing public adapter makes one coarse native
request. Goal terminal evidence and peer-scope facts retain their existing owners
as a transition. Their exit requires migrating the shared Goal source projection
and all its callers together. The Python public function, dataclass and diagnostic
codec retire when CLI/Host callers use the typed kernel directly. The target is
TypeScript ownership throughout, with no Python rule fallback.
The adapter transports bounded facts and diagnostic strings, then applies the
typed quota patch without round-tripping source numbers or metadata. Receipt-bound
overlays, later route/action builders and effect authority retain their owners.
The existing effective-action vocabulary and generated TS binding are reused;
its canonical Python enum remains until a separate contract-owner cutover.
The TypeScript producer witness executes the real typed classifier against shared guard fixtures and rejects a
changed rule or an enum-only substitute. This delivers the implementation and
semantic parity for one base-admission consumer. Full-CLI performance acceptance
is held for owner review after a p95 regression; whole-Goal migration and
provider/default qualification remain open.

**Long-history transport boundary.** Replan history still has one TS decision
owner. Small requests retain the inline codec; larger complete fact snapshots
travel through a private, digest-bound local file reference. The same reducer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1027,6 +1027,21 @@ T3/D1 reader,未完成全部 Todo writer、retention/compaction 或 promotion

**Scoped gate 动作回读。** 最终 quota 包在选择、能力、workspace、回执及通知决策之后,通过 TS quota 规则投影 scoped User gate/action override。可选 `selected_action` 只在 interaction 允许交付时取最终选中 Todo 的文字;待选择、修复和已结算包省略该字段。准入诊断与回执身份保留。这修正 peer gate 场景的 CLI JSON 误导,不代表剩余 route/primary-action builder 已迁移、推荐已成为预留,或 T3/D1–D3 已完成。

**基础配额准入组合。** `quota/run_decision.ts` 现在统一按顺序组合能力、workspace、
automation、replan、终态、inbox 和协调者覆盖规则,生成基础运行决定。Python 分类器
及其两个动作 helper 已退役;原有公共适配器只发一次粗粒度 native 请求。Goal 终态
证据和 peer 作用域事实暂由既有 owner 提供;共享 Goal 来源投影与所有调用方一起
迁移后退役。CLI/Host 调用方直接使用类型化内核后,Python 公共函数、dataclass
及诊断 codec 退役。最终实现全部由 TypeScript 持有,不设 Python 规则回退。
适配器传递有界事实及诊断字符串,再应用
类型化配额补丁,不让来源数值或元数据经历 JSON 往返转换。回执绑定覆盖、后续
route/action builder 和 effect 权限保留各自 owner。沿用既有 effective-action
词表及生成的 TS binding;canonical Python enum 等独立契约 owner 切换后退役。
TS 生产者验证器通过共享 guard fixture 执行真实 TS 分类器,并拒绝规则变更或
仅枚举 owner 的替代结果。这交付一个基础准入消费者的实现及语义一致性;完整 CLI
出现 p95 回退,性能验收保留 owner 复核门禁。整 Goal 迁移及 provider/默认配置
资格仍待完成。

**长历史传输边界。** Replan 历史仍由一个 TS owner 决策。小请求保留 inline
codec;较大的完整事实快照通过私有临时文件和摘要绑定的引用传递。同一 reducer
校验全部记录、agent 作用域内的 ACK 及重试身份;RPC 预算和展示窗口都不允许截断
Expand Down
8 changes: 4 additions & 4 deletions examples/semantic-vocabulary-drift-smoke.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@
LITERAL_SCAN_ROOTS = ["loopx"]
# Input producers with an executable witness in loopx.semantics.production.
INPUT_PRODUCER_ANCHOR = {
"effective_action": "loopx/control_plane/quota/run_decision.ts::resolveQuotaRunDecision",
"turn_result_kind": "loopx/control_plane/turn_driver/transaction.py::_result_kind",
"loop_disposition": "loopx/control_plane/turn_driver/loop_controller.py::decide_loop_disposition",
# The settlement binding kind is decided inside the TypeScript builder, so
Expand All @@ -210,14 +211,13 @@
}
PRODUCER_VOCABULARY_ANCHOR = {
"effective_action", "turn_route", "loop_disposition", "agent_scope_frontier_action", "turn_result_kind",
# First cross-runtime vocabulary carrying executed production evidence. One
# named boundary, not a claim about the rest of the cross-runtime set.
# Executed evidence is bound to named entrypoints, not every cross-runtime producer.
"settlement_binding_kind",
}
RETURN_PRODUCER_ANCHOR = {
"turn_route": {"loopx/control_plane/turn_driver/driver.py::_typed_route", "loopx/control_plane/turn_driver/loop_controller.py::_envelope_route", "loopx/control_plane/turn_driver/driver.py::build_loopx_turn_plan"},
"loop_disposition": {"loopx/control_plane/turn_driver/turn_contract_generated.py::project_turn_route"},
"effective_action": {"loopx/control_plane/quota/decision_summary.py::quota_effective_action", "loopx/control_plane/quota/decision_summary.py::_task_orchestration_effective_action"},
"effective_action": {"loopx/control_plane/quota/run_decision.ts::quotaEffectiveAction", "loopx/control_plane/quota/run_decision.ts::taskOrchestrationEffectiveAction"},
"turn_result_kind": {"loopx/control_plane/turn_driver/executor.py::_task_validation_receipt"},
}
# Reviewed output arguments/paths replace the old any-enum-use heuristic. These
Expand All @@ -231,7 +231,7 @@
},
}
RETURN_PATH_ANCHOR = {
"effective_action": {"loopx/control_plane/quota/decision_summary.py::_task_orchestration_effective_action": [0]},
"effective_action": {"loopx/control_plane/quota/run_decision.ts::taskOrchestrationEffectiveAction": [0]},
"turn_route": {"loopx/control_plane/turn_driver/driver.py::build_loopx_turn_plan": ["route", "kind"]},
"turn_result_kind": {"loopx/control_plane/turn_driver/executor.py::_task_validation_receipt": ["recovery_kind"]},
}
Expand Down
1 change: 1 addition & 0 deletions loopx/control_plane/effect_runtime_handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,7 @@ export function createEffectRuntimeHandlers(
lazyHandler(() => import("./quota/unsettled_host_turn_recovery.ts"), ({reduceUnsettledHostTurnRecovery}) => reduceUnsettledHostTurnRecovery),
],
["quota.turn_envelope.evaluate", lazyHandler(() => import("./quota/turn_envelope.ts"), ({evaluateTurnEnvelope}) => evaluateTurnEnvelope)],
["quota.run_decision", lazyHandler(() => import("./quota/run_decision.ts"), ({resolveQuotaRunDecision}) => resolveQuotaRunDecision)],
["quota.scoped_override.project", lazyHandler(() => import("./quota/scoped_override.ts"), ({projectScopedOverride}) => projectScopedOverride)],
["task_lease.owner_eligibility", lazyHandler(() => import("./work_items/task_lease_eligibility.ts"), ({evaluateTaskLeaseOwnerEligibility}) => evaluateTaskLeaseOwnerEligibility)],
["task_lease.acquire.native", lazyHandler(() => import("./work_items/task_lease_acquire.ts"), ({executeTaskLeaseAcquire}) => executeTaskLeaseAcquire)],
Expand Down
22 changes: 0 additions & 22 deletions loopx/control_plane/goals/goal_frontier/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,28 +212,6 @@ def align_autonomous_replan_guidance_with_acceptance_policy(
return aligned


def autonomous_replan_decision_allowed(
*,
replan_obligation: dict[str, Any] | None,
plan_ok: bool,
workspace_blocked: bool,
automation_prompt_upgrade_required: bool,
agent_id: str | None = None,
registered_agent_ids: list[str] | None = None,
) -> bool:
return bool(
autonomous_replan_is_required(replan_obligation)
and autonomous_replan_scope_decision(
replan_obligation,
agent_id=agent_id,
registered_agent_ids=registered_agent_ids,
).get("applies")
and plan_ok
and not workspace_blocked
and not automation_prompt_upgrade_required
)


def _normalize_replan_agent_id(value: Any) -> str | None:
text = str(value or "").strip()
return text or None
Expand Down
Loading
Loading