implement ops hub extension contract
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a053ff-1d6f-7fe2-ac1c-a6eb40a42a0c
This commit is contained in:
tegwick 2026-08-31 21:31:53 +02:00
parent 9bbbf2032d
commit 75f4944144
14 changed files with 662 additions and 43 deletions

View file

@ -1,17 +1,33 @@
IHUB_BASE ?= https://hub.coulomb.social
IHUB_OPERATOR_KEY_FILE ?=
OPS_HUB_RUNTIME_KEY_OUTPUT ?=
HUB_CORE_REPO ?= ../hub-core
HUB_CORE_PYTHON ?= $(HUB_CORE_REPO)/.venv/bin/python
.PHONY: help interhub-gate interhub-bootstrap interhub-bootstrap-dry-run interhub-bootstrap-help test
.PHONY: help hub-extension-check hub-core-conformance interhub-gate interhub-bootstrap interhub-bootstrap-dry-run interhub-bootstrap-help test
help:
@echo "Targets:"
@echo " hub-extension-check Validate the owner package against hub-core 0.1.0 schemas/catalog"
@echo " hub-core-conformance Exercise the owner package in a disposable hub-core runtime"
@echo " interhub-gate Probe whether production Inter-Hub exposes the ops-hub bootstrap API surface"
@echo " interhub-bootstrap-help Show bootstrap helper options"
@echo " interhub-bootstrap-dry-run Plan bootstrap actions with IHUB_OPERATOR_KEY_FILE (no mutations)"
@echo " interhub-bootstrap Run attended ops-hub Inter-Hub bootstrap with IHUB_OPERATOR_KEY_FILE"
@echo " test Run unit tests"
hub-extension-check:
@test -x "$(HUB_CORE_PYTHON)" || \
(echo "hub-core environment missing at $(HUB_CORE_PYTHON)" >&2; exit 2)
PYTHONPATH=src "$(HUB_CORE_PYTHON)" scripts/hub-extension-check.py \
--hub-core-repo "$(HUB_CORE_REPO)"
hub-core-conformance:
@test -x "$(HUB_CORE_PYTHON)" || \
(echo "hub-core environment missing at $(HUB_CORE_PYTHON)" >&2; exit 2)
PYTHONPATH=src "$(HUB_CORE_PYTHON)" scripts/hub-core-conformance.py \
--hub-core-repo "$(HUB_CORE_REPO)"
interhub-gate:
IHUB_BASE="$(IHUB_BASE)" python3 scripts/interhub-gate-probe.py

View file

@ -1,7 +1,11 @@
Operations / System 1 extension for Core Hub.
Operations / System 1 extension for Hub Core.
The versioned `helixforge.hub-extension` descriptor, manifest, validation, and
State Hub retirement boundary are documented in
[`docs/hub-extension.md`](docs/hub-extension.md).
`ops-hub` is the operational truth surface for environments, hosts, clusters,
services, endpoints, releases, backups, incidents, risks, runbooks, readiness
gates, and migration waves. Generic hub framework work stays in `core-hub`;
gates, and migration waves. Generic hub framework work stays in `hub-core`;
operations-specific extension code belongs here. Historical Haskell Inter-Hub is
`inter-hub-haskell` (retired 2026-07-08).

View file

@ -8,7 +8,7 @@
| Kind | ID | Status | Lane | Source |
| --- | --- | --- | --- | --- |
| workplan | OPS-WP-0003 | proposed | — | workplans/OPS-WP-0003-extension-contract-alignment.md |
| task | OPS-WP-0003-T01 | todo | — | workplans/OPS-WP-0003-extension-contract-alignment.md |
| task | OPS-WP-0003-T02 | todo | — | workplans/OPS-WP-0003-extension-contract-alignment.md |
| task | OPS-WP-0003-T03 | todo | — | workplans/OPS-WP-0003-extension-contract-alignment.md |
| workplan | OPS-WP-0003 | finished | — | workplans/OPS-WP-0003-extension-contract-alignment.md |
| task | OPS-WP-0003-T01 | done | — | workplans/OPS-WP-0003-extension-contract-alignment.md |
| task | OPS-WP-0003-T02 | done | — | workplans/OPS-WP-0003-extension-contract-alignment.md |
| task | OPS-WP-0003-T03 | done | — | workplans/OPS-WP-0003-extension-contract-alignment.md |

View file

