Repository navigation
feat(quota): seal should-run projection envelope - #6679
Conversation
Signed-off-by: duang777 <duangjl007@gmail.com>
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent; model=gpt-6.1-sol; provider=OpenAI; runtime_reported; reasoning_effort=max
完整评审 6679@0a1cbfde9b977df2b17a8d0dc5693ab0a51f9de5,实际合并基线 da7d0b9979d2e7a2651cdc95230de70549278bfb。结论 REQUEST_CHANGES:有一个已通过真实读取路径复现的 P2。
动机
运行 quota should-run、需要判断当前结果是否可信的自动化 Agent 与本地操作者。
此前 quota 的决定没有自己的来源与覆盖说明,调用者无法直接区分当前、陈旧或不完整的读数;本次增加统一说明,目的是让调用者先看来源告警再决定下一步。
正常来源、状态继承、覆盖与渲染已有可执行覆盖;但独立真实 CLI 和 wheel 均证明损坏的调度状态仍被标成 fresh,整体 alert 为 false,因此核心可信读数尚未成立。
不改变算力准入、任务排序、调度策略或写权限,不完成 review-packet / Decision Context 的后续接入,不证明实际宿主安装、模型采用或持续运行收益。
quota 来源读数需要修复下面的 P2;review-packet 与 Decision Context 仍按既有 RFC 顺序推进,不能将本次接入称为完整迁移。
改动思路
沿用现有 Python quota 投影及唯一 TypeScript envelope owner 是合适的有界接入;来源 IO 的真实结果必须由现有读取 owner 返回,不能在 Python 根据参数存在重新推断成功。
当前 PR 只交付 quota 的真实来源、继承、覆盖及告警;要求修复真实调度读取事实并补负例,不要求先迁移整个 quota 或完成后续投影。
生产入口仍是 quota should-run,先取得 status,再按原有 quota / interaction / scheduler owner 生成决定,最后把直接读取事实与 status 的所有上游来源交给 projection.envelope.seal。Python 不判断陈旧阈值、覆盖完整性和告警组合,既有 TypeScript owner 决定这些语义;Markdown 复用统一告警渲染器。没有新持久化状态、开关或设置动作,也不需要用户重复授权来读取原有响应。这里是既有读模型的元数据接入,前端配置器没有新增可操作能力;没有把 CLI 配置描述当成新 UI 交付。
最强的反对理由是每次 quota 都增加载荷和维护成本,却可能仍然隐藏坏来源。因此关键验收是“真实失败能否被看见”,不能只看 schema、测试数或 seal 的输出形状。当前框架选择可以保留,缺口在读取事实的生产者;采用另一次 Python 文件探测或第二套 freshness 规则会进一步复制知识。
| 同一读取状态 | 基线 | 当前头与 wheel |
|---|---|---|
| 两个调度键都不存在 | 原决定,未声明 quota 自身新鲜度 | 允许作为健康空读,符合声明 |
| 两个调度键都是损坏 JSON | 原决定,无 quota envelope | 仍声称 fresh,整体无告警,违反来源契约 |
| 两个调度路径是目录 | 原决定,无 quota envelope | IO 读取失败仍声称 fresh,无告警 |
| 清除隔离坏数据后重新读取 | 原决定 | 恢复健康空读,原有决定与指令保持 |
此表来自实际 CLI、真实 TypeScript 文件读取与正常 wheel,不是流程示意或模型采用证明。
具体改动
独立规范在读 diff 前固定为 docs/reference/contracts/projection-envelope-contract.md,spec_revision: da7d0b9979d2e7a2651cdc95230de70549278bfb;同时对照相同基线的 docs/architecture/rfcs/typescript-control-plane-migration-v0.md §2.6。规范的当前 rollout 编辑不能反过来充当自己实现的验收依据。
2.6 Projection envelope is a kernel read contract:implemented。quota 增加自己的 envelope,继承上游来源,保持 TypeScript 唯一判断 owner;paused、health、unknown 等返回也接入。Field semantics:not_met。不可读来源必须告警,但新 scheduler 来源仅据参数存在推断成功,真实错误没有进入来源事实。Consumer rule:not_met。渲染顺序本身正确,但调度来源出错时 envelope 告警为 false,调用者没有告警可披露,不能据此声称当前来源健康。Cache and replay:implemented。复用原 TS seal 与上游 envelope,保留旧 observation、重算 freshness;缓存与陈旧来源测试通过。后续 review-packet / Decision Context 接入仍保留在既有 RFC 边界。
关键代码讲解
_attach_quota_should_run_envelope:Assemble source facts and requested Goal coverage; call existing TS seal exactly once. No own envelope -> inherited status and direct source envelope。_record_app_scheduler_state_source:Records App scheduler source after real payload assembly. Infers read from parameters; currently falsefresh on actual read failure。_projection_envelope_migration:Qualify one-time none -> v0 migration for canonical status/quota surfaces including variants. Status-only row prefix -> canonical surface id includes quota。render_quota_should_run_markdown:Print envelope notice before quota decision. No quota notice -> common renderer。
其他差异也完整检查:双语 RFC 仅更新 quota rollout 及剩余入口;projection 文档描述实际来源;测试覆盖上游继承、未知 Goal、缺失 envelope、paused/health、cadence 失败、缓存与渲染,以及一次性输出迁移的反例。源码共 10 文件、+665/-59,主要增量是本地来源适配和 360 行聚焦测试,没有引入新框架或第二决策权威。
预算增加有同负载证据,不能因为旧上限而删去消费者需要的来源说明。独立 hot-path 对照是 quota JSON 15,419→18,636 字符、378→513 个嵌套键、52→53 个顶层键,新上限 20,500 / 525 / 54;原 heartbeat/status 形状没有改变。共享 differential 只为 canonical status / quota_should_run 的 none→v0 提供一次性余量,包括对应模式;同 v0 继续增长、其他 surface、逆向或未知版本不获豁免。实际完整 base/head 96/96 行通过,18 条 quota 迁移提示保留给审查者,没有新增行被隐藏。
对主干的风险
[P2] 调度状态读失败不能被标成 fresh
位置:loopx/control_plane/quota/should_run.py:208-212。有效 App context、runtime 和 Agent 并不能证明来源被成功读取。真实 _build_quota_should_run_payload 调用 scheduler loader;既有 state_store.ts::loadSchedulerState 将非 ENOENT / JSON 解析错误吞成 null,随后新 helper 仅检查两个参数是否非空,写入 read_status=read 和当前时间。seal 忠实处理这些错误的输入事实,于是输出 status=fresh、unreadable_count=0、alert=false。
我在一次性 runtime 中,通过 scheduler_state_path 找到当前键与 Codex 兼容键,分别放入损坏 JSON 和目录;独立物理读取分别得到 JSONDecodeError / IsADirectoryError。真实 API、生产 quota should-run --goal-id goal-a --agent-id reader-a --runtime-profile codex_app_heartbeat 和正常构建安装的 wheel 都复现上述错误健康标签,CLI 均退出 0。API 的 eligible 决定仍为 run;CLI 的已有 operator-gate 指令也保持原样。这里新增的错误是“失败来源被认证为新鲜”,没有声称这个 PR 新增了原有空状态 fallback 或授权绕过。
从实际 scheduler.state.load / load_app_automation_scheduler_state 读取边界带回成功、缺失与不可读事实,保留合法缺失为空的语义;将解析或 IO 失败映射为 unreadable 并由既有 TS seal 产生告警,不要仅由 runtime_root 与 agent_id 是否存在生成 read/fresh。
在隔离 runtime 内分别令当前与 Codex 兼容键的 scheduler_state_path 为不存在、有效状态、损坏 JSON、目录或读取失败;通过 quota should-run 的生产 CLI / 正常 wheel 验证损坏会告警、合法缺失不误报、修复后恢复,并重跑原 178 项测试与 CLI differential。
语义与 CI 对齐
本次复用既有 loopx_projection_envelope_v0 与 read/missing/unreadable/not_read 词汇,source id 是局部事实名;没有新共享生命周期或授权语义。开发期语义 advisory 没发现支持语法内的新载体,完整 semantic-vocabulary check 也通过,但这不能证明来源事实正确,当前 P2 直接违反既有 Field semantics / Consumer rule。回归应覆盖真实 TypeScript 读取错误,而不只用已归一化的正向 mock 替代读取结果。
独立验证:相关 pytest 基线 163、当前 178 项通过;native standard premerge 为 5 个直接检查及 19 个选择检查,failed=0、skip=0、manual hold=0,含真实 CLI 输出、quota 路由、scheduler、维护性与全部 10 文件 public-boundary 扫描。TS typecheck、mypy 17 文件、选定路径 Ruff、完整语义与 DCO/diff 均通过。初次 wheel 因复用工作区的旧 Chat 构建产物被正常校验拒绝,随后运行正常 build:chat 并重建 wheel,独立 site-packages 路径再次复现 P2;没有放松构建校验。未查询或等待远程 CI。
我的整体评价
整体方案与已接受的下一步一致,保留现有 TS owner、局部 Python facts adapter 和有证据的一次性预算调整是合理的。未来适配退出仍归原投影迁移;当前有界整理应把实际读事实从现有 IO owner 传回来,避免参数推断或重复探测,不要求无关的全量 TypeScript 重写。
long_horizon: preserved:四个真实对照场景中,除明确新增的 envelope、隔离路径拼写及生成时间,旧决定、完整指令和解压后的宿主 follow-up 事实逐字段相同;96 个 CLI 场景与原生路由验证没有发现调度或续行变化。这不证明长期收益。user_experience: regression:原先未知的新鲜度现在在坏来源上被错误标为健康,正是本次能力要消除的风险,因此当前头不能批准。
结论是 REQUEST_CHANGES,限于上述已复现的来源真实性缺口。修复后用同一真实 CLI / wheel 的缺失、坏数据与恢复对照重审新头;不以绿测试替代该观察,也不把这条评审视为合并、安装、宿主采用或后续迁移完成的资格。
English verdict: REQUEST_CHANGES - 0a1cbfd: actual corrupt/unreadable scheduler state is labeled fresh with no envelope alert; reproduced through the real source CLI and installed wheel despite 178 passing targeted tests, 96-row differential and 19 green native canaries. Preserve actual read outcomes at the existing IO boundary and test missing/error/recovery.
| if isinstance(identity, Mapping) | ||
| else "" | ||
| ) | ||
| read = bool(status_payload.get("runtime_root") and agent_id) |
There was a problem hiding this comment.
[P2] 调度状态读失败不能被标成 fresh。从实际 scheduler.state.load / load_app_automation_scheduler_state 读取边界带回成功、缺失与不可读事实,保留合法缺失为空的语义;将解析或 IO 失败映射为 unreadable 并由既有 TS seal 产生告警,不要仅由 runtime_root 与 agent_id 是否存在生成 read/fresh。 独立观察:真实 API、生产 CLI 与正常安装 wheel 均输出 app_scheduler_state.read_status=read、status=fresh、unreadable_count=0、envelope.alert=false;读取失败被误当成健康空状态,调用者看不到应该先披露的告警。 验证要求:在隔离 runtime 内分别令当前与 Codex 兼容键的 scheduler_state_path 为不存在、有效状态、损坏 JSON、目录或读取失败;通过 quota should-run 的生产 CLI / 正常 wheel 验证损坏会告警、合法缺失不误报、修复后恢复,并重跑原 178 项测试与 CLI differential。
There was a problem hiding this comment.
Fixed in a74b460d9, with regression coverage in 7f6c8c724 and 9ef61099a.
The TypeScript scheduler state store now reports the actual read result. Missing state is a successful empty read. Malformed JSON, directory reads, invalid state, and other I/O failures report unreadable. Python observes both the canonical and Codex compatibility-key reads; it no longer infers success from runtime_root and agent_id.
Validation on Node 22.22.3 / SQLite 3.51.3:
- scheduler state store: 16/16 passed, including malformed canonical and legacy JSON plus a directory path
- scheduler/projection Python suites: 59 passed
- quota and CLI differential suites: 171 passed
- exact-head premerge: 19/19 selected checks passed
- built and installed wheel: packaged CLI returned fresh for missing state, unreadable with alert for corrupt state, then fresh after recovery
- production CLI regression also covers directory-path I/O failure and recovery
Please re-review 6679@9ef61099af9ee83772020afb052e4d180feff6c3.
|
This pull request has merge conflicts with Choose the remote for the base repository, not an out-of-date fork. 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 HEADFor a same-repository clone whose Keep the DCO |
Signed-off-by: duang777 <duangjl007@gmail.com> # Conflicts: # docs/architecture/rfcs/typescript-control-plane-migration-v0.zh-CN.md
Signed-off-by: duang777 <duangjl007@gmail.com>
Signed-off-by: duang777 <duangjl007@gmail.com>
Signed-off-by: duang777 <duangjl007@gmail.com>
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent; model=gpt-6.1-sol; provider=OpenAI; runtime_reported; reasoning_effort=max
完整评审 6679@9ef61099af9ee83772020afb052e4d180feff6c3,实际 base fdf03ec。APPROVE:当前完整净提案未发现新的可操作阻断;此前调度文件读失败被标成 fresh 的 P2 已在真实 source 和正常安装 wheel 的公开 CLI 中验证修复。
动机
读取 quota should-run 的维护者、自动化 Agent 与终端消费者。
调度文件损坏或被目录占用时,以前无法从 quota 投影识别未读到状态;现在 JSON 和 Markdown 在结论前保留 unreadable 告警,文件恢复后正常消退。
同一真实 API/公开 CLI 的缺失、坏 JSON、目录冲突、恢复四例已在 source 和隔离 wheel 执行;坏状态均 unreadable_count=2 且告警,原 run/should_run 不变。
不认证调度执行权限、已安装共享 CLI、完整前端采用、review-packet/DecisionContext 迁移或长期效用;不合并或升级。
本次交付 quota 只读投影;其余既有 typed migration/frontend adoption 与长期运行资格继续原 RFC,不以本次局部通过关单。
改动思路
复用既有 TypeScript seal 与调度读取 owner,Python 仅传真实事实,Markdown 复用同一警示渲染;不增加第二决策源或配置。
本 PR 完成 quota 的只读来源投影和真实 IO 错误回读;其余 review-packet/DecisionContext、完整前端采用和长期资格按原 RFC 推进。
旧问题不能通过在 Python 中把 None 统一当“成功读取零项”解决:真实文件不存在、坏 JSON、schema 无效和目录冲突都可能得到同一个空结果。当前把 read_status 放在实际读取的 TS owner,在现有 adapter 中作为瞬态事实传回;聚合 freshness/coverage 仍只有既有 typed seal。这个边界既能解释错误,也保留原有 quota 决定、动作与权限。
| 真实调度来源 | 当前 source 与 wheel 的 envelope | 原有决定 |
|---|---|---|
| 当前和 legacy 文件都不存在 | read、fresh、item_count=0、无告警 | run=true |
| 两个文件都是坏 JSON | unreadable_count=2、告警 | run=true |
| 两个路径都是目录 | unreadable_count=2、告警 | run=true |
| 修复为合法空缺状态 | 恢复 read/fresh、无告警 | run=true |
表格是本头真实 API 与公开 CLI 的执行结果,不是仅根据 diff 绘制的流程图;告警描述依据可靠性,不给出额外的执行许可。没有要求用户新增设置、标注事实或再进行一轮确认。
具体改动
当前完整净提案是14文件、+897/-78,已在7f旧头被更新后重新固定并通读9ef头。主生产改动是 should_run 的来源适配和 envelope、should_run_packet 的 observer 转发、scheduler Python/TS 读结果,以及原 Markdown renderer。其余是集中回归、接口预算和双语 RFC 阶段记录,不把整合历史当本次新增机制。
关键代码讲解
loopx/control_plane/quota/should_run.py:142 _attach_quota_should_run_envelope:在正常、暂停、未知及 health 等返回分支附加同一只读 envelope。上游 status 的来源与时间进入原 seal,不用新 observed_at 把上游旧数据洗成新鲜;没运行的读取保留 not_read,不把它当确定不存在。loopx/control_plane/quota/should_run.py:189 _app_scheduler_state_read_observer:接收真正发生的 current/legacy 两次读结果并累积 unreadable_count。即使 fallback 得到空值,前面的失败仍保留。workspace、cadence 和 inbox 也由实际调用产生事实,不建立手工同步状态。loopx/control_plane/scheduler/state_store.ts:619 loadSchedulerState:正常缺文件保留 read/空状态,解码或 IO 问题返回 unreadable。内部 legacy 读取把 state 与 readStatus 一起返回,但导出的migrateLegacySchedulerStateUnderLock仍向现有 heartbeat_commit 消费者返回原 state,锁与持久 JSON 不变。Python adapter 要求明确 read_status,避免再次从空值猜测。loopx/presentation/renderers/quota_markdown.py:350 render_quota_should_run_markdown:复用原共享警示,在原决定前呈现来源问题;没有另写一套 freshness 文案或把告警变成新的 admission gate。源修复后通过同一个现有命令恢复。
实现 diff 前读取并固定的 spec_revision: fdf03ec,来源 docs/reference/contracts/projection-envelope-contract.md:Field semantics implemented(实际读状态、unreadable 告警、最老上游时间);Consumer rule implemented(结论前警示,权限独立);Cache and replay implemented(继承时间/覆盖不洗新,缺读不推断不存在)。这些是本次受影响条款的映射,不是宣布整个 typed migration 或所有产品消费者已完成。
对主干的风险
原 reviewed 0a1头上的 fresh 误报不是用作者声明关闭的:当前独立构造真实损坏 JSON 与目录,直接调用实际 TS reader,再跑真实公开 CLI。source 和正常 wheel 均得到 unreadable_count=2/alert=true;恢复后 read/fresh、无告警。全部原字段的四场景 base/head 比较一致,只剥离声明新增的 envelope,并归一实际 synthetic 临时路径、macOS别名和 generated_at;压缩 host facts 先无损解压再比较,保留所有决定、指导、权限与动作。首次比较漏归一外层临时目录的差异原件保留,修正路径后没有剩余差异。
这是有意的默认附加元数据,不声称 default-off,也不因安装、读取到材料或 envelope 存在就启用调度/花费权限。新 read_status 只在共同发布的 Python/TS 传输中使用,未增加持久 schema 版本;现有 legacy writer/under-lock 调用保留是因为有真实消费者。16项 TS 测试涵盖真实文件、schema无效、legacy、并发/锁及恢复,不以两个新 mock 互比替代旧调用者。
接口预算是呈现回归预算,不是禁止大参数的硬限额。新增各来源的读取/覆盖事实有直接消费者价值,应保留;本头把实测 quota compact 上限与说明、测试一起从16500字符/386嵌套项调整为20500/525,顶层54不变。相同工作负载记录的15419/378/52到18636/513/53仍留余量。独立完整96行真实 CLI 矩阵保留:旧 comparator 有18个新增 schema 形状增长失败,当前96行全部通过,18个 reviewSignals 仍可见。迁移只允许已知 status/quota 的 none→v0,后续 v0→v0、未知和无关 surface 仍被约束;这不是全局增长豁免,也没有删除决定文字换取绿色。
语义与 CI 对齐
SourceReadStatus 复用既有词汇,错误分类来自实际 IO,无 substring/prose 状态 owner;Python 只传事实,TS 保留规则。没有产品或 benchmark 特定通用义务,也未把机器执行要求称为建议。advisory 在完整 semantic smoke 之前运行;空 advisory 本身不证明语义等价,当前判断同时依赖实际接口与物理错误反例。
当前验证为431项 Python、16项 TS、TS类型检查、同负载96行差分,以及 native premerge 的6 direct+19 selected,全部通过、0 manual hold。初次错误 pytest 文件名导致 exit4、未运行任何测试,已按真实路径修正;首次正常打包因旧本地 Chat assets 被正确拒绝,正常 build:chat 后重新构建 wheel/sdist 并隔离安装通过。六个改动产品文件在 source、两种 archive 与安装中逐字节一致;真实四态 receiver 在正常 wheel 复验,不是绕过构建校验。未拉取、轮询或等待 hosted CI;绿验证也不表示已授 merge 权限。
我的整体评价
当前增量与问题相称,架构保留理由明确:读事实归原 typed IO owner,来源汇总归原 seal,呈现归原 renderer。相邻 future-facing pass 已做这项小型归属收敛,并保留有真实调用的 legacy unwrap;不为此引入平行状态、框架或要求无关全量语言迁移。long_horizon=improved、user_experience=improved 限于来源可靠性与现有命令中的直接解释,长期净益未测。
本头可以 APPROVE。此前 P2 已由生产入口与安装包证据关闭,完整当前净提案也已重评;原旧 review 不会因此被自动 dismissal。review-packet/DecisionContext 后续阶段、完整前端/host采用、平台 ACL 与持续运行收益仍归既有验收;此评审不宣称共享默认 CLI 已更新,也不代替维护者的合并授权或 native closeout/readiness。
English verdict: APPROVE - 9ef6109. The full14-file proposal reuses the existing typed seal and scheduler IO owner; real source and normally installed wheel CLI probes distinguish absent, corrupt, directory and recovered sources while preserving prior quota decisions. 431 Python tests,16 TS tests, the complete96-row CLI comparison, type/semantic checks and6direct+19selected canaries pass. The bounded default metadata/budget change is disclosed; remaining frontend/host/DecisionContext and long-run acceptance stay scoped, and this review grants no merge or install authority.
|
This pull request has merge conflicts with Choose the remote for the base repository, not an out-of-date fork. 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 HEADFor a same-repository clone whose Keep the DCO |
Goal And Delivered Outcome
quota should-runinherited status data but did not emit its own canonical freshness, completeness, source, and Goal-coverage envelope.KeyError: projection_envelope. After, every active, paused or stopped, health-blocked, and unknown-Goal result emitsloopx_projection_envelope_v0. The focused regression suite and the source and packaged CLI rows below prove the result.main. No separate issue.Author Declaration
Implemented against
docs/architecture/rfcs/typescript-control-plane-migration-v0.mdanddocs/reference/contracts/projection-envelope-contract.mdat baseda7d0b9979.build_quota_should_runtests/test_projection_envelope.py_tracked_read_callback,_record_app_scheduler_state_sourcetest_quota_should_run_records_live_workspace_inbox_and_scheduler_readsprojection.envelope.sealnpm run typecheck:control-planerender_quota_should_run_markdowntest_quota_should_run_alerts_when_the_status_envelope_is_missingScope And Continuation
quota should-runrollout slice. The RFC still listsreview-packetand Decision Context packets as later read-model adoptions.Validation
0a1cbfde9b977df2b17a8d0dc5693ab0a51f9de5regression_paritypassedprojection_envelopewas absent. After implementation and the final rebase, the related suite passed 228 tests.regression_paritypassedreal_entrypointpassedpython -m loopx.cli ... quota should-runfrom the source checkout and read backprojection=quota_should_run.real_entrypointpassedloopx quota should-runread back the Goal-scoped envelope.staticpassedregression_paritypassedintegrationpassedloopx canary premerge --from-git-diffpassed all 19 selected checks, including the public and private boundary and both interface-budget smokes.See validation disclosure guidance.
Frontend / Visual Evidence
Type of Change
LoopX Area
Technical Direction
Shared-authority RFC fixture impact
Boundary Checklist
.loopx/,.codex/goals/, and liveACTIVE_GOAL_STATE.md).none.Signed-off-bytrailer (git commit -s).