Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions docs/reference/contracts/interface-budget-contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -810,3 +810,34 @@ characters once. Missing clauses, unrelated surfaces and later new→new growth
retain ordinary gates. This is cost attribution, not admission logic or proof of
semantic equivalence. The PR's clause review and current-path validation remain
necessary; deleting an obligation cannot earn this allowance.

### Thin native context route allowance

The complete real-CLI workload (320-character scope, five capabilities and an
explicit CLI route) now emits 4,999 normalized body characters on macOS with the
default native context routes. The earlier route qualification measured 4,851; the
current 4,900 ceiling therefore marks a supported combination over budget. Retain the
complete commands and instructions and raise only the thin presentation
allowance to 5,100, leaving 101 characters of headroom. The unchanged negative
case adds 48 characters to the CLI route, repeated four times, and still fails
with an overflow at 5,191. The original 4,900 failure remains historical evidence.

Matched base/head rendering on one frozen fixture preserves every body byte in
ordinary thin, explicit context-off, captured TurnEnvelope, brief, compact and
full modes. The supported thin body remains 5,347 actual characters / 5,351
UTF-8 bytes; this does not reduce model input or establish token, latency or
cost savings. The separate 400-character captured-envelope and 640-character
Reward Memory allowances remain fixed. The no-memory captured-envelope ceiling
therefore becomes 5,500. Other mode limits, JSON/output/key/line guards,
execution quotas, host hard limits and frozen qualification thresholds stay
unchanged; already-over-budget brief/compact/full workloads remain failures.

