From 02d75dcc74bc2f504c5945ee66cd04fe2d0bec40 Mon Sep 17 00:00:00 2001 From: codex Date: Tue, 3 Nov 2026 14:16:08 +0100 Subject: [PATCH] Make the platform test suite collect and finish; refresh the admission baseline. Fix two collection errors and the order-dependent secrets-engine import. Proofs whose prebuilt binaries are absent now skip with a reason. The admission baseline takes three digests from reviewed rapp-postgres changes. Nine drifted assertions remain, recorded in ADHOC-2026-11-03. Co-Authored-By: Claude Opus 5.5 Assistant: claude-code Assistant-Model: opus Assistant-Process: 236506@bnt-lap001 Assistant-Session: 09087018-91e1-48c5-ab2f-acfbb62c92e4 --- WORK-RECORDS.md | 2 + assurance/admission-baseline.json | 6 +- tests/conftest.py | 16 +++++ tests/task_execution_source_servers.py | 8 ++- tests/task_execution_trusted_servers.py | 7 ++ tests/test_digest_retention.py | 7 +- tests/test_task_execution_mediator.py | 2 + tests/test_task_execution_trusted_whole.py | 2 + ...test_verify_informed_decision_requester.py | 11 +++- workplans/ADHOC-2026-11-03.md | 66 ++++++++++++++++++- 10 files changed, 118 insertions(+), 9 deletions(-) create mode 100644 tests/conftest.py diff --git a/WORK-RECORDS.md b/WORK-RECORDS.md index e77b60d..08b1018 100644 --- a/WORK-RECORDS.md +++ b/WORK-RECORDS.md @@ -59,6 +59,8 @@ | task | RPF-WP-ADHOC-2026-10-19-T02 | done | — | workplans/ADHOC-2026-10-19.md | | task | RPF-WP-ADHOC-2026-10-19-T03 | done | — | workplans/ADHOC-2026-10-19.md | | task | RPF-WP-ADHOC-2026-11-03-T01 | done | — | workplans/ADHOC-2026-11-03.md | +| task | RPF-WP-ADHOC-2026-11-03-T02 | done | — | workplans/ADHOC-2026-11-03.md | +| task | RPF-WP-ADHOC-2026-11-03-T03 | done | — | workplans/ADHOC-2026-11-03.md | | task | RPF-WP-0015-T01 | done | — | workplans/RPF-WP-0015-audit-core-custody-and-recovery-coordination.md | | task | RPF-WP-0015-T02 | done | — | workplans/RPF-WP-0015-audit-core-custody-and-recovery-coordination.md | | task | RPF-WP-0015-T03 | wait | — | workplans/RPF-WP-0015-audit-core-custody-and-recovery-coordination.md | diff --git a/assurance/admission-baseline.json b/assurance/admission-baseline.json index ac76005..93b5058 100644 --- a/assurance/admission-baseline.json +++ b/assurance/admission-baseline.json @@ -96,8 +96,8 @@ "rapp-postgres/consumers/tenant-engine.yaml": "92f36d587f001c86ff401aedd25cb49fa171d49e000b0a6ab551e182e5c11448", "railiance-platform/tools/verify_apps_pg_capacity.py": "b571ec63b0a7501dabba37a84af9d2cfcb7737ed891a7ea2ab05c54010b1893e", "railiance-platform/assurance/placement-owners.json": "e71037f868e3264d43ff5c42511558272a89926dc8dc2f7ee952e018020b4891", - "rapp-postgres/scripts/render_consumers.py": "2dcfd68f94a3d6c7e1072c4a55a497b1697eab30acaecae53865c9b1a596773a", - "rapp-postgres/helm/platform-pg-cluster.yaml": "461da0d43e61a4ddca29d6e98080b8b1642bd3303f3395da1b0beb28775c2c5c", - "rapp-postgres/helm/platform-pg-2-cluster.yaml": "06b92a76189b1a33d1eee3f5c835a3e94269ad7b040383c04e8028c2c3fe766a" + "rapp-postgres/scripts/render_consumers.py": "5d83e29e5ec675b3c78c0129d9e12213b624146f5883534a7e5c99aaaa057f61", + "rapp-postgres/helm/platform-pg-cluster.yaml": "f3101cfed2bdaebef2732c1c13ba44940122cb057366950eed744cd1ec4e6380", + "rapp-postgres/helm/platform-pg-2-cluster.yaml": "c8411681251cd2e48d4e251170adee79689811836156cd2f89d0e663db68ccf8" } } diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..fc96ad9 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,16 @@ +"""Shared test path setup. + +The task-execution fixture proofs import the sibling `secrets-engine` source +checkout. Its root is located the same way as in test_task_execution_plan.py: +SECRETS_ENGINE_SOURCE_ROOT, defaulting to ../secrets-engine. Without this, the +proofs only import when an earlier test has already loaded the package, so +running one file alone fails. +""" +import os +import sys +from pathlib import Path + +_SECRETS = Path(os.environ.get('SECRETS_ENGINE_SOURCE_ROOT', + str(Path(__file__).resolve().parents[2] / 'secrets-engine'))) +if (_SECRETS / 'src' / 'secrets_engine').is_dir() and str(_SECRETS / 'src') not in sys.path: + sys.path.insert(0, str(_SECRETS / 'src')) diff --git a/tests/task_execution_source_servers.py b/tests/task_execution_source_servers.py index 3570382..2aa5186 100644 --- a/tests/task_execution_source_servers.py +++ b/tests/task_execution_source_servers.py @@ -167,7 +167,13 @@ test_missing_approval_denies { task_seam.decision.effect == "deny" with input as def access_server(directory,descriptor,request,reviewer,*,actual_policy=False): binary=Path(os.environ.get('PLATFORM_ACCESS_FIXTURE_BINARY','/tmp/netkingdom-platform-wave4-access')) verifier=Path(os.environ.get('PLATFORM_PDP_FIXTURE_VERIFIER','/tmp/netkingdom-platform-wave4-verify')) - if not binary.is_file() or not verifier.is_file():raise RuntimeError('build source fixture binaries first') + if not binary.is_file() or not verifier.is_file(): + # An ordinary checkout has no prebuilt fixture binaries: skip. If the + # caller pointed the env vars at a build, a missing file is a real failure. + if not ({'PLATFORM_ACCESS_FIXTURE_BINARY','PLATFORM_PDP_FIXTURE_VERIFIER'} & os.environ.keys()): + import pytest + pytest.skip('source fixture binaries not built (set PLATFORM_ACCESS_FIXTURE_BINARY / PLATFORM_PDP_FIXTURE_VERIFIER)') + raise RuntimeError('build source fixture binaries first') registry=directory/'registry.json';registry.write_bytes((ACCESS/'examples/secrets-engine/registry_snapshot.json').read_bytes()) policy=ACCESS/'examples/secrets-engine-service-task-execution/policy_package.md' if actual_policy else fixture_policy(directory,descriptor,request) requestfile=directory/'claim-free-request.json';requestfile.write_text(json.dumps(request)) diff --git a/tests/task_execution_trusted_servers.py b/tests/task_execution_trusted_servers.py index a9dc9f6..6f3d9f7 100644 --- a/tests/task_execution_trusted_servers.py +++ b/tests/task_execution_trusted_servers.py @@ -59,6 +59,13 @@ def serve(server,*,tls=None): @contextmanager def trusted_providers(directory): + # The trusted proof needs a pinned review environment (access source, built + # access binary, PDP verifier, approval-engine). Skip when none is configured; + # fail if one was configured but is incomplete. + configured={'TRUSTED_ACCESS_SOURCE_ROOT','TRUSTED_ACCESS_BINARY','TRUSTED_PDP_VERIFIER'} & os.environ.keys() + if not configured and not (ACCESS.is_dir() and BINARY.is_file() and VERIFIER.is_file()): + import pytest + pytest.skip('trusted review environment not present (set TRUSTED_ACCESS_SOURCE_ROOT / TRUSTED_ACCESS_BINARY / TRUSTED_PDP_VERIFIER)') from approval_engine.api import App from approval_engine.auth import Identity,StaticTokenAuthenticator from approval_engine.store import Engine diff --git a/tests/test_digest_retention.py b/tests/test_digest_retention.py index 54ea568..d5263d1 100644 --- a/tests/test_digest_retention.py +++ b/tests/test_digest_retention.py @@ -1,5 +1,10 @@ from unittest.mock import patch -from scripts import forgejo_package_prune as p +import sys +from pathlib import Path + +# Plain `pytest` does not put the repo root on sys.path; `python -m pytest` does. +sys.path.insert(0, str(Path(__file__).resolve().parents[1])) +from scripts import forgejo_package_prune as p # noqa: E402 IMAGE = 'forgejo.coulomb.social/coulomb/activity-core' diff --git a/tests/test_task_execution_mediator.py b/tests/test_task_execution_mediator.py index 52024f1..819a4b3 100644 --- a/tests/test_task_execution_mediator.py +++ b/tests/test_task_execution_mediator.py @@ -9,6 +9,8 @@ from types import SimpleNamespace import uuid import pytest + +pytest.importorskip('secrets_engine', reason='needs the sibling secrets-engine checkout (SECRETS_ENGINE_SOURCE_ROOT)') sys.path.insert(0,str(Path(__file__).resolve().parents[1]/'scripts')) from test_task_execution_native_fixture import owner,bao_dev,compiler from task_execution_mediator import ConfirmationConfig,run_native_fixture_task diff --git a/tests/test_task_execution_trusted_whole.py b/tests/test_task_execution_trusted_whole.py index 232fce4..2620d76 100644 --- a/tests/test_task_execution_trusted_whole.py +++ b/tests/test_task_execution_trusted_whole.py @@ -12,6 +12,8 @@ from types import SimpleNamespace import uuid import pytest + +pytest.importorskip('secrets_engine', reason='needs the sibling secrets-engine checkout (SECRETS_ENGINE_SOURCE_ROOT)') sys.path.insert(0,str(Path(__file__).resolve().parents[1]/'scripts')) from test_task_execution_native_fixture import owner,bao_dev,compiler from task_execution_trusted_servers import trusted_providers,install_exact_owner_descriptor,http,private diff --git a/tests/test_verify_informed_decision_requester.py b/tests/test_verify_informed_decision_requester.py index a3930c5..6c691cc 100644 --- a/tests/test_verify_informed_decision_requester.py +++ b/tests/test_verify_informed_decision_requester.py @@ -4,10 +4,15 @@ import io import unittest from pathlib import Path from unittest.mock import patch -spec = importlib.util.spec_from_file_location('proof', Path(__file__).resolve().parents[1]/'scripts/verify_informed_decision_requester.py') -m = importlib.util.module_from_spec(spec) -spec.loader.exec_module(m) +# The proof runs inside the informed-decision image, which provides the +# `informed_decision` package. It is not installed in this repo's environment. +HAVE_PACKAGE = importlib.util.find_spec('informed_decision') is not None +if HAVE_PACKAGE: + spec = importlib.util.spec_from_file_location('proof', Path(__file__).resolve().parents[1]/'scripts/verify_informed_decision_requester.py') + m = importlib.util.module_from_spec(spec) + spec.loader.exec_module(m) +@unittest.skipUnless(HAVE_PACKAGE, 'informed_decision package not installed (runs in the informed-decision image)') class ProofTests(unittest.TestCase): def test_negative_identity_is_bounded(self): with patch.object(m.Path, 'read_text', return_value='synthetic-only'), patch.object(m, 'http', return_value=(403, {})): diff --git a/workplans/ADHOC-2026-11-03.md b/workplans/ADHOC-2026-11-03.md index b4b49fe..a1e5c52 100644 --- a/workplans/ADHOC-2026-11-03.md +++ b/workplans/ADHOC-2026-11-03.md @@ -1,7 +1,7 @@ --- id: RPF-WP-ADHOC-2026-11-03 type: workplan -title: "Alert platform-root when the MAS evidence backup fails or goes stale" +title: "Ad hoc tasks 2026-11-03: MAS backup alerting, test-suite and admission-check repair" domain: financials repo: railiance-platform status: finished @@ -58,3 +58,67 @@ scaled), and both timers remain enabled. The test unit succeeded, and the `platform-root` inbox holds `MAS evidence notification test` (message `8d77ed2c…caa4`, 09:20:16Z) from `railiance-platform`. T01 is done. Receipt: `docs/evidence/mas-evidence-alert-install-2026-11-03.json`. + +## Make the platform test suite collect and finish + +```task +id: RPF-WP-ADHOC-2026-11-03-T02 +status: done +priority: medium +``` + +The full suite did not finish locally. Two files failed at collection. +`test_digest_retention.py` imported `scripts` without the repo root on +`sys.path`, and `test_verify_informed_decision_requester.py` needs the +`informed_decision` package from the informed-decision image. Run file by file +(149 files), six `test_task_execution_*` files also errored. Some never put the +sibling `secrets-engine` source on `sys.path`, so they only imported after an +earlier test had loaded it. Fourteen proofs in `test_task_execution_mediator.py` +and `test_task_execution_trusted_whole.py` need prebuilt fixture binaries and a +pinned trusted review environment, which this checkout does not have. +`test_openbao_isolated_restore_native.py` takes about 7 minutes; it failed once +and passed on the re-run. + +Fixes, tests only: +- `test_digest_retention.py` puts the repo root on `sys.path`. +- The informed-decision proof skips unless `informed_decision` is importable. + With `PYTHONPATH=~/informed-decision` it still passes 3/3. +- `tests/conftest.py` adds `SECRETS_ENGINE_SOURCE_ROOT/src` (default + `../secrets-engine`) to `sys.path`, the same root the plan tests use. +- The mediator and trusted-whole proofs skip with a named reason when their + binaries or environment are absent and no env var points at a build. If one + is configured but incomplete, they still fail. + +Result 2026-11-03: `python3 -m pytest` now runs to completion, with 1507 +passed, 9 failed and 18 skipped in 17m58s. Plain `pytest` also collects. The +9 failures are not environment problems: they fail the same way with the new +conftest disabled. They are assertions that have drifted from the source they +check: +- `test_credential_change`: all repo CCRs validate; coding-agent JWT role; + core-hub database lanes. This includes a `principal_type` that is now a + list. +- `test_eso_auth_recovery`: a generated-policy comment check. +- `test_factory_audit_delivery`: three tests stop on `reviewed_manifest_changed`. +- `test_flex_auth_signer_native_preparation`: two status-text and scope + assertions. +These cover credential-governance rules, so they were not loosened here. Each +needs an owner check of whether the source or the test is right. + +## Refresh the admission baseline after reviewed rapp-postgres changes + +```task +id: RPF-WP-ADHOC-2026-11-03-T03 +status: done +priority: medium +``` + +`make assurance-admission` failed with `invalid-or-unavailable-input`. The +report itself was unchanged: cells, ceilings, retention, limits and consumers +were all equal. Only three rapp-postgres source digests had drifted from the +2026-09-15 baseline. They come from two reviewed commits: +- `208f8b6` (RAPP-POSTGRES-WP-0008) lowers CPU and memory requests on + platform-pg and platform-pg-2. Disclosed limits are unchanged. +- `8d4106f` (RAPP-POSTGRES-WP-0007) is a provisioner grant fix: `NOSUPERUSER` + and runtime read on the conformance view. No capacity or retention logic. +`assurance/admission-baseline.json` now carries the three new digests, and +`make assurance-admission` passes.