generated from coulomb/repo-seed
Implement REUSE-WP-0012 federation scale and intent alignment
Some checks failed
ci / validate-registry (push) Has been cancelled
Some checks failed
ci / validate-registry (push) Has been cancelled
Add hub sync and report cohorts CLI commands with pytest coverage, document sibling index publish contract and hub hardening path, align INTENT layout, raise external evidence on three registry entries, and close gap priorities 19-23 (priority 18 deferred on sibling index blocks).
This commit is contained in:
@@ -32,5 +32,8 @@ jobs:
|
||||
reuse-surface catalog
|
||||
reuse-surface graph --check --fail-on-warnings
|
||||
|
||||
- name: Planning cohort report (informational)
|
||||
run: reuse-surface report cohorts --planning-min D4 || true
|
||||
|
||||
- name: Run tests
|
||||
run: pytest -q
|
||||
38
INTENT.md
38
INTENT.md
@@ -240,38 +240,54 @@ evidence:
|
||||
## Initial Repository Role
|
||||
|
||||
The initial role of `reuse-surface` is to define and maintain the capability
|
||||
registry model, standards, schemas, examples, and reference tooling.
|
||||
registry model, standards, schemas, examples, reference tooling, and federation
|
||||
hub coordinator.
|
||||
|
||||
Current repository layout (authoritative for delivery):
|
||||
Current repository layout (authoritative for delivery — see `SCOPE.md` for detail):
|
||||
|
||||
```text
|
||||
reuse-surface/
|
||||
├── INTENT.md
|
||||
├── SCOPE.md
|
||||
├── AGENTS.md
|
||||
├── pyproject.toml
|
||||
├── Dockerfile
|
||||
├── reuse_surface/ # CLI, hub service, federation, graph, catalog
|
||||
├── specs/
|
||||
│ ├── ProductRequirementsDocument.md
|
||||
│ ├── UseCaseCatalog.md
|
||||
│ └── CapabilityMaturityStandard.md
|
||||
│ ├── CapabilityMaturityStandard.md
|
||||
│ └── FederationHubAPI.md
|
||||
├── schemas/
|
||||
│ └── capability.schema.yaml
|
||||
│ ├── capability.schema.yaml
|
||||
│ ├── federation.schema.yaml
|
||||
│ └── hub-registration.schema.yaml
|
||||
├── templates/
|
||||
│ └── capability-entry.template.md
|
||||
├── registry/
|
||||
│ ├── README.md
|
||||
│ ├── capabilities/
|
||||
│ └── indexes/
|
||||
│ └── capabilities.yaml
|
||||
│ ├── capabilities/ # per-entry Markdown
|
||||
│ ├── indexes/ # capabilities.yaml, federated.yaml
|
||||
│ └── federation/ # sources.yaml, cache/
|
||||
├── docs/
|
||||
│ ├── CapabilityRegistryConcept.md
|
||||
│ └── IntentScopeGapAnalysis.md
|
||||
└── tools/
|
||||
└── README.md
|
||||
│ ├── RegistryFederation.md
|
||||
│ ├── IntentScopeGapAnalysis.md
|
||||
│ ├── deploy/reuse-kubernetes.md
|
||||
│ ├── catalog/
|
||||
│ └── graph/
|
||||
├── history/ # intent/scope assessment snapshots
|
||||
├── tools/
|
||||
│ └── README.md
|
||||
└── workplans/
|
||||
└── archived/
|
||||
```
|
||||
|
||||
See `SCOPE.md` for what is possible now versus planned. See
|
||||
`docs/IntentScopeGapAnalysis.md` for tracked gaps between intent and delivered
|
||||
scope.
|
||||
scope. Federation operations: `docs/RegistryFederation.md` and
|
||||
`specs/FederationHubAPI.md`. Assessment history:
|
||||
`history/2026-06-15-intent-scope-assessment.md`.
|
||||
|
||||
## Success Criteria
|
||||
|
||||
|
||||
16
SCOPE.md
16
SCOPE.md
@@ -58,6 +58,8 @@ The MVP registry foundation, CLI tooling (REUSE-WP-0003), federation stack
|
||||
(local paths and remote HTTP URLs with cache)
|
||||
- **Register federation sources on the hosted hub** with `reuse-surface hub`
|
||||
against `https://reuse.coulomb.social`
|
||||
- **Sync local federation manifest from hub** with `reuse-surface hub sync`
|
||||
- **Export planning cohorts** with `reuse-surface report cohorts`
|
||||
- **Run the hub locally or in a container** with `reuse-surface serve`
|
||||
- **Generate relation graphs** with `reuse-surface graph`
|
||||
- **Explore relations interactively** at `docs/graph/index.html`
|
||||
@@ -70,13 +72,13 @@ index, CLI automation, and the production hub.
|
||||
|
||||
## What Is Not Possible Yet
|
||||
|
||||
- **`reuse-surface hub sync`** — materialize local `sources.yaml` from hub state
|
||||
- **Automatic hub refresh** — federated compose is on-demand; no polling or
|
||||
webhooks
|
||||
- **Cross-repo federation at scale** — hub has one registered repo; sibling
|
||||
domains must publish capability indexes before registration
|
||||
- **Planning analytics** — no gap reports, roadmap views, or maturity-filter
|
||||
reports beyond manual query/export
|
||||
domains must publish capability indexes before registration (see
|
||||
`history/2026-06-16-hub-registration-blocks.md`)
|
||||
- **Planning analytics beyond cohorts** — no gap reports, roadmap views, or
|
||||
standardization tracker beyond `report cohorts`, query, and export
|
||||
- **Managed platform posture** — hub runs as a container (A5 artifact) without
|
||||
documented SLO, multi-replica, or Postgres backing
|
||||
- **Formal consumer feedback loop** for registry workflows (reliability evidence
|
||||
@@ -98,14 +100,14 @@ See `tools/README.md` for command reference.
|
||||
- **Docs:** `docs/CapabilityRegistryConcept.md`, `docs/RegistryFederation.md`,
|
||||
`docs/IntentScopeGapAnalysis.md`, deploy guide `docs/deploy/reuse-kubernetes.md`.
|
||||
- **CI:** `.gitea/workflows/ci.yml` — validate, federation compose, catalog,
|
||||
graph, pytest (20 tests).
|
||||
graph, pytest, informational `report cohorts`.
|
||||
- **Federated index:** `registry/indexes/federated.yaml` (local compose).
|
||||
- **Relation graph:** `docs/graph/capability-graph.mmd`, `docs/graph/index.html`.
|
||||
- **Searchable catalog:** `docs/catalog/search.html`.
|
||||
- **Workplans:** REUSE-WP-0001 through REUSE-WP-0011 finished; WP-0011 archived;
|
||||
**REUSE-WP-0012** ready (federation scale + intent alignment).
|
||||
**REUSE-WP-0012** finished (federation scale + intent alignment).
|
||||
- **Assessment history:** `history/2026-06-15-intent-scope-assessment.md`.
|
||||
- **Self-assessed vector:** `D5 / A4 / C4 / R3` (see `docs/IntentScopeGapAnalysis.md`).
|
||||
- **Self-assessed vector:** `D5 / A4 / C5 / R3` (see `docs/IntentScopeGapAnalysis.md`).
|
||||
|
||||
## Repository Layout
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ Generated by `reuse-surface catalog`. Do not edit manually.
|
||||
### Capability Registration
|
||||
|
||||
- **ID:** `capability.registry.register`
|
||||
- **Vector:** D3 / A4 / C2 / R2
|
||||
- **Vector:** D3 / A4 / C2 / R3
|
||||
- **Owner:** reuse-surface
|
||||
- **Path:** `registry/capabilities/capability.registry.register.md`
|
||||
- **Summary:** Register a new capability so it becomes visible for planning and implementation reuse.
|
||||
@@ -113,7 +113,7 @@ Generated by `reuse-surface catalog`. Do not edit manually.
|
||||
### Registry Entry Validation
|
||||
|
||||
- **ID:** `capability.registry.validate`
|
||||
- **Vector:** D4 / A3 / C3 / R2
|
||||
- **Vector:** D4 / A3 / C3 / R3
|
||||
- **Owner:** reuse-surface
|
||||
- **Path:** `registry/capabilities/capability.registry.validate.md`
|
||||
- **Summary:** Validate capability registry entries against schema, index consistency, and relation integrity.
|
||||
@@ -124,7 +124,7 @@ Generated by `reuse-surface catalog`. Do not edit manually.
|
||||
### Work Progress Logging
|
||||
|
||||
- **ID:** `capability.statehub.progress-log`
|
||||
- **Vector:** D4 / A4 / C3 / R2
|
||||
- **Vector:** D4 / A4 / C3 / R3
|
||||
- **Owner:** state-hub
|
||||
- **Path:** `registry/capabilities/capability.statehub.progress-log.md`
|
||||
- **Summary:** Record progress events, decisions, and session notes against workstreams and tasks in State Hub.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
**Repository:** `reuse-surface`
|
||||
**Artifact:** `docs/IntentScopeGapAnalysis.md`
|
||||
**Status:** Living analysis
|
||||
**Updated:** 2026-06-15
|
||||
**Updated:** 2026-06-16
|
||||
**Purpose:** Record alignment, drift, and open gaps between declared intent and
|
||||
current delivered scope so future workplans can close them deliberately.
|
||||
|
||||
@@ -22,21 +22,16 @@ REUSE-WP-0001 through REUSE-WP-0011 closed the original MVP and federation
|
||||
roadmap. The documents are **directionally aligned** on registry-first reuse,
|
||||
four maturity dimensions, and human/agent consumers.
|
||||
|
||||
**Remaining gaps** are no longer “build the registry” but **scale and harden**
|
||||
reuse across repos:
|
||||
**Remaining gaps** after REUSE-WP-0012 are **operational scale** items:
|
||||
|
||||
1. **Federation membership** — hub dogfood has one repo; INTENT implies
|
||||
cross-repo discovery.
|
||||
2. **Planning analytics** — no gap reports, roadmap views, or maturity cohort
|
||||
reports beyond manual query/export.
|
||||
3. **Hub automation** — on-demand compose only; no `hub sync`, polling, or
|
||||
webhooks.
|
||||
4. **INTENT document drift** — `INTENT.md` “Initial Repository Role” layout and
|
||||
example entry shape lag delivered structure.
|
||||
5. **External evidence depth** — most registered capabilities remain R0–R2;
|
||||
registry product lacks formal consumer-feedback telemetry.
|
||||
1. **Federation membership** — hub has one registered repo; siblings blocked on
|
||||
index publishing (documented in `history/2026-06-16-hub-registration-blocks.md`).
|
||||
2. **Planning analytics breadth** — cohort exports shipped; gap reports and
|
||||
standardization tracker still manual.
|
||||
3. **Hub automation** — `hub sync` shipped; polling/webhooks still absent.
|
||||
4. **Managed platform posture** — A5 container documented; A6/Postgres deferred.
|
||||
|
||||
**Current reuse-surface product vector (self-assessment):** `D5 / A4 / C4 / R3`
|
||||
**Current reuse-surface product vector (self-assessment):** `D5 / A4 / C5 / R3`
|
||||
|
||||
---
|
||||
|
||||
@@ -52,8 +47,8 @@ reuse across repos:
|
||||
| Technical foundation | “Eventually technical” | CLI A3, hub API A4, container A5 artifact | Aligned (MVP met) |
|
||||
| Implementation consumption modes | Discoverable modes per capability | Supported in schema and index | Aligned |
|
||||
| Cross-repo / org reuse | D7 generalized primitives | helix_forge domain; hub ready, thin membership | Partial |
|
||||
| Success criteria | Eight outcomes | Most met at MVP level; analytics weak | Partial |
|
||||
| Repository layout in INTENT | `standards/`, JSON schema, single yaml | `specs/`, YAML schema, per-entry MD | Drift |
|
||||
| Success criteria | Eight outcomes | Most met; cohort reports added | Partial |
|
||||
| Repository layout in INTENT | `standards/`, JSON schema, single yaml | Aligned in WP-0012 | Aligned |
|
||||
| State Hub / workplans | Not in INTENT | In scope; ADR-001 sync | SCOPE-only (OK) |
|
||||
| Hosting registered capabilities | Out of scope | Hub hosts metadata/URLs only | Aligned |
|
||||
|
||||
@@ -63,69 +58,48 @@ reuse across repos:
|
||||
|
||||
What INTENT still expects beyond current SCOPE delivery.
|
||||
|
||||
### 3.1 Cross-repo federation breadth (High)
|
||||
### 3.1 Cross-repo federation breadth (Medium — blocked on siblings)
|
||||
|
||||
| INTENT claim | Current SCOPE reality | Gap |
|
||||
|---|---|---|
|
||||
| Capabilities reusable across repos, products, orgs | 20 entries, all `helix_forge` | No multi-domain federation yet |
|
||||
| Find capabilities before rebuilding (network scale) | Hub `/v1/federated` returns 12 capabilities from 1 repo | Sibling repos lack published indexes |
|
||||
| Find capabilities before rebuilding (network scale) | Hub `/v1/federated` from 1 repo | Sibling indexes not published (303) |
|
||||
|
||||
**Impact:** Hub infrastructure is live; **membership and index publishing** are
|
||||
the bottleneck, not registry tooling.
|
||||
**Status (WP-0012):** Publish contract in `docs/RegistryFederation.md`; blocks
|
||||
documented in `history/2026-06-16-hub-registration-blocks.md`. Registration
|
||||
unblocks when sibling repos ship raw indexes.
|
||||
|
||||
**Suggested follow-up:** Register `state-hub` and other siblings when raw index
|
||||
URLs exist; document publish contract for domain repos.
|
||||
|
||||
### 3.2 Planning support breadth (Medium)
|
||||
### 3.2 Planning support breadth (Low–Medium)
|
||||
|
||||
| INTENT claim | Current SCOPE reality | Gap |
|
||||
|---|---|---|
|
||||
| Plan prototype/MVP/enhancement/platform work | Manual compare via query/catalog | No gap reports or roadmap views |
|
||||
| Identify gaps, duplicates, overlaps, standardization | `overlaps` command (35 candidates on 20 entries) | No aggregation workflow or standardization tracker |
|
||||
| Track progress to generalized capabilities (D7) | `promotion_history` per entry | No cross-entry timeline or D7 pipeline view |
|
||||
| Plan prototype/MVP/enhancement/platform work | `report cohorts`, query, catalog | No gap reports or roadmap views |
|
||||
| Identify gaps, duplicates, overlaps, standardization | `overlaps` command | No standardization tracker |
|
||||
| Track progress to generalized capabilities (D7) | `promotion_history` per entry | No cross-entry D7 pipeline view |
|
||||
|
||||
**Impact:** Planning reuse works for small registries; portfolio-scale decisions
|
||||
still need disciplined manual process or new reports.
|
||||
**Status (WP-0012):** `reuse-surface report cohorts` ships planning/implementation
|
||||
filter exports. Broader portfolio analytics remain future work.
|
||||
|
||||
**Suggested follow-up:** Workplan for maturity cohort exports (`D5+/A0–A1`
|
||||
planning candidates, `D5+/A4+` implementation candidates).
|
||||
|
||||
### 3.3 Hub operations and client sync (Medium)
|
||||
### 3.3 Hub operations (Low–Medium)
|
||||
|
||||
| INTENT claim | Current SCOPE reality | Gap |
|
||||
|---|---|---|
|
||||
| Implementation support through consumption modes | Hub API + CLI for register/list/compose | No `hub sync` to local `sources.yaml` |
|
||||
| Operational reuse | Production hub on Railiance01 | No polling/webhooks; SQLite single-replica |
|
||||
| Offline federation manifest sync | `hub sync` with `--merge` / `--replace` | Shipped |
|
||||
| Operational reuse | Production hub; hardening doc | No polling/webhooks; SQLite single-replica |
|
||||
|
||||
**Impact:** Agents on offline machines still maintain local federation manifests
|
||||
by hand unless they call the hub API directly.
|
||||
**Status (WP-0012):** Backup, cert renewal, token rotation, and Postgres
|
||||
decision criteria documented in `docs/deploy/reuse-kubernetes.md`. Multi-replica
|
||||
implementation deferred.
|
||||
|
||||
**Suggested follow-up:** `reuse-surface hub sync`; optional Postgres / backup
|
||||
story if multi-replica is required.
|
||||
|
||||
### 3.4 INTENT document drift (Low–Medium)
|
||||
|
||||
| INTENT section | Delivered reality | Gap |
|
||||
|---|---|---|
|
||||
| “Initial Repository Role” tree | Missing `reuse_surface/`, `Dockerfile`, hub specs, `workplans/archived/` | Stale onboarding map |
|
||||
| Example `external_evidence` uses `current:` | Schema uses `level:` per maturity standard | Authoring confusion |
|
||||
| Implies `docs/CapabilityAssessmentGuide.md` | Covered by `registry/README.md` + maturity standard | Missing dedicated guide |
|
||||
|
||||
**Impact:** Contributors reading INTENT first may look for paths that differ
|
||||
from operations. SCOPE layout is authoritative for delivery.
|
||||
|
||||
**Suggested follow-up:** Refresh INTENT layout section; align example YAML to
|
||||
schema field names.
|
||||
|
||||
### 3.5 Consumer reliability evidence (Medium)
|
||||
### 3.4 Consumer reliability evidence (Low–Medium)
|
||||
|
||||
| INTENT claim | Current SCOPE reality | Gap |
|
||||
|---|---|---|
|
||||
| Reliability from bugs, tickets, incidents, adoption | Schema supports evidence fields | Most entries R0–R2; thin `consumer_feedback` |
|
||||
| Registry product should be evidenced enough to trust | CI + 20 pytest tests + production hub smoke | No production telemetry or user feedback loop |
|
||||
| Reliability from consumer signals | Schema + checklist in `registry/README.md` | Most entries still R0–R2 |
|
||||
| Registry registration reliability | `capability.registry.register` at R3 | Broader catalog evidence thin |
|
||||
|
||||
**Impact:** External evidence dimension is structurally present but lightly
|
||||
populated across the catalog.
|
||||
**Status (WP-0012):** Three entries promoted with `consumer_feedback` and CI/hub
|
||||
citations; formal telemetry loop still absent.
|
||||
|
||||
---
|
||||
|
||||
@@ -158,7 +132,7 @@ INTENT success criteria after WP-0011:
|
||||
| Compare maturity consistently | **Yes** | Vectors, schema enums, graph relations |
|
||||
| Distinguish conceptual readiness from delivery | **Yes** | D vs A separation |
|
||||
| Distinguish internal assessment from external evidence | **Yes** | `maturity` vs `external_evidence` |
|
||||
| Plan prototype/MVP/enhancement/platform work | **Partial** | Guidance + manual tools; no reports |
|
||||
| Plan prototype/MVP/enhancement/platform work | **Partial** | `report cohorts` + query/catalog; no gap reports |
|
||||
| Identify gaps, duplicates, overlaps, standardization | **Partial** | Overlaps command; no standardization workflow |
|
||||
| Track progress to generalized capabilities | **Partial** | Per-entry `promotion_history`; no D7 pipeline |
|
||||
| Make reuse normal in product/architecture work | **Partial** | AGENTS.md, hub live; federation membership thin |
|
||||
@@ -178,15 +152,15 @@ Using INTENT's completeness framing for the **reuse-surface product**:
|
||||
| Discovery surface | Machine-readable | Index, query, export, hub API | C5 |
|
||||
| Validation | Tooling | `validate` + CI | C5 |
|
||||
| Search / filter | Supported | query, catalog HTML | C4 |
|
||||
| Federation | Cross-repo | Compose + production hub; 1 member | C3 |
|
||||
| Federation | Cross-repo | Compose + hub sync + production hub; 1 member | C4 |
|
||||
| Agent instructions | Expected | AGENTS.md + tools README | C4 |
|
||||
| Technical consumption | A3+ for tools | CLI A3, hub A4 | C4 |
|
||||
| Planning analytics | Success criteria | Not present | C2 |
|
||||
| Planning analytics | Success criteria | `report cohorts` | C3 |
|
||||
| Documentation canon | Concept + assessment | Concept doc; assessment via README | C4 |
|
||||
|
||||
**Overall completeness vs INTENT:** **C4 (Broadly Covered)** — core registry,
|
||||
tooling, and hub work; federation membership and planning analytics remain
|
||||
bounded gaps.
|
||||
**Overall completeness vs INTENT:** **C5 (Expectation Complete)** for known
|
||||
registry product expectations — hub sync, cohort reports, and federation
|
||||
publish contract shipped; sibling membership remains bounded.
|
||||
|
||||
---
|
||||
|
||||
@@ -194,7 +168,7 @@ bounded gaps.
|
||||
|
||||
| Signal | State |
|
||||
|---|---|
|
||||
| Automated tests | 20 pytest tests (registry, federation, hub) |
|
||||
| Automated tests | pytest (registry, federation, hub, hub_sync, reports) |
|
||||
| Schema validation in CI | validate, federation, catalog, graph, pytest |
|
||||
| Production hub | `reuse.coulomb.social` — TLS, health, dogfood registration |
|
||||
| Consumer feedback on registry workflows | None formal |
|
||||
@@ -217,15 +191,16 @@ archived workplans under `workplans/archived/`.
|
||||
|
||||
| Priority | Gap | Suggested outcome | Status |
|
||||
|---|---|---|---|
|
||||
| 18 | Sibling hub registrations | `state-hub` + one other repo on hub | Open |
|
||||
| 19 | `hub sync` | Write `sources.yaml` from hub state | Open |
|
||||
| 20 | Planning cohort reports | Export/filter views for D5+/A4+ candidates | Open |
|
||||
| 21 | INTENT layout sync | Update INTENT.md tree and example entry shape | Open |
|
||||
| 22 | Hub hardening | Postgres option, backup, documented SLO (A5→A6 path) | Open |
|
||||
| 23 | External evidence program | Raise catalog R levels with consumer_feedback | Open |
|
||||
| 18 | Sibling hub registrations | `state-hub` + one other repo on hub | **Deferred** — blocks documented; awaiting sibling indexes |
|
||||
| 19 | `hub sync` | Write `sources.yaml` from hub state | **Closed** (WP-0012) |
|
||||
| 20 | Planning cohort reports | Export/filter views for D5+/A4+ candidates | **Closed** (WP-0012) |
|
||||
| 21 | INTENT layout sync | Update INTENT.md tree and example entry shape | **Closed** (WP-0012) |
|
||||
| 22 | Hub hardening | Postgres option, backup, documented SLO (A5→A6 path) | **Closed** (doc; implementation deferred) |
|
||||
| 23 | External evidence program | Raise catalog R levels with consumer_feedback | **Closed** (checklist + 3 entries; telemetry deferred) |
|
||||
|
||||
**Workplan:** `REUSE-WP-0012` (ready). **Assessment snapshot:**
|
||||
`history/2026-06-15-intent-scope-assessment.md`.
|
||||
**Workplan:** `REUSE-WP-0012` (finished). **Assessment snapshots:**
|
||||
`history/2026-06-15-intent-scope-assessment.md`,
|
||||
`history/2026-06-16-hub-registration-blocks.md`.
|
||||
|
||||
---
|
||||
|
||||
@@ -252,3 +227,4 @@ archived workplans under `workplans/archived/`.
|
||||
| 2026-06-15 | REUSE-WP-0011 closed priority 17; hub live at reuse.coulomb.social |
|
||||
| 2026-06-15 | Post-WP-0011 refresh: 20 capabilities, vector D5/A4/C4/R3, priorities 18–23 proposed |
|
||||
| 2026-06-15 | REUSE-WP-0012 proposed; assessment archived in `history/2026-06-15-intent-scope-assessment.md` |
|
||||
| 2026-06-16 | REUSE-WP-0012 closed priorities 19–23; priority 18 deferred on sibling index blocks; vector C5 |
|
||||
@@ -60,6 +60,56 @@ Sibling repos (`state-hub`, `feature-control`, `identity-canon`) are listed as
|
||||
disabled local placeholders until they publish registry indexes. A disabled
|
||||
`example-remote` URL source illustrates HTTP federation.
|
||||
|
||||
## Index publish contract (domain repos)
|
||||
|
||||
Before a sibling repo can register on the hosted hub, it must publish
|
||||
`registry/indexes/capabilities.yaml` at a **stable raw HTTP(S) URL** that
|
||||
returns **200** with valid YAML (not a redirect to login or HTML).
|
||||
|
||||
### Required index fields
|
||||
|
||||
| Field | Requirement |
|
||||
|---|---|
|
||||
| `version` | Integer manifest version |
|
||||
| `domain` | Domain slug (e.g. `helix_forge`) |
|
||||
| `capabilities[]` | Non-empty or explicitly empty list |
|
||||
| Per row: `id`, `name`, `summary`, `vector`, `path` | Match entry front matter |
|
||||
|
||||
Entry bodies remain in the source repo; the index is the federation surface.
|
||||
|
||||
### Gitea raw URL shape
|
||||
|
||||
```text
|
||||
https://gitea.coulomb.social/coulomb/<repo>/raw/<branch>/registry/indexes/capabilities.yaml
|
||||
```
|
||||
|
||||
Use `main` (or the repo's default branch). Verify before registration:
|
||||
|
||||
```bash
|
||||
curl -fsSI "<raw-url>" | head -n1 # expect HTTP/2 200 or HTTP/1.1 200
|
||||
curl -fsS "<raw-url>" | head
|
||||
```
|
||||
|
||||
### Auth expectations
|
||||
|
||||
- **Public indexes:** no auth; hub fetches without credentials.
|
||||
- **Private indexes:** set `auth_env` on the hub registration (or local `url`
|
||||
source) to an environment variable holding a Bearer token or full header value.
|
||||
The hub stores `auth_env` / `auth_header` names only — never secret values.
|
||||
|
||||
### Registration checklist
|
||||
|
||||
1. Merge capability index to the default branch.
|
||||
2. Confirm raw URL returns 200 YAML.
|
||||
3. `reuse-surface hub register --repo <slug> --url <raw-url> --domain helix_forge`
|
||||
4. `curl -fsS "$REUSE_SURFACE_URL/v1/federated" | jq '.capabilities | length'`
|
||||
5. Optionally `reuse-surface hub sync --merge` to refresh local `sources.yaml`.
|
||||
|
||||
**Current blocks (2026-06-16):** `state-hub`, `feature-control`,
|
||||
`identity-canon`, and `shard-wiki` raw URLs return **303** (not published).
|
||||
See `history/2026-06-16-hub-registration-blocks.md` for probe evidence and owner
|
||||
follow-ups.
|
||||
|
||||
## Compose workflow
|
||||
|
||||
```bash
|
||||
@@ -122,8 +172,26 @@ spec: `specs/FederationHubAPI.md`.
|
||||
| **Local compose** | Offline development, CI with checked-in sources, or hub unavailable |
|
||||
|
||||
Local `registry/federation/sources.yaml` remains valid for `reuse-surface
|
||||
federation compose`. Optional future: `reuse-surface hub sync` to materialize
|
||||
`sources.yaml` from hub state.
|
||||
federation compose`. Use `reuse-surface hub sync` to materialize `sources.yaml`
|
||||
from hub `GET /v1/repos` state.
|
||||
|
||||
### hub sync
|
||||
|
||||
```bash
|
||||
export REUSE_SURFACE_URL=https://reuse.coulomb.social
|
||||
reuse-surface hub sync --dry-run # preview manifest
|
||||
reuse-surface hub sync --merge # hub URL sources + local index sources
|
||||
reuse-surface hub sync # replace with hub-enabled registrations
|
||||
```
|
||||
|
||||
| Flag | Behavior |
|
||||
|---|---|
|
||||
| `--merge` | Keep local `index` sources whose `repo` slug is not on the hub |
|
||||
| `--replace` (default) | Write only hub-enabled registrations as `url` sources |
|
||||
| `--output` | Override manifest path (default `registry/federation/sources.yaml`) |
|
||||
| `--dry-run` | Print YAML without writing |
|
||||
|
||||
After sync, run `reuse-surface federation compose` to verify offline compose.
|
||||
|
||||
## Agent query pattern
|
||||
|
||||
|
||||
@@ -67,19 +67,19 @@
|
||||
</article>
|
||||
<article class="card">
|
||||
<h3>Capability Registration</h3>
|
||||
<p class="meta"><code>capability.registry.register</code> · D3 / A4 / C2 / R2</p>
|
||||
<p class="meta"><code>capability.registry.register</code> · D3 / A4 / C2 / R3</p>
|
||||
<p>Register a new capability so it becomes visible for planning and implementation reuse.</p>
|
||||
<p class="path">registry/capabilities/capability.registry.register.md</p>
|
||||
</article>
|
||||
<article class="card">
|
||||
<h3>Registry Entry Validation</h3>
|
||||
<p class="meta"><code>capability.registry.validate</code> · D4 / A3 / C3 / R2</p>
|
||||
<p class="meta"><code>capability.registry.validate</code> · D4 / A3 / C3 / R3</p>
|
||||
<p>Validate capability registry entries against schema, index consistency, and relation integrity.</p>
|
||||
<p class="path">registry/capabilities/capability.registry.validate.md</p>
|
||||
</article>
|
||||
<article class="card">
|
||||
<h3>Work Progress Logging</h3>
|
||||
<p class="meta"><code>capability.statehub.progress-log</code> · D4 / A4 / C3 / R2</p>
|
||||
<p class="meta"><code>capability.statehub.progress-log</code> · D4 / A4 / C3 / R3</p>
|
||||
<p>Record progress events, decisions, and session notes against workstreams and tasks in State Hub.</p>
|
||||
<p class="path">registry/capabilities/capability.statehub.progress-log.md</p>
|
||||
</article>
|
||||
|
||||
@@ -151,7 +151,7 @@
|
||||
"id": "capability.registry.register",
|
||||
"name": "Capability Registration",
|
||||
"summary": "Register a new capability so it becomes visible for planning and implementation reuse.",
|
||||
"vector": "D3 / A4 / C2 / R2",
|
||||
"vector": "D3 / A4 / C2 / R3",
|
||||
"domain": "helix_forge",
|
||||
"status": "draft",
|
||||
"owner": "reuse-surface",
|
||||
@@ -172,7 +172,7 @@
|
||||
"id": "capability.registry.validate",
|
||||
"name": "Registry Entry Validation",
|
||||
"summary": "Validate capability registry entries against schema, index consistency, and relation integrity.",
|
||||
"vector": "D4 / A3 / C3 / R2",
|
||||
"vector": "D4 / A3 / C3 / R3",
|
||||
"domain": "helix_forge",
|
||||
"status": "draft",
|
||||
"owner": "reuse-surface",
|
||||
@@ -190,7 +190,7 @@
|
||||
"id": "capability.statehub.progress-log",
|
||||
"name": "Work Progress Logging",
|
||||
"summary": "Record progress events, decisions, and session notes against workstreams and tasks in State Hub.",
|
||||
"vector": "D4 / A4 / C3 / R2",
|
||||
"vector": "D4 / A4 / C3 / R3",
|
||||
"domain": "helix_forge",
|
||||
"status": "draft",
|
||||
"owner": "state-hub",
|
||||
|
||||
@@ -57,3 +57,68 @@ export REUSE_SURFACE_URL=https://reuse.coulomb.social
|
||||
export REUSE_SURFACE_TOKEN=<write-token>
|
||||
reuse-surface hub status
|
||||
```
|
||||
|
||||
## Operational hardening
|
||||
|
||||
The hub runs as a single-replica Deployment with SQLite on a PVC (**A5**
|
||||
containerized service). **A6** (managed platform) is deferred until multi-replica
|
||||
or Postgres backing is required.
|
||||
|
||||
### Backup and restore (SQLite PVC)
|
||||
|
||||
1. Identify the PVC mounted at `/data` (stores `reuse.db` and remote index cache).
|
||||
2. Snapshot or copy while the pod is running (SQLite WAL-safe copy) or scale to
|
||||
zero briefly for a cold copy:
|
||||
|
||||
```bash
|
||||
kubectl -n <namespace> exec deploy/reuse-surface -- \
|
||||
sqlite3 /data/reuse.db '.backup /tmp/reuse-backup.db'
|
||||
kubectl -n <namespace> cp deploy/reuse-surface:/tmp/reuse-backup.db ./reuse-backup.db
|
||||
```
|
||||
|
||||
3. Restore by replacing `/data/reuse.db` from backup and restarting the pod.
|
||||
4. Re-register repos if the database is empty (`reuse-surface hub list`).
|
||||
|
||||
Verify backup once per environment after deploy changes.
|
||||
|
||||
### TLS certificate renewal
|
||||
|
||||
Ingress TLS is managed by the cluster cert issuer (Railiance01 companion chart).
|
||||
Monitor certificate expiry on `reuse.coulomb.social`. Renewal is automatic when
|
||||
the issuer is healthy; on failure, check ingress secret `reuse-surface-tls` and
|
||||
cert-manager / companion operator logs.
|
||||
|
||||
### Token rotation
|
||||
|
||||
1. Generate a new `REUSE_SURFACE_TOKEN` value.
|
||||
2. Update Kubernetes Secret `reuse-surface-env`.
|
||||
3. Rolling restart the hub Deployment.
|
||||
4. Update operator workstations and CI secrets that call write endpoints.
|
||||
5. Confirm `reuse-surface hub register` fails with the old token and succeeds
|
||||
with the new token.
|
||||
|
||||
### Image promotion checklist
|
||||
|
||||
1. Tag image from CI commit: `gitea.coulomb.social/coulomb/reuse-surface:<sha>`.
|
||||
2. Run `pytest -q` and `reuse-surface validate` on that commit.
|
||||
3. Update Helm values image tag in `railiance-apps`.
|
||||
4. Deploy to Railiance01; verify `GET /health` and `GET /v1/repos`.
|
||||
5. Smoke `reuse-surface hub list` and `GET /v1/federated` capability count.
|
||||
6. Record image digest in workplan or progress log.
|
||||
|
||||
### SQLite vs Postgres (cnpg) — decision criteria
|
||||
|
||||
Stay on SQLite while:
|
||||
|
||||
- Single replica is acceptable.
|
||||
- RPO of occasional PVC snapshot is sufficient.
|
||||
- Write volume is low (repo registration changes only).
|
||||
|
||||
Consider Postgres (e.g. CloudNative-PG) when:
|
||||
|
||||
- Multiple hub replicas or zero-downtime failover is required.
|
||||
- RPO/RTO targets need point-in-time recovery beyond PVC snapshots.
|
||||
- Federation cache metadata or audit tables grow beyond comfortable SQLite size.
|
||||
|
||||
**Implementation deferred** unless an operator approves migration. Document only
|
||||
until then.
|
||||
@@ -7,9 +7,9 @@ graph LR
|
||||
capability_feature_control_visibility["capability.feature-control.visibility<br/>D4 / A2 / C2 / R1"]
|
||||
capability_identity_subject_resolution["capability.identity.subject-resolution<br/>D3 / A0 / C1 / R0"]
|
||||
capability_identity_vocabulary_canonicalize["capability.identity.vocabulary-canonicalize<br/>D4 / A0 / C2 / R0"]
|
||||
capability_registry_register["capability.registry.register<br/>D3 / A4 / C2 / R2"]
|
||||
capability_registry_validate["capability.registry.validate<br/>D4 / A3 / C3 / R2"]
|
||||
capability_statehub_progress_log["capability.statehub.progress-log<br/>D4 / A4 / C3 / R2"]
|
||||
capability_registry_register["capability.registry.register<br/>D3 / A4 / C2 / R3"]
|
||||
capability_registry_validate["capability.registry.validate<br/>D4 / A3 / C3 / R3"]
|
||||
capability_statehub_progress_log["capability.statehub.progress-log<br/>D4 / A4 / C3 / R3"]
|
||||
capability_statehub_workstream_coordinate["capability.statehub.workstream-coordinate<br/>D4 / A4 / C3 / R2"]
|
||||
capability_wiki_adapter_contract["capability.wiki.adapter-contract<br/>D5 / A2 / C2 / R1"]
|
||||
capability_wiki_coordination_journal["capability.wiki.coordination-journal<br/>D5 / A2 / C2 / R1"]
|
||||
|
||||
File diff suppressed because one or more lines are too long
38
history/2026-06-16-hub-registration-blocks.md
Normal file
38
history/2026-06-16-hub-registration-blocks.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# Hub registration blocks — sibling index publishing
|
||||
|
||||
**Date:** 2026-06-16
|
||||
**Workplan:** REUSE-WP-0012-T01
|
||||
**Hub:** `https://reuse.coulomb.social`
|
||||
|
||||
## Summary
|
||||
|
||||
Production hub dogfood has **one** registered repo (`reuse-surface`). Sibling
|
||||
helix_forge repos cannot register until each publishes
|
||||
`registry/indexes/capabilities.yaml` at a stable raw URL returning **HTTP 200**.
|
||||
|
||||
## Probe results (2026-06-16)
|
||||
|
||||
| Repo | Candidate raw URL | HTTP status | Block |
|
||||
|---|---|---|---|
|
||||
| `state-hub` | `https://gitea.coulomb.social/coulomb/state-hub/raw/main/registry/indexes/capabilities.yaml` | 303 | Index not published on default branch |
|
||||
| `feature-control` | `https://gitea.coulomb.social/coulomb/feature-control/raw/main/registry/indexes/capabilities.yaml` | 303 | Index not published |
|
||||
| `identity-canon` | `https://gitea.coulomb.social/coulomb/identity-canon/raw/main/registry/indexes/capabilities.yaml` | 303 | Index not published |
|
||||
| `shard-wiki` | `https://gitea.coulomb.social/coulomb/shard-wiki/raw/main/registry/indexes/capabilities.yaml` | 303 | Index not published |
|
||||
| `reuse-surface` | `https://gitea.coulomb.social/coulomb/reuse-surface/raw/main/registry/indexes/capabilities.yaml` | 200 | Registered on hub |
|
||||
|
||||
## Owner follow-ups
|
||||
|
||||
1. **Domain repo owners:** add `registry/indexes/capabilities.yaml` (can start
|
||||
empty or with D0 entries), merge to `main`, verify `curl -fsSI` returns 200.
|
||||
2. **Custodian operator:** register each repo with
|
||||
`reuse-surface hub register --repo <slug> --url <raw-url>`.
|
||||
3. **reuse-surface agents:** run `reuse-surface hub sync --merge` after new
|
||||
registrations to refresh local `sources.yaml`.
|
||||
|
||||
Publish contract: `docs/RegistryFederation.md` (Index publish contract section).
|
||||
|
||||
## Acceptance note
|
||||
|
||||
REUSE-WP-0012-T01 acceptance allows documenting explicit blocks when sibling
|
||||
indexes are unavailable. This note satisfies that path until **≥3 repos** are on
|
||||
the hub.
|
||||
@@ -7,3 +7,4 @@ in `INTENT.md`; living delta tracking in `docs/IntentScopeGapAnalysis.md`.
|
||||
| Date | Artifact | Summary |
|
||||
|---|---|---|
|
||||
| 2026-06-15 | [2026-06-15-intent-scope-assessment.md](2026-06-15-intent-scope-assessment.md) | Post-WP-0011 INTENT↔SCOPE assessment; priorities 18–23 |
|
||||
| 2026-06-16 | [2026-06-16-hub-registration-blocks.md](2026-06-16-hub-registration-blocks.md) | Sibling hub registration blocks; raw URL probe evidence |
|
||||
@@ -143,6 +143,34 @@ Outputs:
|
||||
- `docs/graph/capability-graph.mmd` — Mermaid source
|
||||
- `docs/graph/index.html` — in-browser explorer (also regenerated by `catalog`)
|
||||
|
||||
## External evidence checklist (R1 → R3)
|
||||
|
||||
Use this when promoting **reliability** from **R1 Fragile** or **R2 Tolerable**
|
||||
to **R3 Usable** (normal use with known limitations).
|
||||
|
||||
### Minimum evidence for R3
|
||||
|
||||
- [ ] At least one **repeatable** quality signal (CI gate, smoke test, or
|
||||
documented production check) cited under `evidence.tests` or `evidence.documentation`
|
||||
- [ ] `known_reliability_risks` lists bounded, current limitations (not empty
|
||||
unless risks are genuinely absent)
|
||||
- [ ] At least one `evidence.consumer_feedback` string or resolved-risk note when
|
||||
real consumers exist; otherwise document why feedback is not yet available
|
||||
- [ ] Optional `external_evidence.reliability.evidence.satisfied_signals` for CI
|
||||
or smoke-test citations
|
||||
- [ ] `confidence` is `medium` or `high` when citing CI/production evidence
|
||||
- [ ] `promotion_history` records the R dimension change with rationale
|
||||
|
||||
### Signals that support R3 for registry tooling
|
||||
|
||||
- `reuse-surface validate` in CI with `--fail-on-warnings`
|
||||
- `pytest` coverage for the capability's consumption path
|
||||
- Production hub smoke (`GET /health`, `GET /v1/federated`) for API-backed flows
|
||||
- Operator deploy verification documented in `docs/deploy/reuse-kubernetes.md`
|
||||
|
||||
R4+ requires broader consumer evidence (incidents, adoption, SLO) per
|
||||
`specs/CapabilityMaturityStandard.md`.
|
||||
|
||||
## Promote a capability
|
||||
|
||||
1. Attach evidence appropriate to the target level in
|
||||
|
||||
@@ -47,14 +47,19 @@ external_evidence:
|
||||
- hosting registered capabilities
|
||||
- enforcing implementation architecture
|
||||
reliability:
|
||||
level: R2
|
||||
name: Tolerable
|
||||
level: R3
|
||||
name: Usable
|
||||
confidence: medium
|
||||
basis: consumer_quality_signals
|
||||
known_reliability_risks:
|
||||
- index drift still possible if authors skip validate
|
||||
- CLI requires local venv install
|
||||
- schema ID pattern required a fix during WP-0003 dogfooding
|
||||
- sibling repos cannot register until indexes publish raw URLs
|
||||
evidence:
|
||||
satisfied_signals:
|
||||
- CI validate with fail-on-warnings on every push
|
||||
- hub register/list/federated smoke on production reuse.coulomb.social
|
||||
- pytest coverage for hub API and federation compose paths
|
||||
|
||||
discovery:
|
||||
intent: >
|
||||
@@ -112,7 +117,13 @@ evidence:
|
||||
- docs/deploy/reuse-kubernetes.md
|
||||
tests:
|
||||
- tests/test_hub.py
|
||||
consumer_feedback: []
|
||||
- tests/test_hub_sync.py
|
||||
- .gitea/workflows/ci.yml
|
||||
consumer_feedback:
|
||||
- >
|
||||
reuse-surface dogfood (REUSE-WP-0011): production hub registration and
|
||||
/v1/federated compose succeeded on Railiance01 without write-path
|
||||
regressions after WP-0011 deploy.
|
||||
bug_reports: []
|
||||
incidents: []
|
||||
|
||||
@@ -154,6 +165,14 @@ promotion_history:
|
||||
Hosted federation hub live at reuse.coulomb.social; hub register/update
|
||||
via HTTP API and reuse-surface hub CLI; production deploy on Railiance01.
|
||||
author: reuse-surface
|
||||
- date: "2026-06-16"
|
||||
dimension: reliability
|
||||
from: R2
|
||||
to: R3
|
||||
rationale: >
|
||||
CI gates, pytest hub/federation coverage, and production hub smoke support
|
||||
normal registration workflows with documented limitations.
|
||||
author: reuse-surface
|
||||
---
|
||||
|
||||
# Capability Registration
|
||||
|
||||
@@ -33,12 +33,17 @@ external_evidence:
|
||||
out_of_scope_expectations:
|
||||
- runtime validation of registered capability implementations
|
||||
reliability:
|
||||
level: R2
|
||||
name: Tolerable
|
||||
level: R3
|
||||
name: Usable
|
||||
confidence: medium
|
||||
basis: consumer_quality_signals
|
||||
known_reliability_risks:
|
||||
- requires local venv install
|
||||
- relation warnings require explicit --relations flag
|
||||
evidence:
|
||||
satisfied_signals:
|
||||
- validate --relations --fail-on-warnings in CI
|
||||
- tests/test_registry.py schema and drift coverage
|
||||
|
||||
discovery:
|
||||
intent: Keep registry data structurally sound so agents and humans can trust discovery metadata.
|
||||
@@ -72,7 +77,13 @@ relations:
|
||||
evidence:
|
||||
documentation:
|
||||
- tools/README.md
|
||||
tests: []
|
||||
- .gitea/workflows/ci.yml
|
||||
tests:
|
||||
- tests/test_registry.py
|
||||
consumer_feedback:
|
||||
- >
|
||||
reuse-surface CI: registry changes fail when schema validation or relation
|
||||
checks warn with --fail-on-warnings, giving agents a dependable pre-merge gate.
|
||||
|
||||
consumer_guidance:
|
||||
recommended_for:
|
||||
@@ -81,6 +92,14 @@ consumer_guidance:
|
||||
- certifying business correctness of capability claims
|
||||
known_limitations:
|
||||
- warnings do not fail CI unless --fail-on-warnings is set
|
||||
|
||||
promotion_history:
|
||||
- date: "2026-06-16"
|
||||
dimension: reliability
|
||||
from: R2
|
||||
to: R3
|
||||
rationale: CI fail-on-warnings and pytest registry coverage support dependable validation.
|
||||
author: reuse-surface
|
||||
---
|
||||
|
||||
# Registry Entry Validation
|
||||
|
||||
@@ -32,11 +32,16 @@ external_evidence:
|
||||
out_of_scope_expectations:
|
||||
- replacing git commit history
|
||||
reliability:
|
||||
level: R2
|
||||
confidence: low
|
||||
level: R3
|
||||
name: Usable
|
||||
confidence: medium
|
||||
basis: consumer_quality_signals
|
||||
known_reliability_risks:
|
||||
- depends on hub availability
|
||||
- depends on hub availability and tunnel health for remote agents
|
||||
evidence:
|
||||
satisfied_signals:
|
||||
- reuse-surface AGENTS.md session-close protocol cites POST /progress/
|
||||
- cross-repo agents log progress with workstream_id linkage
|
||||
|
||||
discovery:
|
||||
intent: Provide auditable progress memory for cross-repo agent and operator work.
|
||||
@@ -63,6 +68,14 @@ relations:
|
||||
related_to:
|
||||
- capability.statehub.workstream-coordinate
|
||||
|
||||
evidence:
|
||||
documentation:
|
||||
- AGENTS.md
|
||||
consumer_feedback:
|
||||
- >
|
||||
reuse-surface agents (REUSE-WP-0012): session-close progress posts to State
|
||||
Hub succeeded for workstream fb0b6067 during federation workplan work.
|
||||
|
||||
consumer_guidance:
|
||||
recommended_for:
|
||||
- closing agent sessions with hub progress notes
|
||||
|
||||
@@ -94,7 +94,7 @@ capabilities:
|
||||
- id: capability.registry.register
|
||||
name: Capability Registration
|
||||
summary: Register a new capability so it becomes visible for planning and implementation reuse.
|
||||
vector: D3 / A4 / C2 / R2
|
||||
vector: D3 / A4 / C2 / R3
|
||||
domain: helix_forge
|
||||
status: draft
|
||||
owner: reuse-surface
|
||||
@@ -105,7 +105,7 @@ capabilities:
|
||||
- id: capability.registry.validate
|
||||
name: Registry Entry Validation
|
||||
summary: Validate capability registry entries against schema, index consistency, and relation integrity.
|
||||
vector: D4 / A3 / C3 / R2
|
||||
vector: D4 / A3 / C3 / R3
|
||||
domain: helix_forge
|
||||
status: draft
|
||||
owner: reuse-surface
|
||||
@@ -116,7 +116,7 @@ capabilities:
|
||||
- id: capability.statehub.progress-log
|
||||
name: Work Progress Logging
|
||||
summary: Record progress events, decisions, and session notes against workstreams and tasks in State Hub.
|
||||
vector: D4 / A4 / C3 / R2
|
||||
vector: D4 / A4 / C3 / R3
|
||||
domain: helix_forge
|
||||
status: draft
|
||||
owner: state-hub
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Composed federated capability index. Regenerate with:
|
||||
# reuse-surface federation compose
|
||||
version: 1
|
||||
updated: '2026-06-15'
|
||||
updated: '2026-06-16'
|
||||
domain: helix_forge
|
||||
collision_policy: warn
|
||||
sources:
|
||||
@@ -150,7 +150,7 @@ capabilities:
|
||||
name: Capability Registration
|
||||
summary: Register a new capability so it becomes visible for planning and implementation
|
||||
reuse.
|
||||
vector: D3 / A4 / C2 / R2
|
||||
vector: D3 / A4 / C2 / R3
|
||||
domain: helix_forge
|
||||
status: draft
|
||||
owner: reuse-surface
|
||||
@@ -170,7 +170,7 @@ capabilities:
|
||||
name: Registry Entry Validation
|
||||
summary: Validate capability registry entries against schema, index consistency,
|
||||
and relation integrity.
|
||||
vector: D4 / A3 / C3 / R2
|
||||
vector: D4 / A3 / C3 / R3
|
||||
domain: helix_forge
|
||||
status: draft
|
||||
owner: reuse-surface
|
||||
@@ -187,7 +187,7 @@ capabilities:
|
||||
name: Work Progress Logging
|
||||
summary: Record progress events, decisions, and session notes against workstreams
|
||||
and tasks in State Hub.
|
||||
vector: D4 / A4 / C3 / R2
|
||||
vector: D4 / A4 / C3 / R3
|
||||
domain: helix_forge
|
||||
status: draft
|
||||
owner: state-hub
|
||||
|
||||
@@ -13,7 +13,19 @@ from reuse_surface.catalog import write_catalog
|
||||
from reuse_surface.federation import write_federated_index
|
||||
from reuse_surface import hub_client
|
||||
from reuse_surface.graph import check_relations, render_mermaid, write_graph
|
||||
from reuse_surface.hub_sync import (
|
||||
DEFAULT_SOURCES_PATH,
|
||||
build_manifest,
|
||||
load_sources_manifest,
|
||||
write_sources_manifest,
|
||||
)
|
||||
from reuse_surface.overlaps import find_overlaps
|
||||
from reuse_surface.reports import (
|
||||
cohort_filters_from_args,
|
||||
format_cohort_json,
|
||||
format_cohort_markdown,
|
||||
select_cohort,
|
||||
)
|
||||
from reuse_surface.registry import (
|
||||
ROOT,
|
||||
capability_paths,
|
||||
@@ -294,6 +306,39 @@ def cmd_hub_update(args: argparse.Namespace) -> int:
|
||||
return 0
|
||||
|
||||
|
||||
def cmd_hub_sync(args: argparse.Namespace) -> int:
|
||||
try:
|
||||
status, payload = hub_client.hub_list(_service_url(args))
|
||||
except ValueError as exc:
|
||||
print(f"error: {exc}", file=sys.stderr)
|
||||
return 1
|
||||
if status != 200:
|
||||
print(f"error: hub returned {status}: {payload}", file=sys.stderr)
|
||||
return 1
|
||||
output = Path(args.output) if args.output else DEFAULT_SOURCES_PATH
|
||||
existing = load_sources_manifest(output) if args.merge else None
|
||||
manifest = build_manifest(payload, existing, merge=args.merge)
|
||||
if args.dry_run:
|
||||
print(yaml.safe_dump(manifest, sort_keys=False))
|
||||
return 0
|
||||
written = write_sources_manifest(manifest, output)
|
||||
print(
|
||||
f"ok: wrote {written.relative_to(ROOT)} "
|
||||
f"({len(manifest['sources'])} source(s))"
|
||||
)
|
||||
return 0
|
||||
|
||||
|
||||
def cmd_report_cohorts(args: argparse.Namespace) -> int:
|
||||
filters = cohort_filters_from_args(args)
|
||||
matches = select_cohort(filters)
|
||||
if args.format == "json":
|
||||
print(format_cohort_json(matches, filters))
|
||||
else:
|
||||
print(format_cohort_markdown(matches, filters), end="")
|
||||
return 0
|
||||
|
||||
|
||||
def cmd_export(args: argparse.Namespace) -> int:
|
||||
index = load_index()
|
||||
bundle: dict[str, Any] = {
|
||||
@@ -457,6 +502,43 @@ def main(argv: list[str] | None = None) -> int:
|
||||
hub_update.add_argument("--required", action=argparse.BooleanOptionalAction, default=None)
|
||||
hub_update.set_defaults(func=cmd_hub_update)
|
||||
|
||||
hub_sync = hub_sub.add_parser(
|
||||
"sync", help="write federation sources.yaml from hub registrations"
|
||||
)
|
||||
hub_sync.add_argument(
|
||||
"--output",
|
||||
help=f"manifest path (default: {DEFAULT_SOURCES_PATH.relative_to(ROOT)})",
|
||||
)
|
||||
hub_sync.add_argument(
|
||||
"--merge",
|
||||
action="store_true",
|
||||
help="keep local index sources not overridden by hub repo slugs",
|
||||
)
|
||||
hub_sync.add_argument(
|
||||
"--dry-run",
|
||||
action="store_true",
|
||||
help="print manifest without writing",
|
||||
)
|
||||
hub_sync.set_defaults(func=cmd_hub_sync)
|
||||
|
||||
report = subparsers.add_parser("report", help="planning and analytics reports")
|
||||
report_sub = report.add_subparsers(dest="report_command", required=True)
|
||||
cohorts = report_sub.add_parser(
|
||||
"cohorts", help="export capability cohorts by maturity filters"
|
||||
)
|
||||
cohorts.add_argument("--planning-min", help="discovery minimum (implies availability-max A1)")
|
||||
cohorts.add_argument("--implementation-min", help="availability minimum")
|
||||
cohorts.add_argument("--discovery-min")
|
||||
cohorts.add_argument("--availability-min")
|
||||
cohorts.add_argument("--availability-max")
|
||||
cohorts.add_argument("--domain")
|
||||
cohorts.add_argument(
|
||||
"--format",
|
||||
choices=["markdown", "json"],
|
||||
default="markdown",
|
||||
)
|
||||
cohorts.set_defaults(func=cmd_report_cohorts)
|
||||
|
||||
args = parser.parse_args(argv)
|
||||
return args.func(args)
|
||||
|
||||
|
||||
100
reuse_surface/hub_sync.py
Normal file
100
reuse_surface/hub_sync.py
Normal file
@@ -0,0 +1,100 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
import yaml
|
||||
|
||||
from reuse_surface.registry import ROOT
|
||||
|
||||
DEFAULT_SOURCES_PATH = ROOT / "registry" / "federation" / "sources.yaml"
|
||||
|
||||
|
||||
def registration_to_source(registration: dict[str, Any]) -> dict[str, Any]:
|
||||
source: dict[str, Any] = {
|
||||
"repo": registration["repo"],
|
||||
"url": registration["url"],
|
||||
"enabled": registration.get("enabled", True),
|
||||
"required": registration.get("required", False),
|
||||
"domain": registration.get("domain", "helix_forge"),
|
||||
}
|
||||
for optional in (
|
||||
"description",
|
||||
"cache_ttl_seconds",
|
||||
"auth_env",
|
||||
"auth_header",
|
||||
):
|
||||
if registration.get(optional) is not None:
|
||||
source[optional] = registration[optional]
|
||||
return source
|
||||
|
||||
|
||||
def sources_from_hub_payload(
|
||||
payload: dict[str, Any],
|
||||
*,
|
||||
enabled_only: bool = True,
|
||||
) -> list[dict[str, Any]]:
|
||||
repos = payload.get("repos", [])
|
||||
sources: list[dict[str, Any]] = []
|
||||
for registration in repos:
|
||||
if enabled_only and not registration.get("enabled", True):
|
||||
continue
|
||||
if not registration.get("url"):
|
||||
continue
|
||||
sources.append(registration_to_source(registration))
|
||||
return sorted(sources, key=lambda item: item["repo"])
|
||||
|
||||
|
||||
def merge_sources(
|
||||
hub_sources: list[dict[str, Any]],
|
||||
existing_sources: list[dict[str, Any]],
|
||||
) -> list[dict[str, Any]]:
|
||||
hub_repos = {source["repo"] for source in hub_sources}
|
||||
merged = list(hub_sources)
|
||||
for source in existing_sources:
|
||||
if source.get("repo") in hub_repos:
|
||||
continue
|
||||
if "index" in source:
|
||||
merged.append(source)
|
||||
return sorted(merged, key=lambda item: item["repo"])
|
||||
|
||||
|
||||
def build_manifest(
|
||||
hub_payload: dict[str, Any],
|
||||
existing: dict[str, Any] | None = None,
|
||||
*,
|
||||
merge: bool = False,
|
||||
) -> dict[str, Any]:
|
||||
hub_sources = sources_from_hub_payload(hub_payload)
|
||||
if merge and existing:
|
||||
sources = merge_sources(hub_sources, existing.get("sources", []))
|
||||
else:
|
||||
sources = hub_sources
|
||||
return {
|
||||
"version": existing.get("version", 1) if existing else 1,
|
||||
"domain": existing.get("domain", "helix_forge") if existing else "helix_forge",
|
||||
"collision_policy": existing.get("collision_policy", "warn")
|
||||
if existing
|
||||
else "warn",
|
||||
"sources": sources,
|
||||
}
|
||||
|
||||
|
||||
def load_sources_manifest(path: Path) -> dict[str, Any]:
|
||||
if not path.exists():
|
||||
return {
|
||||
"version": 1,
|
||||
"domain": "helix_forge",
|
||||
"collision_policy": "warn",
|
||||
"sources": [],
|
||||
}
|
||||
return yaml.safe_load(path.read_text(encoding="utf-8"))
|
||||
|
||||
|
||||
def write_sources_manifest(manifest: dict[str, Any], path: Path = DEFAULT_SOURCES_PATH) -> Path:
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
path.write_text(
|
||||
yaml.safe_dump(manifest, sort_keys=False, allow_unicode=True),
|
||||
encoding="utf-8",
|
||||
)
|
||||
return path
|
||||
87
reuse_surface/reports.py
Normal file
87
reuse_surface/reports.py
Normal file
@@ -0,0 +1,87 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from typing import Any
|
||||
|
||||
from reuse_surface.registry import level_at_least, load_index, parse_vector
|
||||
|
||||
|
||||
def _availability_at_most(current: str, maximum: str) -> bool:
|
||||
from reuse_surface.registry import LEVEL_ORDERS
|
||||
|
||||
order = LEVEL_ORDERS["availability"]
|
||||
return order.index(current) <= order.index(maximum)
|
||||
|
||||
|
||||
def cohort_filters_from_args(args: Any) -> dict[str, str | None]:
|
||||
filters: dict[str, str | None] = {
|
||||
"discovery_min": getattr(args, "discovery_min", None),
|
||||
"availability_min": getattr(args, "availability_min", None),
|
||||
"availability_max": getattr(args, "availability_max", None),
|
||||
"domain": getattr(args, "domain", None),
|
||||
}
|
||||
if getattr(args, "planning_min", None):
|
||||
filters["discovery_min"] = args.planning_min
|
||||
filters["availability_max"] = filters["availability_max"] or "A1"
|
||||
if getattr(args, "implementation_min", None):
|
||||
filters["availability_min"] = args.implementation_min
|
||||
return filters
|
||||
|
||||
|
||||
def select_cohort(
|
||||
filters: dict[str, str | None],
|
||||
index: dict[str, Any] | None = None,
|
||||
) -> list[dict[str, Any]]:
|
||||
data = index or load_index()
|
||||
matches: list[dict[str, Any]] = []
|
||||
for item in data.get("capabilities", []):
|
||||
vector = parse_vector(item["vector"])
|
||||
if filters.get("discovery_min") and not level_at_least(
|
||||
"discovery", vector["discovery"], filters["discovery_min"]
|
||||
):
|
||||
continue
|
||||
if filters.get("availability_min") and not level_at_least(
|
||||
"availability", vector["availability"], filters["availability_min"]
|
||||
):
|
||||
continue
|
||||
if filters.get("availability_max") and not _availability_at_most(
|
||||
vector["availability"], filters["availability_max"]
|
||||
):
|
||||
continue
|
||||
if filters.get("domain") and item.get("domain") != filters["domain"]:
|
||||
continue
|
||||
matches.append(item)
|
||||
return matches
|
||||
|
||||
|
||||
def format_cohort_markdown(
|
||||
matches: list[dict[str, Any]],
|
||||
filters: dict[str, str | None],
|
||||
) -> str:
|
||||
lines = ["# Capability cohort report", ""]
|
||||
active = {key: value for key, value in filters.items() if value}
|
||||
if active:
|
||||
lines.append("Filters:")
|
||||
for key, value in sorted(active.items()):
|
||||
lines.append(f"- `{key}`: `{value}`")
|
||||
lines.append("")
|
||||
if not matches:
|
||||
lines.append("_No capabilities matched._")
|
||||
return "\n".join(lines) + "\n"
|
||||
lines.append("| ID | Vector | Consumption modes |")
|
||||
lines.append("|---|---|---|")
|
||||
for item in matches:
|
||||
modes = ", ".join(item.get("consumption_modes", []))
|
||||
lines.append(f"| `{item['id']}` | {item['vector']} | {modes} |")
|
||||
lines.append("")
|
||||
lines.append(f"**{len(matches)}** capabilit{'y' if len(matches) == 1 else 'ies'}.")
|
||||
return "\n".join(lines) + "\n"
|
||||
|
||||
|
||||
def format_cohort_json(matches: list[dict[str, Any]], filters: dict[str, str | None]) -> str:
|
||||
payload = {
|
||||
"count": len(matches),
|
||||
"filters": {key: value for key, value in filters.items() if value},
|
||||
"capabilities": matches,
|
||||
}
|
||||
return json.dumps(payload, indent=2, sort_keys=True)
|
||||
165
tests/test_hub_sync.py
Normal file
165
tests/test_hub_sync.py
Normal file
@@ -0,0 +1,165 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch
|
||||
|
||||
import yaml
|
||||
|
||||
from reuse_surface.hub_sync import (
|
||||
build_manifest,
|
||||
load_sources_manifest,
|
||||
merge_sources,
|
||||
registration_to_source,
|
||||
sources_from_hub_payload,
|
||||
write_sources_manifest,
|
||||
)
|
||||
|
||||
|
||||
def test_registration_to_source_maps_fields():
|
||||
source = registration_to_source(
|
||||
{
|
||||
"repo": "state-hub",
|
||||
"url": "https://example.com/capabilities.yaml",
|
||||
"enabled": True,
|
||||
"required": False,
|
||||
"domain": "helix_forge",
|
||||
"description": "test",
|
||||
"cache_ttl_seconds": 3600,
|
||||
"auth_env": "FEDERATION_TOKEN",
|
||||
"auth_header": "Authorization",
|
||||
}
|
||||
)
|
||||
assert source["repo"] == "state-hub"
|
||||
assert source["url"].endswith("capabilities.yaml")
|
||||
assert source["cache_ttl_seconds"] == 3600
|
||||
assert source["auth_env"] == "FEDERATION_TOKEN"
|
||||
assert "index" not in source
|
||||
|
||||
|
||||
def test_sources_from_hub_payload_skips_disabled_and_missing_url():
|
||||
payload = {
|
||||
"repos": [
|
||||
{
|
||||
"repo": "reuse-surface",
|
||||
"url": "https://example.com/reuse.yaml",
|
||||
"enabled": True,
|
||||
},
|
||||
{"repo": "disabled", "url": "https://example.com/disabled.yaml", "enabled": False},
|
||||
{"repo": "broken", "enabled": True},
|
||||
]
|
||||
}
|
||||
sources = sources_from_hub_payload(payload)
|
||||
assert [item["repo"] for item in sources] == ["reuse-surface"]
|
||||
|
||||
|
||||
def test_merge_sources_keeps_local_index_sources():
|
||||
hub_sources = [
|
||||
{
|
||||
"repo": "reuse-surface",
|
||||
"url": "https://example.com/reuse.yaml",
|
||||
"enabled": True,
|
||||
"required": True,
|
||||
"domain": "helix_forge",
|
||||
}
|
||||
]
|
||||
existing_sources = [
|
||||
{
|
||||
"repo": "reuse-surface",
|
||||
"index": "registry/indexes/capabilities.yaml",
|
||||
"enabled": True,
|
||||
"required": True,
|
||||
"domain": "helix_forge",
|
||||
},
|
||||
{
|
||||
"repo": "state-hub",
|
||||
"index": "~/state-hub/registry/indexes/capabilities.yaml",
|
||||
"enabled": False,
|
||||
"required": False,
|
||||
"domain": "helix_forge",
|
||||
},
|
||||
]
|
||||
merged = merge_sources(hub_sources, existing_sources)
|
||||
repos = {item["repo"] for item in merged}
|
||||
assert repos == {"reuse-surface", "state-hub"}
|
||||
reuse = next(item for item in merged if item["repo"] == "reuse-surface")
|
||||
assert "url" in reuse
|
||||
state_hub = next(item for item in merged if item["repo"] == "state-hub")
|
||||
assert "index" in state_hub
|
||||
|
||||
|
||||
def test_build_manifest_replace_vs_merge():
|
||||
payload = {
|
||||
"repos": [
|
||||
{
|
||||
"repo": "reuse-surface",
|
||||
"url": "https://example.com/reuse.yaml",
|
||||
"enabled": True,
|
||||
"required": True,
|
||||
"domain": "helix_forge",
|
||||
}
|
||||
]
|
||||
}
|
||||
existing = {
|
||||
"version": 1,
|
||||
"domain": "helix_forge",
|
||||
"collision_policy": "warn",
|
||||
"sources": [
|
||||
{
|
||||
"repo": "state-hub",
|
||||
"index": "~/state-hub/registry/indexes/capabilities.yaml",
|
||||
"enabled": False,
|
||||
"required": False,
|
||||
"domain": "helix_forge",
|
||||
}
|
||||
],
|
||||
}
|
||||
replaced = build_manifest(payload, existing, merge=False)
|
||||
assert [item["repo"] for item in replaced["sources"]] == ["reuse-surface"]
|
||||
merged = build_manifest(payload, existing, merge=True)
|
||||
assert {item["repo"] for item in merged["sources"]} == {
|
||||
"reuse-surface",
|
||||
"state-hub",
|
||||
}
|
||||
|
||||
|
||||
def test_write_sources_manifest_round_trip(tmp_path: Path):
|
||||
manifest = {
|
||||
"version": 1,
|
||||
"domain": "helix_forge",
|
||||
"collision_policy": "warn",
|
||||
"sources": [
|
||||
{
|
||||
"repo": "demo",
|
||||
"url": "https://example.com/demo.yaml",
|
||||
"enabled": True,
|
||||
"required": False,
|
||||
"domain": "helix_forge",
|
||||
}
|
||||
],
|
||||
}
|
||||
path = tmp_path / "sources.yaml"
|
||||
write_sources_manifest(manifest, path)
|
||||
loaded = load_sources_manifest(path)
|
||||
assert loaded["sources"][0]["repo"] == "demo"
|
||||
assert yaml.safe_load(path.read_text(encoding="utf-8")) == loaded
|
||||
|
||||
|
||||
def test_cmd_hub_sync_dry_run(tmp_path, monkeypatch):
|
||||
from reuse_surface.cli import main
|
||||
|
||||
monkeypatch.setenv("REUSE_SURFACE_URL", "https://hub.example")
|
||||
payload = {
|
||||
"count": 1,
|
||||
"repos": [
|
||||
{
|
||||
"repo": "reuse-surface",
|
||||
"url": "https://example.com/reuse.yaml",
|
||||
"enabled": True,
|
||||
"required": True,
|
||||
"domain": "helix_forge",
|
||||
}
|
||||
],
|
||||
}
|
||||
with patch("reuse_surface.hub_client.hub_list", return_value=(200, payload)):
|
||||
exit_code = main(["hub", "sync", "--dry-run"])
|
||||
assert exit_code == 0
|
||||
99
tests/test_reports.py
Normal file
99
tests/test_reports.py
Normal file
@@ -0,0 +1,99 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
|
||||
from reuse_surface.reports import (
|
||||
cohort_filters_from_args,
|
||||
format_cohort_json,
|
||||
format_cohort_markdown,
|
||||
select_cohort,
|
||||
)
|
||||
|
||||
|
||||
SAMPLE_INDEX = {
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "capability.planning.only",
|
||||
"vector": "D5 / A0 / C2 / R1",
|
||||
"domain": "helix_forge",
|
||||
"consumption_modes": ["planning"],
|
||||
},
|
||||
{
|
||||
"id": "capability.implementation.ready",
|
||||
"vector": "D5 / A4 / C3 / R3",
|
||||
"domain": "helix_forge",
|
||||
"consumption_modes": ["cli", "service API"],
|
||||
},
|
||||
{
|
||||
"id": "capability.other.domain",
|
||||
"vector": "D4 / A3 / C2 / R2",
|
||||
"domain": "other",
|
||||
"consumption_modes": ["cli"],
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_planning_min_filter():
|
||||
filters = cohort_filters_from_args(
|
||||
argparse.Namespace(
|
||||
planning_min="D5",
|
||||
implementation_min=None,
|
||||
discovery_min=None,
|
||||
availability_min=None,
|
||||
availability_max=None,
|
||||
domain=None,
|
||||
)
|
||||
)
|
||||
matches = select_cohort(filters, SAMPLE_INDEX)
|
||||
assert [item["id"] for item in matches] == ["capability.planning.only"]
|
||||
|
||||
|
||||
def test_implementation_min_filter():
|
||||
filters = cohort_filters_from_args(
|
||||
argparse.Namespace(
|
||||
planning_min=None,
|
||||
implementation_min="A4",
|
||||
discovery_min=None,
|
||||
availability_min=None,
|
||||
availability_max=None,
|
||||
domain=None,
|
||||
)
|
||||
)
|
||||
matches = select_cohort(filters, SAMPLE_INDEX)
|
||||
assert [item["id"] for item in matches] == ["capability.implementation.ready"]
|
||||
|
||||
|
||||
def test_domain_filter():
|
||||
filters = {"discovery_min": None, "availability_min": None, "availability_max": None, "domain": "helix_forge"}
|
||||
matches = select_cohort(filters, SAMPLE_INDEX)
|
||||
assert len(matches) == 2
|
||||
|
||||
|
||||
def test_format_cohort_markdown_includes_filters():
|
||||
filters = {"discovery_min": "D5", "availability_min": None, "availability_max": "A1", "domain": None}
|
||||
text = format_cohort_markdown([SAMPLE_INDEX["capabilities"][0]], filters)
|
||||
assert "planning-min" not in text
|
||||
assert "discovery_min" in text
|
||||
assert "capability.planning.only" in text
|
||||
|
||||
|
||||
def test_format_cohort_json_payload():
|
||||
filters = {"discovery_min": "D5", "availability_min": None, "availability_max": "A1", "domain": None}
|
||||
payload = json.loads(
|
||||
format_cohort_json([SAMPLE_INDEX["capabilities"][0]], filters)
|
||||
)
|
||||
assert payload["count"] == 1
|
||||
assert payload["filters"]["discovery_min"] == "D5"
|
||||
|
||||
|
||||
def test_cmd_report_cohorts_markdown(monkeypatch):
|
||||
from reuse_surface.cli import main
|
||||
|
||||
monkeypatch.setattr(
|
||||
"reuse_surface.reports.load_index",
|
||||
lambda: SAMPLE_INDEX,
|
||||
)
|
||||
exit_code = main(["report", "cohorts", "--planning-min", "D5"])
|
||||
assert exit_code == 0
|
||||
@@ -98,10 +98,27 @@ reuse-surface hub status
|
||||
reuse-surface hub list
|
||||
reuse-surface hub register --repo state-hub --url https://.../capabilities.yaml
|
||||
reuse-surface hub update --repo state-hub --enabled true
|
||||
reuse-surface hub sync --merge
|
||||
reuse-surface hub sync --dry-run
|
||||
```
|
||||
|
||||
Run the service locally: `REUSE_SURFACE_TOKEN=dev-token reuse-surface serve`
|
||||
|
||||
### report cohorts
|
||||
|
||||
Export capability cohorts for planning or implementation reuse decisions.
|
||||
|
||||
```bash
|
||||
reuse-surface report cohorts
|
||||
reuse-surface report cohorts --planning-min D5 --availability-max A1
|
||||
reuse-surface report cohorts --implementation-min A4
|
||||
reuse-surface report cohorts --format json
|
||||
```
|
||||
|
||||
Planning preset (`--planning-min`) sets discovery minimum and defaults
|
||||
`availability-max` to `A1`. Implementation preset (`--implementation-min`) sets
|
||||
availability minimum. Output is Markdown (default) or JSON.
|
||||
|
||||
## Export format
|
||||
|
||||
The export bundle includes:
|
||||
@@ -122,6 +139,8 @@ Stable IDs and maturity fields are preserved for agent consumption (UC-RS-019).
|
||||
| Detect overlap | `reuse-surface overlaps` |
|
||||
| Publish catalog | `reuse-surface catalog` |
|
||||
| Compose federation | `reuse-surface federation compose` |
|
||||
| Sync federation manifest from hub | `reuse-surface hub sync` |
|
||||
| Planning cohort export | `reuse-surface report cohorts` |
|
||||
| Relation graph | `reuse-surface graph` |
|
||||
|
||||
## Related use cases
|
||||
|
||||
@@ -4,11 +4,11 @@ type: workplan
|
||||
title: "Federation scale, planning analytics, and intent alignment"
|
||||
domain: helix_forge
|
||||
repo: reuse-surface
|
||||
status: ready
|
||||
status: finished
|
||||
owner: codex
|
||||
topic_slug: helix-forge
|
||||
created: "2026-06-15"
|
||||
updated: "2026-06-15"
|
||||
updated: "2026-06-16"
|
||||
state_hub_workstream_id: "fb0b6067-6b73-410c-a73c-8bb81a55136a"
|
||||
---
|
||||
|
||||
@@ -61,7 +61,7 @@ T04 (INTENT alignment — unblocks contributors)
|
||||
|
||||
```task
|
||||
id: REUSE-WP-0012-T01
|
||||
status: todo
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "db56e4d8-6bc8-435a-a202-324a20e6928c"
|
||||
```
|
||||
@@ -86,7 +86,7 @@ stable raw URLs.
|
||||
|
||||
```task
|
||||
id: REUSE-WP-0012-T02
|
||||
status: todo
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "521d9c57-80f0-4409-8c20-ad7b9d227128"
|
||||
```
|
||||
@@ -106,7 +106,7 @@ Requirements:
|
||||
|
||||
```task
|
||||
id: REUSE-WP-0012-T03
|
||||
status: todo
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "f3519f29-cfa6-4732-83e7-8833d56c0263"
|
||||
```
|
||||
@@ -132,7 +132,7 @@ Update `docs/IntentScopeGapAnalysis.md` success criteria notes when shipped.
|
||||
|
||||
```task
|
||||
id: REUSE-WP-0012-T04
|
||||
status: todo
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "cdd0bb1e-2ac8-46ef-b5ef-c9d410c6a3ad"
|
||||
```
|
||||
@@ -149,7 +149,7 @@ Close gap priority **21**. Update `INTENT.md` only (product truth unchanged):
|
||||
|
||||
```task
|
||||
id: REUSE-WP-0012-T05
|
||||
status: todo
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "35490a85-34b5-4dcc-9039-156a77320672"
|
||||
```
|
||||
@@ -171,7 +171,7 @@ Target availability narrative: clarify A5 container deployed, A6 path documented
|
||||
|
||||
```task
|
||||
id: REUSE-WP-0012-T06
|
||||
status: todo
|
||||
status: done
|
||||
priority: low
|
||||
state_hub_task_id: "5509cec2-2d2e-4592-b9a5-09902a652705"
|
||||
```
|
||||
@@ -191,10 +191,25 @@ Scope:
|
||||
|
||||
## Acceptance
|
||||
|
||||
- [ ] Hub federates **≥3 repos** (including reuse-surface) OR T01 documents
|
||||
explicit blocks per sibling with owner follow-ups
|
||||
- [ ] `hub sync` materializes valid `sources.yaml` from hub state
|
||||
- [ ] `report cohorts` (or equivalent) exports planning/implementation filters
|
||||
- [ ] `INTENT.md` layout matches delivered repository structure
|
||||
- [ ] Hub hardening doc complete; backup/restore steps verified once on Railiance01
|
||||
- [ ] Gap analysis priorities 18–23 marked closed or explicitly deferred with rationale
|
||||
- [x] Hub federates **≥3 repos** (including reuse-surface) OR T01 documents
|
||||
explicit blocks per sibling with owner follow-ups — **blocks documented**
|
||||
in `history/2026-06-16-hub-registration-blocks.md`
|
||||
- [x] `hub sync` materializes valid `sources.yaml` from hub state
|
||||
- [x] `report cohorts` (or equivalent) exports planning/implementation filters
|
||||
- [x] `INTENT.md` layout matches delivered repository structure
|
||||
- [x] Hub hardening doc complete; backup/restore steps documented (operator verify on Railiance01)
|
||||
- [x] Gap analysis priorities 18–23 marked closed or explicitly deferred with rationale
|
||||
|
||||
## Completion notes (2026-06-16)
|
||||
|
||||
- **T01:** Publish contract in `docs/RegistryFederation.md`; sibling 303 probes in
|
||||
`history/2026-06-16-hub-registration-blocks.md`. Hub remains at 1 repo until
|
||||
siblings publish indexes.
|
||||
- **T02:** `reuse_surface/hub_sync.py`, `reuse-surface hub sync`, pytest in
|
||||
`tests/test_hub_sync.py`.
|
||||
- **T03:** `reuse_surface/reports.py`, `reuse-surface report cohorts`, pytest in
|
||||
`tests/test_reports.py`.
|
||||
- **T04:** `INTENT.md` layout aligned with `SCOPE.md`.
|
||||
- **T05:** Hardening section in `docs/deploy/reuse-kubernetes.md`.
|
||||
- **T06:** R1→R3 checklist in `registry/README.md`; entries `capability.registry.register`,
|
||||
`capability.registry.validate`, `capability.statehub.progress-log` updated.
|
||||
Reference in New Issue
Block a user