@ -1,18 +1,20 @@
# Ops Hub Bootstrap Runbook
Date: 2026-06-17
Date: 2026-08-31
## Purpose
This runbook is the operator-ready path for activating `ops-hub` in production
Inter-Hub. It covers the preferred API bootstrap, key custody expectations, the
ops-warden remote execution lane, and the explicit SQL fallback.
Hub Core's `/api/v2` compatibility surface. It covers the preferred API
bootstrap, key custody expectations, the ops-warden remote execution lane, and
the explicit SQL fallback.
Use this when finishing `CUST-WP-0047-T05` or any later ops-hub Inter-Hub
activation task.
## Inputs
- Hub-extension package: `registry/hub-extension/v0.1.0/ops-hub.extension.json`
- Manifest draft: `seeds/ops-hub-manifest.draft.json`
- Widget seed: `seeds/ops-hub-widgets.seed.json`
- API helper: `scripts/ops-hub-bootstrap-api.py`
@ -167,14 +169,21 @@ curl -s https://hub.coulomb.social/api/v2/hub-registry
Expected: `ops-hub` is visible, and the operator can see the seeded widgets in
the authenticated UI.
## Current Live-Execution Blocker
## Authenticated rerun boundary
The repo-side helper, dry-run path, and runbook are ready. The remaining step is
an operator-attended production run with:
Ops Hub bootstrap and consumer gates passed during the hub-core candidate
cutover (`RAPPCOREHUB-WP-0002-T04`), and the 2026-08-31 post-cutover public
gate passes against `https://hub.coulomb.social`. There is no pending bootstrap
mutation merely to finish `OPS-WP-0003`.
- an operator-provided `IHUB_OPERATOR_KEY_FILE`,
- an OpenBao-materialized key on a trusted host, or
- an explicitly approved deployment-side migration/bootstrap path.
An authenticated rerun remains a high-risk attended operation because it may
create a consumer key or production records. Use it only for a real registration
change, start with `warden route show inter-hub-bootstrap-ssh --json`, and
record non-secret evidence. For routine validation use:
Until one of those is available, run `make interhub-gate`, `make test`, and
`make interhub-bootstrap-dry-run` for local validation.
```bash
make test
make hub-extension-check
make hub-core-conformance
make interhub-gate
```

78
docs/hub-extension.md Normal file
View file

@ -0,0 +1,78 @@
# Ops Hub extension package
Ops Hub implements the owner side of `helixforge.hub-extension` 0.1.0. Hub
Core owns and runs the framework ports; this repository owns the operations
descriptor, capability declarations, event boundary, compatibility bootstrap,
and evidence used to move service-catalog responsibility out of State Hub.
The canonical package is
`registry/hub-extension/v0.1.0/ops-hub.extension.json`. Its stable identity is
`capability.operations.ops-hub`; it also declares
`capability.operations.service-catalog` as an owner capability.
## Ownership boundary
| Surface | Owner |
| --- | --- |
| Descriptor, manifest, operational vocabulary, service-catalog records | `ops-hub` |
| `port.*` schemas, event catalog, registry and projection runtime | `hub-core` |
| Runtime and operator credentials | OpenBao/platform custody; never this package |
| State Hub compatibility routes during retirement | `state-hub` until their evidenced cutover |
Ops Hub is an aspect hub, not a second hub-core deployment. The API endpoint in
the manifest is a discovery reference to the hub-core-hosted compatibility
surface at `https://hub.coulomb.social/api/v2`.
## Events and legacy compatibility
The 0.1.0 port contract emits `ops.endpoint.verified` and consumes
`hub.progress.recorded`. The older `/api/v2` bootstrap seed uses
`ops-endpoint-verified`; hub-core's compatibility adapter retains that legacy
spelling. New port-native evidence uses the dotted catalog event and must not
silently rewrite historical events.
## Validation
```bash
make test
make hub-extension-check
make hub-core-conformance
make interhub-gate
```
`hub-extension-check` validates the owner package against hub-core's packaged
Draft 2020-12 descriptor and manifest schemas, checks every declared event
against hub-core's catalog, and emits a non-secret checksum receipt.
`hub-core-conformance` injects this repository's package into a disposable
hub-core reference runtime. Contract version 0.1.0 automates C1, C3, C4, C5,
C6, and C8 plus Tier-3 F2 and F3. C2 registry resolution, C7 raw-port policy,
C9 dependency-aware readiness, and C10 version negotiation are not automated
by the current hub-core harness and are not represented as passing.
`interhub-gate` is the safe post-cutover production check. It proves that the
hub-core-hosted `/api/v2` surface exposes the bootstrap resources without
requiring a credential or mutating production.
## Authenticated bootstrap
The existing `scripts/ops-hub-bootstrap-api.py` remains the idempotent
compatibility bootstrap client. It creates or reuses the hub, manifest, API
consumer, widgets, and verification event. Follow `docs/bootstrap-runbook.md`.
Operator and runtime keys are never arguments, logs, Git content, or extension
fields. Credential routing starts with:
```bash
warden route show inter-hub-bootstrap-ssh --json
```
The current route is high-risk and attended. A source change or public gate
does not authorize another live bootstrap mutation.
## State Hub retirement handoff
This package satisfies the receiving-side contract for `STATE-WP-0079` Wave
D1. Removing State Hub's service-catalog routes still requires a separate
caller inventory, projection/count comparison, rollback receipt, and explicit
production writer-cutover authorization. Owner readiness is not cutover proof.

