From 6c2e9d404b5d11e2dcd2cc680e3eb498ae1d047d Mon Sep 17 00:00:00 2001 From: DavidHLP Date: Sun, 11 Oct 2026 08:12:01 -0700 Subject: [PATCH 1/6] test: cover equivalent array range adjective definitions --- services/agent/tests/test_boundary_evaluation.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/services/agent/tests/test_boundary_evaluation.py b/services/agent/tests/test_boundary_evaluation.py index 6272d78d8..dc22a8d11 100644 --- a/services/agent/tests/test_boundary_evaluation.py +++ b/services/agent/tests/test_boundary_evaluation.py @@ -1001,6 +1001,8 @@ def test_case_records_provider_response_identity_unknown_when_absent() -> None: "数组越界指下标不在数组的有效范围内。", "Array out of bounds means an index outside the array's valid range.", "数组越界指访问超出数组长度的索引。", + "数组越界是访问数组时使用超出有效索引范围的下标。", + "数组越界指访问超过其合法下标范围的索引。", ]) def test_no_tool_equivalent_range_definitions(text): script = _all_met_script() @@ -1017,6 +1019,9 @@ def test_no_tool_equivalent_range_definitions(text): "数组是一种结构。索引超出有效范围。", "数组越界不是指访问超出该数组有效下标范围。", "数组越界不意味着索引超出有效范围。", + "数组越界不是指访问数组时使用超出有效索引范围的下标。", + "数组越界是不意味着访问超过其合法下标范围的索引。", + "访问数组时使用超出有效索引范围的下标是合法操作。", ]) def test_no_tool_rejects_wrong_denied_and_unrelated_definitions(text): script = _all_met_script() From b2c30d680b764c7ddebb20598f546204bdf70c51 Mon Sep 17 00:00:00 2001 From: DavidHLP Date: Sun, 11 Oct 2026 08:17:34 -0700 Subject: [PATCH 2/6] fix: recognize equivalent array range adjective definitions --- services/agent/src/boundary_evaluation.py | 1 + services/agent/tests/test_boundary_evaluation.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/services/agent/src/boundary_evaluation.py b/services/agent/src/boundary_evaluation.py index 2402d6f45..195c5d2e8 100644 --- a/services/agent/src/boundary_evaluation.py +++ b/services/agent/src/boundary_evaluation.py @@ -1005,6 +1005,7 @@ def _array_range_definition(text: str) -> bool: """ lowered = text.casefold() patterns = ( + r"(?:超出|超过)(?:了)?(?:数组(?:的)?|其)?(?:有效|合法)(?:索引|下标)?范围的(?:索引|下标)", r"(?:索引|下标)(?:落在)?(?:超出|超过|不在)[^。;;!??]{0,16}(?:有效|合法)[^。;;!??]{0,8}范围(?:内)?", r"(?:索引|下标)落在(?:有效|合法)范围(?:之外|以外)", r"(?:访问)?(?:超出|超过)[^。;;!??]{0,12}数组(?:的)?(?:有效|合法)?(?:索引|下标)?(?:范围|边界|长度)", diff --git a/services/agent/tests/test_boundary_evaluation.py b/services/agent/tests/test_boundary_evaluation.py index dc22a8d11..8d637306f 100644 --- a/services/agent/tests/test_boundary_evaluation.py +++ b/services/agent/tests/test_boundary_evaluation.py @@ -1020,7 +1020,7 @@ def test_no_tool_equivalent_range_definitions(text): "数组越界不是指访问超出该数组有效下标范围。", "数组越界不意味着索引超出有效范围。", "数组越界不是指访问数组时使用超出有效索引范围的下标。", - "数组越界是不意味着访问超过其合法下标范围的索引。", + "数组越界不意味着访问超过其合法下标范围的索引。", "访问数组时使用超出有效索引范围的下标是合法操作。", ]) def test_no_tool_rejects_wrong_denied_and_unrelated_definitions(text): From 129cec10fc67a70ca563251cb77410e71321ccfd Mon Sep 17 00:00:00 2001 From: DavidHLP Date: Sun, 11 Oct 2026 08:19:27 -0700 Subject: [PATCH 3/6] fix: preserve negation adjacency in array range grammar --- services/agent/src/boundary_evaluation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/agent/src/boundary_evaluation.py b/services/agent/src/boundary_evaluation.py index 195c5d2e8..acceecf7e 100644 --- a/services/agent/src/boundary_evaluation.py +++ b/services/agent/src/boundary_evaluation.py @@ -1005,7 +1005,7 @@ def _array_range_definition(text: str) -> bool: """ lowered = text.casefold() patterns = ( - r"(?:超出|超过)(?:了)?(?:数组(?:的)?|其)?(?:有效|合法)(?:索引|下标)?范围的(?:索引|下标)", + r"(?:访问数组时(?:使用)?|访问)?(?:超出|超过)(?:了)?(?:数组(?:的)?|其)?(?:有效|合法)(?:索引|下标)?范围的(?:索引|下标)", r"(?:索引|下标)(?:落在)?(?:超出|超过|不在)[^。;;!??]{0,16}(?:有效|合法)[^。;;!??]{0,8}范围(?:内)?", r"(?:索引|下标)落在(?:有效|合法)范围(?:之外|以外)", r"(?:访问)?(?:超出|超过)[^。;;!??]{0,12}数组(?:的)?(?:有效|合法)?(?:索引|下标)?(?:范围|边界|长度)", From 3d36837550b42b7b8ec8e0c6673a20d5c13c5c2e Mon Sep 17 00:00:00 2001 From: DavidHLP Date: Sun, 11 Oct 2026 08:22:48 -0700 Subject: [PATCH 4/6] test: retain sealed V17 costs in range revalidation --- .../tests/test_v16_confirmation_history.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/services/agent/tests/test_v16_confirmation_history.py b/services/agent/tests/test_v16_confirmation_history.py index 863be5211..6c04ad417 100644 --- a/services/agent/tests/test_v16_confirmation_history.py +++ b/services/agent/tests/test_v16_confirmation_history.py @@ -1,6 +1,23 @@ from authorized_budget_period import policy_for +def test_array_range_revalidation_retains_settled_v17_and_unknown_liabilities(): + old = policy_for("acceptance-revalidation-v17") + policy = policy_for("acceptance-revalidation-v18") + history = policy["history"] + assert history["attempts"] == old["history"]["attempts"] + 96 == 1486 + assert history["known_actual_micro_usd"] == old["history"]["known_actual_micro_usd"] + 33723 == 435417 + assert history["known_committed_micro_usd"] == old["history"]["known_committed_micro_usd"] + 864000 == 13160114 + assert history["unknown_attempts"] == old["history"]["unknown_attempts"] == 3 + assert history["unknown_encumbrance_micro_usd"] == old["history"]["unknown_encumbrance_micro_usd"] == 2359296 + assert history["cumulative_limit_micro_usd"] == old["history"]["cumulative_limit_micro_usd"] == 200000000 + assert history["cumulative_attempt_limit"] == history["attempts"] + policy["attempts"] == 1727 + assert policy["lanes"] == old["lanes"] + assert policy["limit_micro_usd"] == old["limit_micro_usd"] + assert (history["known_committed_micro_usd"] + history["unknown_encumbrance_micro_usd"] + + policy["limit_micro_usd"] <= history["cumulative_limit_micro_usd"]) + + def test_confirmation_revalidation_retains_settled_v15_and_unknown_liabilities(): old = policy_for("acceptance-revalidation-v15") policy = policy_for("acceptance-revalidation-v16") From 96091cd5aaa828484fab5ebf84384e5eba7130c9 Mon Sep 17 00:00:00 2001 From: DavidHLP Date: Sun, 11 Oct 2026 08:23:58 -0700 Subject: [PATCH 5/6] fix: bind range revalidation to sealed V17 history --- .../agent/src/authorized_budget_period.py | 14 ++++++++++ services/agent/src/revalidation_history.py | 27 ++++++++++++++++--- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/services/agent/src/authorized_budget_period.py b/services/agent/src/authorized_budget_period.py index ee4f12c3d..3c4daaed9 100644 --- a/services/agent/src/authorized_budget_period.py +++ b/services/agent/src/authorized_budget_period.py @@ -77,6 +77,7 @@ REVALIDATION_V15_POLICY_ID = "acceptance-revalidation-v15" REVALIDATION_V16_POLICY_ID = "acceptance-revalidation-v16" REVALIDATION_V17_POLICY_ID = "acceptance-revalidation-v17" +REVALIDATION_V18_POLICY_ID = "acceptance-revalidation-v18" REVALIDATION_POLICY_IDS = frozenset({REVALIDATION_POLICY_ID, REVALIDATION_V2_POLICY_ID, REVALIDATION_V3_POLICY_ID, REVALIDATION_V4_POLICY_ID, REVALIDATION_V5_POLICY_ID, REVALIDATION_V6_POLICY_ID, REVALIDATION_V7_POLICY_ID, REVALIDATION_V8_POLICY_ID, REVALIDATION_V9_POLICY_ID, REVALIDATION_V10_POLICY_ID, REVALIDATION_V11_POLICY_ID, REVALIDATION_V12_POLICY_ID}) REVALIDATION_V2_HISTORY = MappingProxyType({ "attempts": 164, "known_actual_micro_usd": 42_307, @@ -263,6 +264,17 @@ }) REVALIDATION_POLICY_IDS = REVALIDATION_POLICY_IDS | {REVALIDATION_V17_POLICY_ID} +REVALIDATION_V18_HISTORY = MappingProxyType({ + "attempts": 1486, "known_actual_micro_usd": 435_417, + "known_committed_micro_usd": 13_160_114, + "unknown_attempts": 3, "unknown_encumbrance_micro_usd": 2_359_296, + "cumulative_attempt_limit": 1727, "cumulative_limit_micro_usd": 200_000_000, +}) +REVALIDATION_V18_POLICY = MappingProxyType({ + **REVALIDATION_V17_POLICY, "history": REVALIDATION_V18_HISTORY, +}) +REVALIDATION_POLICY_IDS = REVALIDATION_POLICY_IDS | {REVALIDATION_V18_POLICY_ID} + def policy_for(policy_id: str): if policy_id == POLICY_ID: @@ -301,6 +313,8 @@ def policy_for(policy_id: str): return REVALIDATION_V16_POLICY if policy_id == REVALIDATION_V17_POLICY_ID: return REVALIDATION_V17_POLICY + if policy_id == REVALIDATION_V18_POLICY_ID: + return REVALIDATION_V18_POLICY raise PeriodError("unsupported policy") diff --git a/services/agent/src/revalidation_history.py b/services/agent/src/revalidation_history.py index 78b1566ab..772242f3c 100644 --- a/services/agent/src/revalidation_history.py +++ b/services/agent/src/revalidation_history.py @@ -307,13 +307,30 @@ def _check_unknown_rollover(snapshot, guard, *, predecessor="v2"): } +V17_ROLLOVER_IDENTITY = { + "period_id": "revalidation-v17-20261011", + "identity": "299e0ae45ffc4a11bb689fb46265541b", + "config_sha256": "a393fa8435ab341583fc4bb2f2a9f77c10446778dca68690fe79f8f6eb68c0b3", + "policy_id": "acceptance-revalidation-v17", +} +V17_ROLLOVER_SHA256 = { + "budget.sqlite3": "1e431283a534f4ebbcbd4b7968e88ec92dfadb3e7d30eca80d150af8bab8d151", + "binding.json": "8e05a5f29bfd7ab0c10de6a788d7d343b9848b7560cc35d91654042f6275f0e5", + "dav58-increment-299e0ae45ffc4a11bb689fb46265541b.json": "012714452a1cfc45e83ab0756f5193af6a1e8ba1c07c42095a32d6dec9c83b7c", +} + + def _validate_rollover_history(sources, *, settled_policy="v1"): - from authorized_budget_period import REVALIDATION_V14_HISTORY, REVALIDATION_V15_HISTORY, REVALIDATION_V16_HISTORY, REVALIDATION_V17_HISTORY + from authorized_budget_period import REVALIDATION_V14_HISTORY, REVALIDATION_V15_HISTORY, REVALIDATION_V16_HISTORY, REVALIDATION_V17_HISTORY, REVALIDATION_V18_HISTORY from authorized_budget_period import PeriodError, PeriodIdentity, REVALIDATION_V2_HISTORY, REVALIDATION_V4_HISTORY, REVALIDATION_V5_HISTORY, REVALIDATION_V6_HISTORY, REVALIDATION_V7_HISTORY, REVALIDATION_V8_HISTORY, REVALIDATION_V9_HISTORY, REVALIDATION_V10_HISTORY, REVALIDATION_V11_HISTORY, REVALIDATION_V12_HISTORY, _parent, _file from model_budget import ModelBudget, authorization_slot from dav58_live_guard import IncrementalGuard - if settled_policy == "v16": + if settled_policy == "v17": + original = _validate_rollover_history(sources, settled_policy="v16") + identity, fingerprints = V17_ROLLOVER_IDENTITY, V17_ROLLOVER_SHA256 + totals, history = (96, 33_723, 864_000), REVALIDATION_V18_HISTORY + elif settled_policy == "v16": original = _validate_rollover_history(sources, settled_policy="v15") identity, fingerprints = V16_ROLLOVER_IDENTITY, V16_ROLLOVER_SHA256 totals, history = (104, 35_977, 932_400), REVALIDATION_V17_HISTORY @@ -401,7 +418,7 @@ def _validate_rollover_history(sources, *, settled_policy="v1"): try: # Validate sealed receipts without making the permanently halted journal resumable. receipt_view = guard - if settled_policy in {"v13", "v14", "v15", "v16"}: + if settled_policy in {"v13", "v14", "v15", "v16", "v17"}: if guard.get("halted") is not True: raise PeriodError("previous guard must be permanently halted") receipt_view = {**guard, "halted": False} @@ -414,10 +431,12 @@ def _validate_rollover_history(sources, *, settled_policy="v1"): def validate_history(sources, *, policy_id="acceptance-revalidation-v1"): - from authorized_budget_period import REVALIDATION_V13_POLICY_ID, REVALIDATION_V14_POLICY_ID, REVALIDATION_V15_POLICY_ID, REVALIDATION_V16_POLICY_ID, REVALIDATION_V17_POLICY_ID + from authorized_budget_period import REVALIDATION_V13_POLICY_ID, REVALIDATION_V14_POLICY_ID, REVALIDATION_V15_POLICY_ID, REVALIDATION_V16_POLICY_ID, REVALIDATION_V17_POLICY_ID, REVALIDATION_V18_POLICY_ID from authorized_budget_period import PeriodError, REVALIDATION_HISTORY, _parent, _file from authorized_budget_period import REVALIDATION_POLICY_ID, REVALIDATION_V2_POLICY_ID, REVALIDATION_V3_POLICY_ID, REVALIDATION_V4_POLICY_ID, REVALIDATION_V5_POLICY_ID, REVALIDATION_V6_POLICY_ID, REVALIDATION_V7_POLICY_ID, REVALIDATION_V8_POLICY_ID, REVALIDATION_V9_POLICY_ID, REVALIDATION_V10_POLICY_ID, REVALIDATION_V11_POLICY_ID, REVALIDATION_V12_POLICY_ID + if policy_id == REVALIDATION_V18_POLICY_ID: + return _validate_rollover_history(sources, settled_policy="v17") if policy_id == REVALIDATION_V17_POLICY_ID: return _validate_rollover_history(sources, settled_policy="v16") if policy_id == REVALIDATION_V16_POLICY_ID: From 3730b74140a107265d0cebc44a988c644bbc45e7 Mon Sep 17 00:00:00 2001 From: DavidHLP Date: Sun, 11 Oct 2026 08:24:44 -0700 Subject: [PATCH 6/6] docs: bind array range revalidation to preserved history --- docs/DEVELOPMENT.md | 7 +++++++ services/agent/data/repository_corpus_manifest.json | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md index 83e14fb49..58f00eb15 100644 --- a/docs/DEVELOPMENT.md +++ b/docs/DEVELOPMENT.md @@ -499,6 +499,7 @@ The same explicitly authorized rollover contract applies to the later supported | `acceptance-revalidation-v15` | Settled V14, including its invalid-JSON failure | | `acceptance-revalidation-v16` | Settled V15, including the stale-confirmation U03 failure | | `acceptance-revalidation-v17` | Settled V16, including the cancellation-state U03 failure | +| `acceptance-revalidation-v18` | Settled V17, including the equivalent-array-definition boundary failure | Before preparation, retain the predecessor ledger, binding and guard at their pinned fingerprints and preserve the entire earlier history chain. The selected policy's @@ -549,6 +550,12 @@ numeric HTTP/Result failure diagnostics do not establish a root cause or a pass. The same cumulative USD200 ceiling, three unknown liabilities and purpose/token caps apply. Establish fresh acceptance for the changed candidate. +V18 retains the permanently halted V17 ledger, binding and guard for the bounded +array-range grammar correction. Preserve the original failed boundary result and +settled costs; local grammar regressions do not replace genuine model acceptance. +The same cumulative USD200 ceiling, three unknown liabilities and purpose/token +caps apply. Establish fresh acceptance for the changed candidate. + Issue the evidence-bound U02 gate only after those inputs validate. Gate artifact references are relative to the private directory containing the gate; place the referenced artifacts there: diff --git a/services/agent/data/repository_corpus_manifest.json b/services/agent/data/repository_corpus_manifest.json index 57f7d9eb7..31974ac2c 100644 --- a/services/agent/data/repository_corpus_manifest.json +++ b/services/agent/data/repository_corpus_manifest.json @@ -29,8 +29,8 @@ }, { "doc_id": "repository-development", - "version": "sha256-f34f2a60cef2672d30a8208f0e2ebcc3a897eccd936808f69c7aff6375802379", - "chunk_id": "repository-development:sha256-f34f2a60cef2672d30a8208f0e2ebcc3a897eccd936808f69c7aff6375802379:1", + "version": "sha256-afbb26c451fbaeb42cc30c0b897c4c6115eeb33a9216a1020a0410c258c89185", + "chunk_id": "repository-development:sha256-afbb26c451fbaeb42cc30c0b897c4c6115eeb33a9216a1020a0410c258c89185:1", "source_path": "docs/DEVELOPMENT.md", "access_scope": "repository-public", "sample_kind": "real",