CATALOG_ENDPOINTS = [ "/api/v2/widget-types", "/api/v2/event-types", "/api/v2/annotation-categories", "/api/v2/policy-scopes", "/api/v2/openapi.json", "/api/v2/openapi.yaml", ] PROTECTED_ENDPOINTS = [ "/api/v2/hubs", "/api/v2/hub-capability-manifests", "/api/v2/api-consumers", "/api/v2/widgets", "/api/v2/interaction-events", "/api/v2/annotations", "/api/v2/requirement-candidates", "/api/v2/decision-records", "/api/v2/deployment-records", "/api/v2/outcome-signals", "/api/v2/hub-registry", ] OPERATOR_HEADERS = {"Authorization": "Bearer operator-token"} def test_catalog_endpoints_respond_without_auth(client): for endpoint in CATALOG_ENDPOINTS: response = client.get(endpoint) assert response.status_code == 200, endpoint def test_protected_api_v2_endpoints_fail_before_business_logic(client): for endpoint in PROTECTED_ENDPOINTS: response = client.get(endpoint) assert response.status_code == 401, endpoint assert response.json()["detail"]["code"] == "unauthorized" def test_openapi_contains_ops_hub_gate_paths(client): payload = client.get("/api/v2/openapi.json").json() assert "/api/v2/hubs" in payload["paths"] assert "/hubs" in payload["paths"] assert "/hub-capability-manifests" in payload["paths"] assert "/api-consumers" in payload["paths"] assert "/policy-scopes" in payload["paths"] def test_ops_hub_bootstrap_sequence(client): hub = client.post( "/api/v2/hubs", headers=OPERATOR_HEADERS, json={ "slug": "ops-hub", "name": "Ops Hub", "domain": "ops.coulomb.social", "hubKind": "domain", "hubFamily": "vsm", "vsmFunction": "OPS", "vsmSystem": "1", }, ) assert hub.status_code == 201 hub_record = hub.json() assert hub_record["slug"] == "ops-hub" listed_hubs = client.get("/api/v2/hubs", headers=OPERATOR_HEADERS).json() assert listed_hubs["data"][0]["id"] == hub_record["id"] manifest = client.post( "/api/v2/hub-capability-manifests", headers=OPERATOR_HEADERS, json={ "hubId": hub_record["id"], "manifestVersion": "1.0", "declaredWidgetTypes": ["ops-readiness-gate"], "declaredEventTypes": ["ops-endpoint-verified"], "declaredAnnotationCategories": ["ops-readiness-blocker"], "declaredPolicyScopes": ["ops-registry"], }, ) assert manifest.status_code == 201 manifest_record = manifest.json() activated = client.post( f"/api/v2/hub-capability-manifests/{manifest_record['id']}/activate", headers=OPERATOR_HEADERS, ) assert activated.status_code == 200 assert activated.json()["status"] == "active" consumer = client.post( "/api/v2/api-consumers", headers=OPERATOR_HEADERS, json={ "name": "ops-hub", "description": "API consumer for the VSM Operations hub", "hubCapabilityManifestId": manifest_record["id"], "rateLimitPerMinute": 120, "quotaPerDay": 50000, }, ) assert consumer.status_code == 201 consumer_record = consumer.json() key_response = client.post( f"/api/v2/api-consumers/{consumer_record['id']}/api-keys", headers=OPERATOR_HEADERS, json={"scopes": "framework:read hub:ops-hub:read hub:ops-hub:write"}, ) assert key_response.status_code == 201 runtime_key = key_response.json()["fullKey"] runtime_headers = {"Authorization": f"Bearer {runtime_key}"} widget = client.post( "/api/v2/widgets", headers=runtime_headers, json={ "hubId": hub_record["id"], "status": "active", "name": "Gitea Registry Readiness", "widgetType": "ops-readiness-gate", "capabilityRef": "ops:readiness:gitea-registry", "viewContext": "ops-hub/readiness/gitea-registry", "policyScope": "ops-registry", }, ) assert widget.status_code == 201 widget_record = widget.json() event = client.post( "/api/v2/interaction-events", headers=runtime_headers, json={ "widgetId": widget_record["id"], "eventType": "ops-endpoint-verified", "viewContext": "railiance-apps/workplans/RAIL-AP-WP-0001", "metadata": {"expectedStatus": 401}, }, ) assert event.status_code == 201 assert event.json()["eventType"] == "ops-endpoint-verified" registry = client.get("/api/v2/hub-registry", headers=runtime_headers) assert registry.status_code == 200 assert registry.json()["data"]["hubs"][0]["slug"] == "ops-hub"