Skip to content

feat(reliability-diagnostics): compare harnesses and expose combined readback - #3975

Merged
huangruiteng merged 6 commits into
loopx-project:mainfrom
songoow:codex/harness-comparison-diagnostics
Sep 9, 2026
Merged

huangruiteng merged 6 commits into
loopx-project:mainfrom
songoow:codex/harness-comparison-diagnostics

Conversation

@songoow

@songoow songoow commented Sep 6, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Operators can request reliability-diagnostics status --with-receipt to obtain the existing projection and integrity receipt from one ledger read. Projection-only output remains the default. A bilingual, revision-pinned DSH/Pi assessment links this bounded readback increment to #3936 and both Desktop/reliability RFCs.

Explicit --as-of now validates at the projection input boundary regardless of ledger contents. Previously, a timezone-free timestamp could crash with events and be silently accepted without events. Empty, malformed and timezone-free timestamps now produce a contextual error and CLI exit 2; Z and UTC offsets are accepted. Omitting the argument retains historical replay at the last event time. This correction applies with and without --with-receipt.

Ownership and boundaries

Existing capability: reliability-diagnostics; existing provider: dsh-session-events. No new provider, model call, UI, scheduler or control authority. The bounded refactor pass preserves the existing LedgerReading/projection owner and validates its explicit input without introducing another time library or state model. No PostgreSQL authority path changes.

Same-read consistency is not file snapshot atomicity; partial records remain invalid evidence. Full-ledger reads must not become automatic polling without a bounded-read design. DSH remains the first passive event source, not a production managed-runtime selection. Managed panels/supervisors, eligible matched C1, measured C0/C1 overhead and retention/deletion acceptance remain follow-up work; none was executed here.

Validation

  • 137 reliability diagnostics tests passed, including real CLI subprocesses and synthetic temporary ledger files.
  • Regression matrix: missing/empty/corrupt/event-bearing ledger × receipt off/on × Z/offset/timezone-free/malformed/empty time. Tests check exit codes, controlled errors, offset-equivalent age, receipt opt-in and unchanged ledger bytes.
  • The new regression failed before the fix: timezone-free input on a missing ledger exited 0 instead of 2.
  • DSH shadow-observer fixture/CLI smoke, docs governance smoke, Ruff on changed Python, and git diff --check passed.
  • Candidate paths classified as product code, durable regression tests and public docs; private-path/credential-pattern scan clean.

Merged upstream main at a46fe93749163a6fafa2c1b38f0f2f8f51d74814 without conflicts and preserved published history. Local validation is complete; current-head CI and independent review are separate gates. Author self-checks do not constitute independent approval. No merge requested.

@songoow songoow 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.

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

Exact head: 7b9bf61b92a6a710652e96b36bf9ae54aa1c8cab.
No blocking code finding for this bounded CLI/documentation increment. This is not approval to merge while required CI is pending, nor acceptance of a complete Mode B implementation.

动机

有提交价值,但价值应限定为两件事:将既有 L1 event-source 决策与尚未决定的 managed runtime 选择分开;让操作者不必通过两次 CLI 读取取得可能属于不同追加时刻的 receipt/projection。DSH/Pi 材料提供接入成本、权限边界和验收框架,不是实测性能选型。现有 pipeline 无须增加新 HTTP 服务或 supervisor 来获得这个收益。

改动思路

loopx.cli 的真实 dispatch 调用 handle_reliability_diagnostics_command。注册函数增加显式 --with-receipt;handler 先解析一次 ledger,交给既有 projection builder,再按 opt-in 附加既有 receipt builder 的结果。权威输入仍是经独立验证的 LedgerReading,没有新的持久化状态、任务状态转换、scheduler 输入或模型调用。错误仍由现有 CLI ValueError/OSError 边界处理。

正向:同一个已解析 reading 生成两个合同;默认关闭时仍只有 projection。负向:缺失或损坏 ledger 仍报告 invalid,不创建或改写诊断文件。并发追加不是原子 snapshot,文档已明确没有扩大一致性承诺。

具体改动

