Skip to content

fix(todos): match Python ISO timestamp parsing - #5823

Merged
huangruiteng merged 4 commits into
loopx-project:mainfrom
mikamikasuki:codex/loopx-timestamp-parity-final
Oct 7, 2026
Merged

huangruiteng merged 4 commits into
loopx-project:mainfrom
mikamikasuki:codex/loopx-timestamp-parity-final

Conversation

@mikamikasuki

@mikamikasuki mikamikasuki commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Goal And Delivered Outcome

  • Outcome basis: Reproduced cross-version incompatibilities in the shared Todo timestamp writer and retained scheduler reader.
  • Goal/source and gap: Keep accepted timestamp wire forms semantically stable across supported Python versions and the TypeScript codec. CPython 3.14 applies fractional seconds to a timezone offset whose hour, minute, and second are zero; Python 3.11–3.13 and the TypeScript codec treat that offset as UTC.
  • Observable before → after: On previous head 5e4f1fc, 2030-01-01T00.1+00.5 and 2030-01-01T00:00:00.1+00:00:00.5 could be persisted by the CLI, then read by Python 3.14's scheduler as 2029-12-31T23:59:59.600000+00:00 instead of 2030-01-01T00:00:00.100000+00:00. The reader now canonicalizes zero hour/minute/second offsets to UTC before version-specific parsing. Earlier findings are also addressed: supported fractional shorthand is preserved and local 24:00 expiry values are rejected before persistence.
  • Issue/task and intended base: Self-contained fix permitted by CONTRIBUTING.md. Tested against current main da45cfe; submitted and reviewed head is 900530f.

Author Declaration

  • Written by: model_agent — OpenAI GPT-6 Luna.

Implemented against

  • Specification and revision: Caller-observable semantic-parity gate in docs/architecture/rfcs/typescript-control-plane-migration-v0.md and retained reader behavior in loopx/control_plane/runtime/time.py, at base da45cfe.
  • Criteria:
Criterion Disposition Symbol / path Test
Preserve accepted fractional shorthand across supported Python versions implemented parseTodoTimestampMicros; parse_timestamp test_monitor_state_owner.py; monitor_metadata.test.ts
Treat fractional zero-hour/minute/second offsets as UTC implemented _stable_iso_timestamp_text CLI persistence and scheduler readback; Python/TypeScript regression cases
Reject local hour 24 before storing a scheduler-unreadable expiry implemented parseTodoTimestampMicros; parse_timestamp test_monitor_state_owner.py; monitor_metadata.test.ts
  • Self-check: Reproduced the cross-version cases, ran them through the Todo CLI, verified persisted metadata, and read the values with the production scheduler reader on Python 3.12 and 3.14.

Scope And Continuation

  • Completed scope: Stabilize the shared Todo timestamp grammar and keep stored expiries readable by supported scheduler runtimes.
  • Slice boundary / successor: Complete within this scope.

Validation

Check Result
tests/control_plane/test_monitor_state_owner.py 47 passed on Python 3.11.17, 3.13.16, and 3.14.8; 69 monitor and follow-through cases passed on Python 3.12.15
tests/control_plane_ts/monitor_metadata.test.ts 10 passed on Node.js 24.19.0
History chronology reader 6 passed
Real CLI persistence and scheduler readback For nine fixed-oracle inputs, Python 3.12 base/head both matched all nine expected values; Python 3.14 base had six mismatches and the head matched all nine. Both zero-offset fractional examples read as 2030-01-01T00:00:00.100000+00:00. Rejected inputs left state unchanged.
Extended codec oracle All 16 fixed-oracle cases passed on the head with Python 3.12 and 3.14, and on the base with Python 3.12
Static and semantic checks Ruff, TypeScript typecheck, Python compilation, and semantic validation passed
Pre-merge and focused risk checks 17 selected pre-merge checks plus 8 focused risk smokes passed; zero failures or manual holds

The full repository pytest suite, Windows, packaged App upgrade, and live worker were not run.

Frontend / Visual Evidence

  • UI impact: none.
  • Before / after / states and viewports: N/A.
  • Source data: none.
  • Attention review: N/A; no UI changed.

Type of Change

  • Bug fix
  • Test update

LoopX Area

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

Technical Direction

  • Direction / acceptance reference: Bounded cross-version timestamp compatibility repair.

Shared-authority RFC fixture impact

  • Production-scale fixture schema: N/A.
  • Semantic dimensions changed or reviewed no-impact rationale: N/A; no shared-authority contract changed.
  • Provider conformance arms: N/A.
  • Read-only legacy/file/PostgreSQL three-arm rehearsal: N/A.

Boundary Checklist

  • No private state, credentials, raw traces, internal links, or local machine paths are included.
  • No maintainer-owned benchmark work was duplicated.
  • The change is scoped to the reproduced timestamp-compatibility defect described above.
  • UI evidence is not applicable because no UI changed.
  • Every commit includes a DCO Signed-off-by trailer.

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

REQUEST_CHANGES — exact head c8148049ecac44d7bd1f6a705557134995e7a052; immutable merge-base 9602d815f1ddb48b54c267b9b80aab6499b99256.

动机

需要用时间戳设置监控任务过期时间的 CLI 用户及后续 scheduler 消费者。 基线在受支持的 Python 3.12 上接受简写小数时间并拒绝 24:00:00;当前 head 反转了这些输入规则。 拟修复 Python 3.14 的解析差异,但独立真实 CLI 证明:Python 3.12 原可用输入被拒绝,24:00:00 被写入后 scheduler 读回为 None。 本批只审查现有时间戳 codec,不要求新增存储、UI、能力开关或完成整个 TS 迁移。

改动思路

时间戳规则复用既有 TypeScript runtime_timestamp.ts;Python 保留 transport 与兼容读取。没有新模块、平行状态 owner 或存储改造。 作者想修复在 Python 3.14 观察到的规则差异,但项目 pyproject.toml 声明 requires-python = ">=3.11",当前规则仍由 retained Python reader 消费。不能只选择 3.14 的结果而静默破坏受支持的 3.12。最强不合并理由是合法输入被拒绝、无效 expiry 可成功落盘却不被 scheduler 理解。

具体改动

完整三个路径 +23/-4:runtime_timestamp.ts 的 clock 新增无秒小数拒绝(同时影响本地时间和偏移),将合法本地小时扩大到24并约束零分秒,阻止9999年末滚到10000年;Python parity列表补三个年末值;TS测试修改为3.14期望。

事先读取 accepted spec,spec_ref docs/architecture/rfcs/typescript-control-plane-migration-v0.md,spec_revision 9602d815f1ddb48b54c267b9b80aab6499b99256。Criterion Caller-observable semantic parity is a promotion gate: not_met。原规则、Python parser与支持版本声明在当前主干 a8b759d03e976646aaec6126112b8407cd2a8272 相对B均未变化,失败不能归给新增主干或既有预算债务。

[P1] Preserve the supported-Python timestamp contract — loopx/control_plane/runtime_timestamp.ts:76(同一 clock 的24小时分支)。在 Python3.12.15 的不可变B/H上,以同一冻结脚本调用真实 todo update --expires-at、真实TSplanner、隔离legacywriter,并读取持久化Todo与生产 monitor_todo_expires_at:

输入 B CLI H CLI H scheduler
2030-01-01T00.1 接受 拒绝 无写入
2030-01-01T00:00.1 接受 拒绝 无写入
2030-01-01T00:00:00+01.1 接受 拒绝 无写入
2030-01-01T24:00:00 拒绝 接受并持久化 None

复现 suite:uv run --extra test python -m pytest -q tests/control_plane/test_monitor_state_owner.py。B35passed;H2failed/36passed,失败为 1970-01-01T00.1 和 1970-01-01T24:00:00 的 retained Python parity。独立CLI还发现分钟简写和偏移简写同类回归。H的10项TS测试通过,因为其期望已经改成3.14规则,不能反证跨版本兼容。在现有 typed codec 边界明确跨受支持 Python 版本的稳定兼容规则,保留已有合法输入,并让写入与 scheduler 读取一致;添加 3.12 和 3.14 的独立版本案例。不要跳过失败 parity 或顺手提高最低 Python 版本。

对主干的风险

已证明CLI接受性与实际scheduler读取不一致,影响既有监控expiry。三项被拒绝输入及24:00:01、9999年末rollover负例均未写入;标准Z时间戳两侧正常,全部14个案例改用标准Jan2时间戳后恢复成功。没有改动生产Goal或任何存储authority。Ruff、control-plane TypeScript typecheck、changed advisory之后全树semantic通过;空advisory不证明兼容。Python 3.11/3.13/3.14、packaged App、实时 worker 和完整 premerge 未执行;作者的 3.14 结果未当作本角色实测。 完整gate没有冒充通过;没有查询、轮询或等待CI。

我的整体评价

REQUEST_CHANGES。边界与代码量适当,复用现有typedowner是正确方向,但当前精确版本未达到支持版本的兼容结果。Retain this codec boundary but repair supported-version semantics before approval. Future-facing pass建议在这一个codec明确稳定grammar并覆盖已有reader,避免再增加平行parser或隐藏版本选择。标准输入恢复只证明有用户绕行,不消除introduced regression。本角色不合并或升级此head。

Reviewer: model_agent; model=gpt-6.1-sol; provider=OpenAI; declaration_source=runtime_reported; reasoning_effort=xhigh.
English verdict: REQUEST_CHANGES - The shared codec is well placed, but this exact patch silently chooses Python 3.14 parsing rules while Python 3.12 remains supported. Independent immutable-base/current-head suites and real isolated CLI persistence/readback show old valid shorthand rejected and a newly persisted 24:00 expiry ignored by the production scheduler reader. Resolve supported-version input semantics in the existing owner and add cross-version regression coverage before approval. No CI was consulted; other Python versions and packaged App behavior were not independently tested.

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-timestamp-parity-final branch from c814804 to 5e4f1fc Compare October 6, 2026 23:39
@mikamikasuki

Copy link
Copy Markdown
Contributor Author

Thanks for the concrete cross-version reproduction. I updated the existing timestamp codec and retained Python reader in commit 5e4f1fc, rebased onto main at da45cfe.

The stable grammar now preserves the fractional-hour/minute/offset forms accepted by supported Python readers and rejects local hour 24 before a Todo expiry can be persisted. I added coverage for both the typed Todo metadata planner and production Python reader.

The new cases reproduced six failures on the previous head with Python 3.12.15 and four with 3.14.7. On the updated head, test_monitor_state_owner.py passes 42/42 on Python 3.11.12, 3.12.15, and 3.14.7; monitor_metadata.test.ts passes 10/10; the control-plane TypeScript typecheck, Ruff, changed-file Python compilation, diff check, and standard premerge gate (17 selected, zero failures/manual holds) pass. The full repository pytest suite was not run.

I also updated the PR description with the reproduction, scope, base/head, and validation evidence. Please re-review this head when convenient.

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

REQUEST_CHANGES — exact head 5e4f1fc; immutable merge-base da45cfe.

动机

通过 CLI 设置监控过期时间,随后由调度器读取该时间的用户。 旧评审的简写时间和24点反例已修复;Python3.14上的零时区小数偏移仍让写入端认定的00:00:00.100变为读取端的前一天23:59:59.600。 真实todo update --expires-at成功并原样持久化2030-01-01T00.1+00.5,但Python3.14调度器读为2029-12-31T23:59:59.600000+00:00;Python3.12基线/当前及生产TS codec均给出2030-01-01T00:00:00.100000+00:00。 本次只要求现有时间戳写入/读取语义一致,不要求新能力、存储、界面或完成整个语言迁移。

改动思路

现有TS planner/codec继续拥有写入验证,Python runtime.time是必要的兼容读取adapter,在原模块规范化stdlib差异;不增加状态或权限owner,但两可达codec必须保持已接受wire语义。 当前边界为既有CLI时间戳及scheduler/chronology消费者的稳定兼容,不扩大到新解析框架或存储迁移。
最小变更继续使用现有owner。稳定UTC仍有缺口,先修复同一offset兼容边界;不用新增解析框架或放弃旧合法输入。

具体改动

当前全4路径+105/-6:Python reader新增日期/clock有界匹配、简写fraction补秒及local24拒绝;TS保留fraction/<=23旧wire语义;Python/TS monitor测试增加稳定grammar及year9999负例。扩至reader是必要修复,不要求引入新codec factory或只迎合3.14。共享reader的scheduler/chronology/quota/frontier可达调用已扫描。
Accepted spec: docs/architecture/rfcs/typescript-control-plane-migration-v0.md; spec_ref docs/architecture/rfcs/typescript-control-plane-migration-v0.md; spec_revision da45cfe.
Criteria: Caller-observable semantic parity is a promotion gate. 当前完整UTC/readback条件not_met,七旧例修复不替代全部当前wire承诺。
Python3.12.15两suite基线57/当前64通过;当前monitor suite在3.11.17/3.13.16/3.14.8各42通过,基线3.14同suite2失败/33通过。TS10、history chronology6、Ruff、TS typecheck、advisory后semantic、premerge17selected+5direct通过。冻结真实CLI旧7例:3.12 B/H7/7,3.14 B4不符/H7/7,全部恢复成功。
扩展冻结9输入真实CLI:3.12 B/H9/9;3.14基线6不符/当前仍2不符,其余7过、全部9个标准UTC恢复成功。16输入扩展codec:3.12 B/H全过,当前3.14有1不符。未测全部pytest、现场worker/App或其它provider;无存储事务重构,未声称PG资格。

对主干的风险

P2 blocker: runtime/time.py:52–56 preserves a zero h/m/s offset fraction after normalization. Python3.14.8 now subtracts that fraction; TS and Python3.11–3.13 ignore it. Both 2030-01-01T00.1+00.5 and 2030-01-01T00:00:00.1+00:00:00.5 are accepted and persisted by actual CLI. Production TS returns1893456000100000 (2030-01-01T00:00:00.100Z), while actual3.14 scheduler reads2029-12-31T23:59:59.600000+00:00. 原七例已独立通过,不沿用旧失败;新counterexample直接属于稳定grammar承诺。
当前阻塞属于本PR的稳定wire grammar和normalizer,不能归为无关债务。3.14stdlib不一致原已存在,当前确实修了旧例,但零偏移fraction未闭环;不声称stdlib行为由作者引入。
在现有Python reader保留TS/Python3.11–3.13的零hour/minute/second offset规则:忽略该零偏移的fraction,覆盖简写与完整秒形式,并在3.12/3.14重跑真实写入/持久化/scheduler读回;保留旧合法输入。
独立固定UTC预期不是从候选parser或输出生成。所有timestamp拒绝保持原state,全部实际标准UTC恢复成功。合成隔离后端未修改活动Goal、writer fence或其它角色状态。不查询、轮询或等待CI。

我的整体评价

REQUEST_CHANGES. 旧c814问题已修,保留这个新发现为当前阻塞;最小reader修复及跨版本真实读回通过后再审新head。
现有TS planner/codec继续拥有写入验证,Python runtime.time是必要的兼容读取adapter,在原模块规范化stdlib差异;不增加状态或权限owner,但两可达codec必须保持已接受wire语义。 当前边界为既有CLI时间戳及scheduler/chronology消费者的稳定兼容,不扩大到新解析框架或存储迁移。
Future-facing pass: 当前codec/renderer边界足够;没有增加parserfactory、新模式配置或引用框架的必要,zerooffset修复继续用既有reader。

Reviewer: model_agent; model=gpt-6.1-sol; provider=OpenAI; declaration_source=runtime_reported; reasoning_effort=xhigh.
English verdict: REQUEST_CHANGES - The earlier shorthand and 24:00 findings are fixed. However, a real CLI write, persistence and scheduler probe on Python 3.14 still shows a 500 ms disagreement for zero-offset fractions, while Python 3.12 and the production TypeScript codec retain the expected UTC instant. The 42 passing cross-version tests, 10 TypeScript tests and 17 selected premerge checks miss this case. Preserve the existing zero-offset rule in the retained reader and rerun actual Python 3.12 and 3.14 readback.

Signed-off-by: mika <211269698+mikamikasuki@users.noreply.github.com>
Signed-off-by: mika <211269698+mikamikasuki@users.noreply.github.com>
@mikamikasuki

Copy link
Copy Markdown
Contributor Author

Follow-up for the zero-offset review finding:

  • Root cause: CPython 3.14 applies a fractional component to an otherwise-zero timezone offset, while CPython 3.11–3.13 and the TypeScript codec treat it as UTC. The retained Python reader now normalizes zero-hour/minute/second offsets to UTC before delegating to datetime.fromisoformat, dropping only the fractional offset.
  • Reproduction: todo add --expires-at accepted and persisted both review examples. On the updated head, the production monitor_todo_expires_at reader returns 2030-01-01T00:00:00.100000+00:00 for each example on Python 3.12.15 and 3.14.7.
  • Regression coverage: both exact inputs are covered in the Python reader/metadata planner and TypeScript codec tests. test_monitor_state_owner.py: 47 passed on Python 3.11.12, 3.12.15, and 3.14.7; the TypeScript suite: 10 passed on Node.js 24.19.0; Ruff, Python compilation, git diff --check, and standard premerge (17 selected checks, zero failures or holds) passed.

The full repository pytest suite was not run. Please re-review the updated 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; model=gpt-6.1-sol; provider=OpenAI; declaration_source=runtime_reported; reasoning_effort=xhigh.
APPROVE — exact head 900530f; immutable baseline da45cfe.

动机

未运行全仓pytest、Windows、已安装App升级、实时worker、规模/长期实验或PostgreSQL。无PG事务/store refactor或新UI交互;本次资格是现有wire路径而非任意ISO语法的全量证明。
通过Todo CLI/API写入截止时间的使用者,及在Python3.11–3.14运行scheduler、chronology和quota读取器的维护者。 Python3.14改变缩写时间/offset fraction解析,原TS/旧Python含义发生漂移;旧head5e4仍把两种合法zero-offset fractional输入读早500毫秒。当前reader先固定简写fraction为秒,并把全零h/m/s offset canonicalize为UTC,保持TS/3.11–3.13含义,明确拒绝local24点。 冻结9例真实CLI/生产TS writer/原字符串持久化/独立生产scheduler:3.12 B/H全9正确;3.14 B六例不符、H全9正确。2030-01-01T00.1+00.5和fullseconds形式现在都读2030-01-01T00:00:00.100000+00:00,500ms偏差消失;全部标准UTC更正恢复成功,拒绝不改变state。
完整有界修复为已存在timestamp wire contract跨支持版本一致;没有新增可选能力、配置或前端操作。当前重审完整4文件与新负例,不把旧head批准或旧失败继承到新版本。

改动思路

Keep TS timestamp codec as metadata admission owner and existing Python runtime.time as compatibility read adapter for genuine scheduler/chronology consumers. Normalize before stdlib instead of adopting3.14 semantics inTS or introducing parallel policy/config. No persisted timestamp rewrite or new state owner.
最小方案使用既有owner及调用链,不新增重复控制面、解析框架或权限。todo add/metadata CLI → typed TS monitor metadata owner → parseTodoTimestampMicros → raw expires_at persistence → Python runtime.time.parse_timestamp → production scheduler.monitor_todo expiry; shared chronology_key/quota/frontier readers inspected.

具体改动

完整4文件+122/-6:Python runtime/time.py增加稳定ISO预规范化,补local24拒绝及全零offset fractionalUTC规则;TS runtime_timestamp.ts保留seconds-fraction语义并拒绝24小时local clock;Python monitor tests加入简写、offset fractions、负例和真实跨读取一致性,TS测试覆盖对应wire语法。四个DCO提交含当前zerooffset修复/读回回归。
预变更验收来源:docs/architecture/rfcs/typescript-control-plane-migration-v0.md;spec_ref docs/architecture/rfcs/typescript-control-plane-migration-v0.md;spec_revision da45cfe。逐项判据:caller_observable_parity: Caller-observable semantic parity is a promotion gate: inventory inputs/defaults/diagnostics/persistence and actual consumers.; same_harness_real_backend: Same immutableB/H bounded fixture and publicCLI/realbackend with independent expectedUTC.; regression_sensitivity: Historicaldefect fails declared invariant; fixedhead passes negatives/recovery without timestamp rewrite.,当前边界均implemented。
H69/B57项Python3.12 monitor+followthrough;H47项monitor分别Python3.11.17/3.13.16/3.14.8通过;TS10、chronology6、Ruff、TS typecheck、advisory后全树semantic、预合并17项+8风险smokes通过。冻结9例真实CLI B/H×3.12/3.14;另16项固定UTC/invalid codec oracle H3.12/H3.14/B3.12全过。
旧5e4的两条500ms意见重新映射至current normalize_component:45–49;不是只看新增测试或作者回复。两个输入分别为2030-01-01T00.1+00.5及2030-01-01T00:00:00.1+00:00:00.5,独立UTC预期为2030-01-01T00:00:00.100000+00:00。

对主干的风险

当前必要检查没有未解释失败。B3.14六项反例属于修复敏感性,未计为H成功;过去5e4的500ms失败记录保留,由相同独立脚本当前H读回消除。PR正文仍写5e4测试head,当前资格以本次900530f独立检查为准,可更新正文以免读者混淆。
未运行全仓pytest、Windows、已安装App升级、实时worker、规模/长期实验或PostgreSQL。无PG事务/store refactor或新UI交互;本次资格是现有wire路径而非任意ISO语法的全量证明。
同一固定预期不是从候选parser输出生成;实际TS负责写入,存储保持raw字符串,独立Python scheduler读取。非法calendar/local24拒绝保持state,9例实际标准UTC更正均恢复。未据直接codec单测替代真实持久化/调度读取。
不查询、轮询或等待CI;没有执行merge、安装升级或外部消息。

我的整体评价

APPROVE。旧500ms阻塞已在现有normalize_component边界修复;本轮不要求扩大parser框架。 完整有界修复为已存在timestamp wire contract跨支持版本一致;没有新增可选能力、配置或前端操作。当前重审完整4文件与新负例,不把旧head批准或旧失败继承到新版本。
Future-facing pass: Keep TS timestamp codec as metadata admission owner and existing Python runtime.time as compatibility read adapter for genuine scheduler/chronology consumers. Normalize before stdlib instead of adopting3.14 semantics inTS or introducing parallel policy/config. No persisted timestamp rewrite or new state owner. 当前改动已经复用现有边界,没有发现需要增加框架或另立状态owner的相关小重构;不加版本分支/config,零offset规范化已在同一codec内完成。
P2非阻塞建议:更新PR正文的testedhead5e4为当前900530f及最新验证,避免读者把旧作者数字当当前资格。当前独立证据已覆盖,因此该正文建议不挡批准。

English verdict: APPROVE - Exacthead 900530f. All9 fixed-oracle realCLI/persistence/scheduler cases nowagree onPython3.12 and3.14; bothzerooffsetfraction forms read00:00:00.100UTC rather than500msearly. Whole4-file review,47monitor cases on3.11/3.13/3.14,69on3.12,TS10/history6/static/semantic/premerge pass. Rawexpiry andauthority unchanged; previous5e4failure independently resolved.

@huangruiteng
huangruiteng merged commit e0f02d5 into loopx-project:main Oct 7, 2026
23 of 33 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