View file

@ -1,15 +0,0 @@
---
repo: ops-hub
reason: >
Only a single diagnostic bootstrap-API probe script exists; the described operational-truth surface (hosts/services/incidents/runbooks) isn't implemented yet.
reviewed: "2026-07-06"
reviewed_by: claude-code
revisit: >
Revisit once the operational-truth surface has real implementation beyond the probe script.
---
# No reusable capability
This repo was reviewed for the `reuse-surface` capability registry
(REUSE-WP-0017 coverage campaign) and has no capability to register at this
time. See the `reason` field above.

View file

@ -0,0 +1,140 @@
---
id: capability.operations.ops-hub
name: Operations Hub Extension Contract
summary: Versioned hub-extension package and bootstrap client for operational truth, service-catalog records, readiness evidence, and migration gates.
owner: ops-hub
status: reviewed
domain: operations
tags:
- operations
- service-catalog
- readiness
- hub-extension
maturity:
discovery:
current: D3
target: D4
confidence: high
rationale: >
The owner boundary, versioned descriptor/manifest, hub-core ports, event
families, compatibility bootstrap, and State Hub retirement handoff are
explicit and tested.
availability:
current: A1
target: A3
confidence: high
rationale: >
The contract package and idempotent bootstrap client are available from
source; the framework runtime is hosted by hub-core rather than this repo.
external_evidence:
completeness:
level: C1
confidence: medium
basis: scope_vs_intent_and_consumer_expectations
satisfied_expectations:
- versioned extension descriptor and manifest
- hub-core schema and event-catalog validation
- disposable Tier 2/3 conformance profile
- production compatibility API public gate
broken_expectations: []
out_of_scope_expectations:
- independent framework runtime
- secret custody
reliability:
level: R1
confidence: high
basis: consumer_quality_signals
known_reliability_risks:
- authenticated re-bootstrap requires the attended high-risk access lane
discovery:
intent: >
Let hub-core host an Ops Hub extension without transferring ownership of
operational records or credentials into the framework.
includes:
- descriptor and capability manifest
- operations service-catalog declaration
- readiness evidence event boundary
- compatibility bootstrap client and public gate
excludes:
- hub-core framework implementation
- credential storage or vending
- State Hub compatibility routes after cutover
assumptions:
- hub-core remains the surviving framework runtime
use_cases:
- register Ops Hub against hub-core
- publish and project service-catalog records
- attach non-secret readiness evidence
research_memos: []
availability:
current_level: A1
target_level: A3
current_artifacts:
- registry/hub-extension/v0.1.0/ops-hub.extension.json
- scripts/ops-hub-bootstrap-api.py
- scripts/hub-extension-check.py
- scripts/hub-core-conformance.py
target_artifacts:
- policy-bound unattended registration lane
consumption_modes:
- contract package
- command-line bootstrap
relations:
depends_on:
- capability.infotech.hub-core-library
supports:
- capability.operations.service-catalog
related_to: []
evidence:
documentation:
- docs/hub-extension.md
- docs/bootstrap-runbook.md
tests:
- tests/test_extension_contract.py
- make hub-core-conformance
consumer_feedback:
- RAPPCOREHUB-WP-0002-T04
bug_reports: []
incidents: []
consumer_guidance:
recommended_for:
- registering and validating the Ops Hub extension on hub-core
- migrating State Hub service-catalog consumers to an owner-backed contract
not_recommended_for:
- treating ops-hub as another hub-core runtime
- retrieving or storing credentials
known_limitations:
- C2, C7, C9, and C10 are not automated by hub-core contract version 0.1.0
- authenticated live bootstrap requires the governed attended access lane
promotion_history:
- date: "2026-08-31"
dimension: discovery
from: D0
to: D3
rationale: Published the owner-side 0.1.0 package and conformance evidence.
author: codex
- date: "2026-08-31"
dimension: availability
from: A0
to: A1
rationale: Published source-level validation and bootstrap consumers.
author: codex
---
# Operations Hub Extension Contract
The capability is the owner-side contract package and bootstrap client. Hub
Core supplies the framework runtime; Ops Hub retains the operational vocabulary,
service-catalog model, readiness evidence, and migration-gate ownership.
The package contains no credentials. Authenticated bootstrap follows
`docs/bootstrap-runbook.md` and emits only non-secret identifiers and key
prefixes as evidence.