10 文件,+351/-3:生产 CLI +7,测试 +56,文档 +288/-3,没有生成资源或新增生产模块。机制与问题成比例。

  • loopx/cli_commands/reliability_diagnostics.py:87:argparse 注册 opt-in,默认 false,不自动激活 observer。
  • 同文件 :222 / :260:真实 handler 的 status 分支复用 reading,附加 receipt;原有默认调用路径不新增读盘或写操作。
  • loopx/capabilities/reliability_diagnostics/projection.py:187:原有 builder 已从 receipt 归约 integrity。显式 opt-in 会再次计算 receipt,但不会再次读取文件。这是有限冗余,不值得为七行增量引入新缓存或框架。

本轮独立复跑:96 个相关 Python 测试通过,包括真实 subprocess CLI 与临时文件读回;docs governance 和 diff check 通过。默认输出、缺失/损坏输入、文件字节不变均有覆盖。未执行真实模型 session 或 Mode B UI。远端 required build/pytest/Windows 检查在发布评审前仍运行中。

对主干的风险

[P2] 新读取示例应明确 --as-of 的实时性含义。 docs/architecture/rfcs/harness-selection-dsh-pi-v0.md:86-103 展示了不带 --as-of 的命令并讨论 managed 接入;现有 projection.py:202 默认用最后事件时间作为 as-of。因此将这个命令直接用于当前健康展示时,静默再久也可能得到 age=0/no stall。同一 fixture 本轮验证:不传 as-of 得到 age=0、detected=false;传入后续时间得到正年龄、detected=true。这不是本 PR 引入的运行时回归,且文档明确禁止直接轮询,故不阻断本次窄范围提交。建议同步中英文示例:历史重放可保留默认;实时调用必须传入时区明确的当前评估时间,并显示观测时间。后续 consumer 回归应覆盖该差异,不应悄悄改变旧 CLI 默认。

其余残余风险是 goal ledger 聚合多 session/run、全量读取无大小预算、半行并发追加、上游版本升级差异。这些均未被本 PR 修复,也不应被解释为已可直接接入生产面板。规则沿用 typed integrity contract,没有新增 substring 状态判断;文案 domain-neutral,default-off 和 authority=none 与实现相符。C0/C1/retention 是文档验收条件,不是此代码已经执行的机器门禁。

我的整体评价

建议保留本 PR,按“对比与只读 CLI 增量”完成 CI/维护者评审即可;不必为了使这个 PR 看起来完整,把全部 supervisor 和实验平台塞进来。

产品闭环应继续完成:

  1. 明确 owner、固定两侧安装版本/provider/model/tools/budget 与验收阈值,形成可执行 C0/C1 计划;目前只是方法框架。
  2. 在真实隔离 DSH/Pi session 运行 C0、eligible C1 和 overhead,报告失败样本、完整性与不确定性,不用 fixture 代替实跑。
  3. Mode B 接入先完成 exact goal/session/run、freshness/as-of、有界读取及失败状态合同,再接可见视图;receipt 有效不等于 worker 健康,更不是自动 retry 权限。
  4. 单独验收 supervisor 的启动、恢复、中断、关闭、崩溃及单 Turn 串行化,与 canonical validation/writeback 对齐。
  5. owner 选定 retention/deletion profile 后,以 disposable ledger 验证活跃 writer、备份及删除回执;再回填 RFC 里程碑。

Future-facing pass: reuse existing owners is appropriate; defer a shared receipt/projection optimization until a measured need exists. Full feature completion remains unverified. No merge action requested.

English verdict: APPROVE for the narrowly stated CLI/docs increment, with a non-blocking P2 clarification on --as-of. Required CI and maintainer review remain pending; real C0/C1, overhead, Mode B lifecycle/UI and retention acceptance are not established by this PR.

@songoow

songoow commented Sep 6, 2026

Copy link
Copy Markdown
Collaborator Author

Addressed the review P2 in ecd1dfb: both languages now distinguish historical replay from live evaluation. Live examples explicitly pass a timezone-aware current --as-of (POSIX date); other clients are instructed to supply an equivalent timestamp. Default CLI behavior is unchanged.

