Skip to content

feat(turns): watch persisted journal progress - #5998

Merged
huangruiteng merged 2 commits into
loopx-project:mainfrom
mikamikasuki:codex/loopx-turn-journal-watch
Oct 10, 2026
Merged

huangruiteng merged 2 commits into
loopx-project:mainfrom
mikamikasuki:codex/loopx-turn-journal-watch

Conversation

@mikamikasuki

@mikamikasuki mikamikasuki commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Goal and delivered outcome

  • Outcome basis: issue #5886 identifies a gap in operator visibility during long-running Turns and suggests journal polling as a workaround.
  • Goal and gap: On canonical main 647e216bacc0a69368dccc18fcb52dcba6002553, turn inspect-journal reads once, so operators cannot follow persisted phase checkpoints while a run is active.
  • Observable change: The CLI now supports opt-in --watch polling with JSON Lines or Markdown output. It emits only changed, allowlisted status and completed-phase fields and exits at a terminal journal state. It rejects inconsistent typed journal results before emitting progress, while still allowing a consistent in_progress journal to be observed.
  • Scope: Read-only CLI output and English/Chinese custom-runner guidance. This does not report transient, unpersisted host progress or change execution, authority, quota, or settlement behavior.

Author declaration

  • Written by: model_agent — OpenAI GPT-6 Luna Medium.
  • Some coding work was AI-assisted. I personally reviewed the changes, verified the relevant behavior and tests, and take responsibility for the submission.

Implemented against

Criterion Result Evidence
Follow persisted status and phase checkpoints Implemented turn inspect-journal --watch; concurrent-writer regression
Keep progress output allowlisted and consistent Implemented Existing typed inspection result gates each event; mismatched owner and invalid phase regressions
Document the opt-in command for custom runners Implemented English and Chinese integration guides; CLI help

Validation

  • Tested head: d1e47f26f8cf630171d45771b2184e1a5601a384, based on canonical main 647e216bacc0a69368dccc18fcb52dcba6002553.
  • Regression/unit: tests/test_loopx_turn_journal_inspection.py and tests/test_loopx_turn_executor.py — 115 passed on this exact head, including inconsistent owner/phase rejection and consistent in-progress observation.
  • Static: Ruff on changed Python modules and tests, Python compilation, and git diff --check origin/main...HEAD passed. Both commits contain DCO Signed-off-by trailers.
  • Earlier full validation on pre-rebase implementation head a7f4b1f: strict mypy (19 source files), TypeScript typecheck, semantic smoke, CLI help, and pre-merge canary (14/14) passed.
  • Hosted checks after this rebase have started: Summary is in progress; DCO, dependency review, Frontstage Pages, Release Artifacts, and both adapter-contract checks are queued; merge-gate is expected. The changes-requested review refers to older head f4d9015; the fix and current-head test results are documented in the review follow-up. No merge is claimed.

Coverage and boundary

Tests cover changed-only event emission, terminal exit, interval validation, private-content exclusion, inconsistent owner/phase rejection, and observation of persisted checkpoints from a concurrent journal writer. The journal must exist when watching starts. Transient host progress that has not been persisted is outside this change.

Frontend / visual evidence

  • UI impact: none; this adds a CLI option and integration documentation.

Type of change

  • New feature
  • Documentation update
  • Test update

LoopX area

  • Control plane

Technical direction

Additive operator-facing observability for the existing Turn journal. No architecture or authority contract changes.

Shared-authority RFC fixture impact

  • Production-scale fixture schema: N/A.
  • Semantic dimensions: unchanged; no shared-authority schema or provider semantics changed.
  • Provider conformance arms: N/A.
  • Read-only backend rehearsal: N/A.

Boundary checklist

See validation disclosure guidance.

@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; runtime_reported; reasoning_effort=xhigh.

Reviewed exact head f4d90159e370c8c8ab3cad01778395c49b529cdc against base 3ed5d6bc88ffaaa05f2b1bc6a98ed5d921379fd1. REQUEST_CHANGES:一项当前进度投影缺陷。

动机