View file

@ -0,0 +1,76 @@
{
"descriptor": {
"contract_id": "helixforge.hub-extension",
"contract_version": "0.1.0",
"hub_slug": "ops-hub",
"display_name": "Operations Hub",
"description": "Operations aspect hub for operational truth, service-catalog records, readiness evidence, and migration gates.",
"domain": "operations",
"hub_kind": "aspect",
"status": "active",
"reuse_surface_id": "capability.operations.ops-hub",
"contract_version_min": "0.1.0",
"contract_version_max": "0.1.0",
"vsm_system": "operations",
"vsm_function": "coordination"
},
"manifest": {
"manifest_version": "0.1.0",
"schema_version": "0.1.0",
"reuse_surface_id": "capability.operations.ops-hub",
"provides": [
"capability.operations.ops-hub",
"capability.operations.service-catalog"
],
"consumes": [
"port.registry",
"port.messaging",
"port.events.interaction",
"port.projection.query",
"port.policy"
],
"events_emitted": [
"ops.endpoint.verified"
],
"events_consumed": [
"hub.progress.recorded"
],
"endpoints": [
{
"id": "api",
"discovery_key": "service.ops-hub.http"
},
{
"id": "framework-api",
"url": "https://hub.coulomb.social/api/v2"
},
{
"id": "docs",
"url": "https://forgejo.coulomb.social/coulomb/ops-hub/src/branch/main/docs/hub-extension.md"
}
],
"policy_scopes": [
"ops.catalog.read",
"ops.evidence.write"
],
"widgets": [
{
"id": "ops-overview",
"kind": "widget",
"description": "Non-secret operations overview surface."
}
],
"operator_surfaces": [
{
"id": "ops-console",
"kind": "console",
"description": "Operator-facing operations console hosted by hub-core projections."
},
{
"id": "ops-bootstrap",
"kind": "cli",
"description": "Attended, idempotent registration and compatibility bootstrap."
}
]
}
}

View file

@ -1,4 +1,20 @@
version: 1
updated: '2026-06-16'
updated: '2026-08-31'
domain: helix_forge
capabilities: []
capabilities:
- id: capability.operations.ops-hub
name: Operations Hub Extension Contract
summary: Versioned hub-extension package and bootstrap client for operational truth, service-catalog records, readiness evidence, and migration gates.
vector: D3 / A1 / C1 / R1
domain: operations
status: reviewed
owner: ops-hub
path: registry/capabilities/capability.operations.ops-hub.md
tags:
- operations
- service-catalog
- readiness
- hub-extension
consumption_modes:
- contract package
- command-line bootstrap

View file

@ -0,0 +1,35 @@
#!/usr/bin/env python3
"""Run Ops Hub's package through a disposable hub-core reference runtime."""
from __future__ import annotations
import argparse
import json
import sys
from pathlib import Path
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--hub-core-repo", type=Path, default=Path("../hub-core"))
args = parser.parse_args()
sys.path.insert(0, str(args.hub_core_repo.resolve()))
from fastapi.testclient import TestClient
from hub_core.conformance import ConformanceHarness
from hub_core.runtime.app import create_app
from hub_core.runtime.config import RuntimeSettings
from hub_core.runtime.store import InMemoryPortStore
from ops_hub.extension_contract import load_extension_package
settings = RuntimeSettings(environment="test", backend="memory", allow_ephemeral=True)
target = TestClient(create_app(settings=settings, port_store=InMemoryPortStore()))
harness = ConformanceHarness(target)
harness.package = load_extension_package()
report = harness.run()
print(json.dumps(report.to_dict(), indent=2, sort_keys=True))
return 0 if report.passed else 1
if __name__ == "__main__":
raise SystemExit(main())

