Files
railiance-fabric/docs/state-hub-integration.md

160 lines
3.9 KiB
Markdown

# State Hub Integration Contract
Railiance Fabric is the authoring and validation layer for ecosystem graph
declarations. State Hub should ingest Fabric outputs as a read model for
coordination, search, dashboards, and planning. It should not become the
primary authoring surface for services, capabilities, interfaces, dependencies,
or bindings.
## Source-Of-Truth Boundary
| Layer | Owns | Does Not Own |
|-------|------|--------------|
| Participating repos | Declaration files under `fabric/` | Global graph interpretation |
| Railiance Fabric | Schemas, type catalogs, validation, graph construction, exports | State Hub tasks/progress/decisions |
| State Hub | Read-model storage, links to repos/workstreams/tasks/progress, dashboard/search views | Editing Fabric declarations |
The flow is:
```text
repo-local fabric/*.yaml
|
v
railiance-fabric validate/export
|
v
State Hub graph read model
|
v
dashboard, search, planning, progress links
```
## Export Shape
The CLI emits `FabricGraphExport` JSON:
```bash
railiance-fabric export --format json
```
Schema: `schemas/state-hub-export.schema.yaml`
Top-level shape:
```yaml
apiVersion: railiance.fabric/v1alpha1
kind: FabricGraphExport
nodes: []
edges: []
```
Node fields:
| Field | Meaning |
|-------|---------|
| `id` | Stable graph id from declaration metadata. |
| `kind` | Declaration kind: service, capability, interface, dependency, or binding. |
| `name` | Human-readable name. |
| `repo` | Owning repo slug. |
| `domain` | Owning domain slug. |
| `lifecycle` | Declaration lifecycle. |
Edge fields:
| Field | Meaning |
|-------|---------|
| `from` | Source node id. |
| `to` | Target node id. |
| `type` | Relationship type, such as `provides`, `exposes`, `available_via`, `consumes`, `binds:exact`, or `uses_interface`. |
## Proposed State Hub Read Model
Add a State Hub ingestion endpoint or job that stores the latest graph export
per source repo:
```text
POST /fabric/graph-exports
```
Suggested payload:
```json
{
"repo_slug": "railiance-fabric",
"commit": "<git-sha>",
"generated_at": "2026-05-17T00:00:00Z",
"graph": {
"apiVersion": "railiance.fabric/v1alpha1",
"kind": "FabricGraphExport",
"nodes": [],
"edges": []
}
}
```
Suggested storage:
```text
fabric_graph_exports
id
repo_id
commit
generated_at
graph_json
created_at
fabric_graph_nodes
export_id
graph_id
kind
name
repo_slug
domain_slug
lifecycle
fabric_graph_edges
export_id
from_graph_id
to_graph_id
edge_type
```
The normalized node/edge tables are optional at first. State Hub can begin with
`fabric_graph_exports.graph_json` and materialize node/edge tables once query
needs harden.
## Linking To Existing State Hub Entities
State Hub should enrich graph nodes by matching:
- `node.repo` -> `managed_repos.slug`
- `node.domain` -> `domains.slug`
- workplan source links -> `workstreams.slug` or file-backed workplan index
- progress events -> `repo_id` and related workstream/task when available
These links are annotations on the read model. They should never overwrite the
repo-owned declaration files.
## Ingestion Rules
1. Reject exports that fail `schemas/state-hub-export.schema.yaml`.
2. Record the source repo and commit for every accepted export.
3. Replace the previous latest export for the same repo only after the new
export validates.
4. Preserve historical exports long enough to compare graph drift.
5. Surface validation errors as State Hub progress events or human-review tasks,
but do not auto-edit declaration files.
## Initial Dashboard Queries
State Hub should be able to answer:
- providers for a capability type
- consumers of a capability or interface
- unresolved dependencies
- blast radius for an interface id or type
- graph nodes by repo/domain/lifecycle
These are the same query families exposed locally by Railiance Fabric. The hub
read model should match local answers for the same export.