运行长任务的自定义 runner 操作者需要及时看到已经写入 journal 的阶段进展。
旧命令只能单次查看;新 watch 能随持久化阶段变化输出,但身份不匹配或 journal 不一致时仍输出成功事件。
真实 CLI 已观察到并发写入的阶段变化;同时复现了错误身份和非法阶段被当成正常 committed 进度。
本 PR 不提供未持久化的 Host 步骤进度,不改变执行权限、额度或停止结算,也未交付 packaged frontend。
当前 safe 进度流仍缺一致性拒绝;长时间 Host 阶段的细粒度进度和 frontend 采用仍未验收。

完整读取 #5886 后,我将 journal 轮询视为它明确提出的有用 workaround,而不是完整解决 40–85 分钟 Host 步骤可见性的声明。召回的恢复旅程建议只用于检查这个交付边界,不继承旧结论或宣称记忆提升了模型效果。

改动思路

轮询和格式化适合留在既有 CLI I/O adapter;一致性必须继续由现有 TypeScript owner 决定。
本轮最小修复是在构造事件前消费 journal_consistent,安全报告绑定或阶段错误;保留正常 in_progress 观察。

与手工反复调用单次 inspection 相比,changed-only 流能减少操作成本;无需另造 journal、事件持久化或执行框架。最强反对理由是:读到了文件不代表 journal 一致,缩短投影不能丢掉错误语义。当前代码复用低层读取,却没有消费它已提供的一致性结论。

具体改动

全量 B..H 覆盖六个文件、+340/-0:两份 runner 指南加入可选调用及终止说明,registration 加入 --watch / --watch-interval,inspection 增加轮询和状态/阶段 tuple 去重,rendering 增加 Markdown 进度格式,原 inspection 测试文件加入 mock 快照、非法间隔和并发 writer 三个用例。

关键代码讲解

  • register_turn_commands 保持 watch 默认 false;只有显式调用才进入新分支,help/指南是可选入口说明。
  • handle_turn_journal_inspection 继续使用实际锁定 journal 和 TypeScript 解释器,再以 (status, completed_phases) 去重;ok 只证明读取成功,不能替代 journal_consistent。
  • render_loopx_turn_journal_progress_markdown 格式化新投影,不能修正前面已经丢掉的绑定或阶段验证。

规格依据:https://github.com/loopx-project/loopx/issues/5886,issue body revision sha256:b6a0badb06b9a51843d6ad42f4d07f3162d7e553a799ee21d723920e2f71c647;同时对照 3ed5d6bc88ffaaa05f2b1bc6a98ed5d921379fd1 的 loopx/control_plane/turn_driver/turn_journal.ts 和原 inspection 契约。persisted-progress implemented:真实 CLI 观察到三个持久化快照;truthful-safe-projection not_met:下面的反例;transient-host-progress deferred:仍在 #5886 原有需求中,未交付 frontend 或未持久化 Host 事件。

语义与CI对齐

新 loopx_turn_progress_event_v0 是观察投影,不是执行回执。terminal 的本地轮询集合复用已有状态语义;身份和 ordered-prefix 的权威仍在 TS owner。开发期 advisory 和 full semantic smoke 均通过,但 advisory 的空结果不覆盖动态语义,也不能证明这个有损投影正确。未查询、轮询或等待 CI。

对主干的风险

[P2] 不要把读取成功当成一致的进度。 用同一真实 committed journal,把 CLI agent 改成不同身份:原 inspection 报 owner_matches=false、journal_consistent=false、owner_mismatch 和 blocked recovery;watch 却把调用者填写的 agent_id 放进 committed 事件并 exit 0。将 completed_phases 改成非法合成文本,原 typed reader 同样明确报告不一致;watch 原样输出文本并成功退出。所有作者的 112 项相关测试仍通过。这里证明的是新增投影丢失诊断和错误归属;没有声称本地可信 CLI 成了远程认证边界或实际泄露了私人账户数据。

最小修复:消费现有 journal_consistent,在绑定或阶段不一致时返回安全可读的诊断,不生成可信进度事件;合法 in_progress 虽然 replay_blocked,仍应可观察,因此不要直接把 replay_legal 当 watcher 准入。补 real CLI 的错 owner、非法 prefix 和合法 in_progress 负/正例。

