Skip to content

feat: enforce runtime agent budgets - #37

Merged
GhostXia merged 3 commits into
mainfrom
codex/issue-36-runtime-budgets
Aug 12, 2026
Merged

feat: enforce runtime agent budgets#37
GhostXia merged 3 commits into
mainfrom
codex/issue-36-runtime-budgets

Conversation

@GhostXia

@GhostXia GhostXia commented Aug 12, 2026

Copy link
Copy Markdown
Owner

概要

独立实现 issue #36:为 Lean Dev Router 增加运行时预算与硬熔断机制。

本 PR 直接基于 main,不依赖 PR #35,也不包含 terra_planner 快路径或第四角色改动。

主要改动

  • 新增标准库实现的 runtime_guard.py,在启动子代理前校验完整 DISPATCH。
  • 为每个角色和阶段增加模型调用、假设数、模型主动时间、返工轮次与停滞调用上限。
  • 增加 spinning 检测、升级锁存、角色身份租约和 parent 禁止写入门禁。
  • 防止相同 revision 重复审计;revision 变化时执行增量审计。
  • 记录输入、缓存输入、缓存创建、输出、推理、耗时、上游尝试和终止原因等遥测。
  • 更新 Skill、Sol/Luna/Terra 契约、英文/中文文档、仓库验证器和回归测试。

验证

  • python -B scripts/validate_repo.py:通过
  • 测试:48 项通过,1 项因 Windows 文件名限制跳过
  • Scope:通过
  • 基线:origin/main
  • 与 PR Use Terra High parent for bounded routing #35:无提交祖先关系、无功能依赖

Closes #36

Summary by CodeRabbit

  • New Features

    • Added runtime safeguards for dispatch validation, budgets, progress tracking, audit registration, repair cycles, and exhaustion handling.
    • Added persistent runtime state, telemetry, snapshots, structured errors, and command-line controls.
    • Added revision-aware audit handling, including duplicate prevention and incremental re-audits.
  • Documentation

    • Updated English and Chinese guidance for identities, budgets, runtime controls, audits, repairs, installation, and self-testing.
  • Validation & Tests

    • Expanded repository checks and automated coverage for runtime limits, authorization, persistence, audits, repairs, and malformed data.

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@GhostXia, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 17 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 0d8d80e1-dc09-4245-9997-44bca04ef3df

📥 Commits

Reviewing files that changed from the base of the PR and between fbe774c and 1860891.

📒 Files selected for processing (5)
  • .agents/skills/lean-dev-router/SKILL.md
  • .agents/skills/lean-dev-router/scripts/runtime_guard.py
  • scripts/validate_repo.py
  • tests/test_runtime_guard.py
  • tests/test_validate_repo.py
📝 Walkthrough

Walkthrough

The PR adds a standard-library runtime guard for dispatch validation, telemetry, budgets, repairs, audits, persistence, and CLI control. It expands Sol/Luna/Terra contracts and documentation, strengthens repository validation, and adds comprehensive tests.

Changes

Runtime-guarded router

