generated from coulomb/repo-seed
feat(registry): complete ATLAS-WP-0002 T02, T03, T06
Some checks failed
validate-registry / validate (push) Has been cancelled
Some checks failed
validate-registry / validate (push) Has been cancelled
T02: remove inherited capability.infotech.repo-template and template consumer docs (statehub-register, template-validation-checklist); add capability.infotech.config-surface-atlas and rewrite capabilities.yaml. T03: seed 4 configuration surfaces (state-hub api-config, ops-warden routing-catalog, reuse-surface federation-sources, ops-bridge tunnel-config) with registry/indexes/surfaces.yaml; source-linked, no values, secret deps by reference. T06: add tools/validate_registry.py (schema + index gate), Makefile (make validate), and .github/workflows/validate.yml (GitHub + Gitea Actions); document in stack-and-commands. Verified malformed entries are rejected. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
## Stack
|
||||
|
||||
- **Language:** Markdown-first registry and planning repo (no application runtime)
|
||||
- **Key deps:** State Hub ADR-001 workplans, `registry/indexes/capabilities.yaml`
|
||||
- **Key deps:** State Hub ADR-001 workplans, `registry/indexes/{capabilities,surfaces}.yaml`,
|
||||
`schemas/surface-entry.schema.json` (validated with PyYAML + jsonschema)
|
||||
|
||||
## Dev Commands
|
||||
|
||||
@@ -13,16 +14,21 @@ cat SCOPE.md
|
||||
ls workplans/
|
||||
ls registry/
|
||||
|
||||
# Validate registry entries (from reuse-surface checkout)
|
||||
reuse-surface validate --root .
|
||||
|
||||
# Sanity-check markdown / registry edits
|
||||
git diff --check
|
||||
# Validate the registry (the CI gate — run after any registry/schema edit)
|
||||
make validate # schema + index + whitespace + reuse-surface
|
||||
python3 tools/validate_registry.py # schema + index consistency only
|
||||
git diff --check # whitespace / conflict markers
|
||||
reuse-surface validate --root . # capability federation (from reuse-surface checkout)
|
||||
|
||||
# After workplan or registry edits — from ~/state-hub
|
||||
make fix-consistency REPO=config-atlas
|
||||
```
|
||||
|
||||
**Install / test / lint / build / run:** not applicable — this repo has no
|
||||
application runtime. Verify changes with `git diff --check` and
|
||||
`reuse-surface validate` when registry files change.
|
||||
**Validation gate (CI):** `make validate` is the single gate run by agents and CI
|
||||
(`.github/workflows/validate.yml`, read by GitHub *and* Gitea Actions). It validates
|
||||
every `registry/surfaces/*.md` against `schemas/surface-entry.schema.json`
|
||||
(forbidding inline values/secrets), checks `registry/indexes/surfaces.yaml`
|
||||
consistency, and runs `git diff --check`. Requires `pip install pyyaml jsonschema`.
|
||||
|
||||
**Install / test / build / run:** not applicable — no application runtime. Verify
|
||||
changes with `make validate`.
|
||||
22
.github/workflows/validate.yml
vendored
Normal file
22
.github/workflows/validate.yml
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
# Registry validation gate (ATLAS-WP-0002-T06).
|
||||
# Runs on GitHub Actions and Gitea Actions (both read .github/workflows).
|
||||
name: validate-registry
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
validate:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.12"
|
||||
- name: Install validation dependencies
|
||||
run: pip install --quiet pyyaml jsonschema
|
||||
- name: Validate surface entries against schema + index
|
||||
run: python3 tools/validate_registry.py
|
||||
- name: Check whitespace / conflict markers
|
||||
run: git diff --check $(git hash-object -t tree /dev/null) -- .
|
||||
24
Makefile
Normal file
24
Makefile
Normal file
@@ -0,0 +1,24 @@
|
||||
# config-atlas — registry validation gate (ATLAS-WP-0002-T06)
|
||||
# Markdown-first repo: no build/run, only validation.
|
||||
|
||||
.PHONY: validate validate-schema validate-reuse validate-whitespace
|
||||
|
||||
# Full gate run by agents and CI.
|
||||
validate: validate-schema validate-whitespace validate-reuse
|
||||
@echo "validate: all checks passed"
|
||||
|
||||
# Surface entries validate against the JSON Schema; index is consistent.
|
||||
validate-schema:
|
||||
@python3 tools/validate_registry.py
|
||||
|
||||
# No trailing whitespace / conflict markers in staged or working tree.
|
||||
validate-whitespace:
|
||||
@git diff --check HEAD -- . && echo "validate-whitespace: OK"
|
||||
|
||||
# Capability registry federation validation (skipped if reuse-surface absent).
|
||||
validate-reuse:
|
||||
@if command -v reuse-surface >/dev/null 2>&1; then \
|
||||
reuse-surface validate --root . ; \
|
||||
else \
|
||||
echo "validate-reuse: reuse-surface CLI not on PATH — skipped" ; \
|
||||
fi
|
||||
@@ -1,104 +0,0 @@
|
||||
# statehub register — Consumer Guide
|
||||
|
||||
Use this guide when bootstrapping a new Coulomb repository from the `repo-seed`
|
||||
template and registering it with Custodian State Hub.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- State Hub API running locally (`cd ~/state-hub && make api`) or reachable via tunnel
|
||||
- `statehub` CLI installed from `~/state-hub` (`uv tool install .` or `uv run statehub`)
|
||||
- A git repository cloned or copied from `repo-seed` (or an equivalent scaffold)
|
||||
|
||||
## Quick start
|
||||
|
||||
From the new repository root:
|
||||
|
||||
```bash
|
||||
cd /path/to/new-repo
|
||||
|
||||
# Optional: skip LLM inference and supply facts manually
|
||||
statehub register \
|
||||
--domain <domain-slug> \
|
||||
--repo-slug <repo-slug> \
|
||||
--wp-prefix <PREFIX-WP> \
|
||||
--description "One-sentence repo purpose." \
|
||||
--no-llm
|
||||
|
||||
# Operator follow-up (from state-hub checkout)
|
||||
cd ~/state-hub
|
||||
make fix-consistency REPO=<repo-slug>
|
||||
```
|
||||
|
||||
`statehub register` is idempotent: existing files are not overwritten unless you
|
||||
pass `--force`.
|
||||
|
||||
## What register writes
|
||||
|
||||
`statehub register` inspects the repository, infers identity (optionally via
|
||||
`llm-connect`), and writes these files when absent:
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `INTENT.md` | Why the repository exists |
|
||||
| `SCOPE.md` | In/out scope and current state |
|
||||
| `AGENTS.md` | Codex/Grok agent instructions with repo identity placeholders filled |
|
||||
| `.custodian-brief.md` | Offline-safe session orientation |
|
||||
| `workplans/<PREFIX>-0001-statehub-bootstrap.md` | First workplan with T01–T03 bootstrap tasks |
|
||||
|
||||
It also registers the repo and host path through the State Hub API and records a
|
||||
progress milestone.
|
||||
|
||||
## Template extras (from repo-seed)
|
||||
|
||||
Cloning `repo-seed` provides additional scaffold not written by `register`:
|
||||
|
||||
| Path | Purpose |
|
||||
|------|---------|
|
||||
| `CLAUDE.md` + `.claude/rules/` | Claude Code agent instructions |
|
||||
| `registry/` | Capability registry scaffold |
|
||||
| `README.md`, `LICENSE`, `.gitignore` | Project metadata |
|
||||
| `.repo-classification.yaml` | Repo classification metadata |
|
||||
|
||||
After `register`, complete the bootstrap workplan (`*-0001-statehub-bootstrap.md`):
|
||||
|
||||
1. **T01** — Review and refine generated integration files
|
||||
2. **T02** — Document install/test/lint/build/run commands in agent instructions
|
||||
3. **T03** — Create the first real implementation workplan
|
||||
|
||||
## CLI reference
|
||||
|
||||
```
|
||||
statehub register [options]
|
||||
|
||||
--path PATH Repo directory (default: cwd)
|
||||
--domain SLUG State Hub domain slug
|
||||
--repo-slug SLUG Repo slug (auto-detected from directory name)
|
||||
--wp-prefix PREFIX Workplan prefix, e.g. DEMO-WP
|
||||
--description TEXT One-sentence repo description
|
||||
--intent TEXT Intent text when INTENT.md is absent
|
||||
--api-base URL State Hub API base (default: http://127.0.0.1:8000)
|
||||
--no-llm Skip LLM inference; use files and flags
|
||||
--force Overwrite generated files
|
||||
```
|
||||
|
||||
Environment overrides: `API_BASE`, `STATEHUB_REGISTER_LLM_PROVIDER`,
|
||||
`STATEHUB_REGISTER_LLM_MODEL`, `STATEHUB_REGISTER_LLM_API_KEY`,
|
||||
`STATEHUB_REGISTER_LLM_TIMEOUT`.
|
||||
|
||||
## fix-consistency
|
||||
|
||||
Workplans are canonical in repo files (ADR-001). After creating or updating
|
||||
workplan files, sync them into State Hub:
|
||||
|
||||
```bash
|
||||
cd ~/state-hub
|
||||
make fix-consistency REPO=<repo-slug>
|
||||
```
|
||||
|
||||
This rebuilds hub workstreams/tasks from files, updates `.custodian-brief.md`,
|
||||
and reports consistency findings (C-15 file/DB drift, C-16 remote behind, etc.).
|
||||
|
||||
## Validation
|
||||
|
||||
Use [template-validation-checklist.md](template-validation-checklist.md) to
|
||||
verify a bootstrapped repo against expected `statehub register` output.
|
||||
@@ -1,90 +0,0 @@
|
||||
# Template Validation Checklist
|
||||
|
||||
Validate a repository bootstrapped from `repo-seed` against `statehub register`
|
||||
output and Coulomb onboarding conventions.
|
||||
|
||||
**Validated:** 2026-06-24 against `statehub register` in `~/state-hub`.
|
||||
|
||||
---
|
||||
|
||||
## 1. Register with State Hub
|
||||
|
||||
- [ ] State Hub API is reachable (`curl -s http://127.0.0.1:8000/state/health`)
|
||||
- [ ] `statehub register` completes without error
|
||||
- [ ] Registration prints repo slug, domain, topic ID, and `make fix-consistency` hint
|
||||
- [ ] Progress milestone recorded (`Repo registered with State Hub: <slug>`)
|
||||
|
||||
## 2. Agent files (register output)
|
||||
|
||||
Confirm these files exist and contain repo-specific values (not `{PLACEHOLDER}` tokens):
|
||||
|
||||
- [ ] `INTENT.md` — governing purpose; derived from README or `--intent`
|
||||
- [ ] `SCOPE.md` — one-liner, in/out scope, current state
|
||||
- [ ] `AGENTS.md` — **Purpose**, **Domain**, **Repo slug**, **Topic ID**, **Workplan prefix**
|
||||
- [ ] `.custodian-brief.md` — domain, topic ID, bootstrap workplan reference
|
||||
|
||||
### AGENTS.md spot checks
|
||||
|
||||
- [ ] `**Repo slug:**` matches directory slug and State Hub registration
|
||||
- [ ] `**Workplan prefix:**` matches workplan file prefix (e.g. `DEMO-WP-`)
|
||||
- [ ] Session protocol references `cat .custodian-brief.md` and inbox curl examples
|
||||
- [ ] `make fix-consistency REPO=<slug>` documented for workplan edits
|
||||
|
||||
## 3. First workplan
|
||||
|
||||
- [ ] `workplans/<PREFIX>-0001-statehub-bootstrap.md` exists
|
||||
- [ ] Frontmatter: `id`, `type: workplan`, `status: ready`, `repo`, `domain`
|
||||
- [ ] Tasks T01 (review files), T02 (dev workflow), T03 (seed real workplan) present
|
||||
- [ ] T03 references `make fix-consistency REPO=<slug>`
|
||||
|
||||
## 4. Template extras (repo-seed scaffold)
|
||||
|
||||
Beyond register output, confirm template scaffold is present:
|
||||
|
||||
- [ ] `CLAUDE.md` includes `@.claude/rules/*` references
|
||||
- [ ] `.claude/rules/` contains session-protocol, workplan-convention, stack-and-commands
|
||||
- [ ] `registry/README.md` and `registry/indexes/capabilities.yaml` exist
|
||||
- [ ] `README.md` describes the repository purpose
|
||||
- [ ] `.gitignore` and `LICENSE` present
|
||||
|
||||
## 5. Bootstrap workplan completion
|
||||
|
||||
After register, complete `*-0001-statehub-bootstrap.md`:
|
||||
|
||||
- [ ] **T01** — Placeholders replaced; SCOPE refined for repo-specific boundaries
|
||||
- [ ] **T02** — `.claude/rules/stack-and-commands.md` lists real dev commands
|
||||
- [ ] **T03** — First implementation workplan created (`*-0002-*.md` or equivalent)
|
||||
- [ ] Workplan status set to `finished` when all tasks done
|
||||
|
||||
## 6. fix-consistency sync
|
||||
|
||||
- [ ] `make fix-consistency REPO=<slug>` run from `~/state-hub`
|
||||
- [ ] `.custodian-brief.md` updated with active workstreams (replaces register stub)
|
||||
- [ ] Hub workstreams/tasks match workplan file statuses
|
||||
- [ ] No blocking C-16 (repo behind remote) findings
|
||||
|
||||
## 7. Registry (optional)
|
||||
|
||||
When the repo exposes reusable behavior:
|
||||
|
||||
- [ ] Capability entry in `registry/capabilities/`
|
||||
- [ ] Row added to `registry/indexes/capabilities.yaml`
|
||||
- [ ] `reuse-surface validate --root .` passes
|
||||
|
||||
---
|
||||
|
||||
## repo-seed self-validation notes
|
||||
|
||||
`repo-seed` is the meta-template and intentionally differs in a few places:
|
||||
|
||||
| Item | repo-seed state | Consumer expectation |
|
||||
|------|-----------------|----------------------|
|
||||
| `INTENT.md` | Absent — `README.md` is canonical intent | Present after `register` |
|
||||
| `SCOPE.md` | Refined (no "generated by statehub register" banner) | Generated, then refined in T01 |
|
||||
| `.custodian-brief.md` | Maintained by `fix-consistency` | Register stub, then fix-consistency |
|
||||
| `REPO-WP-0001` | `finished` | `ready` until bootstrap complete |
|
||||
| `REPO-WP-0002` | Template validation (this checklist) | First domain-specific workplan |
|
||||
|
||||
All register-output structures were verified by running `write_registration_files`
|
||||
from `statehub_register.py` with `repo_slug=repo-seed`, `wp_prefix=REPO-WP`,
|
||||
`domain=infotech`.
|
||||
@@ -0,0 +1,128 @@
|
||||
---
|
||||
id: capability.infotech.config-surface-atlas
|
||||
name: Configuration Surface Atlas
|
||||
summary: Read-first, cross-kind map and evidence layer for configuration surfaces — what configures a system, who owns it, its scope, and where the source of truth lives.
|
||||
owner: config-atlas
|
||||
status: draft
|
||||
domain: infotech
|
||||
tags:
|
||||
- configuration
|
||||
- registry
|
||||
- control-plane
|
||||
- effective-config
|
||||
- evidence
|
||||
|
||||
maturity:
|
||||
discovery:
|
||||
current: D5
|
||||
target: D6
|
||||
confidence: medium
|
||||
rationale: >
|
||||
Intent, scope, layering model, competitive landscape, and a control-plane
|
||||
research digest are documented (INTENT, SCOPE, research/, wiki/, PRD,
|
||||
ArchitectureBlueprint). Boundaries vs sister repos are explicit.
|
||||
availability:
|
||||
current: A0
|
||||
target: A2
|
||||
confidence: medium
|
||||
rationale: >
|
||||
Markdown/YAML registry with a JSON Schema for entries; no runtime resolver
|
||||
or API (intentionally — resolution is delegated). Consumed informationally
|
||||
and by agents; a source-module validator exists under tools/.
|
||||
|
||||
external_evidence:
|
||||
completeness:
|
||||
level: C2
|
||||
confidence: low
|
||||
basis: scope_vs_intent_and_consumer_expectations
|
||||
satisfied_expectations:
|
||||
- configuration-surface entry schema (schemas/surface-entry.schema.json)
|
||||
- scope/precedence/merge model (docs/configuration-surface-schema.md)
|
||||
- canon mapping to InfoTechCanon (docs/canon-mapping.md)
|
||||
- seed configuration surfaces (registry/surfaces/)
|
||||
broken_expectations: []
|
||||
out_of_scope_expectations:
|
||||
- runtime effective-value resolution
|
||||
- configuration delivery or control execution
|
||||
- secret value storage
|
||||
reliability:
|
||||
level: R2
|
||||
confidence: low
|
||||
basis: consumer_quality_signals
|
||||
known_reliability_risks:
|
||||
- schema and surface seed are early; coverage is partial
|
||||
- ownership resolution to domain-tree not yet wired
|
||||
|
||||
discovery:
|
||||
intent: >
|
||||
Make the distributed configuration surface of the ecosystem discoverable,
|
||||
explainable, and governable — map the territory before controlling it.
|
||||
includes:
|
||||
- configuration-surface registry and entry schema
|
||||
- scope/layer ordering and explicit merge semantics
|
||||
- cross-repo relationship and effective-config path modelling
|
||||
- canon alignment and sister-repo boundary documentation
|
||||
excludes:
|
||||
- runtime resolver, delivery, or control plane
|
||||
- secret values or live configuration values
|
||||
- feature-availability runtime control (feature-control owns it)
|
||||
assumptions:
|
||||
- downstream repos remain authoritative for their own config
|
||||
- reuse-surface federation and the State Hub graph are available
|
||||
use_cases: []
|
||||
research_memos:
|
||||
- research/configuration-control-plane.md
|
||||
- docs/configuration-surface-schema.md
|
||||
|
||||
availability:
|
||||
current_level: A0
|
||||
target_level: A2
|
||||
current_artifacts:
|
||||
- registry/surfaces/
|
||||
- schemas/surface-entry.schema.json
|
||||
- docs/configuration-surface-schema.md
|
||||
- docs/canon-mapping.md
|
||||
- tools/validate_registry.py
|
||||
consumption_modes:
|
||||
- informational
|
||||
- source module
|
||||
|
||||
relations:
|
||||
depends_on:
|
||||
- capability.statehub.workstream-coordinate
|
||||
supports: []
|
||||
related_to:
|
||||
- capability.registry.register
|
||||
|
||||
evidence:
|
||||
documentation:
|
||||
- INTENT.md
|
||||
- SCOPE.md
|
||||
- specs/ProductRequirementsDocument.md
|
||||
- specs/ArchitectureBlueprint.md
|
||||
- docs/ecosystem-boundaries.md
|
||||
tests:
|
||||
- tools/validate_registry.py
|
||||
|
||||
consumer_guidance:
|
||||
recommended_for:
|
||||
- discovering what configures a system and who owns it
|
||||
- reasoning about defaults, precedence, and cross-repo config relationships
|
||||
not_recommended_for:
|
||||
- storing or resolving live configuration values
|
||||
- secret management or feature-flag runtime control
|
||||
known_limitations:
|
||||
- early-stage schema and partial surface coverage
|
||||
- effective-value resolution is out of scope by design
|
||||
---
|
||||
|
||||
# Configuration Surface Atlas
|
||||
|
||||
config-atlas indexes **configuration surfaces** — bounded, named places where
|
||||
configuration is defined, read, or overridden — as source-linked registry entries
|
||||
with ownership, kind, scope, and evidence. It is the read-first map and evidence
|
||||
layer of a configuration control plane; it does not resolve, deliver, or control
|
||||
configuration (see `SCOPE.md`, `docs/ecosystem-boundaries.md`).
|
||||
|
||||
See `docs/configuration-surface-schema.md` for the entry model and
|
||||
`docs/canon-mapping.md` for InfoTechCanon alignment.
|
||||
@@ -1,121 +0,0 @@
|
||||
---
|
||||
id: capability.infotech.repo-template
|
||||
name: Coulomb Repository Template
|
||||
summary: Bootstrap new git repositories with agent instructions, registry scaffold, and State Hub onboarding conventions.
|
||||
owner: repo-seed
|
||||
status: draft
|
||||
domain: infotech
|
||||
tags:
|
||||
- template
|
||||
- bootstrap
|
||||
- state-hub
|
||||
- onboarding
|
||||
|
||||
maturity:
|
||||
discovery:
|
||||
current: D3
|
||||
target: D5
|
||||
confidence: medium
|
||||
rationale: >
|
||||
Template purpose, consumer guide, and validation checklist are documented.
|
||||
Scope boundaries are explicit in SCOPE.md.
|
||||
availability:
|
||||
current: A3
|
||||
target: A4
|
||||
confidence: medium
|
||||
rationale: >
|
||||
Consumers clone or copy repo-seed and run statehub register. Template
|
||||
files are markdown/git artifacts without a hosted provisioning API.
|
||||
|
||||
external_evidence:
|
||||
completeness:
|
||||
level: C2
|
||||
confidence: medium
|
||||
basis: scope_vs_intent_and_consumer_expectations
|
||||
satisfied_expectations:
|
||||
- agent instruction scaffold (AGENTS.md, CLAUDE.md, .claude/rules/)
|
||||
- registry directory scaffold
|
||||
- statehub register consumer documentation
|
||||
- template validation checklist for bootstrap verification
|
||||
- bootstrap workplan pattern (WP-0001)
|
||||
broken_expectations: []
|
||||
out_of_scope_expectations:
|
||||
- automated repo creation on Gitea
|
||||
- runtime application code generation
|
||||
reliability:
|
||||
level: R2
|
||||
confidence: medium
|
||||
basis: consumer_quality_signals
|
||||
known_reliability_risks:
|
||||
- register output evolves with state-hub releases; checklist must be revalidated
|
||||
- LLM inference path depends on llm-connect availability
|
||||
|
||||
discovery:
|
||||
intent: >
|
||||
Give new Coulomb repositories a consistent starting point for agent
|
||||
coordination, capability registry growth, and State Hub workplan tracking.
|
||||
includes:
|
||||
- git template files for agent instructions and registry scaffold
|
||||
- documentation for statehub register usage
|
||||
- consumer validation checklist
|
||||
- bootstrap workplan convention
|
||||
excludes:
|
||||
- application runtime implementation
|
||||
- owning downstream project code
|
||||
assumptions:
|
||||
- consumers have access to state-hub CLI and API
|
||||
- workplans remain canonical in repo files (ADR-001)
|
||||
use_cases: []
|
||||
research_memos:
|
||||
- docs/statehub-register.md
|
||||
- docs/template-validation-checklist.md
|
||||
|
||||
availability:
|
||||
current_level: A3
|
||||
target_level: A4
|
||||
current_artifacts:
|
||||
- README.md
|
||||
- AGENTS.md
|
||||
- CLAUDE.md
|
||||
- .claude/rules/
|
||||
- registry/
|
||||
- docs/statehub-register.md
|
||||
- docs/template-validation-checklist.md
|
||||
consumption_modes:
|
||||
- git clone
|
||||
- informational
|
||||
|
||||
relations:
|
||||
depends_on:
|
||||
- capability.statehub.workstream-coordinate
|
||||
supports: []
|
||||
related_to:
|
||||
- capability.registry.register
|
||||
|
||||
evidence:
|
||||
documentation:
|
||||
- docs/statehub-register.md
|
||||
- docs/template-validation-checklist.md
|
||||
- SCOPE.md
|
||||
tests: []
|
||||
|
||||
consumer_guidance:
|
||||
recommended_for:
|
||||
- bootstrapping new Coulomb domain repositories
|
||||
- standardizing agent onboarding and workplan conventions
|
||||
not_recommended_for:
|
||||
- repos that already have mature agent instructions and hub registration
|
||||
- application templates with heavy code generation requirements
|
||||
known_limitations:
|
||||
- register must be run separately after cloning
|
||||
- fix-consistency requires operator access to state-hub checkout
|
||||
---
|
||||
|
||||
# Coulomb Repository Template
|
||||
|
||||
`repo-seed` is the canonical git template for new Coulomb repositories. Clone it,
|
||||
run `statehub register`, complete the bootstrap workplan, and sync with
|
||||
`make fix-consistency`.
|
||||
|
||||
See `docs/statehub-register.md` for the consumer workflow and
|
||||
`docs/template-validation-checklist.md` for verification steps.
|
||||
@@ -1,14 +1,14 @@
|
||||
version: 1
|
||||
updated: '2026-06-24'
|
||||
updated: '2026-06-26'
|
||||
domain: infotech
|
||||
capabilities:
|
||||
- id: capability.infotech.repo-template
|
||||
name: Coulomb Repository Template
|
||||
summary: Bootstrap new git repositories with agent instructions, registry scaffold, and State Hub onboarding conventions.
|
||||
vector: D3 / A3 / C2 / R2
|
||||
- id: capability.infotech.config-surface-atlas
|
||||
name: Configuration Surface Atlas
|
||||
summary: Read-first, cross-kind map and evidence layer for configuration surfaces — what configures a system, who owns it, its scope, and where the source of truth lives.
|
||||
vector: D5 / A0 / C2 / R2
|
||||
domain: infotech
|
||||
status: draft
|
||||
owner: repo-seed
|
||||
path: registry/capabilities/capability.infotech.repo-template.md
|
||||
tags: [template, bootstrap, state-hub, onboarding]
|
||||
consumption_modes: [git clone, informational]
|
||||
owner: config-atlas
|
||||
path: registry/capabilities/capability.infotech.config-surface-atlas.md
|
||||
tags: [configuration, registry, control-plane, effective-config, evidence]
|
||||
consumption_modes: [informational, source module]
|
||||
|
||||
40
registry/indexes/surfaces.yaml
Normal file
40
registry/indexes/surfaces.yaml
Normal file
@@ -0,0 +1,40 @@
|
||||
version: 1
|
||||
updated: '2026-06-26'
|
||||
domain: infotech
|
||||
surfaces:
|
||||
- id: surface.infotech.state-hub.api-config
|
||||
name: State Hub API configuration
|
||||
kind: app-config
|
||||
summary: Runtime configuration for the Custodian State Hub API (bind host/port, database URL, environment mode).
|
||||
owner: custodian
|
||||
status: active
|
||||
default_layer: company
|
||||
security_class: operational
|
||||
path: registry/surfaces/surface.infotech.state-hub.api-config.md
|
||||
- id: surface.infotech.ops-warden.routing-catalog
|
||||
name: ops-warden credential routing catalog
|
||||
kind: policy
|
||||
summary: Catalog mapping credential/access needs to their owning subsystem, consumed via `warden route`.
|
||||
owner: ops-warden
|
||||
status: active
|
||||
default_layer: company
|
||||
security_class: policy
|
||||
path: registry/surfaces/surface.infotech.ops-warden.routing-catalog.md
|
||||
- id: surface.infotech.reuse-surface.federation-sources
|
||||
name: reuse-surface federation sources
|
||||
kind: app-config
|
||||
summary: Federation roster and source list defining which registries reuse-surface aggregates.
|
||||
owner: reuse-surface
|
||||
status: active
|
||||
default_layer: company
|
||||
security_class: operational
|
||||
path: registry/surfaces/surface.infotech.reuse-surface.federation-sources.md
|
||||
- id: surface.infotech.ops-bridge.tunnel-config
|
||||
name: ops-bridge SSH tunnel configuration
|
||||
kind: infra-state
|
||||
summary: Declares the reverse SSH tunnels exposing State Hub and MCP services to remote machines.
|
||||
owner: ops-bridge
|
||||
status: active
|
||||
default_layer: installation
|
||||
security_class: operational
|
||||
path: registry/surfaces/surface.infotech.ops-bridge.tunnel-config.md
|
||||
@@ -0,0 +1,43 @@
|
||||
---
|
||||
id: surface.infotech.ops-bridge.tunnel-config
|
||||
name: ops-bridge SSH tunnel configuration
|
||||
kind: infra-state
|
||||
summary: Declares the reverse SSH tunnels (local/remote port maps) that expose State Hub and MCP services to remote machines.
|
||||
owner: ops-bridge
|
||||
status: active
|
||||
scope:
|
||||
allowed_layers: [company, environment, installation]
|
||||
default_layer: installation
|
||||
mutability: deploy-time
|
||||
security_class: operational
|
||||
schema:
|
||||
type: object
|
||||
validator: ~/ops-bridge/schemas/tunnel.schema.yaml
|
||||
sources:
|
||||
- repo: ops-bridge
|
||||
path: config/tunnels.yaml
|
||||
role: installation-overlay
|
||||
relations:
|
||||
consumed_by:
|
||||
- service.ops-bridge
|
||||
overrides: []
|
||||
depends_on_secret:
|
||||
- ops-bridge/ssh-cert
|
||||
related_to:
|
||||
- surface.infotech.state-hub.api-config
|
||||
evidence:
|
||||
last_seen: '2026-06-26'
|
||||
discovery_method: manual
|
||||
change_log_ref: ATLAS-WP-0002-T03
|
||||
---
|
||||
|
||||
# ops-bridge SSH tunnel configuration
|
||||
|
||||
ops-bridge maintains reverse SSH tunnels that expose the State Hub API and MCP
|
||||
endpoints to remote machines (the remote port map: State Hub API `:18000`, MCP
|
||||
`:18001`). This surface maps that tunnel configuration as **infra-state**.
|
||||
|
||||
- **Source of truth:** the `ops-bridge` repo tunnel config; SSH certs are a secret
|
||||
reference (`depends_on_secret`), signed by ops-warden, never stored here.
|
||||
- **Relation:** exposes `surface.infotech.state-hub.api-config` to remote workers.
|
||||
- **Mutability:** deploy-time — tunnel changes are brought up via `bridge up`.
|
||||
@@ -0,0 +1,44 @@
|
||||
---
|
||||
id: surface.infotech.ops-warden.routing-catalog
|
||||
name: ops-warden credential routing catalog
|
||||
kind: policy
|
||||
summary: Catalog mapping credential/access needs to their owning subsystem (who issues what), consumed via `warden route`.
|
||||
owner: ops-warden
|
||||
status: active
|
||||
scope:
|
||||
allowed_layers: [company, platform]
|
||||
default_layer: company
|
||||
mutability: deploy-time
|
||||
security_class: policy
|
||||
schema:
|
||||
type: object
|
||||
validator: ~/ops-warden/registry/routing/catalog.schema.yaml
|
||||
sources:
|
||||
- repo: ops-warden
|
||||
path: registry/routing/catalog.yaml
|
||||
role: company-baseline
|
||||
relations:
|
||||
consumed_by:
|
||||
- service.warden-cli
|
||||
overrides: []
|
||||
depends_on_secret: []
|
||||
related_to:
|
||||
- surface.infotech.state-hub.api-config
|
||||
evidence:
|
||||
last_seen: '2026-06-26'
|
||||
discovery_method: manual
|
||||
change_log_ref: ATLAS-WP-0002-T03
|
||||
---
|
||||
|
||||
# ops-warden credential routing catalog
|
||||
|
||||
The credential routing catalog answers "who owns this credential need?" — SSH certs
|
||||
(ops-warden), API keys/DB passwords (OpenBao), login/OIDC (key-cape), etc. It is a
|
||||
**routing policy** surface: it carries pointers, never secret values.
|
||||
|
||||
- **Source of truth:** `ops-warden/registry/routing/catalog.yaml`; consumed via
|
||||
`warden route find/show`.
|
||||
- **Boundary:** this surface maps the catalog's existence, owner, and scope; secret
|
||||
values are never stored here (`security_class: policy`, no `depends_on_secret`).
|
||||
- **Why indexed:** credential routing is high-frequency and high-risk; the atlas
|
||||
records where the routing policy lives and who owns it.
|
||||
@@ -0,0 +1,44 @@
|
||||
---
|
||||
id: surface.infotech.reuse-surface.federation-sources
|
||||
name: reuse-surface federation sources
|
||||
kind: app-config
|
||||
summary: Federation roster and source list that define which registries reuse-surface aggregates, including the reserved id namespaces.
|
||||
owner: reuse-surface
|
||||
status: active
|
||||
scope:
|
||||
allowed_layers: [company, platform, installation]
|
||||
default_layer: company
|
||||
mutability: hot-reloadable
|
||||
security_class: operational
|
||||
schema:
|
||||
type: object
|
||||
validator: ~/reuse-surface/schemas/federation.schema.yaml
|
||||
sources:
|
||||
- repo: reuse-surface
|
||||
path: registry/federation/sources.yaml
|
||||
role: company-baseline
|
||||
- repo: reuse-surface
|
||||
path: registry/federation/local-repo-roster.yaml
|
||||
role: installation-overlay
|
||||
relations:
|
||||
consumed_by:
|
||||
- service.reuse-surface-hub
|
||||
overrides: []
|
||||
depends_on_secret: []
|
||||
related_to:
|
||||
- surface.infotech.state-hub.api-config
|
||||
evidence:
|
||||
last_seen: '2026-06-26'
|
||||
discovery_method: manual
|
||||
change_log_ref: ATLAS-WP-0002-T03
|
||||
---
|
||||
|
||||
# reuse-surface federation sources
|
||||
|
||||
The federation sources configure which registries reuse-surface aggregates and the
|
||||
id namespaces each owns. config-atlas federates here as a typed peer (the `surface.*`
|
||||
namespace reservation is ATLAS-WP-0002-T05).
|
||||
|
||||
- **Source of truth:** `reuse-surface/registry/federation/{sources,local-repo-roster}.yaml`.
|
||||
- **Why indexed:** this is the surface that governs cross-registry interoperability;
|
||||
config-atlas's own discoverability depends on it.
|
||||
104
tools/validate_registry.py
Normal file
104
tools/validate_registry.py
Normal file
@@ -0,0 +1,104 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Validate config-atlas registry entries.
|
||||
|
||||
Gate run by agents and CI (ATLAS-WP-0002-T06). Checks:
|
||||
1. Every registry/surfaces/*.md frontmatter validates against
|
||||
schemas/surface-entry.schema.json (Draft 2020-12).
|
||||
2. Entries never inline a configuration value or secret value
|
||||
(enforced by additionalProperties:false in the schema).
|
||||
3. registry/indexes/surfaces.yaml is consistent with the entry files
|
||||
(same id set, and each declared path exists with a matching id).
|
||||
|
||||
Exit code 0 = pass, 1 = validation failure, 2 = setup error.
|
||||
Dependencies: PyYAML, jsonschema.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
try:
|
||||
import yaml
|
||||
from jsonschema import Draft202012Validator
|
||||
except ImportError as exc: # pragma: no cover
|
||||
print(f"setup error: missing dependency ({exc}). pip install pyyaml jsonschema", file=sys.stderr)
|
||||
raise SystemExit(2)
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
SCHEMA_PATH = ROOT / "schemas" / "surface-entry.schema.json"
|
||||
SURFACES_DIR = ROOT / "registry" / "surfaces"
|
||||
SURFACES_INDEX = ROOT / "registry" / "indexes" / "surfaces.yaml"
|
||||
|
||||
FRONTMATTER = re.compile(r"^---\n(.*?)\n---\n", re.S)
|
||||
|
||||
|
||||
def load_frontmatter(path: Path) -> dict:
|
||||
m = FRONTMATTER.match(path.read_text())
|
||||
if not m:
|
||||
raise ValueError(f"{path}: missing YAML frontmatter")
|
||||
data = yaml.safe_load(m.group(1))
|
||||
if not isinstance(data, dict):
|
||||
raise ValueError(f"{path}: frontmatter is not a mapping")
|
||||
return data
|
||||
|
||||
|
||||
def main() -> int:
|
||||
if not SCHEMA_PATH.exists():
|
||||
print(f"setup error: schema not found at {SCHEMA_PATH}", file=sys.stderr)
|
||||
return 2
|
||||
|
||||
schema = json.loads(SCHEMA_PATH.read_text())
|
||||
Draft202012Validator.check_schema(schema)
|
||||
validator = Draft202012Validator(schema)
|
||||
|
||||
errors: list[str] = []
|
||||
seen_ids: dict[str, Path] = {}
|
||||
|
||||
entry_files = sorted(SURFACES_DIR.glob("*.md")) if SURFACES_DIR.exists() else []
|
||||
for path in entry_files:
|
||||
try:
|
||||
fm = load_frontmatter(path)
|
||||
except ValueError as exc:
|
||||
errors.append(str(exc))
|
||||
continue
|
||||
for err in sorted(validator.iter_errors(fm), key=lambda e: list(e.path)):
|
||||
loc = "/".join(str(p) for p in err.path) or "(root)"
|
||||
errors.append(f"{path.name}: {loc}: {err.message}")
|
||||
sid = fm.get("id")
|
||||
if sid in seen_ids:
|
||||
errors.append(f"{path.name}: duplicate id '{sid}' (also {seen_ids[sid].name})")
|
||||
elif sid:
|
||||
seen_ids[sid] = path
|
||||
# filename should match the id for discoverability
|
||||
if sid and path.stem != sid:
|
||||
errors.append(f"{path.name}: filename does not match id '{sid}'")
|
||||
|
||||
# index consistency
|
||||
if SURFACES_INDEX.exists():
|
||||
index = yaml.safe_load(SURFACES_INDEX.read_text()) or {}
|
||||
indexed = {row.get("id"): row for row in index.get("surfaces", [])}
|
||||
for sid in indexed.keys() - seen_ids.keys():
|
||||
errors.append(f"surfaces.yaml: id '{sid}' indexed but no entry file found")
|
||||
for sid in seen_ids.keys() - indexed.keys():
|
||||
errors.append(f"surfaces.yaml: entry '{sid}' present but not indexed")
|
||||
for sid, row in indexed.items():
|
||||
declared = row.get("path")
|
||||
if declared and not (ROOT / declared).exists():
|
||||
errors.append(f"surfaces.yaml: '{sid}' path '{declared}' does not exist")
|
||||
elif entry_files:
|
||||
errors.append("registry/indexes/surfaces.yaml missing but surface entries exist")
|
||||
|
||||
if errors:
|
||||
print(f"FAIL: {len(errors)} problem(s) in registry validation:", file=sys.stderr)
|
||||
for e in errors:
|
||||
print(f" - {e}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
print(f"OK: {len(entry_files)} surface entr{'y' if len(entry_files)==1 else 'ies'} valid; index consistent.")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -98,11 +98,17 @@ merge rules.
|
||||
|
||||
```task
|
||||
id: ATLAS-WP-0002-T02
|
||||
status: todo
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "2d8e41e9-ba93-4a1a-862b-993da03df1f9"
|
||||
```
|
||||
|
||||
Result 2026-06-26: Removed `capability.infotech.repo-template` and the inherited
|
||||
template consumer docs (`docs/statehub-register.md`,
|
||||
`docs/template-validation-checklist.md`). Added
|
||||
`capability.infotech.config-surface-atlas` and rewrote
|
||||
`registry/indexes/capabilities.yaml` to list only config-atlas-owned entries.
|
||||
|
||||
Remove `capability.infotech.repo-template` and other `repo-seed` artifacts from
|
||||
`registry/`. Add the config-atlas capability entry and update
|
||||
`registry/indexes/capabilities.yaml`. Relocate or delete inherited template
|
||||
@@ -118,11 +124,17 @@ references (e.g. `registry/README.md` points at reuse-surface templates).
|
||||
|
||||
```task
|
||||
id: ATLAS-WP-0002-T03
|
||||
status: todo
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "9b8bb1c2-a6ee-4b6e-91a4-2cd902fb52ff"
|
||||
```
|
||||
|
||||
Result 2026-06-26: Created `registry/indexes/surfaces.yaml` and seeded 4 surfaces:
|
||||
state-hub api-config (app-config), ops-warden routing-catalog (policy),
|
||||
reuse-surface federation-sources (app-config), ops-bridge tunnel-config
|
||||
(infra-state). All source-linked, no values; secret deps recorded as references
|
||||
(`depends_on_secret`). All validate via the T06 gate.
|
||||
|
||||
Create `registry/surfaces/` and `registry/indexes/surfaces.yaml`. Hand-author 3–5
|
||||
high-value configuration surfaces already present in the ecosystem (e.g. State Hub
|
||||
API config, warden routing catalog, reuse-surface registry layout) with `surface.*`
|
||||
@@ -157,11 +169,18 @@ federation mechanism. Coordinate via reuse-surface federation docs
|
||||
|
||||
```task
|
||||
id: ATLAS-WP-0002-T06
|
||||
status: todo
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "da6e44a7-ed87-433e-b183-f926e7e0caf8"
|
||||
```
|
||||
|
||||
Result 2026-06-26: Added `tools/validate_registry.py` (schema + index-consistency
|
||||
gate; forbids inline values via additionalProperties:false), a `Makefile`
|
||||
(`make validate` = schema + whitespace + reuse-surface), and
|
||||
`.github/workflows/validate.yml` (runs on GitHub & Gitea Actions). Documented in
|
||||
`.claude/rules/stack-and-commands.md`. Verified: 4 seed surfaces pass; a malformed
|
||||
entry (bad kind, inline `value`, unindexed) is rejected with rc=1.
|
||||
|
||||
Wire registry validation to run on every change: `reuse-surface validate --root .`,
|
||||
surface-entry schema validation (T01), and `git diff --check` (PRD FR-9, NFR-6).
|
||||
Document the check in `AGENTS.md` / `.claude/rules/stack-and-commands.md` so agents
|
||||
|
||||
Reference in New Issue
Block a user