Skip to content

Commit b6b778e

Browse files
committed
fix: recover proof-bound dual drift
1 parent 3d9409c commit b6b778e

12 files changed

Lines changed: 299 additions & 51 deletions

File tree

‎README.md‎

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -591,10 +591,14 @@ remained outside the marker, setup accepts the combined state only after the
591591
completed recovery evidence reconstructs the marker-era Approval and Core
592592
documents. It reverses only the evidence-bound owner and signer fields in
593593
memory, then requires both reconstructed canonical digests to equal the
594-
marker. The realized current documents are journaled, the TTL policy is
595-
normalized, and owner/Core convergence is rechecked idempotently. Missing
596-
Core-OIDC agreement, incomplete evidence, or unrelated drift fails before
597-
setup creates its upgrade journal or changes managed state.
594+
marker. Historical marker matching treats only the fixed mandatory
595+
approval-purpose set as order-insensitive; it may reconstruct that set's
596+
serialized order to reproduce the retained digest, but any added, removed,
597+
duplicated, or changed purpose fails closed. The realized current documents
598+
are journaled, the TTL policy is normalized, and owner/Core convergence is
599+
rechecked idempotently. Missing Core-OIDC agreement, incomplete evidence, or
600+
unrelated drift fails before setup creates its upgrade journal or changes
601+
managed state.
598602

599603

600604
Git tag `v0.1.23` reached the staging workflow, but CI stopped before npm