Layer / File(s) Summary
Dispatch and audit contracts
.agents/skills/lean-dev-router/SKILL.md, agents/*.toml, README.md, docs/zh-CN/README.md, lean-dev-router-self-test-guide.md
Contracts now require stable identities, task metadata, positive budgets, runtime-guard events, revision-aware audits, bounded repairs, and exhaustion routing.
Runtime guard lifecycle
.agents/skills/lean-dev-router/scripts/runtime_guard.py
Adds packet validation, telemetry, leases, budget enforcement, stagnation detection, audit and repair tracking, state snapshots, atomic persistence, and JSON CLI commands.
Repository contract validation
scripts/validate_repo.py
Validates expanded dispatch fields, runtime-guard implementation markers, restricted imports, required protocol terms, and executable guard integration.
Runtime guard and validator tests
tests/test_runtime_guard.py, tests/test_validate_repo.py
Adds coverage for guard lifecycle, authorization, budgets, stagnation, repairs, audits, snapshots, CLI behavior, and repository validation.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant SolPlanner
  participant RuntimeGuard
  participant LunaWorker
  participant TerraAuditor
  SolPlanner->>RuntimeGuard: initialize dispatch with identities and budgets
  RuntimeGuard->>LunaWorker: permit bounded execution
  LunaWorker->>RuntimeGuard: record event telemetry
  RuntimeGuard->>TerraAuditor: route exhaustion or register revision audit
  TerraAuditor->>RuntimeGuard: report audit completion and claims
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 3.03% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: enforcing runtime budgets for agent execution.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/issue-36-runtime-budgets

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
scripts/validate_repo.py (1)

468-479: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider AST-based checks instead of raw source substrings.

Markers such as 'sub.add_parser("start"' depend on the local variable name sub, on double quotes, and on single-line formatting. A formatter run or a rename in runtime_guard.py breaks repository validation without any behavior change. Detect the subcommands and the named constants through the parsed tree instead, and keep substring checks only for message literals.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/validate_repo.py` around lines 468 - 479, Replace the raw-source
checks in the runtime-gate validation loop with AST-based detection using the
parsed tree: identify registered subcommands independent of the parser variable,
quote style, and formatting, and detect the named constants by their AST
definitions or references. Retain substring checks only for required message
literals, while preserving the existing missing-gate errors.
tests/test_runtime_guard.py (1)

74-78: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Add a timeout to each subprocess.run call.

Each call pipes JSON to the guard CLI and waits for exit. If the CLI blocks on stdin or loops, the test suite hangs with no output instead of failing. A timeout keeps the failure bounded and diagnosable.

♻️ Example change
         result = subprocess.run(
             [sys.executable, "-B", str(GUARD_PATH), "schema"],
-            text=True, capture_output=True, check=False,
+            text=True, capture_output=True, check=False, timeout=30,
         )

Note on the static analysis hints for these lines: the S603 and subprocess-from-request findings are false positives. The argument vector is a fixed list built from sys.executable and a repository path, and no shell is used.

Also applies to: 98-106, 111-121, 122-128

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_runtime_guard.py` around lines 74 - 78, Add an explicit finite
timeout argument to every subprocess.run call in the runtime guard tests,
including the calls covering the schema, stdin JSON, and related CLI cases. Keep
the existing fixed argument vectors and result assertions unchanged so blocked
or looping guard processes fail promptly.

Source: Linters/SAST tools

tests/test_validate_repo.py (1)

229-241: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Make the negative case independent of the marker occurrence count, and widen the branch coverage.

source.replace("duplicate_audit_revision", "removed", 1) removes only the first occurrence. validate_runtime_guard() uses if term not in source, so the test only passes while that literal appears exactly once in runtime_guard.py. If a second occurrence is added later, this test fails for a reason unrelated to the contract. Drop the count argument.

The test also leaves three branches of validate_runtime_guard() uncovered: the unreadable-file path, the SyntaxError path, and the import allowlist. Each is cheap to exercise with a temporary file.

Minor naming point: the test name states "executable", but the test does not run the guard.

♻️ Proposed changes
         validate_repo.ERRORS.clear()
         self.write(
             ".agents/skills/lean-dev-router/scripts/runtime_guard.py",
-            source.replace("duplicate_audit_revision", "removed", 1),
+            source.replace("duplicate_audit_revision", "removed"),
         )
         validate_repo.validate_runtime_guard()
         self.assertTrue(any("duplicate_audit_revision" in error for error in validate_repo.ERRORS))
+
+    def test_runtime_guard_rejects_bad_syntax_and_foreign_imports(self) -> None:
+        relative = ".agents/skills/lean-dev-router/scripts/runtime_guard.py"
+        self.write(relative, "def broken(:\n")
+        validate_repo.validate_runtime_guard()
+        self.assertTrue(any("invalid Python" in error for error in validate_repo.ERRORS))
+
+        validate_repo.ERRORS.clear()
+        self.write(relative, "import requests\n")
+        validate_repo.validate_runtime_guard()
+        self.assertTrue(any("requests" in error for error in validate_repo.ERRORS))
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_validate_repo.py` around lines 229 - 241, Update
test_runtime_guard_is_executable_and_required to replace every
duplicate_audit_revision occurrence in the negative fixture, avoiding dependence
on marker count. Extend coverage for validate_runtime_guard with temporary-file
cases for unreadable files, SyntaxError input, and import allowlist validation,
and rename the test to reflect that it validates required content rather than
execution.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.agents/skills/lean-dev-router/scripts/runtime_guard.py:
- Around line 436-454: Add an abandon_audit terminal transition to the audit
lifecycle, validating PLAN_ID, DISPATCH_ID, REVISION, AUDITOR_INSTANCE_ID, and
TERMINATION_REASON, locating the running job, recording status "abandoned" and
its termination reason, and returning the parent:sol decision. Wire the
audit_job action routing to invoke it, release the running-job block in
begin_audit, and leave last_completed_audits unchanged so the next audit
requires full mode.

---

Nitpick comments:
In `@scripts/validate_repo.py`:
- Around line 468-479: Replace the raw-source checks in the runtime-gate
validation loop with AST-based detection using the parsed tree: identify
registered subcommands independent of the parser variable, quote style, and
formatting, and detect the named constants by their AST definitions or
references. Retain substring checks only for required message literals, while
preserving the existing missing-gate errors.

In `@tests/test_runtime_guard.py`:
- Around line 74-78: Add an explicit finite timeout argument to every
subprocess.run call in the runtime guard tests, including the calls covering the
schema, stdin JSON, and related CLI cases. Keep the existing fixed argument
vectors and result assertions unchanged so blocked or looping guard processes
fail promptly.

In `@tests/test_validate_repo.py`:
- Around line 229-241: Update test_runtime_guard_is_executable_and_required to
replace every duplicate_audit_revision occurrence in the negative fixture,
avoiding dependence on marker count. Extend coverage for validate_runtime_guard
with temporary-file cases for unreadable files, SyntaxError input, and import
allowlist validation, and rename the test to reflect that it validates required
content rather than execution.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c0289756-c485-4697-98da-fcaa7adc3a6f

📥 Commits

Reviewing files that changed from the base of the PR and between 6cff13e and fbe774c.

📒 Files selected for processing (11)
  • .agents/skills/lean-dev-router/SKILL.md
  • .agents/skills/lean-dev-router/scripts/runtime_guard.py
  • README.md
  • agents/luna-worker.toml
  • agents/sol-planner.toml
  • agents/terra-auditor.toml
  • docs/zh-CN/README.md
  • lean-dev-router-self-test-guide.md
  • scripts/validate_repo.py
  • tests/test_runtime_guard.py
  • tests/test_validate_repo.py

Comment thread .agents/skills/lean-dev-router/scripts/runtime_guard.py
@GhostXia
GhostXia merged commit af1d45a into main Aug 12, 2026
2 checks passed
@GhostXia
GhostXia deleted the codex/issue-36-runtime-budgets branch August 12, 2026 11:22
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.

perf: 真实 L3 运行消耗 3474 万 token,需硬化 Luna/Terra/parent 预算边界

1 participant