5.7 KiB
Ops Hub Evidence Intake - Current State
Date: 2026-06-15
Workplan: IHUB-WP-0022
Summary
Inter-Hub has the generic v2 API surface needed for activity-core evidence intake, but the activity-core path is not live yet. The safe implementation slice is therefore contract-first:
- document the ops-hub widget mapping shape;
- document the Inter-Hub event payload shape;
- keep
OPS_HUB_KEYoutside Git; - accept State Hub fallback as the temporary safety path;
- wait on live ops-hub manifest/widgets, key provisioning, and production smoke before enabling per-entity Inter-Hub submission.
Inter-Hub API Surface
The current repo supports the necessary primitives through /api/v2.
Web.Controller.Api.V2.Widgets:
GET /api/v2/widgetsis authenticated and paginated.POST /api/v2/widgetsrequireshubId,name, andwidgetType.- Optional fields are
capabilityRef,viewContext,policyScope,status, andadapterSpecId. policyScopedefaults tointernalwhen omitted.- Valid widget statuses are
active,deprecated, anddraft. - Widget type and policy scope are validated through the type registries.
- Widget creation creates an initial
WidgetVersionsnapshot.
Web.Controller.Api.V2.InteractionEvents:
GET /api/v2/interaction-eventsis authenticated and paginated.- Supported list filters are
widgetIdandeventType. POST /api/v2/interaction-eventsrequireswidgetIdandeventType.viewContextis optional and is persisted asviewContextRef.metadatais accepted as a JSON object when the request content type isapplication/json.- The event type must exist in
event_type_registry. - If the API consumer is bound to an active manifest, the event type must also be declared by that manifest.
occurredAtis server-set. Activity-core should send its observed timestamp insidemetadata.attributes.observed_at.- Actor attribution is
actorType = "api"for this endpoint.
docs/new-hub-quickstart.md and scripts/ops-hub-bootstrap-smoke.py already
show the bootstrap shape for a single ops-hub endpoint event. The activity-core
intake needs that pattern expanded from one smoke widget/event to a durable
five-event contract.
Activity-Core Contract
The neighboring activity-core repo already defines the intended event
vocabulary under event-types/:
ops-service-observedops-endpoint-verifiedops-access-path-checkedops-backup-verifiedops-inventory-drift
The current activity-core sink implementation is intentionally conservative:
state-hub-progressis implemented and idempotent.- It posts
ops_inventory_probeprogress with compact non-secret detail. - The idempotency key is
activity_core_run_id + context_key + event_type. - The compact probe strips raw response bodies, headers, credentials, URL query strings, and token-like material.
- Inter-Hub sink names are recognized, but the sink currently returns
missing_inter_hub_configorinter_hub_sink_deferred; it does not submit events yet. - Inter-Hub mode requires
INTER_HUB_URL,OPS_HUB_KEY, and eitherOPS_HUB_WIDGET_MAPPING,widget_mapping, orcapability_mapping.
Activity-core deployment placeholders exist in
activity-core/k8s/railiance/20-runtime.yaml:
INTER_HUB_URLis present but empty.OPS_HUB_WIDGET_MAPPINGis present but empty.OPS_HUB_KEYis created only as an empty Secret placeholder bybootstrap-secrets.sh.
Fallback Evidence State
State Hub was queried directly for live fallback evidence:
GET http://127.0.0.1:8000/progress/?event_type=ops_inventory_probe&limit=20
Result on 2026-06-15: an empty list.
That means the fallback sink is implemented and tested in activity-core, but no
live ops_inventory_probe progress event is available for Inter-Hub to accept
as closure evidence yet.
Production Gates
Known gates before per-entity Inter-Hub submission can be treated as live:
- The production Inter-Hub deployment must include commit
5101eb5or an equivalent fix for PostgreSQLCOUNT(*)decoding in widget creation and API rate-limit reads. - The active
ops-hubmanifest must declare the five activity-core event types, the selected widget types, the annotation category, and the policy scope. - Seed widgets named by the mapping contract must exist in the target environment.
OPS_HUB_KEYmust be provisioned outside Git, preferably in OpenBao atplatform/operators/ops-hub/runtime, fieldOPS_HUB_KEY.- Activity-core must receive
INTER_HUB_URL,OPS_HUB_KEY, andOPS_HUB_WIDGET_MAPPINGthrough its runtime config/Secret path. - A controlled smoke must submit one event for each declared event type and verify that an undeclared event type is rejected.
Recommended Manifest Vocabulary
Use one policy scope for the first slice:
ops-evidence
Use one annotation category:
ops-risk
Use these widget types unless the operator prefers to keep a smaller aggregate surface:
ops-service-cardops-endpoint-cardops-access-path-cardops-backup-cardops-drift-card
Use the activity-core event types exactly as published:
ops-service-observedops-endpoint-verifiedops-access-path-checkedops-backup-verifiedops-inventory-drift
Open Questions
- Does ops-hub already have a production manifest that should be patched rather than replaced?
- Should the first production mapping use only aggregate widgets, or seed per-entity widgets for the known Railiance inventory?
- Which OpenBao or cluster Secret path should activity-core consume for
OPS_HUB_KEY? - Should activity-core close
ACTIVITY-WP-0007/T06after a live State Hub fallback event with explicit Inter-Hub deferral, or only after real Inter-Hub submission?