Skip to content

refactor(work-items): read the execution handoff modes from the vocabulary owner - #8184

Merged
huangruiteng merged 1 commit into
loopx-project:mainfrom
Jiaqiiii523:refactor/execution-handoff-mode-vocabulary-owner
Nov 7, 2026
Merged

huangruiteng merged 1 commit into
loopx-project:mainfrom
Jiaqiiii523:refactor/execution-handoff-mode-vocabulary-owner

Conversation

@Jiaqiiii523

@Jiaqiiii523 Jiaqiiii523 commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

Goal And Delivered Outcome

  • Outcome basis / optional anchor: self-contained maintenance outcome, no issue. The accepted specification is docs/architecture/rfcs/typescript-control-plane-migration-v0.md:343, which states that new execution and configuration targets share EXECUTION_HANDOFF_MODES (soft_claim / hard_lease), with the historical HandoffMode kept for decoding.
  • Goal/source and gap: loopx/control_plane/work_items/execution_preparation.ts:16 restated those two modes locally under the name HANDOFF_MODES — the exact name of the owner's three-value historical list at loopx/control_plane/coordination/handoff_mode_vocabulary.ts:2. Every other consumer of this vocabulary already imports it (local_authority_defaults.ts:6, handoff_mode_policy.ts:6, handoff_mode_migration.ts:14, work_items/task_lease_acquire.ts:1, work_items/task_lease_acquire_decision.ts:1, work_items/task_lease_lifecycle_decision.ts:1, quota/settlement_plan.ts:13, and the dashboard's apps/presentation/dashboard/src/data/chat.ts:3), so this file was the one surface holding its own copy.
  • Observable before → after, with the validation row that proves it: before, the accepted handoff vocabulary existed in two places with two different names and one shadowed name; after, it exists once, and the difference between the historical and execution lists is asserted rather than implied by a local constant. See the integration and static rows.
  • Issue/task and intended base: no issue is closed. Intended base main.

Author Declaration

  • Written by: model_agent (Qoder Desktop coding agent, Anthropic Claude model family).

Implemented against

  • Specification and revision: docs/architecture/rfcs/typescript-control-plane-migration-v0.md (and its Chinese pair, unchanged) at repository main 62e234c939996ad42f2b1168451cc9a656dce11d; the owner module's own comments, which label HANDOFF_MODES as "Shared wire vocabulary" and EXECUTION_HANDOFF_MODES as "New configuration targets".
Criterion (spec clause) Disposition Symbol / path Test or command
New execution/config targets share EXECUTION_HANDOFF_MODES implemented loopx/control_plane/work_items/execution_preparation.ts:1,58 node --experimental-strip-types --test tests/control_plane_ts/execution_preparation.test.ts
Historical HandoffMode stays decodable but is not a new target implemented tests/control_plane_ts/execution_preparation.test.ts (new case) same command
No local restatement of the vocabulary implemented deleted const HANDOFF_MODES = [...] as const same command, plus the mutation check below
  • Self-check before submission: I read the owner module, the RFC sentence it implements, the seven existing importers, and every use of the local constant before changing it. I deliberately did not import the same-named HANDOFF_MODES list: it also contains legacy, so that "obvious" fold would silently widen the accepted handoff_mode input on this surface — the new case is written specifically to fail if anyone does that. I left LEASE_STATUSES alone; it has one definition, and folding it would be a different decision. No Python twin is claimed or moved here — the cross-runtime pair is governed by the migration RFC.

Why this is a fold and not a rename

The local list and the owner's execution list are the same two values, so the change is behaviour-preserving on every accepted input. The name, however, was not the same thing: HANDOFF_MODES in the owner carries the retired legacy mode for stored-state decoding. Binding the validator to the value-matching export instead of the name-matching one keeps the accepted set at two while removing the duplicated list, and the pinned difference is what stops a future "cleanup" from importing the wider list.

Scope And Continuation

  • Completed scope and remaining work: complete within this scope. If the maintainer wants the vocabulary census extended to TypeScript module-local lists the way tests/architecture/test_content_digest_single_owner.py does for Python, that is a separate decision; this PR does not pre-empt it.
  • Slice boundary / successor: N/A — independently reversible, one surface.

