Files
ops-bridge/workplans/BRIDGE-WP-0002-opscatalog-extension.md
tegwick af2d419bf6 chore: mark BRIDGE-WP-0001 and BRIDGE-WP-0002 workplans as completed
All 39 tasks marked done; both workstreams updated to completed status
in the State Hub and workplan files.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 03:37:32 +01:00

10 KiB
Raw Blame History

id, type, title, domain, repo, status, owner, topic_slug, state_hub_workstream_id, created, updated
id type title domain repo status owner topic_slug state_hub_workstream_id created updated
BRIDGE-WP-0002 workplan OpsCatalog Extension custodian ops-bridge completed Bernd custodian f38bfcdb-f115-4431-88b5-ce906a24199c 2026-03-11 2026-03-12

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-2729, 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>/
      domain.yaml                  # type: domain
      targets/
        <target>.yaml              # type: target
      bridges/
        <bridge>.yaml              # type: bridge
      docs/
        *.md                       # operations notes
  actors/
    <actor>.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

type: domain
id: coulombcore
name: CoulombCore Infrastructure
description: Core infrastructure domain for operational services
environment: production

target.yaml

type: target
id: state-hub
domain: coulombcore
kind: service
description: Infrastructure state coordination service
reachable_via:
  - state-hub-coulombcore

bridge.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

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

id: BRIDGE-WP-0002-T01
state_hub_task_id: 21b90574-a27c-467c-8e9d-d4029a659171
status: done
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

id: BRIDGE-WP-0002-T02
state_hub_task_id: 782b5b4d-1f3f-4e5d-ad46-dc57b345bda3
status: done
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

id: BRIDGE-WP-0002-T03
state_hub_task_id: 41fed4f8-7818-4ca1-bb48-6ac1089220e8
status: done
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

id: BRIDGE-WP-0002-T04
state_hub_task_id: 32946d15-5516-4599-8f27-8c653dec6786
status: done
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

id: BRIDGE-WP-0002-T05
state_hub_task_id: 6061a6eb-9966-4be9-aa5e-ea7edf7fd085
status: done
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

id: BRIDGE-WP-0002-T06
state_hub_task_id: a92d97c8-4eec-4dd5-9b90-d9c1cba813ac
status: done
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

id: BRIDGE-WP-0002-T07
state_hub_task_id: 23799377-64f2-4c13-aa72-364770d80f91
status: done
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

id: BRIDGE-WP-0002-T08
state_hub_task_id: d2313182-975f-409f-9d4f-ebabf66b44df
status: done
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

id: BRIDGE-WP-0002-T09
state_hub_task_id: f9e508db-a19f-42be-9437-b4bdeb00a534
status: done
priority: medium

Table columns: DOMAIN, TARGET, KIND, BRIDGES. --domain <name> filter. --json flag for automation. Requires catalog to be configured; clear error if catalog_path not set.

T10 — CLI: bridge targets show

id: BRIDGE-WP-0002-T10
state_hub_task_id: e288a1d3-d676-404a-a3eb-25dbb241502d
status: done
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

id: BRIDGE-WP-0002-T11
state_hub_task_id: 73899b70-b0ac-4f48-b362-cc2455a66f41
status: done
priority: medium

List all domains and a count of targets and bridges per domain.

T12 — CLI: bridge catalog validate

id: BRIDGE-WP-0002-T12
state_hub_task_id: e091daa2-7c20-4169-b634-1fcc469513ea
status: done
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

id: BRIDGE-WP-0002-T13
state_hub_task_id: 9f5f4f30-bfe6-40fd-b178-2fbb396816ee
status: done
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

id: BRIDGE-WP-0002-T14
state_hub_task_id: 5ccb2b4b-7ea5-4c38-8246-d59b8f7d4419
status: done
priority: medium

Fixture: minimal catalog directory with one domain, one target, one bridge. Test bridge up <catalog-bridge-name> resolves and starts tunnel.

T15 — Integration test: bridge targets output

id: BRIDGE-WP-0002-T15
state_hub_task_id: 72c9f686-c474-46c4-a759-bfd47e2d4211
status: done
priority: medium

Test bridge targets output matches catalog fixture. Test --json flag.

T16 — Integration test: bridge catalog validate

id: BRIDGE-WP-0002-T16
state_hub_task_id: 83c0734e-0dc2-49ce-8b6a-a4d5e26ff33a
status: done
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-2729 (identity integration) remain deferred — require external identity provider infrastructure.


Deferred

  • FR-2729 — 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.