Skip to content

fix(quota): bound blocked-frontier Vision baseline initialization - #8574

Open
xiaobaifly7 wants to merge 1 commit into
loopx-project:mainfrom
xiaobaifly7:codex/blocked-missing-vision-wait
Open

xiaobaifly7 wants to merge 1 commit into
loopx-project:mainfrom
xiaobaifly7:codex/blocked-missing-vision-wait

Conversation

@xiaobaifly7

Copy link
Copy Markdown
Contributor

Goal And Delivered Outcome

Author Declaration

  • Written by: model_agent — OpenAI Codex (GPT-6).

Implemented against

  • Specification and revision: #8572, issue body as read on 2026-11-11; no maintainer comments were present. Existing agent_scope_frontier_v1 / agent_scope_wait behavior is reused.
  • Criteria:
Criterion (spec clause) Disposition Symbol / path Test or command
Finite baseline initialization before blocked-only wait implemented quota/vision_baseline_admission.ts::boundVisionBaselineAdmission first admission, fresh-Turn and independent-process readback regression
Durable closeout/re-entry rule implemented runtime/Goal/Agent-scoped admission; original initialization Turn retained scope isolation, concurrent admission and receipt-bound re-entry tests
Retain missing baseline pending without authorizing blocked delivery implemented typed agent_scope_frontier, existing interaction/scheduler projection test_missing_vision_baseline_wait.py::assert_wait checks no attempt/delivery, quiet wait and scheduler backoff
Preserve independent work, resume proofs and original settlement implemented complete scoped work counts; due-monitor and receipt guards; unchanged resume owners File/SQLite independent-work and due-monitor tests; resume/replan/wait contract suites
Owner Stop and legal no-debit boundaries implemented existing stopped/paused entry and settlement owners remain authoritative existing run-decision contracts and original owed replan regression
Actual host/model loop or installed UI qualification out_of_scope this changes control-plane admission only no installed runtime, model or host test claimed
  • Self-check before submission: read the repository instructions, applicable contribution/quality/frontend-delivery boundaries, issue and fix(quota): wait when the only scoped work is blocked #8511 wait contract; ran typed tests, real should-run projection and isolated File/SQLite readback, baseline reproduction, semantic advisory/full-tree checks, typecheck, Ruff, diff/RFC checks and quick premerge. No RFC pair changed.

Scope And Continuation

  • Completed scope and remaining work: complete within this scoped policy proposal. No new action enum, CLI option, Python decision owner or installed-host change.
  • Slice boundary / successor: fix(quota): wait when the only scoped work is blocked #8511 remains the broader blocked-only wait change; Clarify replan admission after compute quota is exhausted #8571 governs exhausted-window admission separately. This PR does not define a quota exception or replace receipt recovery.
  • Adjacent refactoring: unnecessary; the existing TypeScript run-decision owner composes the bounded admission, and Python only transports facts and the typed frontier.

POLICY CHOICES

  1. Allow exactly one initialization Turn per runtime root / Goal / Agent, consumed when that fully qualified runtime-bound should-run admission is issued. A projection without an explicit runtime root, Agent and Turn remains stateless and does not consume or claim this durable allowance.
  2. The initial Turn may re-enter with its original identity to finish work/settlement. Receipt-bound original Todo/replan work bypasses this fresh-Turn limit. A new Turn ID or changed missing-checkpoint timestamp does not reset the allowance.
  3. Apply the limit only with complete same-Agent runnable counts, at least one explicit scoped blocked advancement/blocker, no due monitor/schedule gap, and only missing-baseline checkpoint gaps/triggers. Unknown sources and independent repair/replan obligations retain their original owner decision.
  4. Runnable work, due monitors and meaningful independently triggered replans can run again; they do not erase the initialization record. This proposal does not automatically grant another baseline-only attempt after an owner lifecycle action or add a reset UI. Maintainers may choose a different explicit rearm policy.
  5. Use existing quiet agent_scope_wait / scheduler backoff while retaining the pending Vision obligation and the original admission identity in the frontier. No quota debit or successful-baseline receipt is fabricated.

These are proposed conservative defaults, not a claim of a prior maintainer ruling. Maintainers may change the allowance, consumption point, scope or rearm rule.

Validation

  • Tested revision: 2938c33.
  • Run state: finished.
  • Input classes: synthetic, public_fixture.