独立 source-checkout 验证:112 focused tests、Ruff、configured mypy 19、TS typecheck、完整 semantic smoke、DCO 和 diff check 通过。另起真实 CLI 与锁定文件 writer,依次观察 in_progress 空阶段、host_execute、committed;JSONL/Markdown terminal 和 0/NaN/Inf/负 interval 边界已验。关闭 watch 时,B/H 的完整 inspection JSON 逐字段相等,无归一化;base 的 --watch exit 2。观察过程未改 journal 内容,也未执行 Host、额度或 settlement effects。

两次私有 probe 准备失败(重复建目录、误用缺少入口的 Python module)已保留并修正,没有把它们记为 PR 回归。以上结论来自修正后真实 CLI 和实际 TS 读取,未用 mock 提供所需后置条件。未测试长时间轮询成本、live 模型、Windows、packaged frontend 或安装采用。

我的整体评价

REQUEST_CHANGES。真实 persisted-progress 入口有价值,默认单次路径保持,但错误 journal 不能被包装成健康进度。未来重构检查落在同一小边界:保留 CLI I/O,将一致性判断留给现有 TS owner,补齐投影而不是添加第二套状态规则。该修复与正/负 CLI 回读通过后,再评估这个有界增量;不要求本 PR 一次完成整个 milestone 或 frontend 产品。

English verdict: REQUEST_CHANGES — exact head f4d9015; the new watch stream drops existing typed identity/consistency diagnostics and reports invalid journals as successful committed progress. 112 focused tests, static/semantic checks and healthy real concurrent CLI observation pass; independent wrong-owner and invalid-phase probes expose the missing guard.

@mikamikasuki

Copy link
Copy Markdown
Contributor Author

Review follow-up for the findings on f4d9015:

The watch path now requires the existing typed inspection result to report journal_consistent=true before it emits a progress event. An inconsistent journal prints the existing structured inspection diagnostic and exits 1. The gate does not require replay_legal, so a consistent in_progress journal remains observable.

Added real CLI regressions for mismatched owner and invalid phase prefix, plus an in_progress-to-committed watch. Before the fix, both negative cases returned 0 and emitted the progress projection. On commit a7f4b1f, all three focused regressions and the existing watch/concurrent-writer cases pass; the full inspection/executor modules pass 115 tests. Ruff, Python compilation, strict mypy (19 source files), CLI help, diff checks, and the repository premerge canary (14/14) pass.

The commit is pushed to this PR branch. Fresh hosted checks are queued; I will report their results when they finish.

@mikamikasuki

Copy link
Copy Markdown
Contributor Author

CI attribution for run 37862599353 at PR head a7f4b1f: the Frontstage Pages build fails in examples/blog-bilingual-index-smoke.mjs because it expects one exact relative href for edgebench-feedback-and-memory. I reproduced the same failure on this PR's exact base 3ed5d6b (node examples/blog-bilingual-index-smoke.mjs, exit 1); the changed files in #5998 do not touch the smoke or blog content. The equivalent-destination correction is already submitted in PR #5968, whose head passes all six bilingual article pairs locally. This is a pre-existing unrelated check failure, not a regression from #5998. #5998's other hosted checks are still pending; I am not claiming the overall run is green.

@mikamikasuki

Copy link
Copy Markdown
Contributor Author

CI attribution for run 37862599634 at head a7f4b1f: test-shard (1) completed with 4 failures, 4,757 passed, and 71 skipped; test-shards (2)–(4) and dashboard-acceptance were cancelled. The admission-codec replay assertion reproduces 3/3 on current upstream main 0e5acf and on this PR head, so it is not caused by this diff; the assertion predates this PR and now conflicts with the exact-source recovery boundary added in #5939. The canonical-successor failure is also present on current main: the parser supplies derived content_revision metadata to a strict domain fixture. Its correction is already in #5994. Two scripted Doubao actor cases raised provider_transport_failed, but the job output suppresses the underlying exception, so I cannot attribute those further. Other hosted checks passed or are listed separately above.

@mikamikasuki
mikamikasuki force-pushed the codex/loopx-turn-journal-watch branch from a7f4b1f to 6da959d Compare October 9, 2026 03:57
@mikamikasuki

Copy link
Copy Markdown
Contributor Author

