hub-core/docs/conformance.md
tegwick 7f0dc78607
Some checks failed
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / pytest-smoke (push) Failing after 2s
test: verify outcome migrations and worker recovery on PostgreSQL
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a0e747-8f27-7242-8df8-8bc44f88c929
2026-09-28 14:22:05 +02:00

5.9 KiB

Hub-extension conformance

hub_core.conformance is the reusable Tier 2/3 harness scaffold for contract version 0.1.0. It drives only public HTTP ports, so a FastAPI TestClient, an httpx.Client, or another compatible target can be used without importing the runtime implementation.

The harness mutates its target. Run it against a disposable instance or a dedicated test namespace:

hub-core api --host 127.0.0.1 --port 8010
hub-core conformance --base-url http://127.0.0.1:8010
hub-core conformance --base-url http://127.0.0.1:8010 --json

Implemented profile

ID Tier Automated evidence
C1 2 Packaged descriptor, manifest, and catalog validate against Draft 2020-12 schemas
C3 2 Runtime health probe returns healthy
C4 2 Repeated manifest registration is reported as a duplicate
C5 2 Cataloged progress/interaction events are accepted; wrong-family and unknown events are rejected
C6 2 Contract and scenario fixtures reject secret-shaped keys, credentialed database URLs, and private keys
C7 2 Disabled compatibility groups (/api/v2/hubs, /console) deny access without needing fixture credentials
C8 2 Registry response propagates the request correlation identifier
C9 2 /readyz reports each dependency (database, port.repo projection, workload projection, authorization) individually, only degrading when a configured dependency is unavailable or stale
C10 2 A registration whose contract_version_min/contract_version_max excludes the runtime's contract version is rejected with an explicit incompatibility error
C2 2 GET /ports/registry/registrations/{hub_slug} resolves missing (404) and ambiguous (two hub_slugs sharing one reuse_surface_id) registrations, and GET .../audit returns queryable registration history
F2 3 Progress and interaction fixture events appear only in their respective projections
F3 3 Authority fixtures appear in projections with declared rebuild sources and provenance hashes

The projection scenario is shipped in the wheel as fixtures/projection-rebuild.json. Correlation and time fields are generated per run, allowing the harness to identify its own evidence without relying on global row counts.

Deliberately open checks

F1 registry audit history at framework scale (beyond the per-hub_slug audit trail above), F4 /api/v2 consumer smokes, F5 MCP projection binding, F6 policy fail-closed behavior beyond the raw-port group check above, F7 telemetry rejection, and F8 migration metadata isolation require ports or absorption slices that are not part of the T04 minimal vertical. Tenant isolation also remains open because the 0.1 runtime has no tenant identity or authorization context yet. These gaps must not be interpreted as passing; the harness reports only the implemented profile above.

Access enforcement and CI gates

make ci-check runs the test suite, checks the reviewed access inventory for source drift, runs disposable PostgreSQL integration tests, builds distributions and validates an installed wheel outside the checkout's import path. The wheel check uses a fresh environment and refreshes the Hub package so rebuilding the same version cannot reuse an older installation. Forgejo runs these gates for main pushes and manual runs, using the full commit SHA and a unique temporary checkout. CI installs the locked development and runtime dependencies first. Individual gates are make test, make inventory-check, make package-check and make postgres-test.

tests/test_enforced_conformance.py runs all twelve existing Tier 2/3 checks through an explicitly enforced runtime using a real signed IAM JWT and synthetic owner facts, policy and audit. It verifies event attribution against authorization records. Additional journeys establish valid state, deny both reads and writes for anonymous/invalid credentials, revoked entitlement, policy denial and policy/audit outages, then independently read back unchanged stored messages. These tests run in the ordinary suite; they need no external owner checkout.

The installed-wheel gate validates runtime/security imports, packaged action and browser route coverage, contract fixtures/schemas and the migration template. It makes no owner requests and starts no service. The separate optional Audit Core interoperability suite still requires HUB_CORE_AUDIT_CORE_SOURCE and is not silently represented as covered by ordinary CI. Local CI-equivalent success is not a deployed Forgejo receipt or live owner/platform acceptance.

Disposable PostgreSQL gate

make postgres-test enables tests/test_postgres_integration.py. It creates its own Docker container and a separate database for each test, then removes both. It never accepts an operator database URL. The container uses a random fixture password, a loopback-only ephemeral port and tmpfs data storage. The PostgreSQL 16 Alpine image is pinned by digest in the test file. Readiness waits for TCP so the image's temporary initialization server cannot be mistaken for the final one.

The tests run the entire packaged Alembic chain through 0006_outcome_outbox, check the pending-outcome downgrade guard and re-upgrade, demonstrate concurrent SKIP LOCKED delivery, roll back business and ledger writes after an outbox failure, and verify persisted retry state. A child worker exits with os._exit after writing a synthetic receiver receipt but before committing its local acknowledgement; a new connection then replays the identical envelope.

This is a required gate of make ci-check, including Forgejo. The runner needs Docker daemon access and the pinned image cached or registry pull access. Missing Docker/image access fails this gate; it does not silently pass. Ordinary pytest skips this module unless HUB_CORE_TEST_POSTGRES=1; the dedicated gate enables it explicitly. Tests use disposable superuser credentials and synthetic custody, so production runtime grants and live receiver admission remain separate checks.