View file

@ -0,0 +1,50 @@
#!/usr/bin/env python3
"""Validate the owner package against hub-core's versioned schemas."""
from __future__ import annotations
import argparse
import json
from pathlib import Path
from jsonschema import Draft202012Validator, FormatChecker
from ops_hub.extension_contract import load_extension_package, validation_receipt
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--hub-core-repo", type=Path, default=Path("../hub-core"))
args = parser.parse_args()
root = (
args.hub_core_repo
/ "hub_core"
/ "contracts"
/ "helixforge_hub_extension"
/ "v0_1_0"
)
schemas = root / "schemas"
package = load_extension_package()
for key, schema_name in (
("descriptor", "hub-descriptor.schema.json"),
("manifest", "hub-manifest.schema.json"),
):
schema = json.loads((schemas / schema_name).read_text(encoding="utf-8"))
Draft202012Validator.check_schema(schema)
Draft202012Validator(schema, format_checker=FormatChecker()).validate(package[key])
catalog = json.loads((root / "catalogs" / "event-types.json").read_text(encoding="utf-8"))
known_events = {entry["type"] for entry in catalog["event_types"]}
declared_events = set(package["manifest"]["events_emitted"])
declared_events.update(package["manifest"]["events_consumed"])
unknown = sorted(declared_events - known_events)
if unknown:
raise SystemExit("events absent from hub-core catalog: " + ", ".join(unknown))
print(json.dumps(validation_receipt(), indent=2, sort_keys=True))
return 0
if __name__ == "__main__":
raise SystemExit(main())

View file

@ -0,0 +1,102 @@
"""Ops Hub's owner-side ``helixforge.hub-extension`` package helpers."""
from __future__ import annotations
import hashlib
import json
import re
from collections.abc import Mapping, Sequence
from pathlib import Path
from typing import Any
CONTRACT_ID = "helixforge.hub-extension"
CONTRACT_VERSION = "0.1.0"
REUSE_SURFACE_ID = "capability.operations.ops-hub"
PACKAGE_PATH = (
Path(__file__).resolve().parents[2]
/ "registry"
/ "hub-extension"
/ "v0.1.0"
/ "ops-hub.extension.json"
)
_SECRET_KEY = re.compile(
r"(?:^|_)(?:api_?(?:key|token)|access_?token|auth_?token|client_?secret|"
r"credential|passwd|password|private_?key|secret)(?:$|_)",
re.IGNORECASE,
)
_SECRET_VALUE = re.compile(
r"(?:postgres(?:ql)?|mysql|mariadb|mongodb(?:\+srv)?|redis)://"
r"[^\s/:]+:[^\s/@]+@|-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----",
re.IGNORECASE,
)
def load_extension_package(path: Path = PACKAGE_PATH) -> dict[str, Any]:
return json.loads(path.read_text(encoding="utf-8"))
def package_sha256(path: Path = PACKAGE_PATH) -> str:
return hashlib.sha256(path.read_bytes()).hexdigest()
def find_secret_violations(value: Any, path: str = "$") -> list[str]:
"""Return paths with secret-shaped keys/values without returning values."""
violations: list[str] = []
if isinstance(value, Mapping):
for key, child in value.items():
child_path = f"{path}.{key}"
if _SECRET_KEY.search(str(key)):
violations.append(child_path)
violations.extend(find_secret_violations(child, child_path))
elif isinstance(value, Sequence) and not isinstance(value, (str, bytes)):
for index, child in enumerate(value):
violations.extend(find_secret_violations(child, f"{path}[{index}]"))
elif isinstance(value, str) and _SECRET_VALUE.search(value):
violations.append(path)
return violations
def validate_owner_invariants(package: Mapping[str, Any]) -> None:
descriptor = package.get("descriptor")
manifest = package.get("manifest")
if not isinstance(descriptor, Mapping) or not isinstance(manifest, Mapping):
raise ValueError("package must contain descriptor and manifest objects")
if descriptor.get("contract_id") != CONTRACT_ID:
raise ValueError("unexpected extension contract id")
if descriptor.get("contract_version") != CONTRACT_VERSION:
raise ValueError("unexpected extension contract version")
if descriptor.get("hub_slug") != "ops-hub":
raise ValueError("descriptor is not owned by ops-hub")
if descriptor.get("reuse_surface_id") != REUSE_SURFACE_ID:
raise ValueError("descriptor reuse_surface_id is not canonical")
if manifest.get("reuse_surface_id") != REUSE_SURFACE_ID:
raise ValueError("descriptor and manifest reuse_surface_id differ")
if REUSE_SURFACE_ID not in manifest.get("provides", []):
raise ValueError("manifest does not provide its canonical capability")
if "capability.operations.service-catalog" not in manifest.get("provides", []):
raise ValueError("manifest omits the service-catalog retirement handoff")
if "ops.endpoint.verified" not in manifest.get("events_emitted", []):
raise ValueError("manifest omits its governed verification event")
violations = find_secret_violations(package)
if violations:
raise ValueError("secret-like material at " + ", ".join(violations))
def validation_receipt(path: Path = PACKAGE_PATH) -> dict[str, Any]:
package = load_extension_package(path)
validate_owner_invariants(package)
return {
"ok": True,
"contract_id": CONTRACT_ID,
"contract_version": CONTRACT_VERSION,
"package": str(path),
"sha256": package_sha256(path),
"reuse_surface_id": REUSE_SURFACE_ID,
"provides": package["manifest"]["provides"],
"events_emitted": package["manifest"]["events_emitted"],
"events_consumed": package["manifest"]["events_consumed"],
"secret_violations": [],
}