Current-head attribution for Frontstage Pages job 113662411500 (run 37881637281, head 6da959d): it fails on the same edgebench-feedback-and-memory paired-link assertion. I ran node examples/blog-bilingual-index-smoke.mjs three times on exact PR base fac40bb and three times on current head; all six runs exit 1 with the same assertion. #5998 changes only journal CLI, docs, and tests, not this smoke or the blog catalog. The pending smoke correction is in open PR #5968, whose diff changes this validation script. This is a baseline failure, not a #5998 regression. Other checks remain pending; I have not treated the overall run as green.

@mikamikasuki
mikamikasuki force-pushed the codex/loopx-turn-journal-watch branch from 6da959d to a4fd1b6 Compare October 9, 2026 04:44
Add an opt-in read-only watch mode to turn inspect-journal. Emit allowlisted JSONL or Markdown events only when persisted status or phase checkpoints change, and stop at terminal journal states.

Document the shared runtime-root invocation in English and Chinese.

Related to loopx-project#5886.

Signed-off-by: mika <211269698+mikamikasuki@users.noreply.github.com>
Signed-off-by: mika <211269698+mikamikasuki@users.noreply.github.com>
@mikamikasuki
mikamikasuki force-pushed the codex/loopx-turn-journal-watch branch from a4fd1b6 to d1e47f2 Compare October 9, 2026 05:28
@mikamikasuki

Copy link
Copy Markdown
Contributor Author

Rebased the existing #5998 branch onto canonical main. Current head d1e47f2; base 647e216. The journal_consistent guard and wrong-owner/invalid-phase CLI regressions are retained. On this exact head, tests/test_loopx_turn_journal_inspection.py plus tests/test_loopx_turn_executor.py pass (115); Ruff, Python compilation, diff check, and both DCO trailers pass. Fresh hosted Summary, DCO, dependency, two adapter-contract, and two build checks have started and are pending. The REQUEST_CHANGES review is on prior head f4d9015; the fix was already documented and review remains requested; please reassess this rebased head.

@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=xhigh.

Exact head: d1e47f26f8cf630171d45771b2184e1a5601a384; frozen base: 647e216bacc0a69368dccc18fcb52dcba6002553.

动机

运行长任务的自定义 runner 操作者需要及时查看已经落盘的阶段进度。
旧命令每次只读一次,操作者需要反复重输同一身份;watch 用同一命令持续报告已落盘的状态和阶段变化。
已验证真实 CLI 可观察并发写入的阶段变化、正常结束和提前停止;错误身份及非法阶段会给出原诊断并拒绝健康进度事件。
本增量仅观察持久化 journal;不提供未落盘的 Host 步骤,不执行任务、扣额或取消任务,也不声明 frontend 已交付。
长 Host 阶段内部的瞬时进度及 packaged frontend 的采用仍在 #5886 中待交付。

召回建议用于核验真实使用、恢复和有界交付;旧 recovery-RFC 结论不继承,未证明记忆带来模型效用。

改动思路

轮询与格式化留在 CLI I/O adapter,一致性与恢复继续消费既有 TS owner,不增加第二套状态判断。
本 PR 是 #5886 明确提出的 CLI journal 轮询 workaround;frontend 与未持久化 Host 进度保持原需求中的开放边界。

与继续手工反复 inspection 相比,直接复用既有 reader 的轮询成本和维护面更小;不必新增 journal、scheduler 或执行事件框架。

具体改动

完整 B..H 六文件 +424/-0:两份 runner 指南 +33,CLI inspection +98、registration +15、rendering +20,原 inspection 测试 +258。新开关在默认单次路径之外,实际读取、锁和规则仍复用原入口。

关键代码讲解

  • register_turn_commands(turn_registration.py:51)提供 --watch / --watch-interval,默认 watch=false;可从 help 和两份指南发现。没有持久化配置开关。
  • handle_turn_journal_inspection(turn_inspection.py:22)每次走原 locked reader/TS interpreter;先要求 ok 与 journal_consistent,再用 (status, phases) 去重和 flush。replay_legal 与观察资格分别判断,合法 in_progress 不被误挡。
  • render_loopx_turn_journal_progress_markdown(turn_rendering.py:277)只展示允许的状态/阶段;JSONL 另带原请求身份和空 effects,均排除 Host/session/receipt 内容。
  • 未修改的 TurnJournalInspection / turn_journal.ts 继续唯一决定身份、phase prefix、一致性与恢复;terminal 集合只是 CLI 观察停止条件,不执行 terminal settlement。

