Skip to content

refactor(status): compose the status task graph in TypeScript - #7904

Open
hhyykk wants to merge 4 commits into
mainfrom
codex/status-task-graph-ts-20261102
Open

hhyykk wants to merge 4 commits into
mainfrom
codex/status-task-graph-ts-20261102

Conversation

@hhyykk

@hhyykk hhyykk commented Nov 2, 2026 •

Copy link
Copy Markdown
Collaborator

Goal And Delivered Outcome

  • Outcome basis / optional anchor: TypeScript control-plane migration RFC: replacement-first migration of domain-neutral decisions to the typed owner, with no parallel Python decision owner.
  • Goal/source and gap: the optional status task graph (work_items/task_graph.py, 1,044 lines) decided selected work, claim display, user-gate selection/count/cap/overflow, predecessor traversal, run/lineage joins, evidence, handoff, repair, dedup, dangling-edge rejection, timestamps and limits in Python, crossing into TypeScript once for topology plus up to six public-text calls per source string.
  • Observable before → after: Python composer → one work_item.task_graph.status request owned by the existing work_items/task_graph.ts. The standalone work_item.task_graph.topology RPC is retired (topology stays an internal composition, reused in process). Goal-map shares the same native identity/state/topology-row rules; the three Python rule helpers are deleted. Frozen status and Goal-map outputs are byte-identical, and real status --include-task-graph CLI output matches base byte-for-byte on File and SQLite in JSON and Markdown.
  • Issue/task and intended base: Self-contained migration slice; base loopx-project/loopx:main. No issue closure claimed.

Author Declaration

  • Written by: model_agent: Factory Droid (lead, review and commits) with OpenAI Codex CLI (implementation).

Implemented against

Criterion Disposition Symbol / path Check
Pin complete output before moving code implemented tests/control_plane/test_status_task_graph_characterization.py + frozen fixture (18 status cases + 3 Goal-map cases: cycles, caps/overflow, missing prerequisites, lineage, handoff, Unicode ids, redaction, empty/invalid goals); frozen on unchanged base before implementation expected bytes unchanged; 21 cases green
Complete decision in one typed owner implemented projectStatusTaskGraph composes topology, Todo summary, classification and handoff owners in process; no Python selection/traversal/gate/evidence/lineage/repair/limit fallback remains native refusal test proves no Python fallback
Goal-map shares native rules implemented node identity, state and topology-row rules shared with status; Python helpers deleted; build_goal_task_map keeps its public signature and byte-identical output for chat_status_api.py 3 pinned Goal-map cases + chat entrypoint parity (2,310 bytes on each provider)
Identity materialization in the composer implemented SHA-256 node/edge identities materialize in TS with byte-identical Unicode/None encoding, so dedup compares actual identities duplicate_identity, unicode_ids cases
Public text crosses once, as facts implemented one recursive Python codec; missing facts throw; TS compacts only registered public strings or qualified composed text; no TS copy of the redaction patterns boundary test: private/unknown/unredacted fields never cross
Bounded request implemented codec caches repeated source strings and computes only field-used caps; large packets reuse the local snapshot transport largest case 6,797 → 4,899 bytes; calls 61 → 21
Retained duplication disclosed implemented statusOpenItems keeps the historical source-key/dedup/bounded-open selection (no equivalent TS owner yet); exit condition recorded ledger, both languages
Ledger entry in both languages implemented ledger/typescript-control-plane-migration-v0/2026-11-02-status-task-graph{,.zh-CN}.md, linked from both RFC files check_rfc_bilingual.py
  • Self-check before submission: A first draft kept a TS redaction-pattern copy, left Goal-map identity/state helpers in Python, and called the public codec six times per source string. All three were reworked as described above.

Migration economics receipt

Field Result
Canonical owner loopx/control_plane/work_items/task_graph.ts (projectStatusTaskGraph, projectGoalTaskMap)
Legacy code deleted Python graph decision rules, uncalled status builders/attachers/collectors/ref helpers/constants (module 1,044 → 255 lines)
Code added TS status composer; one module-level recursive public-text codec and two source/transport facades in Python
Cross-runtime calls selected work 4 → 1; user-gate overflow 7 → 1; run/gate without selection 4 → 1; valid all-empty 0 → 1; absent/invalid Goal 0 → 0; Goal-map 1 → 1
Public-text calls per-case table in the ledger; maximum 193 → 47, largest-text case 61 → 21
Product net change +865 / −1,030 (net −165)
Facade exit the Python status/Goal-map facades leave when status and chat callers deliver source/public-text facts natively (recorded in the ledger)

No latency or long-horizon benefit is claimed; the numbers above are codec/request cost evidence. A rejected native request has no Python fallback.