View file

@ -0,0 +1,51 @@
from __future__ import annotations
import json
import unittest
from ops_hub.extension_contract import (
CONTRACT_ID,
CONTRACT_VERSION,
PACKAGE_PATH,
REUSE_SURFACE_ID,
find_secret_violations,
load_extension_package,
package_sha256,
validate_owner_invariants,
validation_receipt,
)
class ExtensionContractTests(unittest.TestCase):
def test_owner_package_is_valid_and_versioned(self) -> None:
package = load_extension_package()
validate_owner_invariants(package)
self.assertEqual(package["descriptor"]["contract_id"], CONTRACT_ID)
self.assertEqual(package["descriptor"]["contract_version"], CONTRACT_VERSION)
self.assertEqual(package["manifest"]["reuse_surface_id"], REUSE_SURFACE_ID)
def test_package_is_canonical_json_and_receipt_is_non_secret(self) -> None:
package = load_extension_package()
self.assertEqual(package, json.loads(PACKAGE_PATH.read_text(encoding="utf-8")))
receipt = validation_receipt()
self.assertTrue(receipt["ok"])
self.assertEqual(len(package_sha256()), 64)
self.assertEqual(receipt["secret_violations"], [])
def test_secret_detection_reports_paths_without_values(self) -> None:
value = {
"nested": {"api_token": "do-not-return"},
"database": "postgresql://runtime:do-not-return@example.invalid/hub",
}
self.assertEqual(find_secret_violations(value), ["$.nested.api_token", "$.database"])
def test_service_catalog_handoff_and_event_boundary_are_declared(self) -> None:
manifest = load_extension_package()["manifest"]
self.assertIn("capability.operations.service-catalog", manifest["provides"])
self.assertEqual(manifest["events_emitted"], ["ops.endpoint.verified"])
self.assertEqual(manifest["events_consumed"], ["hub.progress.recorded"])
self.assertIn("port.events.interaction", manifest["consumes"])
if __name__ == "__main__":
unittest.main()

View file