Added a real subprocess/file regression: omitted as-of yields zero age/no stall; a later evaluation time detects silence while receipt and ledger bytes remain identical. Validation: 97 related tests passed, Ruff passed, docs governance and diff check passed. Previous-head CI was green; successor-head CI must rerun. Real C0/C1, overhead, Mode B and retention remain separate uncompleted acceptance gates.

@now-ing

now-ing commented Sep 6, 2026

Copy link
Copy Markdown
Collaborator

The increment discipline here is what stands out: --with-receipt reuses the already-parsed LedgerReading (reliability_diagnostics.py:260-261) instead of re-reading the file, so the combined payload cannot observe two different append states, and the default path is byte-for-byte unchanged when the flag is omitted. The test suite earns its confidence the hard way — real subprocess CLI runs, path.read_bytes() invariance, a str(tmp_path) not in json.dumps(...) leak check, and an absent-vs-corrupt split that pins invalid on both. I reran the three reliability-diagnostics test modules on the exact head: 97 passed in 3.4s, and a red probe (flipping the args.with_receipt gate to unconditional) fails test_receipt_opt_in_preserves_projection_and_real_ledger, so the opt-in behavior is genuinely pinned. The ecd1dfb docs pass correctly separates historical replay from live evaluation in both languages, and the RFC pins its evidence to exact upstream revisions without claiming a quantitative winner — that restraint makes the document credible.

One non-blocking finding, plus a small observation:

  1. [P2] A naive --as-of crashes with an uncontrolled TypeError instead of the CLI's error boundary. parse_observed_at (envelope.py:276-277) accepts any fromisoformat-valid string, and _ms_between (projection.py:202-204) then subtracts it from the timezone-aware envelope timestamps. A syntactically valid but timezone-naive value — exactly what common shell habits produce, e.g. date +%FT%T without -u/%z, or Python's datetime.now().isoformat() — passes parsing and raises TypeError: can't subtract offset-naive and offset-aware datetimes outside the handler's except (OSError, ValueError). Reproduced on the exact head via the real CLI: --as-of 2026-09-06T00:00:00 exits 1 with a raw traceback, while --as-of garbage exits 2 with the controlled error: reliability-diagnostics: Invalid isoformat string: 'garbage'. The asymmetry matters more now that this PR promotes live --as-of to the standard operator entry point (README and RFC both say clients "must supply a timezone-aware current timestamp", but nothing enforces it at the machine boundary). Suggested repair: after fromisoformat, reject utcoffset() is None with a ValueError so naive input lands in the existing controlled path, plus a regression asserting exit 2 for a naive timestamp. This is pre-existing behavior rather than a regression introduced here, so it need not block this PR.

Minor: with zero envelopes in the ledger, last_event_age_ms reports 0 even when a live --as-of is supplied (projection.py:202-204 short-circuits when last_observed_at is None). Consumers can disambiguate via integrity.status: invalid and the integrity_not_valid signal, so this is fine at the current seam — just worth remembering when the future panel renders age as a headline number, since "never observed" and "observed just now" both display as zero-age.

Cross-confirmation of the author's self-review points I could verify independently: receipt and projection statuses agree on the same reading by construction (build_diagnostic_projection reduces integrity from build_integrity_receipt), ledger bytes are untouched across both output modes, and --with-receipt on the receipt subcommand is rejected by argparse rather than silently ignored. The double receipt computation and unbounded full-ledger read are correctly called out as deferred; no new disagreement found there.

@songoow songoow 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.

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

Exact head: ecd1dfb5e7156b6369736b956986b9d8a7652e94.

动机

对照 #3936 的实际讨论,本 PR 回应了 DSH/Pi 选型评估和 Desktop RFC 联动,而不是承诺交付整个 managed runtime。以前 operator 分别执行 receipt/status,可能读到不同追加位置;新增组合读取有独立使用价值。不需要为这一步引入面板、supervisor 或新调度器。

改动思路

生产链是 loopx.cli → handle_reliability_diagnostics_command → 一次 read_ledger_records / read_ledger → projection 与可选 receipt。register_reliability_diagnostics_commands 用 store_true 将新增输出显式开启;不加选项保持原有分支。build_diagnostic_projection 仍属于现有诊断能力,不获得 Goal/Todo/lease 或重试权限。