Scope And Continuation

  • Completed scope and remaining work: complete for both production entrypoints (status.build_task_graph_projection, chat_status_api.build_goal_task_map).
  • Deliberately not included: migrating status attention/monitor projections, project-asset readbacks or Todo summary renderers off Python open_todo_items selection (the retained duplication's exit); per-PR installed-artifact or latency qualification; these run once on the cumulative migration candidate.
  • Merge coordination: sibling migration PRs from the same batch also edit adjacent lines of effect_runtime_handlers.ts. Whichever merges later needs a trivial rebase.

Validation

  • Tested revision: 4fa58bfe650f81f5723ee880fbfccaa2ccc046e4
  • Run state: finished
  • Input classes: synthetic
Check kind Result Public-safe evidence / limitation
ruff (changed Python files) pass
pytest (focused suite, 7 files) 103 passed, 2 pre-existing failures `test_quota_planning_horizon.py::test_real_cli_exposes_goal_before_selection_without_granting_delivery[file
Node control-plane TS tests (3 files) pass graph semantics, handler and loading suites
npm run typecheck:control-plane pass
examples/semantic-vocabulary-drift-smoke.py pass budgets and anchors unchanged; no new py/ts basename pair
scripts/check_rfc_bilingual.py --base origin/main --head HEAD pass
loopx canary premerge --from-git-diff --git-diff-base origin/main pass direct checks, catalog canaries, risk-profile smokes and public-boundary scan all green
CLI/chat base/head parity pass real status --include-task-graph byte-identical on File and SQLite in JSON and Markdown with a fixed observation clock; chat _goal_task_map matches at 2,310 bytes on each provider
  • Coverage and gaps: source-checkout qualification only; wheel/sdist and installed-host checks were not run. No storage or persisted-format changes.

Frontend / Visual Evidence

  • UI impact: none. Status JSON/Markdown and chat Goal-map payloads are byte-identical.
  • Before / After / First viewport / States / Source data / Attention / Craft: N/A; no UI surface change.

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: TypeScript control-plane migration RFC. Status task-graph composition is domain-neutral projection policy, so it belongs with the existing task-graph owner in TypeScript; Python remains source acquisition, public-text codecs and transport facades.

Shared-authority RFC fixture impact

  • Production-scale fixture schema / semantic dimensions / conformance arms / three-arm rehearsal: N/A; no authority store or persisted format change.

Boundary Checklist

  • Reviewed diff and body for private state, credentials, raw traces, internal links and local machine paths; none included.
  • No maintainer-owned benchmark work duplicated.
  • Change remains scoped to the request described above.
  • Paired RFC and ledger files changed together (EN and zh-CN).
  • UI impact marked none.
  • Every branch commit includes a DCO Signed-off-by trailer (git commit -s).

Merge requires explicit maintainer authorization (status/Todo projections and CLI surfaces under loopx/**).

Cumulative Migration Qualification

  • This PR does not change packaging, installer layout or release artifacts, so it does not ship a separate migration package. Legal-input preservation, real File/SQLite behavior and exact-head premerge remain required here.
  • Mixed-case handoff identities are accepted only as lower-case derivations of approved public-text facts; arbitrary unqualified text remains rejected. work_item.task_graph.status is now eligible for the existing inline-first local snapshot fallback, so a legal 4.3M-character note preserves the complete input.
  • Wheel/sdist deep execution, installed-host readback and matched cold/warm latency/RSS qualification run once on the cumulative migration candidate after the migration stack is integrated, unless a later PR changes the distribution surface itself.
  • Exact-head evidence: 25 focused Python tests passed, including the 4.3M-character snapshot regression; 68 related TypeScript tests passed, including mixed-case handoff; control-plane typecheck passed; diff-scoped standard premerge passed all selected checks. The premerge inherited maintainability advisory is outside this diff. No merge is claimed.

Handoff identity repair

Head f78fe2d3c4b12e263f916567e2d97ba88018de03 uses the existing readAgent codec for handoff identity normalization. It covers case, leading/trailing whitespace and Python-compatible internal whitespace. A normalized identity is accepted only when its source has a nonempty approved public-text fact; rejected facts still fail closed.

Target main at ecbf90540 is incorporated. The English and Chinese migration-RFC conflicts were additive ledger entries; both sides are retained.

Validation:

  • Python task-graph topology, characterization and Goal-map composition: 56 passed. Real File and SQLite CLI cases exercise JSON and Markdown with task graphs enabled, the default graph-off path, both present/missing display files, and unchanged canonical records/display contents. JSON includes the normalized handoff title; Markdown retains its existing display contract.
  • TypeScript task graph: 40 passed. Cases include mixed case, surrounding/internal/Unicode whitespace, and rejected null/empty source facts. The public CLI whitespace regression and rejected-source regression failed before the repair.
  • Full control-plane typecheck, Ruff, bilingual RFC and diff checks passed.
  • Standard diff-selected premerge: 6 direct and 19 selected checks passed; zero failures, advisory failures or manual holds.

The repair adds no normalization owner or fallback. Product code in this repair is one line shorter. Packaged/installed Host adoption and matched latency/RSS qualification remain deferred to the maintainer-scoped cumulative migration candidate. Remote CI and a fresh review of this head remain pending; no merge performed.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-04T14:48:36.344963Z f78fe2d New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e0c9044fbb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +709 to +710
const from = safe(note.from_agent, 80);
const to = safe(note.to_agent, 80);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Qualify normalized handoff agent IDs before public-text lookup

When a predecessor's handoff_note contains accepted mixed-case agent IDs, such as from_agent: "Builder" and to_agent: "Reviewer", the in-process projectTodoSummaryDisplay normalizes them to builder and reviewer. However, _encode_public_text only supplies public-text facts for the original strings, so these lookups throw Missing public text facts for display cap 80 and abort the entire graph projection. The previous implementation successfully rendered this input. Supply qualified facts for the normalized handoff values, or preserve their codec provenance through normalization.

Useful? React with 👍 / 👎.

@mergify

mergify Bot commented Nov 2, 2026

Copy link
Copy Markdown

This pull request has merge conflicts with main and cannot be merged
until they are resolved. Please rebase or merge the base branch, @hhyykk.

Choose the remote for the base repository, not an out-of-date fork.
For a fork clone, first inspect git remote -v; upstream must point
to https://github.com/loopx-project/loopx.git. If it is absent, add it
with git remote add upstream https://github.com/loopx-project/loopx.git.
Then run:

git fetch upstream
git rebase upstream/main
# Resolve each conflict, git add the resolved files, then git rebase --continue.
git push --force-with-lease origin HEAD

For a same-repository clone whose origin points to
https://github.com/loopx-project/loopx.git, use origin instead of
upstream for fetch/rebase. If you prefer merging the base, use
git merge <base-remote>/main and push normally.

Keep the DCO Signed-off-by trailer on every commit when you rebase.
https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork

@mergify mergify Bot added the needs-rebase Mergify: the pull request has merge conflicts with its base branch label Nov 2, 2026

@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 | model=gpt-6.1-sol | provider=OpenAI | reasoning_effort=max | source=runtime_reported

动机 / Motivation

启用可选任务图、需要从状态页读回工作依赖与交接的操作者。此前 Python 负责挑选状态节点、组装交接与证据,TypeScript 只负责拓扑;这使同一任务图事务的规则分散在两种语言中。普通任务图与关闭模式保持兼容,但真实 File/SQLite 的混合大小写交接和较长合法 note 都使启用任务图的 status 从成功变成失败。本次只切换既有可选任务图的组装 owner,不新增写入、调度或模型权限;源码测试不代表安装包和完整成本已经合格。需修复两项合法输入回归,并完成该事务已接受的安装包与完整成本资格。

改动思路 / Approach

完整选择、拓扑和呈现迁入既有 TypeScript owner,Python 保留公共文本安全 codec、源读取及历史身份编码;既有 planning_relations、Todo display 与 envelope 被复用。当前 PR 的边界是既有可选状态任务图的完整事务切换;保留合法输入、安装深层执行与成本资格必须随该切换成立。拓扑、Todo display 与 handoff 规则继续复用原 owner,公共文本拒绝仍是安全不变量。statusOpenItems 的局部保留有其他真实消费者作为依据,无需为代码负数强行合并。结构方向合理,但边界 codec、传输和部署资格必须同时覆盖。

具体改动 / Changes

完整审查 head e0c9044fbb88dc568f71d78e1d66c3159e8ccb58;不可变迁移前 base fb16c6cb1369efce52a673030c914b38e1dac166。依据既有规范,spec_ref docs/architecture/rfcs/typescript-control-plane-migration-v0.md,spec_revision fb16c6cb1369efce52a673030c914b38e1dac166。十一个文件包含完整 composer、handler 替换、Python facade 精简、冻结语义样本与双语 RFC/ledger。TG-OWNER implemented;TG-INPUT、TG-INSTALL、TG-COST not_met。读取的是迁移前已接受 §6;新 ledger 的 source-only 声明不改变该事务的既有验收。

关键代码讲解

  • build_task_graph_projection:编码原始源字符串的公共安全事实,再调用单次 native composer;新 method 的 snapshot eligibility 缺失。
  • publicTextCodec:仅允许已验证的源文本或明确组合的文本;规范化后的身份没有相应事实时会拒绝。
  • projectStatusTaskGraph:统一选择、依赖、交接、gate、run 和 repair 节点,复用既有共享 owner。
  • materializeGoalTaskMap:Goal map 复用同一身份和公共文本 codec,保留有界拓扑和来源 envelope。

对主干的风险 / Risks

[P2] TG-HANDOFF:规范化身份打断整个任务图。 已在真实 canonical File/SQLite 写入并读回合法 predecessor handoff_note:from_agent=Builder、to_agent=Reviewer。原 owner 的显示投影把身份规范化为小写,新的 publicTextCodec 却只拥有原字符串事实,故 status --include-task-graph 报 Missing public text facts for display cap 80、exit1;固定 base 两组均 exit0。同样输入关闭图时正常。已有同义 inline,本轮独立复现,复用该讨论,不重复留言。在同一公共文本 owner 下,为规范化后的 Agent 身份提供匹配的安全文本事实,或在源侧规范化后编码;补上混合大小写的真实 status 回归,不能放开任意未验证源文本。

[P2] TG-SNAPSHOT:大输入 fallback 实际不可用。 真实 provider 接受并读回一个4,300,016字符的普通 note,原 base 的开启图两组成功;head 判断请求超过 inline 界限后传 large_local_snapshot=True,但新 status method 没在现有 eligibility 列表中,两个后端均报 local snapshot transport is unavailable for this method、exit1。关闭图仍成功。把新 work_item.task_graph.status 正确接入既有受控 snapshot eligibility,并验证请求/响应与拒绝边界;或使用保留完整输入的现有有界投影传输,不能截断 note 或 Todo 来规避。

[P2] TG-INSTALL / TG-COST:当前切换的强制资格缺证。 迁移前 §6 的 Correctness 与 Performance 分别要求 fresh wheel/sdist 深层语义,以及匹配的默认 SQLite 请求、事务、完整 CLI latency/RSS。PR 明确排除安装和 latency,ledger 只给源码/结构证据;减少 crossings 不能充当实际成本通过。在该 exact head 构建 wheel 与 sdist,分别装入全新隔离环境,从 packaged files 执行任务图正常、拒绝和恢复的深层语义探针并记录来源。按迁移前固定 base 与当前 head、同 fixture/环境,在默认 SQLite 测 cold/warm request、完整 transaction 与 CLI 的 p50/p95,以及 idle/burst daemon RSS;按既有阈值判定,File 单独披露。本轮未测得或声称性能回归,这两项是既有强制资格尚未满足。

聚焦 Python 78 PASS /2 FAIL,TS 48 PASS,typecheck PASS。两项 planning_horizon KeyError 在固定 base 同测试名、同 line238 复现,归因为不在本次图路径的既有失败,FAIL 保留。标准 premerge FAIL:hot-path-interface-budget 失败;之后相同命令在 base/head 的直接 cohort 都通过,仍不能解释或改绿原门。相同 canonical source 的六组关闭输出、两组普通开启输出在仅去除验证过的读时钟后完整一致;四组上述反例失败,来源和 provider revision 均未改变。未执行安装或完整成本实验。

语义与 CI 对齐

扩展既有内部 RPC vocabulary 并移除旧 topology RPC,状态、关系和只读 authority 继续复用。include_task_graph 默认仍关闭,六组真实 feature-off 完整输出证明共享 facade 不额外投影;启用分支的合法输入仍回归。不要用宽松字符串 fallback 绕过公共文本安全,也不能以 source-only 或较少 RPC 把既有安装/成本义务降成建议。本轮 exact-scope change-quality 按上述实际失败与缺证判为 FAIL,未请求基线豁免。当前 wait_for_ci=false,未获取、轮询或等待远端 CI;review、change-quality 与 merge readiness 分开判断。

我的整体评价 / Verdict

这是有真实消费者和可回滚边界的 justified_increment,当前机制归属与规模合理。完整选择、拓扑和呈现迁入既有 TypeScript owner,Python 保留公共文本安全 codec、源读取及历史身份编码;既有 planning_relations、Todo display 与 envelope 被复用。当前 PR 的边界是既有可选状态任务图的完整事务切换;保留合法输入、安装深层执行与成本资格必须随该切换成立。long_horizon 与 user_experience 为 regression:合法累积文本或交接输入会阻断本来成功的后续状态读取。没有新增人工准备或确认轮次,但读回真实性和成本边界仍必须满足。已检查现有 CLI/Chat 消费路径;本次没有页面布局、控件或第一屏设计改动,视觉检查不适用。仅限源码与隔离真实后端;已安装 Host、跨 Host 采用和长期净收益未验证。不修改作者源码;作者在本 PR 修复上述具体边界并补齐必要证据后,再对新 exact head 整审。未合并,也未把本次记录视为项目完成。

English verdict: REQUEST_CHANGES — head e0c9044fbb88dc568f71d78e1d66c3159e8ccb58; mixed-case handoff and legal large-note inputs regress on real File/SQLite status. Installed-artifact and complete-cost qualification remain missing; the original premerge failure is retained.

"fallback_time": now_utc_iso(),
"public_texts": texts,
}
use_snapshot = (

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.

[P2] TG-SNAPSHOT:新 status method 未接入大快照白名单。真实 File/SQLite 接受4,300,016字符 note,base 的 status --include-task-graph 成功,head 则报 local snapshot transport is unavailable for this method。把新 work_item.task_graph.status 正确接入既有受控 snapshot eligibility,并验证请求/响应与拒绝边界;或使用保留完整输入的现有有界投影传输,不能截断 note 或 Todo 来规避。

The adjacent cleanup removes the obsolete topology RPC and callback surface;
no unrelated refactor or product journey is introduced. Existing CLI, attention
queue, chat and review-packet consumers keep their public payloads. No end-to-end latency,
total resource-cost or long-horizon effectiveness/efficiency benefit is claimed.

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.

[P2] TG-INSTALL / TG-COST:迁移前已接受的 RFC §6 对每个事务切换仍要求 fresh wheel/sdist 深层语义及匹配的默认 SQLite request/transaction/full-CLI p50/p95、idle/burst RSS。本 PR 明确排除安装/latency qualification;结构 crossing 数不能替代。在该 exact head 构建 wheel 与 sdist,分别装入全新隔离环境,从 packaged files 执行任务图正常、拒绝和恢复的深层语义探针并记录来源。按迁移前固定 base 与当前 head、同 fixture/环境,在默认 SQLite 测 cold/warm request、完整 transaction 与 CLI 的 p50/p95,以及 idle/burst daemon RSS;按既有阈值判定,File 单独披露。

hhyykk and others added 2 commits November 4, 2026 14:43
Move the complete optional status task-graph decision (selected work,
claim display, user-gate selection/cap/overflow, predecessor traversal,
run and lineage joins, evidence, handoff, repair, dedup, dangling-edge
rejection, timestamps and limits) from work_items/task_graph.py into
the existing TypeScript task_graph.ts behind one
work_item.task_graph.status request; the standalone topology RPC is
retired and topology stays an internal composition. Goal-map shares the
same native identity, state and topology-row rules. Python keeps the
public-text codec and source facades only. Frozen status and Goal-map
outputs stay byte-identical; ledger entry in both languages.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Signed-off-by: hhyykk <4408344+hhyykk@users.noreply.github.com>
Signed-off-by: huangruiteng <huangrt01@163.com>
@huangruiteng
huangruiteng force-pushed the codex/status-task-graph-ts-20261102 branch from e0c9044 to 4fa58bf Compare November 4, 2026 06:51
@huangruiteng

Copy link
Copy Markdown
Collaborator

Repair head 4fa58bfe650f81f5723ee880fbfccaa2ccc046e4 fixes both real-input regressions: lower-case handoff identities are accepted only as derivations of approved public-text facts, and work_item.task_graph.status now uses the existing inline-first local snapshot fallback for a legal 4.3M-character note. Focused Python 25 passed; related TypeScript 68 passed; typecheck and diff-scoped premerge passed.

Per the agreed cumulative migration policy, this PR does not ship its own wheel/sdist. Installation, installed-host readback and matched cold/warm latency/RSS qualification run once on the cumulative migration candidate, unless packaging changes separately.

@mergify mergify Bot removed the needs-rebase Mergify: the pull request has merge conflicts with its base branch label Nov 4, 2026

@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

用户和 Agent 在 status 开启任务图,查看前序交付与交接关系。 已完成前序任务保留带首尾空白的交接身份时,原有任务图能显示规范化身份;当前头会令整个 status 失败,用户丢失本次状态和后续行动读回。 普通混合大小写和大备注路径已恢复,但完整合法身份规范化仍回归,尚不能接受此源代码切换。 本轮不授予合并权限,不证明安装 Host 采用、长期有效成果或完整成本收益。 wheel/sdist 深层安装、真实 Host 采用和匹配 cold/warm/RSS 留在维护者接受的累计候选资格边界,仍为 UNVERIFIED。

改动思路 / Approach

完整资格或图组合归既有 TS owner,Python 保留有实际调用者的 IO/codec;当前缺陷应在原 owner 内修复。 本次交付限于源代码只读切换;累计安装、Host 与完整成本资格按独立维护者约定保留为待验证。

预期是让既有 TS task-graph owner 统一组合 topology、节点、公开文本、来源范围与 Goal map,Python 保留 source IO 和公开文本事实 codec。默认 status 不启用任务图,显式 --include-task-graph 才调用组合,read-only envelope 不授予 Todo、交接或验收写权限。现有 Chat Goal map 和 dashboard schema 是实际消费者,不能只凭新 helper 的绿色测试证明用户读回可用。

这一完整只读组合边界符合迁移方向;旧 topology helper 保留内部消费者,不应按旧 RPC 名字猜测重复规则。statusOpenItems 的剩余 Python 消费者有明确迁移退出边界。当前最小修复是让 codec 直接复用既有身份规范化 owner,而非另补几种字符串特判。安装/Host/匹配 cold/warm/RSS 按 维护者当前约定留给累计候选,保持 UNVERIFIED;这不能豁免当前源代码合法输入兼容。

具体改动 / Changes

评审 head 4fa58bfe650f81f5723ee880fbfccaa2ccc046e4,基线 d4aaaaefbd37a83a30f10681de839b45d631eeb9。12 文件的生产变动(含 snapshot 配置)为 +878/−1030,其余是英中 RFC/ledger 和迁移/回归 fixture;净减少代码不自动证明行为兼容。

关键代码讲解

  1. build_task_graph_projection / _encode_public_text:Python 把原始 source 与批准过的公开展示事实交给 TS,保留 source 截断/缺失界限,不能从展示缺失推断规范来源不存在。
  2. projectStatusTaskGraph:组合前序/交接/证据/运行状态,复用既有 topology 和 typed Todo 语义;ordinary status 的关闭路径保持隔离。
  3. publicTextCodec 的身份派生:只将原 source 转成小写,未执行既有 normalizeTodoAgent 的 Python 空白压缩、trim 与空格转连字符。因此 handoff owner 产生的规范化 builder 无对应公开文本事实。

[P2] 合法带空白交接身份令整个 status 失败。 规范 File/SQLite writer 接受并由独立 todo list --todo-id 读回 handoff_note={"from_agent":" Builder ","to_agent":" Reviewer ","status":"done"},已完成前序通过 successor 指向当前任务。执行 status --goal-id graph-proof --include-task-graph:基线 JSON/Markdown 均 exit 0,当前头四种 provider/format 组合均 exit 1,错误为 Missing public text facts for display cap 80;同一来源关闭任务图全部成功。位置为上述 TS 452–455 行。应从已批准 source 复用完整 normalizeTodoAgent 产生展示事实,保留未批准文本拒绝;增加公开 CLI 的首尾/内部空白、混合大小写 File/SQLite 正例及非法文本负例。该反例扩展既有身份规范化讨论,未把普通小写/混合大小写修复判为失败。

规范依据为 docs/architecture/rfcs/typescript-control-plane-migration-v0.md,接受前版本 d4aaaaefbd37a83a30f10681de839b45d631eeb9。Stage 0 与 5. Payoff-phase PR contract:完整组合/codec/caller inventory 已审,保留 staging 边界。Stage 2B:TS 组合 owner 方向合理。Caller-observable semantic parity:上述合法输入不满足,minimum repair 为复用完整身份规范化并重跑双 provider/format。4,300,016 字符备注的真实公共路径在两端、开关和两种格式的 16 次调用通过,支持 snapshot 修复,但不能覆盖身份反例。Performance、7. Install, upgrade, and rollback:按维护者约定 deferred,未验证也不重开为本轮每 PR 安装门。

对主干的风险 / Risks

PASS:TS 70 项、control-plane typecheck、修改 Python 的 Ruff、standard premerge 19 项(含 bilingual/public boundary/semantic smoke)。Python 原选择集为 87 PASS / 2 FAIL;两项 test_real_cli_exposes_goal_before_selection_without_granting_delivery[file|sqlite] 在不变测试第 238 行抛 KeyError: planning_horizon,同命令在不可变基线与当前头复现相同失败身份和详情。该 quota should-run 测试未打开 task graph,测试/fixture/quota 路径未变;它是保留的既有失败,不是本轮身份回归的证据或修复。原始 maintainability ratchet 四个未变模块告警也在基线匹配,native premerge 将其保留为 advisory。

32 次 handoff 公共调用中,基线 16 次均成功,当前头只在带空白身份且开启图的四次失败;其余六组 Markdown 基线/head 原文一致,六组 JSON 仅三个 summary 生成时间不同。没有归一化错误、诊断、身份或图节点来掩盖差异。原图中的 audit/continue 文本提示仍是既有只读启发式,不是新增权限规则;未宣称这些提示证明验收。schema 和关闭路径兼容不抵消开启路径的合法输入回归。

我的整体评价 / Verdict

REQUEST_CHANGES:完整迁移方向合理,但用户读取合法交接记录仍丢失整次 status 结果;长程读回和用户体验均为 regression,需先修复完整身份规范化。现有测试会全部通过图相关正例,仍未覆盖该普通输入,因此不能用测试总数批准。无需新增配置或人工确认;成功路径的必要新增交互轮次为零,当前错误却增加无谓排查。visual_review 不适用:改动不涉及渲染布局,已检查现有 Goal Chat/dashboard schema 与 capability editor 消费路径;未验证范围为累计安装 Host 和实际展示采用。最小修复限于既有 owner 复用和公开回归,不要求扩展新协议或重写 UI。

English verdict: REQUEST_CHANGES at 4fa58bf. Legal whitespace-normalized handoff identities fail the public CLI on File and SQLite in both formats; baseline succeeds. Large-note transport passes; cumulative install/Host/performance qualification remains unverified.

@mergify

mergify Bot commented Nov 4, 2026

Copy link
Copy Markdown

This pull request has merge conflicts with main and cannot be merged
until they are resolved. Please rebase or merge the base branch, @hhyykk.

Choose the remote for the base repository, not an out-of-date fork.
For a fork clone, first inspect git remote -v; upstream must point
to https://github.com/loopx-project/loopx.git. If it is absent, add it
with git remote add upstream https://github.com/loopx-project/loopx.git.
Then run:

git fetch upstream
git rebase upstream/main
# Resolve each conflict, git add the resolved files, then git rebase --continue.
git push --force-with-lease origin HEAD

For a same-repository clone whose origin points to
https://github.com/loopx-project/loopx.git, use origin instead of
upstream for fetch/rebase. If you prefer merging the base, use
git merge <base-remote>/main and push normally.

Keep the DCO Signed-off-by trailer on every commit when you rebase.
https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork

@mergify mergify Bot added the needs-rebase Mergify: the pull request has merge conflicts with its base branch label Nov 4, 2026
Signed-off-by: aihop <4408344+hhyykk@users.noreply.github.com>

# Conflicts:
#	docs/architecture/rfcs/typescript-control-plane-migration-v0.md
#	docs/architecture/rfcs/typescript-control-plane-migration-v0.zh-CN.md
Signed-off-by: aihop <4408344+hhyykk@users.noreply.github.com>
@mergify mergify Bot removed the needs-rebase Mergify: the pull request has merge conflicts with its base branch label Nov 4, 2026

@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: actor_kind=model_agent; model=gpt-6.1-sol; provider=OpenAI; declaration_source=runtime_reported; reasoning_effort=max.

动机 / Motivation

启用状态任务图、需要读回依赖和交接的 LoopX 操作者,以及消费 Goal map 的 Chat 界面。 此前同一只读任务图由 Python 组装、TypeScript 决定拓扑;迁移初稿遇到合法带空白身份或大备注时会使整个 status 失败,现在需要在统一 owner 下保留这些输入和默认关闭路径。 当前头在 File/SQLite 的真实 CLI 中保留带空白交接与 4.3M 字符备注,两种格式和开关组合均成功;现有 Chat Goal-map caller 的结果与基线一致,规范记录及显示文件不变。

本轮验收完整源码事务迁移和真实 caller 兼容;按维护者约定,wheel/sdist、安装 Host、匹配 cold/warm latency 与 RSS 留给累积迁移候选,不把减少 RPC 当作已测性能收益。 采用队列中关于真实用户结果的建议:把恢复后的可用工作与原请求结果作为判断对象,不以字段、图边、receipt 或测试数量证明采用和长期收益;该建议不增加执行权限,也不是记忆效用实验。

改动思路 / Approach

完整可选图组合进入既有 TypeScript task_graph owner,Python 仅保留源读取、公开文本事实和传输;身份规范化直接复用 readAgent,没有另建权限规则或第二套脱敏规则。 当前 PR 边界是 status 与 Chat Goal-map 的完整只读组装切换、旧 topology RPC 退役及合法输入保持;累积安装和完整成本资格按维护者约定单独验收。

不改动可保留已工作的旧组合器,却继续把一次事务拆在两种语言;只修两处字符串特判会留下完整身份规则的重复,另建 fallback 又重新引入 Python 决策权威。当前头直接复用 readAgent,只从已批准的 public-text fact 派生规范身份;拒绝的源仍不能借 normalization 绕过。选择、拓扑、证据、gate、handoff、run 和 repair 进入同一 owner,旧 topology RPC 被删除,而纯内部 topology 被复用。Python 公开文本 provider 与源读取暂留是实际部署边界,不能把它们误称为第二个图决策 owner。

Caller 基线与当前头的实际结果
带首尾空白的合法 handoff,图开启 两后端、两格式都成功
合法 4,300,016 字符备注,图开/关 完整输入保留,所有组合成功
默认图关闭 同一 packet 语义保留
Chat Goal map 和独立 canonical 回读 map 相同,记录及显示 bytes 不变

具体改动 / Changes

完整审查 ecbf905402ccfd9e4d75b2b963b52376b4ef7332 → f78fe2d3c4b12e263f916567e2d97ba88018de03,13 文件,+1716/-1038;生产代码 +877/-1030,净 -153。另独立核对上次 4fa58bfe650f81f5723ee880fbfccaa2ccc046e4 → 当前头的 readAgent 修复及目标主干整合。依据 docs/architecture/rfcs/typescript-control-plane-migration-v0.md,spec_revision ecbf905402ccfd9e4d75b2b963b52376b4ef7332;读取修改前规范,新增 ledger 仅作实施说明,不改变接受标准。

  • Stage 0 — implemented:当前 caller、原始字段、身份、输出、关闭模式和源完整性已与不可变基线比较。
  • Stage 2B — implemented:完整事务迁入既有 TS owner;旧 Python selection/build/attach/identity/state/topology-row 决策和 topology RPC 退役,保留进程内 topology。
  • 5. Payoff-phase PR contract — implemented:双语 ledger 说明 owner、physical LOC、crossings、codec、保留重复及 facade/fixture 退出条件;净减代码本身不算行为证明。
  • Caller-observable semantic parity — implemented:当前真实 CLI、完整 packet、Chat map、canonical 不变和负例已执行,见下面结果。
  • Performance — deferred,及 7. Install, upgrade, and rollback — deferred:按维护者已明确的累积迁移约定,在累积候选验收;这不豁免本头的合法输入和真实 backend 正确性,也不授予升级现有 Host 的权限。

关键路径为 task_graph.py:73 的 source/public-text codec 与单请求 facade,task_graph.ts:431 的批准事实与完整 readAgent 身份派生,task_graph.ts:586 的 projectStatusTaskGraph,以及 task_graph.ts:253 的 Goal-map materialization。handler 将旧 topology RPC 换为 status operation,snapshot allowlist 新增该 operation;status 删除旧 callbacks。当前 Python facade 无 native refusal fallback,旧 source codec 不被 TS redaction pattern 副本替代。Goal map 的外部签名、schema/envelope 和现有 Chat 消费接口保留。

相邻收敛采用删除旧决策和 RPC,未引入新配置或权限模型。statusOpenItems 的历史 source-key、先去重后排序与 cap 行为仍在其他 Python 消费者存在,因此保留有限重复并遵循现有 ledger 的统一 native selection 退出条件;不能用不等价的 summary lane 粗暴替换。冻结 corpus 是兼容证据,独立 native tests 才保护语义,不将快照当永久规范。

对主干的风险 / Risks

当前独立公共路径共 32 次 CLI 调用:空白身份和大备注各包含两个后端、两种格式及图开关的 base/head 组合,全部 exit 0。16 份 Markdown 原文比较无差异;8 组 JSON 的完整比较只见 /decision_freshness_summary/generated_at、/event_ledger_summary/generated_at、/usage_summary/generated_at 三个观察时间变化,没有归一化错误、字段缺席、身份、图节点、持久状态或诊断来掩盖差异。最初未声明 adapter.kind 的无效 fixture 在两头都正确失败,已保留为拒绝对照;修正 fixture 的现有 manual adapter 后再验证正常路径,未把前者称为产品回归。Chat Goal-map 的真实 caller 亦在两后端与基线一致,独立 canonical 与显示读回证明未发生写入。

73 项 native 图/handler 测试通过,包含 Unicode/Python whitespace、null/empty 拒绝、cap、缺失前驱和旧 RPC 拒绝。刻意删除一个必要的公开文本事实时,实际 CLI 以 Missing public text facts for display cap 80 失败;同一未变异输入恢复成功。它检验了一个真正会丢失完整状态结果的负面边界,未用 helper 存在性当作敏感性证明。

聚焦 Python 87 PASS / 2 FAIL。两项 planning_horizon 用例在未启用图的 quota should-run 第 238 行抛相同 KeyError;基线同名用例及完整失败内容相同,quota/test blobs 不变。默认17根 mypy 还有一项相同的 task_orchestration_admission.py:110 no-any-return;基线和两个头完整输出相同。Ruff 和完整 control-plane typecheck 通过,bilingual 检查通过。premerge 6 direct PASS / 18 selected PASS / 1 selected FAIL:quota_should_run_json 为 20949 > 20500,用同一原生 smoke runner、同一环境在不可变基线也得到完全相同失败。另一个受控路径在两头均为20741,原始20949失败没有被改写或靠短路径标绿。没有调高预算、缩小输入或查询 CI;该 checker/quota 路径未变,图默认关闭。

因此这些 red checks 是已归因的基线资格问题,保留 strict change-quality 和独立合并 hold;不将它们称为本 PR 已修复,也不要求修复无关 quota。没有测量或声称端到端性能回归或收益。

我的整体评价 / Verdict

APPROVE,仅针对 f78fe2d3c4b12e263f916567e2d97ba88018de03。合法身份和大输入的具体阻塞已在实际入口闭合,默认关闭及另一生产 caller 的兼容有独立证据。完整可选图组合进入既有 TypeScript task_graph owner,Python 仅保留源读取、公开文本事实和传输;身份规范化直接复用 readAgent,没有另建权限规则或第二套脱敏规则。 当前 PR 边界是 status 与 Chat Goal-map 的完整只读组装切换、旧 topology RPC 退役及合法输入保持;累积安装和完整成本资格按维护者约定单独验收。

本次保留长期读回和用户可用性:原来合法的交接记录仍能看到完整状态,失败时不会借 fallback 猜测或修改状态,也不增加必要用户确认。本次只迁移 CLI/HTTP 的只读组装;已检查 attention queue、Chat delivery-review 和现有 dashboard schema 消费路径,没有渲染页面或布局改动。 未验证累积安装 Host 的实际界面采用、真实模型阅读或匹配 latency/RSS;源码字节比较不证明这些结果。 历史 hints 仍是只读上下文,图边和测试数量不证明接收者采用或效益。原生 red checks、strict 资格、旧审查及讨论限制分别保留;本轮没有执行合并或撤销他人结论。

English verdict: APPROVE at f78fe2d. Legal handoff normalization, large-note transport and default-off/Chat-map semantics pass real File/SQLite caller checks. Identical baseline quota/mypy failures and separate merge holds remain; cumulative install/Host/performance qualification is unverified.

This branch has not been deployed

No deployments
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