From 2c7c440ea753e8fea2cead6739a6baee7e2f9b02 Mon Sep 17 00:00:00 2001 From: tegwick Date: Wed, 11 Mar 2026 22:00:09 +0100 Subject: [PATCH] docs: add BRIDGE-WP-0002 OpsCatalog extension workplan MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 7-phase plan covering catalog data models, loader, validator, bridge resolver (inline-first with catalog fallback), bridge targets and bridge catalog CLI commands, and integration tests. 16 tasks registered in Custodian State Hub (workstream bridge-wp-0002). Covers OpsCatalog FRS FR-1–15 and OpsBridge FRS FR-21–23. Co-Authored-By: Claude Sonnet 4.6 --- .../BRIDGE-WP-0002-opscatalog-extension.md | 404 ++++++++++++++++++ 1 file changed, 404 insertions(+) create mode 100644 workplans/BRIDGE-WP-0002-opscatalog-extension.md diff --git a/workplans/BRIDGE-WP-0002-opscatalog-extension.md b/workplans/BRIDGE-WP-0002-opscatalog-extension.md new file mode 100644 index 0000000..c0f9a67 --- /dev/null +++ b/workplans/BRIDGE-WP-0002-opscatalog-extension.md @@ -0,0 +1,404 @@ +--- +id: BRIDGE-WP-0002 +type: workplan +title: "OpsCatalog Extension" +domain: custodian +repo: ops-bridge +status: active +owner: Bernd +topic_slug: custodian +state_hub_workstream_id: f38bfcdb-f115-4431-88b5-ce906a24199c +created: "2026-03-11" +updated: "2026-03-11" +--- + +# BRIDGE-WP-0002 — OpsCatalog Extension + +**Scope:** Implement OpsCatalog as a Git-backed YAML knowledge repository and +integrate it with the `bridge` CLI. +**Depends on:** BRIDGE-WP-0001 complete (bridge CLI operational). +**Out of scope:** Identity provider integration (FR-27–29, deferred indefinitely). + +--- + +## Goal + +Deliver the OpsCatalog subsystem: a structured YAML catalog of operations +domains, targets, bridges, and actor classes stored in a Git repository. +OpsBridge loads the catalog at runtime to resolve bridge identifiers, orient +operators, and expose the `bridge targets` and `bridge catalog` commands. + +--- + +## Reference Documents + +| Document | Location | +|---|---| +| OpsCatalog Spec (PRD + FRS + Schemas) | `wiki/OpsCatalogSpecification.md` | +| OpsBridge FRS (deferred FRs) | `wiki/OpsBridgeFrs.md` §5.8, §5.10 | +| CLAUDE.md | `CLAUDE.md` | + +--- + +## Architecture Summary + +``` +~/.config/bridge/tunnels.yaml + catalog_path: ~/ops-catalog # path to the OpsCatalog Git repo + +ops-catalog/ # separate Git repo, consumed by bridge + domains/ + / + domain.yaml # type: domain + targets/ + .yaml # type: target + bridges/ + .yaml # type: bridge + docs/ + *.md # operations notes + actors/ + .yaml # type: actor + schemas/ + domain.schema.yaml + target.schema.yaml + bridge.schema.yaml + actor.schema.yaml + +src/bridge/ + catalog/ + __init__.py + loader.py # walk catalog_path, parse YAML files into typed objects + models.py # CatalogDomain, CatalogTarget, CatalogBridge, ActorClass + validator.py # validate catalog entries against schemas + resolver.py # resolve tunnel name → CatalogBridge → TunnelConfig +``` + +**Integration points with existing bridge code:** +- `config.py`: read `catalog_path` from `tunnels.yaml`; pass to catalog loader +- `manager.py`: use `resolver.py` to look up bridge config from catalog when + tunnel is not defined inline in `tunnels.yaml` +- `cli.py`: add `bridge targets` and `bridge catalog` commands + +--- + +## YAML Schemas + +### domain.yaml +```yaml +type: domain +id: coulombcore +name: CoulombCore Infrastructure +description: Core infrastructure domain for operational services +environment: production +``` + +### target.yaml +```yaml +type: target +id: state-hub +domain: coulombcore +kind: service +description: Infrastructure state coordination service +reachable_via: + - state-hub-coulombcore +``` + +### bridge.yaml +```yaml +type: bridge +id: state-hub-coulombcore +domain: coulombcore +target: state-hub +description: Operations bridge for state hub diagnostics +access_method: ssh-reverse +host: coulombcore.local +remote_port: 18000 +local_port: 8000 +ssh_user: ubuntu +ssh_key: ~/.ssh/id_ops +actor: agent.claude-coulombcore +health_check: + url: http://127.0.0.1:18000/health + interval_seconds: 30 + timeout_seconds: 5 +reconnect: + max_attempts: 0 + backoff_initial: 5 + backoff_max: 60 +``` + +### actor.yaml +```yaml +type: actor +id: agent.claude-remediator +class: automation +description: Automated remediation agent +``` + +--- + +## Phase 1 — Catalog Data Models + +**Acceptance:** All catalog YAML types parse into typed Python objects. + +### T01 — Define catalog dataclasses in catalog/models.py + +```task +id: BRIDGE-WP-0002-T01 +state_hub_task_id: 21b90574-a27c-467c-8e9d-d4029a659171 +status: todo +priority: high +``` + +Define `CatalogDomain`, `CatalogTarget`, `CatalogBridge`, `ActorClass` dataclasses. +`CatalogBridge` must be mergeable with `TunnelConfig` (catalog supplies defaults; +inline `tunnels.yaml` entries can override). + +--- + +## Phase 2 — Catalog Loader (FR-14) + +**Acceptance:** `catalog.load(path)` returns a populated `Catalog` object from a +directory tree; unknown `type:` values are skipped with a warning. + +### T02 — Implement catalog/loader.py + +```task +id: BRIDGE-WP-0002-T02 +state_hub_task_id: 782b5b4d-1f3f-4e5d-ad46-dc57b345bda3 +status: todo +priority: high +``` + +Walk `catalog_path` recursively, parse every `*.yaml` file, dispatch on `type:` +field. Build in-memory index: domains, targets, bridges, actors. + +### T03 — Unit tests for catalog loader + +```task +id: BRIDGE-WP-0002-T03 +state_hub_task_id: 41fed4f8-7818-4ca1-bb48-6ac1089220e8 +status: todo +priority: medium +``` + +Test: full catalog directory fixture loads correctly; missing required field raises +clear error; unknown type is skipped; empty catalog returns empty index. + +--- + +## Phase 3 — Catalog Validation (FR-15) + +**Acceptance:** `bridge catalog validate` exits non-zero and prints all violations +when the catalog contains invalid entries. + +### T04 — Implement catalog/validator.py + +```task +id: BRIDGE-WP-0002-T04 +state_hub_task_id: 32946d15-5516-4599-8f27-8c653dec6786 +status: todo +priority: medium +``` + +Validate required fields per type. Cross-reference checks: target's `domain` must +exist; target's `reachable_via` bridge IDs must exist; bridge's `target` and +`domain` must exist; actor referenced by bridge must exist. + +### T05 — Unit tests for catalog validation + +```task +id: BRIDGE-WP-0002-T05 +state_hub_task_id: 6061a6eb-9966-4be9-aa5e-ea7edf7fd085 +status: todo +priority: medium +``` + +Test: valid catalog passes; dangling `reachable_via` reference fails; missing +required field fails. + +--- + +## Phase 4 — Bridge Resolver (FR-2 integration) + +**Acceptance:** `bridge up state-hub-coulombcore` resolves the bridge config from +the catalog when no inline entry exists in `tunnels.yaml`. + +### T06 — Implement catalog/resolver.py + +```task +id: BRIDGE-WP-0002-T06 +state_hub_task_id: a92d97c8-4eec-4dd5-9b90-d9c1cba813ac +status: todo +priority: high +``` + +`resolve(name, catalog, inline_config) → TunnelConfig`. Lookup order: inline +`tunnels.yaml` entry wins; fall back to catalog bridge by ID. Merge catalog +bridge fields into `TunnelConfig`. Raise `BridgeNotFound` if neither source +has the name. + +### T07 — Integrate resolver into config.py and manager.py + +```task +id: BRIDGE-WP-0002-T07 +state_hub_task_id: 23799377-64f2-4c13-aa72-364770d80f91 +status: todo +priority: high +``` + +Read `catalog_path` from `tunnels.yaml` (optional; catalog disabled if absent). +Pass resolved `TunnelConfig` to `TunnelManager` unchanged — manager stays +catalog-unaware. + +### T08 — Unit tests for resolver + +```task +id: BRIDGE-WP-0002-T08 +state_hub_task_id: d2313182-975f-409f-9d4f-ebabf66b44df +status: todo +priority: medium +``` + +Test: inline entry takes precedence; catalog fallback works; inline overrides +catalog fields; missing name raises `BridgeNotFound`. + +--- + +## Phase 5 — CLI: bridge targets (FR-21, FR-22, FR-23) + +**Acceptance:** `bridge targets` prints a table of domains, targets, and which +bridges provide access to each target. + +### T09 — CLI: bridge targets command + +```task +id: BRIDGE-WP-0002-T09 +state_hub_task_id: f9e508db-a19f-42be-9437-b4bdeb00a534 +status: todo +priority: medium +``` + +Table columns: `DOMAIN`, `TARGET`, `KIND`, `BRIDGES`. `--domain ` filter. +`--json` flag for automation. Requires catalog to be configured; clear error if +`catalog_path` not set. + +### T10 — CLI: bridge targets show + +```task +id: BRIDGE-WP-0002-T10 +state_hub_task_id: e288a1d3-d676-404a-a3eb-25dbb241502d +status: todo +priority: low +``` + +Show full metadata for a single target: domain, kind, description, reachable_via +bridges, and any operations notes from `docs/*.md` files in the domain directory. + +--- + +## Phase 6 — CLI: bridge catalog commands + +**Acceptance:** Operators can inspect and validate the catalog from the CLI. + +### T11 — CLI: bridge catalog list + +```task +id: BRIDGE-WP-0002-T11 +state_hub_task_id: 73899b70-b0ac-4f48-b362-cc2455a66f41 +status: todo +priority: medium +``` + +List all domains and a count of targets and bridges per domain. + +### T12 — CLI: bridge catalog validate + +```task +id: BRIDGE-WP-0002-T12 +state_hub_task_id: e091daa2-7c20-4169-b634-1fcc469513ea +status: todo +priority: medium +``` + +Run `validator.py` and print all violations. Exit 0 if clean, 1 if violations +found. Useful in CI pipelines for the catalog repo. + +### T13 — CLI: bridge catalog show + +```task +id: BRIDGE-WP-0002-T13 +state_hub_task_id: 9f5f4f30-bfe6-40fd-b178-2fbb396816ee +status: todo +priority: low +``` + +Print full resolved bridge metadata including target and domain context. + +--- + +## Phase 7 — Integration Tests + +**Acceptance:** `uv run pytest` passes cleanly with catalog fixtures. + +### T14 — Integration test: catalog load and resolve + +```task +id: BRIDGE-WP-0002-T14 +state_hub_task_id: 5ccb2b4b-7ea5-4c38-8246-d59b8f7d4419 +status: todo +priority: medium +``` + +Fixture: minimal catalog directory with one domain, one target, one bridge. +Test `bridge up ` resolves and starts tunnel. + +### T15 — Integration test: bridge targets output + +```task +id: BRIDGE-WP-0002-T15 +state_hub_task_id: 72c9f686-c474-46c4-a759-bfd47e2d4211 +status: todo +priority: medium +``` + +Test `bridge targets` output matches catalog fixture. Test `--json` flag. + +### T16 — Integration test: bridge catalog validate + +```task +id: BRIDGE-WP-0002-T16 +state_hub_task_id: 83c0734e-0dc2-49ce-8b6a-a4d5e26ff33a +status: todo +priority: medium +``` + +Test clean catalog exits 0; catalog with a dangling reference exits 1 with a +clear message. + +--- + +## FRS Traceability + +| FRS Requirement Group | Phase | +|---|---| +| FR-14 — Catalog retrieval | 2 | +| FR-15 — Catalog validation | 3 | +| FR-1 to FR-3 — Domain management | 2, 5 | +| FR-4 to FR-6 — Target management | 2, 5 | +| FR-7 to FR-9 — Bridge definition | 2, 4 | +| FR-10 to FR-11 — Actor classification | 2 | +| FR-12 to FR-13 — Operational annotations | 5 (docs/*.md) | +| FR-21 to FR-23 — Infrastructure target discovery (OpsBridge FRS) | 5 | + +*FR-27–29 (identity integration) remain deferred — require external identity +provider infrastructure.* + +--- + +## Deferred + +- **FR-27–29** — Identity provider integration (privacyIDEA / SSH CA) — separate + workplan when identity infrastructure is available. +- **Operations notes search** — full-text search across `docs/*.md` files — nice + to have, not required for MVP.