具体改动

  • 生产代码只有 CLI 的 7 行增量;71 行测试通过临时真实 NDJSON 和 CLI 子进程覆盖默认/开启对照、缺失/损坏文件及历史/当前评估时间,属于可复用验证,而不是实验日志。
  • 新增双语 harness 评估,两份既有 RFC 及 capability README 的双语链接/使用说明同步。文档明确区分 DSH 首个 L1 来源与最终 Mode B 选型,未给出未经测量的性能胜负。
  • 正向:开启选项后 projection 不变,receipt 与 integrity 状态相符,文件字节不变。负向:损坏或不存在的 ledger 给出 invalid,不创建“健康”证据。新的调用不激活 observer、不修改 scheduler 输入。
  • 类型/权限审查:增量未添加字符串状态猜测、领域特定控制规则或把强制义务称作 guidance;既有 typed projection/receipt 继续负责诊断语义。CLI 可用不等于 observer 已开启。

对主干的风险

P2,确认存在但不是本 PR 新引入的回归:--as-of 输入校验依赖 ledger 是否有有效事件。 我用真实 CLI 独立复现了此前评审提到的无时区输入,并补充了空账本反例:

ledger as-of 当前结果
有有效事件 2026-09-06T00:00:00+00:00 exit 0
有有效事件 2026-09-06T00:00:00 exit 1,未捕获 TypeError traceback
有有效事件 not-a-date exit 2,可控错误
无文件/无有效事件 上述无时区值或 not-a-date exit 0,非法参数被静默接受

路径:projection.py:201-206 只在存在 last_observed_at 时调用 _ms_between;envelope.py:276-277 的解析函数没有拒绝无时区值;CLI 的 except (OSError, ValueError) 不覆盖 datetime 相减产生的 TypeError。这使同一命令从空账本转为有数据后才突然崩溃。文档现在正式介绍实时 as-of 用法,值得就近补齐,但不应把原有问题误判成 --with-receipt 引入。

最小修复:在 projection 的显式 as_of is not None 输入边界验证 ISO 时间及 utcoffset() is not None,不依赖是否有事件,抛出有上下文的 ValueError 交给现有 CLI 转为 exit 2。不要仅扩大 catch 到 TypeError,也不要只修改 _ms_between,否则空账本仍绕过验证。保持省略 as-of 的历史重放语义。增加有/无有效事件 × Z/offset/无时区/非法/空字符串 × receipt 开关的参数化回归;不用扩大成全局时间库重构。

独立验证:能力测试首次运行 96 passed / 1 子进程超过 30 秒;未修改测试阈值,单独重跑新增 readback 文件 3 passed。另跑上述 6 个真实 CLI 输入组合,结果如表。git diff --check 通过。当前远端 checks 成功,发布/部署类为预期 skipped。本次没有重跑真实 DSH/Pi 模型、开销实验或整个 observer 打包测试;这些不是本次 CLI 增量已完成的证据。

我的整体评价

没有发现本 PR 新增的阻塞性回归,范围和代价相称;建议接受当前 docs + opt-in CLI 阶段,同时优先补上述小型参数校验。该项可在当前 PR 或独立修复 PR 中闭环,不需要把 managed runtime 塞进来。未来性审查:复用现有 LedgerReading 所有者是正确的;projection 内已有 receipt 计算导致的一次重复计算不值得为了 7 行功能新增框架。

与 #3936 的闭环仍需分开记录:评估/RFC 联动已交付;managed 面板与 supervisor 未交付;真实 eligible C1、匹配的 C0/C1 开销证据、retention/deletion profile 仍待专项验收。面板实现前先有 exact goal/session/run 读取范围和有界刷新策略,且空账本不得仅凭 age=0 显示健康。原有全量读取不得直接变成后台高频轮询。

English verdict: APPROVE the bounded docs and opt-in CLI increment at ecd1dfb5e7156b6369736b956986b9d8a7652e94; no newly introduced blocking regression found. Independently confirmed a pre-existing P2 as-of validation gap, including invalid input silently accepted with an empty ledger. Fix at the projection input boundary with aware-time validation and empty/nonempty-ledger regressions. Validation: 96 capability tests passed on the initial run with one CLI timeout; all 3 readback tests passed on isolated rerun; six real CLI counterexamples exercised. Managed runtime, live C1, overhead and retention acceptance remain separate work.

