Skip to content

fix(monitor): unify successor routing before writeback and receipt validation - #4145

Merged
huangruiteng merged 3 commits into
mainfrom
codex/monitor-successor-contract
Sep 10, 2026
Merged

huangruiteng merged 3 commits into
mainfrom
codex/monitor-successor-contract

Conversation

@huangruiteng

Copy link
Copy Markdown
Collaborator

Summary

Unify monitor successor routing across quota preflight, legacy writeback and provider-receipt validation. This is a bounded T2 prerequisite against the TypeScript/control-plane and shared Goal Authority RFCs, not a new monitor engine or an atomic native writer.

  • Add one pure scheduler/monitor_successor.ts owner, reused directly by quota and through the existing effect runtime by the Python writeback adapter.
  • Delete Python route guard/resolver logic and the separate TS receipt-default/capability interpretation. Production code is +187/-189 (net -2); the remaining growth is regression coverage and documentation.
  • Preserve the original observation in the v0 request fingerprint and stored provider plan. Normalize routes only for validation, materialization and receipt comparison, so legitimate pending effects remain retryable.
  • Update both RFCs in English/Chinese and the public Todo contract without removing the larger migration roadmap.

Issue Or Task

Maintainer-requested next cohesive RFC implementation slice. Started independently of #4142/#4143; rebased onto merged #4142 and revalidated its authoring scope. #4143 is not a prerequisite.

Intentional semantic changes

  1. Valid action/claim/continuation aliases and common Git URL transports now survive the entire writeback-to-receipt path. Previously Python could persist the normalized successor and TS would reject it against the original spelling.
  2. Every supplied capability must be valid. A mixed valid/invalid list no longer silently drops the invalid member and weakens the requested execution requirements.
  3. Malformed successor claim ids and follow-ups without material change are rejected before the monitor observation is written. An orphan next_claimed_by is treated like other agent-route flags and requires an agent successor.
  4. Repository routes must round-trip through the canonical identity contract. Dot segments, credentials, control characters, backslashes, percent-encoded paths and other unrepresentable routes are rejected before writeback rather than repaired into a different target.

Unchanged: material-change generation, result-hash successor keys, unchanged polling, user_action/user_gate distinction, authoring/claim authority, user approval/global-gate scope, writer fences, provider defaults and promotion holds. A valid route is not an execution grant. This does not promise that unrelated downstream authority/effect failures cannot leave a partially completed legacy workflow; full monitor-plus-successor atomicity remains T2 work.

Validation

  • Tested revision: 935ebb805db704eeaf3d9a0f991a6abffac45f14, based on bc18304a02acabc3f7c8c55728743885c0c24f91.
  • Run state: finished
  • Input classes: synthetic, public_fixture
Check kind Result Public-safe evidence / limitation
static passed Control-plane TS typecheck, touched Python Ruff, repository-configured mypy targets and diff whitespace checks. Mypy coverage is limited to its configured targets.
unit passed npm run test:control-plane: 942 passed, no failures or skips, with PostgreSQL enabled.
integration passed 127 Python tests across monitor follow-through, external wait, split-runtime writer fence, mutation authority, authoring scope, grouped monitor materialization and maintainability ratchets.
real_entrypoint passed Actual quota monitor-poll --execute with alias action/Git URL/capability inputs produces a canonical independent advancement successor; invalid successor intent leaves the monitor document unchanged.
real_entrypoint passed python examples/control_plane/monitor-poll-writeback-smoke.py completed successfully on the rebased implementation.
real_backend passed Full TS run includes an isolated real PostgreSQL 16.15 server; File and NoKV test-backend conformance also run. This PR does not change AuthorityStore or claim native monitor support on those providers.
regression_parity passed Before implementation, three Python route-validation cases and the alias-receipt TS case failed. Three assertion-killed source mutants cover invalid-capability dropping, removal of the material-change guard and rewriting of the persisted observation fingerprint.
regression_parity passed Common repository transport aliases are compared with the retained node-independent Python codec. Pending receipt retry is checked against the original v0 JSON/SHA-256 recipe; a different repository remains an effect conflict.
integration passed Read-only route planning for all 63 monitors in the checked-in production-scale fixture keeps target keys distinct and leaves the complete 464-Todo/64-lease projection unchanged. This is not a scale claim for native monitor writes.

Coverage and gaps: validation exercises the actual CLI and existing legacy effects, typed preflight/receipt lifecycle, retry/CAS behavior, negative authority boundaries and realistic fixture structure. Earlier development failures included an incorrect hash test vector, a conflict-result assertion expecting an exception, and a TS nullable-union narrowing issue; these were corrected before final validation. The final commit adds only the production-scale test; production code is unchanged from the rebased Python/smoke runs. No live Goal was mutated, and no full-repository Python or whole-Goal promotion qualification is claimed. Hosted CI will run separately.

Type of Change

  • Bug fix
  • Documentation update
  • Test update
  • Behavior-changing refactor; not advertised as complete zero-behavior-change parity.

LoopX Area

  • Control plane (goals, todos, quota, scheduler, registry, runtime)

Technical Direction

  • Core control-plane hardening
  • Target base branch: main
  • Direction tracker or promotion unit: TypeScript RFC T2 successor-route prerequisite; no storage or whole-Goal promotion request.

Shared-authority RFC fixture impact

  • Production-scale fixture schema: loopx_coordination_production_scale_fixture_v0; existing public fixture reused unchanged.
  • Semantic dimensions: monitor source identity, successor target separation, route normalization, execution capability preservation and unchanged stored Todo/lease fields.
  • Provider conformance arms: File, NoKV test backend, isolated real PostgreSQL in the TS suite. No new provider transaction was added.
  • Read-only legacy/file/PostgreSQL three-arm rehearsal: not a routing/promotion/projection-write change. The affected public execution path remains legacy and fenced; existing provider conformance is regression evidence, not native monitor qualification.