‎RELEASE_MANIFEST.json‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -538,8 +538,8 @@
538538
"release_inputs": {
539539
"README.md": {
540540
"path": "README.md",
541-
"sha256": "04c40c68406ab67f430cb1d3eaf5adb702137d015ff4acfc0dd8fe68110c50b3",
542-
"size": 46300
541+
"sha256": "fb8b10a622b64f024462047ba82708cc090270b27f13e9f94e045c8208ad99b8",
542+
"size": 46552
543543
},
544544
"REQUIREMENTS_STATUS.md": {
545545
"path": "REQUIREMENTS_STATUS.md",
@@ -618,14 +618,14 @@
618618
},
619619
"scripts/verify_release.py": {
620620
"path": "scripts/verify_release.py",
621-
"sha256": "ae5cc17c04aa8d2e3895d6ae5e2408b947a06a25ce33d755e01048d694f143a9",
621+
"sha256": "119c226d6f87f100e2e41e4c974339417859b6f6c1d5212896ec799898541e3b",
622622
"size": 56697
623623
}
624624
},
625625
"release_source_tree": {
626626
"algorithm": "sha256(path NUL bytes NUL)",
627627
"path": "src",
628-
"sha256": "9baef70ed843decde60e73ce6eb22718a29754c6087177672f5c5c6d1633e212"
628+
"sha256": "e00067bb4365b9089d45af45a726ff3d4f080baca6b39f3e2e4a017226857a10"
629629
},
630630
"runtime": {
631631
"implementation": "CPython",

‎docs/ARCHITECTURE.md‎

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -925,12 +925,15 @@ Approval/Core policy, one active canonical owner binding, target credential
925925
state, and one immutable adoption audit jointly reproduce the exact marker-era
926926
source and current realized digests. Reconstructing the marker-era source
927927
reverses only the exact evidence-bound Approval and Core owner/signer policy
928-
fields. The reconstruction write is the first mutation and changes no
929-
authority. Its strict evidence is revalidated after process loss. A resumed
930-
upgrade journal rechecks the exact two-signer custody and matching current
931-
Core/Core-OIDC policy immediately before the Approval TTL compare-and-swap;
932-
missing, additional, ambiguous, or drifted evidence leaves Approval unchanged
933-
and fails closed.
928+
fields. Because the historical policy writer serialized a `frozenset`, marker
929+
matching may search only permutations of the exact mandatory approval-purpose
930+
set to recover its former byte order. Added, removed, duplicated, or changed
931+
purposes cannot enter that path. The reconstruction write is the first
932+
mutation and changes no authority. Its strict evidence is revalidated after
933+
process loss. A resumed upgrade journal rechecks the exact two-signer custody
934+
and matching current Core/Core-OIDC policy immediately before the Approval TTL
935+
compare-and-swap; missing, additional, ambiguous, or drifted evidence leaves
936+
Approval unchanged and fails closed.
934937

935938
That same v0.1.50→v0.1.51 boundary preserves the exact published v0.1.50
936939
Approval policy with its 300-second generic request TTL and absent

‎docs/SCHEMAS_INTERFACES.md‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -879,7 +879,11 @@ Approval and Core schemas, and the exact source/target identity and signer
879879
fields needed to reconstruct both marker-era documents. The inverse TTL
880880
comparison may remove only the known communication-scope field and restore the
881881
published 300-second generic value. The reconstructed Approval and Core
882-
digests must equal the marker before upgrade journal v3 is created. Every
882+
digests must equal the marker before upgrade journal v3 is created. Historical
883+
`allowed_purposes` ordering is not authority-bearing: marker matching may
884+
permute only the exact fixed mandatory set to reproduce either retained
885+
digest. Set membership, cardinality, all other fields, and the digest remain
886+
exact; any added, removed, duplicated, or changed purpose fails closed. Every
883887
initial or resumed attempt repeats the terminal journal,
884888
exact-single-active-owner, adoption-audit, target-credential, and
885889
signer-custody checks. An upgrade-journal resume also requires the current Core

‎docs/implementation-guide.md‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,11 @@ Approval unchanged.
429429
Setup reconstructs the exact marker-era Approval and Core documents by
430430
reversing only the recovery-evidence-bound owner and signer fields, applies the
431431
bounded inverse TTL comparison, and requires both reconstructed digests to
432-
equal the marker. It parses the retained 3600-second source policy without
432+
equal the marker. The old writer emitted the fixed mandatory
433+
`allowed_purposes` set in process-dependent order. Setup may therefore try only
434+
permutations of that exact set when reproducing the retained Approval/Core
435+
digests. It never accepts different membership, duplicates, or unrelated
436+
policy drift. Setup parses the retained 3600-second source policy without
433437
writing and admits only that exact legacy TTL shape. Only then does it journal
434438
the realized current documents, normalize the TTL policy, and recheck the
435439
owner command and Core policy as idempotent

‎docs/superpowers/specs/2026-08-09-agentnet-canonical-owner-recovery-design.md‎

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,15 @@ Before creating the setup upgrade journal, setup may reverse only the
7777
documented recovery transformations in memory: the TTL fields are restored to
7878
the published v0.1.50 shape, while the Approval and Core owner/signer policy
7979
fields are restored from the exact recovery evidence. The reconstructed
80-
Approval and Core digests must equal the retained marker. The current Core OIDC
81-
sidecar must equal Core, and the realized target signer, domain, target
82-
principal, and fixed setup request must agree with the recovery evidence. This
83-
reconstruction writes only a strict terminal evidence journal when the
84-
original journal is absent; it does not change authority.
80+
Approval and Core digests must equal the retained marker. The historical writer
81+
serialized the fixed mandatory approval-purpose `frozenset` in
82+
process-dependent order. Digest reconstruction may therefore try only
83+
permutations of that exact set; membership, cardinality, every other field, and
84+
both retained digests remain exact. The current Core OIDC sidecar must equal
85+
Core, and the realized target signer, domain, target principal, and fixed setup
86+
request must agree with the recovery evidence. This reconstruction writes only
87+
a strict terminal evidence journal when the original journal is absent; it
88+
does not change authority.
8589

8690
An incomplete or malformed recovery journal, a wrong domain or target,
8791
unverifiable signer state, extra configuration drift, Core/Core-OIDC
Binary file not shown.
Binary file not shown.

‎evidence/local/2026-08-09-v0.1.51/manifest.json‎

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,30 @@
22
"artifacts": [
33
{
44
"path": "evidence/local/2026-08-09-v0.1.51/artifacts/agentnet-0.1.51.tar.gz",
5-
"sha256": "46064f63be8e8b0d2b0cfe2b5d118c0d6749e40045575ebd3284eabdd15c24fd"
5+
"sha256": "c557316e5bfe8ae1d3332390754ed74e73da9d1e06508dded5c37825cefa4897"
66
},
77
{
88
"path": "evidence/local/2026-08-09-v0.1.51/artifacts/agentnet-0.1.51-py3-none-any.whl",
9-
"sha256": "ebee10aecef0bcb947d6facfad83adb8f0deee9934a98cd7f02fa0aa002d9d47"
9+
"sha256": "615dd15d58da962d21727a1852eec320ba2a95e5bf6fc2e80a09f376b61878fb"
1010
}
1111
],
1212
"change_boundary": "Candidate 0.1.51 recognizes only the exact retained live state where completed canonical-owner recovery changed the Approval and Core owner/signer policy while the one-hour Approval TTL hotfix remained outside the retained v0.1.50 marker. Marker-relative recovery reverses only evidence-bound source/target principal and signer fields in current typed Approval/Core documents, requires both reconstructed canonical digests to equal the marker, and requires the current Core OIDC sidecar to equal Core. Journal-less recovery additionally requires one active canonical owner binding, one matching adoption audit, exact target credential state, and exactly two fixed-custody signer keys; every resumed write revalidates marker/current digests, Core/Core-OIDC agreement, database evidence, and signer custody before mutation.",
1313
"commands": [
1414
{
1515
"command": "PYTHONDONTWRITEBYTECODE=1 UV_CACHE_DIR=/tmp/uv-cache uv run pytest -q tests/approval/test_approval_cli.py tests/approval/test_webauthn_service.py tests/operations/test_canonical_owner_recovery.py tests/operations/test_server_setup_recovery.py tests/authorization/test_communication_scope_service.py tests/production/test_release_v7_schema.py tests/integration/test_collaboration_scope_messaging.py tests/production/test_postgres_runtime.py::test_keeper_failure_blocks_protected_work_until_recovery_state_is_published tests/production/test_postgres_runtime.py::test_expired_keeper_lease_recovers_on_next_operation_with_higher_fence tests/production/test_postgres_runtime.py::test_expired_keeper_recovery_starts_new_background_keeper",
16-
"result": "PASS: 281 passed"
16+
"result": "PASS: 287 passed"
1717
},
1818
{
1919
"command": "PYTHONDONTWRITEBYTECODE=1 UV_CACHE_DIR=/tmp/uv-cache uv run pytest -q tests/authorization/test_scope_harness_replacement.py tests/authorization/test_communication_scope_service.py tests/integration/test_collaboration_scope_messaging.py tests/cli/test_server_agent_activation.py",
2020
"result": "PASS: 62 passed"
2121
},
2222
{
2323
"command": "PYTHONDONTWRITEBYTECODE=1 UV_CACHE_DIR=/tmp/uv-cache uv run --extra test pytest -q --ignore=tests/adapters/test_installed_live_inference.py --ignore=tests/adapters/test_subprocess_lifecycle.py --ignore=tests/components/test_bakeoff_evidence.py --ignore=tests/conformance/test_release_manifest.py",
24-
"result": "PASS: 2269 passed and 22 expected platform/dedicated-PostgreSQL skips"
24+
"result": "PASS: 2275 passed and 22 expected platform/dedicated-PostgreSQL skips"
2525
},
2626
{
2727
"command": "SOURCE_DATE_EPOCH=1580601600 PYTHONDONTWRITEBYTECODE=1 UV_CACHE_DIR=/tmp/uv-cache UV_LINK_MODE=copy uv build --offline --no-build-isolation twice",
28-
"result": "PASS: two independent builds are byte-identical; sdist sha256 46064f63be8e8b0d2b0cfe2b5d118c0d6749e40045575ebd3284eabdd15c24fd; wheel sha256 ebee10aecef0bcb947d6facfad83adb8f0deee9934a98cd7f02fa0aa002d9d47"
28+
"result": "PASS: two independent builds are byte-identical; sdist sha256 c557316e5bfe8ae1d3332390754ed74e73da9d1e06508dded5c37825cefa4897; wheel sha256 615dd15d58da962d21727a1852eec320ba2a95e5bf6fc2e80a09f376b61878fb"
2929
},
3030
{
3131
"command": "PYTHONDONTWRITEBYTECODE=1 UV_CACHE_DIR=/tmp/uv-cache uv run python -B -I scripts/ci/packaged_local_communication_e2e.py run --package-root <installed package> --launcher <installed agentnet.mjs> --workspace <empty unrelated workspace>",
@@ -61,14 +61,14 @@
6161
},
6262
{
6363
"command": "PYTHONDONTWRITEBYTECODE=1 UV_CACHE_DIR=/tmp/uv-cache uv run agentnet verify",
64-
"result": "PASS: 2296 passed and 22 expected platform/dedicated-PostgreSQL skips"
64+
"result": "PASS: 2302 passed and 22 expected platform/dedicated-PostgreSQL skips"
6565
},
6666
{
6767
"command": "npm run check",
68-
"result": "PASS: source plus generations 1 and 2 each reported 2296 passed and 22 expected platform/dedicated-PostgreSQL skips; exact-endpoint routing gate and packaged v0.1.45 user journey passed; excludes installed-live-inference, subprocess-lifecycle, and bake-off-evidence; two installed-harness pin failures remain non-green and were not rerun or waived"
68+
"result": "PASS: source plus generations 1 and 2 each reported 2302 passed and 22 expected platform/dedicated-PostgreSQL skips; exact-endpoint routing gate and packaged v0.1.45 user journey passed; excludes installed-live-inference, subprocess-lifecycle, and bake-off-evidence; two installed-harness pin failures remain non-green and were not rerun or waived"
6969
}
7070
],
71-
"evaluated_at": "2026-08-12T13:39:04Z",
71+
"evaluated_at": "2026-08-12T16:41:11Z",
7272
"execution_context": {
7373
"callback_incident": "Exact-commit GitHub workflow and server PostgreSQL results are included; no callback result is claimed",
7474
"local_retry_incident": "No retry is counted as evidence for this corrective tree. The final exact focused lane, broad lane, release verifier, release-manifest contract, recursive npm check, and source agentnet verify completed green with the recorded counts.",
@@ -84,7 +84,7 @@
8484
"source_revision": "4e8ebd72d6b5e39550e438816abb1e2d30a5326a"
8585
},
8686
"release_certified": false,
87-
"release_source_tree_sha256": "9baef70ed843decde60e73ce6eb22718a29754c6087177672f5c5c6d1633e212",
87+
"release_source_tree_sha256": "e00067bb4365b9089d45af45a726ff3d4f080baca6b39f3e2e4a017226857a10",
8888
"run_id": "2026-08-09-v0.1.51-local-package-candidate",
8989
"scope": "v0_1_51_dual_policy_drift_journalless_owner_recovery_candidate",
9090
"source_revision": "Working-tree corrective candidate bound by release_source_tree_sha256; exact-commit CI, disposable PostgreSQL evidence, and live convergence must be refreshed after commit",

‎scripts/verify_release.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,7 +1022,7 @@ def _verify_evidence_ledgers(manifest: dict[str, Any], root: Path, failures: lis
10221022
npm_result = command_results.get("npm run check", "")
10231023
if (
10241024
not npm_result.startswith("PASS:")
1025-
or "2296 passed and 22 expected" not in npm_result
1025+
or "2302 passed and 22 expected" not in npm_result
10261026
or "source plus generations 1 and 2" not in npm_result
10271027
or "exact-endpoint routing gate" not in npm_result
10281028
or "packaged v0.1.45 user journey" not in npm_result
@@ -1069,7 +1069,7 @@ def _verify_evidence_ledgers(manifest: dict[str, Any], root: Path, failures: lis
10691069
"uv run pytest -q "
10701070
)
10711071
and all(path in command.split() for path in required_focused_paths)
1072-
and result == "PASS: 281 passed"
1072+
and result == "PASS: 287 passed"
10731073
for command, result in command_results.items()
10741074
):
10751075
failures.append("0.1.51 focused release-blocker evidence is incomplete")

0 commit comments

Comments
 (0)