Signed-off-by: song <liusongstep@gmail.com>
…events

Signed-off-by: song <liusongstep@gmail.com>
@songoow

songoow commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator Author

Addressed the --as-of finding in #3975 (review) with fix commit e32576c; current head is 8192589.

Validation now happens at the projection's explicit-input boundary before processing events. Invalid ISO input, empty strings and missing timezones raise a contextual ValueError, which the existing CLI maps to exit 2. No broad TypeError catch or change to omitted-as-of replay semantics. Z and offset timestamps remain accepted. The missing-ledger counterexample failed before the fix and passes afterwards.

Validation: 137 capability tests passed, including the real CLI matrix across four ledger states, five explicit-time cases and receipt off/on; ledger bytes are unchanged. DSH fixture/CLI smoke, docs governance smoke, changed-Python Ruff and diff checks passed. Typed-state/domain-neutrality/authority review found no new classification heuristics, scheduler influence or control-plane obligations. The related refactor pass retained the existing projection input owner; no new abstraction was necessary.

Upstream main a46fe93 merged cleanly. The PR body and bilingual usage docs now disclose the input-validation correction and distinguish local checks from current-head CI and independent review. Live model runs, managed UI, overhead measurement and retention operations remain unexecuted follow-ups. This is an author repair report, not an independent approval; another reviewer is still required.

@songoow

songoow commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator Author

Follow-up author assessment at head 8192589 (source/readback review; no new test run in this pass):

One small, non-blocking test improvement remains in test_explicit_as_of_validation_is_independent_of_ledger: expected age currently takes observed_until from a second projection produced by the implementation under test. A shared error in selecting the final event could therefore make both outputs agree. Prefer an explicitly constructed, known-timestamp event fixture and an independently calculated expected age; this also removes the extra CLI invocation. The current matrix still proves explicit-time rejection, timezone-offset handling, receipt gating and ledger immutability.

No additional runtime blocker found in the examined input-validation/readback paths. The new validation is domain-neutral and uses the existing projection owner, adds no state classification heuristics or authority, and preserves omitted-as-of replay. The intended invalid-input behavior change is now disclosed for both receipt modes. Keep bounded reads, exact session/run selection, live C0/C1 and retention work as separate increments.

Current-head CI is still pending in several jobs and GitHub requires independent review. Prior author self-checks and the cross-author comment on the old head are not current-head approval. The next useful step after CI is a fresh review of the repaired head, rather than broadening this PR.

@huangruiteng huangruiteng 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.

结论:APPROVE。当前 head 819258921b407ebc413759ee4edd0c4e4d15333c 没有阻塞性发现;--as-of 的旧问题已在真正的 projection 输入边界修复,--with-receipt 也保持默认关闭且复用同一次 ledger read。

动机

这个 PR 解决两个相邻但边界清楚的问题:一是 DSH 作为首个 L1 事件源不能被误读成已赢得 Mode B managed-runtime 选型;二是操作者分别调用 receipt/status 时可能读到两个不同追加位置。后者会让 integrity 与 projection 在诊断现场互相矛盾,前者则容易把 fixture 和接口可用性夸大成生产选择证据。

最终行为是:默认 status 仍只返回 projection;显式 --with-receipt 时,两个既有合同来自同一个 LedgerReading。实时诊断必须提供带时区的当前 --as-of,省略只代表历史 replay,不宣称当前 liveness。

改动思路

公共入口仍是 loopx reliability-diagnostics status。handler 只读一次目标 ledger,先交给 build_diagnostic_projection,再在 opt-in 分支把同一 reading 交给既有 build_integrity_receipt。没有新 storage、snapshot service、scheduler input 或 Goal/Todo 写入。