Validation

  • Tested revision: 60c62f5f593fcc75bff23a2f5a4e1f4055531bd2
  • Run state: finished
  • Input classes: synthetic, public_fixture
Check kind Result Public-safe evidence / limitation
integration passed Full control-plane TypeScript lane (node --no-warnings --experimental-sqlite --experimental-strip-types --test --test-concurrency=4 tests/control_plane_ts/*.test.ts) run twice on this host: identical footing on d0985c35aa3d05fd5de964e719aaf69f45d72535, with the same installed dev dependencies visible to both trees: clean base checkout → 6224 tests, 6145 pass, 2 fail; this head → 6225 tests, 6146 pass, 2 fail. The two failing test names are identical between the runs (persistent machine routes retain notice-before-default-on without an enable flag, temporary roots, filesystem aliases and path-component boundaries are local eligibility facts). Net regressions 0, and the +1 test is the new case. Earlier runs of this lane without npm ci produced 17 file-level failures in both trees; the dependency state, not the code, was the difference, so the row is restated on the equal-footing pair.
real_entrypoint passed node --no-warnings --experimental-sqlite --experimental-strip-types --test tests/control_plane_ts/execution_preparation.test.ts → 8 pass, 0 fail (7 before the change).
regression_parity passed Mutation check on the guard: replacing EXECUTION_HANDOFF_MODES with the owner's same-named three-value HANDOFF_MODES in the changed source makes exactly the new case fail (7 pass / 1 fail); the file was restored and compared byte-identical afterwards.
static passed npm ci --ignore-scripts then tsc --project tsconfig.control-plane.json --noEmit → no output, exit 0.
unit not_run Covered by the TypeScript lane rows above; no Python test path reads this module.
  • Coverage and gaps: the changed line is the validator input set, and the executed case drives the real projection for both accepted modes plus the rejected historical mode. The two pre-existing failures reproduce identically on an untouched base checkout of the same revision on this host; I did not investigate their causes and they are out of scope here. Gap named honestly: with the repository's dev dependencies installed the PostgreSQL integration files pass on this host, so this lane was not exercised against a live database, and the CI browser lanes and dashboard build were not run here.

Frontend / Visual Evidence

  • UI impact: none
  • Before: N/A
  • After: N/A
  • First viewport and preview: N/A
  • States and viewports shown: N/A
  • Source data: none
  • Attention review: N/A
  • Craft review: N/A

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Refactoring (no functional changes)
  • Documentation update
  • Test update

LoopX Area

  • Control plane (goals, todos, quota, scheduler, registry, runtime)
  • Benchmark boundary (adapters, runners, verifiers, scoring, evidence)
  • Capability or extension (providers, adapters, skills)
  • Public docs or presentation surface (README, protocols, dashboard)
  • Build, packaging, installer, or CI
  • Host or runtime integration

Technical Direction

  • Direction / acceptance reference, when applicable: Shared Goal Authority and cross-host coordination, under the TypeScript control-plane migration RFC.

Shared-authority RFC fixture impact

  • Production-scale fixture schema: N/A — no fixture schema or generated contract changed.
  • Semantic dimensions changed, or reviewed no-impact rationale: no semantic dimension moves. The accepted handoff_mode input set on this surface stays exactly soft_claim / hard_lease, which is the registered handoff_mode vocabulary's execution subset in loopx/semantics/vocabulary_v0.json.
  • Provider conformance arms run: N/A
  • Read-only legacy/file/PostgreSQL three-arm rehearsal: not_run — this change touches no authority store or writer fence; the PostgreSQL lanes are the pre-existing host limitation above.

Boundary Checklist

  • Neither the diff nor this PR body/comments/attachments disclose private state, credentials, raw traces or verifier output, internal links, or local machine paths.
  • I did not duplicate maintainer-owned benchmark work unless a maintainer split out a public issue for it.
  • I kept the change scoped to the linked issue/task.
  • Existing English/Chinese RFC pairs both have a diff, or no paired RFC changed: no RFC file changed.
  • I completed the visual evidence section for UI changes, or marked UI impact none.
  • Every commit includes a DCO Signed-off-by trailer.

Rebase note: rebased onto d0985c35aa3d05fd5de964e719aaf69f45d72535 with no content change (git patch-id --stable identical: cf8f91054e388d99a8b7); the focused lane (8 pass / 0 fail) and tsc --project tsconfig.control-plane.json --noEmit were re-run on the rebased revision.

Second rebase in this session: moved onto d0985c35aa3d05fd5de964e719aaf69f45d72535 (main advanced twice while these were open). git patch-id --stable unchanged per branch (f3ce546bc69ef120722a, 69bc07982a79a5840364, cf8f91054e388d99a8b7), and the branch's own checks were re-run on that revision: the six smoke consumers exit 0 with the change and exit 1 without it, the guard pair is 26 passed against a 3 failed, 472 passed baseline identical on the untouched base, and the TypeScript lane is 6225 tests / 2 fail against 6224 / 2 fail with the same two failing test names, tsc --noEmit clean.

@Jiaqiiii523
Jiaqiiii523 force-pushed the refactor/execution-handoff-mode-vocabulary-owner branch from f74581a to 8ac2638 Compare November 6, 2026 14:53
…ulary owner

execution_preparation.ts restated the two accepted modes under the name
HANDOFF_MODES, which is the vocabulary owner's three-value historical list.
Bind the validator to EXECUTION_HANDOFF_MODES, the list the TypeScript
migration RFC names for new execution and configuration targets, and pin the
two lists apart so widening the input vocabulary fails a test.

Signed-off-by: Jiaqiiii523 <293262669+Jiaqiiii523@users.noreply.github.com>
@Jiaqiiii523
Jiaqiiii523 force-pushed the refactor/execution-handoff-mode-vocabulary-owner branch from 8ac2638 to 60c62f5 Compare November 6, 2026 15:06

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewer: model_agent; gpt-6.1-sol; OpenAI; runtime_reported; reasoning_effort=max.

动机 / Motivation

维护执行准入与租约代码的开发者,需要区分历史状态解码和新执行所允许的模式。 此前执行准备模块自行保存 soft_claim/hard_lease 双值表,却把它叫作 HANDOFF_MODES;共享 owner 中同名表还包含 legacy。以后改规则需要同步副本,按名字误换引用还可能扩大准入。现在直接读取共享的执行子集,消除这个同步点。 执行准备已复用既有 EXECUTION_HANDOFF_MODES;原来的正常准备、冲突拒绝和 legacy 拒绝结果保持。 范围仅是这个执行准备投影,不新增模式、不修改 claim/lease 权限或历史解码,也不声称完成整个迁移路线图或取得性能收益。

这是一个独立可验收的维护切片。当前运行结果原本就应正确;价值是移除第二个规则来源,降低以后修改词汇时误用历史列表的风险。维持原状会保留该同步点,单纯改名也不能消除副本。

改动思路 / Approach

这是对既有无依赖词汇 owner 的直接复用;保留历史三值表与执行双值表的语义分工,比新增 wrapper 或按同名导出替换更合适。 当前 PR 只删除执行准备模块的本地副本并增加一个拒绝范围回归,不改变状态源、执行副作用、交互或安装默认。 原子 claim 仍负责重新核对归属、写入范围和工作树,执行准备只读规范事实并返回下一步,不会因导入一个列表就获取租约或额外权限。没有必要再加模式转换、兼容 wrapper 或新的开关。

列表 保留的用途 值
HANDOFF_MODES 历史状态和回执解码 legacy、soft_claim、hard_lease
EXECUTION_HANDOFF_MODES 新配置和执行目标 soft_claim、hard_lease

具体改动 / Changes

审查绑定 60c62f5,实际 merge-base 为 d0985c3。完整范围为两个文件:生产代码 +2/-2,测试 +22/-0;没有新增模块、状态、CLI、模式或协议版本。完整 diff、变更模块与测试均已阅读,也沿运行时 handler 和 Python quota caller 核对了真实调用点。

关键代码讲解

  • projectExecutionPreparation 的模式校验改用现成的执行子集;后续无权威、任务不开放、外人持有、软 claim、硬 lease 和恢复分支保持原样。
  • EXECUTION_HANDOFF_MODES 是既有无依赖 owner。它与上面的历史列表用途不同,所以这次没有按名字直接换成更宽的 HANDOFF_MODES。
  • project_selected_todo_execution_preparation 仍从规范状态中筛选准确 Todo 和租约,再调用同一个 typed projector;它与普通 claim 才是实际准入链路,测试导入成功不能替代这条链路。

规格依据为 docs/architecture/rfcs/typescript-control-plane-migration-v0.md,固定在 d0985c35aa3d05fd5de964e719aaf69f45d72535(接受的原文)。Current delivery frontier (post-merge, 2026-10-16) 条款在本头为 implemented:新执行使用共享执行子集,历史 legacy 词汇保持,实际 legacy 执行输入仍被拒绝。这里没有把更广泛的迁移、默认采用或所有存储资格当成本切片的新前置条件。

新增回归直接检查两种正常模式与 legacy 拒绝,针对的是“误导入历史列表会扩大合法输入”这个独立语义。它服务实际生产校验,未把源码拼写或行数当成行为断言。相邻的 lease-status 词汇没有被顺便重构。

对主干的风险 / Risks

未发现阻塞问题。最强反例是历史列表仍含 legacy,却被误当成新执行列表;当前真实请求对此仍抛 typed error。另以 25 组相同事实覆盖软/硬模式、租约缺失/释放/过期、己方/外人持有、任务完成、无权威、多租约及非法 JSON 类型,两个版本的完整返回与错误 JSON 逐字一致,没有删掉字段、命令或 prose 来做归一化。

独立执行的检查 基线 当前头
完整 TypeScript lane PASS:6147 passed,77 skipped,0 failed PASS:6148 passed,77 skipped,0 failed
真实 File/SQLite quota、claim 和恢复模块 PASS:31 passed PASS:31 passed
25 组完整投影/错误对照 与候选逐字相同 与基线逐字相同
TS typecheck、默认 mypy 17 roots、仓库 Ruff、semantic vocabulary smoke — PASS
准确范围 CQR — PASS,verify valid

两边在安装相同开发依赖后使用 Node 24.21.0 和同一完整 TS 命令;runner 均设 LOOPX_USAGE_PING=0。77 项 skipped 保持为跳过,没有称作通过。作者曾报告的两项 TS 失败属于其历史观测;本机本次基线和候选均无失败,原因差异未归因,不能说是本 PR 修好了那两个检查。当前改变的校验、真实调用与恢复有独立通过证据。没有查询或等待远端 CI,也未另外资格化安装态、真实 PostgreSQL 或模型成本。

语义与 CI 对齐

本提案 reuse_existing,没有创建词汇或扩大闭集。完整语义扫描通过;更关键的是执行集合仍为双值、历史三值集合未动,实际 legacy 拒绝和所有比较返回保持。claim 的准备义务、归属拒绝、原捕获恢复和停止条件没有新措辞或默认变化。

我的整体评价 / Verdict

对这个明确维护边界,交付判断为 goal_achieved。long_horizon 与 user_experience 均为 preserved:真实调用和恢复保持,用户没有新增准备、导航或确认轮次;维护改善限定为少一个重复规则来源,没有把测试数或共享导入换算成长期收益。更大迁移计划和实际效果/成本结论不由本评审关闭。

视觉检查不适用。两个变更文件没有渲染页面改动;已检查的 CLI/Host 调用方也没有新增呈现行为。没有验证打包 UI 或安装态 rollout;这不属于本次源码词汇合并的验收。当前源码范围无需再增加 wrapper、配置或后续任务。合并所需的当前权限、分支状态和保护仍由各自 owner 判定,本次批准不执行合并或安装。

English verdict: APPROVE for 60c62f5f593fcc75bff23a2f5a4e1f4055531bd2; the shared execution vocabulary preserves the current admission and recovery contract.

@huangruiteng
huangruiteng merged commit d39fac2 into loopx-project:main Nov 7, 2026
26 of 42 checks passed
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.

3 participants