Repository navigation
fix(quota): compare scheduling write scopes with the canonical fold - #7674
huangruiteng merged 2 commits into
Conversation
…ical owner Quota scheduling compared child-lane write scopes with its own matcher. Add an entry point next to the canonical lease owner that composes the canonical folded glob decision with the subtree containment scheduling keeps, so the two layers share one set of primitives. Signed-off-by: lll-hhh <169072815+lll-hhh@users.noreply.github.com>
…ld lanes The scheduling matcher compared scopes case-sensitively, so on a case-insensitive host it admitted two lanes naming the same physical file while the canonical lease owner rejected the same pair. Consume the new scheduling entry point and keep the subtree rule the scheduler already had. Signed-off-by: lll-hhh <169072815+lll-hhh@users.noreply.github.com>
35b3930 to
a936189
Compare
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent | gpt-6.1-sol | OpenAI | runtime_reported | reasoning_effort=max
动机 / Motivation
同一 Goal 的协调者把多个声明了写入范围的临时子任务排入同一轮时,会使用这项比较。 原先 src/Main.ts 与 src/main.ts 会同时被排入一轮,之后可能遇到延迟的 lease 冲突;现在调度先标出冲突,并保留独立文件的工作。 可观察交付是调度与 canonical lease 共用 Unicode 比较规则,并保留调度原有更宽的子树语义。 范围限于同一调度调用的 scope 比较;临时子任务执行、独立 peer 权限、存储事务和安装资格由原边界负责。
改动思路 / Approach
复用现有 TS caseFold、glob 和 comparisonWriteScopes,删除 Python matcher;具名 scheduling 变体保存已存在的子树规则,比再次移植 Unicode 算法或直接换成较窄 lease 语义更合适。 范围限于同一调度调用的 scope 比较;临时子任务执行、独立 peer 权限、存储事务和安装资格由原边界负责。File/SQLite 的真实 quota should-run 把 Latin、Sigma、sharp-s 别名子任务从可并行改为 write_scope_conflict,同时继续给出独立子任务。
具体改动 / Changes
精确 head a9361897d5f437b393da8c3b14f19aae0dea791e,完整比较基线 ed0972c3190ad9f0e864284bdb1d95bdefefb4a6。验收依据 issue #7652 与 docs/reference/canonical-lease-renew.md,版本 ed0972c3190ad9f0e864284bdb1d95bdefefb4a6;先读原合同/问题,未用本次新写的文档替代独立规范。Host/path case aliases remain overlapping、empty scope set、request spellings 三项均为 implemented;依据是实际调度对照、既有 lease 测试和未改写声明的 comparison-only 实现。 五个路径的全部改动及相关合同条款均已阅读;改动行数只用于定位成本,结论来自真实 caller 与反例。既有 compatibility export 或子树变体有实际调用者,保留原因已经核验。
关键代码讲解
- _write_scopes_conflict:跨仓库及空范围短路后,把同一仓库范围交给 runtime。
- evaluateQuotaSchedulingWriteScopesOverlap:解码原声明并构造 comparison-only view,复用现有 matcher。
- schedulingScopePairOverlaps:先用 lease overlap,再合成调度既有的无尾斜杠子树语义。
对主干的风险 / Risks
没有发现阻断项。14组 File/SQLite 的真实 should-run 对照覆盖 Latin、Σ/ς、ß/SS、子树、独立文件、glob class 和关闭状态。三个应保持原义的分支完整 orchestration contract 相等;案例中的声明、claim、实际子任务执行和预算消费由既有 owner 管理,测试未启动子任务。70项 Python、16项 TS、Ruff 和 tsc 通过。 native standard premerge PASS:六项直接检查、18项选择检查及当前 CQR 均通过。 不查询或等待 GitHub CI;本地失败、缺少资格和 merge readiness 分开保留。
我的整体评价 / Verdict
这项调度比较修复达到当前任务的验收:大小写别名提前冲突,既有子树、独立文件和关闭行为得到保留。复用现有 matcher 的边界清晰,未增加独立权限或持久状态 owner。没有 rendered presentation 变化。本次验证覆盖 source CLI/runtime;原生 Windows 文件系统、安装宿主和实际模型子任务执行未资格化,也未测量长期吞吐或完整成本。未发现需要阻断此 head 的问题。
English verdict: APPROVE — the scoped scheduling fix is validated with preserved disabled and existing-subtree behavior.
Goal And Delivered Outcome
Outcome basis / optional anchor: [Bug]: the quota scheduling layer compares write scopes case-sensitively while the canonical lease owner folds case #7652, reproduced on
mainat8caaf678e.Goal/source and gap: the quota scheduling layer decided "do these two child lanes write the same file" with a matcher it owns itself (
fnmatchcase, plus a segment-prefix subtree rule), while the canonical lease owner for the same concept folds case with Unicode semantics. On a case-insensitive host the two owners returned opposite answers for one pair, so the lane that collides with the primary lane was admitted as an eligible child lane instead of blocked withwrite_scope_conflict.Observable before → after, with the validation row that proves it: before, the pairs
src/Main.ts/src/main.ts,src/Σ.ts/src/ς.ts,src/ß.ts/src/SS.tsandsrc//SRC/returned "no overlap" from scheduling, and the case-aliased child lane ran in the same round; after, that child lane is blocked withwrite_scope_conflictnaming the primary Todo. The scheduling layer's own wider subtree rule is unchanged:src/src/a.ts,src/main/src/main/x,src/a/src/a/bandsrc/a.ts/src/a.ts/bstill report overlap even though the canonical lease rule does not. Proven by theregression_parityrow (a failing-before test) and the twounitrows below.Issue/task and intended base: Closes [Bug]: the quota scheduling layer compares write scopes case-sensitively while the canonical lease owner folds case #7652. Intended base
mainat8caaf678e.Author Declaration
Implemented against
docs/reference/canonical-lease-renew.mdatmain8caaf678e("Host/path case aliases remain overlapping"), and the divergence table [Bug]: the quota scheduling layer compares write scopes case-sensitively while the canonical lease owner folds case #7652 measured betweenevaluateTaskLeaseWriteScopesOverlapand_scope_patterns_overlap.schedulingScopePairOverlaps,loopx/control_plane/work_items/task_lease_acquire_decision.tsnode --test tests/control_plane_ts/effect_runtime_handlers.test.tscaseFold/fnmatchcase/scopePairOverlaps;_scope_patterns_overlapand_scope_static_prefixare deleted fromloopx/control_plane/quota/task_orchestration_admission.pypython -m pytest tests/control_plane/test_task_orchestration_admission.pyschedulingScopeRoot,loopx/control_plane/work_items/task_lease_acquire_decision.ts…/a.ts-style rows of the same TS test, plustest_admission_keeps_scheduling_subtree_containment_without_a_trailing_slashcomparisonWriteScopesis reused and no caller writes scopes backtest_admission_serializes_case_alias_write_scopes,test_admission_leaves_sibling_files_independentnpm run typecheck:control-plane;ruff checkon the changed Python files; and the same new tests run against the base revision as a failing-before control. Assumed, not verified — that the managed runtime is reachable on this path:apply_task_orchestration_contractalready calls it for peer lanes in the same module, so this adds no new host requirement to the flow, but a scheduling call that previously worked with no runtime now requires one. Not attempted — native Windows/macOS filesystem behaviour of the admitted lanes; this change is a comparison rule, not an IO path.Scope And Continuation
Validation
a9361897d5f437b393da8c3b14f19aae0dea791e(baseed0972c31). The earlier35b393044was the same patch on8caaf678e; it was rebased when main advanced, andgit patch-id --stableis unchanged (d13b9e1df76fa31106f3db84eaa8b582e503f19a), so no content moved. Re-verified on the new base: control-plane typecheck clean, the 15 rows above re-evaluated with 0 mismatches, 26 admission tests and 14 runtime handler tests pass.unitpassedpython -m pytest tests/control_plane/test_task_orchestration_admission.py— 26 passed, including three new rows: a case-aliased pair now serializes, a no-trailing-slash subtree pair still serializes, sibling files stay independent.unitpassednode --test tests/control_plane_ts/effect_runtime_handlers.test.ts tests/control_plane_ts/effect_runtime_handler_loading.test.ts— 16 passed, including all 15 rows of the divergence table measured in #7652.integrationpassedpython -m pytest tests/control_plane/test_task_orchestration_admission.py tests/control_plane/test_task_lease.py tests/control_plane/test_quota_planning_horizon.py— 70 passed; these cover the canonical owner, the admission decision and its should-run consumers.regression_paritypassed8caaf678e: the case-alias row fails because both lanes are admitted, the subtree and sibling rows pass; on this head all three pass. The failure sets differ by exactly that one behaviour, so the wider subtree rule is not a silent change.staticpassednpm run typecheck:control-planeandruff checkon the changed Python files, both clean.manualpassedtests/architecture/test_control_plane_import_boundaries.py::test_lark_projection_sinks_are_owned_by_the_extension_layerfailure reproduces identically on8caaf678e, so it is not attributable to this change. The fulltests/control_plane/suite and the browser lanes were not run locally; CI covers them. Not covered: real host filesystem case-folding behaviour on Windows/macOS.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).python3 scripts/check_rfc_bilingual.py --base origin/main --head HEADpasses, or no paired RFC changed.none.Signed-off-bytrailer (git commit -s).