generated from coulomb/repo-seed
Align ops-hub activity-core contract vocabulary
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
# Ops Hub Activity-Core Event Payloads
|
||||
|
||||
Date: 2026-06-15
|
||||
Updated: 2026-06-27
|
||||
|
||||
Workplan: `IHUB-WP-0022`
|
||||
|
||||
@@ -33,6 +34,28 @@ Each request body must use the Inter-Hub v2 interaction-event shape:
|
||||
Inter-Hub sets `occurredAt` on receipt. Activity-core must send the actual
|
||||
probe timestamp as `metadata.attributes.observed_at`.
|
||||
|
||||
## Live Vocabulary Alignment
|
||||
|
||||
Use event names declared by the live ops-hub manifest:
|
||||
|
||||
- `ops-service-discovered`
|
||||
- `ops-endpoint-verified`
|
||||
- `ops-backup-verified`
|
||||
- `ops-drift-detected`
|
||||
|
||||
Transitional aliases may be accepted in local mapping logic but should not be
|
||||
submitted to Inter-Hub:
|
||||
|
||||
| Earlier activity-core name | Live event name |
|
||||
| --- | --- |
|
||||
| `ops-service-observed` | `ops-service-discovered` |
|
||||
| `ops-inventory-drift` | `ops-drift-detected` |
|
||||
|
||||
`ops-access-path-checked` is deferred because the live manifest has no
|
||||
access-path event type or access-path widget type. Keep State Hub fallback
|
||||
posting for access-path evidence until ops-hub adds that vocabulary or an
|
||||
operator decision maps it to `ops-readiness-gate-updated` or `ops-risk-raised`.
|
||||
|
||||
## Shared Rules
|
||||
|
||||
- `widgetId` must be a UUID for an existing ops-hub widget.
|
||||
@@ -41,7 +64,7 @@ probe timestamp as `metadata.attributes.observed_at`.
|
||||
be declared by that manifest.
|
||||
- `viewContext` should be `ops-inventory-probe` unless a more specific context
|
||||
is useful, such as `ops-inventory-probe/endpoints`.
|
||||
- `metadata.type` must match the Inter-Hub `eventType`.
|
||||
- `metadata.type` must match the Inter-Hub `eventType` after alias translation.
|
||||
- `metadata.version` must match the activity-core event definition version.
|
||||
- `metadata.publisher` must be `activity-core`.
|
||||
- `metadata.attributes.idempotency_key` is required, even though Inter-Hub does
|
||||
@@ -69,26 +92,27 @@ Use `reason` for compact machine-readable explanations, for example:
|
||||
- `backup_probe_not_implemented`
|
||||
- `missing_endpoint`
|
||||
|
||||
## Example: Service Observed
|
||||
## Example: Service Discovered
|
||||
|
||||
```json
|
||||
{
|
||||
"widgetId": "<service-widget-uuid>",
|
||||
"eventType": "ops-service-observed",
|
||||
"widgetId": "<service-or-catalog-widget-uuid>",
|
||||
"eventType": "ops-service-discovered",
|
||||
"viewContext": "ops-inventory-probe/services",
|
||||
"metadata": {
|
||||
"type": "ops-service-observed",
|
||||
"type": "ops-service-discovered",
|
||||
"version": "1.0",
|
||||
"publisher": "activity-core",
|
||||
"attributes": {
|
||||
"activity_core_run_id": "12345678-aaaa-bbbb-cccc-123456789abc",
|
||||
"idempotency_key": "12345678-aaaa-bbbb-cccc-123456789abc:state-hub:ops-service-observed",
|
||||
"idempotency_key": "12345678-aaaa-bbbb-cccc-123456789abc:state-hub:ops-service-discovered",
|
||||
"service_id": "state-hub",
|
||||
"service_name": "State Hub",
|
||||
"environment": "local",
|
||||
"lifecycle_state": "observed",
|
||||
"lifecycle_state": "discovered",
|
||||
"observed_status": "ok",
|
||||
"observed_at": "2026-06-05T10:15:01Z"
|
||||
"observed_at": "2026-06-05T10:15:01Z",
|
||||
"widget_ref": "ops:service:state-hub"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -124,37 +148,26 @@ Use `reason` for compact machine-readable explanations, for example:
|
||||
}
|
||||
```
|
||||
|
||||
## Example: Access Path Checked
|
||||
## Deferred: Access Path Checked
|
||||
|
||||
```json
|
||||
{
|
||||
"widgetId": "<access-path-widget-uuid>",
|
||||
"eventType": "ops-access-path-checked",
|
||||
"viewContext": "ops-inventory-probe/access-paths",
|
||||
"metadata": {
|
||||
"type": "ops-access-path-checked",
|
||||
"version": "1.0",
|
||||
"publisher": "activity-core",
|
||||
"attributes": {
|
||||
"activity_core_run_id": "12345678-aaaa-bbbb-cccc-123456789abc",
|
||||
"idempotency_key": "12345678-aaaa-bbbb-cccc-123456789abc:gitea:gitea-access-1:ops-access-path-checked",
|
||||
"service_id": "gitea",
|
||||
"access_path_id": "gitea-access-1",
|
||||
"access_path_type": "k8s",
|
||||
"declared_status": "unknown",
|
||||
"observed_status": "skipped",
|
||||
"reason": "unsupported_access_path_type",
|
||||
"observed_at": "2026-06-05T10:15:01Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
Do not submit `ops-access-path-checked` to Inter-Hub while the live ops-hub
|
||||
manifest lacks that event type and a matching widget type. Activity-core should
|
||||
continue to include compact access-path detail in State Hub fallback summaries
|
||||
and return a non-secret deferred sink result for Inter-Hub.
|
||||
|
||||
If the operator chooses to represent access-path state as readiness or risk,
|
||||
create a separate mapping decision and send the supported event type instead of
|
||||
silently rewriting access-path evidence.
|
||||
|
||||
## Example: Backup Verified
|
||||
|
||||
This event is declared by the live manifest, but it needs a target
|
||||
`ops-backup-set` widget such as `ops:backup-set:aggregate` before the smoke can
|
||||
submit it.
|
||||
|
||||
```json
|
||||
{
|
||||
"widgetId": "<backup-widget-uuid>",
|
||||
"widgetId": "<backup-set-widget-uuid>",
|
||||
"eventType": "ops-backup-verified",
|
||||
"viewContext": "ops-inventory-probe/backups",
|
||||
"metadata": {
|
||||
@@ -170,26 +183,27 @@ Use `reason` for compact machine-readable explanations, for example:
|
||||
"restore_verified": false,
|
||||
"observed_status": "skipped",
|
||||
"reason": "backup_probe_not_implemented",
|
||||
"observed_at": "2026-06-05T10:15:01Z"
|
||||
"observed_at": "2026-06-05T10:15:01Z",
|
||||
"widget_ref": "ops:backup-set:aggregate"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Example: Inventory Drift
|
||||
## Example: Drift Detected
|
||||
|
||||
```json
|
||||
{
|
||||
"widgetId": "<drift-widget-uuid>",
|
||||
"eventType": "ops-inventory-drift",
|
||||
"widgetId": "<readiness-or-risk-widget-uuid>",
|
||||
"eventType": "ops-drift-detected",
|
||||
"viewContext": "ops-inventory-probe/drift",
|
||||
"metadata": {
|
||||
"type": "ops-inventory-drift",
|
||||
"type": "ops-drift-detected",
|
||||
"version": "1.0",
|
||||
"publisher": "activity-core",
|
||||
"attributes": {
|
||||
"activity_core_run_id": "12345678-aaaa-bbbb-cccc-123456789abc",
|
||||
"idempotency_key": "12345678-aaaa-bbbb-cccc-123456789abc:gitea:gitea-oci-registry:ops-inventory-drift",
|
||||
"idempotency_key": "12345678-aaaa-bbbb-cccc-123456789abc:gitea:gitea-oci-registry:ops-drift-detected",
|
||||
"service_id": "gitea",
|
||||
"inventory_object_id": "gitea-oci-registry",
|
||||
"drift_kind": "status_mismatch",
|
||||
@@ -197,7 +211,8 @@ Use `reason` for compact machine-readable explanations, for example:
|
||||
"observed_summary": "status_code=200",
|
||||
"observed_status": "degraded",
|
||||
"reason": "expected_status_mismatch",
|
||||
"observed_at": "2026-06-05T10:15:01Z"
|
||||
"observed_at": "2026-06-05T10:15:01Z",
|
||||
"widget_ref": "ops:readiness:gitea-registry"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -208,12 +223,12 @@ Use `reason` for compact machine-readable explanations, for example:
|
||||
Activity-core should treat these as configuration or rollout errors:
|
||||
|
||||
| Error | Meaning | Recovery |
|
||||
|---|---|---|
|
||||
| --- | --- | --- |
|
||||
| `401` | Missing or invalid `OPS_HUB_KEY` | Check Secret provisioning; do not log the key. |
|
||||
| `422` with `unregistered_event_type` | Event type not in Inter-Hub registry | Activate the ops-hub manifest vocabulary. |
|
||||
| `422` with `unregistered_event_type` | Event type not in Inter-Hub registry | Use a live manifest event or activate a corrected ops-hub manifest. |
|
||||
| `422` with `event_type_not_in_manifest` | Runtime consumer manifest does not declare the event | Bind the consumer to the active manifest or activate a corrected manifest. |
|
||||
| `422` with `Widget not found` | Mapping points at a missing widget | Refresh `OPS_HUB_WIDGET_MAPPING`. |
|
||||
| `422` with `unregistered_policy_scope` during widget seed | Policy scope is absent | Declare and activate `ops-evidence`. |
|
||||
| `422` with `Widget not found` | Mapping points at a missing widget | Refresh `OPS_HUB_WIDGET_MAPPING` from authenticated widget lookup. |
|
||||
| `422` with `unregistered_policy_scope` during widget seed | Policy scope is absent | Use one of the declared ops scopes, not the old `ops-evidence` proposal. |
|
||||
|
||||
For the first activity-core slice, a failed Inter-Hub submission should not
|
||||
fail the whole probe if State Hub fallback posting succeeds. It should return a
|
||||
|
||||
Reference in New Issue
Block a user