完整真实 CLI 负载(320 字符 scope、五项能力及显式 CLI 路径)在 macOS 默认原生上下文
路由下为 4,999 个归一化正文字符;此前路径资格化为 4,851,现有 4,900
展示上限因此将受支持组合标为超限。保留完整命令和指令,仅将 thin 展示预算调至 5,100,
余量 101 字符。原负例仍将 CLI 路径增加 48 字符、重复四次,在 5,191 时报告超限;
原 4,900 上限失败保留。单一冻结夹具的 base/head 各模式正文逐字节相同,受支持
thin 仍为实际 5,347 字符/5,351 UTF-8 字节,不据此宣称输入、token、延迟或费用
下降。可选 envelope 的 400 和 Reward Memory 的 640 字符余量不变;无 memory 的
envelope 上限随 thin 基础预算变为 5,500。其余模式、JSON/输出/键数/行数、执行
额度、宿主硬限制及冻结门槛不变;已超限的 brief/compact/full 场景仍保持失败。
9 changes: 5 additions & 4 deletions loopx/control_plane/heartbeat/budget.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@
# The same generic CLI + 320-char scope with explicit runtime also needs
# 5,715 chars; retain those routes instead of shortening the instructions.
"brief": 5_800,
# Full runtime capability flags plus an explicit CLI route and 320-char
# scope emit 4,851 normalized chars with unchanged guidance. Keep that
# supported combination; this is not a transport or execution limit.
"thin": 4_900,
# Default native context routes bring the complete capability/CLI-route
# fixture with a 320-char scope from 4,851 to 4,999 normalized chars.
# Retain the full instructions and 101 chars of presentation headroom;
# the unchanged oversized-route case still exceeds this allowance.
"thin": 5_100,
"visible_goal": 4_000,
}
NATIVE_GOAL_HOST_MAX_CHARS = INTERFACE_BUDGET_CHARS["visible_goal"]
Expand Down
6 changes: 3 additions & 3 deletions tests/control_plane/test_cli_output_budget.py
Original file line number Diff line number Diff line change
Expand Up @@ -1776,7 +1776,7 @@ def test_thin_json_budget_retains_full_supported_scope(tmp_path: Path) -> None:
)
payload = measurement["payload"]
assert scope in payload["task_body"]
assert payload["interface_budget"]["max_chars"] == 4900
assert payload["interface_budget"]["max_chars"] == 5100
assert payload["interface_budget"]["within_budget"] is True
assert "refresh-state --goal-outcome-update-json" in payload["task_body"]
assert "Local outcomes never replace root continuation, budget or stop criteria." in payload["task_body"]
Expand Down Expand Up @@ -1816,8 +1816,8 @@ def test_thin_budget_covers_complete_capability_and_cli_routes(
# Preserve the historical 4,500-character failure as a characterized
# input; the allowance changes, not the complete emitted instructions.
assert budget["budget_char_count"] > 4500
assert budget["max_chars"] == 4900
assert budget["within_budget"] is within_budget
assert budget["max_chars"] == 5100
assert budget["within_budget"] is within_budget, budget


def test_brief_budget_retains_full_commands_on_real_long_paths() -> None:
Expand Down
2 changes: 1 addition & 1 deletion tests/control_plane/test_heartbeat_agent_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def test_thin_cli_preserves_readable_admission_and_authority_with_host_scope(tmp
packet = json.loads(subprocess.check_output(command, text=True))
assert packet["ok"] is True
budget = packet["interface_budget"]
assert budget["max_chars"] == 4900
assert budget["max_chars"] == 5100
assert budget["budget_char_count"] <= budget["max_chars"]
assert budget["within_budget"] is True
body = packet["task_body"]
Expand Down
8 changes: 4 additions & 4 deletions tests/control_plane/test_heartbeat_envelope_transport.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,13 @@ def test_capture_preserves_full_dispatcher_and_envelope_needs_explicit_opt_in(tm
no_memory = dict(args, reward_memory_enabled=False)
ordinary = build_heartbeat_prompt(**no_memory)
captured_only = build_heartbeat_prompt(**no_memory, decision_output_root=tmp_path)
assert ordinary['interface_budget']['max_chars'] == 4_900
assert captured_only['interface_budget']['max_chars'] == 4_900
assert ordinary['interface_budget']['max_chars'] == 5_100
assert captured_only['interface_budget']['max_chars'] == 5_100
oversized = build_heartbeat_prompt(
**no_memory, decision_output_root=tmp_path, turn_envelope=True,
agent_scopes=[letter * 320 for letter in 'stuv'],
)
assert oversized['interface_budget']['max_chars'] == 5_300
assert oversized['interface_budget']['max_chars'] == 5_500
assert oversized['interface_budget']['within_budget'] is False
for overrides in (dict(turn_instance_id=None), dict(thin=False, full=True),
dict(runtime_profile='codex_app_ssh_goal')):
Expand Down Expand Up @@ -176,7 +176,7 @@ def test_bound_captured_prompt_fits_budget_without_reward_memory(
assert '--reward-memory-reflection-json' not in body
assert str(runtime) in body and str(capture) in body
assert payload['turn_instance_id'] == TURN_ID
assert payload['interface_budget']['max_chars'] == 5_300
assert payload['interface_budget']['max_chars'] == 5_500
assert payload['interface_budget']['within_budget'], payload['interface_budget']
assert len(result.stdout) <= 5_400 # Shipped Agent JSON, not generator metadata.
assert 'using inline ACK argv' in body
Expand Down
4 changes: 2 additions & 2 deletions tests/control_plane/test_heartbeat_prompt_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def test_native_profile_long_routes_retain_one_complete_settlement_contract() ->

@pytest.mark.parametrize("mode,limit", [
("full", 13100), ("compact", 8000), ("brief", 5800),
("thin", 4900), ("visible_goal", 4000),
("thin", 5100), ("visible_goal", 4000),
])
def test_prompt_body_limit_remains_independent_of_json_envelope(mode: str, limit: int) -> None:
for size in (limit, limit + 1):
Expand Down Expand Up @@ -356,7 +356,7 @@ def test_brief_diagnostics_keep_only_the_selected_prompt_command() -> None:

@pytest.mark.parametrize(
("mode", "base_budget"),
[("full", 13100), ("compact", 8000), ("brief", 5800), ("thin", 4900)],
[("full", 13100), ("compact", 8000), ("brief", 5800), ("thin", 5100)],
)
@pytest.mark.parametrize("scope_chars", [0, 320])
@pytest.mark.parametrize("runtime_profile", ["codex_app_heartbeat", "generic_cli"])
Expand Down
Loading