@ -4,11 +4,25 @@ type: workplan
title: "Extension contract alignment"
domain: infotech
repo: ops-hub
status: proposed
status: finished
owner: codex
topic_slug: infotech
created: "2026-08-09"
updated: "2026-08-09"
updated: "2026-08-31"
reviewed_at: "2026-08-31"
reviewed_by: codex
reviewed_against_commit: "9bbbf2032daf257d786446217bad79dc051a529c"
quality_dor: DoR-Ok
quality_dor_at: "2026-08-31"
quality_dor_by: codex
quality_dod: DoD-Ok
quality_dod_at: "2026-08-31"
quality_dod_by: codex
quality_dod_note: >-
The owner-side 0.1.0 package is versioned and federated, passes hub-core's
schemas/catalog and all eight implemented conformance checks, and the
post-cutover production compatibility gate is green. Unimplemented framework
checks are live residual HUB-WP-0009 rather than reported as passing.
parent_project: prj-state-hub-retirement
parent_workplan: SHR-WP-0001
related:
@ -30,7 +44,7 @@ registration without secrets.
```task
id: OPS-WP-0003-T01
status: todo
status: done
priority: high
state_hub_task_id: "a938b0e2-912e-5126-aa6f-d63bdeebca5d"
```
@ -39,22 +53,50 @@ Produce hub descriptor + capability manifest referencing
`capability.infotech.ops-hub` (or current registry id), events emitted/consumed,
and non-secret endpoints.
**Completed 2026-08-31.** Published the owner-side
`helixforge.hub-extension` 0.1.0 package at
`registry/hub-extension/v0.1.0/ops-hub.extension.json`. It uses the current
hub-core fixture identity `capability.operations.ops-hub`, declares the
operations service-catalog handoff, named framework ports, emitted
`ops.endpoint.verified`, consumed `hub.progress.recorded`, and non-secret
discovery/documentation endpoints. The package checksum is
`d48bb22c88598af482a3a779b930d1269e5bd8fd9e245681e278f14c4bd064d0`.
The capability is now a reviewed federation entry (`D3 / A1 / C1 / R1`) rather
than an empty index. `docs/hub-extension.md` records that hub-core owns the
runtime while ops-hub owns operational vocabulary and records; the legacy
dash-separated event remains a compatibility spelling, not a rewrite target.
## Pass Tier 2 conformance against hub-core
```task
id: OPS-WP-0003-T02
status: todo
status: done
priority: high
state_hub_task_id: "1d1c422d-892c-5404-8d7f-a1f78c5cd87a"
```
When HUB-WP-0004 harness exists, run C1C10 checks; fix gaps in ops-hub.
**Completed 2026-08-31 with framework residuals.** The owner package validates
against hub-core's packaged Draft 2020-12 descriptor/manifest schemas and event
catalog with zero secret-shaped fields. Injecting that package into a disposable
hub-core runtime passed the complete implemented profile: Tier-2 C1, C3, C4,
C5, C6, C8 and Tier-3 F2/F3 (8/8).
Hub Core contract 0.1.0 explicitly does not automate C2, C7, C9, or C10; those
cannot be fixed honestly in an extension repository. They are residual-owned by
new proposed owner workplan `HUB-WP-0009`, covering registry resolution,
raw-port configuration policy, dependency-aware readiness, version negotiation,
and any remaining tenant-isolation split. It is registered as State Hub
workplan `0d6e94f3-fd15-5f57-af41-60f0b862da5e`. The report does not count
unsupported checks as passing.
## Bootstrap dual-run on consolidated runtime
```task
id: OPS-WP-0003-T03
status: todo
status: done
priority: high
state_hub_task_id: "947306d4-8a00-5cd6-8c6d-1f266d45055c"
```
@ -62,8 +104,23 @@ state_hub_task_id: "947306d4-8a00-5cd6-8c6d-1f266d45055c"
Verify bootstrap/smokes against hub-core-hosted `/api/v2` during CORE-WP-0010
dual-run and after cutover.
**Completed 2026-08-31.** `RAPPCOREHUB-WP-0002-T04` records the ops-hub
consumer gate passing against the public candidate during the S1S5 dual-run.
The production cutover and exercised rollback/forward recovery repeated the
consumer gates. A fresh post-cutover `make interhub-gate` now passes against
`https://hub.coulomb.social`: `/api/v2/hubs` fails closed with 401 for an
anonymous caller, `/api/v2/openapi.json` returns 200, and all four required
bootstrap resources are present.
No new authenticated bootstrap mutation was needed or performed. The routed
Inter-Hub operator-key lane is high-risk and attended
(`inter-hub-bootstrap-ssh`); repeating a successful bootstrap merely to obtain
fresh evidence would create credentials and production records without a
functional change. Existing idempotent bootstrap behavior remains covered by
the source tests, while the current production check is non-mutating.
## Acceptance
- [ ] Hub package artefacts present and versioned
- [ ] Tier 2 conformance green (or residual-owned gaps)
- [ ] Bootstrap works on consolidated runtime
- [x] Hub package artefacts present and versioned
- [x] Tier 2 conformance green (or residual-owned gaps)
- [x] Bootstrap works on consolidated runtime