generated from coulomb/repo-seed
feat: version state hub fabric export contract
This commit is contained in:
@@ -1,26 +1,27 @@
|
||||
# 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.
|
||||
Railiance Fabric is the discovery, validation, and versioning layer for the
|
||||
Railiance infrastructure-responsibility graph. 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 Fabric topology,
|
||||
ownership, fabric membership, or cross-boundary utility relations.
|
||||
|
||||
## 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 |
|
||||
| Deployment/accountability roots | Durable evidence of infrastructure, deployment, ownership, utility, and payment responsibility | State Hub task state |
|
||||
| Participating repos | Self-description evidence such as code, manifests, API contracts, package metadata, and legacy `fabric/` declarations | All external deployment/fabric relations |
|
||||
| Railiance Fabric | Schemas, discovery, validation, graph construction, accepted snapshots, exports | State Hub tasks/progress/decisions |
|
||||
| State Hub | Read-model storage, links to repos/workstreams/tasks/progress, dashboard/search views | Editing Fabric topology or inventing ownership |
|
||||
|
||||
The flow is:
|
||||
|
||||
```text
|
||||
repo-local fabric/*.yaml
|
||||
accountability roots + durable deployment evidence + repo evidence
|
||||
|
|
||||
v
|
||||
railiance-fabric validate/export
|
||||
railiance-fabric scan/validate/export
|
||||
|
|
||||
v
|
||||
State Hub graph read model
|
||||
@@ -31,7 +32,7 @@ dashboard, search, planning, progress links
|
||||
|
||||
## Export Shape
|
||||
|
||||
The CLI emits `FabricGraphExport` JSON:
|
||||
The CLI and registry emit `FabricGraphExport` JSON:
|
||||
|
||||
```bash
|
||||
railiance-fabric export --format json
|
||||
@@ -39,7 +40,16 @@ railiance-fabric export --format json
|
||||
|
||||
Schema: `schemas/state-hub-export.schema.yaml`
|
||||
|
||||
Top-level shape:
|
||||
The schema now accepts two export families:
|
||||
|
||||
- `railiance.fabric/v1alpha1`: legacy declaration-centered graph export.
|
||||
- `railiance.fabric/v1alpha2` with `schema_version:
|
||||
financial-fabric-v1`: financial Fabric graph export.
|
||||
|
||||
### Legacy v1alpha1 Shape
|
||||
|
||||
The legacy top-level shape remains supported for compatibility with
|
||||
`STATE-WP-0050`:
|
||||
|
||||
```yaml
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
@@ -74,6 +84,57 @@ Edge fields:
|
||||
| `display_only` | `true` when the edge is a visualization/layout relationship rather than a canonical graph claim. |
|
||||
| `evidence_state` | Evidence state for the claim: `observed`, `declared`, `inferred`, `proposed`, or `gap`. |
|
||||
|
||||
### Financial v1alpha2 Shape
|
||||
|
||||
The financial Fabric export adds first-class responsibility and value
|
||||
semantics:
|
||||
|
||||
```yaml
|
||||
apiVersion: railiance.fabric/v1alpha2
|
||||
kind: FabricGraphExport
|
||||
schema_version: financial-fabric-v1
|
||||
netkingdom:
|
||||
id: railiance.netkingdom
|
||||
king_actor_id: actor.railiance.king
|
||||
actors: []
|
||||
fabrics: []
|
||||
nodes: []
|
||||
edges: []
|
||||
unresolved: []
|
||||
```
|
||||
|
||||
Additional top-level sections:
|
||||
|
||||
| Field | Meaning |
|
||||
|-------|---------|
|
||||
| `schema_version` | Financial Fabric export schema identity. |
|
||||
| `netkingdom` | Root responsibility context and king actor. |
|
||||
| `actors` | King, lord, tenant, operator, and steward actors. |
|
||||
| `fabrics` | Fabric and subfabric boundaries. |
|
||||
| `unresolved` | Ownership, containment, or import gaps to display for review. |
|
||||
|
||||
Additional node fields:
|
||||
|
||||
| Field | Meaning |
|
||||
|-------|---------|
|
||||
| `containment` | Netkingdom, fabric, optional subfabric, environment, and optional deployment scenario. |
|
||||
| `ownership` | Owner actor, owner role, and ownership resolution state. |
|
||||
| `accounting` | Optional cost/profit center and allocation metadata. |
|
||||
| `evidence` | Evidence state, review state, confidence, and evidence references. |
|
||||
|
||||
Additional edge fields:
|
||||
|
||||
| Field | Meaning |
|
||||
|-------|---------|
|
||||
| `relationship_category` | `containment`, `ownership`, `technical`, `utility`, `accounting`, or `evidence`. |
|
||||
| `provider` / `consumer` | Owner and boundary context for utility edges. |
|
||||
| `boundary` | Whether the edge crosses fabric or subfabric boundaries. |
|
||||
| `utility` | Utility type, contract, payment schema, metering basis, and business model. |
|
||||
| `accounting` | Optional cost/profit attribution for the relationship. |
|
||||
| `evidence` | Evidence state, review state, confidence, and evidence references. |
|
||||
|
||||
Example payload: `examples/exports/financial-fabric-v1.json`.
|
||||
|
||||
## Proposed State Hub Read Model
|
||||
|
||||
Add a State Hub ingestion endpoint or job that stores the latest graph export
|
||||
@@ -126,9 +187,20 @@ fabric_graph_edges
|
||||
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.
|
||||
The `STATE-WP-0050` implementation already stores a v1alpha1 read model. The
|
||||
`STATE-WP-0051` follow-up should extend that storage with:
|
||||
|
||||
- import/export schema version;
|
||||
- netkingdom id;
|
||||
- fabric and subfabric ids;
|
||||
- actor ids and roles;
|
||||
- node containment;
|
||||
- node owner actor, owner role, and ownership resolution;
|
||||
- edge relationship category;
|
||||
- utility provider/consumer ownership context;
|
||||
- fabric/subfabric boundary crossing flags;
|
||||
- node and edge accounting attribution;
|
||||
- unresolved ownership or containment gaps.
|
||||
|
||||
## Linking To Existing State Hub Entities
|
||||
|
||||
@@ -140,7 +212,7 @@ State Hub should enrich graph nodes by matching:
|
||||
- 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.
|
||||
Fabric export or source evidence.
|
||||
|
||||
## Ingestion Rules
|
||||
|
||||
@@ -150,7 +222,22 @@ repo-owned declaration files.
|
||||
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.
|
||||
but do not auto-edit Fabric topology, ownership, or source evidence.
|
||||
6. For `v1alpha2`, preserve unresolved ownership/containment gaps rather than
|
||||
inventing State Hub-owned values.
|
||||
7. For `v1alpha2`, expose cost/profit center fields as accounting views, not as
|
||||
fabric membership changes.
|
||||
|
||||
## Current State Hub Limitations
|
||||
|
||||
As of `STATE-WP-0050`, State Hub imports the legacy `v1alpha1` export as a
|
||||
read model. It does not yet materialize the `v1alpha2` financial Fabric fields.
|
||||
|
||||
Until `STATE-WP-0051` is implemented, a `v1alpha2` export is a contract and
|
||||
registry capability in `railiance-fabric`, not a fully queryable State Hub read
|
||||
model. Operators should keep importing the current `v1alpha1` export for
|
||||
existing dashboard/query behavior and use `v1alpha2` payloads for contract
|
||||
verification and follow-on implementation.
|
||||
|
||||
## Initial Dashboard Queries
|
||||
|
||||
|
||||
192
examples/exports/financial-fabric-v1.json
Normal file
192
examples/exports/financial-fabric-v1.json
Normal file
@@ -0,0 +1,192 @@
|
||||
{
|
||||
"apiVersion": "railiance.fabric/v1alpha2",
|
||||
"kind": "FabricGraphExport",
|
||||
"schema_version": "financial-fabric-v1",
|
||||
"generated_at": "2026-05-24T00:00:00Z",
|
||||
"source": {
|
||||
"producer": "railiance-fabric",
|
||||
"registry": "registry",
|
||||
"commit": "example",
|
||||
"generation_reason": "operator_refresh"
|
||||
},
|
||||
"compatibility": {
|
||||
"legacy_v1alpha1_supported": true,
|
||||
"breaking_reset": false
|
||||
},
|
||||
"netkingdom": {
|
||||
"id": "railiance.netkingdom",
|
||||
"name": "Railiance Netkingdom",
|
||||
"king_actor_id": "actor.railiance.king"
|
||||
},
|
||||
"actors": [
|
||||
{
|
||||
"id": "actor.railiance.king",
|
||||
"kind": "FabricActor",
|
||||
"role": "king",
|
||||
"name": "Railiance King"
|
||||
},
|
||||
{
|
||||
"id": "actor.railiance.primary-lord",
|
||||
"kind": "FabricActor",
|
||||
"role": "lord",
|
||||
"name": "Railiance Primary Lord"
|
||||
},
|
||||
{
|
||||
"id": "actor.coulomb.tenant",
|
||||
"kind": "FabricActor",
|
||||
"role": "tenant",
|
||||
"name": "Coulomb Tenant"
|
||||
}
|
||||
],
|
||||
"fabrics": [
|
||||
{
|
||||
"id": "fabric.railiance.primary",
|
||||
"kind": "Fabric",
|
||||
"name": "Railiance Primary Fabric",
|
||||
"netkingdom_id": "railiance.netkingdom",
|
||||
"lord_actor_id": "actor.railiance.primary-lord",
|
||||
"parent_fabric_id": null,
|
||||
"status": "active",
|
||||
"boundary": {
|
||||
"boundary_type": "fabric",
|
||||
"criterion": "financial_and_operational_accountability"
|
||||
},
|
||||
"evidence_refs": []
|
||||
},
|
||||
{
|
||||
"id": "subfabric.railiance.tenant.coulomb",
|
||||
"kind": "Subfabric",
|
||||
"name": "Coulomb Tenant Subfabric",
|
||||
"netkingdom_id": "railiance.netkingdom",
|
||||
"parent_fabric_id": "fabric.railiance.primary",
|
||||
"tenant_actor_id": "actor.coulomb.tenant",
|
||||
"status": "planned",
|
||||
"boundary": {
|
||||
"boundary_type": "subfabric",
|
||||
"criterion": "restricted_paid_tenant_utility"
|
||||
},
|
||||
"evidence_refs": []
|
||||
}
|
||||
],
|
||||
"nodes": [
|
||||
{
|
||||
"id": "state-hub.http",
|
||||
"kind": "UtilityInterface",
|
||||
"name": "State Hub HTTP API",
|
||||
"repo": "state-hub",
|
||||
"domain": "custodian",
|
||||
"lifecycle": "active",
|
||||
"containment": {
|
||||
"netkingdom_id": "railiance.netkingdom",
|
||||
"fabric_id": "fabric.railiance.primary",
|
||||
"subfabric_id": null,
|
||||
"environment": "local",
|
||||
"deployment_scenario_id": null
|
||||
},
|
||||
"ownership": {
|
||||
"owner_actor_id": "actor.railiance.primary-lord",
|
||||
"owner_role": "lord",
|
||||
"resolution": "inherited",
|
||||
"inherited_from": "fabric.railiance.primary",
|
||||
"supporting_actor_ids": []
|
||||
},
|
||||
"accounting": {
|
||||
"cost_center_id": "cc.platform.shared",
|
||||
"allocation_model": "direct"
|
||||
},
|
||||
"evidence": {
|
||||
"state": "declared",
|
||||
"review_state": "accepted",
|
||||
"confidence": 0.9,
|
||||
"refs": []
|
||||
},
|
||||
"canon_category": "endpoint",
|
||||
"canon_anchor": "model/network",
|
||||
"mapping_fit": "partial",
|
||||
"evidence_state": "declared",
|
||||
"attributes": {
|
||||
"description": "Example tenant-facing State Hub API utility."
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "coulomb.automation-client",
|
||||
"kind": "Service",
|
||||
"name": "Coulomb Automation Client",
|
||||
"repo": "coulomb-automation",
|
||||
"domain": "railiance",
|
||||
"lifecycle": "planned",
|
||||
"containment": {
|
||||
"netkingdom_id": "railiance.netkingdom",
|
||||
"fabric_id": "fabric.railiance.primary",
|
||||
"subfabric_id": "subfabric.railiance.tenant.coulomb",
|
||||
"environment": "local",
|
||||
"deployment_scenario_id": null
|
||||
},
|
||||
"ownership": {
|
||||
"owner_actor_id": "actor.coulomb.tenant",
|
||||
"owner_role": "tenant",
|
||||
"resolution": "explicit",
|
||||
"supporting_actor_ids": []
|
||||
},
|
||||
"accounting": {
|
||||
"cost_center_id": "cc.coulomb.automation",
|
||||
"allocation_model": "direct"
|
||||
},
|
||||
"evidence": {
|
||||
"state": "declared",
|
||||
"review_state": "accepted",
|
||||
"confidence": 0.8,
|
||||
"refs": []
|
||||
},
|
||||
"attributes": {}
|
||||
}
|
||||
],
|
||||
"edges": [
|
||||
{
|
||||
"id": "utility:state-hub-http:coulomb-client",
|
||||
"from": "state-hub.http",
|
||||
"to": "coulomb.automation-client",
|
||||
"type": "provides_utility_to",
|
||||
"relationship_category": "utility",
|
||||
"canonical_type": "depends_on",
|
||||
"canon_anchor": "model/landscape",
|
||||
"mapping_fit": "partial",
|
||||
"display_only": false,
|
||||
"evidence_state": "declared",
|
||||
"provider": {
|
||||
"owner_actor_id": "actor.railiance.primary-lord",
|
||||
"fabric_id": "fabric.railiance.primary",
|
||||
"subfabric_id": null
|
||||
},
|
||||
"consumer": {
|
||||
"owner_actor_id": "actor.coulomb.tenant",
|
||||
"fabric_id": "fabric.railiance.primary",
|
||||
"subfabric_id": "subfabric.railiance.tenant.coulomb"
|
||||
},
|
||||
"boundary": {
|
||||
"crosses_fabric_boundary": false,
|
||||
"crosses_subfabric_boundary": true
|
||||
},
|
||||
"utility": {
|
||||
"utility_type": "coordination_api",
|
||||
"contract_id": "state-hub.http",
|
||||
"payment_schema_id": "payment.internal-tenant-access",
|
||||
"metering_basis": "unknown",
|
||||
"business_model": "tenant_utility"
|
||||
},
|
||||
"accounting": {
|
||||
"provider_profit_center_id": "pc.tenant-utilities",
|
||||
"consumer_cost_center_id": "cc.coulomb.automation",
|
||||
"allocation_model": "usage_weighted"
|
||||
},
|
||||
"evidence": {
|
||||
"state": "declared",
|
||||
"review_state": "accepted",
|
||||
"confidence": 0.8,
|
||||
"refs": []
|
||||
},
|
||||
"attributes": {}
|
||||
}
|
||||
],
|
||||
"unresolved": []
|
||||
}
|
||||
@@ -1,119 +1,578 @@
|
||||
$schema: "https://json-schema.org/draft/2020-12/schema"
|
||||
$id: "https://railiance.local/fabric/schemas/state-hub-export.schema.yaml"
|
||||
title: "FabricGraphExport"
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required:
|
||||
- apiVersion
|
||||
- kind
|
||||
- nodes
|
||||
- edges
|
||||
properties:
|
||||
apiVersion:
|
||||
type: string
|
||||
const: railiance.fabric/v1alpha1
|
||||
kind:
|
||||
type: string
|
||||
const: FabricGraphExport
|
||||
generated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
source:
|
||||
oneOf:
|
||||
- $ref: "#/$defs/legacyGraphExport"
|
||||
- $ref: "#/$defs/financialGraphExport"
|
||||
|
||||
$defs:
|
||||
legacyGraphExport:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required:
|
||||
- apiVersion
|
||||
- kind
|
||||
- nodes
|
||||
- edges
|
||||
properties:
|
||||
apiVersion:
|
||||
type: string
|
||||
const: railiance.fabric/v1alpha1
|
||||
kind:
|
||||
type: string
|
||||
const: FabricGraphExport
|
||||
generated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
source:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
properties:
|
||||
repo:
|
||||
type: string
|
||||
commit:
|
||||
type: string
|
||||
path:
|
||||
type: string
|
||||
nodes:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/$defs/legacyNode"
|
||||
edges:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/$defs/legacyEdge"
|
||||
|
||||
financialGraphExport:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required:
|
||||
- apiVersion
|
||||
- kind
|
||||
- schema_version
|
||||
- netkingdom
|
||||
- actors
|
||||
- fabrics
|
||||
- nodes
|
||||
- edges
|
||||
properties:
|
||||
apiVersion:
|
||||
type: string
|
||||
const: railiance.fabric/v1alpha2
|
||||
kind:
|
||||
type: string
|
||||
const: FabricGraphExport
|
||||
schema_version:
|
||||
type: string
|
||||
const: financial-fabric-v1
|
||||
generated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
source:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
compatibility:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
netkingdom:
|
||||
$ref: "#/$defs/netkingdom"
|
||||
actors:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/$defs/actor"
|
||||
fabrics:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/$defs/fabricBoundary"
|
||||
nodes:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/$defs/financialNode"
|
||||
edges:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/$defs/financialEdge"
|
||||
unresolved:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/$defs/unresolvedGap"
|
||||
|
||||
legacyNode:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required:
|
||||
- id
|
||||
- kind
|
||||
- name
|
||||
- repo
|
||||
- domain
|
||||
- lifecycle
|
||||
properties:
|
||||
id:
|
||||
$ref: "./common.schema.yaml#/$defs/graphId"
|
||||
kind:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
repo:
|
||||
type: string
|
||||
commit:
|
||||
domain:
|
||||
type: string
|
||||
path:
|
||||
lifecycle:
|
||||
type: string
|
||||
nodes:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required:
|
||||
- id
|
||||
- kind
|
||||
- name
|
||||
- repo
|
||||
- domain
|
||||
- lifecycle
|
||||
properties:
|
||||
id:
|
||||
canon_category:
|
||||
type: string
|
||||
canon_anchor:
|
||||
type: string
|
||||
mapping_fit:
|
||||
$ref: "#/$defs/mappingFit"
|
||||
evidence_state:
|
||||
$ref: "#/$defs/evidenceState"
|
||||
attributes:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
|
||||
legacyEdge:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required:
|
||||
- from
|
||||
- to
|
||||
- type
|
||||
properties:
|
||||
from:
|
||||
$ref: "./common.schema.yaml#/$defs/graphId"
|
||||
to:
|
||||
$ref: "./common.schema.yaml#/$defs/graphId"
|
||||
type:
|
||||
type: string
|
||||
canonical_type:
|
||||
type: string
|
||||
canon_anchor:
|
||||
type: string
|
||||
mapping_fit:
|
||||
$ref: "#/$defs/mappingFit"
|
||||
display_only:
|
||||
type: boolean
|
||||
evidence_state:
|
||||
$ref: "#/$defs/evidenceState"
|
||||
attributes:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
|
||||
netkingdom:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required:
|
||||
- id
|
||||
- name
|
||||
- king_actor_id
|
||||
properties:
|
||||
id:
|
||||
$ref: "./common.schema.yaml#/$defs/graphId"
|
||||
name:
|
||||
type: string
|
||||
minLength: 1
|
||||
king_actor_id:
|
||||
$ref: "./common.schema.yaml#/$defs/graphId"
|
||||
|
||||
actor:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
required:
|
||||
- id
|
||||
- kind
|
||||
- role
|
||||
- name
|
||||
properties:
|
||||
id:
|
||||
$ref: "./common.schema.yaml#/$defs/graphId"
|
||||
kind:
|
||||
type: string
|
||||
const: FabricActor
|
||||
role:
|
||||
type: string
|
||||
enum:
|
||||
- king
|
||||
- lord
|
||||
- tenant
|
||||
- operator
|
||||
- steward
|
||||
name:
|
||||
type: string
|
||||
minLength: 1
|
||||
|
||||
fabricBoundary:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
required:
|
||||
- id
|
||||
- kind
|
||||
- name
|
||||
- netkingdom_id
|
||||
- status
|
||||
properties:
|
||||
id:
|
||||
$ref: "./common.schema.yaml#/$defs/graphId"
|
||||
kind:
|
||||
type: string
|
||||
enum:
|
||||
- Fabric
|
||||
- Subfabric
|
||||
name:
|
||||
type: string
|
||||
minLength: 1
|
||||
netkingdom_id:
|
||||
$ref: "./common.schema.yaml#/$defs/graphId"
|
||||
parent_fabric_id:
|
||||
anyOf:
|
||||
- $ref: "./common.schema.yaml#/$defs/graphId"
|
||||
- type: "null"
|
||||
lord_actor_id:
|
||||
$ref: "./common.schema.yaml#/$defs/graphId"
|
||||
tenant_actor_id:
|
||||
$ref: "./common.schema.yaml#/$defs/graphId"
|
||||
status:
|
||||
type: string
|
||||
minLength: 1
|
||||
boundary:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
evidence_refs:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/$defs/evidenceRef"
|
||||
|
||||
financialNode:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required:
|
||||
- id
|
||||
- kind
|
||||
- name
|
||||
- containment
|
||||
- ownership
|
||||
- evidence
|
||||
properties:
|
||||
id:
|
||||
$ref: "./common.schema.yaml#/$defs/graphId"
|
||||
kind:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
minLength: 1
|
||||
repo:
|
||||
type: string
|
||||
domain:
|
||||
type: string
|
||||
lifecycle:
|
||||
type: string
|
||||
containment:
|
||||
$ref: "#/$defs/containment"
|
||||
ownership:
|
||||
$ref: "#/$defs/ownership"
|
||||
accounting:
|
||||
$ref: "#/$defs/accounting"
|
||||
evidence:
|
||||
$ref: "#/$defs/evidence"
|
||||
canon_category:
|
||||
type: string
|
||||
canon_anchor:
|
||||
type: string
|
||||
mapping_fit:
|
||||
$ref: "#/$defs/mappingFit"
|
||||
evidence_state:
|
||||
$ref: "#/$defs/evidenceState"
|
||||
attributes:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
|
||||
financialEdge:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required:
|
||||
- from
|
||||
- to
|
||||
- type
|
||||
- relationship_category
|
||||
- evidence
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
minLength: 1
|
||||
from:
|
||||
$ref: "./common.schema.yaml#/$defs/graphId"
|
||||
to:
|
||||
$ref: "./common.schema.yaml#/$defs/graphId"
|
||||
type:
|
||||
type: string
|
||||
minLength: 1
|
||||
relationship_category:
|
||||
type: string
|
||||
enum:
|
||||
- containment
|
||||
- ownership
|
||||
- technical
|
||||
- utility
|
||||
- accounting
|
||||
- evidence
|
||||
canonical_type:
|
||||
type: string
|
||||
canon_anchor:
|
||||
type: string
|
||||
mapping_fit:
|
||||
$ref: "#/$defs/mappingFit"
|
||||
display_only:
|
||||
type: boolean
|
||||
evidence_state:
|
||||
$ref: "#/$defs/evidenceState"
|
||||
provider:
|
||||
$ref: "#/$defs/utilitySide"
|
||||
consumer:
|
||||
$ref: "#/$defs/utilitySide"
|
||||
boundary:
|
||||
$ref: "#/$defs/boundaryCrossing"
|
||||
utility:
|
||||
$ref: "#/$defs/utility"
|
||||
accounting:
|
||||
$ref: "#/$defs/accounting"
|
||||
evidence:
|
||||
$ref: "#/$defs/evidence"
|
||||
attributes:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
relationship_category:
|
||||
const: utility
|
||||
then:
|
||||
required:
|
||||
- provider
|
||||
- consumer
|
||||
- boundary
|
||||
- utility
|
||||
|
||||
containment:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required:
|
||||
- netkingdom_id
|
||||
- fabric_id
|
||||
properties:
|
||||
netkingdom_id:
|
||||
$ref: "./common.schema.yaml#/$defs/graphId"
|
||||
fabric_id:
|
||||
$ref: "./common.schema.yaml#/$defs/graphId"
|
||||
subfabric_id:
|
||||
anyOf:
|
||||
- $ref: "./common.schema.yaml#/$defs/graphId"
|
||||
- type: "null"
|
||||
environment:
|
||||
anyOf:
|
||||
- type: string
|
||||
minLength: 1
|
||||
- type: "null"
|
||||
deployment_scenario_id:
|
||||
anyOf:
|
||||
- type: string
|
||||
minLength: 1
|
||||
- type: "null"
|
||||
|
||||
ownership:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required:
|
||||
- owner_actor_id
|
||||
- owner_role
|
||||
- resolution
|
||||
properties:
|
||||
owner_actor_id:
|
||||
$ref: "./common.schema.yaml#/$defs/graphId"
|
||||
owner_role:
|
||||
type: string
|
||||
enum:
|
||||
- king
|
||||
- lord
|
||||
- tenant
|
||||
- operator
|
||||
- steward
|
||||
resolution:
|
||||
type: string
|
||||
enum:
|
||||
- explicit
|
||||
- inherited
|
||||
- unresolved
|
||||
- ambiguous
|
||||
inherited_from:
|
||||
anyOf:
|
||||
- $ref: "./common.schema.yaml#/$defs/graphId"
|
||||
- type: "null"
|
||||
supporting_actor_ids:
|
||||
type: array
|
||||
items:
|
||||
$ref: "./common.schema.yaml#/$defs/graphId"
|
||||
kind:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
repo:
|
||||
type: string
|
||||
domain:
|
||||
type: string
|
||||
lifecycle:
|
||||
type: string
|
||||
canon_category:
|
||||
type: string
|
||||
canon_anchor:
|
||||
type: string
|
||||
mapping_fit:
|
||||
type: string
|
||||
enum:
|
||||
- direct
|
||||
- partial
|
||||
- conflict
|
||||
- gap
|
||||
- unknown
|
||||
evidence_state:
|
||||
type: string
|
||||
enum:
|
||||
- observed
|
||||
- declared
|
||||
- inferred
|
||||
- proposed
|
||||
- gap
|
||||
attributes:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
edges:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required:
|
||||
- from
|
||||
- to
|
||||
- type
|
||||
properties:
|
||||
from:
|
||||
$ref: "./common.schema.yaml#/$defs/graphId"
|
||||
to:
|
||||
$ref: "./common.schema.yaml#/$defs/graphId"
|
||||
type:
|
||||
type: string
|
||||
canonical_type:
|
||||
type: string
|
||||
canon_anchor:
|
||||
type: string
|
||||
mapping_fit:
|
||||
type: string
|
||||
enum:
|
||||
- direct
|
||||
- partial
|
||||
- conflict
|
||||
- gap
|
||||
- unknown
|
||||
display_only:
|
||||
type: boolean
|
||||
evidence_state:
|
||||
type: string
|
||||
enum:
|
||||
- observed
|
||||
- declared
|
||||
- inferred
|
||||
- proposed
|
||||
- gap
|
||||
attributes:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
|
||||
utilitySide:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required:
|
||||
- owner_actor_id
|
||||
- fabric_id
|
||||
properties:
|
||||
owner_actor_id:
|
||||
$ref: "./common.schema.yaml#/$defs/graphId"
|
||||
fabric_id:
|
||||
$ref: "./common.schema.yaml#/$defs/graphId"
|
||||
subfabric_id:
|
||||
anyOf:
|
||||
- $ref: "./common.schema.yaml#/$defs/graphId"
|
||||
- type: "null"
|
||||
|
||||
boundaryCrossing:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required:
|
||||
- crosses_fabric_boundary
|
||||
- crosses_subfabric_boundary
|
||||
properties:
|
||||
crosses_fabric_boundary:
|
||||
type: boolean
|
||||
crosses_subfabric_boundary:
|
||||
type: boolean
|
||||
|
||||
utility:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
required:
|
||||
- utility_type
|
||||
properties:
|
||||
utility_type:
|
||||
type: string
|
||||
minLength: 1
|
||||
contract_id:
|
||||
type: string
|
||||
payment_schema_id:
|
||||
type: string
|
||||
metering_basis:
|
||||
type: string
|
||||
business_model:
|
||||
type: string
|
||||
|
||||
accounting:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
properties:
|
||||
cost_center_id:
|
||||
type: string
|
||||
profit_center_id:
|
||||
type: string
|
||||
provider_profit_center_id:
|
||||
type: string
|
||||
consumer_cost_center_id:
|
||||
type: string
|
||||
allocation_model:
|
||||
type: string
|
||||
payment_schema_id:
|
||||
type: string
|
||||
metering_basis:
|
||||
type: string
|
||||
valid_from:
|
||||
type: string
|
||||
valid_until:
|
||||
anyOf:
|
||||
- type: string
|
||||
- type: "null"
|
||||
|
||||
evidence:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required:
|
||||
- state
|
||||
- review_state
|
||||
properties:
|
||||
state:
|
||||
$ref: "#/$defs/evidenceState"
|
||||
review_state:
|
||||
type: string
|
||||
enum:
|
||||
- accepted
|
||||
- candidate
|
||||
- needs_review
|
||||
- rejected
|
||||
confidence:
|
||||
type: number
|
||||
minimum: 0
|
||||
maximum: 1
|
||||
refs:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/$defs/evidenceRef"
|
||||
|
||||
evidenceRef:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
source_kind:
|
||||
type: string
|
||||
source_path:
|
||||
type: string
|
||||
source_url:
|
||||
type: string
|
||||
source_repo:
|
||||
type: string
|
||||
source_commit:
|
||||
type: string
|
||||
scanner:
|
||||
type: string
|
||||
scanner_version:
|
||||
type: string
|
||||
content_hash:
|
||||
type: string
|
||||
observed_at:
|
||||
type: string
|
||||
format: date-time
|
||||
|
||||
unresolvedGap:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
required:
|
||||
- target_id
|
||||
- kind
|
||||
- message
|
||||
properties:
|
||||
target_id:
|
||||
type: string
|
||||
minLength: 1
|
||||
kind:
|
||||
type: string
|
||||
minLength: 1
|
||||
severity:
|
||||
type: string
|
||||
message:
|
||||
type: string
|
||||
minLength: 1
|
||||
evidence_refs:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/$defs/evidenceRef"
|
||||
|
||||
mappingFit:
|
||||
type: string
|
||||
enum:
|
||||
- direct
|
||||
- partial
|
||||
- conflict
|
||||
- gap
|
||||
- unknown
|
||||
|
||||
evidenceState:
|
||||
type: string
|
||||
enum:
|
||||
- observed
|
||||
- declared
|
||||
- inferred
|
||||
- proposed
|
||||
- gap
|
||||
|
||||
@@ -8,6 +8,7 @@ from pathlib import Path
|
||||
|
||||
from railiance_fabric.cli import main as cli_main
|
||||
from railiance_fabric.graph import build_graph
|
||||
from railiance_fabric.financial import materialize_financial_graph_export
|
||||
from railiance_fabric.registry import (
|
||||
RESET_CONFIRMATION_TOKEN,
|
||||
RegistryError,
|
||||
@@ -21,6 +22,7 @@ from railiance_fabric.registry import (
|
||||
validate_graph_export,
|
||||
xregistry_projection,
|
||||
)
|
||||
from railiance_fabric.schema_validation import draft202012_validator
|
||||
from railiance_fabric.server import RegistryHandler
|
||||
|
||||
|
||||
@@ -261,6 +263,20 @@ def test_graph_export_validation_rejects_unflagged_display_edges() -> None:
|
||||
raise AssertionError("expected RegistryError for unflagged display-only edge")
|
||||
|
||||
|
||||
def test_state_hub_export_schema_accepts_legacy_and_financial_shapes() -> None:
|
||||
validator = draft202012_validator(Path("schemas/state-hub-export.schema.yaml"))
|
||||
legacy_graph = {
|
||||
"apiVersion": "railiance.fabric/v1alpha1",
|
||||
"kind": "FabricGraphExport",
|
||||
"nodes": [],
|
||||
"edges": [],
|
||||
}
|
||||
financial_graph = materialize_financial_graph_export(_financial_graph())
|
||||
|
||||
assert list(validator.iter_errors(legacy_graph)) == []
|
||||
assert list(validator.iter_errors(financial_graph)) == []
|
||||
|
||||
|
||||
def test_financial_graph_export_requires_resolvable_owner() -> None:
|
||||
graph = _financial_graph()
|
||||
del graph["nodes"][0]["ownership"]
|
||||
|
||||
@@ -190,7 +190,7 @@ Result:
|
||||
|
||||
```task
|
||||
id: RAIL-FAB-WP-0017-T04
|
||||
status: todo
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "d10f120d-746d-468d-b208-d946b54c2707"
|
||||
```
|
||||
@@ -215,6 +215,24 @@ Done when:
|
||||
- compatibility tests cover both old baseline import behavior and the new
|
||||
vNext export behavior, or intentionally document a controlled breaking reset.
|
||||
|
||||
Result:
|
||||
|
||||
- Updated `schemas/state-hub-export.schema.yaml` to accept both the legacy
|
||||
`railiance.fabric/v1alpha1` declaration-centered export and the
|
||||
`railiance.fabric/v1alpha2` / `financial-fabric-v1` export.
|
||||
- Added schema fields for netkingdom, actors, fabrics, node containment,
|
||||
node ownership, accounting attribution, evidence, utility edge
|
||||
provider/consumer context, boundary crossing flags, and unresolved gaps.
|
||||
- Added `examples/exports/financial-fabric-v1.json` as a materialized sample
|
||||
payload.
|
||||
- Updated `docs/state-hub-integration.md` to describe the v1alpha1/v1alpha2
|
||||
contract split, State Hub import expectations, and the current limitation
|
||||
that `STATE-WP-0050` only materializes v1alpha1 until `STATE-WP-0051`.
|
||||
- Added schema compatibility coverage for both old and financial graph export
|
||||
shapes.
|
||||
- Verified with `python3 -m pytest tests/test_registry.py -q` and full
|
||||
`python3 -m pytest`.
|
||||
|
||||
## T05 - Seed The Current Railiance Netkingdom Baseline
|
||||
|
||||
```task
|
||||
|
||||
Reference in New Issue
Block a user