Check kind Result Public-safe evidence / limitation
unit / integration passed 122 distinct focused Python cases across six files, including 8 new cases; affected shared-fixture cases rerun after updating the nullable frontier result
unit passed 91 focused TypeScript cases: run decision, baseline admission, resume planning, replan semantics and Vision wait coverage; concurrent fresh-Turn initialization and malformed persisted-state rejection included
real_entrypoint / real_backend passed build_quota_should_run with disposable runtime and real File/SQLite authority; fresh Python process reads the durable admission and waits
regression_parity passed pinned main reproduces repeated autonomous_replan_required; same synthetic scenario on this branch waits after initialization
static passed control-plane typecheck; focused Ruff; diff advisory including the new source; full semantic vocabulary smoke; public-boundary scan of all 10 outgoing files with empty registry; staged/diff/RFC checks
integration passed quick premerge: maintainability, semantic vocabulary and quota-plan canaries, direct checks and changed-Python compilation
environment failed then resolved for validation first quick premerge hit Windows default-codepage subprocess JSON decoding; independently reproduced on pinned main; command-local PYTHONUTF8=1 passes without a source/config change
regression_parity failed then fixed initial fixture comparison omitted the new nullable frontier field; shared Python/TypeScript fixture updated and all 31 affected cases pass on rerun
  • Reproducible selections (checkout-installed test environment, LOOPX_USAGE_PING=0; Windows commands also use PYTHONUTF8=1):
python -m pytest -q tests/control_plane/test_missing_vision_baseline_wait.py tests/control_plane/test_quota_run_decision.py tests/control_plane/test_quota_decision_summary.py tests/control_plane/test_agent_scope_frontier_contract.py tests/control_plane/test_monitor_replan_agent_scope.py tests/control_plane/test_vision_wait_coverage.py
node --no-warnings --experimental-sqlite --experimental-strip-types --test --test-concurrency=4 tests/control_plane_ts/quota_run_decision.test.ts tests/control_plane_ts/vision_baseline_admission.test.ts tests/control_plane_ts/resume_planning.test.ts tests/control_plane_ts/replan_semantics.test.ts tests/control_plane_ts/vision_wait_coverage.test.ts
npm run -s typecheck:control-plane
python -m loopx.cli canary premerge --tier quick --from-git-diff --git-diff-base origin/main
  • Coverage and gaps: focused validation, not full Python/TypeScript-suite, model-behavior, PostgreSQL, installed Driver or desktop qualification. Public should-run and existing interaction/scheduler contracts are exercised; no live registry is scanned. Root npm installation attempts failed on network resets; an existing compatible dependency tree was reused read-only without manifest/lock changes.

Frontend / Visual Evidence

  • UI impact: none.
  • Before / After / First viewport and preview / States and viewports shown: N/A; no visual surface or layout change.
  • Source data: synthetic.
  • Attention review / Craft review: N/A. Existing CLI/interaction/scheduler wait presentation consumes the same typed frontier; no new UI capability or control.

Type of Change

  • Bug fix
  • Test update

LoopX Area

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

Technical Direction

  • Direction / acceptance reference: governed continuation; finite missing-baseline initialization and existing scoped wait. No migration/promotion claim.

Shared-authority RFC fixture impact

  • Production-scale fixture schema: N/A; no shared-authority migration or promotion claimed.
  • Semantic dimensions changed, or reviewed no-impact rationale: local admission identity/once policy; authority routing, Todo/lease records and acceptance schemas unchanged.
  • Provider conformance arms run: isolated File/SQLite consumers.
  • Read-only legacy/file/PostgreSQL three-arm rehearsal: N/A; no provider promotion, runtime-routing or compatibility projection change.

Boundary Checklist

  • Neither the diff nor this PR body/comments/attachments disclose private state, credentials, raw traces or verifier output, internal links, or local machine paths.
  • No duplication of maintainer-owned benchmark work.
  • Change scoped to the linked issue.
  • No paired RFC changed; bilingual RFC check passes.
  • UI impact marked none.
  • Every commit includes a DCO Signed-off-by trailer.

Signed-off-by: xiaobaifly7 <196511160+xiaobaifly7@users.noreply.github.com>

@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 · gpt-6.1-sol · OpenAI · runtime_reported · reasoning_effort=max

评审提交 2938c338851793a4e487bf4381ce7b8b10a4cb0d。结论 REQUEST_CHANGES。

P2 等待回执在重试时绕过一次性初始化限制

等待回执绑定了重规划身份。用同一个等待 Turn ID 重读后,回执升级,返回 should_run=true、must_attempt=true 和结算计划。 从原始正向准入回执派生豁免。安静等待应保留诊断义务,避免写入能在重试时绕过限制的结算身份。

P2 准入回执写失败仍消耗唯一初始化机会

只在真实 CLI 的 rollout 追加点注入 OSError。首次 guard 返回 heartbeat_receipt_write_failed,磁盘上已有准入 sidecar。修复 IO 后,新的 Turn 返回 agent_scope_wait。仍持有失败 Turn ID 的调用方可以原样重试并成功准入。 在现有回执提交边界确认一次性初始化,或把预留与真实回执对账,在明确失败后恢复资格。

动机 / Motivation

处理阻塞 Todo 的 Agent 需要一次有明确结算身份的 Vision 基线初始化,并能在后续唤醒进入安静等待。 自治重规划只剩缺失的 Vision 基线时,主干会为没有可执行 Todo 的 Agent 再次返回 run_now。 候选首次等待是安静的。两个新的 Turn 各自在相同身份下重试后都重新取得执行权,正常重试可以绕过单次初始化上限。 检查覆盖真实 CLI、回执和调度投影,执行范围到启动判定为止。

