From a676f67706e912a895e6c54463b5cf9ecb6199cf Mon Sep 17 00:00:00 2001 From: DavidHLP Date: Sun, 11 Oct 2026 04:45:20 -0700 Subject: [PATCH 1/3] test: retain settled V13 costs in integrated acceptance --- .../agent/tests/test_v14_settled_history.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 services/agent/tests/test_v14_settled_history.py diff --git a/services/agent/tests/test_v14_settled_history.py b/services/agent/tests/test_v14_settled_history.py new file mode 100644 index 000000000..2b145f0d6 --- /dev/null +++ b/services/agent/tests/test_v14_settled_history.py @@ -0,0 +1,18 @@ +from authorized_budget_period import policy_for + + +def test_integrated_acceptance_retains_settled_costs_and_old_unknowns(): + previous = policy_for("acceptance-revalidation-v13") + policy = policy_for("acceptance-revalidation-v14") + history, old = policy["history"], previous["history"] + assert history["attempts"] == old["attempts"] + 98 == 1086 + assert history["known_actual_micro_usd"] == old["known_actual_micro_usd"] + 33738 + assert history["known_committed_micro_usd"] == old["known_committed_micro_usd"] + 877200 + assert history["unknown_attempts"] == old["unknown_attempts"] == 3 + assert history["unknown_encumbrance_micro_usd"] == old["unknown_encumbrance_micro_usd"] == 2359296 + assert history["cumulative_limit_micro_usd"] == old["cumulative_limit_micro_usd"] == 200000000 + assert history["cumulative_attempt_limit"] == history["attempts"] + policy["attempts"] + assert policy["lanes"] == previous["lanes"] + assert policy["limit_micro_usd"] == previous["limit_micro_usd"] + assert (history["known_committed_micro_usd"] + history["unknown_encumbrance_micro_usd"] + + policy["limit_micro_usd"] <= history["cumulative_limit_micro_usd"]) From 5f4a4f418e2a9942eeb677dd93a099881b5d44ca Mon Sep 17 00:00:00 2001 From: DavidHLP Date: Sun, 11 Oct 2026 04:46:51 -0700 Subject: [PATCH 2/3] fix: bind integrated acceptance to sealed V13 history --- docs/DEVELOPMENT.md | 7 ++++++ .../data/repository_corpus_manifest.json | 4 ++-- .../agent/src/authorized_budget_period.py | 14 +++++++++++ services/agent/src/revalidation_history.py | 24 +++++++++++++++++-- 4 files changed, 45 insertions(+), 4 deletions(-) diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md index 254a23ed8..b0863be1b 100644 --- a/docs/DEVELOPMENT.md +++ b/docs/DEVELOPMENT.md @@ -493,6 +493,7 @@ The same explicitly authorized rollover contract applies to the later supported | `acceptance-revalidation-v11` | V10 | | `acceptance-revalidation-v12` | V11 | | `acceptance-revalidation-v13` | V12, including its retained unknown request | +| `acceptance-revalidation-v14` | Settled V13 on the integrated U03 candidate | Before preparation, retain the predecessor ledger, binding and guard at their pinned fingerprints and preserve the entire earlier history chain. The selected policy's @@ -519,6 +520,12 @@ V12 remains permanently halted; V13 starts its complete fresh prefix on the newly bound candidate. Unknown settlement needs verifiable provider usage and must not be inferred from a balance change. +V14 continues only within the owner's cumulative USD200 authorization. Its sealed +V13 predecessor must have no unsettled or newly unknown requests; all known costs, +commitments and inherited unknown liabilities remain cumulative. Failed protocol +evidence stays in the predecessor, while the integrated candidate receives a fresh +complete acceptance prefix without changing the existing purpose or token limits. + 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 e28739e4e..9ed74c1d5 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-358501dfb1501c23655cad1f7c246422be91cee82c65bcd4c1f0cda2f3e2ea6b", - "chunk_id": "repository-development:sha256-358501dfb1501c23655cad1f7c246422be91cee82c65bcd4c1f0cda2f3e2ea6b:1", + "version": "sha256-24c1cea137aab6834ef530d75fdf95984ebbe55bafc5322d6173a6c65e8a5a89", + "chunk_id": "repository-development:sha256-24c1cea137aab6834ef530d75fdf95984ebbe55bafc5322d6173a6c65e8a5a89:1", "source_path": "docs/DEVELOPMENT.md", "access_scope": "repository-public", "sample_kind": "real", diff --git a/services/agent/src/authorized_budget_period.py b/services/agent/src/authorized_budget_period.py index 2db336999..ffd73cf97 100644 --- a/services/agent/src/authorized_budget_period.py +++ b/services/agent/src/authorized_budget_period.py @@ -73,6 +73,7 @@ REVALIDATION_V11_POLICY_ID = "acceptance-revalidation-v11" REVALIDATION_V12_POLICY_ID = "acceptance-revalidation-v12" REVALIDATION_V13_POLICY_ID = "acceptance-revalidation-v13" +REVALIDATION_V14_POLICY_ID = "acceptance-revalidation-v14" 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, @@ -215,6 +216,17 @@ }) REVALIDATION_POLICY_IDS = REVALIDATION_POLICY_IDS | {REVALIDATION_V13_POLICY_ID} +REVALIDATION_V14_HISTORY = MappingProxyType({ + "attempts": 1086, "known_actual_micro_usd": 296_653, + "known_committed_micro_usd": 9_568_514, + "unknown_attempts": 3, "unknown_encumbrance_micro_usd": 2_359_296, + "cumulative_attempt_limit": 1327, "cumulative_limit_micro_usd": 200_000_000, +}) +REVALIDATION_V14_POLICY = MappingProxyType({ + **REVALIDATION_V13_POLICY, "history": REVALIDATION_V14_HISTORY, +}) +REVALIDATION_POLICY_IDS = REVALIDATION_POLICY_IDS | {REVALIDATION_V14_POLICY_ID} + def policy_for(policy_id: str): if policy_id == POLICY_ID: @@ -245,6 +257,8 @@ def policy_for(policy_id: str): return REVALIDATION_V12_POLICY if policy_id == REVALIDATION_V13_POLICY_ID: return REVALIDATION_V13_POLICY + if policy_id == REVALIDATION_V14_POLICY_ID: + return REVALIDATION_V14_POLICY raise PeriodError("unsupported policy") diff --git a/services/agent/src/revalidation_history.py b/services/agent/src/revalidation_history.py index b9ec7b65a..dcf489b26 100644 --- a/services/agent/src/revalidation_history.py +++ b/services/agent/src/revalidation_history.py @@ -256,12 +256,30 @@ def _check_unknown_rollover(snapshot, guard, *, predecessor="v2"): } +V13_ROLLOVER_IDENTITY = { + "period_id": "revalidation-v13-20261011", + "identity": "10a5b715a8dc4a6b96056116a789abea", + "config_sha256": "ecb6bdfacb4d24280b0e73cdf863932c95804b2276f0b272f714933eda67a885", + "policy_id": "acceptance-revalidation-v13", +} +V13_ROLLOVER_SHA256 = { + "budget.sqlite3": "643852a26d70b7a7e40b664cfdd1f147e7e2a7bff9ee79e250d04dbcc435a1cc", + "binding.json": "65277536052f174cd083b97b200e6e792679d741a3f0a345d7209afc1ad20de7", + "dav58-increment-10a5b715a8dc4a6b96056116a789abea.json": "a4f08105519da4c96c258625676b92d428028066da3e230c8a1e7bad2a8607a8", +} + + def _validate_rollover_history(sources, *, settled_policy="v1"): + from authorized_budget_period import REVALIDATION_V14_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 == "v11": + if settled_policy == "v13": + original = _validate_unknown_rollover_history(sources, predecessor="v12") + identity, fingerprints = V13_ROLLOVER_IDENTITY, V13_ROLLOVER_SHA256 + totals, history = (98, 33_738, 877_200), REVALIDATION_V14_HISTORY + elif settled_policy == "v11": original = _validate_rollover_history(sources, settled_policy="v10") identity, fingerprints = V11_ROLLOVER_IDENTITY, V11_ROLLOVER_SHA256 totals, history = (84, 23_714, 806_400), REVALIDATION_V12_HISTORY @@ -340,10 +358,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 + from authorized_budget_period import REVALIDATION_V13_POLICY_ID, REVALIDATION_V14_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_V14_POLICY_ID: + return _validate_rollover_history(sources, settled_policy="v13") if policy_id == REVALIDATION_V13_POLICY_ID: return _validate_unknown_rollover_history(sources, predecessor="v12") if policy_id == REVALIDATION_V2_POLICY_ID: From 2342962a509969ccbf350e6c27203e8edfa04509 Mon Sep 17 00:00:00 2001 From: DavidHLP Date: Sun, 11 Oct 2026 04:54:29 -0700 Subject: [PATCH 3/3] fix: validate permanently halted history without resuming it --- services/agent/src/revalidation_history.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/services/agent/src/revalidation_history.py b/services/agent/src/revalidation_history.py index dcf489b26..a2d4e690c 100644 --- a/services/agent/src/revalidation_history.py +++ b/services/agent/src/revalidation_history.py @@ -349,7 +349,13 @@ def _validate_rollover_history(sources, *, settled_policy="v1"): or snapshot["unknown_usage_attempts"] or snapshot["unsettled_attempts"]): raise PeriodError("previous period must be sealed with all liabilities retained") try: - IncrementalGuard._validate_resume(guard, expected.identity, expected.config_sha256, budget.policy, budget) + # Validate sealed receipts without making the permanently halted journal resumable. + receipt_view = guard + if settled_policy == "v13": + if guard.get("halted") is not True: + raise PeriodError("previous guard must be permanently halted") + receipt_view = {**guard, "halted": False} + IncrementalGuard._validate_resume(receipt_view, expected.identity, expected.config_sha256, budget.policy, budget) except ValueError as error: raise PeriodError("sealed rollover receipts invalid") from error return {"sources": sources, "sha256": {**original["sha256"], **hashes},