build_diagnostic_projection 在消费事件前统一验证显式 as_of:ISO 解析失败、空字符串或缺少 timezone offset 都抛出有上下文的 ValueError,现有 CLI 边界稳定映射到 exit 2。这个位置很关键:它使空/缺失/损坏 ledger 与 populated ledger 使用同一输入规则,而不是等到 datetime 相减时才偶发崩溃。

具体改动

精确 diff 为 11 文件、+445/-3:production 2 文件 +16,subprocess regression 1 文件 +116,双语 RFC/README 8 文件 +313/-3。

关键代码讲解

  • register_reliability_diagnostics_commands 增加 status 专属 --with-receipt,store_true 默认 false;receipt 子命令不会悄悄接受该 flag。
  • handle_reliability_diagnostics_command 只调用一次 read_ledger_records / read_ledger。启用 flag 只是追加 build_integrity_receipt(reading),不会二次读盘或写 ledger。
  • build_diagnostic_projection 把显式时间校验前移到 reducer 入口。省略 as_of 的 replay 语义保持不变;显式值则必须 timezone-aware。
  • 新测试通过真实 CLI 子进程和真实临时 NDJSON 覆盖 flag off/on、missing/empty/corrupt/events 四类 ledger、Z/offset/naive/malformed/empty 五类时间,以及 ledger bytes 不变。

仓库复用是合理的:projection、receipt 和 ledger reader 都沿用现有 owner;没有为 16 行生产改动创建新抽象。DSH/Pi 文档也明确区分 passive observation、managed lifecycle、provider/工具/预算一致性、公开证据边界和 retention,未声称未经测量的赢家。

对主干的风险

没有阻塞性 finding。不可忽略但已正确披露的残余边界有:并发 append 不是原子 snapshot;当前是全量 ledger read,不应直接进入高频自动 polling;missing ledger 的 age=0 不能被 UI 渲染成“刚刚健康”;真实 C0/C1、overhead、Mode B lifecycle 和 retention 仍未完成。

另有一个非阻塞测试改进:参数化测试计算 expected age 时先从同一实现生成的 observed_until 取值,最终事件选择如果同时出错,oracle 可能跟着错。后续可用已知 timestamp 的最小 fixture 独立算期望值。未来若要支持早于 observed_until 的历史 cutoff,也应明确过滤事件或拒绝负 age;本 PR 当前只承诺“省略为 replay、显式当前时间为 live”。

本轮验证:137 个 capability tests 全过(78.56s);DSH fixture smoke、docs governance、Ruff、git diff --check 全过;真实默认 Markdown 与 opt-in JSON readback 均通过;当前 head 远端 19 checks 全绿。

我还用同一 populated ledger 对比 immutable base a46fe9374 与当前 head:默认 projection 归一化后完全一致;base 的 naive time 在有事件时 exit 1 traceback、无 ledger 时 exit 0 静默接受,head 两者均稳定 exit 2;base 不认识 --with-receipt,head 返回同一次 read 的匹配 receipt/projection。这证明的是公共入口语义,不只是 helper 单测。

我的整体评价

这个 PR 可以批准。运行时代价很小,文档虽然占大头,但它承担了防止“L1 adapter 可用 = managed runtime 已选定”的必要边界说明;修复后的输入合同也回应了此前 review 的真实反例,而不是扩大 catch 或依赖 ledger 内容。

Future-facing pass:当前继续复用两个 reducer 是正确的,没必要抽象 shared snapshot object。下一个有价值的阶段应是 exact goal/session/run 的有界读取与真实 C0/C1/overhead 证据;在这些完成前,不应把本 PR 解释成 panel 或 supervisor 已可生产使用。

English verdict: APPROVE exact head 819258921b407ebc413759ee4edd0c4e4d15333c. The default projection-only path is baseline-equivalent, the opt-in receipt shares one ledger read, explicit invalid timestamps now fail consistently at the projection boundary, 137 focused tests and all current-head remote checks pass. Live C0/C1, bounded polling, managed-runtime lifecycle, overhead and retention remain outside this approval.

@huangruiteng
huangruiteng merged commit 6f6255e into loopx-project:main Sep 9, 2026
19 checks passed
@songoow
songoow deleted the codex/harness-comparison-diagnostics branch September 16, 2026 05:54
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