改动思路 / Approach

复用现有 agent_scope_wait,保留原始初始化身份,让等待和回执协调读取同一个有效准入事实。 新增本地准入记录需要与已有 heartbeat receipt 的真实状态一致,现有回执协调负责解释重试资格。 设计问题 #8572

具体改动 / Changes

10 文件,+299/-3。生产 +110/-2,测试和 fixture +189/-1。 新默认策略仍需 maintainer 决定。NEW-ADMISSION 的首次决策通过。ORIGINAL-RECEIPT 的同身份接续在下述情形失败。OWNER-STOP 仍走既有前置检查。主干基线 beff0f3e55d1f70eceebbd8e78c11f1cff34643b。docs/quota-allocation.md

对主干的风险 / Risks

额度 1/0,原 Turn 已获得正向回执。另开两个 Turn,各自第一次查询均安静等待,使用各自同一 ID 再读 guard 后均升级成正向重规划。 只在真实 CLI 的 rollout 追加点注入 OSError。首次 guard 返回 heartbeat_receipt_write_failed,磁盘上已有准入 sidecar。修复 IO 后,新的 Turn 返回 agent_scope_wait。仍持有失败 Turn ID 的调用方可以原样重试并成功准入。

首次真实准入返回 autonomous_replan_required,首次新 Turn 安静等待。独立任务和到期监控的 File、SQLite 对照通过。 Python 109 项、TypeScript 91 项、控制面 typecheck、Ruff、quick premerge 6 项直接检查及 3 项选定检查均通过。

合成数据通过真实 CLI 和 TypeScript Effect runtime,分别用 File 与 SQLite Todo authority 验证。安装后的宿主和远端 CI 尚未复验。

我的整体评价 / Verdict

从原始正向准入回执派生豁免。安静等待应保留诊断义务,避免写入能在重试时绕过限制的结算身份。 用同一夹具验证原身份、新 Turn 和重复读取的结果。另加回执追加故障并验证修复后的重新准入。

English verdict: REQUEST_CHANGES for 2938c338851793a4e487bf4381ce7b8b10a4cb0d. A quiet wait receipt becomes executable on same-Turn replay. A failed guard append also consumes the sole initialization admission.

prepared.vision_initialization_context = {
"runtime_root": str(runtime_root), "goal_id": safe_goal_id,
"agent_id": prepared.agent_frontier_id, "turn_instance_id": turn_instance_id,
"receipt_bound": bool(receipt_bound_todo_id or receipt_bound_replan_obligation_id),

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.

[P2] 等待回执在重试时绕过一次性初始化限制

等待回执绑定了重规划身份。用同一个等待 Turn ID 重读后,回执升级,返回 should_run=true、must_attempt=true 和结算计划。 从原始正向准入回执派生豁免。安静等待应保留诊断义务,避免写入能在重试时绕过限制的结算身份。

if (!previous) {
const admission: VisionBaselineAdmission = {schema_version: BASELINE_ADMISSION_SCHEMA, ...scope,
turn_instance_id: turn, replan_obligation_id: requireNonEmptyString(obligation.obligation_id, "obligation_id")};
await durableWriteJson(path, admission);

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.

[P2] 准入回执写失败仍消耗唯一初始化机会

只在真实 CLI 的 rollout 追加点注入 OSError。首次 guard 返回 heartbeat_receipt_write_failed,磁盘上已有准入 sidecar。修复 IO 后,新的 Turn 返回 agent_scope_wait。仍持有失败 Turn ID 的调用方可以原样重试并成功准入。 在现有回执提交边界确认一次性初始化,或把预留与真实回执对账,在明确失败后恢复资格。

@mergify

mergify Bot commented Nov 11, 2026

Copy link
Copy Markdown

This pull request has merge conflicts with main and cannot be merged
until they are resolved. Please rebase or merge the base branch, @xiaobaifly7.

Choose the remote for the base repository, not an out-of-date fork.
For a fork clone, first inspect git remote -v; upstream must point
to https://github.com/loopx-project/loopx.git. If it is absent, add it
with git remote add upstream https://github.com/loopx-project/loopx.git.
Then run:

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 HEAD

For a same-repository clone whose origin points to
https://github.com/loopx-project/loopx.git, use origin instead of
upstream for fetch/rebase. If you prefer merging the base, use
git merge <base-remote>/main and push normally.

Keep the DCO Signed-off-by trailer on every commit when you rebase.
https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork

@mergify mergify Bot added the needs-rebase Mergify: the pull request has merge conflicts with its base branch label Nov 11, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-rebase Mergify: the pull request has merge conflicts with its base branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Clarify blocked-only wait when an Agent Vision baseline is missing

2 participants