规格:spec_ref https://github.com/loopx-project/loopx/issues/5886;spec_revision sha256:b6a0badb06b9a51843d6ad42f4d07f3162d7e553a799ee21d723920e2f71c647. 同时读取冻结 base 647e216bacc0a69368dccc18fcb52dcba6002553 的 typed journal contract。逐项:persisted-progress implemented;truthful-safe-projection implemented;transient-host-progress deferred,仍由原 issue 承载 Host 内部事件和 frontend 的需求。此次按有用 CLI workaround 判断,没有将作者 UI impact=none 当作完整产品验收。

语义与CI对齐

loopx_turn_progress_event_v0 是本地只读观察投影,不是执行/扣额回执。关闭 watch 时,B/H 完整 inspection JSON 逐字段完全相同;help/docs 只增加明确的可选说明,不自动开启行为。原 typed diagnostics、额度/执行/恢复义务没有删除。advisory 在 full semantic 前运行,0 候选不能覆盖动态/单值语义;完整 semantic、TS typecheck 与 static 检查通过。没有查询、轮询或等待 CI。

对主干的风险

旧评审 head f4d90159e370c8c8ab3cad01778395c49b529cdc 的错 owner / 非法 phase 两项反例,本次分别在旧 head 和当前 head 通过实际 CLI 重跑:旧版均生成健康事件、exit 0;当前返回完整 owner_mismatch 或 completed_phases_not_ordered_prefix 诊断、exit 1,不生成健康事件,也不修改文件。

独立同一 actual File journal + TS reader:并发 locked writer 产生 phase1→phase3→committed,观察到三条已 flush 的状态变化;重启 watcher 两次读相同终态、文件字节不变;正常 in_progress 虽 replay blocked 仍可观察;committed/stopped/failed 结束 exit 0,Ctrl-C exit 130 只停止 observer;0/NaN interval 拒绝。两种格式与 private-content 排除均验证,没有 mock 提供关键一致性后置条件。

115 项正式测试、Ruff、configured mypy 19、TS typecheck 通过。native premerge 13/14 通过,保留一项红色质量 gate:examples/control_plane/cli-output-budget-regression-smoke.py。同命令在冻结 base 647e216bacc0a69368dccc18fcb52dcba6002553 与 head 都失败,四项 Todo list 行和增长数值完全相同(7583/4951/1007/2759 chars);该 PR 不改 Todo list/其预算因果路径,默认完整 inspection 又精确相等。按原验证政策归为 pre_existing_unrelated,不称整个 canary 通过,也不调整预算或删除断言。

首次 failed-journal fixture 把 failed_phase 放错位置,造成合法拒绝;更正为既有 receipt 字段后 failed 终态通过,原失败保留。另有准备时脚本名、npm 依赖和 TS script 名错误,修正后通过,未算产品回归。没有验证多小时轮询 CPU/延迟、live 模型、Windows、packaged frontend 或本机升级采用。

我的整体评价

APPROVE 这个有界 CLI 增量;native premerge 的独立基线红项保持。 原阅读成功≠一致性的问题已通过原 TS owner 的正确消费关闭。一次启动代替反复输入,可正常结束、停止观察和读回,效果和操作效率有具体正向证据;没有测量多小时资源或模型收益。

未来重构检查:重复 diagnostic 分支可在邻近改动时合并为一个小函数,terminal names 继续复用当前 TS 契约;当前轮询未新造第二个决策 owner,无需为此添加框架。完整 #5886 / frontend 没有被这个 workaround 结算,原需求保留。APPROVE 不是 merge 或升级授权。

English verdict: APPROVE — d1e47f2; the existing typed consistency verdict now rejects wrong-owner/invalid-phase watches while healthy persisted progress, terminal restart, default single-shot parity and read-only Ctrl-C work through real CLI. 115 focused tests and static/semantic checks pass. Native premerge is 13/14: an unchanged Todo-list budget failure independently reproduces on the immutable base and head; preserve that separate quality hold. No CI, merge or upgrade claimed.

@huangruiteng
huangruiteng merged commit 7fe9ccd into loopx-project:main Oct 10, 2026
30 of 36 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