Boundary Checklist

  • No private state, credentials, raw logs/traces, internal links, connection strings or local machine paths in the diff or PR. Unsafe-URL tests use explicit synthetic placeholders only.
  • No duplicate benchmark delivery or new benchmark job.
  • Scope is the existing monitor successor contract; no new capability, provider, scheduling engine or gate authority.
  • Every commit includes a DCO sign-off.

Future-facing pass applied: one route owner is ready for the eventual native T2 transaction to call in process. The node-independent repository/bootstrap codec is intentionally retained and characterized rather than making bootstrap depend on Node. T1 update closure, full T2 atomic writeback/recovery and shared-provider durability qualification remain separate, explicit work.

Signed-off-by: huangruiteng <huangrt01@163.com>
Signed-off-by: huangruiteng <huangrt01@163.com>
Signed-off-by: huangruiteng <huangrt01@163.com>

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Request changes conclusion (author-owned PR; GitHub blocks formal self-review)

审阅绑定 exact head:935ebb805db704eeaf3d9a0f991a6abffac45f14。

动机

把 monitor successor 的 preflight、Python writeback 和 provider-receipt validation 收束到一个 typed route owner,方向和必要性都成立。它能避免 action、capability、repository 与 receipt 在三层各自解释后漂移,也保持了“typed TypeScript 决策、Python host effect”的既有边界。

改动思路

新的 monitor_successor.ts 统一校验 successor intent、规范化 route,并由 quota preflight 与 receipt validation 直接复用;Python adapter 通过 effect runtime 取得同一个计划后再执行现有 Todo 写回。原 observation 继续参与 v0 fingerprint/provider plan,canonical route 仅用于物化与回读比较,这个兼容策略本身合理。

具体改动

关键代码讲解

  • monitorSuccessorIntent 统一约束 material change、action、claim、continuation、capabilities、repository 与 user-task class。
  • monitorSuccessorRoute 生成 provider writeback 和 receipt comparison 共用的 canonical successor route。
  • write_monitor_poll_todo_state 删除 Python 的 route 决策重复,只保留 source lookup 与实际 effects。
  • validatedProviderReceipt 复用同一个 typed route,不再单独实现 defaults/capability comparison。

但这里有一个阻塞的边界遗漏:monitor_successor.ts 的 URL 校验只检查 url.password,没有检查 url.username;保留的 repository_identity.py 也同样只检查 password。现有测试只覆盖 https://user:password@...,因此全部通过时,username-only credential 仍会漏过。

我通过真实 public CLI 路径复现:在临时 synthetic registry 上执行 loopx quota monitor-poll --execute,传入 https://user_only@example.invalid/owner/repo,命令成功并创建了 git:example.invalid/owner/repo successor,而不是在第一次写入前拒绝。这与 PR 声明的 credential-free、pre-write rejection 语义冲突。

最低修复范围:

  1. 在 TypeScript 与保留的 Python codec 中都拒绝 HTTP/HTTPS/git 的 username credential;若契约需要 ssh://git@host/...,要用 transport-aware 规则保留合法 SSH username。
  2. 增加 public quota monitor-poll 负向回归,证明 username-only credential 在 provider plan/首次写入前失败且 Todo/receipt 状态不变。
  3. 增加两套 codec 的 parity case,防止其中一侧以后再次漏掉该语义。

验证结果:27 个聚焦 Python 测试、20 个 TypeScript 测试、Ruff、git diff --check、DCO 与 public/private 扫描均通过;上述真实入口反例单独失败并构成阻塞证据。

对主干的风险

这是公共控制面输入边界。把 credential-bearing URL 静默剥离成 canonical identity 会让调用方误以为不安全输入已被合规接受,也破坏 provider plan/fingerprint 所承诺的 credential-free 约束。影响只需一个小而明确的 admission 修复即可消除,不需要推翻本 PR 的架构。PR 当前还 BEHIND main,修复后应一并 rebase 并重跑检查。

我的整体评价

整体重构是 proportionate 的,production net change 也很克制,typed owner 与 host effect 分工清晰;但本 PR 最强的承诺之一正是“所有不可表示/带 credential 的 route 在 writeback 前拒绝”,而当前测试 oracle 漏掉了 username-only URL 这一等价输入形态。修复该语义差异并补齐真实入口负向回归后,可以快速复审。

English verdict: REQUEST_CHANGES — exact head 935ebb805db704eeaf3d9a0f991a6abffac45f14 accepts username-only HTTP credentials at the public monitor-poll boundary; reject them in both reachable codecs and add no-write parity coverage.

try {
const url = new URL(raw);
if (!["git:", "http:", "https:", "ssh:"].includes(url.protocol) ||
!url.hostname || url.password || url.search || url.hash) throw new Error();

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] url.password does not cover username-only HTTP credentials. The real quota monitor-poll --execute path accepts the synthetic https://user_only@example.invalid/owner/repo input and creates a successor instead of rejecting before writeback. Please reject url.username for non-SSH transports in this typed codec and the retained Python repository codec, preserve legitimate SSH usernames deliberately, and add a public-entrypoint no-write parity regression.

@huangruiteng
huangruiteng merged commit 25143eb into main Sep 10, 2026
20 checks passed
@huangruiteng
huangruiteng deleted the codex/monitor-successor-contract branch September 10, 2026 01:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant