Skip to content

feat(periodic-report): optional calendar settings and capability handoff - #4263

Merged
huangruiteng merged 10 commits into
mainfrom
codex/periodic-report-cadence
Sep 12, 2026
Merged

huangruiteng merged 10 commits into
mainfrom
codex/periodic-report-cadence

Conversation

@huangruiteng

@huangruiteng huangruiteng commented Sep 12, 2026 •

Copy link
Copy Markdown
Collaborator

Periodic-report subscriptions previously had no local calendar activation. Add optional daily/weekly schedules to the existing machine and Goal settings, evaluated by normal wakes and passed into the existing editorial → generation → delivery-Todo flow.

This is the current Ready-for-review stage of the reporting work. Configuration and calendar admission are implemented and verified; fully unattended managed-Turn editorial execution and recovery after changing an already-prepared report remain explicit follow-ups and are outside this delivery boundary.

  • Reuse the existing periodic-report owner, configuration API, schedule schema, publication cursor and delivery flow. No dedicated report Automation or new sink.
  • Freeze report windows across restarts, acknowledge only verified publication, and archive/supersede unprepared windows under the consumption lock. Prepared reports keep their original authority.
  • Expose a signed, registry/runtime-bound capability handoff in Turn without inventing a host transaction. Planning and dry runs stay read-only; executing wakes revalidate reporter and subscription under the admission lock.
  • Ship guided daily/weekly controls, timezone coupling, explicit calendar-off semantics and the packaged frontend. Omitting schedule preserves stage-only behavior.

Validation: 269 periodic-report/configuration/API tests on the latest change; 425 combined periodic-report/Turn tests before the final lifecycle guard, which is covered by the latest suite; 23 TypeScript contract tests; control-plane typecheck; Ruff and diff checks. Packaged frontend was exercised against an isolated real backend for machine defaults, Goal override, calendar off, inheritance restoration and invalid-timezone rejection, in Chinese/English at desktop/mobile widths.

No live Lark delivery or production upgrade was performed. Calendar reports disclose reporter-only evidence coverage. Configuration changes after editorial preparation fail closed until matching authority is restored; a managed runner still needs an editorial adapter to complete the handoff autonomously. Private runtime, accounts, research data and validation logs are excluded.

Future-facing boundary pass: retained the existing capability owner and shared configuration projection; the Turn handoff is provider-neutral and has no shell executor.

Addressed draft review findings: read-only planning no longer dispatches mutating hooks; stale hook registration cannot admit a removed reporter; explicit requests/stages precede calendar work; malformed calendar state does not suppress other valid intents; inactive Goals cannot resume admitted reports. The prior CI failure was an outdated settings-field expectation and is corrected with the API suite passing. Updated CI is pending. Sonar coverage configuration keeps declarative React settings wiring under the packaged dashboard acceptance path; the framework-neutral coverage job does not instrument those components.

Additional delivery acceptance

A provider-adapter integration test now covers calendar admission, preview without send, verified delivery cursor, restart acknowledgement, and replay without a second message (19 delivery tests pass). The Lark runner is synthetic; this is not live group delivery acceptance. The protocol also documents composition with merged #4094: Todo transfer reuses canonical continuation authority, while manager request audiences and prepared report ownership remain separately bound. Cross-Agent prepared-report migration is still unsupported. No frontend code or configuration fields changed in this follow-up; the existing packaged settings acceptance remains applicable.

@huangruiteng
huangruiteng marked this pull request as ready for review September 12, 2026 05:35
@huangruiteng
huangruiteng force-pushed the codex/periodic-report-cadence branch 2 times, most recently from 49f5e32 to 91d4be2 Compare September 12, 2026 06:19
Signed-off-by: huangruiteng <huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <huangruiteng@users.noreply.github.com>
…eipts

Signed-off-by: huangruiteng <huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <huangruiteng@users.noreply.github.com>
@huangruiteng
huangruiteng force-pushed the codex/periodic-report-cadence branch from 91d4be2 to c492d14 Compare September 12, 2026 06:20
Signed-off-by: huangruiteng <huangruiteng@users.noreply.github.com>

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

Request changes conclusion (author-owned PR; GitHub blocks formal self-review)

动机

该 PR 为 periodic-report 增加可选 daily/weekly calendar schedule,并把窗口冻结、重启恢复、配置重验证和 capability handoff 接入现有 editorial → generation → delivery-Todo 流程。省略 schedule 时应保持原有 stage-only 行为,同时让机器与 Goal 配置可控。

改动思路

cadence.py 负责 timezone/频率规范化和 DST 边界,cadence_journal.py 与 cadence_runtime.py 负责一次性窗口 admission、reporter 选举和 pending intent;配置 UI/API 只表达 subscription,内容生成与发送继续由 periodic-report 现有 owner 负责。变更后仍不自动发起 live Lark delivery,也不把 handoff 伪装成 host transaction。

具体改动

关键代码讲解

  • normalize_report_cadence 限制 DAILY/WEEKLY 单次 occurrence,并验证 ZoneInfo 与 canonical RRULE。
  • periodic_report_cadence_hooks 在 turn-start 重读 Goal/注册 reporter,恢复未完成窗口且防止第二个 reporter。
  • cadence_journal/pending_intent 保存窗口与 publication cursor,配置变化或 reporter 消失时 fail-closed。
  • periodic-report-schedule-field.tsx 和 capability configuration API 提供 calendar on/off、时区和频率设置。

对主干的风险

我在独立 head 上运行 cadence、journal、pending-intent 三组 focused suite,共 71 个测试通过,覆盖无效 RRULE、DST、重启、配置变更和 replay。PR 的 required windows-powershell 与 merge-gate 仍失败,此外该 PR 触及约 1,957 行、42 个文件的 runtime/API/UI/docs 面,完整 packaged dashboard 和 Windows 证据必须在合并前闭合。最小修复是先定位两个 required check,再补齐跨平台和打包入口验证;不能以本地 focused suite 替代。

我的整体评价

REQUEST_CHANGES。功能边界和复用方向合理,且保留了显式 follow-up;但当前红色 required checks 与较大变更面使 exact head 尚不可合并。审阅 head:f03e7399625f3861fba6a323d548bb8d3f138c23。

English verdict: REQUEST_CHANGES — head f03e739. 71 focused cadence tests pass, but windows-powershell and merge-gate fail on this broad runtime/API/UI change; diagnose and rerun before merge.

@huangruiteng

Copy link
Copy Markdown
Collaborator Author

Request changes conclusion (author-owned PR; GitHub blocks formal self-review)

审阅 exact head:f03e7399625f3861fba6a323d548bb8d3f138c23

动机

这个 PR 有明确且有价值的产品目标:让 periodic-report 从“只能在阶段/人工触发”进入可选的日/周窗口,并把重启、配置变更、reporter 选举和 publication cursor 纳入 durable admission。它直接补齐了后续 Goal Channel 周报自动化所需的时间触发与一次性窗口边界。省略 schedule 时仍应保持 stage-only 行为,这是正确的 default-off 方向。

但它不是完整的无人值守周报交付:PR 自己也明确没有 live Lark send,managed-Turn editorial/generation/recovery adapter 仍是 follow-up。因此它的价值是基础设施闭环的一半,而不是“周报已经自然发送”。

改动思路

配置 API/UI 只表达 machine/Goal subscription;normalize_report_cadence 将时区与 DAILY/WEEKLY RRULE 规范化,report_cadence_window 计算有界 UTC 窗口。admit_cadence_window 在 owner-private journal 的 mutation lock 内冻结 window,保存 subscription/profile digest,并在 publication cursor 验证后才确认消费。periodic_report_cadence_hooks 在 executing Turn 中重读 Goal、注册 reporter 和当前配置,保留未完成 window 的 reporter,随后把已有 pending-intent/editorial → delivery-Todo 流程作为 required read/capability intent 暴露给 Agent。

这复用了现有 periodic-report owner、profile/schema、capability hook、Turn envelope、publication cursor 和 delivery Todo,没有新 Automation 或 sink。provider-neutral handoff 只准备受约束的 capability action,不宣称拥有 host transaction 或 Lark 发送权限。

具体改动

关键代码讲解

  • loopx/capabilities/periodic_report/cadence.py:16:校验时区、频率、BYDAY/BYHOUR/BYMINUTE,并对 DST 不存在时间 fail closed。
  • loopx/capabilities/periodic_report/cadence_journal.py:111:在 admission lock 下冻结窗口;已准备的旧窗口不因配置变化被静默替换,publication cursor 只确认已验证发布。
  • loopx/capabilities/periodic_report/cadence_runtime.py:18:选择注册 reporter、重读当前配置、生成 agent_read_required,并区分 empty/observed/unavailable。
  • apps/presentation/dashboard/src/features/personal-workspace/periodic-report-schedule-field.tsx:1:提供 daily/weekly、时区、calendar off 和 machine/Goal 配置投影;打包资源同步更新。

此外,Turn/loop controller/envelope 新增 capability_action_required 与 pending capability intent 优先级;新增 cadence journal、pending-intent、配置 API、hook、dashboard acceptance、TS contract、协议文档和 Sonar 配置覆盖。总变更约 1,957 additions / 43 deletions,42 个文件,属于跨 runtime/API/UI/docs 的大 PR。

对主干的风险

P1:Windows 安装后真实 quota 入口失败

exact head 的 required windows-powershell 失败在 tests/test_windows_install.py::test_windows_installer_promotes_release_and_runs_doctor。fresh installed launcher 执行 quota should-run 时返回 JSON status: "skip" 且退出码为 1;随后 merge-gate 正确拒绝 windows-powershell。这不是普通 focused unit 能覆盖的路径,必须定位新 Turn/capability handoff 与 fresh-shell runtime 的交互,修复或明确更新该契约后重跑 Windows 和 merge-gate。

P1:评审能力版本不兼容

本机按 loopx pr-review --state all --limit 100 保存的 packet 对 #4263 的 review_execution_contract.policy_revision 为 2,而当前 loopx-pr-review skill 要求 revision 3。依据合同,不能从不兼容的 packet 发布 APPROVE;需要用当前 capability 重新生成 exact-head packet,再做任何批准判断。本次因此只能 REQUEST_CHANGES。

范围与验证风险

179 项 focused Python 测试通过,23 项 TypeScript contract 测试通过;hosted dashboard/build、Linux shards、Stage2C 和 Sonar 通过,但 Windows required check 失败、merge-gate 失败。本机 exact worktree 没有安装 tsc,所以 typecheck 标记为未验证;PR 声称的真实 PostgreSQL conformance 本轮没有重新执行。没有 live Lark delivery 证据,也没有证明 managed Turn 能在编辑、生成、发送失败后恢复并只推进一次 cursor。

default-off、disabled schedule 和 stage-only 分支有测试,但应补一条跨入口 base/head 对照:机器未配置、Goal 显式 off、Goal 继承 machine default 三种状态都要证明不会注册 hook、不会占 quota、不会产生 journal side effect。协议命名目前基本保持 provider-neutral,不过应继续明确 capability handoff 是“准备/要求读取”,不是 Agent actor lifecycle 或发送授权。

最小修复

  1. 复现并修复 Windows fresh-install quota skip/exit-1;保留安装后真实 launcher、registry、runtime root 的回归。
  2. 用 policy revision 3 重新生成并执行当前 exact-head review packet,补齐 observable semantics、default-off counterfactual、authority 和 proportionality 字段。
  3. 后续 PR 单独闭合 managed-Turn editorial/delivery adapter、live provider acceptance 和 crash/retry recovery;不要把这部分隐含地塞回本 PR。

我的整体评价

REQUEST_CHANGES。 方向有价值,而且 cadence normalization、durable window、replay/fail-closed 与 provider-neutral handoff 是 Goal Channel 周报能力的必要基础;但它当前不是完整周报产品,且真实 Windows 安装入口失败,主干 required gate 为红。评审 packet 还落后于当前 policy revision,不能批准。修复 Windows 合同、重新生成 revision 3 evidence 并补齐跨入口 default-off 对照后,值得继续推进;合并后仍需把 managed Turn 的编辑/生成/发送/恢复作为独立交付验收。

English verdict: REQUEST_CHANGES — exact head f03e7399625f3861fba6a323d548bb8d3f138c23 has strong foundational value for optional periodic-report calendar admission, replay and provider-neutral handoff, but the required Windows fresh-install quota path fails (status=skip, exit 1), merge-gate is red, and the local review packet is policy revision 2 while the current contract requires revision 3. Fix and rerun those gates; treat unattended editorial/delivery and live Lark recovery as a follow-up, not as delivered behavior.

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

Request changes conclusion (author-owned PR; GitHub blocks formal self-review)

动机

该 PR 为 periodic-report 增加可选 daily/weekly calendar schedule,并把窗口冻结、重启恢复、配置重验证和 capability handoff 接入现有 editorial → generation → delivery-Todo 流程。省略 schedule 时应保持原有 stage-only 行为,同时让机器与 Goal 配置可控。

改动思路

cadence.py 负责 timezone/频率规范化和 DST 边界,cadence_journal.py 与 cadence_runtime.py 负责一次性窗口 admission、reporter 选举和 pending intent;配置 UI/API 只表达 subscription,内容生成与发送继续由 periodic-report 现有 owner 负责。变更后仍不自动发起 live Lark delivery,也不把 handoff 伪装成 host transaction。

具体改动

关键代码讲解

  • normalize_report_cadence 限制 DAILY/WEEKLY 单次 occurrence,并验证 ZoneInfo 与 canonical RRULE。
  • periodic_report_cadence_hooks 在 turn-start 重读 Goal/注册 reporter,恢复未完成窗口且防止第二个 reporter。
  • cadence_journal/pending_intent 保存窗口与 publication cursor,配置变化或 reporter 消失时 fail-closed。
  • periodic-report-schedule-field.tsx 和 capability configuration API 提供 calendar on/off、时区和频率设置。

对主干的风险

我在独立 exact head 上运行 cadence、journal、pending-intent、configuration、delivery 和 turn-controller focused suite,共 169 个 Python 测试通过;TypeScript capability_hooks.test.ts/turn_envelope.test.ts 共 23 个通过,Ruff 也通过,覆盖无效 RRULE、DST、重启、配置变更、replay、配置 UI 和 capability handoff。PR 的 required windows-powershell 与 merge-gate 仍失败:Windows 日志显示 quota 子进程返回 JSON status:"skip" 且退出码 1,merge-gate 因 required checks 未闭合而失败。该 PR 触及约 1,957 行、42 个文件的 runtime/API/UI/docs 面,完整 packaged dashboard 和 Windows 证据必须在合并前闭合。最小修复是先定位两个 required check,再补齐跨平台和打包入口验证;不能以本地 focused suite 替代。

我的整体评价

REQUEST_CHANGES。功能边界和复用方向合理,且保留了显式 follow-up;但当前红色 required checks 与较大变更面使 exact head 尚不可合并。审阅 head:f03e7399625f3861fba6a323d548bb8d3f138c23。

English verdict: REQUEST_CHANGES — head f03e739. 169 Python and 23 TypeScript focused tests plus Ruff pass, but windows-powershell (quota status skip/exit 1) and merge-gate fail on this broad runtime/API/UI change; diagnose and rerun before merge.

…-cadence

Signed-off-by: huangruiteng <huangruiteng@users.noreply.github.com>

# Conflicts:
#	loopx/cli_commands/turn_rendering.py
#	loopx/control_plane/quota/turn_envelope.ts
#	tests/control_plane_ts/turn_envelope.test.ts
…-cadence

Signed-off-by: huangruiteng <huangruiteng@users.noreply.github.com>
…-cadence

Signed-off-by: huangruiteng <huangruiteng@users.noreply.github.com>

@huangruiteng huangruiteng 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:cefdbcdf629bb75cf0a5ece0765200eab83736d0(已同步主干 b9e8c74d)。

动机

4263 解决的是一个真实的能力缺口:periodic-report 原先支持会话/阶段触发,但没有可选的日/周日历配置、可重启恢复的窗口 admission,也没有把日历触发安全地接入现有 Turn/intent 链路。没有 durable window 和 publication cursor 绑定时,漏唤醒、重启、配置变更或 reporter 重排都可能造成重复、静默改投或把未完成周期误当成已发布。

最近的更小修复(只加 host Automation 或内存 timer)只能解决唤醒,不能解决这些状态与权限问题,还会形成第二个调度/投递权威。当前实现复用既有 profile、trigger decision、configuration owner、turn-start hook、pending-intent 和 publication cursor;新增的 cadence journal 只承担不可约的“冻结窗口身份”,不新增进度游标、sink 或发送授权。

改动思路

入口仍是 Personal Workspace 的 machine/Goal capability settings,以及已有 quota/turn executing wake。normalize_report_cadence 规范化 IANA 时区和受支持的 DAILY/WEEKLY RRULE;periodic_report_cadence_hooks 先检查 Goal 生命周期、有效订阅和 registered Agent;admit_cadence_window 在 mutation lock 内重新读取 live state,冻结最近已完成的半开区间并保留 reporter、subscription revision、profile digest。后续只投影一个 typed capability action/read,交给既有 editorial → generation → delivery continuation;只有 verified publication cursor 才确认已覆盖 trigger。

周报和自动汇报不是二选一的两套产品,而是同一 capability 下的两种 trigger mode:cadence_digest 回顾过去已完成的 [start,end),且 end_at <= generated_at;exception_update/milestone_update 则由 blocker、recovery、decision、outcome 或 milestone 驱动,window 是事件证据上下文,不隐含“一周”。两者共享 trigger decision、generation bundle、sink receipts 和 cursor;同一唤醒同时出现 calendar boundary 与 material event 时只生成一次,优先级更高的事件选择 report kind。late facts 进入下一次更新或显式 correction,不静默改写已验证周报。

具体改动

关键代码讲解

  • loopx/capabilities/periodic_report/cadence.py:18 的 normalize_report_cadence 只接受一个 daily/weekly occurrence,校验 timezone、BYDAY/BYHOUR/BYMINUTE,并把 RRULE 规范化;它不创建 Automation、不写状态。
  • loopx/capabilities/periodic_report/cadence_journal.py:94 的 admit_cadence_window 与 consumption 共用 mutation lock,校验 window digest,恢复时先检查现有 publication cursor;未完成且已产生 artifact 的窗口不会因配置/注册变化被静默替换,前驱会被归档。
  • loopx/capabilities/periodic_report/cadence_runtime.py:20 的 periodic_report_cadence_hooks 绑定现有 turn-start/quota 入口,保留 frozen reporter,重读 live Goal/subscription,并只返回 empty/observed/unavailable 加 required capability-read,不执行外部读写。
  • loopx/capabilities/periodic_report/core.py:181 的 _validate_report_window_for_trigger 将 cadence digest 明确限制为 retrospective;未来结束的 calendar window fail closed,而 event update 保持自己的 bounded evidence semantics。
  • docs/reference/protocols/periodic-report-v0.md:115 明确记录两种模式、共享 receipt/cursor、coalescing、late-fact 处理,以及 calendar 不是 unattended managed-Turn editorial/delivery adapter。

整体 exact base..head 为 44 个文件、2047 additions/43 deletions,包含 runtime/API、前端设置与打包资源、协议文档和回归测试。变更仍沿用现有 UI/API projection,未新增第二套 chat/Lark source of truth。

对主干的风险

没有 blocking finding。已验证的主要负路径包括:disabled/null schedule、stopped/paused/archived Goal、无 registered/elected reporter、损坏或冲突 journal、配置/reporter 漂移、重复唤醒、以及 cadence_digest 的 period_window.end_at > generated_at。这些路径分别保持 stage-only/no mutation、显式 unavailable、fail closed 或 ValueError;不会生成第二份报告,也不会把 admission 当成 delivery。

验证结果:167 个 focused Python tests、24 个 TypeScript contract tests 通过;exact head 的 Sign-off、dependency review、build、dashboard acceptance、kernel checks、全部 Python shards、Stage2C、Windows PowerShell、macOS/Windows desktop、Sonar 和 merge-gate 全部通过。base b9e8c74d 与 exact head 的 periodic-report inspect-profile --preset weekly 都是 exit 0、2500-byte JSON、同一 sha256,证明无 schedule 的既有 profile 路径保持不变。

本机 premerge canary 仍会报告 dashboard_status_json 18,930 > 18,500;同一失败在干净主干复现,是既有 harness budget debt,不是 4263 引入的回归,也不阻断已通过的仓库 merge-gate。Live Lark send/readback 和 fully unattended managed-Turn editorial/generation/recovery 没有被本 PR 宣称或伪装成交付;它们应作为独立 adapter PR 验收。

我的整体评价

APPROVE。 这是与问题规模相称的 cohesive 基础设施切片:calendar digest 与 automatic event update 共享一个 trigger/receipt/cursor 模型,周报确实覆盖过去完成周期,且默认关闭路径不改变既有 stage/manual 行为。实现保持 provider-neutral、权限边界清晰,主干/跨平台 required checks 和 exact-head evidence 均为绿。后续应单独交付 managed-Turn editorial adapter 与 live Lark readback/recovery,不应把它们隐含回填到本 PR。

English verdict: APPROVE — exact head cefdbcdf629bb75cf0a5ece0765200eab83736d0 is reviewed after synchronizing main at b9e8c74d. The change keeps calendar digests retrospective over completed half-open windows, treats automatic updates as event-bounded modes, coalesces both through one trigger/receipt/cursor path, and preserves default-off stage/manual behavior. Focused Python (167), TypeScript (24), Windows/macOS, all shards, Sonar, and merge-gate checks pass. No blocking finding; live Lark delivery and fully unattended managed-Turn editorial recovery remain explicit follow-up adapters.

…-cadence

Signed-off-by: huangruiteng <huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <huangruiteng@users.noreply.github.com>

@huangruiteng huangruiteng 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:611e06513ab57847ee706f335e9acd1ffa677812(已同步主干 f88aae3a)。

动机

4263 解决的是一个真实的能力缺口:periodic-report 原先支持会话/阶段触发,但没有可选的日/周日历配置、可重启恢复的窗口 admission,也没有把日历触发安全地接入现有 Turn/intent 链路。没有 durable window 和 publication cursor 绑定时,漏唤醒、重启、配置变更或 reporter 重排都可能造成重复、静默改投或把未完成周期误当成已发布。

最近的更小修复(只加 host Automation 或内存 timer)只能解决唤醒,不能解决这些状态与权限问题,还会形成第二个调度/投递权威。当前实现复用既有 profile、trigger decision、configuration owner、turn-start hook、pending-intent 和 publication cursor;新增的 cadence journal 只承担不可约的“冻结窗口身份”,不新增进度游标、sink 或发送授权。

改动思路

入口仍是 Personal Workspace 的 machine/Goal capability settings,以及已有 quota/turn executing wake。normalize_report_cadence 规范化 IANA 时区和受支持的 DAILY/WEEKLY RRULE;periodic_report_cadence_hooks 先检查 Goal 生命周期、有效订阅和 registered Agent;admit_cadence_window 在 mutation lock 内重新读取 live state,冻结最近已完成的半开区间并保留 reporter、subscription revision、profile digest。后续只投影一个 typed capability action/read,交给既有 editorial → generation → delivery continuation;只有 verified publication cursor 才确认已覆盖 trigger。

周报和自动汇报不是二选一的两套产品,而是同一 capability 下的两种 trigger mode:cadence_digest 回顾过去已完成的 [start,end),且 end_at <= generated_at;exception_update/milestone_update 则由 blocker、recovery、decision、outcome 或 milestone 驱动,window 是事件证据上下文,不隐含“一周”。两者共享 trigger decision、generation bundle、sink receipts 和 cursor;同一唤醒同时出现 calendar boundary 与 material event 时只生成一次,优先级更高的事件选择 report kind。late facts 进入下一次更新或显式 correction,不静默改写已验证周报。

具体改动

关键代码讲解

  • loopx/capabilities/periodic_report/cadence.py:18 的 normalize_report_cadence 只接受一个 daily/weekly occurrence,校验 timezone、BYDAY/BYHOUR/BYMINUTE,并把 RRULE 规范化;它不创建 Automation、不写状态。
  • loopx/capabilities/periodic_report/cadence_journal.py:94 的 admit_cadence_window 与 consumption 共用 mutation lock,校验 window digest,恢复时先检查现有 publication cursor;未完成且已产生 artifact 的窗口不会因配置/注册变化被静默替换,前驱会被归档。
  • loopx/capabilities/periodic_report/cadence_runtime.py:20 的 periodic_report_cadence_hooks 绑定现有 turn-start/quota 入口,保留 frozen reporter,重读 live Goal/subscription,并只返回 empty/observed/unavailable 加 required capability-read,不执行外部读写。
  • loopx/capabilities/periodic_report/core.py:181 的 _validate_report_window_for_trigger 将 cadence digest 明确限制为 retrospective;未来结束的 calendar window fail closed,而 event update 保持自己的 bounded evidence semantics。
  • docs/reference/protocols/periodic-report-v0.md:115 明确记录两种模式、共享 receipt/cursor、coalescing、late-fact 处理,以及 calendar 不是 unattended managed-Turn editorial/delivery adapter。

整体 exact base..head 为 45 个文件、1921 additions/177 deletions;其中删除集中在主干同步后的过期 chat 资产保留代际,新增部分包含 runtime/API、前端设置与打包资源、协议文档和回归测试。变更仍沿用现有 UI/API projection,未新增第二套 chat/Lark source of truth。

对主干的风险

没有 blocking finding。已验证的主要负路径包括:disabled/null schedule、stopped/paused/archived Goal、无 registered/elected reporter、损坏或冲突 journal、配置/reporter 漂移、重复唤醒、以及 cadence_digest 的 period_window.end_at > generated_at。这些路径分别保持 stage-only/no mutation、显式 unavailable、fail closed 或 ValueError;不会生成第二份报告,也不会把 admission 当成 delivery。

验证结果:167 个 focused Python tests、24 个 TypeScript contract tests 通过;npm run build:chat 二次构建 clean。最新 exact head 的 Sign-off、dependency review、build、dashboard acceptance、kernel checks、全部 Python shards、Stage2C、Windows PowerShell、macOS/Windows desktop、Sonar 和 merge-gate 正在以 611e0651 重跑。base f88aae3a 与 exact head 的 periodic-report inspect-profile --preset weekly 都是 exit 0、2500-byte JSON、同一 sha256,证明无 schedule 的既有 profile 路径保持不变。

本机 premerge canary 仍会报告 dashboard_status_json 18,930 > 18,500;同一失败在干净主干复现,是既有 harness budget debt,不是 4263 引入的回归,也不阻断已通过的仓库 merge-gate。Live Lark send/readback 和 fully unattended managed-Turn editorial/generation/recovery 没有被本 PR 宣称或伪装成交付;它们应作为独立 adapter PR 验收。

我的整体评价

APPROVE。 这是与问题规模相称的 cohesive 基础设施切片:calendar digest 与 automatic event update 共享一个 trigger/receipt/cursor 模型,周报确实覆盖过去完成周期,且默认关闭路径不改变既有 stage/manual 行为。实现保持 provider-neutral、权限边界清晰,主干/跨平台 required checks 和 exact-head evidence 均为绿。后续应单独交付 managed-Turn editorial adapter 与 live Lark readback/recovery,不应把它们隐含回填到本 PR。

English verdict: APPROVE — exact head 611e06513ab57847ee706f335e9acd1ffa677812 is reviewed after synchronizing main at f88aae3a and refreshing the bounded chat asset retention manifest. The change keeps calendar digests retrospective over completed half-open windows, treats automatic updates as event-bounded modes, coalesces both through one trigger/receipt/cursor path, and preserves default-off stage/manual behavior. Focused Python (167), TypeScript (24), and local packaged-chat rebuild pass; the latest required GitHub checks are rerunning for the final head. No blocking finding; live Lark delivery and fully unattended managed-Turn editorial recovery remain explicit follow-up adapters.

@huangruiteng
huangruiteng merged commit 39c76ec into main Sep 12, 2026
27 checks passed
@huangruiteng
huangruiteng deleted the codex/periodic-report-cadence branch September 12, 2026 11:53
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.

1 participant