generated from coulomb/repo-seed
Compare commits
142 Commits
d1c003411f
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 20316c533f | |||
| 58a2cfac5c | |||
| 7312ed3767 | |||
| f9e661ec69 | |||
| f57a5c1dce | |||
| 757770b42f | |||
| 635521406f | |||
| 2afeb86ed2 | |||
| caa1e4100d | |||
| dae9e3409a | |||
| e23ed0c06b | |||
| fe2e98e2a4 | |||
| 7cb943ed41 | |||
| 31841d0f1c | |||
| 40b409cd92 | |||
| 0b5d295800 | |||
| 5dff7f14da | |||
| 5e89f6a075 | |||
| f09f110e77 | |||
| 558e0dc157 | |||
| 0f7b7d1fed | |||
| 9b612447ca | |||
| a7a22a673f | |||
| 296ac051a7 | |||
| 1ad432270b | |||
| f1cd74dc7b | |||
| d060b1c896 | |||
| fdee0b0855 | |||
| f41d0da831 | |||
| 5a2d987b6a | |||
| ea81533172 | |||
| c26a725f92 | |||
| 8176d88926 | |||
| ff1c4ce05b | |||
| 62236f6453 | |||
| d9f1f3f71a | |||
| 5c9c2f281e | |||
| ea2fa1203b | |||
| e60e8d5bb4 | |||
| 735867392e | |||
| 7956415924 | |||
| 355b7be66a | |||
| 071a4c49e3 | |||
| a55f1a45d6 | |||
| c27d71a511 | |||
| ab7e0ccab1 | |||
| 26f1913d51 | |||
| 999f90dcbe | |||
| 43d3866b18 | |||
| a1bd9df8e4 | |||
| 455362153d | |||
| f4aa4aa996 | |||
| 9717b18b02 | |||
| 13188a6ae1 | |||
| 7d9b49764b | |||
| 63379ca329 | |||
| be0299e528 | |||
| 3a47a92729 | |||
| 3318d2c1b9 | |||
| 39762551c0 | |||
| 0874446994 | |||
| 7db9c3cbf2 | |||
| a1e99d9b34 | |||
| b70e74fde5 | |||
| d3fe1e3ed3 | |||
| fd859998c4 | |||
| 3e181e58ff | |||
| f6dbf31db1 | |||
| 9c22d3e0df | |||
| 653411ffb8 | |||
| 0193c97094 | |||
| 01bc4f3efe | |||
| 072fa8f7a7 | |||
| a8e67db9e9 | |||
| af4132c182 | |||
| 78e8d381c2 | |||
| e3440df163 | |||
| 36d4b895f9 | |||
| 5e0ffea585 | |||
| 56b73dbab0 | |||
| c73815a115 | |||
| 9ad2750965 | |||
| 0db4292db5 | |||
| 4fdf552f73 | |||
| 50810ffd54 | |||
| 6746943c0b | |||
| babbe88a46 | |||
| be7252019f | |||
| 68cf01aa39 | |||
| 0b093741e2 | |||
| 239ad11547 | |||
| 17356a41d6 | |||
| 73f7cdbdb5 | |||
| a76c6a4aea | |||
| bc25eb6871 | |||
| afd8b3d608 | |||
| 17bd23e79b | |||
| 1c0995004e | |||
| e150270511 | |||
| 5523b8f493 | |||
| edf2062a7a | |||
| 9f4d8a3958 | |||
| 0e2adcbe84 | |||
| 93593a5b56 | |||
| 33f0a52068 | |||
| 5777c283f7 | |||
| 6fa1d1d824 | |||
| 28511db909 | |||
| 99993c7cb2 | |||
| 4f4f28a6d5 | |||
| 98a747dd5a | |||
| d9c5bf1bd4 | |||
| 88ccc973e4 | |||
| 035381a9df | |||
| 2a2616653f | |||
| 95901feb0d | |||
| e6a74fb474 | |||
| 5b6e4faf68 | |||
| b2165b5a2a | |||
| dc3051aa8e | |||
| 29fe6a941f | |||
| aa42b6f84c | |||
| 49dc23f919 | |||
| 229191c802 | |||
| 004e3cb976 | |||
| 55db37b1ca | |||
| 43ed6e69e0 | |||
| 01840d848f | |||
| 8a31258785 | |||
| eea1156fd6 | |||
| d31b1376c8 | |||
| d2056c9046 | |||
| 91f329f878 | |||
| eec7e2a9f6 | |||
| ae4f567a2b | |||
| 251637c1b4 | |||
| 9f1f93217e | |||
| 2f06d2a277 | |||
| 3ddf76252b | |||
| f372d5f0e4 | |||
| bc73b05566 | |||
| 5c20f62fbb |
20
.claude/rules/agents.md
Normal file
20
.claude/rules/agents.md
Normal file
@@ -0,0 +1,20 @@
|
||||
## Kaizen Agents
|
||||
|
||||
Specialized agent personas available on demand via the state-hub MCP.
|
||||
|
||||
**Discover:** `list_kaizen_agents()` — returns all agents with name, description, category
|
||||
**Load:** `get_kaizen_agent("tdd-workflow")` — returns full instructions; read and follow them
|
||||
|
||||
Common agents:
|
||||
|
||||
| Agent | Category | When to use |
|
||||
|-------|----------|-------------|
|
||||
| `tdd-workflow` | testing | Step-by-step TDD8 workflow for any feature |
|
||||
| `code-refactoring` | quality | Code quality analysis and safe refactoring |
|
||||
| `test-maintenance` | testing | Diagnose and fix failing tests |
|
||||
| `requirements-engineering` | process | Prevent interface/mock mismatches upfront |
|
||||
| `keepaTodofile` | process | Maintain TODO.md during work |
|
||||
| `project-management` | process | Track status, determine next steps |
|
||||
| `datamodel-optimization` | quality | Optimize dataclasses and data structures |
|
||||
|
||||
All 17 agents: call `list_kaizen_agents()` for the full list.
|
||||
8
.claude/rules/architecture.md
Normal file
8
.claude/rules/architecture.md
Normal file
@@ -0,0 +1,8 @@
|
||||
## Architecture
|
||||
|
||||
<!-- TODO: Describe the key design decisions and component structure.
|
||||
Key modules, data flows, external integrations, state machines, etc. -->
|
||||
|
||||
## Quick Reference
|
||||
|
||||
`~/state-hub/mcp_server/TOOLS.md` — MCP tool reference
|
||||
50
.claude/rules/credential-routing.md
Normal file
50
.claude/rules/credential-routing.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# Credential and access routing
|
||||
|
||||
**Audience:** Codex, Claude Code, Grok, and custodian agents that call **llm-connect**
|
||||
for inference. Run this check **before** requesting secrets, API keys, SSH access,
|
||||
login tokens, or database passwords — in any repo, not only `ops-warden`.
|
||||
|
||||
ops-warden **issues SSH certificates only** (`warden sign`, `cert_command`). Every
|
||||
other credential need belongs to another subsystem. **Do not** message
|
||||
`ops-warden` on State Hub expecting a secret value; the reply is a pointer, not a key.
|
||||
|
||||
### Lookup (do this first)
|
||||
|
||||
```bash
|
||||
warden route find "<describe your need>" --json
|
||||
warden route show <catalog-id> --json
|
||||
```
|
||||
|
||||
Requires the `warden` CLI from `~/ops-warden` (`uv tool install .` or `uv run warden`).
|
||||
|
||||
| Agent runtime | How to orient |
|
||||
| --- | --- |
|
||||
| **Codex / Grok** (shell, HTTP State Hub) | `warden route` commands above; inbox `to_agent=railiance-fabric` is for coordination, not secret vending |
|
||||
| **Claude Code** (MCP when available) | `get_domain_summary("custodian")` for workplans; **still** use `warden route` for credential ownership |
|
||||
| **llm-connect** (inference service) | Never put secret retrieval in prompts; route custody to OpenBao/operator paths surfaced by `warden route` |
|
||||
|
||||
### Quick routing table
|
||||
|
||||
| I need… | Owner | ops-warden executes? |
|
||||
| --- | --- | --- |
|
||||
| SSH cert (`adm`/`agt`/`atm`) | ops-warden | **Yes** — `warden sign` |
|
||||
| API key, DB password, provider token | OpenBao (`railiance-platform`) | No — route only |
|
||||
| Login / OIDC / MFA | key-cape / Keycloak | No — route only |
|
||||
| Authorization decision | flex-auth | No — route only |
|
||||
| activity-core → issue-core emission | activity-core + issue-core | No — `warden route show activity-core-issue-sink` |
|
||||
| SSH tunnel | ops-bridge (+ `cert_command` from warden) | No — route only |
|
||||
|
||||
### Anti-patterns (do not do these)
|
||||
|
||||
- `POST /messages/` to `ops-warden` asking for `ISSUE_CORE_API_KEY`, `OPENROUTER_API_KEY`, etc.
|
||||
- Inventing `warden secret`, `warden login`, `warden bao`, `warden tunnel` — they do not exist
|
||||
- Pasting secrets into Git, State Hub, workplans, logs, or chat
|
||||
|
||||
### Other capabilities (reuse-surface)
|
||||
|
||||
Non-credential capabilities are usually discovered through **reuse-surface** federation
|
||||
(`reuse-surface` registry / `capability.*` indexes). Credential routing is inlined in
|
||||
every repo's agent instructions because it is high-frequency, high-risk, and easy to
|
||||
get wrong.
|
||||
|
||||
**Canon:** `~/ops-warden/wiki/CredentialRouting.md` · catalog `~/ops-warden/registry/routing/catalog.yaml`
|
||||
42
.claude/rules/first-session.md
Normal file
42
.claude/rules/first-session.md
Normal file
@@ -0,0 +1,42 @@
|
||||
## First Session Protocol
|
||||
|
||||
Triggered when `get_domain_summary("financials")` shows **no workplans**.
|
||||
The project is registered but work has not yet been structured.
|
||||
|
||||
**Step 1 — Read, don't write**
|
||||
- `~/the-custodian/canon/projects/financials/project_charter_v0.1.md` — purpose, scope
|
||||
- `~/the-custodian/canon/projects/financials/roadmap_v0.1.md` — planned phases
|
||||
- Scan repo root: README, directory structure, existing code or docs
|
||||
|
||||
**Step 2 — Survey in-progress work**
|
||||
Look for TODOs, open branches, half-finished files. Note done vs. started but incomplete.
|
||||
|
||||
**Step 3 — Propose workplans to Bernd**
|
||||
Propose 1–3 workplans — each a coherent strand, weeks to months, anchored to a
|
||||
roadmap phase. **Wait for approval before creating.**
|
||||
|
||||
**Step 4 — Write the workplan file; fix-consistency registers it (ADR-001)**
|
||||
```
|
||||
workplans/RAILIANCE-WP-NNNN-<slug>.md ← write this, commit it
|
||||
```
|
||||
Then register by running the consistency check — do **not** call
|
||||
`create_workplan`/`create_task` (or legacy `create_workstream`) yourself;
|
||||
manual registration duplicates what C-06 creates from the file:
|
||||
```bash
|
||||
statehub fix-consistency --repo railiance-fabric
|
||||
```
|
||||
C-06 creates the hub workplan + tasks and writes `state_hub_workstream_id` /
|
||||
`state_hub_task_id` back into the file (legacy field names, kept for
|
||||
compatibility — they hold workplan/task IDs).
|
||||
|
||||
**Step 5 — Record the setup**
|
||||
```
|
||||
add_progress_event(
|
||||
summary="First session: structured financials into N workplans, M tasks",
|
||||
event_type="milestone",
|
||||
topic_id="ca369340-a64e-442e-98f1-a4fa7dc74a38",
|
||||
detail={"workplans": [...], "tasks_created": M}
|
||||
)
|
||||
```
|
||||
|
||||
<!-- Delete or archive this file once past first session -->
|
||||
8
.claude/rules/repo-boundary.md
Normal file
8
.claude/rules/repo-boundary.md
Normal file
@@ -0,0 +1,8 @@
|
||||
## Repo boundary
|
||||
|
||||
This repo owns **railiance-fabric** only. It does not own:
|
||||
|
||||
<!-- TODO: List what belongs in adjacent repos, e.g.:
|
||||
- SSH key management → railiance-infra/
|
||||
- State hub code → state-hub/
|
||||
-->
|
||||
5
.claude/rules/repo-identity.md
Normal file
5
.claude/rules/repo-identity.md
Normal file
@@ -0,0 +1,5 @@
|
||||
**Purpose:** railiance-fabric - (fill in purpose)
|
||||
|
||||
**Domain:** financials
|
||||
**Repo slug:** railiance-fabric
|
||||
**Topic ID:** ca369340-a64e-442e-98f1-a4fa7dc74a38
|
||||
94
.claude/rules/session-protocol.md
Normal file
94
.claude/rules/session-protocol.md
Normal file
@@ -0,0 +1,94 @@
|
||||
## Session Protocol
|
||||
|
||||
Dev Hub (State Hub API): http://127.0.0.1:8000
|
||||
MCP server name in `~/.claude.json`: `dev-hub`
|
||||
|
||||
**Step 1 — Orient**
|
||||
|
||||
Read the offline-safe brief first — it works without a live hub connection:
|
||||
```bash
|
||||
cat .custodian-brief.md
|
||||
```
|
||||
Then call the MCP tool for richer cross-domain context when MCP tools are exposed:
|
||||
```
|
||||
get_domain_summary("financials")
|
||||
```
|
||||
If MCP tools are unavailable in the current agent session, use the REST API:
|
||||
```bash
|
||||
curl -s "http://127.0.0.1:8000/state/summary" | python3 -m json.tool
|
||||
```
|
||||
If the hub is offline: `cd ~/state-hub && make api`
|
||||
|
||||
**Step 2 — Check inbox**
|
||||
With MCP tools:
|
||||
```
|
||||
get_messages(to_agent="railiance-fabric", unread_only=True)
|
||||
```
|
||||
Mark read with `mark_message_read(message_id)`. Reply or act on coordination
|
||||
requests before proceeding.
|
||||
|
||||
Without MCP tools:
|
||||
```bash
|
||||
curl -s "http://127.0.0.1:8000/messages/?to_agent=railiance-fabric&unread_only=true" \
|
||||
| python3 -m json.tool
|
||||
curl -s -X PATCH "http://127.0.0.1:8000/messages/<id>/read" \
|
||||
-H "Content-Type: application/json" -d '{}'
|
||||
```
|
||||
|
||||
**Step 3 — Scan workplans**
|
||||
```bash
|
||||
ls workplans/
|
||||
```
|
||||
For each file with `status: ready`, `active`, or `blocked`, note pending
|
||||
`wait`/`todo`/`progress` tasks.
|
||||
|
||||
**Step 4 — Present brief**
|
||||
|
||||
1. **Active workplans** for `financials` — title, task counts, blocking decisions
|
||||
2. **Pending tasks** from `workplans/` + any `[repo:railiance-fabric]` hub tasks
|
||||
3. **Goal guidance** — if `goal_guidance` in summary:
|
||||
- `needs_workplan`: surface as top action — *"Repo goal '{title}' has no workplan yet"*
|
||||
- `alignment_warnings`: flag if active work is not aligned with current goal
|
||||
4. **Suggested next action** — highest-priority open item
|
||||
5. **SBOM status** — flag if `last_sbom_at` is unset for this repo
|
||||
|
||||
If no workplans: follow First Session Protocol (`first-session.md`).
|
||||
|
||||
**During work:** `record_decision()` · `add_progress_event()` · `resolve_decision()`
|
||||
|
||||
> State Hub is a *read model*. **Never register workplans or tasks by hand**
|
||||
> (`create_workplan`, `create_task`, or the legacy `create_workstream`) — write
|
||||
> the workplan file in `workplans/` and run `fix-consistency`; its C-06 check
|
||||
> registers the workplan and its tasks in the hub and writes the IDs back into
|
||||
> the file. Manual registration creates duplicates the moment fix-consistency
|
||||
> runs. Work structure belongs in repo files (ADR-001).
|
||||
>
|
||||
> Terminology: "workstream" is the legacy name for workplan. Some API/frontmatter
|
||||
> field names keep it for compatibility (`state_hub_workstream_id`,
|
||||
> `workstream_id` params) — treat them as workplan IDs.
|
||||
|
||||
**Session close:**
|
||||
With MCP tools:
|
||||
```
|
||||
add_progress_event(summary="...", topic_id="ca369340-a64e-442e-98f1-a4fa7dc74a38", workplan_id="<uuid>")
|
||||
```
|
||||
Without MCP tools:
|
||||
```bash
|
||||
curl -s -X POST http://127.0.0.1:8000/progress/ \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"topic_id":"ca369340-a64e-442e-98f1-a4fa7dc74a38","workplan_id":"<uuid>","event_type":"note","summary":"what changed","author":"codex"}'
|
||||
```
|
||||
If workplan files were modified, ensure the local copy is up to date first,
|
||||
then sync from the repo checkout:
|
||||
```bash
|
||||
git pull --ff-only
|
||||
statehub fix-consistency
|
||||
```
|
||||
For repos where implementation runs on a remote machine (e.g. CoulombCore),
|
||||
use the pull-before-fix mode from any shell with the State Hub CLI:
|
||||
```bash
|
||||
statehub fix-consistency --repo railiance-fabric --remote
|
||||
```
|
||||
**C-15** (DB task ahead of file) is normal in multi-machine workflows — writeback
|
||||
will sync the file to match DB. **C-16** (repo behind remote) blocks all writes
|
||||
until you pull — intentional to prevent clobbering remote progress.
|
||||
14
.claude/rules/stack-and-commands.md
Normal file
14
.claude/rules/stack-and-commands.md
Normal file
@@ -0,0 +1,14 @@
|
||||
## Stack
|
||||
|
||||
- **Language:** Python ≥3.12 (`railiance_fabric` package)
|
||||
- **Key deps:** jsonschema, PyYAML; SQLite registry at `.railiance-fabric/registry.sqlite3`
|
||||
|
||||
## Dev Commands
|
||||
|
||||
```bash
|
||||
python3 -m pytest tests/ # run the test suite
|
||||
make graph-explorer # registry-backed graph explorer (HOST/PORT/REGISTRY_DB overridable)
|
||||
python3 -m railiance_fabric.server --db .railiance-fabric/registry.sqlite3
|
||||
```
|
||||
|
||||
Local-only tooling — no production deploy surface in this repo.
|
||||
45
.claude/rules/workplan-convention.md
Normal file
45
.claude/rules/workplan-convention.md
Normal file
@@ -0,0 +1,45 @@
|
||||
## Workplan Convention (ADR-001)
|
||||
|
||||
File location: `workplans/RAILIANCE-WP-NNNN-<slug>.md`
|
||||
ID prefix: `RAILIANCE-WP-`
|
||||
|
||||
Work items originate as files in this repo **before** being registered in the hub.
|
||||
|
||||
Canonical workplan frontmatter statuses are:
|
||||
`proposed`, `ready`, `active`, `blocked`, `backlog`, `finished`, `archived`.
|
||||
Use `proposed` for a newly drafted plan, `ready` after review against current
|
||||
repo state, and `finished` when implementation is complete. `stalled` and
|
||||
`needs_review` are derived health labels, not stored statuses.
|
||||
|
||||
Closed workplans may be moved to `workplans/archived/` with a completion-date
|
||||
prefix: `YYMMDD-RAILIANCE-WP-NNNN-<slug>.md`. The frontmatter id remains
|
||||
unchanged; the prefix is only for quick visual reference.
|
||||
|
||||
Small opportunistic tasks discovered during another session use **Ad Hoc Tasks**:
|
||||
`workplans/ADHOC-YYYY-MM-DD.md`, workplan slug `adhoc-YYYY-MM-DD`, and task ids
|
||||
`ADHOC-YYYY-MM-DD-T01`, `T02`, etc. Use adhocs only for low-risk work completed
|
||||
directly. Promote anything requiring analysis, design, approval, dependencies, or
|
||||
multiple planned phases into a normal workplan.
|
||||
|
||||
Ecosystem todos from other agents arrive as `[repo:railiance-fabric]` hub tasks —
|
||||
visible at session start. Pick one up by creating the workplan file, committing,
|
||||
and running `statehub fix-consistency` — C-06 registers the workplan in the hub.
|
||||
Never register by hand with `create_workplan`/`create_workstream`.
|
||||
|
||||
Task blocks use this shape:
|
||||
|
||||
```task
|
||||
id: RAILIANCE-WP-NNNN-T01
|
||||
status: wait | todo | progress | done | cancel
|
||||
priority: high | medium | low
|
||||
state_hub_task_id: "<uuid>" # written by fix-consistency — do not edit
|
||||
```
|
||||
|
||||
Status progression is `todo` → `progress` → `done`; use `wait` for waiting or
|
||||
blocked work and `cancel` for stopped work.
|
||||
|
||||
Workplan frontmatter carries `state_hub_workstream_id` — a legacy field name
|
||||
kept for compatibility ("workstream" is the old term for workplan); it holds
|
||||
the hub workplan id and is written by fix-consistency. Do not edit or rename it.
|
||||
|
||||
<!-- Ralph Loop rules and HEUREKA sequence: ~/.claude/CLAUDE.md — do not duplicate here -->
|
||||
@@ -1,40 +1,18 @@
|
||||
# Railiance Fabric Brief
|
||||
<!-- custodian-brief: generated by fix-consistency — do not edit manually -->
|
||||
# Custodian Brief — railiance-fabric
|
||||
|
||||
Domain: railiance
|
||||
Repo slug: railiance-fabric
|
||||
State Hub topic ID: ca369340-a64e-442e-98f1-a4fa7dc74a38
|
||||
State Hub workstream ID: bd190990-8e68-49a3-9ce4-0ba89103ea54
|
||||
**Domain:** financials
|
||||
**Last synced:** 2026-07-01 22:24 UTC
|
||||
**State Hub:** http://127.0.0.1:8000 *(adjust if running on a remote machine)*
|
||||
|
||||
## Purpose
|
||||
## Active Workstreams
|
||||
|
||||
Railiance Fabric defines the repo-owned declaration model for the Railiance
|
||||
ecosystem graph: services, capabilities, interfaces, dependencies, bindings,
|
||||
validation, discovery queries, and State Hub export contracts.
|
||||
*(none — repo may need first-session setup)*
|
||||
|
||||
## Current Work
|
||||
---
|
||||
## MCP Orientation (when available)
|
||||
|
||||
- `RAIL-FAB-WP-0001` is active and establishes the first ecosystem graph model.
|
||||
- `T01` is done: `INTENT.md` defines the vocabulary and source-of-truth
|
||||
boundary.
|
||||
- `T02` is done: `docs/declaration-schema.md`, `schemas/`, and
|
||||
`examples/declarations/` define the first declaration schema baseline.
|
||||
- `T03` is done: `catalog/` and `docs/type-catalog.md` define the first
|
||||
capability/interface type catalog.
|
||||
- `T04` is done: `fabric/` contains seed declarations for the first Railiance
|
||||
ecosystem provider/consumer graph.
|
||||
- `T05` is done: `railiance-fabric validate` loads and validates schema,
|
||||
catalog, reference, provider, source-link, and cycle checks.
|
||||
- `T06` is done: discovery queries and JSON/Mermaid exports are available from
|
||||
the CLI.
|
||||
- `T07` is done: `docs/state-hub-integration.md` defines the graph export and
|
||||
proposed hub read-model ingestion path.
|
||||
- `T08` is done: `docs/adoption-guide.md` and `docs/first-rollout.md` define
|
||||
how other repos should adopt and promote the seed declarations.
|
||||
- All tasks in `RAIL-FAB-WP-0001` are done.
|
||||
|
||||
## State Hub
|
||||
|
||||
- Local API: `http://127.0.0.1:8000`
|
||||
- Remote tunnel: `http://127.0.0.1:18000`
|
||||
- After changing workplan files, sync from `~/the-custodian/state-hub` with:
|
||||
`make fix-consistency REPO=railiance-fabric`
|
||||
If the state-hub MCP server is reachable, call:
|
||||
`get_domain_summary("financials")`
|
||||
This provides richer cross-domain context.
|
||||
If the MCP call fails, use this file as your orientation source.
|
||||
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -52,6 +52,10 @@ coverage.xml
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Railiance Fabric local runtime state
|
||||
.railiance-fabric/
|
||||
.fabric-discovery/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
@@ -173,4 +177,3 @@ cython_debug/
|
||||
|
||||
# PyPI configuration file
|
||||
.pypirc
|
||||
|
||||
|
||||
17
.repo-classification.yaml
Normal file
17
.repo-classification.yaml
Normal file
@@ -0,0 +1,17 @@
|
||||
repo_classification:
|
||||
standard: Repo Classification Standard
|
||||
version: '1.0'
|
||||
classified_at: '2026-06-22'
|
||||
classified_by: agent
|
||||
category: project
|
||||
domain: financials
|
||||
secondary_domains: []
|
||||
capability_tags:
|
||||
- platform
|
||||
- operations
|
||||
business_stake:
|
||||
- technology
|
||||
- operations
|
||||
business_mechanics:
|
||||
- coordination
|
||||
- operation
|
||||
117
AGENTS.md
117
AGENTS.md
@@ -2,12 +2,12 @@
|
||||
|
||||
## Repo Identity
|
||||
|
||||
**Purpose:** Railiance Fabric defines the repo-owned declaration model, validation tooling, graph queries, and State Hub export contract for the Railiance ecosystem graph.
|
||||
**Purpose:** railiance-fabric - (fill in purpose)
|
||||
|
||||
**Domain:** railiance
|
||||
**Domain:** financials
|
||||
**Repo slug:** railiance-fabric
|
||||
**Topic ID:** `ca369340-a64e-442e-98f1-a4fa7dc74a38`
|
||||
**Workplan prefix:** `RAIL-FAB-WP-`
|
||||
**Workplan prefix:** `RAILIANCE-WP-`
|
||||
|
||||
---
|
||||
|
||||
@@ -20,6 +20,12 @@ there is no MCP server for Codex agents.
|
||||
|---------|-----|
|
||||
| Local workstation | `http://127.0.0.1:8000` |
|
||||
| Remote via tunnel | `http://127.0.0.1:18000` |
|
||||
| Optional local edge relay | http://127.0.0.1:18080 |
|
||||
|
||||
When an operator has enabled the edge relay, set API_BASE to the relay URL.
|
||||
Queueable writes return an explicit queued receipt if the central hub is
|
||||
unreachable. Treat that as pending local evidence, then ask the operator to run
|
||||
statehub outbox status/replay after connectivity returns.
|
||||
|
||||
### Orient at session start
|
||||
|
||||
@@ -27,8 +33,8 @@ there is no MCP server for Codex agents.
|
||||
# Offline brief — works without hub connection
|
||||
cat .custodian-brief.md
|
||||
|
||||
# Active workstreams for this domain
|
||||
curl -s "http://127.0.0.1:8000/workstreams/?topic_id=ca369340-a64e-442e-98f1-a4fa7dc74a38&status=active" \
|
||||
# Active workplans for this domain
|
||||
curl -s "http://127.0.0.1:8000/workplans/?topic_id=ca369340-a64e-442e-98f1-a4fa7dc74a38&status=active" \
|
||||
| python3 -m json.tool
|
||||
|
||||
# Check inbox
|
||||
@@ -51,20 +57,20 @@ curl -s -X POST http://127.0.0.1:8000/progress/ \
|
||||
"summary": "what was done",
|
||||
"event_type": "note",
|
||||
"author": "codex",
|
||||
"workstream_id": "<uuid>",
|
||||
"workplan_id": "<uuid>",
|
||||
"task_id": "<uuid>"
|
||||
}'
|
||||
```
|
||||
|
||||
Omit `workstream_id` / `task_id` when not applicable.
|
||||
Omit `workplan_id` / `task_id` when not applicable.
|
||||
|
||||
### Update task status
|
||||
|
||||
```bash
|
||||
curl -s -X PATCH "http://127.0.0.1:8000/tasks/<task_id>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"status": "in_progress"}'
|
||||
# values: todo | in_progress | done | blocked
|
||||
-d '{"status": "progress"}'
|
||||
# values: wait | todo | progress | done | cancel
|
||||
```
|
||||
|
||||
### Flag a task for human review
|
||||
@@ -80,10 +86,10 @@ curl -s -X PATCH "http://127.0.0.1:8000/tasks/<task_id>" \
|
||||
## Session Protocol
|
||||
|
||||
**Start:**
|
||||
1. `cat .custodian-brief.md` — domain goal and open workstreams (offline-safe)
|
||||
1. `cat .custodian-brief.md` — domain goal and open workplans (offline-safe)
|
||||
2. Check inbox: `GET /messages/?to_agent=railiance-fabric&unread_only=true`; mark read
|
||||
3. Scan workplans: `ls workplans/` — note `status: active` files and open tasks
|
||||
4. Check blocked tasks: `GET /tasks/?needs_human=true`
|
||||
3. Scan workplans: `ls workplans/` — note `status: ready`, `active`, or `blocked` files and open tasks
|
||||
4. Check human-needed tasks: `GET /tasks/?needs_human=true`
|
||||
|
||||
**During work:**
|
||||
- Update task statuses in workplan files as tasks progress
|
||||
@@ -92,12 +98,69 @@ curl -s -X PATCH "http://127.0.0.1:8000/tasks/<task_id>" \
|
||||
**Close:**
|
||||
1. Update workplan file task statuses to reflect progress
|
||||
2. Log: `POST /progress/` with a summary of what changed
|
||||
3. Note for the custodian operator: after workplan file changes, run from
|
||||
`~/the-custodian/state-hub`:
|
||||
3. After workplan file changes, run:
|
||||
```bash
|
||||
make fix-consistency REPO=railiance-fabric
|
||||
statehub fix-consistency
|
||||
```
|
||||
This syncs task status from files into the hub DB.
|
||||
Coding agents should run this directly; ask the operator only if the CLI or
|
||||
State Hub API is unavailable. This syncs task status from files into the hub DB.
|
||||
|
||||
---
|
||||
|
||||
## Credential and access routing
|
||||
|
||||
**Audience:** Codex, Claude Code, Grok, and custodian agents that call **llm-connect**
|
||||
for inference. Run this check **before** requesting secrets, API keys, SSH access,
|
||||
login tokens, or database passwords — in any repo, not only `ops-warden`.
|
||||
|
||||
ops-warden **issues SSH certificates only** (`warden sign`, `cert_command`). Every
|
||||
other credential need belongs to another subsystem. **Do not** message
|
||||
`ops-warden` on State Hub expecting a secret value; the reply is a pointer, not a key.
|
||||
|
||||
### Lookup (do this first)
|
||||
|
||||
```bash
|
||||
warden route find "<describe your need>" --json
|
||||
warden route show <catalog-id> --json
|
||||
```
|
||||
|
||||
Requires the `warden` CLI from `~/ops-warden` (`uv tool install .` or `uv run warden`).
|
||||
|
||||
| Agent runtime | How to orient |
|
||||
| --- | --- |
|
||||
| **Codex / Grok** (shell, HTTP State Hub) | `warden route` commands above; inbox `to_agent=railiance-fabric` is for coordination, not secret vending |
|
||||
| **Claude Code** (MCP when available) | `get_domain_summary("custodian")` for workplans; **still** use `warden route` for credential ownership |
|
||||
| **llm-connect** (inference service) | Never put secret retrieval in prompts; route custody to OpenBao/operator paths surfaced by `warden route` |
|
||||
|
||||
### Quick routing table
|
||||
|
||||
| I need… | Owner | ops-warden executes? |
|
||||
| --- | --- | --- |
|
||||
| SSH cert (`adm`/`agt`/`atm`) | ops-warden | **Yes** — `warden sign` |
|
||||
| API key, DB password, provider token | OpenBao (`railiance-platform`) | No — route only |
|
||||
| Login / OIDC / MFA | key-cape / Keycloak | No — route only |
|
||||
| Authorization decision | flex-auth | No — route only |
|
||||
| activity-core → issue-core emission | activity-core + issue-core | No — `warden route show activity-core-issue-sink` |
|
||||
| SSH tunnel | ops-bridge (+ `cert_command` from warden) | No — route only |
|
||||
|
||||
### Anti-patterns (do not do these)
|
||||
|
||||
- `POST /messages/` to `ops-warden` asking for `ISSUE_CORE_API_KEY`, `OPENROUTER_API_KEY`, etc.
|
||||
- Inventing `warden secret`, `warden login`, `warden bao`, `warden tunnel` — they do not exist
|
||||
- Pasting secrets into Git, State Hub, workplans, logs, or chat
|
||||
|
||||
### Other capabilities (reuse-surface)
|
||||
|
||||
Non-credential capabilities are usually discovered through **reuse-surface** federation
|
||||
(`reuse-surface` registry / `capability.*` indexes). Credential routing is inlined in
|
||||
every repo's agent instructions because it is high-frequency, high-risk, and easy to
|
||||
get wrong.
|
||||
|
||||
**Canon:** `~/ops-warden/wiki/CredentialRouting.md` · catalog `~/ops-warden/registry/routing/catalog.yaml`
|
||||
|
||||
<!-- REPO-AGENTS-EXTENSIONS -->
|
||||
<!-- Append repo-specific agent instructions below this marker.
|
||||
The state-hub template sync preserves content after this line. -->
|
||||
|
||||
---
|
||||
|
||||
@@ -106,10 +169,10 @@ curl -s -X PATCH "http://127.0.0.1:8000/tasks/<task_id>" \
|
||||
Work items originate as files in this repo — not in the hub. The hub is a
|
||||
read/cache/index layer that rebuilds from files.
|
||||
|
||||
**File location:** `workplans/RAIL-FAB-WP-NNNN-<slug>.md`
|
||||
**File location:** `workplans/RAILIANCE-WP-NNNN-<slug>.md`
|
||||
|
||||
**Archived location:** completed workplans may move to
|
||||
`workplans/archived/YYMMDD-RAIL-FAB-WP-NNNN-<slug>.md`. The `YYMMDD` prefix is
|
||||
**Archived location:** finished workplans may move to
|
||||
`workplans/archived/YYMMDD-RAILIANCE-WP-NNNN-<slug>.md`. The `YYMMDD` prefix is
|
||||
the completion/archive date; the frontmatter `id` does not change.
|
||||
|
||||
**Ad Hoc Tasks:** small opportunistic fixes discovered during a session use
|
||||
@@ -121,12 +184,12 @@ anything needing analysis, design, approval, dependencies, or multiple phases.
|
||||
|
||||
```yaml
|
||||
---
|
||||
id: RAIL-FAB-WP-NNNN
|
||||
id: RAILIANCE-WP-NNNN
|
||||
type: workplan
|
||||
title: "..."
|
||||
domain: railiance
|
||||
domain: financials
|
||||
repo: railiance-fabric
|
||||
status: active | done
|
||||
status: proposed | ready | active | blocked | backlog | finished | archived
|
||||
owner: codex
|
||||
topic_slug: ...
|
||||
created: "YYYY-MM-DD"
|
||||
@@ -135,14 +198,18 @@ state_hub_workstream_id: "<uuid>" # written by fix-consistency — do not edit
|
||||
---
|
||||
```
|
||||
|
||||
Use `proposed` for a new draft, `ready` after review against current repo
|
||||
state, and `finished` after implementation. `stalled` and `needs_review` are
|
||||
derived health labels, not frontmatter statuses.
|
||||
|
||||
**Task block format** (one per `##` section):
|
||||
|
||||
```
|
||||
## Task Title
|
||||
|
||||
` ` `task
|
||||
id: RAIL-FAB-WP-NNNN-T01
|
||||
status: todo | in_progress | done | blocked
|
||||
id: RAILIANCE-WP-NNNN-T01
|
||||
status: wait | todo | progress | done | cancel
|
||||
priority: high | medium | low
|
||||
state_hub_task_id: "<uuid>" # written by fix-consistency — do not edit
|
||||
` ` `
|
||||
@@ -150,7 +217,7 @@ state_hub_task_id: "<uuid>" # written by fix-consistency — do not edit
|
||||
Task description text.
|
||||
```
|
||||
|
||||
Status progression: `todo` → `in_progress` → `done` (or `blocked`)
|
||||
Status progression: `todo` → `progress` → `done`; use `wait` for waiting/blocked work and `cancel` for stopped work.
|
||||
|
||||
To create a new workplan:
|
||||
1. Write the file following the format above
|
||||
|
||||
12
CLAUDE.md
Normal file
12
CLAUDE.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# railiance-fabric — Claude Code Instructions
|
||||
|
||||
@SCOPE.md
|
||||
@.claude/rules/repo-identity.md
|
||||
@.claude/rules/session-protocol.md
|
||||
@.claude/rules/first-session.md
|
||||
@.claude/rules/workplan-convention.md
|
||||
@.claude/rules/stack-and-commands.md
|
||||
@.claude/rules/architecture.md
|
||||
@.claude/rules/repo-boundary.md
|
||||
@.claude/rules/credential-routing.md
|
||||
@.claude/rules/agents.md
|
||||
93
DECISIONS.md
Normal file
93
DECISIONS.md
Normal file
@@ -0,0 +1,93 @@
|
||||
# Decision Log
|
||||
|
||||
_Auto-generated by the Custodian State Hub._
|
||||
|
||||
## State Hub workstation Postgres migration approval
|
||||
|
||||
**Date:** 2026-06-03
|
||||
**Decided by:** codex
|
||||
|
||||
Superseded by WP-0004 T09 cancellation and CUST-WP-0038 ownership of State Hub HA migration, including hostname, registry, exposure model, HA database/storage, restore drills, and production data migration approval.
|
||||
|
||||
---
|
||||
|
||||
## activity-core deployment architecture
|
||||
|
||||
**Date:** 2026-06-03
|
||||
**Decided by:** codex
|
||||
|
||||
Superseded by completed WP-0004 outcome: activity-core was deployed as a K3s production service on railiance01 on 2026-05-22; the packaging architecture question is no longer blocking this workplan.
|
||||
|
||||
---
|
||||
|
||||
## Review CCR-2026-0001 whynot-design npm publish token lane
|
||||
|
||||
**Date:** 2026-06-27
|
||||
**Decided by:** human
|
||||
|
||||
APPROVE: scoped path and confirmed binding are acceptable
|
||||
|
||||
---
|
||||
|
||||
## Review CCR-2026-0001 corrected whynot-design npm publish token lane
|
||||
|
||||
**Date:** 2026-06-27
|
||||
**Decided by:** human
|
||||
|
||||
APPROVE: We fixed the path using coulomb as the org/tenant.
|
||||
|
||||
---
|
||||
|
||||
## Forgejo hostname and exposure model
|
||||
|
||||
**Date:** 2026-07-02
|
||||
**Decided by:** human
|
||||
|
||||
the hostname shall be forgejo.coulomb.social. The exposure model is private repos by default. We will use the transition from gitea to forgejo for closing down public access and establishing credential handling to have convenience when working with the repos. Gitea can and should remain reachable during transition.
|
||||
|
||||
---
|
||||
|
||||
## Forgejo SMTP and sender identity
|
||||
|
||||
**Date:** 2026-07-02
|
||||
**Decided by:** human
|
||||
|
||||
We will use forgejo@coulomb.social
|
||||
|
||||
---
|
||||
|
||||
## Forgejo package registry scope
|
||||
|
||||
**Date:** 2026-07-02
|
||||
**Decided by:** human
|
||||
|
||||
We should support the full range from the start.
|
||||
|
||||
---
|
||||
|
||||
## Forgejo Actions runner isolation model
|
||||
|
||||
**Date:** 2026-07-02
|
||||
**Decided by:** human
|
||||
|
||||
we will try to go with isolated host runners, with least-privilege credential boundaries.
|
||||
|
||||
---
|
||||
|
||||
## Forgejo backup target and restore cadence
|
||||
|
||||
**Date:** 2026-07-02
|
||||
**Decided by:** human
|
||||
|
||||
We will need to figure out the details, but i want to use backup.coulomb.social as the hostname with a backend we need to figure out yet.
|
||||
|
||||
---
|
||||
|
||||
## Forgejo cutover and rollback strategy
|
||||
|
||||
**Date:** 2026-07-02
|
||||
**Decided by:** human
|
||||
|
||||
We will do a staged migration and lock the gitea repos of transitioned repos but keep gitea until everything has been transfered and just then start a 14day trial phase and after that retire gitea to the backup.
|
||||
|
||||
---
|
||||
21
Makefile
Normal file
21
Makefile
Normal file
@@ -0,0 +1,21 @@
|
||||
PYTHON ?= python3
|
||||
REGISTRY_DB ?= .railiance-fabric/registry.sqlite3
|
||||
HOST ?= 127.0.0.1
|
||||
PORT ?= 8765
|
||||
|
||||
.DEFAULT_GOAL := help
|
||||
|
||||
.PHONY: help graph-explorer registry
|
||||
|
||||
help:
|
||||
@printf "Available targets:\n"
|
||||
@printf " make graph-explorer Start the registry-backed graph explorer on HOST:PORT.\n"
|
||||
@printf " Defaults: HOST=$(HOST), PORT=$(PORT), REGISTRY_DB=$(REGISTRY_DB)\n"
|
||||
@printf " make registry Alias for graph-explorer.\n"
|
||||
|
||||
graph-explorer:
|
||||
@mkdir -p $(dir $(REGISTRY_DB))
|
||||
@echo "Starting Railiance Fabric graph explorer at http://$(HOST):$(PORT)/ui/graph-explorer"
|
||||
$(PYTHON) -m railiance_fabric.server --db "$(REGISTRY_DB)" --host "$(HOST)" --port "$(PORT)"
|
||||
|
||||
registry: graph-explorer
|
||||
91
README.md
91
README.md
@@ -1,11 +1,20 @@
|
||||
# Railiance Fabric
|
||||
|
||||
Railiance Fabric defines the repo-owned declaration model for the Railiance
|
||||
ecosystem graph.
|
||||
Railiance Fabric models the durable infrastructure-responsibility graph of the
|
||||
Railiance netkingdom.
|
||||
|
||||
It will hold schemas, seed declarations, validation tools, graph queries, and
|
||||
State Hub export contracts for services, capabilities, interfaces,
|
||||
dependencies, and bindings across Railiance repositories.
|
||||
Fabric is bounded by financial and operational accountability: who pays for the
|
||||
infrastructure, who is accountable for keeping it alive, and which durable
|
||||
interfaces create value across fabric and subfabric boundaries.
|
||||
|
||||
It holds schemas, discovery tools, registry services, graph queries, and State
|
||||
Hub export contracts for services, machines, repositories, deployables,
|
||||
endpoints, ownership, dependencies, and bindings across Railiance deployment
|
||||
realities.
|
||||
|
||||
See `docs/FabricDiscoveryAndUpdate.md` for the current architecture direction
|
||||
for fabric boundaries, king/lord/tenant ownership, discovery, rebuilds, and
|
||||
update loops.
|
||||
|
||||
## Validate Declarations
|
||||
|
||||
@@ -35,22 +44,59 @@ railiance-fabric unresolved
|
||||
railiance-fabric blast-radius openbao-kv-v2-mount
|
||||
railiance-fabric export --format json
|
||||
railiance-fabric export --format mermaid
|
||||
railiance-fabric export --format graph-explorer
|
||||
railiance-fabric export --format financial
|
||||
```
|
||||
|
||||
See `docs/discovery-queries.md` for command details.
|
||||
|
||||
## Financial Fabric Baseline
|
||||
|
||||
The current financial Fabric model starts from
|
||||
`fabric/financial/railiance-netkingdom.yaml`. It defines the Railiance
|
||||
netkingdom, the king, the current lord, the one active Railiance fabric, and
|
||||
the default ownership rules used while Railiance still has one effective payer.
|
||||
|
||||
`railiance-fabric export --format financial` projects the current accepted
|
||||
legacy graph into the `railiance.fabric/v1alpha2` / `financial-fabric-v1`
|
||||
contract. Repo-local `fabric/` declarations remain useful evidence and
|
||||
bootstrap data; they are not the long-term authority for external deployment,
|
||||
ownership, tenant, or utility relations.
|
||||
|
||||
See `docs/financial-fabric-operator-guide.md` for the reset/rebuild refresh
|
||||
loop and State Hub handoff.
|
||||
|
||||
## Adopt In Another Repo
|
||||
|
||||
See `docs/adoption-guide.md` for the declaration workflow and
|
||||
`docs/first-rollout.md` for the initial Railiance repo rollout.
|
||||
See `docs/adoption-guide.md` for the legacy declaration workflow and
|
||||
`docs/first-rollout.md` for the initial Railiance repo rollout. Treat
|
||||
repo-local declarations as self-description and discovery evidence. Financial
|
||||
fabric membership, ownership, and cross-boundary utility relations are owned by
|
||||
the accountability-root discovery model described in
|
||||
`docs/FabricDiscoveryAndUpdate.md`.
|
||||
|
||||
## Next: Ecosystem Registry Service
|
||||
|
||||
See `docs/ecosystem-registry-service.md` for the standards comparison and
|
||||
service direction for registering repos and interacting with the combined
|
||||
ecosystem model.
|
||||
ecosystem model. See `docs/registry-api.md` for the current registry HTTP API.
|
||||
|
||||
Start the first registry service slice with:
|
||||
List available Make targets from the repo root:
|
||||
|
||||
```bash
|
||||
make
|
||||
```
|
||||
|
||||
Start the first registry service slice and graph explorer explicitly:
|
||||
|
||||
```bash
|
||||
make graph-explorer
|
||||
```
|
||||
|
||||
The target serves `http://127.0.0.1:8765/ui/graph-explorer` by default. Override
|
||||
`PORT`, `HOST`, or `REGISTRY_DB` if the local port or database path differs.
|
||||
|
||||
Equivalent raw command:
|
||||
|
||||
```bash
|
||||
railiance-fabric-registry --db .railiance-fabric/registry.sqlite3 --port 8765
|
||||
@@ -67,6 +113,20 @@ Feed the running service from this checkout:
|
||||
railiance-fabric registry sync --repo-slug railiance-fabric .
|
||||
```
|
||||
|
||||
Or register and sync the known local Railiance ecosystem repos from the
|
||||
onboarding manifest:
|
||||
|
||||
```bash
|
||||
railiance-fabric registry sync-manifest registry/railiance-repos.yaml
|
||||
```
|
||||
|
||||
To onboard every active State Hub repo with an available local checkout on this
|
||||
host:
|
||||
|
||||
```bash
|
||||
railiance-fabric registry sync-manifest registry/local-repos.yaml
|
||||
```
|
||||
|
||||
Ingest a CycloneDX SBOM as queryable library inventory:
|
||||
|
||||
```bash
|
||||
@@ -80,4 +140,17 @@ GET /repositories/{repo_slug}/inventory
|
||||
GET /repositories/{repo_slug}/snapshots
|
||||
GET /repositories/{repo_slug}/snapshots/diff
|
||||
GET /search?q=jsonschema
|
||||
GET /ui/graph-explorer
|
||||
GET /exports/graph-explorer/manifest
|
||||
GET /exports/graph-explorer
|
||||
```
|
||||
|
||||
See `docs/registry-onboarding.md` for the multi-repo manifest and operating
|
||||
loop.
|
||||
|
||||
The graph explorer export is the first executable slice of the interactive
|
||||
Fabric map. See `docs/graph-explorer-transfer-review.md` for the repo-scoping
|
||||
transfer review, `docs/graph-explorer-contract.md` for the shared manifest and
|
||||
payload contract, `docs/semantic-attractors.md` for the attractor-based layout
|
||||
orientation concept, and `docs/graph-explorer-operations.md` for launch,
|
||||
refresh, verification, and extraction guidance.
|
||||
|
||||
@@ -87,6 +87,80 @@ spec:
|
||||
- sts-token
|
||||
tags: [storage, credentials, security]
|
||||
|
||||
- id: kubernetes-runtime
|
||||
name: Kubernetes runtime
|
||||
lifecycle: active
|
||||
description: Provides the Kubernetes API, namespaces, workloads, Services, Ingresses, and runtime primitives consumed by Railiance services.
|
||||
default_criticality: critical
|
||||
default_data_classification: restricted
|
||||
expected_interface_types:
|
||||
- kubernetes-api
|
||||
- kubernetes-crd
|
||||
tags: [kubernetes, cluster, runtime]
|
||||
|
||||
- id: ci-cd-template-catalog
|
||||
name: CI/CD template catalog
|
||||
lifecycle: planned
|
||||
description: Provides reusable workflow templates, release gates, and delivery conventions for Railiance workloads.
|
||||
default_criticality: medium
|
||||
default_data_classification: internal
|
||||
expected_interface_types:
|
||||
- workflow-template-contract
|
||||
- cli
|
||||
tags: [ci, cd, gitops, enablement]
|
||||
|
||||
- id: source-hosting
|
||||
name: Source hosting
|
||||
lifecycle: active
|
||||
description: Hosts Git repositories, repository metadata, review surfaces, and source-forge web/API access.
|
||||
default_criticality: high
|
||||
default_data_classification: confidential
|
||||
expected_interface_types:
|
||||
- web-ui
|
||||
- http-api
|
||||
- git-ssh
|
||||
tags: [forge, git, source]
|
||||
|
||||
- id: container-registry
|
||||
name: Container registry
|
||||
lifecycle: active
|
||||
description: Publishes and serves OCI container images for Railiance workloads.
|
||||
default_criticality: high
|
||||
default_data_classification: confidential
|
||||
expected_interface_types:
|
||||
- oci-registry
|
||||
tags: [forge, registry, container-image]
|
||||
|
||||
- id: python-package-registry
|
||||
name: Python package registry
|
||||
lifecycle: active
|
||||
description: Publishes and serves Python package artifacts for Railiance source and app builds.
|
||||
default_criticality: high
|
||||
default_data_classification: confidential
|
||||
expected_interface_types:
|
||||
- python-package-index
|
||||
tags: [forge, registry, python, package]
|
||||
|
||||
- id: workflow-runner-substrate
|
||||
name: Workflow runner substrate
|
||||
lifecycle: planned
|
||||
description: Provides forge-backed runner infrastructure, labels, placement, and credential boundaries for workflows.
|
||||
default_criticality: high
|
||||
default_data_classification: restricted
|
||||
expected_interface_types:
|
||||
- workflow-runner-label-contract
|
||||
tags: [forge, runner, actions, automation]
|
||||
|
||||
- id: artifact-promotion-evidence
|
||||
name: Artifact promotion evidence
|
||||
lifecycle: active
|
||||
description: Provides release artifact identity, provenance, publish, restore, and readiness evidence for consumers.
|
||||
default_criticality: high
|
||||
default_data_classification: internal
|
||||
expected_interface_types:
|
||||
- evidence-contract
|
||||
tags: [forge, evidence, provenance, release]
|
||||
|
||||
- id: audit-event-sink
|
||||
name: Audit/event sink
|
||||
lifecycle: planned
|
||||
@@ -117,5 +191,17 @@ spec:
|
||||
default_data_classification: internal
|
||||
expected_interface_types:
|
||||
- http-api
|
||||
- mcp-api
|
||||
- event-stream
|
||||
tags: [coordination, state-hub, planning]
|
||||
|
||||
- id: ecosystem-registry
|
||||
name: Ecosystem registry
|
||||
lifecycle: active
|
||||
description: Registers repositories and exposes graph, inventory, and visualization projections over the ecosystem model.
|
||||
default_criticality: high
|
||||
default_data_classification: internal
|
||||
expected_interface_types:
|
||||
- http-api
|
||||
- web-ui
|
||||
tags: [registry, discovery, graph, visualization]
|
||||
|
||||
@@ -17,6 +17,22 @@ spec:
|
||||
typical_auth_methods: [none, oidc, jwt, mtls, api_key]
|
||||
versioning: path, header, media-type, or documented semantic version.
|
||||
|
||||
- id: web-ui
|
||||
name: Web UI
|
||||
lifecycle: active
|
||||
description: Browser-based user interface for humans and agents operating through a visual surface.
|
||||
category: ui
|
||||
typical_auth_methods: [none, oidc, jwt, mtls, api_key]
|
||||
versioning: URL path, static asset version, and documented user-facing workflow compatibility.
|
||||
|
||||
- id: mcp-api
|
||||
name: MCP API
|
||||
lifecycle: active
|
||||
description: Model Context Protocol interface consumed by agents or agent runtimes.
|
||||
category: api
|
||||
typical_auth_methods: [none, oidc, jwt, mtls, api_key]
|
||||
versioning: MCP protocol version, tool schema version, and documented capability compatibility.
|
||||
|
||||
- id: oidc-discovery
|
||||
name: OIDC discovery
|
||||
lifecycle: active
|
||||
@@ -41,6 +57,14 @@ spec:
|
||||
typical_auth_methods: [kubernetes_service_account]
|
||||
versioning: group, version, and kind.
|
||||
|
||||
- id: kubernetes-api
|
||||
name: Kubernetes API
|
||||
lifecycle: active
|
||||
description: Kubernetes API server surface consumed by operators, controllers, and automation.
|
||||
category: kubernetes
|
||||
typical_auth_methods: [kubernetes_service_account, oidc, static_secret]
|
||||
versioning: Kubernetes version, API groups, RBAC contract, and kubeconfig delivery path.
|
||||
|
||||
- id: helm-release
|
||||
name: Helm release
|
||||
lifecycle: active
|
||||
@@ -65,6 +89,54 @@ spec:
|
||||
typical_auth_methods: [database_role, static_secret, openbao_token]
|
||||
versioning: engine version, connection contract, and migration compatibility.
|
||||
|
||||
- id: git-ssh
|
||||
name: Git SSH
|
||||
lifecycle: active
|
||||
description: Git-over-SSH repository access endpoint.
|
||||
category: source-control
|
||||
typical_auth_methods: [static_secret, unknown]
|
||||
versioning: hostname, port, SSH host key, authorized key scope, and Git server compatibility.
|
||||
|
||||
- id: oci-registry
|
||||
name: OCI registry
|
||||
lifecycle: active
|
||||
description: OCI distribution-compatible container image registry endpoint.
|
||||
category: registry
|
||||
typical_auth_methods: [api_key, static_secret, none]
|
||||
versioning: registry host, API behavior, package visibility, and tag/digest semantics.
|
||||
|
||||
- id: python-package-index
|
||||
name: Python package index
|
||||
lifecycle: active
|
||||
description: Python package index endpoint compatible with pip/uv simple API consumption.
|
||||
category: registry
|
||||
typical_auth_methods: [api_key, static_secret, none]
|
||||
versioning: package index URL, package visibility, token scope, and package version semantics.
|
||||
|
||||
- id: workflow-runner-label-contract
|
||||
name: Workflow runner label contract
|
||||
lifecycle: planned
|
||||
description: Published runner label, placement, and trust contract consumed by CI/CD workflows.
|
||||
category: automation
|
||||
typical_auth_methods: [none, kubernetes_service_account, static_secret]
|
||||
versioning: semantic label names, trust level, credential purpose, and runner replacement rules.
|
||||
|
||||
- id: workflow-template-contract
|
||||
name: Workflow template contract
|
||||
lifecycle: planned
|
||||
description: Reusable CI/CD workflow template or template catalog contract.
|
||||
category: automation
|
||||
typical_auth_methods: [none]
|
||||
versioning: template id, input schema, runner labels, and release gate semantics.
|
||||
|
||||
- id: evidence-contract
|
||||
name: Evidence contract
|
||||
lifecycle: active
|
||||
description: Documented evidence bundle or machine-readable evidence contract for release, restore, or readiness decisions.
|
||||
category: evidence
|
||||
typical_auth_methods: [none, api_key]
|
||||
versioning: evidence schema version, required fields, source links, and retention policy.
|
||||
|
||||
- id: object-storage-bucket
|
||||
name: Object-storage bucket
|
||||
lifecycle: planned
|
||||
|
||||
367
docs/FabricDiscoveryAndUpdate.md
Normal file
367
docs/FabricDiscoveryAndUpdate.md
Normal file
@@ -0,0 +1,367 @@
|
||||
# Fabric Discovery And Update
|
||||
|
||||
## Intent
|
||||
|
||||
`railiance-fabric` models the durable infrastructure-responsibility graph of the
|
||||
Railiance netkingdom.
|
||||
|
||||
A fabric is not a repository, environment, cluster, deployment scenario, or
|
||||
security zone. A fabric is the financial and operational responsibility boundary
|
||||
around infrastructure: who pays for it, who is accountable for it, and who has
|
||||
the authority to keep it alive.
|
||||
|
||||
The graph exists to answer:
|
||||
|
||||
- what infrastructure, services, repositories, deployables, endpoints, and
|
||||
machines exist;
|
||||
- who owns or pays for each node;
|
||||
- which fabrics and subfabrics contain those nodes;
|
||||
- which durable interfaces cross ownership boundaries;
|
||||
- which cross-boundary interfaces provide utility that may carry business value.
|
||||
|
||||
Fabric intentionally stays out of live operational telemetry. It may represent
|
||||
that a service, host, endpoint, or deployment exists because durable automation
|
||||
or configuration proves it. It should not represent whether that thing is
|
||||
currently healthy, loaded, failing, or profitable in the accounting sense.
|
||||
|
||||
## Financial Boundary Terms
|
||||
|
||||
Fabric uses financial responsibility terms for fabric boundaries.
|
||||
|
||||
### King
|
||||
|
||||
The king is responsible for the whole netkingdom.
|
||||
|
||||
The king has the key to the netkingdom. Literally, this means the master key or
|
||||
at least a relevant key component for secrets, backups, and recovery paths across
|
||||
the infrastructure under the netkingdom.
|
||||
|
||||
The king also holds the legal and contractual relationship with all lords and
|
||||
tenants. Even when responsibility is delegated, the king remains the actor that
|
||||
can ultimately restore, recover, govern, or terminate the netkingdom.
|
||||
|
||||
### Lord
|
||||
|
||||
A lord pays for a fabric.
|
||||
|
||||
A lord is accountable for a durable infrastructure-responsibility boundary. In
|
||||
the current Railiance setup there is one effective fabric because one actor pays
|
||||
for all infrastructure. Additional fabrics appear when the responsibility to pay
|
||||
for a coherent infrastructure boundary changes.
|
||||
|
||||
### Tenant
|
||||
|
||||
A tenant pays for restricted use of a subfabric.
|
||||
|
||||
A tenant is not the root payer for the whole fabric. A tenant receives bounded
|
||||
access to utility inside a subfabric and may consume services or interfaces
|
||||
provided by a lord, by the king, or by another tenant-facing utility.
|
||||
|
||||
## Fabrics, Subfabrics, And Views
|
||||
|
||||
### Fabric
|
||||
|
||||
A fabric is a durable responsibility boundary. Membership changes when financial
|
||||
or operational responsibility changes, not when a service is redeployed, a repo
|
||||
is refactored, a host is replaced, or an environment name changes.
|
||||
|
||||
Criteria for establishing a fabric:
|
||||
|
||||
- there is a lord who pays for the infrastructure in that boundary;
|
||||
- the boundary can be discovered from durable infrastructure, deployment, or
|
||||
contractual evidence;
|
||||
- the boundary remains stable across ordinary deployment and development churn;
|
||||
- ownership changes imply a meaningful change to who is accountable for cost,
|
||||
continuity, recovery, and utility delivery.
|
||||
|
||||
### Subfabric
|
||||
|
||||
A subfabric is a delegated responsibility or tenancy partition within a fabric.
|
||||
|
||||
Subfabrics are useful when a tenant receives restricted access to infrastructure
|
||||
or utility while the parent fabric remains under a lord or king. A subfabric may
|
||||
eventually become a separate fabric if payment, control, recovery, and legal
|
||||
responsibility move to another lord.
|
||||
|
||||
### View
|
||||
|
||||
A view is a diagnostic or informational slice through the graph.
|
||||
|
||||
Views can filter by repository, service, environment, machine, endpoint, tenant,
|
||||
workstream, deployment stack, or business capability. Views do not define fabric
|
||||
membership and should not mutate fabric boundaries.
|
||||
|
||||
Zone views are a special kind of view. They group the subgraph by deployment
|
||||
environment, deployment scenario, routing authority, or access zone. They are
|
||||
useful for questions such as:
|
||||
|
||||
- which services are currently visible in private dev, shared test, or
|
||||
production;
|
||||
- which control surfaces appear in user-facing zones;
|
||||
- which production surfaces still have unrestricted developer access;
|
||||
- which routes exist in production but not in test;
|
||||
- which early-access interfaces lack an explicit policy authority.
|
||||
|
||||
### Environment
|
||||
|
||||
An environment such as local, dev, staging, production, or lab is a deployment
|
||||
classification inside a fabric. It is not a fabric by itself.
|
||||
|
||||
Railiance uses these baseline environment terms:
|
||||
|
||||
| Environment | Meaning |
|
||||
|-------------|---------|
|
||||
| `dev` | Private developer-local execution. Useful for debugging and discovery, but not shared truth for other developers unless explicitly published. |
|
||||
| `test` | Shared central test stage for collaborators and friendly early-access users. |
|
||||
| `prod` | Production execution. Alpha-stage developer access may exist now, but production must be able to move toward restricted operator access and applicable security and data-privacy controls. |
|
||||
|
||||
### Deployment Scenario
|
||||
|
||||
A deployment scenario is a realized or planned arrangement of services,
|
||||
machines, endpoints, automation, and configuration. It belongs inside a fabric
|
||||
or subfabric but does not define the financial boundary.
|
||||
|
||||
Current Railiance scenario names:
|
||||
|
||||
| Scenario | Environment | Meaning |
|
||||
|----------|-------------|---------|
|
||||
| `bernd-laptop` | `dev` | Private local workstation scenario. It may discover useful loopback services and ports, but it is not a shared developer environment. |
|
||||
| `coulombcore` | `test` | Central shared test-stage server for developers and friendly early-access users. |
|
||||
| `railiance01` | `prod` | Production host. It is still alpha-accessible to developers, but the intended direction is restricted production access. |
|
||||
|
||||
### Routing Authority
|
||||
|
||||
A routing authority is the deployment component that maps an external name,
|
||||
local URL, ingress host, or port to a backend service. Fabric discovers routing
|
||||
authority output; it does not allocate ports or author routes.
|
||||
|
||||
Examples:
|
||||
|
||||
- local loopback process launch configuration for developer tools;
|
||||
- Makefile or script defaults for local-only bootstrap surfaces;
|
||||
- Docker Compose published ports;
|
||||
- Kubernetes `Service`, `Ingress`, or controller-specific route manifests;
|
||||
- Traefik, nginx, Caddy, HAProxy, or other reverse-proxy configuration;
|
||||
- DNS records and TLS/certificate automation when they prove reachable names.
|
||||
|
||||
### Access Zone
|
||||
|
||||
An access zone is a visualization and discovery overlay that describes who a
|
||||
surface is intended to be reachable by in a deployment scenario. It is not a
|
||||
fabric boundary and does not define the policy itself.
|
||||
|
||||
Useful initial access zones:
|
||||
|
||||
| Access zone | Intended reach |
|
||||
|-------------|----------------|
|
||||
| `private-dev` | One developer's local machine. |
|
||||
| `collaborator-test` | Collaborating developers in the shared test stage. |
|
||||
| `early-access` | Friendly users participating in early access. |
|
||||
| `production-public` | Production user-facing surfaces. |
|
||||
| `production-admin` | Production administrative or control surfaces. |
|
||||
|
||||
### Policy Authority
|
||||
|
||||
A policy authority is the system expected to enforce access rules for a surface.
|
||||
Fabric may record which authority is in play, such as NetKingdom IAM, an ingress
|
||||
policy, network policy, or local-only loopback binding, but Fabric does not
|
||||
define or enforce those rules.
|
||||
|
||||
These terms let the graph say: "this service belongs to the Railiance primary
|
||||
fabric, runs in the `coulombcore` test scenario, is routed by Traefik, and is
|
||||
intended for the `early-access` zone." That is a deployment and access overlay,
|
||||
not a change to fabric membership.
|
||||
|
||||
## Ownership Rule
|
||||
|
||||
Every node in the Fabric graph must carry owner information.
|
||||
|
||||
Ownership may be explicit on the node or inherited from the containing fabric or
|
||||
subfabric, but it must be resolvable. Nodes without resolvable ownership are
|
||||
incomplete because Fabric cannot explain who is accountable for their cost,
|
||||
continuity, recovery, or utility.
|
||||
|
||||
Ownership should identify the relevant king, lord, tenant, or delegated operator
|
||||
where applicable. Operators and maintainers may be represented as supporting
|
||||
actors, but they do not replace the financial boundary terms unless they also
|
||||
pay for or legally own the responsibility boundary.
|
||||
|
||||
## Cross-Boundary Edges
|
||||
|
||||
Edges may cross fabric and subfabric boundaries.
|
||||
|
||||
These edges are especially important. They are where one owned boundary consumes
|
||||
utility from another owned boundary. They are also where business value can
|
||||
appear: paid access, cost recovery, shared platform utility, tenant-facing
|
||||
interfaces, or contractual service delivery.
|
||||
|
||||
Fabric should treat cross-boundary interfaces as first-class graph facts. A
|
||||
cross-boundary utility edge should be able to identify:
|
||||
|
||||
- provider owner;
|
||||
- consumer owner;
|
||||
- provider fabric or subfabric;
|
||||
- consumer fabric or subfabric;
|
||||
- exposed endpoint, contract, service, or utility;
|
||||
- durable evidence for the relationship;
|
||||
- expected payment or business model when known;
|
||||
- metering basis when known.
|
||||
|
||||
The existence of a cross-boundary interface belongs in Fabric. Live usage,
|
||||
current health, latency, revenue events, and incident state belong to telemetry,
|
||||
accounting, or operational systems outside the Fabric core.
|
||||
|
||||
## Cost And Profit Center Attribution
|
||||
|
||||
Cost centers and profit centers are accounting attributions. They are not fabric
|
||||
boundaries by themselves.
|
||||
|
||||
A cost center may be evidence that a responsibility boundary exists, especially
|
||||
when it corresponds to a lord who pays for infrastructure. However, the fabric
|
||||
boundary is still established by financial and operational accountability, not
|
||||
by the accounting label alone.
|
||||
|
||||
Cost and profit center attribution may overlap with fabrics and subfabrics:
|
||||
|
||||
- one fabric may contain many cost centers;
|
||||
- one tenant may span several cost centers;
|
||||
- one cost center may include nodes from multiple subfabrics;
|
||||
- one shared service may allocate cost across several tenants or cost centers;
|
||||
- one cross-boundary utility may be cost-bearing for one actor and
|
||||
profit-bearing for another.
|
||||
|
||||
Fabric should therefore support optional accounting attribution on nodes and
|
||||
edges without allowing that attribution to redefine containment:
|
||||
|
||||
- node cost center;
|
||||
- node profit center;
|
||||
- edge cost allocation model;
|
||||
- edge profit attribution;
|
||||
- payment schema;
|
||||
- metering or allocation basis when known;
|
||||
- attribution validity period when known.
|
||||
|
||||
This lets Fabric build cost-center and profit-center views while preserving the
|
||||
durability of fabric membership. A node moving from one cost center to another
|
||||
does not necessarily move fabrics. A node moves fabrics only when financial or
|
||||
operational responsibility for the infrastructure boundary changes.
|
||||
|
||||
Useful accounting views include:
|
||||
|
||||
- all infrastructure attributed to a cost center;
|
||||
- all cross-boundary utility edges attributed to a profit center;
|
||||
- tenant-facing utilities without a payment schema;
|
||||
- shared services with unresolved allocation;
|
||||
- owned nodes without cost-center attribution;
|
||||
- expensive or critical infrastructure with no visible value interface.
|
||||
|
||||
## Discovery Approach
|
||||
|
||||
Fabric discovery should start from accountability roots, not from arbitrary repo
|
||||
ownership declarations.
|
||||
|
||||
Useful roots include:
|
||||
|
||||
- the king and current netkingdom inventory;
|
||||
- lords and their fabrics;
|
||||
- tenants and their subfabrics;
|
||||
- State Hub attached repositories and known host paths;
|
||||
- Gitea organizations and repository URLs;
|
||||
- deployment automation repositories;
|
||||
- Docker, Compose, Kubernetes, systemd, reverse proxy, and infrastructure
|
||||
manifests;
|
||||
- backup, recovery, and secret-management evidence;
|
||||
- service endpoint and API specifications;
|
||||
- CI/CD and release automation that proves deployables and deployment targets.
|
||||
|
||||
The scanner follows these roots outward to discover durable evidence of nodes
|
||||
and edges. Repository-local facts can still help identify deployables, APIs, and
|
||||
artifacts, but repository-owned declarations should not be the default source of
|
||||
truth for external fabric relations.
|
||||
|
||||
## Rebuild From Scratch
|
||||
|
||||
A full rebuild should be deterministic enough to repeat and provenance-rich
|
||||
enough to review.
|
||||
|
||||
Recommended phases:
|
||||
|
||||
1. Establish the netkingdom root and current king.
|
||||
2. Register known lords, fabrics, tenants, and subfabrics.
|
||||
3. Register durable discovery roots for each fabric and subfabric.
|
||||
4. Crawl deployment automation, infrastructure manifests, repo inventories,
|
||||
service configs, and endpoint contracts.
|
||||
5. Store raw evidence with source paths, URLs, timestamps, scanner versions, and
|
||||
content hashes.
|
||||
6. Normalize identities across host paths, repository URLs, image names, service
|
||||
names, endpoint names, and deployment names.
|
||||
7. Build candidate graph nodes and edges.
|
||||
8. Resolve or flag ownership for every node.
|
||||
9. Promote accepted candidates into a versioned fabric snapshot.
|
||||
10. Export the accepted snapshot to State Hub as a read model.
|
||||
|
||||
## Keeping The Model Up To Date
|
||||
|
||||
Fabric freshness should be based on durable configuration and automation changes,
|
||||
with scheduled rescans as a safety net.
|
||||
|
||||
Rescan triggers include:
|
||||
|
||||
- deployment automation changes;
|
||||
- infrastructure manifest changes;
|
||||
- State Hub attached repository inventory changes;
|
||||
- repository changes that affect deployables, APIs, images, service names,
|
||||
endpoint contracts, ports, or deployment configuration;
|
||||
- tenant or lord changes;
|
||||
- backup, recovery, or secret-root changes;
|
||||
- manual operator requests;
|
||||
- scheduled periodic rebuilds.
|
||||
|
||||
Normal source-code edits do not necessarily change the Fabric graph. Fabric
|
||||
should focus on changes that alter durable topology, ownership, deployment,
|
||||
interfaces, or cross-boundary utility.
|
||||
|
||||
Each update should compare new discovery output with the previous accepted
|
||||
snapshot and produce a delta. The delta should distinguish:
|
||||
|
||||
- added, changed, and removed nodes;
|
||||
- added, changed, and removed edges;
|
||||
- changed ownership;
|
||||
- changed fabric or subfabric membership;
|
||||
- new or removed cross-boundary utility interfaces;
|
||||
- ambiguous identity merges that need review;
|
||||
- discovered nodes without resolvable ownership.
|
||||
|
||||
## Boundary With Security Terms
|
||||
|
||||
Fabric should avoid using security-zone language for its core concepts.
|
||||
|
||||
Terms such as realm, domain, tenant realm, identity realm, and security domain
|
||||
are useful in systems such as Microsoft environments or Keycloak, but they carry
|
||||
security and identity-management semantics. Fabric may later relate to those
|
||||
systems as discovered evidence, but the core Fabric concept is financial and
|
||||
operational responsibility, not identity or access-control topology.
|
||||
|
||||
For now, use:
|
||||
|
||||
- king, lord, and tenant for financial responsibility actors;
|
||||
- fabric and subfabric for durable responsibility boundaries;
|
||||
- view for diagnostic graph slices;
|
||||
- environment for deployment classification;
|
||||
- deployment scenario for a concrete place where services run;
|
||||
- routing authority for the component that maps names or ports to services;
|
||||
- access zone for the visualization overlay that groups intended reachability;
|
||||
- policy authority for the external system expected to enforce access rules.
|
||||
|
||||
Access zones may be security-relevant, but they are not Fabric security policy.
|
||||
They are discovered and visualized evidence that helps operators spot misplaced
|
||||
surfaces, missing policy authorities, or accidental exposure.
|
||||
|
||||
## State Hub Role
|
||||
|
||||
State Hub coordinates work and stores a readable projection of the Fabric graph.
|
||||
It should not be the primary author of Fabric topology.
|
||||
|
||||
`railiance-fabric` discovers, normalizes, versions, and exports Fabric snapshots.
|
||||
State Hub imports those snapshots so agents and operators can ask practical
|
||||
questions about work, ownership, dependencies, and cross-boundary utility.
|
||||
337
docs/ZoneEntityVisualization.md
Normal file
337
docs/ZoneEntityVisualization.md
Normal file
@@ -0,0 +1,337 @@
|
||||
# Zone Entity Visualization
|
||||
|
||||
## Intent
|
||||
|
||||
The graph explorer currently treats zones as visual overlays derived from node
|
||||
metadata. That is useful for first orientation, but it keeps zones as a
|
||||
decoration around an already-laid-out graph. The next step is to make a zone a
|
||||
first-class visualization entity beside nodes and edges.
|
||||
|
||||
A zone is a bounded drawing surface for a subgraph. It is similar to a sheet of
|
||||
paper or a layer in a graphics application: it decides which graph elements are
|
||||
drawn inside it, how those elements are laid out, how it stacks with other
|
||||
zones, and whether it can be collapsed into a representative node.
|
||||
|
||||
Zones are view entities. They help the operator inspect the fabric without
|
||||
changing the underlying fabric graph. A zone can be based on deployment
|
||||
environment, ownership, tenant boundaries, cost center, access zone, or any
|
||||
other declared view rule, but those concepts remain distinct from the zone
|
||||
mechanism itself.
|
||||
|
||||
## Core Model
|
||||
|
||||
A graph view contains three visible entity classes:
|
||||
|
||||
- nodes: fabric entities such as services, hosts, repos, scenarios, or owners
|
||||
- edges: fabric relationships such as deployment, routing, ownership, policy,
|
||||
dependency, or evidence links
|
||||
- zones: visual drawing surfaces that contain a selected subgraph
|
||||
|
||||
A zone definition describes how to derive and render one zone. A zone instance
|
||||
is the result of applying a definition to the current graph, filter state, and
|
||||
view profile.
|
||||
|
||||
Zone definitions should be serializable so they can later live in saved graph
|
||||
profiles, operator presets, or a dedicated view registry.
|
||||
|
||||
## Zone Definition
|
||||
|
||||
A zone definition should contain at least these fields:
|
||||
|
||||
```yaml
|
||||
id: prod
|
||||
label: Production
|
||||
enabled: true
|
||||
membership:
|
||||
mode: include
|
||||
rules:
|
||||
- field: deploymentEnvironment
|
||||
op: equals
|
||||
value: prod
|
||||
attraction:
|
||||
rules:
|
||||
- edge_type: fabric:serves
|
||||
direction: both
|
||||
depth: 1
|
||||
node_filter:
|
||||
field: kind
|
||||
op: in
|
||||
value: [service, endpoint]
|
||||
layout:
|
||||
algorithm: cose
|
||||
options: {}
|
||||
presentation:
|
||||
height: 30
|
||||
color: "#0f766e"
|
||||
opacity: 0.16
|
||||
blur_below: true
|
||||
collapse:
|
||||
enabled: true
|
||||
label: Production Zone
|
||||
```
|
||||
|
||||
The exact schema can evolve, but the responsibilities should stay separate:
|
||||
|
||||
- membership chooses seed nodes
|
||||
- attraction optionally expands the zone from those seeds through selected edge
|
||||
types and depths
|
||||
- layout chooses how the zone subgraph is arranged
|
||||
- presentation chooses how the zone itself is drawn and stacked
|
||||
- collapse chooses how the zone can become a representative node
|
||||
|
||||
## Membership Rules
|
||||
|
||||
Membership rules decide which nodes initially belong to a zone. They should be
|
||||
declarative and inspect node data rather than hard-code UI concepts.
|
||||
|
||||
Useful operators:
|
||||
|
||||
- `equals`
|
||||
- `not_equals`
|
||||
- `in`
|
||||
- `not_in`
|
||||
- `exists`
|
||||
- `missing`
|
||||
- `matches`
|
||||
|
||||
Useful rule composition:
|
||||
|
||||
- `all`: every nested rule must match
|
||||
- `any`: at least one nested rule must match
|
||||
- `none`: no nested rule may match
|
||||
|
||||
The first implementation can support a small subset such as `equals`, `in`,
|
||||
`exists`, `all`, and `any`, then widen the rule language once saved zone
|
||||
profiles need it.
|
||||
|
||||
## Attraction Rules
|
||||
|
||||
Attraction rules allow a zone to pull in additional nodes connected to the seed
|
||||
set. This is useful when the operator wants a zone to include the services,
|
||||
routes, machines, or contracts that make the zone understandable, even when
|
||||
those nodes do not carry the seed attribute themselves.
|
||||
|
||||
An attraction rule should define:
|
||||
|
||||
- edge type or edge-type pattern
|
||||
- direction: `out`, `in`, or `both`
|
||||
- maximum depth
|
||||
- optional node filter
|
||||
- optional edge filter
|
||||
|
||||
Attraction must be deterministic. Given the same graph and zone definitions, the
|
||||
same node should land in the same zone every time.
|
||||
|
||||
Attraction also needs a conflict policy because a node must not belong to more
|
||||
than one zone. The recommended first policy is priority by zone height and then
|
||||
definition order:
|
||||
|
||||
1. Seed membership wins over attracted membership.
|
||||
2. If two zones seed the same node, the conflict is reported and the node is
|
||||
assigned to the higher zone.
|
||||
3. If two zones attract the same node, the node is assigned to the higher zone.
|
||||
4. If height ties, the earlier definition wins.
|
||||
5. Every conflict is recorded as a view diagnostic.
|
||||
|
||||
This keeps the single-zone invariant while making ambiguous rules visible.
|
||||
|
||||
## Single-Zone Invariant
|
||||
|
||||
A visible node must be assigned to zero or one zone in a given graph view. A node
|
||||
that belongs to no zone remains on the base canvas.
|
||||
|
||||
The invariant is important because zones are meant to behave like drawing
|
||||
surfaces, not like arbitrary tags. Allowing the same node to appear in multiple
|
||||
zones would make edge routing, selection, collapse behavior, and interaction
|
||||
state ambiguous.
|
||||
|
||||
The model can still support analytical overlap by reporting diagnostics and by
|
||||
offering alternative view presets. It should not solve overlap by duplicating
|
||||
nodes in the same rendered view.
|
||||
|
||||
## Zone Layout
|
||||
|
||||
Each zone may choose its own layout algorithm for its subgraph. For example:
|
||||
|
||||
- deployment zones may use force-directed layout
|
||||
- ownership zones may use concentric layout
|
||||
- stage zones may use grid layout
|
||||
- collapsed or nearly empty zones may use compact deterministic placement
|
||||
|
||||
The outer graph layout and the zone subgraph layouts are separate concerns. A
|
||||
first implementation can keep the current Cytoscape layout for all nodes and
|
||||
only render zone surfaces around assigned nodes. A later implementation should
|
||||
introduce a two-phase layout:
|
||||
|
||||
1. Place zones and unzoned nodes on the main canvas.
|
||||
2. Place each zone's assigned subgraph inside that zone using the zone's layout.
|
||||
|
||||
This will likely require an internal view model that separates fabric graph data
|
||||
from rendered graph coordinates.
|
||||
|
||||
### Per-Zone Layout Preparation
|
||||
|
||||
The current graph explorer should not immediately run independent Cytoscape
|
||||
layouts inside each zone rectangle. Cytoscape layouts operate on collections in
|
||||
one coordinate space, while the current zone overlay is a view layer drawn over
|
||||
the already-laid-out graph. Running nested layouts directly against visible
|
||||
nodes would make pan/zoom, filters, collapse state, and edge routing fragile.
|
||||
|
||||
The safer path is a two-phase view layout:
|
||||
|
||||
1. Resolve zones from the current graph and view filters.
|
||||
2. Place zone containers and unzoned nodes in the global canvas.
|
||||
3. For each zone, compute local coordinates for its assigned nodes using the
|
||||
zone's configured layout algorithm.
|
||||
4. Project local zone coordinates into global graph coordinates.
|
||||
5. Route internal edges inside the zone and boundary edges through the zone
|
||||
perimeter or collapsed zone node.
|
||||
|
||||
The implementation needs these pieces before per-zone layouts become safe:
|
||||
|
||||
- a resolved zone view model that survives filtering and saved profiles;
|
||||
- a stable assignment invariant so a visible node belongs to no more than one
|
||||
zone;
|
||||
- a zone container model with size, position, padding, and height;
|
||||
- a local coordinate projection layer from zone space to Cytoscape space;
|
||||
- explicit boundary-edge routing rules;
|
||||
- collapse state that can replace a zone subgraph with a representative node;
|
||||
- diagnostics when a configured zone layout cannot be applied.
|
||||
|
||||
The present implementation already establishes the first, second, and sixth
|
||||
pieces. A follow-up should introduce a zone container placement phase before
|
||||
attempting per-zone node layout. That follow-up can keep Cytoscape as the final
|
||||
renderer while moving layout decisions into a Fabric-owned view model.
|
||||
|
||||
### Stable Zone Containers
|
||||
|
||||
The first container implementation keeps zone surfaces as view state keyed by
|
||||
stable zone id. When a zone first appears, the global graph layout supplies its
|
||||
initial center. Once created, the container owns the zone surface position while
|
||||
the global layout continues to arrange the base canvas and unzoned nodes.
|
||||
|
||||
Dragging a zone moves the container and its currently assigned visible member
|
||||
nodes together. Rerunning layout or switching the layout algorithm should keep
|
||||
the container in its stored graph coordinates and then project the zone's
|
||||
visible subgraph back into that container.
|
||||
|
||||
Container state belongs in saved or copied graph view state, not in the Fabric
|
||||
payload. It is an operator workspace preference, similar to manual visibility
|
||||
overrides.
|
||||
|
||||
Zone-local layout is also view state. The first selectable algorithms are a
|
||||
compact grid and a circle layout. Switching between them should rearrange the
|
||||
assigned nodes inside each stable container without moving the container itself
|
||||
or changing the underlying Fabric relationships.
|
||||
|
||||
### Context Edges
|
||||
|
||||
Display-only context edges are not zone connectivity. Repository `declares`
|
||||
edges, for example, show which repository declared a node, but they should not
|
||||
create boundary diagnostics, attraction paths, or collapsed-zone boundary
|
||||
edges. A host can still show them as explanatory evidence in details, but a
|
||||
zone boundary should only react to canonical or host-promoted graph
|
||||
relationships.
|
||||
|
||||
## Layer Height And Overlap
|
||||
|
||||
Zone presentation includes a height. Height is a visual stacking concept, not a
|
||||
security or ownership concept.
|
||||
|
||||
When zones overlap:
|
||||
|
||||
- higher zones should draw above lower zones
|
||||
- lower zones may be desaturated when covered
|
||||
- lower zones may be blurred or dimmed when covered
|
||||
- labels should remain readable where practical
|
||||
- pointer interaction should prefer the highest visible zone
|
||||
|
||||
The implementation should avoid implying that a higher zone is more important.
|
||||
Height is about rendering order and view ergonomics only.
|
||||
|
||||
## Collapse To Zone Node
|
||||
|
||||
A zone can optionally collapse into a representative node. Collapsing is a view
|
||||
operation that preserves graph connectivity:
|
||||
|
||||
- nodes inside the zone become hidden from the current view
|
||||
- the zone node represents the collapsed zone
|
||||
- edges between inside and outside nodes are reconnected to the zone node
|
||||
- edges fully inside the zone are hidden or summarized
|
||||
- expanding restores the original nodes and edges
|
||||
|
||||
The collapsed zone node should expose useful summary data:
|
||||
|
||||
- contained node count
|
||||
- contained edge count
|
||||
- dominant node kinds
|
||||
- inbound and outbound boundary edge counts
|
||||
- diagnostics such as membership conflicts
|
||||
|
||||
This enables drill-down exploration without destroying the operator's context.
|
||||
|
||||
## Hierarchical Zones
|
||||
|
||||
The collapse model naturally leads to hierarchical zones. A tenant subfabric may
|
||||
sit inside a landlord fabric, an access zone may sit inside a deployment
|
||||
environment, and a cost-center view may cut across both as an alternate profile.
|
||||
|
||||
Hierarchy should be introduced carefully:
|
||||
|
||||
- parent-child containment must be explicit in the zone definition or derived
|
||||
from a deterministic rule
|
||||
- a node still belongs to exactly one visible leaf zone
|
||||
- collapsing a parent collapses all visible descendants
|
||||
- cross-boundary edges must remain visible at the collapsed boundary
|
||||
|
||||
The first implementation should support flat zones. The data model should avoid
|
||||
choices that would make hierarchy impossible later.
|
||||
|
||||
## Diagnostics
|
||||
|
||||
Zones should produce diagnostics because rule-based view construction can hide
|
||||
important ambiguity.
|
||||
|
||||
Useful diagnostics:
|
||||
|
||||
- node matched by more than one membership rule
|
||||
- node attracted by more than one zone
|
||||
- edge crosses zone boundaries
|
||||
- zone has no seed nodes
|
||||
- attraction depth reached limit
|
||||
- collapsed zone has hidden internal boundary evidence
|
||||
|
||||
Diagnostics belong to the visualization layer. They should not mutate the
|
||||
fabric graph.
|
||||
|
||||
## Relationship To Fabric Concepts
|
||||
|
||||
Zones are not fabrics, subfabrics, realms, domains, environments, cost centers,
|
||||
or tenants. A zone is a view mechanism that can visualize those concepts.
|
||||
|
||||
Examples:
|
||||
|
||||
- a deployment-environment zone groups nodes by `dev-tegwick`, `test`, or `prod`
|
||||
- a financial fabric zone groups nodes by lord or tenant responsibility
|
||||
- a cost-center zone groups nodes for accounting analysis
|
||||
- an access-zone view groups nodes by operational access policy once that
|
||||
metadata exists
|
||||
|
||||
This keeps the graph explorer flexible while preserving the stricter meaning of
|
||||
fabric boundaries: who pays for, owns, and is responsible for infrastructure.
|
||||
|
||||
## Implementation Direction
|
||||
|
||||
The recommended path is incremental:
|
||||
|
||||
1. Introduce a pure zone resolver that converts graph data and zone definitions
|
||||
into zone instances, node assignments, edge summaries, and diagnostics.
|
||||
2. Replace the current hard-coded environment/access overlay derivation with
|
||||
resolver-backed default zone definitions.
|
||||
3. Add zone-aware rendering state to the graph explorer UI.
|
||||
4. Add saved zone profiles once the model is stable.
|
||||
5. Add collapse-to-zone-node behavior.
|
||||
6. Add per-zone layout only after the resolver and rendering model are stable.
|
||||
|
||||
This order keeps the current useful overlay behavior while moving the engine
|
||||
toward zones as first-class view entities.
|
||||
172
docs/accountability-root-manifest.md
Normal file
172
docs/accountability-root-manifest.md
Normal file
@@ -0,0 +1,172 @@
|
||||
# Accountability Root Manifest
|
||||
|
||||
The accountability root manifest is the handoff between the financial Fabric
|
||||
model and the discovery/update loop.
|
||||
|
||||
It answers where discovery starts. A manifest names the netkingdom, actors,
|
||||
fabric boundaries, and durable roots that can prove repositories, deployment
|
||||
realities, service configuration, endpoint contracts, backup/recovery evidence,
|
||||
and secret-root metadata. It does not collect live telemetry and it does not
|
||||
make State Hub the authoring surface for topology.
|
||||
|
||||
Schema:
|
||||
|
||||
```text
|
||||
schemas/accountability-root-manifest.schema.yaml
|
||||
```
|
||||
|
||||
Current Railiance manifest:
|
||||
|
||||
```text
|
||||
fabric/discovery/railiance-accountability-roots.yaml
|
||||
```
|
||||
|
||||
Tenant/subfabric example:
|
||||
|
||||
```text
|
||||
examples/discovery/accountability-root-manifest.yaml
|
||||
```
|
||||
|
||||
Raw evidence run schema:
|
||||
|
||||
```text
|
||||
schemas/accountability-root-evidence.schema.yaml
|
||||
```
|
||||
|
||||
Identity projection schema:
|
||||
|
||||
```text
|
||||
schemas/accountability-identity-projection.schema.yaml
|
||||
```
|
||||
|
||||
Ownership review schema:
|
||||
|
||||
```text
|
||||
schemas/accountability-ownership-review.schema.yaml
|
||||
```
|
||||
|
||||
Update delta schema:
|
||||
|
||||
```text
|
||||
schemas/accountability-update-delta.schema.yaml
|
||||
```
|
||||
|
||||
## Required Sections
|
||||
|
||||
- `netkingdom`: root id, name, and king actor.
|
||||
- `actors`: king, lord, tenant, operator, or steward actors.
|
||||
- `fabrics`: fabric and subfabric boundaries.
|
||||
- `discovery_roots`: durable roots such as State Hub repo inventory, Gitea
|
||||
organizations, registry manifests, host paths, repo checkouts, deployment
|
||||
automation, endpoint contracts, backup/recovery evidence, and secret-root
|
||||
metadata.
|
||||
- `refresh`: cadence and trigger hints for the future update loop.
|
||||
|
||||
## Boundary Rules
|
||||
|
||||
The current Railiance manifest has one active fabric:
|
||||
`fabric.railiance.primary`. Future tenant subfabrics are added under that
|
||||
fabric by adding a tenant actor, a `Subfabric`, and subfabric-scoped discovery
|
||||
roots. This does not change the root fabric criterion: the fabric boundary
|
||||
still rests on financial and operational accountability.
|
||||
|
||||
`owner_actor_id` on a discovery root describes the default owner to attach to
|
||||
identity candidates discovered through that root. For ordinary repositories,
|
||||
deployment files, and host-path evidence this should be the lord who pays for
|
||||
the fabric. King authority remains modeled on the netkingdom and on roots that
|
||||
represent recovery, secret, backup, or termination authority.
|
||||
|
||||
Discovery roots should state `safe_discovery` explicitly. Secret and backup
|
||||
roots should use `metadata_only` or `explicit_review`; adapters must never read
|
||||
secret values or operational telemetry while building Fabric graph evidence.
|
||||
|
||||
## Collecting Root Evidence
|
||||
|
||||
The first adapter slice emits raw evidence without promoting it into accepted
|
||||
graph snapshots:
|
||||
|
||||
```bash
|
||||
railiance-fabric discover-roots \
|
||||
--manifest fabric/discovery/railiance-accountability-roots.yaml \
|
||||
--max-items-per-root 200
|
||||
```
|
||||
|
||||
The command covers manifest-backed repository inventory, repository checkout
|
||||
identity, host-path evidence, deployment automation and infrastructure files,
|
||||
State Hub/Gitea metadata roots, endpoint/service-config roots, and safe
|
||||
metadata-only backup or secret roots. Remote HTTP reads are disabled by default;
|
||||
pass `--include-remote` only when the operator intentionally wants configured
|
||||
remote roots such as State Hub inventory endpoints to be fetched.
|
||||
|
||||
The output is an `AccountabilityRootEvidenceRun`. Every evidence item carries
|
||||
provenance, source, fingerprint, `durable: true`, and
|
||||
`live_telemetry: false`, preserving the boundary between Fabric evidence and
|
||||
operational telemetry.
|
||||
|
||||
To normalize raw evidence into reviewable identity candidates:
|
||||
|
||||
```bash
|
||||
railiance-fabric discover-roots \
|
||||
--identity-projection \
|
||||
--max-items-per-root 200
|
||||
```
|
||||
|
||||
To persist raw evidence and identity candidates in a local SQLite store:
|
||||
|
||||
```bash
|
||||
railiance-fabric discover-roots \
|
||||
--store-db .railiance-fabric/accountability-evidence.sqlite3 \
|
||||
--identity-projection
|
||||
```
|
||||
|
||||
The store is intentionally separate from accepted registry graph snapshots. It
|
||||
keeps raw evidence runs, evidence items, and identity candidates available for
|
||||
inspection before any candidate is promoted.
|
||||
|
||||
## Ownership Review
|
||||
|
||||
To resolve ownership and containment from the normalized identities:
|
||||
|
||||
```bash
|
||||
railiance-fabric discover-roots \
|
||||
--ownership-review \
|
||||
--store-db .railiance-fabric/accountability-evidence.sqlite3
|
||||
```
|
||||
|
||||
The ownership review inherits owners from fabric/subfabric containment when
|
||||
possible, applies explicit owner evidence from discovery roots, and marks
|
||||
unresolved or ambiguous candidates as `needs_review`. Accepted candidates must
|
||||
have a resolved owner and containment unless they are actors or the netkingdom
|
||||
root.
|
||||
|
||||
To persist a reviewer decision for a stable identity candidate:
|
||||
|
||||
```bash
|
||||
railiance-fabric review-identity identity:repository:example-repo \
|
||||
--store-db .railiance-fabric/accountability-evidence.sqlite3 \
|
||||
--decision accept \
|
||||
--owner-actor-id actor.railiance.primary-lord \
|
||||
--fabric-id fabric.railiance.primary \
|
||||
--reviewer operator \
|
||||
--note "accepted from reviewed checkout evidence"
|
||||
```
|
||||
|
||||
Reviewer decisions are keyed by stable identity key. Later rescans apply the
|
||||
latest decision for that key, so ordinary evidence refreshes do not lose
|
||||
reviewed ownership choices.
|
||||
|
||||
## Update Deltas
|
||||
|
||||
To compare the current run with previous identity and ownership-review outputs:
|
||||
|
||||
```bash
|
||||
railiance-fabric discover-roots \
|
||||
--delta \
|
||||
--previous-identity-projection previous-identities.json \
|
||||
--previous-ownership-review previous-ownership.json
|
||||
```
|
||||
|
||||
The delta separates candidate graph node changes, candidate graph edge changes,
|
||||
ownership changes, containment changes, review-state changes, and blocker
|
||||
changes. When `summary.promotion_needed` is `false`, the update loop can skip
|
||||
promotion because the durable evidence produced no meaningful Fabric change.
|
||||
140
docs/canon-alignment-review.md
Normal file
140
docs/canon-alignment-review.md
Normal file
@@ -0,0 +1,140 @@
|
||||
# Canon Alignment Review For RAIL-FAB-WP-0016
|
||||
|
||||
Date: 2026-05-23
|
||||
|
||||
## Review Packet
|
||||
|
||||
This review follows the InfoTechCanon consumer alignment workflow for
|
||||
`railiance-fabric`.
|
||||
|
||||
Reviewed Fabric sources:
|
||||
|
||||
- `INTENT.md`, `SCOPE.md`, and `README.md`
|
||||
- `railiance_fabric/graph.py`, `scanner.py`, `registry.py`, and `graph_explorer.py`
|
||||
- `schemas/discovery-snapshot.schema.yaml` and `schemas/state-hub-export.schema.yaml`
|
||||
- workplans `RAIL-FAB-WP-0010` through `RAIL-FAB-WP-0016`
|
||||
|
||||
Reviewed canon sources:
|
||||
|
||||
- `infospace/agent/review-kit/review-kit.yaml`
|
||||
- `infospace/agent/review-kit/review-workflow.yaml`
|
||||
- `infospace/evaluations/railiance-fabric/conformance-pack.yaml`
|
||||
- `infospace/evaluations/railiance-fabric/entity-edge-capture-criteria.yaml`
|
||||
- `infospace/evaluations/railiance-fabric/mapping-expectations.yaml`
|
||||
- `infospace/evaluations/railiance-fabric/visualization-examples.yaml`
|
||||
|
||||
The workplan's `review-kit/alignment` reference is the canon artifact id; the
|
||||
physical files are under `infospace/agent/review-kit/`.
|
||||
|
||||
## Repository Context
|
||||
|
||||
Producer intent: Railiance Fabric owns repo-authored graph declarations,
|
||||
scanner output, registry projection, validation, query tooling, and State Hub
|
||||
export contracts for the Railiance ecosystem graph.
|
||||
|
||||
Current scope: source-controlled declarations model services, capabilities,
|
||||
interfaces, dependencies, and binding assertions. Deterministic scanning adds
|
||||
candidate repositories, libraries, manifests, runtime endpoints, domains,
|
||||
ports, and source evidence. The graph explorer adds visual projection edges and
|
||||
inferred runtime views for usability.
|
||||
|
||||
Consumer purposes:
|
||||
|
||||
- make cross-repo dependencies reviewable,
|
||||
- make provider/consumer and blast-radius queries reliable,
|
||||
- provide State Hub with a read model rather than an authoring surface,
|
||||
- support reingest after a canon-aligned model reset,
|
||||
- prevent visualization metadata from becoming graph truth.
|
||||
|
||||
## Selected Canon Surfaces
|
||||
|
||||
| Surface | Why selected |
|
||||
| --- | --- |
|
||||
| `model/landscape` | Services, software systems, runtime resources, environments, ownership, and dependency claims. |
|
||||
| `model/devsecops` | Source repositories, packages, lockfiles, pipelines, artifacts, deployments, and attestations. |
|
||||
| `model/network` | Endpoints, ports, DNS, routes, reachability, and future flow nodes. |
|
||||
| `model/data` | Datastore and reads/writes relationships are expected gaps in current Fabric capture. |
|
||||
| `model/observability` | Evidence, telemetry signals, scanner provenance, and validation support. |
|
||||
| `model/governance` | Policies, reviews, decisions, exceptions, and reset guardrails. |
|
||||
| `model/security` | Controls and findings that should not be flattened into generic dependency edges. |
|
||||
| `model/task` | Review and remediation work created from graph gaps. |
|
||||
| `model/purpose-demand-extension` | Consumer purpose, scope pressure, and canon evolution feedback. |
|
||||
| `standard/tagging` | Non-relationship classification without using display edges as semantics. |
|
||||
|
||||
## Target Node Taxonomy
|
||||
|
||||
| Canon category | Current Fabric source | Fit | Target action |
|
||||
| --- | --- | --- | --- |
|
||||
| source-repository | `Repository` candidates and registered repos | direct | Keep as source evidence for repo-local declarations and scans. |
|
||||
| service | `ServiceDeclaration` | direct | Keep as logical/deployable service boundary. |
|
||||
| software-system | `CapabilityDeclaration`, `Library`, `ExternalLibrary` | partial | Keep as transitional mapping; later split capability semantics from system/component boundaries. |
|
||||
| endpoint | `InterfaceDeclaration`, `ApplicationEndpoint`, `NetworkPort`, `DomainName` | partial/direct | Prefer explicit endpoint nodes for network reachability; preserve interface contract attributes. |
|
||||
| deployment | `DeploymentService`, `ScoreWorkload`, `ContainerBuild` | partial/direct | Add deployment nodes for actual release/deploy evidence before destructive reset. |
|
||||
| runtime-resource | `RuntimeService`, `Server`, `Kubernetes*` candidates | partial/direct | Capture workload, service DNS, namespace, VM/server, and cluster objects as runtime reality. |
|
||||
| datastore | none first-class | gap | Add explicit datastore extraction from declarations, manifests, and config before reingest acceptance. |
|
||||
| flow | route/resolve/port edges only | gap | Add first-class Flow nodes when observed traffic or declared communication needs protocol/evidence context. |
|
||||
| policy | none first-class | gap | Add policy nodes for governing declarations, reset gates, and validation controls. |
|
||||
| control | none first-class | gap | Add control nodes only when preventive/detective/corrective controls have evidence. |
|
||||
| evidence | `BindingAssertion`, `Lockfile`, `ServiceConfig`, contracts, source anchors | partial | Make evidence explicit instead of hiding it only in attributes. |
|
||||
| task | workplans and review gaps | gap | Capture review/remediation tasks after State Hub readiness work is agreed. |
|
||||
| consumer-purpose | interface card and purpose-fit review | gap | Keep in docs now; model as graph nodes only if State Hub needs purpose-driven filtering. |
|
||||
| telemetry-signal | none first-class | gap | Add metrics/logs/alerts/dashboards as observed signals when connectors exist. |
|
||||
|
||||
## Target Edge Taxonomy
|
||||
|
||||
| Current Fabric edge | Canon relationship | Fit | Notes |
|
||||
| --- | --- | --- | --- |
|
||||
| `exposes`, `exposes_port`, `listens_on` | `exposes` | direct/partial | Good first canonical family for service/endpoint reachability. |
|
||||
| `consumes`, `depends_on_library`, `binds:*`, `uses_interface` | `depends_on` | partial | Preserve helper nodes until a reingest can project direct service relationships safely. |
|
||||
| `provides` | `implements` | partial | Service-to-capability is a Fabric helper relation; needs stronger canon treatment or collapse. |
|
||||
| `available_via`, `names_endpoint` | `exposes` | partial | Useful transitional mappings from capability/interface/domain to endpoint. |
|
||||
| `defines_deployment`, `builds_container`, `declares_package` | `built_from` | partial | Direction and artifact semantics need cleanup before being canonical claims. |
|
||||
| `defines_runtime_object`, `defines_workload`, `runs_on`, `deployed_as` | `deploys` | partial | Current scanner/UI edges mix source definitions and deployment reality. |
|
||||
| `routes_to_port`, `routes_to_service`, `resolves_to` | `flows_to` | partial | These are reachability hints, not logical dependencies. |
|
||||
| `uses_lockfile`, `uses_config`, `documents_interface`, `cataloged_as` | `evidenced_by` | partial | Evidence should become first-class where it supports a specific claim. |
|
||||
| `declares`, `owns_deployment`, canon display examples | display-only | direct | These are view/cluster edges and must not be conformance claims. |
|
||||
|
||||
## Mapping Findings
|
||||
|
||||
Direct mappings are strong for repositories, services, runtime resources,
|
||||
application endpoints, network ports, and explicit `exposes` relationships.
|
||||
|
||||
Partial mappings are expected for capability, interface, dependency, binding,
|
||||
package, manifest, and route concepts. They should keep legacy names during the
|
||||
transition but carry `canon_category`, `canonical_type`, `mapping_fit`, and
|
||||
`evidence_state` metadata.
|
||||
|
||||
Conflicts: network flow must not be treated as logical dependency, and
|
||||
graph-explorer layout edges must not be treated as canonical ownership,
|
||||
dependency, reachability, policy, or evidence.
|
||||
|
||||
Gaps: datastores, flows, policy, control, telemetry signals, tasks, and
|
||||
consumer-purpose nodes are not first-class scanner outputs yet. These should be
|
||||
implemented as explicit gaps or candidate mappings, not forced into nearby
|
||||
legacy Fabric semantics.
|
||||
|
||||
## Execution Direction
|
||||
|
||||
The first implementation slice adds canon metadata beside existing node and
|
||||
edge names. That keeps registry and graph explorer behavior stable while making
|
||||
the renewed model inspectable and testable.
|
||||
|
||||
The destructive reset phase remains blocked until the following exist:
|
||||
|
||||
- export and archive command for current registry graph data,
|
||||
- reset command that requires an explicit operator flag,
|
||||
- rollback note that explains restore limits,
|
||||
- validation that the new scanner/projection can reingest registered repos,
|
||||
- before/after counts and sample graph review.
|
||||
|
||||
No destructive reset was executed during this T01/T02 start.
|
||||
|
||||
## Canon Feedback
|
||||
|
||||
- Capability and dependency helper nodes are useful Fabric authoring concepts
|
||||
but do not map cleanly to canonical graph entity categories.
|
||||
- Edge direction needs explicit treatment for source repo to package/deployment
|
||||
evidence, because canon `built_from` points from deployment/artifact context
|
||||
back to source.
|
||||
- Evidence state should remain independent from review state: accepted inferred
|
||||
claims and candidate declared claims are different situations.
|
||||
100
docs/canon-interface-card.yaml
Normal file
100
docs/canon-interface-card.yaml
Normal file
@@ -0,0 +1,100 @@
|
||||
schema: info-tech-canon.interface-card.v1
|
||||
id: railiance-fabric/interface-card
|
||||
title: Railiance Fabric Canon Interface Card
|
||||
consumer:
|
||||
repo: railiance-fabric
|
||||
domain: railiance
|
||||
owner: codex
|
||||
intent: Make the Railiance ecosystem understandable, discoverable, and evolvable through accepted Fabric snapshots, accountability-root discovery, and repo-local evidence.
|
||||
scope: Shared schemas, validation, graph construction, registry projections, scanner output, and State Hub export contracts for repository, service, capability, interface, dependency, binding, and runtime discovery data.
|
||||
purposes:
|
||||
- id: purpose/graph-refactor
|
||||
use_case: Canon-aligned graph model reset and reingest.
|
||||
consumer_need: Separate canonical graph semantics from registry, scanner, and visualization convenience edges before broad adoption.
|
||||
demand_signals:
|
||||
- RAIL-FAB-WP-0016
|
||||
- Registry graph explorer needs clearer canonical/display boundary.
|
||||
- Scanner output needs evidence state and canon mapping metadata.
|
||||
canon_surfaces:
|
||||
implemented_profiles: []
|
||||
consumed_artifacts:
|
||||
- model/landscape
|
||||
- model/network
|
||||
- model/data
|
||||
- model/devsecops
|
||||
- model/observability
|
||||
- model/governance
|
||||
- model/security
|
||||
- model/task
|
||||
- model/purpose-demand-extension
|
||||
- standard/tagging
|
||||
- conformance/railiance-fabric
|
||||
owned_concepts:
|
||||
- FabricGraphExport
|
||||
- FabricDiscoverySnapshot
|
||||
- GraphExplorerPayload
|
||||
- RegistryOnboardingManifest
|
||||
produced_concepts:
|
||||
- FabricEntity
|
||||
- FabricEdge
|
||||
- CaptureSource
|
||||
- DisplayEdge
|
||||
- CanonicalEdgeCandidate
|
||||
- VisualizationView
|
||||
consumed_concepts:
|
||||
- Repository
|
||||
- Service
|
||||
- SoftwareSystem
|
||||
- RuntimeResource
|
||||
- Endpoint
|
||||
- Deployment
|
||||
- Flow
|
||||
- Evidence
|
||||
- Task
|
||||
mappings:
|
||||
- source: Repository
|
||||
target: source-repository
|
||||
fit: direct
|
||||
- source: ServiceDeclaration
|
||||
target: service
|
||||
fit: direct
|
||||
- source: InterfaceDeclaration
|
||||
target: endpoint
|
||||
fit: partial
|
||||
- source: CapabilityDeclaration
|
||||
target: software-system
|
||||
fit: partial
|
||||
- source: DependencyDeclaration
|
||||
target: depends_on edge
|
||||
fit: gap
|
||||
validation_expectations:
|
||||
commands:
|
||||
- python3 -m pytest
|
||||
evidence_required:
|
||||
- Nodes carry canon_category, canon_anchor, mapping_fit, and evidence_state.
|
||||
- Edges carry canonical_type, display_only, mapping_fit, and evidence_state.
|
||||
- Display-only edges do not act as conformance claims.
|
||||
- Reset commands are guarded and documented before graph data is dropped.
|
||||
known_gaps:
|
||||
- Datastore, flow, policy, control, telemetry-signal, task, and consumer-purpose are not first-class scanner outputs yet.
|
||||
- Legacy declaration nodes still preserve capability/dependency/binding helper nodes until reingest rules collapse or replace them safely.
|
||||
purpose_fit:
|
||||
state: partial-fit
|
||||
matched_capabilities:
|
||||
- entity and edge capture criteria
|
||||
- mapping expectations
|
||||
- visualization boundary examples
|
||||
scope_pressure: Fabric needs a stable edge vocabulary and evidence-state vocabulary for mixed declared, observed, inferred, and proposed graph claims.
|
||||
recommended_disposition: Continue consumer-side refactor; record canon gaps as explicit feedback rather than silently extending Fabric semantics.
|
||||
consumer_needs:
|
||||
current:
|
||||
- Canon-aligned graph metadata in scanner, registry, export, and graph explorer payloads.
|
||||
- Safe destructive reset guardrails before dropping previous graph snapshots.
|
||||
- Reingest validation across registered and local repositories.
|
||||
requested_extensions:
|
||||
- Stable relationship vocabulary for graph capture.
|
||||
- Evidence-state vocabulary for captured edges.
|
||||
- Visualization boundary guidance for display-only edges.
|
||||
feedback:
|
||||
- CapabilityDeclaration and DependencyDeclaration are useful Fabric authoring helpers but do not map cleanly to canon node categories.
|
||||
- Network flow and logical dependency must remain separate even when both are inferred from the same source artifact.
|
||||
@@ -1,12 +1,18 @@
|
||||
# Declaration Schema
|
||||
|
||||
Railiance Fabric declarations are small YAML documents owned by the repository
|
||||
that provides or consumes the declared thing. The first schema version is
|
||||
Railiance Fabric declarations are small YAML documents that capture repo-local
|
||||
self-description evidence. The first schema version is
|
||||
`railiance.fabric/v1alpha1`.
|
||||
|
||||
These declarations are still supported for bootstrap and compatibility, but
|
||||
they are not the long-term authority for external deployment realities,
|
||||
financial fabric boundaries, tenant subfabrics, or cross-boundary utility
|
||||
relations. The financial Fabric model starts from accountability roots as
|
||||
described in `docs/FabricDiscoveryAndUpdate.md`.
|
||||
|
||||
## File Layout
|
||||
|
||||
Participating repositories should use this layout:
|
||||
Participating repositories that publish local evidence should use this layout:
|
||||
|
||||
```text
|
||||
fabric/
|
||||
@@ -56,7 +62,7 @@ begin with the owning repo slug when possible:
|
||||
| `kind` | Declaration kind: service, capability, interface, dependency, or binding assertion. |
|
||||
| `metadata.id` | Stable graph identifier used for references and bindings. |
|
||||
| `metadata.name` | Human-readable display name. |
|
||||
| `metadata.owner` | Owning team, repo, or domain owner. |
|
||||
| `metadata.owner` | Local evidence owner for the declaration; financial Fabric ownership is resolved separately. |
|
||||
| `metadata.repo` | Repo slug that owns the declaration. |
|
||||
| `metadata.domain` | Domain slug, such as `railiance` or `custodian`. |
|
||||
| `metadata.source_links` | Optional source pointers to docs, code, manifests, ADRs, or workplans. |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Discovery Queries And Exports
|
||||
|
||||
Railiance Fabric includes a first CLI surface for inspecting local declaration
|
||||
graphs.
|
||||
graphs and projecting them into the current financial Fabric baseline.
|
||||
|
||||
All commands accept a repo root, `fabric/` directory, or declaration files. When
|
||||
paths are omitted, commands read `./fabric`.
|
||||
@@ -78,8 +78,36 @@ Export the graph as Mermaid:
|
||||
railiance-fabric export --format mermaid
|
||||
```
|
||||
|
||||
Export the graph as the manifest-compatible graph explorer payload:
|
||||
|
||||
```bash
|
||||
railiance-fabric export --format graph-explorer
|
||||
```
|
||||
|
||||
Export the graph as the financial Fabric baseline projection:
|
||||
|
||||
```bash
|
||||
railiance-fabric export --format financial
|
||||
```
|
||||
|
||||
The JSON export has two top-level arrays:
|
||||
|
||||
- `nodes`: service, capability, interface, dependency, and binding nodes
|
||||
- `edges`: graph relationships such as `provides`, `exposes`,
|
||||
`available_via`, `consumes`, `binds:<status>`, and `uses_interface`
|
||||
|
||||
Canon-aligned exports also carry mapping metadata beside the existing Fabric
|
||||
terms: nodes include `canon_category`, `canon_anchor`, `mapping_fit`, and
|
||||
`evidence_state`; edges include `canonical_type`, `display_only`,
|
||||
`mapping_fit`, and `evidence_state`.
|
||||
|
||||
The graph explorer payload wraps those nodes and edges as Cytoscape-compatible
|
||||
elements with stable keys, layers, display state, visual facets, source
|
||||
references, and deep links. The registry service exposes the same projection at
|
||||
`GET /exports/graph-explorer`.
|
||||
|
||||
The financial export emits `railiance.fabric/v1alpha2` /
|
||||
`financial-fabric-v1`. It combines the current legacy graph evidence with
|
||||
`fabric/financial/railiance-netkingdom.yaml`, assigning inherited ownership and
|
||||
fabric containment for the current single Railiance fabric. Use it as the reset
|
||||
contract and State Hub vNext handoff artifact.
|
||||
|
||||
@@ -7,12 +7,16 @@ services, capabilities, interfaces, and dependencies.
|
||||
## Recommendation
|
||||
|
||||
Build a small Railiance Ecosystem Registry service as the API and indexed read
|
||||
model over repo-owned Fabric declarations.
|
||||
model over accepted Fabric graph snapshots, discovery evidence, and supporting
|
||||
inventory.
|
||||
|
||||
The registry should not replace the `fabric/` files in each repo. Repositories
|
||||
remain the source of truth. The service validates, snapshots, queries, and
|
||||
projects that model so agents, humans, and State Hub can interact with the
|
||||
ecosystem graph without cloning every repo or rerunning the local CLI.
|
||||
The registry should not become the authoring surface for Fabric ownership or
|
||||
boundaries. Repo-local `fabric/` files remain useful evidence, while financial
|
||||
fabric membership, tenant boundaries, ownership, and cross-boundary utility
|
||||
relations are resolved from accountability roots and accepted snapshots. The
|
||||
service validates, snapshots, queries, and projects that model so agents,
|
||||
humans, and State Hub can interact with the ecosystem graph without cloning
|
||||
every repo or rerunning the local CLI.
|
||||
|
||||
The closest external model to compare against is CNCF xRegistry. xRegistry is
|
||||
specifically about metadata registries, with both file/document and API views.
|
||||
|
||||
421
docs/financial-fabric-model-audit.md
Normal file
421
docs/financial-fabric-model-audit.md
Normal file
@@ -0,0 +1,421 @@
|
||||
# Financial Fabric Model Audit
|
||||
|
||||
Date: 2026-05-24
|
||||
|
||||
Workplan: `RAIL-FAB-WP-0017`
|
||||
|
||||
## Purpose
|
||||
|
||||
This audit identifies the current `railiance-fabric` assumptions that must
|
||||
change to implement the financial Fabric architecture in
|
||||
`docs/FabricDiscoveryAndUpdate.md`.
|
||||
|
||||
The current implementation is still centered on repo-owned declarations:
|
||||
|
||||
```text
|
||||
repo -> service -> capability -> interface -> dependency -> binding
|
||||
```
|
||||
|
||||
That model remains useful as legacy evidence and as a self-description layer,
|
||||
but it is no longer the correct top-level source of truth for external fabric
|
||||
relations. The vNext model must start from accountability roots: netkingdom,
|
||||
king, lords, tenants, fabrics, subfabrics, deployment automation, durable
|
||||
infrastructure evidence, and cross-boundary utility interfaces.
|
||||
|
||||
## Current Model Assumptions
|
||||
|
||||
### Repo-Owned Declarations Are The Primary Graph Source
|
||||
|
||||
Affected files:
|
||||
|
||||
- `INTENT.md`
|
||||
- `SCOPE.md`
|
||||
- `docs/declaration-schema.md`
|
||||
- `docs/adoption-guide.md`
|
||||
- `docs/first-rollout.md`
|
||||
- `docs/repo-reality-scanner.md`
|
||||
- `fabric/README.md`
|
||||
- `examples/declarations/**`
|
||||
- `fabric/services/**`
|
||||
- `fabric/capabilities/**`
|
||||
- `fabric/interfaces/**`
|
||||
- `fabric/dependencies/**`
|
||||
- `fabric/bindings/**`
|
||||
|
||||
Current behavior:
|
||||
|
||||
- Repositories are expected to own declarations for services, capabilities,
|
||||
interfaces, dependencies, and binding assertions.
|
||||
- The scanner treats repo-owned Fabric declarations as the highest-trust source
|
||||
for accepted graph data.
|
||||
- Existing examples and docs teach adoption by adding `fabric/` files to
|
||||
participating repositories.
|
||||
|
||||
Required change:
|
||||
|
||||
- Repo-owned declarations should become one evidence source, mostly useful for
|
||||
self-description, not the default authority for external relations.
|
||||
- External relations, tenancy, deployment membership, and cross-boundary utility
|
||||
edges should come from fabric-scoped discovery roots and deployment evidence.
|
||||
|
||||
### Declaration Kinds Encode The Graph Shape
|
||||
|
||||
Affected files:
|
||||
|
||||
- `schemas/service.schema.yaml`
|
||||
- `schemas/capability.schema.yaml`
|
||||
- `schemas/interface.schema.yaml`
|
||||
- `schemas/dependency.schema.yaml`
|
||||
- `schemas/binding.schema.yaml`
|
||||
- `schemas/common.schema.yaml`
|
||||
- `railiance_fabric/model.py`
|
||||
- `railiance_fabric/loader.py`
|
||||
- `railiance_fabric/validation.py`
|
||||
- `railiance_fabric/graph.py`
|
||||
- `railiance_fabric/canon.py`
|
||||
- `tests/test_canon.py`
|
||||
- `tests/test_registry.py`
|
||||
- `tests/test_scanner.py`
|
||||
- `tests/test_discovery.py`
|
||||
- `tests/test_discovery_registry.py`
|
||||
- `tests/test_reconciliation.py`
|
||||
|
||||
Current behavior:
|
||||
|
||||
- `loader.py` hardcodes declaration directories:
|
||||
`services`, `capabilities`, `interfaces`, `dependencies`, and `bindings`.
|
||||
- `validation.py` only accepts the legacy declaration kinds through
|
||||
`SCHEMA_BY_KIND`.
|
||||
- `graph.py` builds provider/consumer/binding behavior directly from those
|
||||
declaration kinds.
|
||||
- `canon.py` maps those declaration kinds into canonical categories, with
|
||||
several partial or gap mappings.
|
||||
- Tests assert the legacy kinds and edge types as the normal graph shape.
|
||||
|
||||
Required change:
|
||||
|
||||
- Add vNext semantic graph concepts for netkingdom, actor, fabric, subfabric,
|
||||
owned node, utility interface, accounting attribution, and provenance.
|
||||
- Keep legacy declaration kinds as a compatibility/evidence layer until they
|
||||
can be migrated or intentionally retired.
|
||||
- Stop treating environment tags as possible fabric boundaries.
|
||||
|
||||
### Metadata Owner Is Not Financial Ownership
|
||||
|
||||
Affected files:
|
||||
|
||||
- `schemas/common.schema.yaml`
|
||||
- `railiance_fabric/graph.py`
|
||||
- `railiance_fabric/scanner.py`
|
||||
- `railiance_fabric/registry.py`
|
||||
- `schemas/state-hub-export.schema.yaml`
|
||||
- existing declaration files under `fabric/**`
|
||||
|
||||
Current behavior:
|
||||
|
||||
- `metadata.owner` is required for declarations, but it is just a string.
|
||||
- Graph exports place owner inside node `attributes.owner`, not as a first-class
|
||||
field.
|
||||
- Discovery candidates can carry owner-like attributes, but there is no
|
||||
enforced owner actor, role, inheritance rule, or unresolved-owner state.
|
||||
- State Hub export nodes require `repo`, `domain`, and `lifecycle`, but not
|
||||
financial owner, fabric, or subfabric.
|
||||
|
||||
Required change:
|
||||
|
||||
- Introduce actor identity and role: king, lord, tenant, and supporting
|
||||
operator/steward where needed.
|
||||
- Every accepted node must resolve to an owner actor, either explicit or
|
||||
inherited from containing fabric/subfabric.
|
||||
- Missing or ambiguous ownership must be represented as review state before
|
||||
promotion.
|
||||
|
||||
### Fabric Membership Is Missing
|
||||
|
||||
Affected files:
|
||||
|
||||
- `schemas/state-hub-export.schema.yaml`
|
||||
- `schemas/discovery-snapshot.schema.yaml`
|
||||
- `railiance_fabric/scanner.py`
|
||||
- `railiance_fabric/registry.py`
|
||||
- `railiance_fabric/graph_explorer.py`
|
||||
- `railiance_fabric/graph_explorer_ui.py`
|
||||
- `docs/graph-explorer-contract.md`
|
||||
- `docs/state-hub-integration.md`
|
||||
|
||||
Current behavior:
|
||||
|
||||
- Accepted graph nodes have repo/domain/lifecycle fields, but no `fabric_id`,
|
||||
`subfabric_id`, containment path, or owning lord/tenant relation.
|
||||
- Discovery snapshots are scoped to one `repo_slug`, one commit, and one scan
|
||||
profile.
|
||||
- Registry snapshots are stored per repository and combined by merging the
|
||||
latest snapshot for each repo.
|
||||
|
||||
Required change:
|
||||
|
||||
- Add first-class fabric/subfabric identity and containment.
|
||||
- Preserve repo scoping for repository evidence, but do not let repo scope
|
||||
define fabric membership.
|
||||
- Add a root netkingdom/fabric baseline for the current one-fabric Railiance
|
||||
setup.
|
||||
|
||||
### Cross-Boundary Utility Is Flattened Into Dependency Edges
|
||||
|
||||
Affected files:
|
||||
|
||||
- `schemas/dependency.schema.yaml`
|
||||
- `schemas/binding.schema.yaml`
|
||||
- `railiance_fabric/graph.py`
|
||||
- `railiance_fabric/registry.py`
|
||||
- `railiance_fabric/canon.py`
|
||||
- `railiance_fabric/graph_explorer.py`
|
||||
- `railiance_fabric/graph_explorer_ui.py`
|
||||
- `tests/test_registry.py`
|
||||
- `tests/test_graph_explorer.py`
|
||||
|
||||
Current behavior:
|
||||
|
||||
- Consumers and providers are expressed as dependencies and binding assertions.
|
||||
- Edges such as `consumes`, `binds:*`, and `uses_interface` map mostly to
|
||||
canonical `depends_on`.
|
||||
- There is no explicit provider-owner/consumer-owner boundary, payment schema,
|
||||
metering basis, or business model on the edge.
|
||||
|
||||
Required change:
|
||||
|
||||
- Add a first-class cross-boundary utility edge concept.
|
||||
- Preserve technical dependency edges, but distinguish them from economic or
|
||||
tenancy value interfaces.
|
||||
- Allow cross-boundary edges across fabric and subfabric boundaries without
|
||||
treating the boundary crossing as an error.
|
||||
|
||||
### Cost/Profit Centers Are Not Represented
|
||||
|
||||
Affected files:
|
||||
|
||||
- all current graph schemas and exports
|
||||
- `railiance_fabric/registry.py`
|
||||
- `railiance_fabric/graph_explorer.py`
|
||||
- `railiance_fabric/graph_explorer_ui.py`
|
||||
- State Hub import contract in `schemas/state-hub-export.schema.yaml`
|
||||
|
||||
Current behavior:
|
||||
|
||||
- There are no node or edge fields for cost center, profit center, allocation
|
||||
model, payment schema, metering basis, or attribution validity.
|
||||
|
||||
Required change:
|
||||
|
||||
- Add optional accounting attribution on nodes and edges.
|
||||
- Ensure accounting attribution can drive views without changing fabric or
|
||||
subfabric membership.
|
||||
|
||||
### Discovery Has Good Mechanics But Wrong Roots
|
||||
|
||||
Affected files:
|
||||
|
||||
- `railiance_fabric/scanner.py`
|
||||
- `railiance_fabric/discovery.py`
|
||||
- `railiance_fabric/reconciliation.py`
|
||||
- `railiance_fabric/connectors.py`
|
||||
- `schemas/discovery-snapshot.schema.yaml`
|
||||
- `docs/repo-reality-scanner.md`
|
||||
- `docs/operational-rescan-loops.md`
|
||||
- `docs/registry-onboarding.md`
|
||||
|
||||
Current behavior:
|
||||
|
||||
- Discovery snapshots are provenance-rich and already separate candidates from
|
||||
accepted graph state.
|
||||
- Replacement scopes, stable keys, tombstones, review states, reconciliation
|
||||
diffs, and connector runs are already present.
|
||||
- Discovery is still repo-scoped and gives `repo_declaration` precedence.
|
||||
- `local-fabric-registry` reads repository onboarding manifests, not
|
||||
accountability roots or deployment responsibility boundaries.
|
||||
|
||||
Required change:
|
||||
|
||||
- Reuse the raw-evidence/candidate/accepted mechanics.
|
||||
- Add accountability-root manifests and adapters for deployment automation,
|
||||
infrastructure evidence, recovery/secrets/backup evidence, and ownership
|
||||
boundaries.
|
||||
- Change precedence so repo declarations can be strong self-description
|
||||
evidence without overriding fabric-scoped deployment evidence.
|
||||
|
||||
### State Hub Export Is Too Thin For The New Model
|
||||
|
||||
Affected files:
|
||||
|
||||
- `schemas/state-hub-export.schema.yaml`
|
||||
- `railiance_fabric/graph.py`
|
||||
- `railiance_fabric/registry.py`
|
||||
- `railiance_fabric/server.py`
|
||||
- `docs/state-hub-integration.md`
|
||||
- `docs/registry-api.md`
|
||||
|
||||
Current behavior:
|
||||
|
||||
- `/exports/state-hub` returns a `FabricGraphExport` with nodes and edges.
|
||||
- Nodes require `id`, `kind`, `name`, `repo`, `domain`, and `lifecycle`.
|
||||
- Edges require `from`, `to`, and `type`.
|
||||
- Canon metadata and evidence state are present, but ownership, containment,
|
||||
accounting, and utility metadata are not first-class.
|
||||
|
||||
Required change:
|
||||
|
||||
- Version the export contract.
|
||||
- Add fabric/subfabric containment, owner actor identity, owner role,
|
||||
cross-boundary utility metadata, and optional cost/profit attribution.
|
||||
- Keep enough compatibility metadata for State Hub to support old imports until
|
||||
`STATE-WP-0051` replaces or migrates the read model.
|
||||
|
||||
## Affected APIs And Commands
|
||||
|
||||
HTTP surfaces:
|
||||
|
||||
- `GET /exports/state-hub`
|
||||
- `GET /exports/graph-explorer`
|
||||
- `GET /exports/backstage`
|
||||
- `GET /exports/xregistry`
|
||||
- `GET /graph/providers`
|
||||
- `GET /graph/consumers`
|
||||
- `GET /graph/unresolved`
|
||||
- `GET /graph/blast-radius`
|
||||
- `GET /graph/dependency-path`
|
||||
- `POST /repositories/{repo_slug}/snapshots`
|
||||
- `POST /repositories/{repo_slug}/discovery-snapshots`
|
||||
- `POST /repositories/{repo_slug}/discovery-snapshots/{id}/accept`
|
||||
- `GET /repositories/{repo_slug}/inventory`
|
||||
|
||||
CLI surfaces:
|
||||
|
||||
- `railiance-fabric validate`
|
||||
- `railiance-fabric export`
|
||||
- `railiance-fabric providers`
|
||||
- `railiance-fabric consumers`
|
||||
- `railiance-fabric dependency-path`
|
||||
- `railiance-fabric unresolved`
|
||||
- `railiance-fabric blast-radius`
|
||||
- `railiance-fabric scan`
|
||||
- `railiance-fabric registry sync`
|
||||
- `railiance-fabric registry sync-manifest`
|
||||
- `railiance-fabric registry scan-manifest`
|
||||
- `railiance-fabric registry ingest-discovery`
|
||||
- `railiance-fabric registry accept-discovery`
|
||||
- `railiance-fabric registry rescan-status`
|
||||
|
||||
Projection surfaces:
|
||||
|
||||
- Graph Explorer payload and manifest.
|
||||
- Backstage projection.
|
||||
- xRegistry projection.
|
||||
- State Hub Fabric read-model import.
|
||||
|
||||
## Compatibility Risks
|
||||
|
||||
1. State Hub import compatibility:
|
||||
`STATE-WP-0050` expects the current `FabricGraphExport` shape. Adding
|
||||
required fields or changing node/edge semantics can break ingest unless the
|
||||
export is versioned or State Hub is updated in lockstep.
|
||||
|
||||
2. Graph Explorer compatibility:
|
||||
Graph Explorer filters and detail panes use current node kinds, layers,
|
||||
dependency chains, unresolved states, and canon metadata. New actor/fabric
|
||||
nodes and utility edges need UI mapping before the explorer remains useful.
|
||||
|
||||
3. Query command compatibility:
|
||||
Provider/consumer/dependency-path commands are built on capability and
|
||||
dependency declarations. They may remain useful as legacy views, but should
|
||||
not be presented as the whole Fabric model.
|
||||
|
||||
4. Registry storage compatibility:
|
||||
The registry stores snapshots as JSON, so schema migration is flexible, but
|
||||
combined graph behavior currently deduplicates by node id across latest
|
||||
per-repo snapshots. Fabric-scoped snapshots may need a root snapshot or
|
||||
scenario/fabric identity instead of only repo latest snapshots.
|
||||
|
||||
5. Test fixture blast radius:
|
||||
Most tests assert legacy declaration kinds, repo-scoped discovery keys, and
|
||||
current export payload shape. The migration should add vNext tests before
|
||||
replacing old assertions.
|
||||
|
||||
6. Canon mapping ambiguity:
|
||||
Current canonical categories do not include financial actors, fabrics,
|
||||
subfabrics, accounting attributions, or utility value interfaces. These
|
||||
either need canonical mappings or explicit `mapping_fit: gap` handling.
|
||||
|
||||
7. Existing accepted graph baseline:
|
||||
The current accepted graph contains 49 nodes and 58 edges from the
|
||||
post-`RAIL-FAB-WP-0016` reset. It should be treated as a legacy baseline
|
||||
and re-exported or archived before a controlled vNext reset.
|
||||
|
||||
## Migration Approach
|
||||
|
||||
1. Preserve legacy declarations as `v1alpha1` evidence.
|
||||
Do not delete `fabric/` declarations or examples immediately. Reclassify
|
||||
them as self-description and bootstrap evidence.
|
||||
|
||||
2. Introduce a vNext contract alongside the current export.
|
||||
Add schema version metadata before making breaking changes. Prefer either
|
||||
`railiance.fabric/v1alpha2` or an explicit export `schema_version`.
|
||||
|
||||
3. Add first-class model concepts before changing scanner roots.
|
||||
Implement netkingdom, actor, fabric, subfabric, ownership, utility edge, and
|
||||
accounting attribution semantics in schemas/tests first.
|
||||
|
||||
4. Extend discovery rather than replacing it.
|
||||
Reuse `FabricDiscoverySnapshot`, replacement scopes, candidates,
|
||||
provenance, reconciliation, and acceptance. Add accountability-root
|
||||
manifest evidence and deployment automation adapters.
|
||||
|
||||
5. Seed the current one-fabric baseline.
|
||||
Create the Railiance netkingdom root, current king, current lord/fabric, and
|
||||
inherited ownership defaults. This lets existing nodes resolve ownership
|
||||
before tenant subfabrics exist.
|
||||
|
||||
6. Version State Hub import.
|
||||
Coordinate with `STATE-WP-0051` so State Hub can ingest both the old and
|
||||
vNext export during the transition, or explicitly perform a read-model reset.
|
||||
|
||||
7. Rebuild and compare.
|
||||
Produce a vNext export from the current baseline, compare it against the
|
||||
legacy 49-node/58-edge export, and document intentional semantic changes.
|
||||
|
||||
## Follow-On Implementation Notes
|
||||
|
||||
For `RAIL-FAB-WP-0017-T02`:
|
||||
|
||||
- Define schema names and versioning for vNext graph exports.
|
||||
- Decide whether netkingdom/fabric/actor are node kinds, top-level export
|
||||
sections, or both.
|
||||
- Define ownership inheritance and unresolved-owner representation.
|
||||
- Define utility edge fields:
|
||||
provider owner, consumer owner, provider boundary, consumer boundary,
|
||||
payment schema, metering basis, and evidence.
|
||||
- Define accounting fields:
|
||||
cost center, profit center, allocation model, attribution validity.
|
||||
|
||||
For `RAIL-FAB-WP-0017-T03`:
|
||||
|
||||
- Add model classes or typed helpers beyond the generic `Declaration` wrapper.
|
||||
- Extend validation to enforce resolvable ownership on accepted nodes.
|
||||
- Update registry projection to preserve ownership, containment, accounting,
|
||||
and utility metadata.
|
||||
- Keep old declaration graph validation available as a legacy command or
|
||||
compatibility path.
|
||||
|
||||
For `RAIL-FAB-WP-0017-T04`:
|
||||
|
||||
- Update `schemas/state-hub-export.schema.yaml`.
|
||||
- Add sample vNext export payloads and tests.
|
||||
- Coordinate the import fields with `STATE-WP-0051`.
|
||||
|
||||
For `RAIL-FAB-WP-0018`:
|
||||
|
||||
- Build an accountability-root manifest instead of extending
|
||||
`registry/local-repos.yaml` into too many meanings.
|
||||
- Treat State Hub attached repos as one discovery root, not as the Fabric
|
||||
boundary itself.
|
||||
- Add deployment automation and infrastructure evidence adapters before trying
|
||||
to infer cross-boundary value edges.
|
||||
226
docs/financial-fabric-operator-guide.md
Normal file
226
docs/financial-fabric-operator-guide.md
Normal file
@@ -0,0 +1,226 @@
|
||||
# Financial Fabric Operator Guide
|
||||
|
||||
This guide is the operator path for the financial Fabric reset described in
|
||||
`docs/FabricDiscoveryAndUpdate.md`.
|
||||
|
||||
## Current Baseline
|
||||
|
||||
Railiance currently has one effective fabric because one actor pays for the
|
||||
infrastructure. The accepted baseline lives at:
|
||||
|
||||
```text
|
||||
fabric/financial/railiance-netkingdom.yaml
|
||||
```
|
||||
|
||||
It defines:
|
||||
|
||||
- `railiance.netkingdom` as the netkingdom root;
|
||||
- `actor.railiance.king` as the king with recovery, secrets, backup, and
|
||||
termination authority;
|
||||
- `actor.railiance.primary-lord` as the lord who pays for the current fabric;
|
||||
- `fabric.railiance.primary` as the current active fabric;
|
||||
- inherited ownership for accepted nodes until a more specific owner is
|
||||
discovered or approved;
|
||||
- a future subfabric template for tenant modeling.
|
||||
|
||||
The baseline is not a security-zone model. Do not introduce realm, domain, or
|
||||
identity-zone language into the Fabric core when updating it.
|
||||
|
||||
## Deployment Overlay Baseline
|
||||
|
||||
Fabric membership is not the same as deployment environment. Use these current
|
||||
Railiance deployment overlays when interpreting discovery evidence:
|
||||
|
||||
| Scenario | Environment | Access zone baseline | Notes |
|
||||
|----------|-------------|----------------------|-------|
|
||||
| `bernd-laptop` | `dev` | `private-dev` | Local machine used by one developer. Its loopback ports and local tools are useful evidence for debugging, but are not shared truth for other developers. |
|
||||
| `coulombcore` | `test` | `collaborator-test`, `early-access` | Central test-stage server for collaborating developers and friendly early-access users. |
|
||||
| `railiance01` | `prod` | `production-public`, `production-admin` | Production host. Developer access exists during alpha, but production should be able to move toward restricted operator access and applicable security and data-privacy controls. |
|
||||
|
||||
The routing authority is the source that maps names or ports to services in a
|
||||
scenario. For local dev this may be a Makefile, script, process launcher, or
|
||||
loopback binding. For test and production this should usually come from
|
||||
Kubernetes `Service` and `Ingress`, Traefik/nginx/Caddy/HAProxy configuration,
|
||||
DNS, and TLS automation.
|
||||
|
||||
Fabric should discover those routes and visualize the resulting zones. It
|
||||
should not allocate ports, author reverse-proxy config, or define the access
|
||||
policy. The policy authority is external evidence, such as NetKingdom IAM,
|
||||
ingress policy, network policy, or local-only loopback binding.
|
||||
|
||||
## Refresh Loop
|
||||
|
||||
Run these checks from the `railiance-fabric` repo after changing declarations,
|
||||
baseline ownership, discovery inputs, or export code:
|
||||
|
||||
```bash
|
||||
railiance-fabric validate .
|
||||
railiance-fabric export --format json
|
||||
railiance-fabric export --format financial
|
||||
python3 -m pytest tests/test_registry.py -q
|
||||
```
|
||||
|
||||
Use the legacy JSON export for compatibility with existing `STATE-WP-0050`
|
||||
State Hub behavior. Use the financial export to verify the vNext contract and
|
||||
the ownership/fabric projection.
|
||||
|
||||
For accountability-root discovery, start from the current root manifest:
|
||||
|
||||
```text
|
||||
fabric/discovery/railiance-accountability-roots.yaml
|
||||
```
|
||||
|
||||
The manifest schema is documented in `docs/accountability-root-manifest.md`.
|
||||
|
||||
To collect raw evidence from those roots without promoting graph state:
|
||||
|
||||
```bash
|
||||
railiance-fabric discover-roots --max-items-per-root 200
|
||||
```
|
||||
|
||||
To inspect normalized identity candidates or persist a local evidence run:
|
||||
|
||||
```bash
|
||||
railiance-fabric discover-roots --identity-projection
|
||||
railiance-fabric discover-roots --store-db .railiance-fabric/accountability-evidence.sqlite3
|
||||
```
|
||||
|
||||
To inspect ownership blockers and apply review decisions:
|
||||
|
||||
```bash
|
||||
railiance-fabric discover-roots --ownership-review \
|
||||
--store-db .railiance-fabric/accountability-evidence.sqlite3
|
||||
|
||||
railiance-fabric review-identity <stable-key> \
|
||||
--store-db .railiance-fabric/accountability-evidence.sqlite3 \
|
||||
--decision accept \
|
||||
--owner-actor-id actor.railiance.primary-lord \
|
||||
--fabric-id fabric.railiance.primary
|
||||
```
|
||||
|
||||
To compare a new run with saved review outputs:
|
||||
|
||||
```bash
|
||||
railiance-fabric discover-roots --delta \
|
||||
--previous-identity-projection previous-identities.json \
|
||||
--previous-ownership-review previous-ownership.json
|
||||
```
|
||||
|
||||
The current bootstrap artifacts live at:
|
||||
|
||||
```text
|
||||
fabric/discovery/snapshots/2026-05-24-railiance-bootstrap-identities.json
|
||||
fabric/discovery/snapshots/2026-05-24-railiance-bootstrap-ownership-review.json
|
||||
fabric/discovery/snapshots/2026-05-24-railiance-bootstrap-update-delta.json
|
||||
exports/state-hub/2026-05-24-railiance-financial-fabric-v1.json
|
||||
```
|
||||
|
||||
To refresh the same artifact set:
|
||||
|
||||
```bash
|
||||
railiance-fabric discover-roots --include-remote --max-items-per-root 200 \
|
||||
--identity-projection > fabric/discovery/snapshots/YYYY-MM-DD-railiance-bootstrap-identities.json
|
||||
railiance-fabric discover-roots --include-remote --max-items-per-root 200 \
|
||||
--ownership-review > fabric/discovery/snapshots/YYYY-MM-DD-railiance-bootstrap-ownership-review.json
|
||||
railiance-fabric discover-roots --include-remote --max-items-per-root 200 \
|
||||
--delta > fabric/discovery/snapshots/YYYY-MM-DD-railiance-bootstrap-update-delta.json
|
||||
railiance-fabric export --format financial . \
|
||||
> exports/state-hub/YYYY-MM-DD-railiance-financial-fabric-v1.json
|
||||
```
|
||||
|
||||
The financial export must satisfy these invariants:
|
||||
|
||||
- every accepted node has resolvable ownership;
|
||||
- every accepted node has fabric containment;
|
||||
- cost/profit center fields are optional accounting attribution, not fabric
|
||||
boundaries;
|
||||
- cross-boundary utility edges carry provider and consumer owner context when
|
||||
known;
|
||||
- unresolved ownership or containment remains explicit rather than invented by
|
||||
State Hub.
|
||||
|
||||
## Registry Reset Rebuild
|
||||
|
||||
After a guarded registry reset, rebuild from durable roots in this order:
|
||||
|
||||
1. Confirm the baseline still reflects who pays for the infrastructure.
|
||||
2. Validate the repo evidence with `railiance-fabric validate .`.
|
||||
3. Emit `railiance-fabric export --format financial` and review the ownership
|
||||
projection.
|
||||
4. Start the registry and sync this repo:
|
||||
|
||||
```bash
|
||||
railiance-fabric-registry --db .railiance-fabric/registry.sqlite3 --port 8765
|
||||
railiance-fabric registry sync --repo-slug railiance-fabric .
|
||||
```
|
||||
|
||||
5. Sync broader known repos with `registry/local-repos.yaml` or
|
||||
`registry/railiance-repos.yaml` when their local checkouts exist.
|
||||
6. Compare snapshot diffs before promoting new discovery output.
|
||||
|
||||
Repo-local `fabric/` declarations are evidence during this rebuild. The
|
||||
replacement discovery loop should start from the netkingdom, king, lords,
|
||||
tenants, deployment automation, service manifests, endpoints, backups, and
|
||||
secret roots rather than asking each repo to own all external relations.
|
||||
|
||||
## State Hub Handoff
|
||||
|
||||
State Hub is a read model for Fabric topology. It should ingest Fabric exports,
|
||||
link them to repos/workstreams/tasks, and expose dashboard/search views. It
|
||||
should not author ownership, fabric membership, or utility boundaries.
|
||||
|
||||
Until `STATE-WP-0051` is implemented:
|
||||
|
||||
- continue importing or syncing the legacy `v1alpha1` graph for existing State
|
||||
Hub graph views;
|
||||
- keep the `v1alpha2` financial export as the contract artifact for State Hub
|
||||
implementation and review;
|
||||
- update file-backed workplan state through State Hub consistency after
|
||||
workplan edits:
|
||||
|
||||
```bash
|
||||
cd ~/state-hub
|
||||
make fix-consistency REPO=railiance-fabric
|
||||
```
|
||||
|
||||
After `STATE-WP-0051`, the financial export should become the preferred State
|
||||
Hub graph import. The importer must preserve netkingdom, actors, fabrics,
|
||||
containment, ownership, accounting attribution, cross-boundary utility context,
|
||||
and unresolved gaps.
|
||||
|
||||
To import a saved financial export into State Hub:
|
||||
|
||||
```bash
|
||||
curl -s -X POST \
|
||||
"http://127.0.0.1:8000/fabric/graph-exports?source_repo_slug=railiance-fabric" \
|
||||
-H "Content-Type: application/json" \
|
||||
--data-binary @exports/state-hub/2026-05-24-railiance-financial-fabric-v1.json
|
||||
```
|
||||
|
||||
If the `/fabric/graph-exports` endpoints return `500` while ordinary State Hub
|
||||
routes work, run the State Hub migrations and retry:
|
||||
|
||||
```bash
|
||||
cd ~/state-hub
|
||||
make migrate
|
||||
# or, when uv is not on PATH:
|
||||
.venv/bin/alembic upgrade head
|
||||
```
|
||||
|
||||
## Discovery Work Handoff
|
||||
|
||||
The next discovery/update-loop work should replace the baseline projection with
|
||||
durable evidence collection:
|
||||
|
||||
- discover repos from State Hub and Gitea;
|
||||
- discover deployment realities from automation and infrastructure manifests;
|
||||
- discover services, machines, endpoints, backup roots, and secret roots;
|
||||
- normalize identities across repo URLs, host paths, image names, service
|
||||
names, and endpoint contracts;
|
||||
- resolve owner and containment from the baseline, explicit evidence, or
|
||||
review decisions;
|
||||
- emit deltas for ownership, containment, nodes, edges, and cross-boundary
|
||||
utility changes.
|
||||
|
||||
The baseline projection is therefore a safe bridge, not the final discovery
|
||||
engine.
|
||||
493
docs/financial-fabric-vnext-contract.md
Normal file
493
docs/financial-fabric-vnext-contract.md
Normal file
@@ -0,0 +1,493 @@
|
||||
# Financial Fabric VNext Contract
|
||||
|
||||
Date: 2026-05-24
|
||||
|
||||
Workplan: `RAIL-FAB-WP-0017`
|
||||
|
||||
Status: contract draft for implementation
|
||||
|
||||
## Intent
|
||||
|
||||
The vNext Fabric contract models the Railiance netkingdom as a durable
|
||||
infrastructure-responsibility graph.
|
||||
|
||||
The contract separates:
|
||||
|
||||
- financial responsibility boundaries from environments and views;
|
||||
- ownership from repository metadata;
|
||||
- cross-boundary utility interfaces from ordinary technical dependencies;
|
||||
- accounting attribution from fabric membership;
|
||||
- durable topology from live telemetry.
|
||||
|
||||
The contract should be implemented as a versioned export shape before replacing
|
||||
the existing `railiance.fabric/v1alpha1` declaration-centered graph.
|
||||
|
||||
## Versioning
|
||||
|
||||
Recommended contract identity:
|
||||
|
||||
```yaml
|
||||
apiVersion: railiance.fabric/v1alpha2
|
||||
kind: FabricGraphExport
|
||||
schema_version: financial-fabric-v1
|
||||
```
|
||||
|
||||
`v1alpha1` remains the compatibility layer for legacy declarations and the
|
||||
current State Hub import. `v1alpha2` introduces first-class netkingdom,
|
||||
actor, fabric, subfabric, ownership, utility, and accounting semantics.
|
||||
|
||||
## Top-Level Export Shape
|
||||
|
||||
```yaml
|
||||
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: ""
|
||||
generation_reason: rebuild | rescan | operator_refresh
|
||||
compatibility:
|
||||
legacy_v1alpha1_supported: true
|
||||
breaking_reset: false
|
||||
netkingdom:
|
||||
id: railiance.netkingdom
|
||||
name: Railiance Netkingdom
|
||||
king_actor_id: actor.railiance.king
|
||||
actors: []
|
||||
fabrics: []
|
||||
nodes: []
|
||||
edges: []
|
||||
unresolved: []
|
||||
```
|
||||
|
||||
The top-level sections are intentionally explicit. `nodes` and `edges` remain
|
||||
the primary graph payload for State Hub and visualizers, but `netkingdom`,
|
||||
`actors`, and `fabrics` define the responsibility boundary context used to
|
||||
resolve ownership and containment.
|
||||
|
||||
## Actors
|
||||
|
||||
Actors are accountable parties. They are graph addressable and may also be
|
||||
materialized as nodes when a consumer needs a pure node/edge projection.
|
||||
|
||||
```yaml
|
||||
id: actor.railiance.king
|
||||
kind: FabricActor
|
||||
role: king
|
||||
name: Railiance King
|
||||
legal_name: ""
|
||||
description: Responsible for the Railiance netkingdom.
|
||||
authority:
|
||||
recovery_authority: true
|
||||
secrets_authority: true
|
||||
backup_authority: true
|
||||
termination_authority: true
|
||||
relationships:
|
||||
contracts_with:
|
||||
- actor.railiance.primary-lord
|
||||
```
|
||||
|
||||
Actor roles:
|
||||
|
||||
- `king`: responsible for the netkingdom and relevant recovery/secrets/backup
|
||||
authority.
|
||||
- `lord`: pays for a fabric.
|
||||
- `tenant`: pays for restricted use of a subfabric.
|
||||
- `operator`: operates infrastructure on behalf of a king, lord, or tenant.
|
||||
- `steward`: maintains a repo, service, or capability but does not necessarily
|
||||
pay for it.
|
||||
|
||||
Only king, lord, and tenant define financial boundary semantics. Operator and
|
||||
steward roles are supporting roles.
|
||||
|
||||
## Fabrics And Subfabrics
|
||||
|
||||
Fabrics and subfabrics are responsibility boundaries.
|
||||
|
||||
```yaml
|
||||
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
|
||||
boundary:
|
||||
boundary_type: fabric
|
||||
criterion: financial_and_operational_accountability
|
||||
payment_responsibility: actor.railiance.primary-lord
|
||||
operational_responsibility: actor.railiance.king
|
||||
recovery_responsibility: actor.railiance.king
|
||||
status: active
|
||||
evidence_refs: []
|
||||
```
|
||||
|
||||
```yaml
|
||||
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
|
||||
boundary:
|
||||
boundary_type: subfabric
|
||||
criterion: restricted_paid_tenant_utility
|
||||
payment_responsibility: actor.coulomb.tenant
|
||||
operational_responsibility: actor.railiance.primary-lord
|
||||
recovery_responsibility: actor.railiance.king
|
||||
status: planned
|
||||
evidence_refs: []
|
||||
```
|
||||
|
||||
Fabric membership changes when payment, operational responsibility, recovery
|
||||
responsibility, or legal accountability changes. It does not change because a
|
||||
service moves environments, a host is replaced, a repo is refactored, or a
|
||||
diagnostic view changes.
|
||||
|
||||
## Nodes
|
||||
|
||||
Every accepted node must resolve ownership and containment.
|
||||
|
||||
```yaml
|
||||
id: state-hub.api
|
||||
kind: Service
|
||||
name: State Hub 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:
|
||||
- actor.state-hub.steward
|
||||
accounting:
|
||||
cost_center_id: null
|
||||
profit_center_id: null
|
||||
allocation_model: null
|
||||
evidence:
|
||||
state: observed
|
||||
review_state: accepted
|
||||
confidence: 0.95
|
||||
refs: []
|
||||
attributes: {}
|
||||
```
|
||||
|
||||
Required accepted-node semantics:
|
||||
|
||||
- `containment.netkingdom_id`
|
||||
- `containment.fabric_id`
|
||||
- `ownership.owner_actor_id`
|
||||
- `ownership.owner_role`
|
||||
- `ownership.resolution`
|
||||
- `evidence.state`
|
||||
- `evidence.review_state`
|
||||
|
||||
Recommended compatibility fields:
|
||||
|
||||
- `repo`
|
||||
- `domain`
|
||||
- `lifecycle`
|
||||
- `canon_category`
|
||||
- `canon_anchor`
|
||||
- `mapping_fit`
|
||||
- `attributes`
|
||||
|
||||
## Ownership Resolution
|
||||
|
||||
Ownership resolution values:
|
||||
|
||||
- `explicit`: evidence directly names the owner actor.
|
||||
- `inherited`: ownership is inherited from containing fabric or subfabric.
|
||||
- `unresolved`: no acceptable owner could be resolved.
|
||||
- `ambiguous`: multiple plausible owners exist and review is needed.
|
||||
|
||||
Unresolved or ambiguous nodes may appear as candidates or importable read-model
|
||||
gaps, but they must not silently become accepted graph truth.
|
||||
|
||||
```yaml
|
||||
id: unresolved:node:fixture
|
||||
target_id: fixture.unknown-service
|
||||
kind: unresolved_ownership
|
||||
severity: needs_review
|
||||
message: Node has no explicit owner and no resolvable fabric/subfabric owner.
|
||||
evidence_refs: []
|
||||
```
|
||||
|
||||
## Edges
|
||||
|
||||
Edges keep technical topology while adding boundary and value semantics.
|
||||
|
||||
```yaml
|
||||
id: edge:state-hub.api:exposes:state-hub.http
|
||||
from: state-hub.api
|
||||
to: state-hub.http
|
||||
type: exposes
|
||||
relationship_category: technical
|
||||
canonical_type: exposes
|
||||
boundary:
|
||||
crosses_fabric_boundary: false
|
||||
crosses_subfabric_boundary: false
|
||||
evidence:
|
||||
state: observed
|
||||
review_state: accepted
|
||||
confidence: 0.95
|
||||
refs: []
|
||||
attributes: {}
|
||||
```
|
||||
|
||||
Relationship categories:
|
||||
|
||||
- `containment`: netkingdom, fabric, subfabric, actor, or node containment.
|
||||
- `ownership`: owner/steward/operator relationships.
|
||||
- `technical`: deployment, exposure, dependency, flow, build, or evidence edge.
|
||||
- `utility`: value-bearing interface from provider to consumer.
|
||||
- `accounting`: cost/profit attribution or allocation edge.
|
||||
- `evidence`: source artifact or provenance relationship.
|
||||
|
||||
## Cross-Boundary Utility Edges
|
||||
|
||||
Cross-boundary utility edges are first-class because they represent value moving
|
||||
across financial responsibility boundaries.
|
||||
|
||||
```yaml
|
||||
id: utility:state-hub-api:coulomb-tenant
|
||||
from: state-hub.http
|
||||
to: tenant.coulomb.automation-client
|
||||
type: provides_utility_to
|
||||
relationship_category: utility
|
||||
canonical_type: depends_on
|
||||
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: request | seat | flat | allocation | unknown
|
||||
business_model: tenant_utility
|
||||
accounting:
|
||||
provider_profit_center_id: null
|
||||
consumer_cost_center_id: null
|
||||
allocation_model: null
|
||||
evidence:
|
||||
state: declared
|
||||
review_state: accepted
|
||||
confidence: 0.8
|
||||
refs: []
|
||||
attributes: {}
|
||||
```
|
||||
|
||||
The edge may cross a subfabric boundary without crossing the parent fabric
|
||||
boundary. This is expected for tenant utility inside the current Railiance
|
||||
fabric.
|
||||
|
||||
## Cost And Profit Center Attribution
|
||||
|
||||
Accounting attribution is optional and must not redefine containment.
|
||||
|
||||
Node-level attribution:
|
||||
|
||||
```yaml
|
||||
accounting:
|
||||
cost_center_id: cc.platform.shared
|
||||
profit_center_id: null
|
||||
allocation_model: direct
|
||||
valid_from: "2026-05-24"
|
||||
valid_until: null
|
||||
```
|
||||
|
||||
Edge-level attribution:
|
||||
|
||||
```yaml
|
||||
accounting:
|
||||
provider_profit_center_id: pc.tenant-utilities
|
||||
consumer_cost_center_id: cc.coulomb.automation
|
||||
allocation_model: usage_weighted
|
||||
payment_schema_id: payment.internal-tenant-access
|
||||
metering_basis: request
|
||||
valid_from: "2026-05-24"
|
||||
valid_until: null
|
||||
```
|
||||
|
||||
Cost/profit center changes should produce accounting deltas and views, not
|
||||
fabric moves.
|
||||
|
||||
## Evidence And Provenance
|
||||
|
||||
Every discovered or accepted fact should carry evidence.
|
||||
|
||||
```yaml
|
||||
evidence:
|
||||
state: observed | declared | inferred | proposed | gap
|
||||
review_state: accepted | candidate | needs_review | rejected
|
||||
confidence: 0.0
|
||||
refs:
|
||||
- id: evidence:state-hub:compose:api
|
||||
source_kind: deployment_manifest
|
||||
source_path: compose.yaml
|
||||
source_url: null
|
||||
source_repo: state-hub
|
||||
source_commit: abc123
|
||||
scanner: compose
|
||||
scanner_version: "0.1.0"
|
||||
content_hash: sha256:...
|
||||
observed_at: "2026-05-24T00:00:00Z"
|
||||
```
|
||||
|
||||
The contract continues to distinguish durable discovered configuration from
|
||||
live operational telemetry. Health, current running state, latency, incident
|
||||
status, and usage volume are not Fabric core fields.
|
||||
|
||||
## Legacy Canon Mapping
|
||||
|
||||
Existing canonical metadata remains useful for compatibility, but some legacy
|
||||
terms should be demoted to evidence.
|
||||
|
||||
| Existing kind/type | vNext disposition |
|
||||
| --- | --- |
|
||||
| `Repository` | Keep as source-repository node evidence. |
|
||||
| `ServiceDeclaration` | Legacy self-description evidence for `Service`. |
|
||||
| `CapabilityDeclaration` | Legacy self-description evidence for utility or service capability. |
|
||||
| `InterfaceDeclaration` | Legacy self-description evidence for `Endpoint` or `Contract`. |
|
||||
| `DependencyDeclaration` | Legacy consumer-purpose or dependency evidence; not sufficient for value edge alone. |
|
||||
| `BindingAssertion` | Legacy binding evidence; may support utility edge when boundary actors are known. |
|
||||
| `RuntimeService`, `DeploymentService`, `Kubernetes*`, `Server` | Durable deployment/runtime-resource evidence. |
|
||||
| `provides`, `exposes`, `runs_on`, `deployed_as`, `flows_to` | Keep as technical/topology edges. |
|
||||
| `consumes`, `binds:*`, `uses_interface` | Keep as technical dependency edges; promote to utility edges only when provider/consumer ownership and boundary context are known. |
|
||||
| `declares` | Display/evidence edge only. |
|
||||
|
||||
New vNext node kinds to map:
|
||||
|
||||
| vNext kind | Suggested canonical category |
|
||||
| --- | --- |
|
||||
| `Netkingdom` | `software-system` until canon has a better category. |
|
||||
| `FabricActor` | `consumer-purpose` or `control` depending role; likely canon gap. |
|
||||
| `Fabric` | `software-system` or `control`; likely canon gap. |
|
||||
| `Subfabric` | `software-system` or `control`; likely canon gap. |
|
||||
| `UtilityInterface` | `endpoint` when technical, `software-system` when abstract. |
|
||||
| `CostCenter` | `control`; likely canon gap. |
|
||||
| `ProfitCenter` | `control`; likely canon gap. |
|
||||
|
||||
New vNext edge types to map:
|
||||
|
||||
| vNext edge type | Suggested canonical type |
|
||||
| --- | --- |
|
||||
| `contains` | `part_of` |
|
||||
| `owned_by` | `governed_by` |
|
||||
| `operated_by` | `governed_by` |
|
||||
| `provides_utility_to` | `depends_on` with `relationship_category: utility` |
|
||||
| `attributed_to_cost_center` | `governed_by` or canon gap |
|
||||
| `attributed_to_profit_center` | `governed_by` or canon gap |
|
||||
| `evidenced_by` | `evidenced_by` |
|
||||
|
||||
## Examples
|
||||
|
||||
### Current Single Railiance Fabric
|
||||
|
||||
```yaml
|
||||
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
|
||||
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
|
||||
```
|
||||
|
||||
### Future Tenant Subfabric
|
||||
|
||||
```yaml
|
||||
actors:
|
||||
- id: actor.coulomb.tenant
|
||||
kind: FabricActor
|
||||
role: tenant
|
||||
name: Coulomb Tenant
|
||||
fabrics:
|
||||
- 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
|
||||
```
|
||||
|
||||
### Cross-Subfabric Utility
|
||||
|
||||
```yaml
|
||||
edges:
|
||||
- id: utility:state-hub-http:coulomb-client
|
||||
from: state-hub.http
|
||||
to: coulomb.automation-client
|
||||
type: provides_utility_to
|
||||
relationship_category: utility
|
||||
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
|
||||
```
|
||||
|
||||
## State Hub Import Requirements
|
||||
|
||||
State Hub should materialize at least:
|
||||
|
||||
- export version and schema version;
|
||||
- netkingdom id;
|
||||
- fabric/subfabric ids and names;
|
||||
- actor ids, roles, and names;
|
||||
- node containment fields;
|
||||
- node owner actor and owner role;
|
||||
- ownership resolution state;
|
||||
- edge relationship category;
|
||||
- utility provider/consumer ownership context;
|
||||
- boundary crossing booleans;
|
||||
- cost/profit center attribution;
|
||||
- unresolved ownership and containment gaps;
|
||||
- retained canon metadata and evidence state.
|
||||
|
||||
State Hub must not invent missing ownership or redefine fabric membership. It
|
||||
may display unresolved gaps and expose filters/views for operator review.
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
The first rollout is represented by the seed declarations under `fabric/`.
|
||||
Those files are intentionally centralized in Railiance Fabric for bootstrap;
|
||||
the long-term target is for each owning repo to carry its own `fabric/`
|
||||
declarations.
|
||||
the long-term target is for each owning repo to contribute local evidence while
|
||||
financial Fabric ownership and boundary decisions come from accountability-root
|
||||
discovery.
|
||||
|
||||
## Seeded Repos
|
||||
|
||||
@@ -28,8 +29,9 @@ For each owning repo:
|
||||
4. Validate the owning repo together with `railiance-fabric` and other
|
||||
providers/consumers it depends on.
|
||||
5. Export the multi-repo graph for State Hub ingestion.
|
||||
6. Once repo-local declarations are authoritative, remove or mark the central
|
||||
seed declarations as bootstrap-only.
|
||||
6. Once accountability-root discovery can reproduce the graph, mark the
|
||||
central seed declarations as bootstrap evidence and keep only the repo-local
|
||||
facts that remain useful self-description.
|
||||
|
||||
## Suggested Order
|
||||
|
||||
|
||||
292
docs/graph-explorer-contract.md
Normal file
292
docs/graph-explorer-contract.md
Normal file
@@ -0,0 +1,292 @@
|
||||
# Graph Explorer Contract
|
||||
|
||||
This note defines the first manifest and payload contract for the interactive
|
||||
Fabric map and the possible reusable graph explorer engine.
|
||||
|
||||
The contract is intentionally host-neutral. Fabric and repo-scoping should be
|
||||
able to use the same interaction shell by exposing a manifest and a graph
|
||||
payload with stable fields.
|
||||
|
||||
## Files
|
||||
|
||||
- `schemas/graph-explorer-manifest.schema.yaml` validates a host manifest.
|
||||
- `schemas/graph-explorer-payload.schema.yaml` validates graph payloads.
|
||||
- `railiance_fabric.graph_explorer` provides the first Fabric registry
|
||||
manifest and payload projection.
|
||||
|
||||
## Registry Endpoints
|
||||
|
||||
The registry service exposes the first Fabric projection:
|
||||
|
||||
```text
|
||||
GET /ui/graph-explorer
|
||||
GET /exports/graph-explorer/manifest
|
||||
GET /exports/graph-explorer
|
||||
```
|
||||
|
||||
The local CLI can emit the same payload for repo-local inspection:
|
||||
|
||||
```bash
|
||||
railiance-fabric export --format graph-explorer
|
||||
```
|
||||
|
||||
The manifest tells a graph shell where to load data, which fields are stable,
|
||||
which layers exist, which filter fields are available, and which modes the host
|
||||
supports.
|
||||
|
||||
Fabric currently declares `profile_persistence: local`. That means the shell
|
||||
stores named map views in browser `localStorage`, supports duplicate/delete
|
||||
inside that browser, and can copy a URL with the current query parameters and a
|
||||
state blob. Local profile ids can be reopened in the same browser profile; the
|
||||
copied state blob is the portable sharing path until a host-backed profile API
|
||||
is added.
|
||||
|
||||
The payload is compatible with Cytoscape-style element arrays:
|
||||
|
||||
```json
|
||||
{
|
||||
"apiVersion": "railiance.fabric/v1alpha1",
|
||||
"kind": "GraphExplorerPayload",
|
||||
"manifest_id": "railiance-fabric.registry-map",
|
||||
"mode": "full",
|
||||
"elements": [
|
||||
{
|
||||
"data": {
|
||||
"id": "repo:railiance-fabric",
|
||||
"stableKey": "repo:railiance-fabric",
|
||||
"kind": "Repository",
|
||||
"layer": "repository",
|
||||
"label": "Railiance Fabric",
|
||||
"displayState": "show"
|
||||
}
|
||||
}
|
||||
],
|
||||
"hidden_elements": []
|
||||
}
|
||||
```
|
||||
|
||||
## Required Payload Semantics
|
||||
|
||||
Every element must include:
|
||||
|
||||
- `id`: the current element id used by the graph library.
|
||||
- `stableKey`: the durable id used by profile rules, manual overrides, layout
|
||||
state, and deep links.
|
||||
- `kind`: host-specific entity kind.
|
||||
- `layer`: host-declared layer used for layout, grouping, and color.
|
||||
- `displayState`: one of `show`, `blur`, or `hide`.
|
||||
|
||||
Edges are ordinary elements whose data also includes:
|
||||
|
||||
- `source`
|
||||
- `target`
|
||||
- `edgeType`
|
||||
- `strength`
|
||||
- `sameLayer`
|
||||
|
||||
Hosts should also include useful optional fields when available: `label`,
|
||||
`name`, `description`, `repo`, `domain`, `lifecycle`, `reviewState`,
|
||||
`freshnessState`, `confidence`, `visualSize`, `ownership`, `unresolved`,
|
||||
`sourceReferences`, and `deepLinks`.
|
||||
|
||||
Fabric hosts should also include deployment overlay fields when available:
|
||||
`deploymentEnvironment`, `deploymentScenario`, `routingAuthority`,
|
||||
`accessZone`, `policyAuthority`, `exposure`, and `host`. These fields describe
|
||||
where an element runs or is reachable in a concrete deployment scenario. They
|
||||
do not define fabric membership and must remain filter/grouping metadata unless
|
||||
the host explicitly promotes a separate graph relationship with evidence.
|
||||
|
||||
Edges may include layout hints used by the client-side layout engine:
|
||||
`sameRepo`, `sourceRepo`, `targetRepo`, `layoutAffinity`,
|
||||
`layoutIdealLength`, and `layoutElasticity`. Fabric uses these hints to keep
|
||||
same-repo entities closer than cross-repo dependencies. Deployment-to-server
|
||||
edges are intentionally shortest and most elastic; deployment-to-repo edges are
|
||||
longer and looser so infrastructure placement does not collapse into the repo
|
||||
node.
|
||||
|
||||
## Semantic Attractor Modes
|
||||
|
||||
Semantic attractors are view-only topic poles that can pull graph entities
|
||||
toward conceptual neighborhoods in spring-based layouts. For repository maps,
|
||||
an operator might choose attractors such as `security`, `development`, and
|
||||
`operations`; Fabric can then score each repository's semantic closeness to
|
||||
those attractors from repo-owned `SCOPE.md` evidence and map the score to
|
||||
layout strength.
|
||||
|
||||
Attractors are not domain edges and do not change Fabric graph data. They may
|
||||
be materialized as synthetic display-only nodes and `semantic_attraction`
|
||||
edges, or carried as top-level view metadata that the renderer turns into
|
||||
layout forces. Attraction scores should remain inspectable, with source
|
||||
references and confidence, so the operator can understand why a repository was
|
||||
pulled toward a topic.
|
||||
|
||||
Unlike zones, attractors may overlap. A repository can be close to both
|
||||
`development` and `operations`, and the layout should place it between those
|
||||
poles. Zone resolvers, boundary diagnostics, dependency queries, blast-radius
|
||||
queries, and collapsed-zone boundary edges should ignore semantic attraction
|
||||
edges unless a host explicitly promotes an attractor relation into canonical
|
||||
graph data.
|
||||
|
||||
See `docs/semantic-attractors.md` for the concept model, scoring semantics,
|
||||
payload direction, and implementation path.
|
||||
|
||||
## Display State Ownership
|
||||
|
||||
The contract allows either the host service or the engine to evaluate display
|
||||
state.
|
||||
|
||||
The precedence rule is fixed:
|
||||
|
||||
1. Default element state is `show`.
|
||||
2. Rules are applied in list order; later matching rules override earlier
|
||||
matching rules.
|
||||
3. Manual overrides win last.
|
||||
4. Edges connected to hidden nodes are hidden.
|
||||
5. Edges connected to blurred nodes may carry a contextual muted class or data
|
||||
hint.
|
||||
|
||||
Repo-scoping currently evaluates this host-side. A future extracted engine can
|
||||
evaluate it client-side for static exports, but host-provided `displayState`
|
||||
must remain valid input.
|
||||
|
||||
## Fabric Layers
|
||||
|
||||
The first Fabric manifest declares:
|
||||
|
||||
| Layer | Purpose |
|
||||
|-------|---------|
|
||||
| `repository` | Registered source repositories, including registered-only repos. |
|
||||
| `server` | Endpoint hosts inferred from registered interface URLs. |
|
||||
| `deployment` | Service deployment instances per declared environment. |
|
||||
| `service` | Service declarations. |
|
||||
| `capability` | Capability declarations. |
|
||||
| `interface` | Interface declarations. |
|
||||
| `dependency` | Dependency declarations, including unresolved dependency nodes. |
|
||||
| `binding` | Binding assertions between consumer dependencies and providers. |
|
||||
| `library` | Future library/SBOM inventory nodes. |
|
||||
|
||||
## Zone Overlay Modes
|
||||
|
||||
The graph explorer should support zone-oriented modes for Fabric payloads:
|
||||
|
||||
| Mode | Purpose |
|
||||
|------|---------|
|
||||
| `fabric` | Group by financial responsibility: fabric, subfabric, owner. |
|
||||
| `environment` | Group by `dev`, `test`, `prod`, or other deployment environment. |
|
||||
| `deployment-scenario` | Group by concrete scenario such as `bernd-laptop`, `coulombcore`, or `railiance01`. |
|
||||
| `routing-authority` | Group by loopback launcher, Compose port mapping, ingress controller, reverse proxy, DNS, or equivalent route authority. |
|
||||
| `access-zone` | Group by intended reachability such as `private-dev`, `collaborator-test`, `early-access`, `production-public`, or `production-admin`. |
|
||||
|
||||
Zone modes are diagnostic views. They answer "where does this run or who can
|
||||
reach it here?" without mutating the underlying Fabric responsibility boundary.
|
||||
|
||||
Zone boundary overlays are a visual layer over the graph canvas. They should be
|
||||
computed from visible node positions after layout/filtering rather than modeled
|
||||
as graph parent nodes. The overlay should be backed by explicit zone definitions
|
||||
and a resolver so visible nodes are assigned to at most one rendered zone. The
|
||||
default boundary grouping is `deploymentEnvironment`:
|
||||
|
||||
| Overlay label | Matching nodes |
|
||||
|---------------|----------------|
|
||||
| `dev-tegwick` | visible nodes with `deploymentEnvironment: dev` in the private local development overlay |
|
||||
| `test` | visible nodes with `deploymentEnvironment: test` or legacy `staging` |
|
||||
| `prod` | visible nodes with `deploymentEnvironment: prod` |
|
||||
|
||||
Nodes without deployment overlay data are not enclosed. Edge-only deployment
|
||||
overlay evidence may contribute to zone summaries and warnings, but it should
|
||||
not create a boundary unless at least one visible node belongs to the same zone.
|
||||
When access-zone grouping is selected, boundaries use `accessZone` values such
|
||||
as `private-dev`, `collaborator-test`, `production-public`, or
|
||||
`production-admin`.
|
||||
|
||||
Zone labels should be rendered as plain text in the upper-left corner of the
|
||||
zone rectangle, without badge frames or white backgrounds. The label may still
|
||||
act as the zone's focus/drag handle as long as it visually reads as text drawn
|
||||
on the zone surface.
|
||||
|
||||
Useful warnings for the graph explorer include:
|
||||
|
||||
- control surfaces in user-facing access zones;
|
||||
- production nodes with unrestricted developer access;
|
||||
- early-access routes without a policy authority;
|
||||
- services present in production but missing from test;
|
||||
- local-only surfaces that appear in shared or production scenarios;
|
||||
- conflicting port or host claims within the same deployment scenario.
|
||||
|
||||
Zone resolvers should also expose scoped diagnostics in zone detail panels. The
|
||||
initial diagnostic set includes empty zone seed sets, visible nodes matched by
|
||||
multiple zone definitions, and edges crossing zone boundaries. Attraction
|
||||
diagnostics such as multiple attraction candidates or depth-limit stops belong
|
||||
to the same resolver diagnostic channel when attraction rules are enabled.
|
||||
Display-only context edges, such as repository `declares` edges, are evidence
|
||||
for where declarations came from. They must not count as zone boundary
|
||||
connectivity, attraction paths, or collapsed-zone boundary edges unless a host
|
||||
explicitly promotes them to canonical graph relationships.
|
||||
|
||||
Saved graph profiles should persist zone view state as an explicit nested
|
||||
`zone` object. The initial fields are `visible`, `grouping`, `definitionSet`,
|
||||
`presentation`, and `containers`. URL parameters may continue to expose
|
||||
compatibility aliases such as `zoneBoundaries`, `zoneGrouping`, and
|
||||
`zoneDefinitionSet`, but saved profiles should prefer the nested object so
|
||||
future zone definition sets, presentation preferences, and operator-placed zone
|
||||
surfaces can be restored without another state migration.
|
||||
|
||||
Zone containers are view state, not fabric data. A container stores a stable
|
||||
zone surface position and size in graph coordinates. Global graph layout may
|
||||
place unzoned nodes and provide an initial center for new zones, but existing
|
||||
zone containers should keep their operator-chosen positions when the layout
|
||||
algorithm changes. After the global layout pass, each zone may project its
|
||||
assigned visible nodes into local coordinates inside its container. The current
|
||||
local layout choices are compact grid and circle. The selected zone-local
|
||||
layout algorithm belongs in the nested `zone.layout.algorithm` view state so it
|
||||
can be restored by saved or copied views without changing the Fabric payload.
|
||||
|
||||
Zone collapse is a view-only operation. A collapsed zone should hide its visible
|
||||
member nodes, replace them with a synthetic zone node, and draw synthetic
|
||||
boundary edges from that zone node to visible external neighbors. Internal edges
|
||||
are summarized on the zone node rather than rendered. Expanding the zone removes
|
||||
the synthetic elements and restores the original graph elements without
|
||||
changing the underlying payload.
|
||||
|
||||
Zone dragging is also view-only. Dragging a zone handle should translate the
|
||||
currently assigned visible member nodes by the same delta and then recompute the
|
||||
overlay bounds from the new node positions. The operation updates Cytoscape view
|
||||
coordinates only; it does not change Fabric graph data.
|
||||
|
||||
## Repo-Scoping Compatibility
|
||||
|
||||
Repo-scoping can adapt without a rewrite because its current graph payload
|
||||
already exposes most required fields:
|
||||
|
||||
- `id`, `stableKey`, `kind`, `layer`, labels, and metadata-rich data objects.
|
||||
- `displayState`, `visibilitySource`, and `visibilityReason`.
|
||||
- edge `source`, `target`, `dependencyType`, `strength`, `sameLayer`, and
|
||||
visual width.
|
||||
- profile data, filter rules, manual overrides, hidden elements, and orphaned
|
||||
overrides.
|
||||
|
||||
The main adapter work is manifest generation and small field aliases:
|
||||
`dependencyType` can map to `edgeType`, repo-scoping layers become manifest
|
||||
layers, and existing profile endpoints can be listed under manifest
|
||||
`endpoints.profiles`.
|
||||
|
||||
## Extraction Boundary
|
||||
|
||||
The extracted `graph-explorer-engine` should own:
|
||||
|
||||
- graph rendering and layout controls
|
||||
- filter and manual override UI
|
||||
- hover popups and selection detail panels
|
||||
- profile UI when the host declares profile endpoints
|
||||
- browser-local profiles, URL state, and copied state blobs
|
||||
- schema definitions and compatibility tests
|
||||
|
||||
Host repos should own:
|
||||
|
||||
- graph projection and metadata enrichment
|
||||
- host-side profile persistence, when a repo needs shared/team profiles
|
||||
- authentication and authorization
|
||||
- domain-specific graph modes
|
||||
- deep links back to source systems
|
||||
- deployment overlay extraction from the route/proxy/deployment authority they
|
||||
control
|
||||
257
docs/graph-explorer-operations.md
Normal file
257
docs/graph-explorer-operations.md
Normal file
@@ -0,0 +1,257 @@
|
||||
# Graph Explorer Operations And Extraction
|
||||
|
||||
This note closes the operational side of the interactive Fabric map. It records
|
||||
how to launch and refresh the current registry-backed explorer, what has been
|
||||
verified, and how to extract the shared engine once the second adapter is ready.
|
||||
|
||||
## Launch
|
||||
|
||||
List available Make targets from the repo root:
|
||||
|
||||
```bash
|
||||
make
|
||||
```
|
||||
|
||||
Start the registry-backed graph explorer explicitly:
|
||||
|
||||
```bash
|
||||
make graph-explorer
|
||||
```
|
||||
|
||||
This serves the graph explorer at:
|
||||
|
||||
```text
|
||||
http://127.0.0.1:8765/ui/graph-explorer
|
||||
```
|
||||
|
||||
The target defaults to `.railiance-fabric/registry.sqlite3`, host
|
||||
`127.0.0.1`, and port `8765`. Override those when needed:
|
||||
|
||||
```bash
|
||||
make graph-explorer PORT=8876
|
||||
make graph-explorer HOST=0.0.0.0 PORT=8765 REGISTRY_DB=/tmp/railiance-fabric.sqlite3
|
||||
```
|
||||
|
||||
Equivalent raw command:
|
||||
|
||||
```bash
|
||||
railiance-fabric-registry --db .railiance-fabric/registry.sqlite3 --port 8765
|
||||
```
|
||||
|
||||
Useful supporting endpoints:
|
||||
|
||||
```text
|
||||
GET /exports/graph-explorer/manifest
|
||||
GET /exports/graph-explorer
|
||||
GET /status
|
||||
```
|
||||
|
||||
The Fabric manifest currently declares `profile_persistence: local`. Saved map
|
||||
views are stored in browser `localStorage`, URL query parameters carry normal
|
||||
filter state, and copied state URLs include a state blob so manual overrides can
|
||||
be shared without a profile service.
|
||||
|
||||
The refined rule panel is also browser-local. Rules target either nodes or
|
||||
edges, optionally narrow by type and by attributes present on the currently
|
||||
available elements, and then apply one of five modifiers:
|
||||
|
||||
- `show`, `hide`, and `blur` are visibility states.
|
||||
- `highlight` keeps an element visible and adds visual emphasis.
|
||||
- `remove` hides matching elements and excludes them from the next layout run.
|
||||
|
||||
Rules are applied top to bottom. Later matching rules refine earlier matching
|
||||
rules. Manual overrides win after rules except for `remove`, which is treated as
|
||||
stronger because it changes the layout membership. Edges connected to hidden
|
||||
nodes are hidden; edges connected to removed nodes are removed.
|
||||
|
||||
## Refresh
|
||||
|
||||
Refresh this checkout into the running registry:
|
||||
|
||||
```bash
|
||||
railiance-fabric registry sync \
|
||||
--registry-url http://127.0.0.1:8765 \
|
||||
--repo-slug railiance-fabric \
|
||||
.
|
||||
```
|
||||
|
||||
Refresh the known local Railiance repos:
|
||||
|
||||
```bash
|
||||
railiance-fabric registry sync-manifest \
|
||||
registry/railiance-repos.yaml \
|
||||
--registry-url http://127.0.0.1:8765
|
||||
```
|
||||
|
||||
Refresh every locally available active State Hub repo:
|
||||
|
||||
```bash
|
||||
railiance-fabric registry sync-manifest \
|
||||
registry/local-repos.yaml \
|
||||
--registry-url http://127.0.0.1:8765
|
||||
```
|
||||
|
||||
Repos without Fabric declarations remain registered-only. The graph explorer
|
||||
intentionally shows them as onboarding gaps instead of hiding them.
|
||||
|
||||
## Verification
|
||||
|
||||
The automated coverage for this slice lives in `tests/test_graph_explorer.py`:
|
||||
|
||||
- manifest and payload schema validation
|
||||
- registered-only repo projection
|
||||
- `railiance-fabric export --format graph-explorer`
|
||||
- registry API routes for manifest, payload, and UI
|
||||
- static UI wiring for profile controls, rule controls, orientation text, and
|
||||
shared-state support
|
||||
|
||||
Manual smoke checks for a local registry:
|
||||
|
||||
```bash
|
||||
python3 -m pytest
|
||||
python3 -m railiance_fabric.cli validate .
|
||||
```
|
||||
|
||||
Extract and syntax-check the embedded JavaScript when the UI changes:
|
||||
|
||||
```bash
|
||||
python3 -c "from railiance_fabric.graph_explorer_ui import graph_explorer_page; from pathlib import Path; page=graph_explorer_page(); script=page.split(chr(60)+'script'+chr(62))[1].split(chr(60)+'/script'+chr(62))[0]; Path('/tmp/graph-ui-script.js').write_text(script, encoding='utf-8')"
|
||||
node --check /tmp/graph-ui-script.js
|
||||
```
|
||||
|
||||
With the registry running, confirm that the served manifest reports local
|
||||
profiles:
|
||||
|
||||
```bash
|
||||
curl -s http://127.0.0.1:8765/exports/graph-explorer/manifest
|
||||
```
|
||||
|
||||
## Extraction Decision
|
||||
|
||||
Recommendation: keep the shell in `railiance-fabric` until the repo-scoping
|
||||
adapter is implemented against the same manifest and payload schemas. Extract
|
||||
after two hosts are proven:
|
||||
|
||||
- Fabric registry map
|
||||
- repo-scoping dependency graph
|
||||
|
||||
Recommended repository name: `graph-explorer-engine`.
|
||||
|
||||
The extracted repository should own:
|
||||
|
||||
- `GraphExplorerManifest` and `GraphExplorerPayload` schemas
|
||||
- static graph explorer assets and mount/bootstrap code
|
||||
- display-state and rule evaluation helpers for hosts that want client-side
|
||||
rules, including `show`, `hide`, `blur`, `highlight`, and `remove`
|
||||
- browser-local profile handling, URL state, copied state blobs, and profile UI
|
||||
- Cytoscape rendering, layouts, hover popups, detail panels, focus modes, and
|
||||
manual override controls
|
||||
- conformance fixtures proving Fabric and repo-scoping payloads both load
|
||||
|
||||
Host repositories should keep:
|
||||
|
||||
- graph projection and domain metadata enrichment
|
||||
- host vocabulary and manifest labels for node types, edge types, rule fields,
|
||||
modes, and orientation terms
|
||||
- host-side profile persistence, when shared/team profiles are required
|
||||
- authentication, authorization, and deployment
|
||||
- domain-specific modes and deep links
|
||||
- registry or analysis service APIs
|
||||
|
||||
## Adapter Readiness Notes
|
||||
|
||||
The refined shell is closer to extraction, but these Fabric-specific assumptions
|
||||
should be made manifest-driven or host-adapted before `graph-explorer-engine`
|
||||
becomes a separate repo:
|
||||
|
||||
- The shell still expects the internal element type field to be named `layer`.
|
||||
User-facing text now says nodes and node types, but the shared contract should
|
||||
either rename this to `nodeType` or declare the field through
|
||||
`manifest.identity`.
|
||||
- Node shapes are hardcoded against Fabric node type ids such as `repository`,
|
||||
`service`, `deployment`, `server`, `capability`, `interface`, `dependency`,
|
||||
`binding`, and `library`.
|
||||
- Rule-builder attributes are derived from a fixed allowlist. Repo-scoping can
|
||||
use the model, but the allowlist should move to manifest filter fields so a
|
||||
host can expose facts, evidence, confidence, freshness, scope, ability, or
|
||||
other domain attributes without changing engine code.
|
||||
- Mode behavior is hardcoded for Fabric's `onboarding-gaps`, `unresolved`,
|
||||
`selected-path`, and `neighborhood` semantics. The reusable engine should
|
||||
either provide generic selectors or let hosts define mode predicates.
|
||||
- The orientation panel still contains Fabric-specific renderers for
|
||||
repositories, services, interfaces, dependencies, and capabilities. This
|
||||
should stay host-owned or become a manifest-provided details adapter.
|
||||
- The default detail rows know about `source`, `target`, `edgeType`, `strength`,
|
||||
deep links, and source references. That is acceptable as a shared baseline,
|
||||
but host-specific row ordering should be manifest-driven.
|
||||
|
||||
The current rule-panel data model is compatible with repo-scoping if repo-scoping
|
||||
maps its graph elements into the same basic shape:
|
||||
|
||||
```json
|
||||
{
|
||||
"target": "node",
|
||||
"type": "fact",
|
||||
"attribute": "reviewState",
|
||||
"value": "candidate",
|
||||
"action": "blur"
|
||||
}
|
||||
```
|
||||
|
||||
For extraction, prefer repo-scoping adapter parity as the next workplan. One
|
||||
more Fabric-side polish pass is still useful for orientation workflows, but it
|
||||
does not need to block proving the second host.
|
||||
|
||||
Suggested public API:
|
||||
|
||||
```ts
|
||||
type GraphExplorerManifest = unknown;
|
||||
type GraphExplorerPayload = unknown;
|
||||
|
||||
mountGraphExplorer({
|
||||
container,
|
||||
manifestUrl,
|
||||
graphUrl,
|
||||
initialState,
|
||||
}: {
|
||||
container: HTMLElement;
|
||||
manifestUrl: string;
|
||||
graphUrl?: string;
|
||||
initialState?: Record<string, unknown>;
|
||||
}): Promise<{ destroy(): void }>;
|
||||
```
|
||||
|
||||
Schema ownership should move to `graph-explorer-engine` at extraction time.
|
||||
Fabric should then pin an engine schema version and keep its projection tests as
|
||||
adapter conformance tests.
|
||||
|
||||
## Repo-Scoping Adapter Parity Checklist
|
||||
|
||||
Before extraction, repo-scoping should prove that the shared shell can consume
|
||||
its RREG-WP-0010/RREG-WP-0011 behavior:
|
||||
|
||||
- expose a manifest with repo-scoping layers, filter fields, modes, and profile
|
||||
endpoint capabilities
|
||||
- preserve existing stable keys for facts, evidence, features, capabilities,
|
||||
abilities, scopes, and edges
|
||||
- map `dependencyType` to `edgeType`
|
||||
- carry display states of `show`, `blur`, and `hide`
|
||||
- retain confidence sizing, edge strength sizing, same-layer hints, and review
|
||||
state
|
||||
- preserve manual overrides and hidden/orphaned override recovery semantics
|
||||
- support profile create, update, duplicate, delete, and latest-default loading
|
||||
through host endpoints
|
||||
- keep hover popups, selection details, selected-path, and neighborhood focus
|
||||
- add adapter fixtures that validate against the shared schemas
|
||||
|
||||
## Migration Steps
|
||||
|
||||
1. Add a repo-scoping manifest endpoint or static manifest fixture.
|
||||
2. Add shared conformance fixtures for one Fabric graph and one repo-scoping
|
||||
graph.
|
||||
3. Move the static UI shell and schemas into `graph-explorer-engine`.
|
||||
4. Replace Fabric's local HTML generator with an engine asset route plus Fabric
|
||||
manifest/payload URLs.
|
||||
5. Replace repo-scoping's bespoke shell with the same engine mount.
|
||||
6. Keep both host test suites validating their projections against the engine
|
||||
schemas.
|
||||
84
docs/graph-explorer-transfer-review.md
Normal file
84
docs/graph-explorer-transfer-review.md
Normal file
@@ -0,0 +1,84 @@
|
||||
# Graph Explorer Transfer Review
|
||||
|
||||
This note closes the first implementation step for `RAIL-FAB-WP-0008-T01`.
|
||||
It reviews the repo-scoping dependency graph work from `RREG-WP-0010` and
|
||||
`RREG-WP-0011` and turns the transferable parts into Fabric requirements.
|
||||
|
||||
## Source Implementation
|
||||
|
||||
Repo-scoping already has a useful graph explorer shape:
|
||||
|
||||
- `docs/adr-dependency-graph-visualization-framework.md` chooses Cytoscape.js
|
||||
because the required interaction model is graph-native: pan, zoom, selection,
|
||||
layouts, styling, filtering, and path exploration.
|
||||
- `docs/dependency-visualization-exploration.md` defines layered graph data,
|
||||
`show` / `blur` / `hide` display states, deterministic filters, manual
|
||||
overrides, and saved view profiles.
|
||||
- `src/repo_scoping/core/service.py` emits Cytoscape-compatible payloads with
|
||||
stable keys, metadata-rich node and edge data, visibility state, hidden
|
||||
elements, profile application, confidence sizing, and edge strength sizing.
|
||||
- `src/repo_scoping/web_ui/views.py` provides the first UI shell: profile
|
||||
controls, structured filters, manual overrides, focus depth, hover popups,
|
||||
selection details, and a layered layout.
|
||||
- `tests/test_web_api.py` verifies graph endpoints, ad hoc filters, profile
|
||||
creation, duplicate profiles, latest-profile defaulting, and UI wiring.
|
||||
|
||||
## Reusable Behaviors
|
||||
|
||||
Fabric should carry these behaviors into the shared graph explorer contract:
|
||||
|
||||
- Cytoscape-compatible element arrays with `data` and optional `classes`.
|
||||
- Stable element keys that survive refreshes, so layout state, profile rules,
|
||||
and deep links do not churn.
|
||||
- Metadata-rich nodes and edges rather than UI-only labels.
|
||||
- Explicit `layer`, `kind`, `reviewState`, `freshnessState`, and
|
||||
`displayState` fields.
|
||||
- Visibility actions of `show`, `blur`, and `hide`, with later rules overriding
|
||||
earlier rules and manual overrides winning last.
|
||||
- Hidden element reporting, so over-filtered views are recoverable.
|
||||
- Edge treatment for context-muted nodes.
|
||||
- View profiles that can persist filter rules and manual overrides when a host
|
||||
provides profile endpoints.
|
||||
- Hover popups for compact inspection and selection panels for full detail.
|
||||
- Layout modes for full graph, impact or filtered graph, selected path, and
|
||||
neighborhood focus.
|
||||
- Visual hints for confidence, strength, same-layer edges, stale or unresolved
|
||||
state, and review state.
|
||||
|
||||
## Adapter-Owned Semantics
|
||||
|
||||
These repo-scoping concepts should remain in the repo-scoping adapter and not
|
||||
be hard-coded into the engine:
|
||||
|
||||
- Layer names of `fact`, `evidence`, `feature`, `capability`, `ability`, and
|
||||
`scope`.
|
||||
- Candidate graph approval semantics.
|
||||
- Dependency impact analysis over base and target analysis runs.
|
||||
- Document fact normalization and README/SCOPE de-duplication.
|
||||
- Scope curation recommendations.
|
||||
|
||||
Fabric has its own adapter semantics:
|
||||
|
||||
- Layer names of `repository`, `service`, `capability`, `interface`,
|
||||
`dependency`, `binding`, and `library`.
|
||||
- Registered-only repositories without accepted graph snapshots.
|
||||
- State Hub repo ids, workplan links, and registry endpoints as deep links.
|
||||
- Unresolved dependencies where provider bindings are missing or disputed.
|
||||
- Blast-radius and provider-chain exploration across accepted Fabric
|
||||
declarations.
|
||||
|
||||
## Extraction Recommendation
|
||||
|
||||
Start in `railiance-fabric` with a host-neutral manifest and payload contract,
|
||||
plus a Fabric registry projection. The first UI shell can live locally while
|
||||
the contract is still moving.
|
||||
|
||||
Extract into a separate repository only after two host adapters are proven:
|
||||
|
||||
1. Fabric registry map adapter.
|
||||
2. Repo-scoping dependency graph adapter.
|
||||
|
||||
The likely extracted repository is `graph-explorer-engine`. It should own the
|
||||
static interaction shell, schema definitions, layout/filter/profile client
|
||||
logic, and adapter manifest contract. Host repos should keep graph projection,
|
||||
profile persistence, authentication, and domain-specific deep links.
|
||||
136
docs/operational-rescan-loops.md
Normal file
136
docs/operational-rescan-loops.md
Normal file
@@ -0,0 +1,136 @@
|
||||
# Operational Rescan Loops
|
||||
|
||||
`registry scan-manifest` is the operational entry point for repeated repo
|
||||
reality scans. It can run safely as a dry-run, keep local baselines, reconcile
|
||||
against registry-stored discovery snapshots, write a run report, and optionally
|
||||
ingest or accept reviewed discovery output.
|
||||
|
||||
## Local Cache
|
||||
|
||||
By default, manifest scans use a local runtime directory beside the manifest:
|
||||
|
||||
```text
|
||||
.fabric-discovery/
|
||||
snapshots/
|
||||
<repo-slug>-<profile>.discovery.json
|
||||
reports/
|
||||
<timestamp>-<profile>.rescan-report.json
|
||||
rescan.lock
|
||||
```
|
||||
|
||||
This directory is ignored by git. It is operator/runtime state, not source. Use
|
||||
`--cache-dir` to place it elsewhere, `--output-dir` and `--previous-dir` for
|
||||
explicit snapshot locations, or `--no-cache` when a run should only write
|
||||
explicit outputs.
|
||||
|
||||
## Standard Dry-Run
|
||||
|
||||
```bash
|
||||
railiance-fabric registry scan-manifest registry/local-repos.yaml \
|
||||
--repo-slug railiance-fabric \
|
||||
--dry-run
|
||||
```
|
||||
|
||||
The first run is a baseline. Later runs use the cached snapshot directory by
|
||||
default and report `unchanged`, `changed`, or `review_required` per repo.
|
||||
|
||||
## Registry-Backed Rescan
|
||||
|
||||
Use the registry as the durable previous source:
|
||||
|
||||
```bash
|
||||
railiance-fabric registry scan-manifest registry/local-repos.yaml \
|
||||
--repo-slug railiance-fabric \
|
||||
--previous-from-registry \
|
||||
--dry-run
|
||||
```
|
||||
|
||||
When `--ingest` is enabled, unchanged snapshots are skipped by default to avoid
|
||||
registry churn. Use `--ingest-unchanged` only when a full audit trail of every
|
||||
run is required.
|
||||
|
||||
## Reports
|
||||
|
||||
Every cached scan writes a `FabricDiscoveryRescanReport`. The schema is
|
||||
`schemas/rescan-run-report.schema.yaml`. Reports include:
|
||||
|
||||
- manifest, registry URL, profile, cache paths, and scanner version
|
||||
- selected repos and LLM budget policy
|
||||
- previous snapshot source/id/path per repo
|
||||
- candidate counts, diff counts, review artifacts, connector runs, and errors
|
||||
- discovery snapshot ids and accepted graph snapshot ids when registry writes
|
||||
occur
|
||||
|
||||
Use `--report-output` for a specific path. Use `--json` to print the same report
|
||||
shape to stdout.
|
||||
|
||||
## Acceptance Policy
|
||||
|
||||
`--accept` requires `--ingest`. The default `--accept-policy safe` only projects
|
||||
candidates with `review_state: accepted` and blocks projection when the scan has
|
||||
conflicts, tombstones, or low-confidence LLM artifacts. Use
|
||||
`--accept-policy explicit` only for deliberate manual overrides, such as
|
||||
selected keys or non-default review states.
|
||||
|
||||
## Automation Mode
|
||||
|
||||
For cron or automation, use:
|
||||
|
||||
```bash
|
||||
railiance-fabric registry scan-manifest registry/local-repos.yaml \
|
||||
--previous-from-registry \
|
||||
--dry-run \
|
||||
--exit-code-mode operational
|
||||
```
|
||||
|
||||
Operational exit codes:
|
||||
|
||||
- `0`: no changes and no review/failure
|
||||
- `2`: baseline or changed repo reality detected
|
||||
- `3`: review required
|
||||
- `4`: one or more repo failures
|
||||
- `5`: rescan lock already exists
|
||||
|
||||
The command creates a lock file under the cache directory by default. Use
|
||||
`--lock-file` for an explicit lock path or `--no-lock` when an outer scheduler
|
||||
already provides overlap protection.
|
||||
|
||||
## Rescan Status
|
||||
|
||||
The registry exposes latest discovery health in `/status` and per-repo
|
||||
inventory. The CLI view is:
|
||||
|
||||
```bash
|
||||
railiance-fabric registry rescan-status --review-only
|
||||
```
|
||||
|
||||
Use `--stale-after-hours <n>` to show snapshots older than an operational
|
||||
freshness window.
|
||||
|
||||
## First Rollout
|
||||
|
||||
The first controlled loop should stay small:
|
||||
|
||||
```bash
|
||||
railiance-fabric registry scan-manifest registry/local-repos.yaml \
|
||||
--repo-slug repo-scoping \
|
||||
--repo-slug llm-connect \
|
||||
--repo-slug railiance-fabric \
|
||||
--previous-from-registry \
|
||||
--dry-run
|
||||
```
|
||||
|
||||
If the report shows clean baselines or expected changes, rerun with `--ingest`
|
||||
to store the baseline discovery snapshots. Broader all-local-repo rollout
|
||||
should wait until the small loop is repeatable and the review queue is readable.
|
||||
|
||||
Initial implementation rollout on 2026-05-20:
|
||||
|
||||
- Registry-backed previous lookup correctly reported per-repo failures while
|
||||
the local registry service on `127.0.0.1:8765` was offline.
|
||||
- Local-cache dry-run completed for `repo-scoping`, `llm-connect`, and
|
||||
`railiance-fabric`.
|
||||
- Result: 3 scanned, 2 baseline, 1 changed, 7 conflicted, 1 review required,
|
||||
0 errors.
|
||||
- Follow-up: review `repo-scoping` conflicts before accepting or ingesting a
|
||||
broad baseline.
|
||||
126
docs/registry-api.md
Normal file
126
docs/registry-api.md
Normal file
@@ -0,0 +1,126 @@
|
||||
# Registry API
|
||||
|
||||
The Railiance Fabric registry is a small HTTP API over accepted Fabric graph
|
||||
snapshots, discovery evidence, reset archives, and supporting inventory.
|
||||
Legacy repo-local declarations can still produce snapshots, but they are
|
||||
evidence for the graph rather than the long-term authority for external
|
||||
deployment, ownership, tenant, or utility relations.
|
||||
|
||||
## Health And Status
|
||||
|
||||
```text
|
||||
GET /health
|
||||
GET /status
|
||||
```
|
||||
|
||||
`/health` is intentionally tiny. `/status` includes database path, table counts,
|
||||
and the latest accepted snapshot per repository.
|
||||
|
||||
## Repository Snapshots
|
||||
|
||||
```text
|
||||
POST /repositories
|
||||
GET /repositories
|
||||
GET /repositories/{repo_slug}
|
||||
GET /repositories/{repo_slug}/inventory
|
||||
POST /repositories/{repo_slug}/snapshots
|
||||
GET /repositories/{repo_slug}/snapshots
|
||||
GET /repositories/{repo_slug}/snapshots/latest
|
||||
GET /repositories/{repo_slug}/snapshots/diff
|
||||
```
|
||||
|
||||
Snapshot ingestion accepts a `FabricGraphExport` under `graph` plus `commit`
|
||||
and optional `generated_at`. The registry accepts both legacy
|
||||
`railiance.fabric/v1alpha1` graph exports and the financial
|
||||
`railiance.fabric/v1alpha2` / `financial-fabric-v1` export contract.
|
||||
|
||||
## Discovery Snapshots
|
||||
|
||||
```text
|
||||
POST /repositories/{repo_slug}/discovery-snapshots
|
||||
GET /repositories/{repo_slug}/discovery-snapshots
|
||||
GET /repositories/{repo_slug}/discovery-snapshots/latest
|
||||
GET /repositories/{repo_slug}/discovery-snapshots/diff
|
||||
GET /repositories/{repo_slug}/discovery-snapshots/{snapshot_id}
|
||||
POST /repositories/{repo_slug}/discovery-snapshots/{snapshot_id}/accept
|
||||
```
|
||||
|
||||
Discovery ingestion accepts a `FabricDiscoverySnapshot`. Snapshots are stored by
|
||||
repo, commit, and scan profile for dry-run review. Discovery diffs include
|
||||
candidate additions, removals, changes, confidence changes, reconciliation
|
||||
conflicts, and scoped retirements.
|
||||
|
||||
Acceptance projects only explicitly accepted discovery candidates into a normal
|
||||
`FabricGraphExport` snapshot. Existing graph nodes are preserved, so repo-owned
|
||||
declarations are not overwritten by discovery output. Projected nodes carry
|
||||
discovery provenance, review state, confidence, and source anchors in their
|
||||
attributes; graph explorer exports surface that metadata.
|
||||
|
||||
CLI helpers:
|
||||
|
||||
```bash
|
||||
railiance-fabric registry ingest-discovery discovery.json \
|
||||
--repo-slug railiance-fabric
|
||||
|
||||
railiance-fabric registry accept-discovery railiance-fabric 12 \
|
||||
--accepted-key discovery:railiance-fabric:service-declaration:example
|
||||
```
|
||||
|
||||
## Graph Queries
|
||||
|
||||
```text
|
||||
GET /graph/nodes
|
||||
GET /graph/nodes/{graph_id}
|
||||
GET /graph/providers?capability_type=runtime-secrets
|
||||
GET /graph/consumers?target=railiance-platform.openbao.kv-v2
|
||||
GET /graph/unresolved
|
||||
GET /graph/blast-radius?interface_id=openbao-kv-v2-mount
|
||||
GET /graph/dependency-path?service_id=flex-auth.api
|
||||
GET /search?q=jsonschema
|
||||
```
|
||||
|
||||
## Artifacts And Libraries
|
||||
|
||||
```text
|
||||
POST /artifacts
|
||||
GET /artifacts
|
||||
GET /artifacts/{artifact_id}
|
||||
GET /libraries
|
||||
GET /libraries/{library_id}
|
||||
GET /repositories/{repo_slug}/libraries
|
||||
POST /repositories/{repo_slug}/libraries/cyclonedx
|
||||
```
|
||||
|
||||
CycloneDX ingestion replaces the repo's current library inventory with the
|
||||
components and services in the submitted SBOM.
|
||||
|
||||
## Exports
|
||||
|
||||
```text
|
||||
GET /exports/state-hub
|
||||
GET /exports/backstage
|
||||
GET /exports/xregistry
|
||||
GET /exports/libraries/xregistry
|
||||
GET /ui/graph-explorer
|
||||
GET /exports/graph-explorer/manifest
|
||||
GET /exports/graph-explorer
|
||||
GET /exports/reset-archive
|
||||
```
|
||||
|
||||
`GET /exports/state-hub` currently serves the accepted combined graph for the
|
||||
State Hub read model. During the financial reset, keep using the legacy shape
|
||||
for existing State Hub views until `STATE-WP-0051` materializes v1alpha2
|
||||
fields. Use `railiance-fabric export --format financial` and
|
||||
`examples/exports/financial-fabric-v1.json` as the vNext contract references.
|
||||
|
||||
## Guarded Reset
|
||||
|
||||
```text
|
||||
POST /admin/reset-graph-data
|
||||
```
|
||||
|
||||
The reset endpoint requires `confirm`,
|
||||
`reason`, and `archive_sha256`. `confirm` must be
|
||||
`RESET-RAILIANCE-FABRIC-GRAPH-DATA`. Operators should prefer the CLI wrapper
|
||||
documented in `docs/registry-reset-operations.md`, because it exports the
|
||||
archive and computes the checksum before calling the destructive endpoint.
|
||||
90
docs/registry-onboarding.md
Normal file
90
docs/registry-onboarding.md
Normal file
@@ -0,0 +1,90 @@
|
||||
# Registry Onboarding
|
||||
|
||||
Multi-repo onboarding uses an operator-owned manifest to register ecosystem
|
||||
repositories with a running Railiance Fabric registry and to push graph and
|
||||
library inventory when the local checkout has the required inputs.
|
||||
|
||||
Repo-local declarations remain useful self-description evidence. They should
|
||||
not be treated as the default authority for external fabric membership,
|
||||
ownership, tenant boundaries, or cross-boundary utility relations. Those belong
|
||||
to the accountability-root discovery model described in
|
||||
`docs/FabricDiscoveryAndUpdate.md`.
|
||||
|
||||
## Run The Railiance Manifest
|
||||
|
||||
Start the registry:
|
||||
|
||||
```bash
|
||||
railiance-fabric-registry --db .railiance-fabric/registry.sqlite3 --port 8765
|
||||
```
|
||||
|
||||
Sync the known local Railiance ecosystem repos:
|
||||
|
||||
```bash
|
||||
railiance-fabric registry sync-manifest registry/railiance-repos.yaml
|
||||
```
|
||||
|
||||
Sync every active State Hub repo that is available on this local host:
|
||||
|
||||
```bash
|
||||
railiance-fabric registry sync-manifest registry/local-repos.yaml
|
||||
```
|
||||
|
||||
Use `--json` for automation and `--strict` when unavailable repos or invalid
|
||||
inputs should fail the command.
|
||||
|
||||
## Manifest Shape
|
||||
|
||||
```yaml
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: RegistryOnboardingManifest
|
||||
registry_url: http://127.0.0.1:8765
|
||||
repositories:
|
||||
- slug: railiance-fabric
|
||||
name: railiance-fabric
|
||||
path: ..
|
||||
default_branch: main
|
||||
state_hub_repo_id: 2c0de614-e468-4eb6-8157-470649ac8c05
|
||||
declaration_paths:
|
||||
- ..
|
||||
sbom: bom.json
|
||||
```
|
||||
|
||||
`path` is the local checkout used for git metadata and default graph discovery.
|
||||
`declaration_paths` is optional; when omitted, the repo path is scanned for a
|
||||
`fabric/` directory. Relative paths are resolved from the manifest file.
|
||||
|
||||
`sbom` or `sboms` may point to CycloneDX JSON/YAML files. When present, the
|
||||
command ingests them as queryable library inventory after repository
|
||||
registration.
|
||||
|
||||
## Onboarding Behavior
|
||||
|
||||
Each repository entry is registered first. If the checkout is unavailable or has
|
||||
no Fabric declarations yet, the command leaves the repo registered and reports a
|
||||
warning. This lets the registry represent known repos before every repo has
|
||||
published local evidence.
|
||||
|
||||
When declarations exist, the command validates them, builds a graph snapshot,
|
||||
and posts it to:
|
||||
|
||||
```text
|
||||
POST /repositories/{repo_slug}/snapshots
|
||||
```
|
||||
|
||||
The first Railiance manifest keeps the seed ecosystem graph in
|
||||
`railiance-fabric` and registers adjacent repos as known sources. As discovery
|
||||
roots mature, adjacent repos can contribute local evidence without making each
|
||||
repo responsible for the whole external fabric relation model.
|
||||
|
||||
`registry/local-repos.yaml` is a broader local-host manifest. It is generated
|
||||
from active State Hub repo records whose local path exists on the current WSL
|
||||
host. It registers cross-domain local repos into the Fabric registry while only
|
||||
syncing graph snapshots for repos that already have Fabric declarations.
|
||||
|
||||
When two active repo records point at the same checkout path, accountability
|
||||
root discovery treats them as aliases of one repository identity. The canonical
|
||||
identity can be declared with `canonical_slug`; otherwise discovery prefers the
|
||||
slug matching the checkout directory name and then the entry with a remote URL.
|
||||
Use `split_identity: true` only when shared paths are intentional and should
|
||||
remain separate review candidates.
|
||||
61
docs/registry-reset-operations.md
Normal file
61
docs/registry-reset-operations.md
Normal file
@@ -0,0 +1,61 @@
|
||||
# Registry Reset Operations
|
||||
|
||||
RAIL-FAB-WP-0016 allows a destructive registry graph reset, but only after an
|
||||
archive has been produced and the operator uses an explicit confirmation token.
|
||||
|
||||
## Export Archive Only
|
||||
|
||||
```bash
|
||||
railiance-fabric registry export-reset-archive \
|
||||
.railiance-fabric/reset-archive.json \
|
||||
--registry-url http://127.0.0.1:8765
|
||||
```
|
||||
|
||||
The archive contains:
|
||||
|
||||
- repository registrations,
|
||||
- current combined graph export,
|
||||
- stored graph snapshots,
|
||||
- discovery snapshots and accepted graph snapshot links,
|
||||
- artifacts,
|
||||
- library inventory,
|
||||
- prior reset events,
|
||||
- rollback notes.
|
||||
|
||||
## Guarded Reset
|
||||
|
||||
```bash
|
||||
railiance-fabric registry reset-graph-data \
|
||||
--registry-url http://127.0.0.1:8765 \
|
||||
--archive .railiance-fabric/reset-archive.json \
|
||||
--confirm RESET-RAILIANCE-FABRIC-GRAPH-DATA \
|
||||
--reason "canon-aligned graph reset before full reingest"
|
||||
```
|
||||
|
||||
The command first writes the archive, computes its SHA-256, then calls the
|
||||
registry reset endpoint. The registry records a reset event with the archive
|
||||
path, archive checksum, reason, and dropped row counts.
|
||||
|
||||
The reset deletes graph snapshots, discovery snapshots, artifacts, and library
|
||||
inventory. Repository registration rows are preserved so reingest can start
|
||||
from the known repo list.
|
||||
|
||||
## Rollback Limits
|
||||
|
||||
The archive is a JSON evidence bundle, not an automatic SQLite restore. Use it
|
||||
to inspect or manually reinsert prior registry data if needed. After reset, the
|
||||
intended source of truth is a fresh scan and acceptance pass from accountability
|
||||
roots using the financial Fabric model. The current bridge is the Railiance
|
||||
baseline projection:
|
||||
|
||||
```bash
|
||||
railiance-fabric validate .
|
||||
railiance-fabric export --format financial
|
||||
railiance-fabric registry sync --repo-slug railiance-fabric .
|
||||
```
|
||||
|
||||
Use repo-local declarations as evidence during reingest, not as the authority
|
||||
for all external ownership, tenant, or utility relations.
|
||||
|
||||
Do not run the reset until the replacement scanner/projection path has passed
|
||||
validation and a sample reingest review.
|
||||
484
docs/repo-reality-scanner.md
Normal file
484
docs/repo-reality-scanner.md
Normal file
@@ -0,0 +1,484 @@
|
||||
# Repo Reality Scanner
|
||||
|
||||
The repo reality scanner discovers Fabric entities from repository evidence and
|
||||
turns them into candidate graph facts. It is a discovery layer, not a new
|
||||
authoring surface. Repo-owned declarations remain high-trust self-description
|
||||
evidence, but financial Fabric ownership, tenant boundaries, and cross-boundary
|
||||
utility relations must be resolved from accountability roots or review
|
||||
decisions before they become accepted graph data.
|
||||
|
||||
## Contract
|
||||
|
||||
A scanner run emits a `FabricDiscoverySnapshot`. The snapshot is scoped to one
|
||||
repository, one commit, and one scan profile. It contains:
|
||||
|
||||
- replacement scopes, which define the evidence sets that may be replaced on a
|
||||
rescan
|
||||
- candidate nodes, edges, and attributes
|
||||
- source anchors for every candidate
|
||||
- extractor provenance for every candidate
|
||||
- tombstones for candidates that vanished inside a replacement scope
|
||||
- reconciliation policy metadata
|
||||
|
||||
The JSON schema lives at `schemas/discovery-snapshot.schema.yaml`.
|
||||
|
||||
## Deterministic Scanner CLI
|
||||
|
||||
The first implementation slice adds an offline deterministic scan command:
|
||||
|
||||
```bash
|
||||
railiance-fabric scan . \
|
||||
--repo-slug railiance-fabric \
|
||||
--commit "$(git rev-parse HEAD)" \
|
||||
--dry-run \
|
||||
--output discovery-snapshot.json
|
||||
```
|
||||
|
||||
Use `--json` to print the full `FabricDiscoverySnapshot` to stdout. Without
|
||||
`--json`, the command prints a concise summary of node, edge, attribute, and
|
||||
replacement-scope counts. The scanner does not call registries, catalogs, or
|
||||
LLMs in this mode; `--output` is the only write side effect.
|
||||
|
||||
The deterministic extractor framework currently covers:
|
||||
|
||||
- repository metadata from local git/path evidence
|
||||
- README, INTENT, and SCOPE document presence and headings
|
||||
- repo-owned Fabric declarations under `fabric/`
|
||||
- Python `pyproject.toml` package metadata and dependencies
|
||||
- Node `package.json` package metadata and dependencies
|
||||
- common lockfiles such as `package-lock.json`, `poetry.lock`, and `uv.lock`
|
||||
- Dockerfiles and Docker Compose services
|
||||
- OpenAPI and AsyncAPI contract files
|
||||
- Score workload files
|
||||
- Kubernetes-style deployment manifests
|
||||
- common service config files such as `application.yaml` and
|
||||
`appsettings.json`
|
||||
|
||||
Each extractor emits candidates through the same accumulator so stable-key
|
||||
duplicates merge inside a scan before the snapshot is returned.
|
||||
|
||||
## LLM-Assisted Extraction
|
||||
|
||||
LLM extraction is optional and explicit:
|
||||
|
||||
```bash
|
||||
railiance-fabric scan . \
|
||||
--repo-slug railiance-fabric \
|
||||
--llm \
|
||||
--llm-provider openai \
|
||||
--llm-model gpt-4.1-mini \
|
||||
--dry-run \
|
||||
--output discovery-with-llm.json
|
||||
```
|
||||
|
||||
The implementation integrates through `llm-connect` with `create_adapter` and
|
||||
`RunConfig`. Tests use a `MockLLMAdapter`-compatible boundary so CI stays
|
||||
offline. If `llm-connect` is unavailable, the provider call fails, or the model
|
||||
returns malformed JSON, the scanner records a `review_artifacts` entry and keeps
|
||||
the discovery snapshot schema-valid.
|
||||
|
||||
The LLM never receives the whole repository. The scanner first builds a compact
|
||||
evidence bundle from deterministic candidates, prioritizing durable local
|
||||
evidence such as Fabric declarations, services, capabilities, interfaces,
|
||||
libraries, deployments, and small README/INTENT/SCOPE signals. The prompt asks
|
||||
for strict JSON:
|
||||
|
||||
```json
|
||||
{"nodes": [], "edges": [], "attributes": []}
|
||||
```
|
||||
|
||||
Projected LLM candidates are always `origin: llm` and
|
||||
`review_state: needs_review`. Candidates below the configured confidence
|
||||
threshold become `llm_low_confidence` review artifacts instead of graph
|
||||
candidates. Unresolved edge endpoints or attribute targets also become review
|
||||
artifacts. Accepted graph data still requires deterministic evidence,
|
||||
repo-owned declarations, or a later human review/acceptance path.
|
||||
|
||||
## Reconciliation And Dry-Run Diffs
|
||||
|
||||
Scans can be reconciled against a previous discovery snapshot:
|
||||
|
||||
```bash
|
||||
railiance-fabric scan . \
|
||||
--repo-slug railiance-fabric \
|
||||
--previous-snapshot previous-discovery.json \
|
||||
--dry-run \
|
||||
--output current-discovery.json
|
||||
```
|
||||
|
||||
The reconciler writes `reconciliation.diff` with explicit stable-key sets:
|
||||
|
||||
- `added`
|
||||
- `changed`
|
||||
- `retired`
|
||||
- `conflicted`
|
||||
|
||||
It deduplicates candidates by stable key, merges source anchors and provenance,
|
||||
and applies source-aware precedence when duplicate candidates disagree. The
|
||||
current precedence is:
|
||||
|
||||
1. `repo_declaration`
|
||||
2. `deterministic`
|
||||
3. `catalog`
|
||||
4. `registry`
|
||||
5. `llm`
|
||||
6. `manual`
|
||||
|
||||
Possible duplicates found through matching aliases, normalized labels,
|
||||
relationship endpoints, or attribute targets are not silently merged. They are
|
||||
marked `status: conflicted`, moved to `review_state: needs_review`, and listed
|
||||
under `reconciliation.conflicts`.
|
||||
|
||||
Missing previous candidates become tombstones only when their replacement scope
|
||||
is present in the current scan and has `mode: replacement`. Missing candidates
|
||||
from additive scopes, such as broad LLM evidence bundles, are left alone.
|
||||
Existing tombstones are preserved so repeated scans can explain graph drift.
|
||||
|
||||
## Registry Review And Acceptance
|
||||
|
||||
Discovery snapshots can be stored in the Fabric registry for review:
|
||||
|
||||
```bash
|
||||
railiance-fabric scan . \
|
||||
--repo-slug railiance-fabric \
|
||||
--previous-snapshot previous-discovery.json \
|
||||
--output discovery.json
|
||||
|
||||
railiance-fabric registry ingest-discovery discovery.json \
|
||||
--repo-slug railiance-fabric
|
||||
```
|
||||
|
||||
The registry keeps discovery snapshots separately from accepted graph snapshots
|
||||
by repo, commit, and scan profile. It exposes latest/list/diff API routes so a
|
||||
dry run can be reviewed without changing the accepted graph.
|
||||
|
||||
Accepted discovery can be projected into a normal graph snapshot:
|
||||
|
||||
```bash
|
||||
railiance-fabric registry accept-discovery railiance-fabric 12 \
|
||||
--accepted-key discovery:railiance-fabric:service-declaration:example
|
||||
```
|
||||
|
||||
By default, the accept path only projects candidates already marked
|
||||
`review_state: accepted`. Passing `--accepted-key` explicitly includes selected
|
||||
candidate stable keys. Existing accepted graph nodes win over discovery nodes
|
||||
with the same graph id, so repo-owned declarations are preserved. Projected
|
||||
nodes carry discovery stable key, origin, review state, confidence, provenance,
|
||||
and source anchors in graph attributes; the graph explorer payload exposes
|
||||
those fields for review. For financial Fabric fields, accepted discovery still
|
||||
needs an accountability-root, baseline inheritance rule, or explicit review
|
||||
decision.
|
||||
|
||||
## Connector Follow-Up
|
||||
|
||||
Connector follow-up is explicit and separated from repo-local extraction:
|
||||
|
||||
```bash
|
||||
railiance-fabric scan . \
|
||||
--repo-slug railiance-fabric \
|
||||
--connector local-fabric-registry \
|
||||
--connector-manifest registry/local-repos.yaml \
|
||||
--dry-run
|
||||
```
|
||||
|
||||
The connector interface has slots for:
|
||||
|
||||
- package registries
|
||||
- container registries
|
||||
- API catalogs
|
||||
- service catalogs
|
||||
- deployment inventories
|
||||
- existing Fabric registry data
|
||||
|
||||
The first implementation is `local-fabric-registry`, an offline-safe connector
|
||||
that reads a local onboarding manifest such as `registry/local-repos.yaml`. It
|
||||
adds a `FabricRegistryEntry` candidate, a `cataloged_as` edge from the
|
||||
repository node, and registry-sourced attributes such as domain, remote URL,
|
||||
default branch, State Hub repo id, and declaration paths.
|
||||
|
||||
Connector evidence uses its own replacement scope with source kind
|
||||
`fabric_registry`, so rescans can replace catalog facts without retiring
|
||||
repo-local evidence. Connector run metadata is recorded under `connector_runs`
|
||||
with status, source, message, and candidate counts.
|
||||
|
||||
Connector-derived facts should be treated this way:
|
||||
|
||||
- accepted: only when the connector reads explicit repo-owned evidence,
|
||||
accountability-root evidence, or a catalog already governed as authoritative
|
||||
for that field
|
||||
- candidate: stable local registry facts such as onboarding manifest entries,
|
||||
declared remote URLs, State Hub ids, and declaration paths
|
||||
- review-only: missing catalogs, rate limits, connector failures, ambiguous
|
||||
matches, or facts from catalogs with unclear ownership
|
||||
|
||||
Failures do not corrupt the scan. Missing catalogs become
|
||||
`connector_unavailable` review artifacts, malformed catalogs become
|
||||
`connector_failed` artifacts, and future remote connectors should use
|
||||
`connector_rate_limited` when backoff is required.
|
||||
|
||||
## Multi-Repo Orchestration
|
||||
|
||||
Known local repos can be scanned from the same onboarding manifest used by
|
||||
`registry sync-manifest`:
|
||||
|
||||
```bash
|
||||
railiance-fabric registry scan-manifest registry/local-repos.yaml \
|
||||
--dry-run \
|
||||
--output-dir .fabric-discovery
|
||||
```
|
||||
|
||||
The command isolates each repo. A missing path, invalid previous snapshot, or
|
||||
registry write failure is reported for that repo without aborting the rest of
|
||||
the run. The summary includes repo counts for scanned, changed, retired,
|
||||
conflicted, LLM skipped, LLM failed, ingested, accepted, and errors so it can be
|
||||
copied into State Hub progress notes or future automation output.
|
||||
|
||||
Useful controls:
|
||||
|
||||
- `--repo-slug <slug>` can be repeated to scan an allowlist.
|
||||
- `--profile <name>` tags the scan profile and output filename.
|
||||
- `--previous-dir <dir>` reconciles each repo against
|
||||
`<slug>-<profile>.discovery.json` from an earlier run.
|
||||
- `--llm` enables LLM-assisted extraction; `--deterministic-only` forces the
|
||||
offline rule path.
|
||||
- `--llm-max-runs <n>` caps how many repos may attempt LLM extraction in one
|
||||
orchestration run, while `--llm-max-tokens` remains the per-repo request cap.
|
||||
- `--connector local-fabric-registry` attaches manifest-derived registry facts
|
||||
to every repo scan.
|
||||
- `--ingest` stores discovery snapshots in the registry; `--accept` then
|
||||
projects accepted candidates into graph snapshots. `--dry-run` suppresses
|
||||
registry writes even when those flags are present.
|
||||
|
||||
Example review cycle:
|
||||
|
||||
```bash
|
||||
railiance-fabric registry scan-manifest registry/local-repos.yaml \
|
||||
--repo-slug railiance-fabric \
|
||||
--previous-dir .fabric-discovery \
|
||||
--output-dir .fabric-discovery \
|
||||
--connector local-fabric-registry \
|
||||
--dry-run
|
||||
```
|
||||
|
||||
After review, rerun with `--ingest` to store the snapshots. Add `--accept` only
|
||||
when candidates marked `review_state: accepted` should be projected into the
|
||||
registry graph.
|
||||
|
||||
For repeated operational loops, including default cache paths, registry-backed
|
||||
previous snapshots, run reports, exit codes, and rescan health views, see
|
||||
`docs/operational-rescan-loops.md`.
|
||||
|
||||
## Scan Profiles And Review Workflow
|
||||
|
||||
The initial profile is `deterministic`, which means repo-local extraction plus
|
||||
any explicitly enabled offline connectors. Additional profiles should be named
|
||||
for the evidence policy they represent, for example `deterministic-llm-draft`
|
||||
or `catalog-followup`. Keep profile names stable because per-repo previous
|
||||
snapshots use `<slug>-<profile>.discovery.json`.
|
||||
|
||||
Recommended workflow:
|
||||
|
||||
1. Run `scan` or `registry scan-manifest` with `--dry-run`.
|
||||
2. Reconcile with `--previous-snapshot` or `--previous-dir` when a prior
|
||||
snapshot exists.
|
||||
3. Review candidates with `review_state: needs_review`, `status: conflicted`,
|
||||
tombstones, and review artifacts before accepting anything.
|
||||
4. Store reviewed output with `registry ingest-discovery`.
|
||||
5. Use `registry accept-discovery` or `registry scan-manifest --ingest --accept`
|
||||
only for candidates whose review state is acceptable for projection.
|
||||
|
||||
## Failure Modes
|
||||
|
||||
Failures are captured close to the evidence source:
|
||||
|
||||
- Missing repo paths, invalid manifest entries, unreadable previous snapshots,
|
||||
and registry request failures mark that repo as `status: error` in
|
||||
`scan-manifest` without stopping other repos.
|
||||
- Connector failures become review artifacts such as `connector_unavailable` or
|
||||
`connector_failed`.
|
||||
- LLM provider failures and malformed model output become `llm_execution_error`
|
||||
or `llm_output_invalid` review artifacts.
|
||||
- Low-confidence LLM candidates become `llm_low_confidence` artifacts instead
|
||||
of graph candidates.
|
||||
- Possible duplicates are marked as conflicts and left for review instead of
|
||||
being silently merged.
|
||||
|
||||
## Rollout Dry Run
|
||||
|
||||
The first small local rollout ran on 2026-05-19:
|
||||
|
||||
```bash
|
||||
railiance-fabric registry scan-manifest registry/local-repos.yaml \
|
||||
--repo-slug repo-scoping \
|
||||
--repo-slug llm-connect \
|
||||
--repo-slug railiance-fabric \
|
||||
--dry-run \
|
||||
--connector local-fabric-registry
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
- `repo-scoping`: 18 nodes, 17 edges, 13 attributes
|
||||
- `llm-connect`: 5 nodes, 4 edges, 13 attributes
|
||||
- `railiance-fabric`: 55 nodes, 63 edges, 13 attributes
|
||||
- summary: 3 scanned, 0 changed, 0 retired, 0 conflicted, 3 LLM skipped,
|
||||
0 LLM failed, 0 accepted, 0 errors
|
||||
|
||||
Follow-up backlog from this first pass:
|
||||
|
||||
- Add a standard discovery snapshot directory, likely `.fabric-discovery/`, so
|
||||
repeated dry-runs can reconcile by default.
|
||||
- Add a previous-from-registry option so manifest scans can diff against the
|
||||
latest stored discovery snapshot without exporting JSON first.
|
||||
- Expand runtime/deployment extraction beyond local manifests to cover live
|
||||
server and deployment inventory connectors.
|
||||
- Add review UI affordances for conflicts, tombstones, and bulk acceptance once
|
||||
enough repos have baseline snapshots.
|
||||
- Define privacy and budget defaults before enabling non-mock LLM providers in
|
||||
multi-repo scans.
|
||||
|
||||
## Identity
|
||||
|
||||
Identity is the main safety boundary. The scanner must not append guesses on
|
||||
every run. It needs to produce stable keys that are repeatable for the same
|
||||
observed entity.
|
||||
|
||||
Candidate node keys use this shape:
|
||||
|
||||
```text
|
||||
discovery:{repo_slug}:{entity_kind}:{normalized_name}[:source_fingerprint]
|
||||
```
|
||||
|
||||
Use the optional source fingerprint when a name is too generic or when multiple
|
||||
entities of the same kind can share a display name. Examples include HTTP
|
||||
routes, generated clients, deployment manifests, and catalog records.
|
||||
|
||||
Candidate edge keys use a relationship fingerprint over:
|
||||
|
||||
- source stable key
|
||||
- edge type
|
||||
- target stable key
|
||||
- optional evidence scope
|
||||
|
||||
Candidate attribute keys use the entity stable key plus the normalized
|
||||
attribute name and, where needed, a source fingerprint.
|
||||
|
||||
Stable-key parts are lowercased and normalized to ASCII-like identity segments.
|
||||
The helper functions in `railiance_fabric.discovery` define the initial rules.
|
||||
|
||||
## Source Anchors
|
||||
|
||||
Every candidate must carry one or more source anchors. A source anchor identifies
|
||||
why the scanner believes the fact exists. Anchors can point to files, package
|
||||
manifests, lockfiles, API contracts, deployment manifests, service catalogs,
|
||||
registries, LLM evidence bundles, or manual review notes.
|
||||
|
||||
Source anchors include a fingerprint. The fingerprint should cover stable
|
||||
location fields such as path, URL, ref, line range, or JSON pointer. Snippets are
|
||||
useful for review but should not be the only identity anchor because formatting
|
||||
noise can churn snippets.
|
||||
|
||||
## Replacement Scopes
|
||||
|
||||
A replacement scope says which extractor owns which set of candidates. Rescans
|
||||
may retire missing candidates only inside the same scope.
|
||||
|
||||
Examples:
|
||||
|
||||
- `scope:repo-scoping:python-package:package_manifest:<hash>`
|
||||
- `scope:state-hub:fabric-declarations:declaration`
|
||||
- `scope:llm-connect:readme-summary:file:<hash>`
|
||||
- `scope:railiance-fabric:local-registry:fabric_registry`
|
||||
|
||||
Scopes have a mode:
|
||||
|
||||
- `replacement`: candidates missing from the next run in the same scope become
|
||||
tombstones.
|
||||
- `additive`: candidates are added or updated, but absence does not retire old
|
||||
candidates.
|
||||
|
||||
LLM extractors should usually use replacement mode only for tightly bounded
|
||||
evidence bundles. Broad repo summaries are safer as additive or review-only
|
||||
until the extraction prompts are proven stable.
|
||||
|
||||
## Merge Precedence
|
||||
|
||||
When multiple sources describe the same entity, reconciliation uses this
|
||||
precedence:
|
||||
|
||||
1. `repo_declaration`
|
||||
2. `deterministic`
|
||||
3. `catalog`
|
||||
4. `registry`
|
||||
5. `llm`
|
||||
6. `manual`
|
||||
|
||||
Manual review can override local candidate state, but it should not silently
|
||||
rewrite repo-owned declarations. If accepted discoveries should become durable
|
||||
repo-local evidence, generate a repo-owned declaration patch for human review.
|
||||
If they affect financial ownership, fabric containment, tenancy, or utility
|
||||
value boundaries, generate a baseline or accountability-root review item
|
||||
instead.
|
||||
|
||||
## Duplicate Handling
|
||||
|
||||
The reconciler should merge candidates with the same stable key automatically.
|
||||
It should also look for possible duplicates using:
|
||||
|
||||
- alias overlap
|
||||
- identical source anchors
|
||||
- identical evidence fingerprints
|
||||
- normalized label similarity within the same entity kind
|
||||
- relationship fingerprints with the same endpoints and edge type
|
||||
- declaration ids that match discovery aliases
|
||||
|
||||
Exact stable-key matches can be merged automatically. Alias-only or
|
||||
similarity-only matches should become `needs_review` conflicts unless an
|
||||
extractor has a source-specific rule that makes the match deterministic.
|
||||
|
||||
## Rescan And Tombstones
|
||||
|
||||
On a rescan, the scanner compares the previous accepted discovery snapshot with
|
||||
the newly produced snapshot for the same repo/profile.
|
||||
|
||||
- Same stable key: update in place.
|
||||
- Same source anchor but changed attributes: update with changed evidence.
|
||||
- Missing from same replacement scope: create a tombstone.
|
||||
- Missing from a different scope: leave untouched.
|
||||
- Reappears after tombstone: reactivate if the stable key and scope match.
|
||||
- Reappears with a new key but same alias/source anchor: flag as possible
|
||||
duplicate resurrection.
|
||||
|
||||
Tombstones explain graph drift and prevent immediate re-creation loops. They
|
||||
should be retained long enough to compare several scan cycles and can later be
|
||||
compacted by repo, extractor, or entity kind.
|
||||
|
||||
## Mapping To Fabric Graphs
|
||||
|
||||
Discovery candidates can project into the existing graph model when accepted:
|
||||
|
||||
- candidate service nodes map to `ServiceDeclaration`-like graph nodes
|
||||
- candidate capabilities and interfaces map to provider surface nodes
|
||||
- candidate dependencies map to dependency nodes and `consumes` edges
|
||||
- candidate deployment/runtime entities map to graph explorer infrastructure
|
||||
nodes until declarations gain first-class runtime support
|
||||
- candidate libraries map to library inventory records and graph explorer nodes
|
||||
|
||||
If a repo-owned declaration already exists for the same entity, discovery output
|
||||
should attach as supporting evidence instead of creating another node.
|
||||
|
||||
## LLM Boundary
|
||||
|
||||
LLM extraction through `llm-connect` is optional and schema-gated. The scanner
|
||||
should use deterministic preselection to build small evidence bundles, ask for
|
||||
structured JSON, validate the JSON against the discovery schema, and record:
|
||||
|
||||
- extractor id and version
|
||||
- prompt version
|
||||
- provider and model
|
||||
- usage metadata
|
||||
- confidence and uncertainty
|
||||
- rationale
|
||||
|
||||
Malformed, low-confidence, or conflicting LLM output becomes review material,
|
||||
not accepted graph data.
|
||||
340
docs/semantic-attractors.md
Normal file
340
docs/semantic-attractors.md
Normal file
@@ -0,0 +1,340 @@
|
||||
# Semantic Attractors
|
||||
|
||||
## Intent
|
||||
|
||||
Semantic attractors are view entities that help an operator orient inside a
|
||||
medium or large graph. An attractor represents a topic, concern, capability
|
||||
area, operating mode, or other conceptual pole such as `security`,
|
||||
`development`, `operations`, `identity`, `data`, or `delivery`.
|
||||
|
||||
The graph explorer can place attractors on the canvas and connect graph
|
||||
entities to them with view-only relationship strength. The stronger an
|
||||
entity's semantic closeness to an attractor, the more that attractor should
|
||||
pull the entity in force-directed or spring-based layouts.
|
||||
|
||||
The first motivating use case is repository orientation. Given a set of
|
||||
repositories, the operator defines attractors such as `security`,
|
||||
`development`, and `operations`. Railiance Fabric reads each repository's
|
||||
`SCOPE.md`, estimates semantic closeness to those attractors, and maps that
|
||||
score to layout force. The resulting map becomes a navigational surface: repos
|
||||
with similar purpose drift toward the same conceptual pole without replacing
|
||||
the underlying dependency or responsibility graph.
|
||||
|
||||
## What Attractors Are
|
||||
|
||||
An attractor is not a fabric node in the source graph. It is a graph-view
|
||||
artifact with these responsibilities:
|
||||
|
||||
- name a topic or concern that is useful for orientation;
|
||||
- define how closeness to that topic is measured;
|
||||
- expose a score for each eligible entity;
|
||||
- translate that score into layout hints and optional visual edges;
|
||||
- keep the scoring evidence inspectable so the map does not become mysterious.
|
||||
|
||||
Attractors should be saved as view/profile configuration, operator presets, or
|
||||
host-provided explorer configuration. They should not mutate repo-owned Fabric
|
||||
declarations, and they should not imply that a repository provides or consumes
|
||||
a capability.
|
||||
|
||||
## Why This Helps
|
||||
|
||||
Dependency edges answer "what depends on what?" Ownership and deployment
|
||||
metadata answer "who owns this?" and "where does this run?" Those questions are
|
||||
necessary, but they can still leave a large repo collection hard to scan.
|
||||
|
||||
Attractors answer a softer question: "what is this near, conceptually?"
|
||||
|
||||
This gives operators a fast way to discover clusters such as:
|
||||
|
||||
- repos that are security-heavy but not obvious from their names;
|
||||
- operations tooling that depends on development systems;
|
||||
- application repos that are unexpectedly close to platform/runtime concerns;
|
||||
- thin adapter repos that sit between two conceptual poles;
|
||||
- orphaned or ambiguous repos that have weak attraction to every known topic.
|
||||
|
||||
## Core Model
|
||||
|
||||
An attractor definition should be serializable and stable:
|
||||
|
||||
```yaml
|
||||
id: security
|
||||
label: Security
|
||||
description: Identity, authorization, secrets, MFA, audit, policy, and trust boundaries.
|
||||
applies_to:
|
||||
layers: [repository]
|
||||
evidence:
|
||||
sources:
|
||||
- type: scope_markdown
|
||||
path: SCOPE.md
|
||||
scoring:
|
||||
method: lexical_semantic_profile
|
||||
anchors:
|
||||
- security
|
||||
- identity
|
||||
- authorization
|
||||
- secrets
|
||||
- audit
|
||||
- policy
|
||||
- mfa
|
||||
negative_anchors:
|
||||
- unrelated
|
||||
normalization:
|
||||
mode: per_entity_softmax
|
||||
layout:
|
||||
min_score: 0.15
|
||||
max_score: 1.0
|
||||
strength_scale: 0.8
|
||||
ideal_length:
|
||||
min: 80
|
||||
max: 420
|
||||
presentation:
|
||||
color: "#be123c"
|
||||
edge_style: dashed
|
||||
```
|
||||
|
||||
The exact schema can evolve, but the responsibilities should remain separate:
|
||||
|
||||
- `applies_to` chooses which graph elements can be scored.
|
||||
- `evidence` declares which text or metadata is used.
|
||||
- `scoring` defines the semantic metric.
|
||||
- `normalization` turns raw scores into comparable view weights.
|
||||
- `layout` maps weights to graph layout hints.
|
||||
- `presentation` controls the optional visual attractor node and edges.
|
||||
|
||||
## Scoring From SCOPE.md
|
||||
|
||||
`SCOPE.md` is a useful first evidence source because it is intentionally short,
|
||||
repo-owned, and written to explain when a repository is relevant. For repository
|
||||
attraction, the scorer should use sections such as:
|
||||
|
||||
- `One-liner`
|
||||
- `Core Idea`
|
||||
- `In Scope`
|
||||
- `Relevant When`
|
||||
- `Provided Capabilities`
|
||||
- `Related / Overlapping Repositories`
|
||||
- `Terminology`
|
||||
|
||||
Sections such as `Out of Scope` and `Not Relevant When` should be used
|
||||
carefully. They can reduce false positives, but they should not erase a topic
|
||||
just because the repo mentions a boundary. For example, a repo can say it is
|
||||
not an authorization engine while still being semantically near security
|
||||
because it models secrets, policy, or trust boundaries.
|
||||
|
||||
The first implementation can use a transparent lexical profile:
|
||||
|
||||
1. Parse `SCOPE.md` into sections.
|
||||
2. Tokenize section text and provided capability keywords.
|
||||
3. Weight section matches, with `One-liner`, `Core Idea`, `In Scope`, and
|
||||
capability keywords carrying more weight than incidental notes.
|
||||
4. Score each attractor by matching configured anchors and related terms.
|
||||
5. Normalize scores per entity so one verbose `SCOPE.md` does not dominate.
|
||||
6. Store the score, confidence, and top evidence snippets in the view payload.
|
||||
|
||||
Later implementations can replace or augment lexical scoring with embeddings,
|
||||
LLM-assisted classification, or operator-reviewed labels. The contract should
|
||||
not depend on a particular scorer.
|
||||
|
||||
## Score Semantics
|
||||
|
||||
Attractor scores should be continuous values in `[0, 1]`.
|
||||
|
||||
Suggested interpretation:
|
||||
|
||||
| Score | Meaning |
|
||||
|-------|---------|
|
||||
| `0.00` | no useful evidence of semantic closeness |
|
||||
| `0.10` to `0.30` | weak signal; useful only as a faint layout hint |
|
||||
| `0.30` to `0.60` | moderate closeness; entity should visibly lean toward the attractor |
|
||||
| `0.60` to `0.85` | strong closeness; entity likely belongs near the attractor cluster |
|
||||
| `0.85` to `1.00` | primary semantic identity or explicit operator label |
|
||||
|
||||
Every score should carry a confidence separate from closeness. A repo with a
|
||||
thin or missing `SCOPE.md` may have low confidence even if a few terms match.
|
||||
|
||||
Attractors should also support multi-attraction. A repository can be close to
|
||||
both `development` and `operations`; the layout should then place it between
|
||||
those poles instead of forcing a single category. This is the main difference
|
||||
from zones: zones preserve a single-surface invariant, while attractors are
|
||||
allowed to overlap because they are layout forces, not containers.
|
||||
|
||||
## Layout Mapping
|
||||
|
||||
Attraction scores become layout hints. They should not become domain edges.
|
||||
|
||||
A graph explorer can map scores to synthetic view edges:
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"id": "attractor:security->repo:flex-auth",
|
||||
"source": "attractor:security",
|
||||
"target": "repo:flex-auth",
|
||||
"edgeType": "semantic_attraction",
|
||||
"displayOnly": true,
|
||||
"score": 0.82,
|
||||
"confidence": 0.74,
|
||||
"strength": "strong",
|
||||
"layoutAffinity": 0.82,
|
||||
"layoutIdealLength": 110,
|
||||
"layoutElasticity": 0.9,
|
||||
"sourceReferences": [
|
||||
{
|
||||
"type": "scope_markdown",
|
||||
"path": "SCOPE.md",
|
||||
"section": "In Scope"
|
||||
}
|
||||
]
|
||||
},
|
||||
"classes": "semantic-attraction"
|
||||
}
|
||||
```
|
||||
|
||||
For force-directed layouts:
|
||||
|
||||
- stronger scores should increase spring strength or edge weight;
|
||||
- stronger scores should shorten ideal length;
|
||||
- weak scores may be hidden visually while still applying a small force;
|
||||
- edges below a configured threshold should not affect layout;
|
||||
- display-only attraction edges should be excluded from dependency, boundary,
|
||||
blast-radius, and zone-connectivity diagnostics.
|
||||
|
||||
Attractor nodes can be pinned, arranged on a ring, placed by the operator, or
|
||||
computed from the current profile. For first use, a stable radial placement is
|
||||
usually enough: place three to eight attractors around the graph, then let
|
||||
repositories find their balance.
|
||||
|
||||
## View Payload Shape
|
||||
|
||||
The graph explorer payload should be able to carry attractor metadata without
|
||||
changing the canonical Fabric graph.
|
||||
|
||||
Recommended top-level view extension:
|
||||
|
||||
```json
|
||||
{
|
||||
"view": {
|
||||
"attractors": {
|
||||
"enabled": true,
|
||||
"definitionSet": "repo-concerns-v1",
|
||||
"definitions": [
|
||||
{
|
||||
"id": "security",
|
||||
"label": "Security",
|
||||
"description": "Identity, authorization, secrets, audit, and policy.",
|
||||
"color": "#be123c"
|
||||
}
|
||||
],
|
||||
"scores": [
|
||||
{
|
||||
"attractor_id": "security",
|
||||
"element_id": "repo:flex-auth",
|
||||
"score": 0.82,
|
||||
"confidence": 0.74,
|
||||
"method": "lexical_semantic_profile",
|
||||
"evidence": [
|
||||
{
|
||||
"source": "SCOPE.md",
|
||||
"section": "Core Idea",
|
||||
"terms": ["authorization", "policy"]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The renderer may choose to materialize these into synthetic nodes and edges at
|
||||
runtime. A host may also emit synthetic display-only elements directly if that
|
||||
is easier for the current engine.
|
||||
|
||||
## Operator Workflow
|
||||
|
||||
A useful attractor workflow should feel like mapmaking:
|
||||
|
||||
1. Choose a preset such as `Security / Development / Operations`.
|
||||
2. Review the generated scores and evidence for a few known repos.
|
||||
3. Hide or pin attractors that are not useful for the current question.
|
||||
4. Save the attractor definition set in the graph profile.
|
||||
5. Use the resulting layout to discover ambiguous, central, or misplaced repos.
|
||||
|
||||
The UI should expose:
|
||||
|
||||
- a toggle for semantic attractors;
|
||||
- a definition-set selector;
|
||||
- score threshold controls;
|
||||
- optional visual attraction edges;
|
||||
- pinned/unpinned attractor placement;
|
||||
- detail panels explaining why a repo is close to an attractor;
|
||||
- diagnostics for missing evidence, low confidence, and overly broad
|
||||
attractors.
|
||||
|
||||
## Relationship To Zones
|
||||
|
||||
Zones and attractors solve different orientation problems.
|
||||
|
||||
Zones are bounded drawing surfaces. A visible node belongs to zero or one zone
|
||||
in a given view. They are useful for deployment environments, access zones,
|
||||
ownership surfaces, and other container-like questions.
|
||||
|
||||
Attractors are semantic force points. A visible node can be pulled by multiple
|
||||
attractors at once. They are useful for topical orientation, concern mapping,
|
||||
and discovering conceptual neighborhoods.
|
||||
|
||||
The two concepts can combine cleanly:
|
||||
|
||||
- zones can show where entities run;
|
||||
- attractors can pull repos inside or outside those zones based on semantic
|
||||
concern;
|
||||
- zone diagnostics should ignore semantic attraction edges unless explicitly
|
||||
configured otherwise;
|
||||
- attractor scores can be summarized inside zone details.
|
||||
|
||||
## Initial Presets
|
||||
|
||||
A first repository-orientation preset should keep the set small:
|
||||
|
||||
| Attractor | Topic Signal |
|
||||
|-----------|--------------|
|
||||
| `security` | identity, secrets, authorization, policy, audit, MFA, trust boundaries |
|
||||
| `development` | source code, build, CI/CD, package publishing, scaffolding, developer workflows |
|
||||
| `operations` | deployment, runtime, monitoring, backups, incidents, infrastructure lifecycle |
|
||||
|
||||
Useful follow-up presets:
|
||||
|
||||
- `data`, `identity`, `delivery`, `governance`
|
||||
- `platform`, `application`, `tooling`
|
||||
- `financial`, `runtime`, `coordination`
|
||||
|
||||
Attractors should start as operator-chosen presets rather than global truth.
|
||||
The same repository can be viewed through different conceptual lenses.
|
||||
|
||||
## Implementation Path
|
||||
|
||||
The concept can be implemented incrementally:
|
||||
|
||||
1. Add an attractor definition format for graph explorer profiles.
|
||||
2. Parse repo `SCOPE.md` files during registry sync or graph export.
|
||||
3. Compute transparent lexical scores for repositories.
|
||||
4. Include attractor scores and evidence in the graph explorer payload.
|
||||
5. Add synthetic attractor nodes and display-only attraction edges in the UI.
|
||||
6. Map attraction scores to layout hints for the force-directed layout.
|
||||
7. Add detail-panel evidence and low-confidence diagnostics.
|
||||
8. Support saved attractor presets and operator score overrides.
|
||||
|
||||
This keeps attractors as a view concern until the scoring model proves useful.
|
||||
If a semantic relation becomes durable domain knowledge, it can later be
|
||||
promoted into a proper Fabric declaration with separate evidence and review.
|
||||
|
||||
## Open Questions
|
||||
|
||||
- Should attractor definitions live in graph profiles, repo config, or a shared
|
||||
registry preset file?
|
||||
- Should scoring run during registry sync, export, or entirely in the browser?
|
||||
- How much operator override should be allowed before scores become maintained
|
||||
labels rather than computed evidence?
|
||||
- What is the right default for missing or stale `SCOPE.md` evidence?
|
||||
- Should the first implementation use only lexical scoring, or should it also
|
||||
prepare a pluggable embedding scorer interface?
|
||||
@@ -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,15 +32,25 @@ 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
|
||||
railiance-fabric export --format financial
|
||||
```
|
||||
|
||||
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
|
||||
@@ -58,6 +69,10 @@ Node fields:
|
||||
| `repo` | Owning repo slug. |
|
||||
| `domain` | Owning domain slug. |
|
||||
| `lifecycle` | Declaration lifecycle. |
|
||||
| `canon_category` | Canon-aligned entity category when known. |
|
||||
| `canon_anchor` | Canon surface that owns the selected category. |
|
||||
| `mapping_fit` | Mapping confidence bucket: `direct`, `partial`, `conflict`, `gap`, or `unknown`. |
|
||||
| `evidence_state` | Evidence state for the node claim: `observed`, `declared`, `inferred`, `proposed`, or `gap`. |
|
||||
|
||||
Edge fields:
|
||||
|
||||
@@ -65,7 +80,87 @@ Edge fields:
|
||||
|-------|---------|
|
||||
| `from` | Source node id. |
|
||||
| `to` | Target node id. |
|
||||
| `type` | Relationship type, such as `provides`, `exposes`, `available_via`, `consumes`, `binds:exact`, or `uses_interface`. |
|
||||
| `type` | Fabric relationship type, such as `provides`, `exposes`, `available_via`, `consumes`, `binds:exact`, or `uses_interface`. |
|
||||
| `canonical_type` | Canon-aligned relationship family when known, such as `exposes`, `depends_on`, `deploys`, or `flows_to`. |
|
||||
| `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`.
|
||||
|
||||
## Operator Refresh During Reset
|
||||
|
||||
For the current reset, operators should produce both export families:
|
||||
|
||||
```bash
|
||||
railiance-fabric validate .
|
||||
railiance-fabric export --format json
|
||||
railiance-fabric export --format financial
|
||||
```
|
||||
|
||||
The `json` export remains the compatibility payload for State Hub graph views
|
||||
implemented by `STATE-WP-0050`. The `financial` export is the vNext contract
|
||||
artifact for `STATE-WP-0051` and should be reviewed whenever the baseline,
|
||||
discovery inputs, ownership model, or registry materialization changes.
|
||||
|
||||
After workplan file changes, refresh State Hub's file-backed index from the
|
||||
State Hub repo:
|
||||
|
||||
```bash
|
||||
make fix-consistency REPO=railiance-fabric
|
||||
```
|
||||
|
||||
Graph import and workplan consistency are separate. The consistency command
|
||||
does not author Fabric graph topology; it only keeps State Hub's workplan cache
|
||||
aligned with repo files.
|
||||
|
||||
## Proposed State Hub Read Model
|
||||
|
||||
@@ -119,9 +214,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
|
||||
|
||||
@@ -133,7 +239,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
|
||||
|
||||
@@ -143,7 +249,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
|
||||
|
||||
|
||||
@@ -28,12 +28,15 @@ Machine-readable catalog files:
|
||||
| `audit-event-sink` | planned | high | confidential | `event-stream`, `http-api` |
|
||||
| `scope-generation` | active | medium | internal | `cli`, `http-api` |
|
||||
| `coordination-read-model` | active | high | internal | `http-api`, `event-stream` |
|
||||
| `ecosystem-registry` | active | high | internal | `http-api`, `web-ui` |
|
||||
|
||||
## Interface Types
|
||||
|
||||
| Type | Lifecycle | Category | Typical Auth |
|
||||
|------|-----------|----------|--------------|
|
||||
| `http-api` | active | api | `none`, `oidc`, `jwt`, `mtls`, `api_key` |
|
||||
| `web-ui` | active | ui | `none`, `oidc`, `jwt`, `mtls`, `api_key` |
|
||||
| `mcp-api` | active | api | `none`, `oidc`, `jwt`, `mtls`, `api_key` |
|
||||
| `oidc-discovery` | active | identity | `none` |
|
||||
| `kubernetes-secret` | active | kubernetes | `kubernetes_service_account` |
|
||||
| `kubernetes-crd` | active | kubernetes | `kubernetes_service_account` |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Declaration Fixtures
|
||||
|
||||
These fixtures support the T02 schema baseline and give the future validator
|
||||
real inputs to exercise.
|
||||
These fixtures support the legacy `v1alpha1` declaration schema and give the
|
||||
validator real inputs to exercise.
|
||||
|
||||
`valid/` contains a coherent mini-graph:
|
||||
|
||||
@@ -11,5 +11,10 @@ real inputs to exercise.
|
||||
- flex-auth runtime-secrets dependency
|
||||
- binding assertion from flex-auth to OpenBao
|
||||
|
||||
`invalid/` contains schema-level failures. The future validator should report
|
||||
clear errors for these before it attempts graph-level checks.
|
||||
`invalid/` contains schema-level failures. The validator should report clear
|
||||
errors for these before it attempts graph-level checks.
|
||||
|
||||
For the financial Fabric contract, use
|
||||
`examples/exports/financial-fabric-v1.json`. That fixture exercises
|
||||
king/lord/tenant actors, fabric/subfabric containment, ownership, cost/profit
|
||||
attribution, and a cross-boundary utility edge.
|
||||
|
||||
104
examples/discovery/accountability-root-manifest.yaml
Normal file
104
examples/discovery/accountability-root-manifest.yaml
Normal file
@@ -0,0 +1,104 @@
|
||||
apiVersion: railiance.fabric/v1alpha2
|
||||
kind: AccountabilityRootManifest
|
||||
metadata:
|
||||
id: example.accountability-roots
|
||||
name: Example Accountability Roots
|
||||
description: Minimal example showing how a tenant subfabric can be added without changing the parent fabric criterion.
|
||||
netkingdom:
|
||||
id: example.netkingdom
|
||||
name: Example Netkingdom
|
||||
king_actor_id: actor.example.king
|
||||
actors:
|
||||
- id: actor.example.king
|
||||
role: king
|
||||
name: Example King
|
||||
authority:
|
||||
recovery_authority: true
|
||||
secrets_authority: true
|
||||
backup_authority: true
|
||||
termination_authority: true
|
||||
- id: actor.example.lord
|
||||
role: lord
|
||||
name: Example Lord
|
||||
- id: actor.example.tenant
|
||||
role: tenant
|
||||
name: Example Tenant
|
||||
fabrics:
|
||||
- id: fabric.example.primary
|
||||
kind: Fabric
|
||||
name: Example Primary Fabric
|
||||
netkingdom_id: example.netkingdom
|
||||
lord_actor_id: actor.example.lord
|
||||
parent_fabric_id: null
|
||||
status: active
|
||||
boundary:
|
||||
boundary_type: fabric
|
||||
criterion: financial_and_operational_accountability
|
||||
payment_responsibility: actor.example.lord
|
||||
operational_responsibility: actor.example.king
|
||||
recovery_responsibility: actor.example.king
|
||||
- id: subfabric.example.tenant
|
||||
kind: Subfabric
|
||||
name: Example Tenant Subfabric
|
||||
netkingdom_id: example.netkingdom
|
||||
tenant_actor_id: actor.example.tenant
|
||||
parent_fabric_id: fabric.example.primary
|
||||
status: planned
|
||||
boundary:
|
||||
boundary_type: subfabric
|
||||
criterion: restricted_paid_tenant_utility
|
||||
payment_responsibility: actor.example.tenant
|
||||
operational_responsibility: actor.example.lord
|
||||
recovery_responsibility: actor.example.king
|
||||
discovery_roots:
|
||||
- id: root.example.state-hub
|
||||
type: state_hub_repo_inventory
|
||||
status: active
|
||||
fabric_id: fabric.example.primary
|
||||
owner_actor_id: actor.example.king
|
||||
source:
|
||||
base_url: http://127.0.0.1:8000
|
||||
api_paths:
|
||||
- /managed-repos/
|
||||
safe_discovery: metadata_only
|
||||
evidence_scope:
|
||||
- repo_inventory
|
||||
- repository_identity
|
||||
refresh:
|
||||
cadence: on_change
|
||||
triggers:
|
||||
- state_hub_repo_inventory_change
|
||||
- operator_request
|
||||
- id: root.example.tenant-api-contracts
|
||||
type: endpoint_contract
|
||||
status: planned
|
||||
fabric_id: fabric.example.primary
|
||||
subfabric_id: subfabric.example.tenant
|
||||
owner_actor_id: actor.example.tenant
|
||||
source:
|
||||
repo_slug: example-tenant
|
||||
path: contracts/openapi
|
||||
safe_discovery: local_files
|
||||
evidence_scope:
|
||||
- endpoint_contract
|
||||
- tenant_boundary
|
||||
refresh:
|
||||
cadence: on_change
|
||||
triggers:
|
||||
- endpoint_contract_change
|
||||
- operator_request
|
||||
refresh:
|
||||
cadence: manual
|
||||
triggers:
|
||||
- operator_request
|
||||
- state_hub_repo_inventory_change
|
||||
- endpoint_contract_change
|
||||
- lord_or_tenant_change
|
||||
templates:
|
||||
future_subfabric:
|
||||
parent_fabric_id: fabric.example.primary
|
||||
tenant_actor_role: tenant
|
||||
required_updates:
|
||||
- Add tenant actor.
|
||||
- Add Subfabric with tenant_actor_id.
|
||||
- Add subfabric-scoped discovery roots.
|
||||
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": []
|
||||
}
|
||||
3572
exports/state-hub/2026-05-24-railiance-financial-fabric-v1.json
Normal file
3572
exports/state-hub/2026-05-24-railiance-financial-fabric-v1.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,8 @@
|
||||
# Seed Declarations
|
||||
|
||||
These declarations are the first repo-local seed graph for Railiance Fabric.
|
||||
They are legacy `v1alpha1` evidence used for validation, registry snapshots,
|
||||
and compatibility exports.
|
||||
|
||||
They model current and planned Railiance ecosystem providers:
|
||||
|
||||
@@ -17,4 +19,9 @@ They model current and planned Railiance ecosystem providers:
|
||||
|
||||
The files are intentionally small. They are seed data for graph loading,
|
||||
validation, and State Hub export work, not a claim that every upstream repo has
|
||||
already adopted Fabric declarations as source of truth.
|
||||
already published Fabric evidence.
|
||||
|
||||
The current financial responsibility baseline lives in
|
||||
`fabric/financial/railiance-netkingdom.yaml`. It defines the Railiance
|
||||
netkingdom, king, current lord, one active fabric, inherited node ownership,
|
||||
and the template for future tenant subfabrics.
|
||||
|
||||
16
fabric/bindings/railiance-apps-artifact-evidence-forge.yaml
Normal file
16
fabric/bindings/railiance-apps-artifact-evidence-forge.yaml
Normal file
@@ -0,0 +1,16 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: BindingAssertion
|
||||
metadata:
|
||||
id: railiance-apps.s5-releases.artifact-evidence-to-forge
|
||||
name: S5 artifact evidence binding
|
||||
owner: railiance-apps
|
||||
repo: railiance-apps
|
||||
domain: railiance
|
||||
spec:
|
||||
lifecycle: active
|
||||
environments: [dev, staging, prod]
|
||||
dependency_id: railiance-apps.s5-releases.needs-artifact-evidence
|
||||
provider_capability_id: railiance-forge.source-forge.artifact-promotion-evidence
|
||||
provider_interface_id: railiance-forge.source-forge.evidence-contract
|
||||
status: compatible
|
||||
rationale: S5 release readiness should cite forge-owned artifact publish, restore, and operating evidence.
|
||||
16
fabric/bindings/railiance-apps-container-registry-forge.yaml
Normal file
16
fabric/bindings/railiance-apps-container-registry-forge.yaml
Normal file
@@ -0,0 +1,16 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: BindingAssertion
|
||||
metadata:
|
||||
id: railiance-apps.s5-releases.container-registry-to-forge
|
||||
name: S5 container registry binding
|
||||
owner: railiance-apps
|
||||
repo: railiance-apps
|
||||
domain: railiance
|
||||
spec:
|
||||
lifecycle: active
|
||||
environments: [dev, staging, prod]
|
||||
dependency_id: railiance-apps.s5-releases.needs-container-registry
|
||||
provider_capability_id: railiance-forge.source-forge.container-registry
|
||||
provider_interface_id: railiance-forge.source-forge.oci-registry
|
||||
status: compatible
|
||||
rationale: S5 releases consume already-published app images from the forge-owned OCI registry.
|
||||
@@ -0,0 +1,16 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: BindingAssertion
|
||||
metadata:
|
||||
id: railiance-enablement.delivery-templates.runner-substrate-to-forge
|
||||
name: Enablement runner substrate binding
|
||||
owner: railiance-enablement
|
||||
repo: railiance-enablement
|
||||
domain: railiance
|
||||
spec:
|
||||
lifecycle: planned
|
||||
environments: [dev, staging, prod]
|
||||
dependency_id: railiance-enablement.delivery-templates.needs-runner-substrate
|
||||
provider_capability_id: railiance-forge.source-forge.workflow-runner-substrate
|
||||
provider_interface_id: railiance-forge.source-forge.runner-label-contract
|
||||
status: compatible
|
||||
rationale: S4 reusable templates should consume forge-owned runner labels, trust posture, and runner evidence.
|
||||
@@ -0,0 +1,16 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: BindingAssertion
|
||||
metadata:
|
||||
id: railiance-forge.source-forge.kubernetes-runtime-to-cluster
|
||||
name: Forge Kubernetes runtime binding
|
||||
owner: railiance-forge
|
||||
repo: railiance-forge
|
||||
domain: railiance
|
||||
spec:
|
||||
lifecycle: active
|
||||
environments: [dev, staging, prod]
|
||||
dependency_id: railiance-forge.source-forge.needs-kubernetes-runtime
|
||||
provider_capability_id: railiance-cluster.kubernetes.runtime
|
||||
provider_interface_id: railiance-cluster.kubernetes.api
|
||||
status: compatible
|
||||
rationale: The forge runtime is deployed on the Railiance Kubernetes runtime provided by railiance-cluster.
|
||||
@@ -0,0 +1,16 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: BindingAssertion
|
||||
metadata:
|
||||
id: railiance-forge.source-forge.object-storage-to-artifact-store
|
||||
name: Forge object storage binding
|
||||
owner: railiance-forge
|
||||
repo: railiance-forge
|
||||
domain: railiance
|
||||
spec:
|
||||
lifecycle: planned
|
||||
environments: [dev, staging, prod]
|
||||
dependency_id: railiance-forge.source-forge.needs-object-storage
|
||||
provider_capability_id: artifact-store.object-storage
|
||||
provider_interface_id: artifact-store.object-storage.bucket
|
||||
status: compatible
|
||||
rationale: Durable forge artifact/blob preservation should use the planned Railiance object-storage provider rather than ad hoc forge-local storage.
|
||||
16
fabric/bindings/railiance-forge-postgresql-cnpg.yaml
Normal file
16
fabric/bindings/railiance-forge-postgresql-cnpg.yaml
Normal file
@@ -0,0 +1,16 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: BindingAssertion
|
||||
metadata:
|
||||
id: railiance-forge.source-forge.postgresql-to-cnpg
|
||||
name: Forge PostgreSQL binding
|
||||
owner: railiance-forge
|
||||
repo: railiance-forge
|
||||
domain: railiance
|
||||
spec:
|
||||
lifecycle: active
|
||||
environments: [dev, staging, prod]
|
||||
dependency_id: railiance-forge.source-forge.needs-postgresql
|
||||
provider_capability_id: railiance-platform.cnpg.postgresql
|
||||
provider_interface_id: railiance-platform.cnpg.database-connection
|
||||
status: compatible
|
||||
rationale: Current Gitea database state is backed by the Railiance platform CNPG PostgreSQL service.
|
||||
16
fabric/bindings/railiance-forge-runtime-secrets-openbao.yaml
Normal file
16
fabric/bindings/railiance-forge-runtime-secrets-openbao.yaml
Normal file
@@ -0,0 +1,16 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: BindingAssertion
|
||||
metadata:
|
||||
id: railiance-forge.source-forge.runtime-secrets-to-openbao
|
||||
name: Forge runtime secrets binding
|
||||
owner: railiance-forge
|
||||
repo: railiance-forge
|
||||
domain: railiance
|
||||
spec:
|
||||
lifecycle: active
|
||||
environments: [dev, staging, prod]
|
||||
dependency_id: railiance-forge.source-forge.needs-runtime-secrets
|
||||
provider_capability_id: railiance-platform.openbao.runtime-secrets
|
||||
provider_interface_id: railiance-platform.openbao.kv-v2
|
||||
status: compatible
|
||||
rationale: Runtime secret custody for forge workloads belongs to the platform OpenBao path; SOPS/age remains bootstrap only.
|
||||
@@ -0,0 +1,21 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: CapabilityDeclaration
|
||||
metadata:
|
||||
id: railiance-cluster.kubernetes.runtime
|
||||
name: Kubernetes runtime
|
||||
owner: railiance-cluster
|
||||
repo: railiance-cluster
|
||||
domain: railiance
|
||||
source_links:
|
||||
- label: Cluster scope
|
||||
path: /home/worsch/railiance-cluster/SCOPE.md
|
||||
spec:
|
||||
lifecycle: active
|
||||
environments: [dev, staging, prod]
|
||||
description: Provides Kubernetes runtime primitives and API access consumed by Railiance platform, forge, and app workloads.
|
||||
capability_type: kubernetes-runtime
|
||||
service_id: railiance-cluster.kubernetes
|
||||
interface_ids:
|
||||
- railiance-cluster.kubernetes.api
|
||||
criticality: critical
|
||||
data_classification: restricted
|
||||
@@ -0,0 +1,23 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: CapabilityDeclaration
|
||||
metadata:
|
||||
id: railiance-enablement.delivery-templates.ci-cd-templates
|
||||
name: CI/CD workflow templates
|
||||
owner: railiance-enablement
|
||||
repo: railiance-enablement
|
||||
domain: railiance
|
||||
source_links:
|
||||
- label: Enablement scope
|
||||
path: /home/worsch/railiance-enablement/SCOPE.md
|
||||
- label: Enablement intent
|
||||
path: /home/worsch/railiance-enablement/INTENT.md
|
||||
spec:
|
||||
lifecycle: planned
|
||||
environments: [dev, staging, prod]
|
||||
description: Reusable Railiance workflow templates, promotion conventions, and delivery gates that consume forge runner labels and artifact evidence.
|
||||
capability_type: ci-cd-template-catalog
|
||||
service_id: railiance-enablement.delivery-templates
|
||||
interface_ids:
|
||||
- railiance-enablement.delivery-templates.workflow-template-contract
|
||||
criticality: medium
|
||||
data_classification: internal
|
||||
24
fabric/capabilities/railiance-fabric-ecosystem-registry.yaml
Normal file
24
fabric/capabilities/railiance-fabric-ecosystem-registry.yaml
Normal file
@@ -0,0 +1,24 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: CapabilityDeclaration
|
||||
metadata:
|
||||
id: railiance-fabric.registry.ecosystem-registry
|
||||
name: Railiance ecosystem registry
|
||||
owner: railiance-fabric
|
||||
repo: railiance-fabric
|
||||
domain: railiance
|
||||
source_links:
|
||||
- label: Registry store
|
||||
path: railiance_fabric/registry.py
|
||||
- label: Registry API docs
|
||||
path: docs/registry-api.md
|
||||
spec:
|
||||
lifecycle: active
|
||||
environments: [dev]
|
||||
description: Registers repositories, ingests Fabric graph snapshots and library inventory, and exposes registry projections for discovery, State Hub export, xRegistry, and the interactive Fabric map.
|
||||
capability_type: ecosystem-registry
|
||||
service_id: railiance-fabric.registry
|
||||
interface_ids:
|
||||
- railiance-fabric.registry.http-api
|
||||
- railiance-fabric.registry.graph-explorer-ui
|
||||
criticality: high
|
||||
data_classification: internal
|
||||
@@ -0,0 +1,23 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: CapabilityDeclaration
|
||||
metadata:
|
||||
id: railiance-forge.source-forge.artifact-promotion-evidence
|
||||
name: Artifact promotion evidence
|
||||
owner: railiance-forge
|
||||
repo: railiance-forge
|
||||
domain: railiance
|
||||
source_links:
|
||||
- label: Observability and evidence contract
|
||||
path: /home/worsch/railiance-forge/docs/observability-operating-evidence.md
|
||||
- label: Backup and restore handoff
|
||||
path: /home/worsch/railiance-forge/docs/backup-restore-secret-handoff.md
|
||||
spec:
|
||||
lifecycle: active
|
||||
environments: [dev, staging, prod]
|
||||
description: Provides artifact identity, provenance, publish, restore, and release-readiness evidence that downstream releases can cite.
|
||||
capability_type: artifact-promotion-evidence
|
||||
service_id: railiance-forge.source-forge
|
||||
interface_ids:
|
||||
- railiance-forge.source-forge.evidence-contract
|
||||
criticality: high
|
||||
data_classification: internal
|
||||
21
fabric/capabilities/railiance-forge-container-registry.yaml
Normal file
21
fabric/capabilities/railiance-forge-container-registry.yaml
Normal file
@@ -0,0 +1,21 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: CapabilityDeclaration
|
||||
metadata:
|
||||
id: railiance-forge.source-forge.container-registry
|
||||
name: Container registry
|
||||
owner: railiance-forge
|
||||
repo: railiance-forge
|
||||
domain: railiance
|
||||
source_links:
|
||||
- label: Container registry docs
|
||||
path: /home/worsch/railiance-forge/docs/gitea-container-registry.md
|
||||
spec:
|
||||
lifecycle: active
|
||||
environments: [dev, staging, prod]
|
||||
description: Provides the Gitea OCI container registry endpoint used by Railiance workloads.
|
||||
capability_type: container-registry
|
||||
service_id: railiance-forge.source-forge
|
||||
interface_ids:
|
||||
- railiance-forge.source-forge.oci-registry
|
||||
criticality: high
|
||||
data_classification: confidential
|
||||
@@ -0,0 +1,21 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: CapabilityDeclaration
|
||||
metadata:
|
||||
id: railiance-forge.source-forge.python-package-registry
|
||||
name: Python package registry
|
||||
owner: railiance-forge
|
||||
repo: railiance-forge
|
||||
domain: railiance
|
||||
source_links:
|
||||
- label: Package registry docs
|
||||
path: /home/worsch/railiance-forge/docs/gitea-package-registry.md
|
||||
spec:
|
||||
lifecycle: active
|
||||
environments: [dev, staging, prod]
|
||||
description: Provides the Gitea Python package registry endpoint used by Railiance source and app builds.
|
||||
capability_type: python-package-registry
|
||||
service_id: railiance-forge.source-forge
|
||||
interface_ids:
|
||||
- railiance-forge.source-forge.python-package-index
|
||||
criticality: high
|
||||
data_classification: confidential
|
||||
22
fabric/capabilities/railiance-forge-source-hosting.yaml
Normal file
22
fabric/capabilities/railiance-forge-source-hosting.yaml
Normal file
@@ -0,0 +1,22 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: CapabilityDeclaration
|
||||
metadata:
|
||||
id: railiance-forge.source-forge.source-hosting
|
||||
name: Source hosting
|
||||
owner: railiance-forge
|
||||
repo: railiance-forge
|
||||
domain: railiance
|
||||
source_links:
|
||||
- label: Forge scope
|
||||
path: /home/worsch/railiance-forge/SCOPE.md
|
||||
spec:
|
||||
lifecycle: active
|
||||
environments: [dev, staging, prod]
|
||||
description: Hosts Railiance Git repositories, review surfaces, repository metadata, and source-forge access paths.
|
||||
capability_type: source-hosting
|
||||
service_id: railiance-forge.source-forge
|
||||
interface_ids:
|
||||
- railiance-forge.source-forge.web-ui
|
||||
- railiance-forge.source-forge.git-ssh
|
||||
criticality: high
|
||||
data_classification: confidential
|
||||
@@ -0,0 +1,21 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: CapabilityDeclaration
|
||||
metadata:
|
||||
id: railiance-forge.source-forge.workflow-runner-substrate
|
||||
name: Workflow runner substrate
|
||||
owner: railiance-forge
|
||||
repo: railiance-forge
|
||||
domain: railiance
|
||||
source_links:
|
||||
- label: Runner ownership contract
|
||||
path: /home/worsch/railiance-forge/docs/ci-runner-actions-gitops-ownership.md
|
||||
spec:
|
||||
lifecycle: planned
|
||||
environments: [dev, staging, prod]
|
||||
description: Provides forge-backed runner labels, placement, credential boundaries, and runner health evidence consumed by workflow templates and release checks.
|
||||
capability_type: workflow-runner-substrate
|
||||
service_id: railiance-forge.source-forge
|
||||
interface_ids:
|
||||
- railiance-forge.source-forge.runner-label-contract
|
||||
criticality: high
|
||||
data_classification: restricted
|
||||
30
fabric/dependencies/railiance-apps-artifact-evidence.yaml
Normal file
30
fabric/dependencies/railiance-apps-artifact-evidence.yaml
Normal file
@@ -0,0 +1,30 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: DependencyDeclaration
|
||||
metadata:
|
||||
id: railiance-apps.s5-releases.needs-artifact-evidence
|
||||
name: S5 artifact evidence dependency
|
||||
owner: railiance-apps
|
||||
repo: railiance-apps
|
||||
domain: railiance
|
||||
source_links:
|
||||
- label: Apps scope
|
||||
path: /home/worsch/railiance-apps/SCOPE.md
|
||||
- label: Observability and evidence contract
|
||||
path: /home/worsch/railiance-forge/docs/observability-operating-evidence.md
|
||||
spec:
|
||||
lifecycle: active
|
||||
environments: [dev, staging, prod]
|
||||
consumer_service_id: railiance-apps.s5-releases
|
||||
requires:
|
||||
capability_type: artifact-promotion-evidence
|
||||
capability_id: railiance-forge.source-forge.artifact-promotion-evidence
|
||||
interface:
|
||||
type: evidence-contract
|
||||
version_constraint: ">=v1"
|
||||
auth:
|
||||
method: none
|
||||
criticality: high
|
||||
data_classification: internal
|
||||
fallback:
|
||||
mode: manual
|
||||
description: App operators can record manual evidence, but S5 should cite forge-owned artifact readiness when promoting releases.
|
||||
30
fabric/dependencies/railiance-apps-container-registry.yaml
Normal file
30
fabric/dependencies/railiance-apps-container-registry.yaml
Normal file
@@ -0,0 +1,30 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: DependencyDeclaration
|
||||
metadata:
|
||||
id: railiance-apps.s5-releases.needs-container-registry
|
||||
name: S5 container registry dependency
|
||||
owner: railiance-apps
|
||||
repo: railiance-apps
|
||||
domain: railiance
|
||||
source_links:
|
||||
- label: Apps scope
|
||||
path: /home/worsch/railiance-apps/SCOPE.md
|
||||
- label: Container registry docs
|
||||
path: /home/worsch/railiance-forge/docs/gitea-container-registry.md
|
||||
spec:
|
||||
lifecycle: active
|
||||
environments: [dev, staging, prod]
|
||||
consumer_service_id: railiance-apps.s5-releases
|
||||
requires:
|
||||
capability_type: container-registry
|
||||
capability_id: railiance-forge.source-forge.container-registry
|
||||
interface:
|
||||
type: oci-registry
|
||||
version_constraint: ">=registry-v2"
|
||||
auth:
|
||||
method: api_key
|
||||
criticality: high
|
||||
data_classification: confidential
|
||||
fallback:
|
||||
mode: none
|
||||
description: S5 releases require a reachable container registry for private or internal app images.
|
||||
@@ -0,0 +1,30 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: DependencyDeclaration
|
||||
metadata:
|
||||
id: railiance-enablement.delivery-templates.needs-runner-substrate
|
||||
name: Enablement runner substrate dependency
|
||||
owner: railiance-enablement
|
||||
repo: railiance-enablement
|
||||
domain: railiance
|
||||
source_links:
|
||||
- label: Enablement scope
|
||||
path: /home/worsch/railiance-enablement/SCOPE.md
|
||||
- label: Runner ownership contract
|
||||
path: /home/worsch/railiance-forge/docs/ci-runner-actions-gitops-ownership.md
|
||||
spec:
|
||||
lifecycle: planned
|
||||
environments: [dev, staging, prod]
|
||||
consumer_service_id: railiance-enablement.delivery-templates
|
||||
requires:
|
||||
capability_type: workflow-runner-substrate
|
||||
capability_id: railiance-forge.source-forge.workflow-runner-substrate
|
||||
interface:
|
||||
type: workflow-runner-label-contract
|
||||
version_constraint: ">=v1"
|
||||
auth:
|
||||
method: none
|
||||
criticality: high
|
||||
data_classification: internal
|
||||
fallback:
|
||||
mode: manual
|
||||
description: Reusable templates can remain draft-only until forge publishes runner labels and trust evidence.
|
||||
28
fabric/dependencies/railiance-forge-kubernetes-runtime.yaml
Normal file
28
fabric/dependencies/railiance-forge-kubernetes-runtime.yaml
Normal file
@@ -0,0 +1,28 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: DependencyDeclaration
|
||||
metadata:
|
||||
id: railiance-forge.source-forge.needs-kubernetes-runtime
|
||||
name: Forge Kubernetes runtime dependency
|
||||
owner: railiance-forge
|
||||
repo: railiance-forge
|
||||
domain: railiance
|
||||
source_links:
|
||||
- label: Forge scope
|
||||
path: /home/worsch/railiance-forge/SCOPE.md
|
||||
spec:
|
||||
lifecycle: active
|
||||
environments: [dev, staging, prod]
|
||||
consumer_service_id: railiance-forge.source-forge
|
||||
requires:
|
||||
capability_type: kubernetes-runtime
|
||||
capability_id: railiance-cluster.kubernetes.runtime
|
||||
interface:
|
||||
type: kubernetes-api
|
||||
version_constraint: ">=v1"
|
||||
auth:
|
||||
method: kubernetes_service_account
|
||||
criticality: critical
|
||||
data_classification: restricted
|
||||
fallback:
|
||||
mode: none
|
||||
description: The forge runtime cannot operate without the Railiance Kubernetes runtime.
|
||||
30
fabric/dependencies/railiance-forge-object-storage.yaml
Normal file
30
fabric/dependencies/railiance-forge-object-storage.yaml
Normal file
@@ -0,0 +1,30 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: DependencyDeclaration
|
||||
metadata:
|
||||
id: railiance-forge.source-forge.needs-object-storage
|
||||
name: Forge object storage dependency
|
||||
owner: railiance-forge
|
||||
repo: railiance-forge
|
||||
domain: railiance
|
||||
source_links:
|
||||
- label: Backup and restore handoff
|
||||
path: /home/worsch/railiance-forge/docs/backup-restore-secret-handoff.md
|
||||
- label: Platform OpenBao object-storage handoff
|
||||
path: /home/worsch/railiance-platform/docs/openbao.md
|
||||
spec:
|
||||
lifecycle: planned
|
||||
environments: [dev, staging, prod]
|
||||
consumer_service_id: railiance-forge.source-forge
|
||||
requires:
|
||||
capability_type: object-storage
|
||||
capability_id: artifact-store.object-storage
|
||||
interface:
|
||||
type: object-storage-bucket
|
||||
version_constraint: ">=v1"
|
||||
auth:
|
||||
method: sts_token
|
||||
criticality: high
|
||||
data_classification: confidential
|
||||
fallback:
|
||||
mode: manual
|
||||
description: Current Gitea package blobs remain on PVC until durable object-storage backup or artifact preservation is proven.
|
||||
28
fabric/dependencies/railiance-forge-postgresql.yaml
Normal file
28
fabric/dependencies/railiance-forge-postgresql.yaml
Normal file
@@ -0,0 +1,28 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: DependencyDeclaration
|
||||
metadata:
|
||||
id: railiance-forge.source-forge.needs-postgresql
|
||||
name: Forge PostgreSQL dependency
|
||||
owner: railiance-forge
|
||||
repo: railiance-forge
|
||||
domain: railiance
|
||||
source_links:
|
||||
- label: Backup and restore handoff
|
||||
path: /home/worsch/railiance-forge/docs/backup-restore-secret-handoff.md
|
||||
spec:
|
||||
lifecycle: active
|
||||
environments: [dev, staging, prod]
|
||||
consumer_service_id: railiance-forge.source-forge
|
||||
requires:
|
||||
capability_type: postgresql-database-service
|
||||
capability_id: railiance-platform.cnpg.postgresql
|
||||
interface:
|
||||
type: database-connection
|
||||
version_constraint: ">=v16"
|
||||
auth:
|
||||
method: database_role
|
||||
criticality: critical
|
||||
data_classification: confidential
|
||||
fallback:
|
||||
mode: none
|
||||
description: The forge runtime requires the Gitea database state and cannot degrade safely without it.
|
||||
28
fabric/dependencies/railiance-forge-runtime-secrets.yaml
Normal file
28
fabric/dependencies/railiance-forge-runtime-secrets.yaml
Normal file
@@ -0,0 +1,28 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: DependencyDeclaration
|
||||
metadata:
|
||||
id: railiance-forge.source-forge.needs-runtime-secrets
|
||||
name: Forge runtime secrets dependency
|
||||
owner: railiance-forge
|
||||
repo: railiance-forge
|
||||
domain: railiance
|
||||
source_links:
|
||||
- label: Backup and restore handoff
|
||||
path: /home/worsch/railiance-forge/docs/backup-restore-secret-handoff.md
|
||||
spec:
|
||||
lifecycle: active
|
||||
environments: [dev, staging, prod]
|
||||
consumer_service_id: railiance-forge.source-forge
|
||||
requires:
|
||||
capability_type: runtime-secrets
|
||||
capability_id: railiance-platform.openbao.runtime-secrets
|
||||
interface:
|
||||
type: openbao-kv-v2-mount
|
||||
version_constraint: ">=v1 <v2"
|
||||
auth:
|
||||
method: kubernetes_service_account
|
||||
criticality: critical
|
||||
data_classification: secret
|
||||
fallback:
|
||||
mode: manual
|
||||
description: SOPS/age bootstrap can carry encrypted deploy input, but runtime secret custody belongs to the platform path.
|
||||
227
fabric/discovery/railiance-accountability-roots.yaml
Normal file
227
fabric/discovery/railiance-accountability-roots.yaml
Normal file
@@ -0,0 +1,227 @@
|
||||
apiVersion: railiance.fabric/v1alpha2
|
||||
kind: AccountabilityRootManifest
|
||||
metadata:
|
||||
id: railiance.accountability-roots
|
||||
name: Railiance Accountability Roots
|
||||
description: Current discovery roots for rebuilding the Railiance Fabric graph from durable accountability evidence.
|
||||
source_links:
|
||||
- label: Financial Fabric architecture
|
||||
path: docs/FabricDiscoveryAndUpdate.md
|
||||
- label: Financial baseline
|
||||
path: fabric/financial/railiance-netkingdom.yaml
|
||||
netkingdom:
|
||||
id: railiance.netkingdom
|
||||
name: Railiance Netkingdom
|
||||
king_actor_id: actor.railiance.king
|
||||
baseline_ref:
|
||||
label: Railiance financial baseline
|
||||
path: fabric/financial/railiance-netkingdom.yaml
|
||||
actors:
|
||||
- id: actor.railiance.king
|
||||
role: king
|
||||
name: Railiance King
|
||||
description: Responsible for the Railiance netkingdom and recovery authority.
|
||||
authority:
|
||||
recovery_authority: true
|
||||
secrets_authority: true
|
||||
backup_authority: true
|
||||
termination_authority: true
|
||||
- id: actor.railiance.primary-lord
|
||||
role: lord
|
||||
name: Railiance Primary Lord
|
||||
description: Pays for the current Railiance infrastructure boundary.
|
||||
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
|
||||
payment_responsibility: actor.railiance.primary-lord
|
||||
operational_responsibility: actor.railiance.king
|
||||
recovery_responsibility: actor.railiance.king
|
||||
evidence_refs:
|
||||
- label: Railiance financial baseline
|
||||
path: fabric/financial/railiance-netkingdom.yaml
|
||||
discovery_roots:
|
||||
- id: root.state-hub.attached-repos
|
||||
type: state_hub_repo_inventory
|
||||
status: active
|
||||
fabric_id: fabric.railiance.primary
|
||||
owner_actor_id: actor.railiance.primary-lord
|
||||
source:
|
||||
base_url: http://127.0.0.1:8000
|
||||
api_paths:
|
||||
- /managed-repos/
|
||||
safe_discovery: metadata_only
|
||||
evidence_scope:
|
||||
- repo_inventory
|
||||
- repository_identity
|
||||
refresh:
|
||||
cadence: on_change
|
||||
triggers:
|
||||
- state_hub_repo_inventory_change
|
||||
- operator_request
|
||||
notes: Read State Hub as repo inventory evidence only; State Hub does not author Fabric ownership or topology.
|
||||
- id: root.gitea.coulomb
|
||||
type: gitea_organization
|
||||
status: active
|
||||
fabric_id: fabric.railiance.primary
|
||||
owner_actor_id: actor.railiance.primary-lord
|
||||
source:
|
||||
url: ssh://git@92.205.130.254:30022/coulomb
|
||||
organization: coulomb
|
||||
safe_discovery: metadata_only
|
||||
evidence_scope:
|
||||
- repo_inventory
|
||||
- repository_identity
|
||||
refresh:
|
||||
cadence: on_change
|
||||
triggers:
|
||||
- git_commit
|
||||
- operator_request
|
||||
- id: root.registry.local-repos
|
||||
type: registry_manifest
|
||||
status: active
|
||||
fabric_id: fabric.railiance.primary
|
||||
owner_actor_id: actor.railiance.primary-lord
|
||||
source:
|
||||
manifest_path: registry/local-repos.yaml
|
||||
safe_discovery: local_files
|
||||
evidence_scope:
|
||||
- repo_inventory
|
||||
- repository_identity
|
||||
- local_checkout
|
||||
refresh:
|
||||
cadence: on_change
|
||||
triggers:
|
||||
- state_hub_repo_inventory_change
|
||||
- operator_request
|
||||
- id: root.workspace.home-worsch
|
||||
type: host_path
|
||||
status: active
|
||||
fabric_id: fabric.railiance.primary
|
||||
owner_actor_id: actor.railiance.primary-lord
|
||||
source:
|
||||
path: /home/worsch
|
||||
patterns:
|
||||
- "*/.git"
|
||||
- "*/fabric"
|
||||
safe_discovery: local_files
|
||||
evidence_scope:
|
||||
- local_checkout
|
||||
- repository_identity
|
||||
refresh:
|
||||
cadence: manual
|
||||
triggers:
|
||||
- operator_request
|
||||
- id: root.railiance-fabric.checkout
|
||||
type: repository_checkout
|
||||
status: active
|
||||
fabric_id: fabric.railiance.primary
|
||||
owner_actor_id: actor.railiance.primary-lord
|
||||
source:
|
||||
repo_slug: railiance-fabric
|
||||
path: /home/worsch/railiance-fabric
|
||||
remote_url: gitea-remote:coulomb/railiance-fabric.git
|
||||
safe_discovery: local_files
|
||||
evidence_scope:
|
||||
- repository_identity
|
||||
- local_checkout
|
||||
- service_configuration
|
||||
- endpoint_contract
|
||||
- deployment_topology
|
||||
refresh:
|
||||
cadence: on_change
|
||||
triggers:
|
||||
- git_commit
|
||||
- deployment_manifest_change
|
||||
- endpoint_contract_change
|
||||
- operator_request
|
||||
- id: root.deployment.local-manifests
|
||||
type: deployment_automation
|
||||
status: active
|
||||
fabric_id: fabric.railiance.primary
|
||||
owner_actor_id: actor.railiance.primary-lord
|
||||
source:
|
||||
path: /home/worsch
|
||||
patterns:
|
||||
- "**/compose.yaml"
|
||||
- "**/compose.yml"
|
||||
- "**/docker-compose.yaml"
|
||||
- "**/Dockerfile"
|
||||
- "**/*.service"
|
||||
- "**/k8s/*.yaml"
|
||||
- "**/deploy*.sh"
|
||||
safe_discovery: local_files
|
||||
evidence_scope:
|
||||
- deployment_topology
|
||||
- infrastructure
|
||||
- service_configuration
|
||||
refresh:
|
||||
cadence: on_change
|
||||
triggers:
|
||||
- deployment_manifest_change
|
||||
- infrastructure_manifest_change
|
||||
- operator_request
|
||||
- id: root.openbao.secret-metadata
|
||||
type: secret_root
|
||||
status: planned
|
||||
fabric_id: fabric.railiance.primary
|
||||
owner_actor_id: actor.railiance.king
|
||||
source:
|
||||
repo_slug: railiance-fabric
|
||||
path: fabric/services/railiance-platform-openbao.yaml
|
||||
safe_discovery: metadata_only
|
||||
evidence_scope:
|
||||
- secret_metadata
|
||||
- infrastructure
|
||||
refresh:
|
||||
cadence: manual
|
||||
triggers:
|
||||
- secret_root_change
|
||||
- operator_request
|
||||
notes: Discover only existence and metadata for secret roots; never extract secret values.
|
||||
- id: root.backup-recovery.metadata
|
||||
type: backup_recovery
|
||||
status: planned
|
||||
fabric_id: fabric.railiance.primary
|
||||
owner_actor_id: actor.railiance.king
|
||||
source:
|
||||
path: docs/financial-fabric-operator-guide.md
|
||||
safe_discovery: explicit_review
|
||||
evidence_scope:
|
||||
- backup_recovery
|
||||
- manual_review
|
||||
refresh:
|
||||
cadence: manual
|
||||
triggers:
|
||||
- backup_recovery_change
|
||||
- operator_request
|
||||
refresh:
|
||||
cadence: manual
|
||||
triggers:
|
||||
- operator_request
|
||||
- state_hub_repo_inventory_change
|
||||
- git_commit
|
||||
- deployment_manifest_change
|
||||
- infrastructure_manifest_change
|
||||
- endpoint_contract_change
|
||||
- secret_root_change
|
||||
- backup_recovery_change
|
||||
- lord_or_tenant_change
|
||||
notes: Manual rebuild is the default until snapshot deltas and freshness triggers are implemented.
|
||||
templates:
|
||||
future_subfabric:
|
||||
parent_fabric_id: fabric.railiance.primary
|
||||
tenant_actor_role: tenant
|
||||
required_updates:
|
||||
- Add tenant actor with role tenant.
|
||||
- Add Subfabric under fabric.railiance.primary with tenant_actor_id.
|
||||
- Add tenant-specific discovery roots with subfabric_id.
|
||||
- Add cross-boundary utility edges with provider and consumer owner context.
|
||||
note: Tenant subfabrics do not change the current root fabric criterion.
|
||||
@@ -0,0 +1,404 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: DeploymentZoneInventory
|
||||
generated_at: "2026-05-24T00:00:00+02:00"
|
||||
source:
|
||||
repo: railiance-fabric
|
||||
workplan: RAIL-FAB-WP-0020
|
||||
method: source-search-and-declared-surfaces
|
||||
scope:
|
||||
note: >
|
||||
This inventory captures deployment-zone overlay evidence. It does not
|
||||
define fabric membership, port ownership, live health, or access policy.
|
||||
deployment_environments:
|
||||
- id: dev
|
||||
scenario: bernd-laptop
|
||||
intended_reachability: private operator workstation
|
||||
- id: test
|
||||
scenario: coulombcore
|
||||
intended_reachability: shared collaborator and early-access test stage
|
||||
- id: prod
|
||||
scenario: railiance01
|
||||
intended_reachability: production stage, currently alpha-accessible to developers
|
||||
surfaces:
|
||||
- id: dev.bernd-laptop.railiance-fabric.registry-api
|
||||
name: Railiance Fabric registry HTTP API
|
||||
repo: railiance-fabric
|
||||
service_id: railiance-fabric.registry
|
||||
deployment_environment: dev
|
||||
deployment_scenario: bernd-laptop
|
||||
access_zone: private-dev
|
||||
exposure_class: local-only
|
||||
routing_authority: local-loopback-binding
|
||||
policy_authority: local-loopback-binding
|
||||
route_evidence:
|
||||
route: http://127.0.0.1:8765
|
||||
host: 127.0.0.1
|
||||
port: 8765
|
||||
protocol: http
|
||||
evidence:
|
||||
- path: fabric/interfaces/railiance-fabric-registry-http-api.yaml
|
||||
kind: fabric-interface-declaration
|
||||
- id: dev.bernd-laptop.railiance-fabric.graph-explorer
|
||||
name: Railiance Fabric graph explorer UI
|
||||
repo: railiance-fabric
|
||||
service_id: railiance-fabric.registry
|
||||
deployment_environment: dev
|
||||
deployment_scenario: bernd-laptop
|
||||
access_zone: private-dev
|
||||
exposure_class: local-only
|
||||
routing_authority: local-loopback-binding
|
||||
policy_authority: local-loopback-binding
|
||||
route_evidence:
|
||||
route: http://127.0.0.1:8765/ui/graph-explorer
|
||||
host: 127.0.0.1
|
||||
port: 8765
|
||||
protocol: http
|
||||
path: /ui/graph-explorer
|
||||
evidence:
|
||||
- path: fabric/interfaces/railiance-fabric-registry-graph-explorer-ui.yaml
|
||||
kind: fabric-interface-declaration
|
||||
- id: dev.bernd-laptop.state-hub.api
|
||||
name: State Hub HTTP API
|
||||
repo: the-custodian
|
||||
service_id: the-custodian.state-hub
|
||||
deployment_environment: dev
|
||||
deployment_scenario: bernd-laptop
|
||||
access_zone: private-dev
|
||||
exposure_class: local-only
|
||||
routing_authority: local-loopback-binding
|
||||
policy_authority: local-loopback-binding
|
||||
route_evidence:
|
||||
route: http://127.0.0.1:8000
|
||||
host: 127.0.0.1
|
||||
port: 8000
|
||||
protocol: http
|
||||
evidence:
|
||||
- path: fabric/interfaces/the-custodian-state-hub-http-api.yaml
|
||||
kind: fabric-interface-declaration
|
||||
- id: dev.bernd-laptop.state-hub.mcp
|
||||
name: State Hub MCP API
|
||||
repo: the-custodian
|
||||
service_id: the-custodian.state-hub
|
||||
deployment_environment: dev
|
||||
deployment_scenario: bernd-laptop
|
||||
access_zone: private-dev
|
||||
exposure_class: local-only
|
||||
routing_authority: local-loopback-binding
|
||||
policy_authority: local-loopback-binding
|
||||
route_evidence:
|
||||
route: http://127.0.0.1:8001
|
||||
host: 127.0.0.1
|
||||
port: 8001
|
||||
protocol: http
|
||||
evidence:
|
||||
- path: fabric/interfaces/the-custodian-state-hub-mcp-api.yaml
|
||||
kind: fabric-interface-declaration
|
||||
- id: dev.bernd-laptop.state-hub.dashboard
|
||||
name: State Hub dashboard
|
||||
repo: the-custodian
|
||||
service_id: the-custodian.state-hub
|
||||
deployment_environment: dev
|
||||
deployment_scenario: bernd-laptop
|
||||
access_zone: private-dev
|
||||
exposure_class: local-only
|
||||
routing_authority: local-loopback-binding
|
||||
policy_authority: local-loopback-binding
|
||||
route_evidence:
|
||||
route: http://127.0.0.1:3000
|
||||
host: 127.0.0.1
|
||||
port: 3000
|
||||
protocol: http
|
||||
evidence:
|
||||
- path: fabric/interfaces/the-custodian-state-hub-dashboard.yaml
|
||||
kind: fabric-interface-declaration
|
||||
- id: dev.bernd-laptop.net-kingdom.control-surface
|
||||
name: NetKingdom control surface
|
||||
repo: net-kingdom
|
||||
service_id: net-kingdom.iam-profile
|
||||
deployment_environment: dev
|
||||
deployment_scenario: bernd-laptop
|
||||
access_zone: private-dev
|
||||
exposure_class: local-only
|
||||
routing_authority: local-loopback-binding
|
||||
policy_authority: local-loopback-binding
|
||||
route_evidence:
|
||||
route: http://127.0.0.1:8876
|
||||
host: 127.0.0.1
|
||||
port: 8876
|
||||
protocol: http
|
||||
evidence:
|
||||
- path: fabric/interfaces/net-kingdom-control-surface-ui.yaml
|
||||
kind: fabric-interface-declaration
|
||||
- path: ../net-kingdom/sso-mfa/k8s/keycape/README.md
|
||||
kind: source-search-hit
|
||||
note: local OIDC callback lists localhost port 8876
|
||||
- id: test.coulombcore.state-hub.http-tunnel
|
||||
name: State Hub HTTP API tunnel to coulombcore
|
||||
repo: railiance-infra
|
||||
service_id: the-custodian.state-hub
|
||||
deployment_environment: test
|
||||
deployment_scenario: coulombcore
|
||||
access_zone: collaborator-test
|
||||
exposure_class: collaborator-test
|
||||
routing_authority: ops-bridge
|
||||
policy_authority: ops-bridge-ssh
|
||||
route_evidence:
|
||||
route: http://127.0.0.1:18000
|
||||
host: 127.0.0.1
|
||||
port: 18000
|
||||
protocol: http
|
||||
tunnel_target: coulombcore
|
||||
evidence:
|
||||
- path: ../railiance-infra/docs/deploy-stack.md
|
||||
lines: "127"
|
||||
kind: source-search-hit
|
||||
- id: test.coulombcore.state-hub.mcp-tunnel
|
||||
name: State Hub MCP tunnel to coulombcore
|
||||
repo: railiance-infra
|
||||
service_id: the-custodian.state-hub
|
||||
deployment_environment: test
|
||||
deployment_scenario: coulombcore
|
||||
access_zone: collaborator-test
|
||||
exposure_class: collaborator-test
|
||||
routing_authority: ops-bridge
|
||||
policy_authority: ops-bridge-ssh
|
||||
route_evidence:
|
||||
route: http://127.0.0.1:18001
|
||||
host: 127.0.0.1
|
||||
port: 18001
|
||||
protocol: http
|
||||
tunnel_target: coulombcore
|
||||
evidence:
|
||||
- path: ../railiance-infra/docs/deploy-stack.md
|
||||
lines: "128"
|
||||
kind: source-search-hit
|
||||
- id: test.coulombcore.k3s-api-tunnel
|
||||
name: k3s API tunnel to coulombcore
|
||||
repo: railiance-infra
|
||||
deployment_environment: test
|
||||
deployment_scenario: coulombcore
|
||||
access_zone: collaborator-test
|
||||
exposure_class: collaborator-test
|
||||
routing_authority: ops-bridge
|
||||
policy_authority: ops-bridge-ssh
|
||||
route_evidence:
|
||||
route: https://127.0.0.1:16443
|
||||
host: 127.0.0.1
|
||||
port: 16443
|
||||
protocol: https
|
||||
tunnel_target: coulombcore
|
||||
evidence:
|
||||
- path: ../railiance-infra/docs/deploy-stack.md
|
||||
lines: "129"
|
||||
kind: source-search-hit
|
||||
- path: ../railiance-cluster/SCOPE.md
|
||||
lines: "127"
|
||||
kind: source-search-hit
|
||||
note: cluster scope states it runs on COULOMBCORE
|
||||
- id: prod.railiance01.gitea
|
||||
name: Gitea ingress
|
||||
repo: railiance-apps
|
||||
deployment_environment: prod
|
||||
deployment_scenario: railiance01
|
||||
access_zone: production-public
|
||||
exposure_class: production-public
|
||||
routing_authority: traefik
|
||||
policy_authority: null
|
||||
tls_authority: cert-manager:letsencrypt-prod
|
||||
route_evidence:
|
||||
route: https://gitea.coulomb.social
|
||||
hostname: gitea.coulomb.social
|
||||
port: 443
|
||||
protocol: https
|
||||
review:
|
||||
status: candidate
|
||||
note: access zone and policy authority require operator review
|
||||
evidence:
|
||||
- path: ../railiance-apps/manifests/gitea-ingress.yaml
|
||||
lines: "2,12,14,16,27"
|
||||
kind: kubernetes-ingress
|
||||
- path: ../railiance-apps/workplans/railiance-apps-WP-0002-vergabe-teilnahme-on-railiance01.md
|
||||
lines: "612,613"
|
||||
kind: source-search-hit
|
||||
note: places Gitea before vergabe-teilnahme on railiance01
|
||||
- id: prod.railiance01.vergabe-teilnahme
|
||||
name: Vergabe Teilnahme ingress
|
||||
repo: railiance-apps
|
||||
deployment_environment: prod
|
||||
deployment_scenario: railiance01
|
||||
access_zone: production-public
|
||||
exposure_class: production-public
|
||||
routing_authority: traefik
|
||||
policy_authority: null
|
||||
tls_authority: cert-manager:letsencrypt-prod
|
||||
route_evidence:
|
||||
route: https://vergabe-teilnahme.whywhynot.de
|
||||
hostname: vergabe-teilnahme.whywhynot.de
|
||||
port: 443
|
||||
protocol: https
|
||||
review:
|
||||
status: candidate
|
||||
note: production public classification is inferred from ingress host and workplan
|
||||
evidence:
|
||||
- path: ../railiance-apps/manifests/vergabe-teilnahme-ingress.yaml
|
||||
lines: "2,11,13,15,26"
|
||||
kind: kubernetes-ingress
|
||||
- path: ../railiance-apps/workplans/railiance-apps-WP-0002-vergabe-teilnahme-on-railiance01.md
|
||||
lines: "22,40,68,69,163,612,613"
|
||||
kind: source-search-hit
|
||||
- id: prod.railiance01.authelia
|
||||
name: Authelia ingress
|
||||
repo: net-kingdom
|
||||
deployment_environment: prod
|
||||
deployment_scenario: railiance01
|
||||
access_zone: production-public
|
||||
exposure_class: production-public
|
||||
routing_authority: traefik
|
||||
policy_authority: authelia
|
||||
tls_authority: cert-manager:letsencrypt-prod
|
||||
route_evidence:
|
||||
route: https://auth.coulomb.social
|
||||
hostname: auth.coulomb.social
|
||||
port: 443
|
||||
protocol: https
|
||||
review:
|
||||
status: candidate
|
||||
note: railiance01 attribution comes from NetKingdom deployment workplan
|
||||
evidence:
|
||||
- path: ../net-kingdom/sso-mfa/k8s/authelia/ingress.yaml
|
||||
lines: "13,22,24,26,38"
|
||||
kind: kubernetes-ingress
|
||||
- path: ../net-kingdom/workplans/NK-WP-0003-keycape-privacyidea-cluster-deployment.md
|
||||
lines: "29,47,88,101"
|
||||
kind: source-search-hit
|
||||
- id: prod.railiance01.keycape
|
||||
name: Keycape ingress
|
||||
repo: net-kingdom
|
||||
deployment_environment: prod
|
||||
deployment_scenario: railiance01
|
||||
access_zone: production-public
|
||||
exposure_class: production-public
|
||||
routing_authority: traefik
|
||||
policy_authority: traefik-middleware
|
||||
tls_authority: cert-manager:letsencrypt-prod
|
||||
route_evidence:
|
||||
route: https://kc.coulomb.social
|
||||
hostname: kc.coulomb.social
|
||||
port: 443
|
||||
protocol: https
|
||||
review:
|
||||
status: candidate
|
||||
note: middleware is present, but intended audience still needs operator review
|
||||
evidence:
|
||||
- path: ../net-kingdom/sso-mfa/k8s/keycape/ingress.yaml
|
||||
lines: "13,22,23,27,29,41"
|
||||
kind: kubernetes-ingress
|
||||
- path: ../net-kingdom/sso-mfa/k8s/keycape/middleware.yaml
|
||||
lines: "9,24"
|
||||
kind: traefik-middleware
|
||||
- id: prod.railiance01.privacyidea
|
||||
name: privacyIDEA ingress
|
||||
repo: net-kingdom
|
||||
deployment_environment: prod
|
||||
deployment_scenario: railiance01
|
||||
access_zone: production-admin
|
||||
exposure_class: production-admin
|
||||
routing_authority: traefik
|
||||
policy_authority: traefik-middleware
|
||||
tls_authority: cert-manager:letsencrypt-prod
|
||||
route_evidence:
|
||||
route: https://pink.coulomb.social
|
||||
hostname: pink.coulomb.social
|
||||
port: 443
|
||||
protocol: https
|
||||
review:
|
||||
status: candidate
|
||||
note: admin classification inferred from privacyIDEA role and middleware
|
||||
evidence:
|
||||
- path: ../net-kingdom/sso-mfa/k8s/privacyidea/ingress.yaml
|
||||
lines: "25,34,36,38,40,52,60,69,71,75,77,89"
|
||||
kind: kubernetes-ingress
|
||||
- path: ../net-kingdom/sso-mfa/k8s/privacyidea/middleware.yaml
|
||||
lines: "19,41"
|
||||
kind: traefik-middleware
|
||||
- id: prod.railiance01.privacyidea-account
|
||||
name: privacyIDEA account self-service ingress
|
||||
repo: net-kingdom
|
||||
deployment_environment: prod
|
||||
deployment_scenario: railiance01
|
||||
access_zone: production-public
|
||||
exposure_class: production-public
|
||||
routing_authority: traefik
|
||||
policy_authority: traefik-middleware
|
||||
tls_authority: cert-manager:letsencrypt-prod
|
||||
route_evidence:
|
||||
route: https://pink-account.coulomb.social
|
||||
hostname: pink-account.coulomb.social
|
||||
port: 443
|
||||
protocol: https
|
||||
review:
|
||||
status: candidate
|
||||
note: self-service classification inferred from host name and middleware
|
||||
evidence:
|
||||
- path: ../net-kingdom/sso-mfa/k8s/privacyidea/ingress.yaml
|
||||
lines: "94,103,104,106,108,120"
|
||||
kind: kubernetes-ingress
|
||||
- id: prod.railiance01.lldap
|
||||
name: LLDAP ingress
|
||||
repo: net-kingdom
|
||||
deployment_environment: prod
|
||||
deployment_scenario: railiance01
|
||||
access_zone: production-admin
|
||||
exposure_class: production-admin
|
||||
routing_authority: traefik
|
||||
policy_authority: traefik-admin-allowlist
|
||||
tls_authority: cert-manager:letsencrypt-prod
|
||||
route_evidence:
|
||||
route: https://lldap.coulomb.social
|
||||
hostname: lldap.coulomb.social
|
||||
port: 443
|
||||
protocol: https
|
||||
review:
|
||||
status: candidate
|
||||
note: admin allowlist middleware indicates intended restricted access
|
||||
evidence:
|
||||
- path: ../net-kingdom/sso-mfa/k8s/lldap/ingress.yaml
|
||||
lines: "12,21,22,24,26,38"
|
||||
kind: kubernetes-ingress
|
||||
- path: ../net-kingdom/sso-mfa/k8s/lldap/middleware.yaml
|
||||
lines: "11"
|
||||
kind: traefik-middleware
|
||||
ambiguities:
|
||||
- id: railiance01-coulombcore-ip-conflict
|
||||
severity: high
|
||||
summary: Source documents disagree on which host owns 92.205.130.254.
|
||||
evidence:
|
||||
- path: ../railiance-apps/workplans/railiance-apps-WP-0002-vergabe-teilnahme-on-railiance01.md
|
||||
lines: "22,163"
|
||||
note: says railiance01 and Traefik LoadBalancer use 92.205.130.254
|
||||
- path: ../railiance-infra/SCOPE.md
|
||||
lines: "126"
|
||||
note: says COULOMBCORE is 92.205.130.254 and Railiance01 is 92.205.62.239
|
||||
next: reconcile host inventory before treating IP evidence as authoritative
|
||||
- id: prod-access-zone-review
|
||||
severity: medium
|
||||
summary: Production access zones are candidate classifications.
|
||||
evidence:
|
||||
- path: ../railiance-apps/manifests
|
||||
note: app ingress manifests show routing and TLS but not business audience
|
||||
- path: ../net-kingdom/sso-mfa/k8s
|
||||
note: middleware and network policy hint at access intent but do not replace operator review
|
||||
next: confirm each production host as public, admin, or early-access
|
||||
- id: test-reachability-is-tunneled
|
||||
severity: medium
|
||||
summary: Current coulombcore routes are ops-bridge tunnel evidence, not public ingress evidence.
|
||||
evidence:
|
||||
- path: ../railiance-infra/docs/deploy-stack.md
|
||||
lines: "127,128,129"
|
||||
note: state-hub and k3s API access are tunnel commands
|
||||
next: add executable test-stage ingress/service discovery when coulombcore manifests exist
|
||||
missing_policy_authority:
|
||||
- surface_id: prod.railiance01.gitea
|
||||
reason: route and TLS are discovered, but access policy authority is not evident in the ingress artifact
|
||||
- surface_id: prod.railiance01.vergabe-teilnahme
|
||||
reason: route and TLS are discovered, but access policy authority is not evident in the ingress artifact
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,138 @@
|
||||
{
|
||||
"apiVersion": "railiance.fabric/v1alpha2",
|
||||
"change_sets": {
|
||||
"blockers": [],
|
||||
"containment": [],
|
||||
"ownership": [],
|
||||
"review_state": []
|
||||
},
|
||||
"current": {
|
||||
"generated_at": "2026-05-24T12:04:20Z",
|
||||
"manifest_fingerprint": "dd279b655d68222a99671c1c875afdaa70ae2f907fd526e6673ddf756bc90dae",
|
||||
"manifest_id": "railiance.accountability-roots"
|
||||
},
|
||||
"edge_delta": {
|
||||
"added": [
|
||||
"candidate-edge:d448183c64bba5c0"
|
||||
],
|
||||
"changed": [],
|
||||
"removed": [],
|
||||
"unchanged": []
|
||||
},
|
||||
"generated_at": "2026-05-24T12:04:59Z",
|
||||
"kind": "AccountabilityUpdateDelta",
|
||||
"node_delta": {
|
||||
"added": [
|
||||
"identity:actor:actor.railiance.king",
|
||||
"identity:actor:actor.railiance.primary-lord",
|
||||
"identity:backup-recovery-root:docs-financial-fabric-operator-guide.md",
|
||||
"identity:catalog-root:gitea_organization",
|
||||
"identity:catalog-root:registry_manifest",
|
||||
"identity:deployable:home-worsch-.config-systemd-user-custodian-sync.service",
|
||||
"identity:deployable:home-worsch-activity-core-dockerfile",
|
||||
"identity:deployable:home-worsch-go-src-crypto-internal-boring-dockerfile",
|
||||
"identity:deployable:home-worsch-go-src-crypto-internal-nistec-fiat-dockerfile",
|
||||
"identity:deployable:home-worsch-key-cape-dockerfile",
|
||||
"identity:deployable:home-worsch-repo-scoping-var-checkouts-key-cape-a01db9828dd4-dockerfile",
|
||||
"identity:deployable:home-worsch-state-hub-dockerfile",
|
||||
"identity:deployable:home-worsch-the-custodian-infra-build-machines-haskell-files-build-agent.service",
|
||||
"identity:deployable:home-worsch-vergabe-teilnahme-dockerfile",
|
||||
"identity:fabric:fabric.railiance.primary",
|
||||
"identity:host-path:fabric",
|
||||
"identity:host-path:git",
|
||||
"identity:host-path:home-worsch-.nvm-.git",
|
||||
"identity:host-path:home-worsch-activity-core-.git",
|
||||
"identity:host-path:home-worsch-artifact-store-.git",
|
||||
"identity:host-path:home-worsch-can-you-assist-.git",
|
||||
"identity:host-path:home-worsch-domain-tree-.git",
|
||||
"identity:host-path:home-worsch-flex-auth-.git",
|
||||
"identity:host-path:home-worsch-guide-board-.git",
|
||||
"identity:host-path:home-worsch-helix-forge-.git",
|
||||
"identity:host-path:home-worsch-ihp-railiance-probe-.git",
|
||||
"identity:host-path:home-worsch-info-tech-canon-.git",
|
||||
"identity:host-path:home-worsch-infospace-bench-.git",
|
||||
"identity:host-path:home-worsch-inter-hub-.git",
|
||||
"identity:host-path:home-worsch-issue-core-.git",
|
||||
"identity:host-path:home-worsch-key-cape-.git",
|
||||
"identity:host-path:home-worsch-kontextual-engine-.git",
|
||||
"identity:host-path:home-worsch-llm-connect-.git",
|
||||
"identity:host-path:home-worsch-markitect-filter-.git",
|
||||
"identity:host-path:home-worsch-markitect-main-.git",
|
||||
"identity:host-path:home-worsch-markitect-quarkdown-.git",
|
||||
"identity:host-path:home-worsch-markitect-tool-.git",
|
||||
"identity:host-path:home-worsch-net-kingdom-.git",
|
||||
"identity:host-path:home-worsch-open-cmis-tck-.git",
|
||||
"identity:host-path:home-worsch-open-reuse-.git",
|
||||
"identity:host-path:home-worsch-ops-bridge-.git",
|
||||
"identity:host-path:home-worsch-ops-warden-.git",
|
||||
"identity:host-path:home-worsch-phase-memory-.git",
|
||||
"identity:host-path:home-worsch-railiance-apps-.git",
|
||||
"identity:host-path:home-worsch-railiance-cluster-.git",
|
||||
"identity:host-path:home-worsch-railiance-enablement-.git",
|
||||
"identity:host-path:home-worsch-railiance-infra-.git",
|
||||
"identity:host-path:home-worsch-railiance-platform-.git",
|
||||
"identity:host-path:home-worsch-repo-scoping-.git",
|
||||
"identity:host-path:home-worsch-repo-seed-.git",
|
||||
"identity:host-path:home-worsch-shard-wiki-.git",
|
||||
"identity:host-path:home-worsch-state-hub-.git",
|
||||
"identity:host-path:home-worsch-tegwick-control-.git",
|
||||
"identity:host-path:home-worsch-the-custodian-.git",
|
||||
"identity:host-path:home-worsch-user-engine-.git",
|
||||
"identity:host-path:home-worsch-vantage-point-.git",
|
||||
"identity:host-path:home-worsch-vergabe-teilnahme-.git",
|
||||
"identity:host-path:home-worsch-whynot-control-.git",
|
||||
"identity:host-path:home-worsch-whynot-design-.git",
|
||||
"identity:netkingdom:railiance.netkingdom",
|
||||
"identity:repository:activity-core",
|
||||
"identity:repository:artifact-store",
|
||||
"identity:repository:domain-tree",
|
||||
"identity:repository:flex-auth",
|
||||
"identity:repository:guide-board",
|
||||
"identity:repository:helix-forge",
|
||||
"identity:repository:ihp-railiance-probe",
|
||||
"identity:repository:infospace-bench",
|
||||
"identity:repository:inter-hub",
|
||||
"identity:repository:issue-core",
|
||||
"identity:repository:key-cape",
|
||||
"identity:repository:kontextual-engine",
|
||||
"identity:repository:llm-connect",
|
||||
"identity:repository:markitect-filter",
|
||||
"identity:repository:markitect-project",
|
||||
"identity:repository:markitect-quarkdown",
|
||||
"identity:repository:markitect-tool",
|
||||
"identity:repository:net-kingdom",
|
||||
"identity:repository:open-cmis-tck",
|
||||
"identity:repository:open-reuse",
|
||||
"identity:repository:ops-bridge",
|
||||
"identity:repository:ops-warden",
|
||||
"identity:repository:phase-memory",
|
||||
"identity:repository:railiance-apps",
|
||||
"identity:repository:railiance-cluster",
|
||||
"identity:repository:railiance-enablement",
|
||||
"identity:repository:railiance-fabric",
|
||||
"identity:repository:railiance-infra",
|
||||
"identity:repository:railiance-platform",
|
||||
"identity:repository:repo-scoping",
|
||||
"identity:repository:state-hub",
|
||||
"identity:repository:the-custodian",
|
||||
"identity:repository:vergabe-teilnahme",
|
||||
"identity:secret-root:fabric-services-railiance-platform-openbao.yaml"
|
||||
],
|
||||
"changed": [],
|
||||
"removed": [],
|
||||
"unchanged": []
|
||||
},
|
||||
"previous": {},
|
||||
"summary": {
|
||||
"edges_added": 1,
|
||||
"edges_changed": 0,
|
||||
"edges_removed": 0,
|
||||
"edges_unchanged": 0,
|
||||
"meaningful_change_count": 95,
|
||||
"nodes_added": 94,
|
||||
"nodes_changed": 0,
|
||||
"nodes_removed": 0,
|
||||
"nodes_unchanged": 0,
|
||||
"promotion_needed": true
|
||||
}
|
||||
}
|
||||
65
fabric/financial/railiance-netkingdom.yaml
Normal file
65
fabric/financial/railiance-netkingdom.yaml
Normal file
@@ -0,0 +1,65 @@
|
||||
apiVersion: railiance.fabric/v1alpha2
|
||||
kind: FinancialFabricBaseline
|
||||
metadata:
|
||||
id: railiance.netkingdom-baseline
|
||||
name: Railiance Netkingdom Baseline
|
||||
spec:
|
||||
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
|
||||
description: Responsible for the Railiance netkingdom and recovery authority.
|
||||
authority:
|
||||
recovery_authority: true
|
||||
secrets_authority: true
|
||||
backup_authority: true
|
||||
termination_authority: true
|
||||
- id: actor.railiance.primary-lord
|
||||
kind: FabricActor
|
||||
role: lord
|
||||
name: Railiance Primary Lord
|
||||
description: Pays for the current Railiance infrastructure boundary.
|
||||
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
|
||||
payment_responsibility: actor.railiance.primary-lord
|
||||
operational_responsibility: actor.railiance.king
|
||||
recovery_responsibility: actor.railiance.king
|
||||
evidence_refs: []
|
||||
defaults:
|
||||
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:
|
||||
- actor.railiance.king
|
||||
accounting:
|
||||
cost_center_id: null
|
||||
profit_center_id: null
|
||||
allocation_model: null
|
||||
future_subfabric_template:
|
||||
kind: Subfabric
|
||||
parent_fabric_id: fabric.railiance.primary
|
||||
netkingdom_id: railiance.netkingdom
|
||||
tenant_actor_role: tenant
|
||||
note: Add a tenant actor and subfabric without changing the root fabric criterion.
|
||||
35
fabric/interfaces/net-kingdom-control-surface-ui.yaml
Normal file
35
fabric/interfaces/net-kingdom-control-surface-ui.yaml
Normal file
@@ -0,0 +1,35 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: InterfaceDeclaration
|
||||
metadata:
|
||||
id: net-kingdom.control-surface.ui
|
||||
name: NetKingdom Control Surface
|
||||
owner: net-kingdom
|
||||
repo: net-kingdom
|
||||
domain: railiance
|
||||
spec:
|
||||
lifecycle: active
|
||||
environments: [dev]
|
||||
description: Local NetKingdom control surface on the operator workstation.
|
||||
interface_type: web-ui
|
||||
version: v1
|
||||
service_id: net-kingdom.iam-profile
|
||||
capability_ids:
|
||||
- net-kingdom.iam-profile.issuer
|
||||
endpoint:
|
||||
url: http://127.0.0.1:8876
|
||||
notes: Local workstation endpoint after moving away from the Fabric registry port.
|
||||
deployment_overlay:
|
||||
deployment_environment: dev
|
||||
deployment_scenario: bernd-laptop
|
||||
routing_authority: net-kingdom-local-process
|
||||
access_zone: private-dev
|
||||
policy_authority: local-loopback-binding
|
||||
exposure_class: local-only
|
||||
route_evidence:
|
||||
host: 127.0.0.1
|
||||
port: 8876
|
||||
protocol: tcp
|
||||
route: http://127.0.0.1:8876
|
||||
auth:
|
||||
method: none
|
||||
data_classification: internal
|
||||
23
fabric/interfaces/railiance-cluster-kubernetes-api.yaml
Normal file
23
fabric/interfaces/railiance-cluster-kubernetes-api.yaml
Normal file
@@ -0,0 +1,23 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: InterfaceDeclaration
|
||||
metadata:
|
||||
id: railiance-cluster.kubernetes.api
|
||||
name: Kubernetes API
|
||||
owner: railiance-cluster
|
||||
repo: railiance-cluster
|
||||
domain: railiance
|
||||
source_links:
|
||||
- label: Cluster scope
|
||||
path: /home/worsch/railiance-cluster/SCOPE.md
|
||||
spec:
|
||||
lifecycle: active
|
||||
environments: [dev, staging, prod]
|
||||
description: Kubernetes API surface and RBAC-controlled runtime contract consumed by Railiance workloads and operators.
|
||||
interface_type: kubernetes-api
|
||||
version: v1
|
||||
service_id: railiance-cluster.kubernetes
|
||||
capability_ids:
|
||||
- railiance-cluster.kubernetes.runtime
|
||||
auth:
|
||||
method: kubernetes_service_account
|
||||
data_classification: restricted
|
||||
@@ -0,0 +1,23 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: InterfaceDeclaration
|
||||
metadata:
|
||||
id: railiance-enablement.delivery-templates.workflow-template-contract
|
||||
name: Workflow template contract
|
||||
owner: railiance-enablement
|
||||
repo: railiance-enablement
|
||||
domain: railiance
|
||||
source_links:
|
||||
- label: Enablement scope
|
||||
path: /home/worsch/railiance-enablement/SCOPE.md
|
||||
spec:
|
||||
lifecycle: planned
|
||||
environments: [dev, staging, prod]
|
||||
description: Template contract for reusable Railiance CI/CD and GitOps workflow patterns.
|
||||
interface_type: workflow-template-contract
|
||||
version: v1
|
||||
service_id: railiance-enablement.delivery-templates
|
||||
capability_ids:
|
||||
- railiance-enablement.delivery-templates.ci-cd-templates
|
||||
auth:
|
||||
method: none
|
||||
data_classification: internal
|
||||
@@ -0,0 +1,40 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: InterfaceDeclaration
|
||||
metadata:
|
||||
id: railiance-fabric.registry.graph-explorer-ui
|
||||
name: Railiance Fabric Graph Explorer UI
|
||||
owner: railiance-fabric
|
||||
repo: railiance-fabric
|
||||
domain: railiance
|
||||
source_links:
|
||||
- label: UI shell
|
||||
path: railiance_fabric/graph_explorer_ui.py
|
||||
- label: Graph explorer operations
|
||||
path: docs/graph-explorer-operations.md
|
||||
spec:
|
||||
lifecycle: active
|
||||
environments: [dev]
|
||||
description: Browser UI for exploring the local Fabric registry graph, onboarding gaps, dependencies, interfaces, saved local views, and shareable graph state.
|
||||
interface_type: web-ui
|
||||
version: v1alpha1
|
||||
service_id: railiance-fabric.registry
|
||||
capability_ids:
|
||||
- railiance-fabric.registry.ecosystem-registry
|
||||
endpoint:
|
||||
url: http://127.0.0.1:8765/ui/graph-explorer
|
||||
notes: Local workstation UI when the registry service is running.
|
||||
deployment_overlay:
|
||||
deployment_environment: dev
|
||||
deployment_scenario: bernd-laptop
|
||||
routing_authority: railiance-fabric-registry
|
||||
access_zone: private-dev
|
||||
policy_authority: local-loopback-binding
|
||||
exposure_class: local-only
|
||||
route_evidence:
|
||||
host: 127.0.0.1
|
||||
port: 8765
|
||||
protocol: tcp
|
||||
route: http://127.0.0.1:8765/ui/graph-explorer
|
||||
auth:
|
||||
method: none
|
||||
data_classification: internal
|
||||
40
fabric/interfaces/railiance-fabric-registry-http-api.yaml
Normal file
40
fabric/interfaces/railiance-fabric-registry-http-api.yaml
Normal file
@@ -0,0 +1,40 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: InterfaceDeclaration
|
||||
metadata:
|
||||
id: railiance-fabric.registry.http-api
|
||||
name: Railiance Fabric Registry HTTP API
|
||||
owner: railiance-fabric
|
||||
repo: railiance-fabric
|
||||
domain: railiance
|
||||
source_links:
|
||||
- label: HTTP routes
|
||||
path: railiance_fabric/server.py
|
||||
- label: API docs
|
||||
path: docs/registry-api.md
|
||||
spec:
|
||||
lifecycle: active
|
||||
environments: [dev]
|
||||
description: Local HTTP API for repository registration, graph snapshot ingestion, graph queries, inventory views, State Hub export, Backstage projection, xRegistry projection, and graph explorer payloads.
|
||||
interface_type: http-api
|
||||
version: v1alpha1
|
||||
service_id: railiance-fabric.registry
|
||||
capability_ids:
|
||||
- railiance-fabric.registry.ecosystem-registry
|
||||
endpoint:
|
||||
url: http://127.0.0.1:8765
|
||||
notes: Local workstation endpoint when the registry service is running.
|
||||
deployment_overlay:
|
||||
deployment_environment: dev
|
||||
deployment_scenario: bernd-laptop
|
||||
routing_authority: local-process
|
||||
access_zone: private-dev
|
||||
policy_authority: local-loopback-binding
|
||||
exposure_class: local-only
|
||||
route_evidence:
|
||||
host: 127.0.0.1
|
||||
port: 8765
|
||||
protocol: tcp
|
||||
route: http://127.0.0.1:8765
|
||||
auth:
|
||||
method: none
|
||||
data_classification: internal
|
||||
23
fabric/interfaces/railiance-forge-evidence-contract.yaml
Normal file
23
fabric/interfaces/railiance-forge-evidence-contract.yaml
Normal file
@@ -0,0 +1,23 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: InterfaceDeclaration
|
||||
metadata:
|
||||
id: railiance-forge.source-forge.evidence-contract
|
||||
name: Forge evidence contract
|
||||
owner: railiance-forge
|
||||
repo: railiance-forge
|
||||
domain: railiance
|
||||
source_links:
|
||||
- label: Observability and evidence contract
|
||||
path: /home/worsch/railiance-forge/docs/observability-operating-evidence.md
|
||||
spec:
|
||||
lifecycle: active
|
||||
environments: [dev, staging, prod]
|
||||
description: Release-readiness, artifact promotion, restore, storage, and operating evidence contract for forge consumers.
|
||||
interface_type: evidence-contract
|
||||
version: v1
|
||||
service_id: railiance-forge.source-forge
|
||||
capability_ids:
|
||||
- railiance-forge.source-forge.artifact-promotion-evidence
|
||||
auth:
|
||||
method: none
|
||||
data_classification: internal
|
||||
25
fabric/interfaces/railiance-forge-git-ssh.yaml
Normal file
25
fabric/interfaces/railiance-forge-git-ssh.yaml
Normal file
@@ -0,0 +1,25 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: InterfaceDeclaration
|
||||
metadata:
|
||||
id: railiance-forge.source-forge.git-ssh
|
||||
name: Git SSH endpoint
|
||||
owner: railiance-forge
|
||||
repo: railiance-forge
|
||||
domain: railiance
|
||||
source_links:
|
||||
- label: Observability and evidence contract
|
||||
path: /home/worsch/railiance-forge/docs/observability-operating-evidence.md
|
||||
spec:
|
||||
lifecycle: planned
|
||||
environments: [dev, staging, prod]
|
||||
description: Git-over-SSH endpoint contract for repository clone, fetch, and push operations when exposed.
|
||||
interface_type: git-ssh
|
||||
version: gitea-current
|
||||
service_id: railiance-forge.source-forge
|
||||
capability_ids:
|
||||
- railiance-forge.source-forge.source-hosting
|
||||
endpoint:
|
||||
notes: Record the published SSH host and port once the endpoint is verified.
|
||||
auth:
|
||||
method: static_secret
|
||||
data_classification: confidential
|
||||
28
fabric/interfaces/railiance-forge-oci-registry.yaml
Normal file
28
fabric/interfaces/railiance-forge-oci-registry.yaml
Normal file
@@ -0,0 +1,28 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: InterfaceDeclaration
|
||||
metadata:
|
||||
id: railiance-forge.source-forge.oci-registry
|
||||
name: Gitea OCI registry
|
||||
owner: railiance-forge
|
||||
repo: railiance-forge
|
||||
domain: railiance
|
||||
source_links:
|
||||
- label: Container registry docs
|
||||
path: /home/worsch/railiance-forge/docs/gitea-container-registry.md
|
||||
spec:
|
||||
lifecycle: active
|
||||
environments: [dev, staging, prod]
|
||||
description: OCI registry endpoint served by current Gitea for Railiance container images.
|
||||
interface_type: oci-registry
|
||||
version: registry-v2
|
||||
service_id: railiance-forge.source-forge
|
||||
capability_ids:
|
||||
- railiance-forge.source-forge.container-registry
|
||||
endpoint:
|
||||
url: https://gitea.coulomb.social/v2/
|
||||
auth:
|
||||
method: api_key
|
||||
scopes:
|
||||
- package:read
|
||||
- package:write
|
||||
data_classification: confidential
|
||||
28
fabric/interfaces/railiance-forge-python-package-index.yaml
Normal file
28
fabric/interfaces/railiance-forge-python-package-index.yaml
Normal file
@@ -0,0 +1,28 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: InterfaceDeclaration
|
||||
metadata:
|
||||
id: railiance-forge.source-forge.python-package-index
|
||||
name: Gitea Python package index
|
||||
owner: railiance-forge
|
||||
repo: railiance-forge
|
||||
domain: railiance
|
||||
source_links:
|
||||
- label: Package registry docs
|
||||
path: /home/worsch/railiance-forge/docs/gitea-package-registry.md
|
||||
spec:
|
||||
lifecycle: active
|
||||
environments: [dev, staging, prod]
|
||||
description: Python package index endpoint served by current Gitea for internal Railiance packages.
|
||||
interface_type: python-package-index
|
||||
version: simple-api
|
||||
service_id: railiance-forge.source-forge
|
||||
capability_ids:
|
||||
- railiance-forge.source-forge.python-package-registry
|
||||
endpoint:
|
||||
url: https://gitea.coulomb.social/api/packages/coulomb/pypi/simple/
|
||||
auth:
|
||||
method: api_key
|
||||
scopes:
|
||||
- package:read
|
||||
- package:write
|
||||
data_classification: confidential
|
||||
23
fabric/interfaces/railiance-forge-runner-label-contract.yaml
Normal file
23
fabric/interfaces/railiance-forge-runner-label-contract.yaml
Normal file
@@ -0,0 +1,23 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: InterfaceDeclaration
|
||||
metadata:
|
||||
id: railiance-forge.source-forge.runner-label-contract
|
||||
name: Runner label contract
|
||||
owner: railiance-forge
|
||||
repo: railiance-forge
|
||||
domain: railiance
|
||||
source_links:
|
||||
- label: Runner ownership contract
|
||||
path: /home/worsch/railiance-forge/docs/ci-runner-actions-gitops-ownership.md
|
||||
spec:
|
||||
lifecycle: planned
|
||||
environments: [dev, staging, prod]
|
||||
description: Semantic runner labels, placement, trust levels, and credential boundaries consumed by workflow templates and release checks.
|
||||
interface_type: workflow-runner-label-contract
|
||||
version: v1
|
||||
service_id: railiance-forge.source-forge
|
||||
capability_ids:
|
||||
- railiance-forge.source-forge.workflow-runner-substrate
|
||||
auth:
|
||||
method: none
|
||||
data_classification: internal
|
||||
25
fabric/interfaces/railiance-forge-web-ui.yaml
Normal file
25
fabric/interfaces/railiance-forge-web-ui.yaml
Normal file
@@ -0,0 +1,25 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: InterfaceDeclaration
|
||||
metadata:
|
||||
id: railiance-forge.source-forge.web-ui
|
||||
name: Source forge web UI
|
||||
owner: railiance-forge
|
||||
repo: railiance-forge
|
||||
domain: railiance
|
||||
source_links:
|
||||
- label: Observability and evidence contract
|
||||
path: /home/worsch/railiance-forge/docs/observability-operating-evidence.md
|
||||
spec:
|
||||
lifecycle: active
|
||||
environments: [dev, staging, prod]
|
||||
description: Current Gitea web UI and HTTP endpoint for source hosting and package workflows.
|
||||
interface_type: web-ui
|
||||
version: gitea-current
|
||||
service_id: railiance-forge.source-forge
|
||||
capability_ids:
|
||||
- railiance-forge.source-forge.source-hosting
|
||||
endpoint:
|
||||
url: https://gitea.coulomb.social/
|
||||
auth:
|
||||
method: unknown
|
||||
data_classification: confidential
|
||||
35
fabric/interfaces/the-custodian-state-hub-dashboard.yaml
Normal file
35
fabric/interfaces/the-custodian-state-hub-dashboard.yaml
Normal file
@@ -0,0 +1,35 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: InterfaceDeclaration
|
||||
metadata:
|
||||
id: the-custodian.state-hub.dashboard
|
||||
name: State Hub Dashboard
|
||||
owner: the-custodian
|
||||
repo: the-custodian
|
||||
domain: custodian
|
||||
spec:
|
||||
lifecycle: active
|
||||
environments: [dev]
|
||||
description: Local browser dashboard for State Hub coordination views.
|
||||
interface_type: web-ui
|
||||
version: v1
|
||||
service_id: the-custodian.state-hub
|
||||
capability_ids:
|
||||
- the-custodian.state-hub.coordination
|
||||
endpoint:
|
||||
url: http://127.0.0.1:3000
|
||||
notes: Local workstation dashboard endpoint when the State Hub frontend is running.
|
||||
deployment_overlay:
|
||||
deployment_environment: dev
|
||||
deployment_scenario: bernd-laptop
|
||||
routing_authority: vite-dev-server
|
||||
access_zone: private-dev
|
||||
policy_authority: local-loopback-binding
|
||||
exposure_class: local-only
|
||||
route_evidence:
|
||||
host: 127.0.0.1
|
||||
port: 3000
|
||||
protocol: tcp
|
||||
route: http://127.0.0.1:3000
|
||||
auth:
|
||||
method: none
|
||||
data_classification: internal
|
||||
@@ -15,6 +15,21 @@ spec:
|
||||
service_id: the-custodian.state-hub
|
||||
capability_ids:
|
||||
- the-custodian.state-hub.coordination
|
||||
endpoint:
|
||||
url: http://127.0.0.1:8000
|
||||
notes: Local workstation State Hub REST API.
|
||||
deployment_overlay:
|
||||
deployment_environment: dev
|
||||
deployment_scenario: bernd-laptop
|
||||
routing_authority: state-hub-local-process
|
||||
access_zone: private-dev
|
||||
policy_authority: local-loopback-binding
|
||||
exposure_class: local-only
|
||||
route_evidence:
|
||||
host: 127.0.0.1
|
||||
port: 8000
|
||||
protocol: tcp
|
||||
route: http://127.0.0.1:8000
|
||||
auth:
|
||||
method: none
|
||||
data_classification: internal
|
||||
|
||||
35
fabric/interfaces/the-custodian-state-hub-mcp-api.yaml
Normal file
35
fabric/interfaces/the-custodian-state-hub-mcp-api.yaml
Normal file
@@ -0,0 +1,35 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: InterfaceDeclaration
|
||||
metadata:
|
||||
id: the-custodian.state-hub.mcp-api
|
||||
name: State Hub MCP API
|
||||
owner: the-custodian
|
||||
repo: the-custodian
|
||||
domain: custodian
|
||||
spec:
|
||||
lifecycle: active
|
||||
environments: [dev]
|
||||
description: Local MCP surface for State Hub coordination tools.
|
||||
interface_type: mcp-api
|
||||
version: v1
|
||||
service_id: the-custodian.state-hub
|
||||
capability_ids:
|
||||
- the-custodian.state-hub.coordination
|
||||
endpoint:
|
||||
url: http://127.0.0.1:8001
|
||||
notes: Local workstation MCP endpoint when State Hub is running.
|
||||
deployment_overlay:
|
||||
deployment_environment: dev
|
||||
deployment_scenario: bernd-laptop
|
||||
routing_authority: state-hub-local-process
|
||||
access_zone: private-dev
|
||||
policy_authority: local-loopback-binding
|
||||
exposure_class: local-only
|
||||
route_evidence:
|
||||
host: 127.0.0.1
|
||||
port: 8001
|
||||
protocol: tcp
|
||||
route: http://127.0.0.1:8001
|
||||
auth:
|
||||
method: none
|
||||
data_classification: internal
|
||||
@@ -15,3 +15,4 @@ spec:
|
||||
- net-kingdom.iam-profile.issuer
|
||||
exposes_interfaces:
|
||||
- net-kingdom.iam-profile.oidc-discovery
|
||||
- net-kingdom.control-surface.ui
|
||||
|
||||
18
fabric/services/railiance-apps-s5-releases.yaml
Normal file
18
fabric/services/railiance-apps-s5-releases.yaml
Normal file
@@ -0,0 +1,18 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: ServiceDeclaration
|
||||
metadata:
|
||||
id: railiance-apps.s5-releases
|
||||
name: Railiance S5 app releases
|
||||
owner: railiance-apps
|
||||
repo: railiance-apps
|
||||
domain: railiance
|
||||
source_links:
|
||||
- label: Apps scope
|
||||
path: /home/worsch/railiance-apps/SCOPE.md
|
||||
spec:
|
||||
lifecycle: active
|
||||
environments: [dev, staging, prod]
|
||||
description: S5 application release surface that consumes forge artifacts, app manifests, runbooks, dry-runs, and smoke evidence.
|
||||
service_type: app-release-surface
|
||||
provides_capabilities: []
|
||||
exposes_interfaces: []
|
||||
20
fabric/services/railiance-cluster-kubernetes.yaml
Normal file
20
fabric/services/railiance-cluster-kubernetes.yaml
Normal file
@@ -0,0 +1,20 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: ServiceDeclaration
|
||||
metadata:
|
||||
id: railiance-cluster.kubernetes
|
||||
name: Railiance Kubernetes runtime
|
||||
owner: railiance-cluster
|
||||
repo: railiance-cluster
|
||||
domain: railiance
|
||||
source_links:
|
||||
- label: Cluster scope
|
||||
path: /home/worsch/railiance-cluster/SCOPE.md
|
||||
spec:
|
||||
lifecycle: active
|
||||
environments: [dev, staging, prod]
|
||||
description: Kubernetes runtime layer that provides the API server, namespaces, workloads, Services, Ingresses, and controller substrate for Railiance services.
|
||||
service_type: cluster-runtime
|
||||
provides_capabilities:
|
||||
- railiance-cluster.kubernetes.runtime
|
||||
exposes_interfaces:
|
||||
- railiance-cluster.kubernetes.api
|
||||
22
fabric/services/railiance-enablement-delivery-templates.yaml
Normal file
22
fabric/services/railiance-enablement-delivery-templates.yaml
Normal file
@@ -0,0 +1,22 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: ServiceDeclaration
|
||||
metadata:
|
||||
id: railiance-enablement.delivery-templates
|
||||
name: Railiance delivery templates
|
||||
owner: railiance-enablement
|
||||
repo: railiance-enablement
|
||||
domain: railiance
|
||||
source_links:
|
||||
- label: Enablement scope
|
||||
path: /home/worsch/railiance-enablement/SCOPE.md
|
||||
- label: Enablement intent
|
||||
path: /home/worsch/railiance-enablement/INTENT.md
|
||||
spec:
|
||||
lifecycle: planned
|
||||
environments: [dev, staging, prod]
|
||||
description: Reusable CI/CD and GitOps workflow template surface for Railiance workload delivery.
|
||||
service_type: enablement-template-surface
|
||||
provides_capabilities:
|
||||
- railiance-enablement.delivery-templates.ci-cd-templates
|
||||
exposes_interfaces:
|
||||
- railiance-enablement.delivery-templates.workflow-template-contract
|
||||
23
fabric/services/railiance-fabric-registry.yaml
Normal file
23
fabric/services/railiance-fabric-registry.yaml
Normal file
@@ -0,0 +1,23 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: ServiceDeclaration
|
||||
metadata:
|
||||
id: railiance-fabric.registry
|
||||
name: Railiance Fabric Registry
|
||||
owner: railiance-fabric
|
||||
repo: railiance-fabric
|
||||
domain: railiance
|
||||
source_links:
|
||||
- label: Registry server implementation
|
||||
path: railiance_fabric/server.py
|
||||
- label: Operations guide
|
||||
path: docs/graph-explorer-operations.md
|
||||
spec:
|
||||
lifecycle: active
|
||||
environments: [dev]
|
||||
description: Local ecosystem registry and graph explorer service for registered Railiance repositories, Fabric graph snapshots, inventory, and map-oriented exports.
|
||||
service_type: registry-service
|
||||
provides_capabilities:
|
||||
- railiance-fabric.registry.ecosystem-registry
|
||||
exposes_interfaces:
|
||||
- railiance-fabric.registry.http-api
|
||||
- railiance-fabric.registry.graph-explorer-ui
|
||||
31
fabric/services/railiance-forge-source-forge.yaml
Normal file
31
fabric/services/railiance-forge-source-forge.yaml
Normal file
@@ -0,0 +1,31 @@
|
||||
apiVersion: railiance.fabric/v1alpha1
|
||||
kind: ServiceDeclaration
|
||||
metadata:
|
||||
id: railiance-forge.source-forge
|
||||
name: Railiance source forge
|
||||
owner: railiance-forge
|
||||
repo: railiance-forge
|
||||
domain: railiance
|
||||
source_links:
|
||||
- label: Forge scope
|
||||
path: /home/worsch/railiance-forge/SCOPE.md
|
||||
- label: Forge intent
|
||||
path: /home/worsch/railiance-forge/INTENT.md
|
||||
spec:
|
||||
lifecycle: active
|
||||
environments: [dev, staging, prod]
|
||||
description: Current Gitea source forge and future Forgejo migration surface for source hosting, registries, runner substrate, and release artifact evidence.
|
||||
service_type: forge-runtime
|
||||
provides_capabilities:
|
||||
- railiance-forge.source-forge.source-hosting
|
||||
- railiance-forge.source-forge.container-registry
|
||||
- railiance-forge.source-forge.python-package-registry
|
||||
- railiance-forge.source-forge.workflow-runner-substrate
|
||||
- railiance-forge.source-forge.artifact-promotion-evidence
|
||||
exposes_interfaces:
|
||||
- railiance-forge.source-forge.web-ui
|
||||
- railiance-forge.source-forge.git-ssh
|
||||
- railiance-forge.source-forge.oci-registry
|
||||
- railiance-forge.source-forge.python-package-index
|
||||
- railiance-forge.source-forge.runner-label-contract
|
||||
- railiance-forge.source-forge.evidence-contract
|
||||
@@ -15,3 +15,5 @@ spec:
|
||||
- the-custodian.state-hub.coordination
|
||||
exposes_interfaces:
|
||||
- the-custodian.state-hub.http-api
|
||||
- the-custodian.state-hub.mcp-api
|
||||
- the-custodian.state-hub.dashboard
|
||||
|
||||
@@ -11,6 +11,7 @@ requires-python = ">=3.12"
|
||||
dependencies = [
|
||||
"jsonschema>=4.18",
|
||||
"PyYAML>=6.0",
|
||||
"referencing>=0.30",
|
||||
]
|
||||
|
||||
[project.scripts]
|
||||
|
||||
1420
railiance_fabric/accountability_roots.py
Normal file
1420
railiance_fabric/accountability_roots.py
Normal file
File diff suppressed because it is too large
Load Diff
212
railiance_fabric/canon.py
Normal file
212
railiance_fabric/canon.py
Normal file
@@ -0,0 +1,212 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import Any
|
||||
|
||||
|
||||
CANONICAL_NODE_CATEGORIES = (
|
||||
"source-repository",
|
||||
"software-system",
|
||||
"service",
|
||||
"endpoint",
|
||||
"deployment",
|
||||
"runtime-resource",
|
||||
"datastore",
|
||||
"flow",
|
||||
"policy",
|
||||
"control",
|
||||
"evidence",
|
||||
"task",
|
||||
"consumer-purpose",
|
||||
"telemetry-signal",
|
||||
)
|
||||
|
||||
CANONICAL_EDGE_TYPES = (
|
||||
"built_from",
|
||||
"implements",
|
||||
"exposes",
|
||||
"depends_on",
|
||||
"deploys",
|
||||
"flows_to",
|
||||
"governed_by",
|
||||
"evidenced_by",
|
||||
"observed_by",
|
||||
"part_of",
|
||||
"reads_or_writes",
|
||||
"creates_task",
|
||||
)
|
||||
|
||||
DISPLAY_ONLY_EDGE_TYPES = (
|
||||
"collapsed_into",
|
||||
"declares",
|
||||
"grouped_with",
|
||||
"highlight_path",
|
||||
"near",
|
||||
"owns_deployment",
|
||||
"same_color_group",
|
||||
)
|
||||
|
||||
EVIDENCE_STATES = ("observed", "declared", "inferred", "proposed", "gap")
|
||||
MAPPING_FITS = ("direct", "partial", "conflict", "gap", "unknown")
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class CanonNodeMapping:
|
||||
category: str
|
||||
canon_anchor: str
|
||||
fit: str
|
||||
notes: str = ""
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class CanonEdgeMapping:
|
||||
canonical_type: str
|
||||
canon_anchor: str
|
||||
fit: str
|
||||
display_only: bool = False
|
||||
notes: str = ""
|
||||
|
||||
|
||||
UNKNOWN_NODE_MAPPING = CanonNodeMapping(
|
||||
category="unknown",
|
||||
canon_anchor="",
|
||||
fit="gap",
|
||||
notes="No canon mapping has been selected for this Fabric node kind yet.",
|
||||
)
|
||||
|
||||
UNKNOWN_EDGE_MAPPING = CanonEdgeMapping(
|
||||
canonical_type="",
|
||||
canon_anchor="",
|
||||
fit="gap",
|
||||
notes="No canon mapping has been selected for this Fabric edge type yet.",
|
||||
)
|
||||
|
||||
NODE_KIND_CANON_MAP: dict[str, CanonNodeMapping] = {
|
||||
"ApplicationEndpoint": CanonNodeMapping("endpoint", "model/network", "direct"),
|
||||
"BindingAssertion": CanonNodeMapping("evidence", "model/observability", "partial"),
|
||||
"CapabilityDeclaration": CanonNodeMapping("software-system", "model/landscape", "partial"),
|
||||
"ContainerBuild": CanonNodeMapping("deployment", "model/devsecops", "partial"),
|
||||
"DependencyDeclaration": CanonNodeMapping("service", "model/landscape", "gap"),
|
||||
"DeploymentService": CanonNodeMapping("deployment", "model/devsecops", "direct"),
|
||||
"DomainName": CanonNodeMapping("endpoint", "model/network", "partial"),
|
||||
"ExternalLibrary": CanonNodeMapping("software-system", "model/landscape", "partial"),
|
||||
"FabricRegistryEntry": CanonNodeMapping("source-repository", "model/devsecops", "partial"),
|
||||
"Fabric": CanonNodeMapping("control", "model/governance", "gap"),
|
||||
"FabricActor": CanonNodeMapping("control", "model/governance", "gap"),
|
||||
"InterfaceDeclaration": CanonNodeMapping("endpoint", "model/network", "partial"),
|
||||
"Library": CanonNodeMapping("software-system", "model/landscape", "partial"),
|
||||
"Lockfile": CanonNodeMapping("evidence", "model/observability", "partial"),
|
||||
"Netkingdom": CanonNodeMapping("software-system", "model/landscape", "gap"),
|
||||
"NetworkPort": CanonNodeMapping("endpoint", "model/network", "direct"),
|
||||
"ProfitCenter": CanonNodeMapping("control", "model/governance", "gap"),
|
||||
"Repository": CanonNodeMapping("source-repository", "model/devsecops", "direct"),
|
||||
"RuntimeService": CanonNodeMapping("runtime-resource", "model/landscape", "direct"),
|
||||
"ScoreWorkload": CanonNodeMapping("deployment", "model/devsecops", "direct"),
|
||||
"Server": CanonNodeMapping("runtime-resource", "model/landscape", "partial"),
|
||||
"ServiceConfig": CanonNodeMapping("evidence", "model/observability", "partial"),
|
||||
"ServiceDeclaration": CanonNodeMapping("service", "model/landscape", "direct"),
|
||||
"Subfabric": CanonNodeMapping("control", "model/governance", "gap"),
|
||||
"UtilityInterface": CanonNodeMapping("endpoint", "model/network", "partial"),
|
||||
"CostCenter": CanonNodeMapping("control", "model/governance", "gap"),
|
||||
}
|
||||
|
||||
EDGE_TYPE_CANON_MAP: dict[str, CanonEdgeMapping] = {
|
||||
"available_via": CanonEdgeMapping("exposes", "model/network", "partial"),
|
||||
"attributed_to_cost_center": CanonEdgeMapping("governed_by", "model/governance", "gap"),
|
||||
"attributed_to_profit_center": CanonEdgeMapping("governed_by", "model/governance", "gap"),
|
||||
"binds": CanonEdgeMapping("depends_on", "model/landscape", "partial"),
|
||||
"builds_container": CanonEdgeMapping("built_from", "model/devsecops", "partial"),
|
||||
"cataloged_as": CanonEdgeMapping("evidenced_by", "model/observability", "partial"),
|
||||
"consumes": CanonEdgeMapping("depends_on", "model/landscape", "partial"),
|
||||
"contains": CanonEdgeMapping("part_of", "model/landscape", "partial"),
|
||||
"declares": CanonEdgeMapping("part_of", "model/devsecops", "partial", display_only=True),
|
||||
"declares_package": CanonEdgeMapping("built_from", "model/devsecops", "partial"),
|
||||
"defines_deployment": CanonEdgeMapping("built_from", "model/devsecops", "partial"),
|
||||
"defines_runtime_object": CanonEdgeMapping("deploys", "model/devsecops", "partial"),
|
||||
"defines_workload": CanonEdgeMapping("deploys", "model/devsecops", "partial"),
|
||||
"deployed_as": CanonEdgeMapping("deploys", "model/devsecops", "partial"),
|
||||
"depends_on_library": CanonEdgeMapping("depends_on", "model/landscape", "partial"),
|
||||
"documents_interface": CanonEdgeMapping("evidenced_by", "model/observability", "partial"),
|
||||
"exposes": CanonEdgeMapping("exposes", "model/network", "direct"),
|
||||
"exposes_port": CanonEdgeMapping("exposes", "model/network", "direct"),
|
||||
"listens_on": CanonEdgeMapping("exposes", "model/network", "direct"),
|
||||
"names_endpoint": CanonEdgeMapping("exposes", "model/network", "partial"),
|
||||
"opens_port": CanonEdgeMapping("exposes", "model/network", "partial"),
|
||||
"operated_by": CanonEdgeMapping("governed_by", "model/governance", "partial"),
|
||||
"owned_by": CanonEdgeMapping("governed_by", "model/governance", "partial"),
|
||||
"owns_deployment": CanonEdgeMapping("part_of", "model/devsecops", "partial", display_only=True),
|
||||
"provides": CanonEdgeMapping("implements", "model/landscape", "partial"),
|
||||
"provides_utility_to": CanonEdgeMapping("depends_on", "model/landscape", "partial"),
|
||||
"resolves_to": CanonEdgeMapping("flows_to", "model/network", "partial"),
|
||||
"routes_to_port": CanonEdgeMapping("flows_to", "model/network", "partial"),
|
||||
"routes_to_service": CanonEdgeMapping("flows_to", "model/network", "partial"),
|
||||
"runs_on": CanonEdgeMapping("deploys", "model/devsecops", "partial"),
|
||||
"suggests_capability": CanonEdgeMapping("creates_task", "model/task", "partial"),
|
||||
"uses_config": CanonEdgeMapping("evidenced_by", "model/observability", "partial"),
|
||||
"uses_interface": CanonEdgeMapping("depends_on", "model/landscape", "partial"),
|
||||
"uses_lockfile": CanonEdgeMapping("evidenced_by", "model/observability", "partial"),
|
||||
}
|
||||
|
||||
|
||||
def node_canon_mapping(kind: str) -> CanonNodeMapping:
|
||||
if kind in NODE_KIND_CANON_MAP:
|
||||
return NODE_KIND_CANON_MAP[kind]
|
||||
if kind.startswith("Kubernetes"):
|
||||
return CanonNodeMapping("runtime-resource", "model/landscape", "direct")
|
||||
return UNKNOWN_NODE_MAPPING
|
||||
|
||||
|
||||
def edge_canon_mapping(edge_type: str) -> CanonEdgeMapping:
|
||||
normalized = str(edge_type or "").strip()
|
||||
if normalized.startswith("binds:"):
|
||||
return EDGE_TYPE_CANON_MAP["binds"]
|
||||
if normalized in EDGE_TYPE_CANON_MAP:
|
||||
return EDGE_TYPE_CANON_MAP[normalized]
|
||||
if normalized in CANONICAL_EDGE_TYPES:
|
||||
return CanonEdgeMapping(normalized, _anchor_for_canonical_edge(normalized), "direct")
|
||||
if normalized in DISPLAY_ONLY_EDGE_TYPES:
|
||||
return CanonEdgeMapping("", "", "gap", display_only=True)
|
||||
return UNKNOWN_EDGE_MAPPING
|
||||
|
||||
|
||||
def evidence_state_for(
|
||||
*,
|
||||
origin: str = "",
|
||||
source_kind: str = "",
|
||||
review_state: str = "",
|
||||
confidence: float | None = None,
|
||||
) -> str:
|
||||
if review_state == "rejected":
|
||||
return "gap"
|
||||
if origin == "llm":
|
||||
return "proposed"
|
||||
if confidence is not None and confidence < 0.5:
|
||||
return "inferred"
|
||||
if source_kind in {"package_registry", "container_registry", "service_catalog", "fabric_registry"}:
|
||||
return "observed"
|
||||
if source_kind in {"llm"}:
|
||||
return "proposed"
|
||||
if not source_kind and origin == "deterministic":
|
||||
return "inferred"
|
||||
return "declared"
|
||||
|
||||
|
||||
def source_kind_from_anchor(source_anchor: dict[str, Any]) -> str:
|
||||
return str(source_anchor.get("source_kind") or "")
|
||||
|
||||
|
||||
def _anchor_for_canonical_edge(edge_type: str) -> str:
|
||||
return {
|
||||
"built_from": "model/devsecops",
|
||||
"implements": "model/security",
|
||||
"exposes": "model/network",
|
||||
"depends_on": "model/landscape",
|
||||
"deploys": "model/devsecops",
|
||||
"flows_to": "model/network",
|
||||
"governed_by": "model/governance",
|
||||
"evidenced_by": "model/observability",
|
||||
"observed_by": "model/observability",
|
||||
"part_of": "model/landscape",
|
||||
"reads_or_writes": "model/data",
|
||||
"creates_task": "model/task",
|
||||
}.get(edge_type, "")
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user