generated from coulomb/repo-seed
feat: bootstrap accountability-root fabric snapshot
This commit is contained in:
@@ -70,6 +70,12 @@ 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.
|
||||
|
||||
@@ -84,6 +84,28 @@ railiance-fabric discover-roots --delta \
|
||||
--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;
|
||||
@@ -144,6 +166,25 @@ 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
|
||||
|
||||
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
@@ -52,7 +52,7 @@ discovery_roots:
|
||||
type: state_hub_repo_inventory
|
||||
status: active
|
||||
fabric_id: fabric.railiance.primary
|
||||
owner_actor_id: actor.railiance.king
|
||||
owner_actor_id: actor.railiance.primary-lord
|
||||
source:
|
||||
base_url: http://127.0.0.1:8000
|
||||
api_paths:
|
||||
@@ -71,7 +71,7 @@ discovery_roots:
|
||||
type: gitea_organization
|
||||
status: active
|
||||
fabric_id: fabric.railiance.primary
|
||||
owner_actor_id: actor.railiance.king
|
||||
owner_actor_id: actor.railiance.primary-lord
|
||||
source:
|
||||
url: ssh://git@92.205.130.254:30022/coulomb
|
||||
organization: coulomb
|
||||
@@ -88,7 +88,7 @@ discovery_roots:
|
||||
type: registry_manifest
|
||||
status: active
|
||||
fabric_id: fabric.railiance.primary
|
||||
owner_actor_id: actor.railiance.king
|
||||
owner_actor_id: actor.railiance.primary-lord
|
||||
source:
|
||||
manifest_path: registry/local-repos.yaml
|
||||
safe_discovery: local_files
|
||||
@@ -105,7 +105,7 @@ discovery_roots:
|
||||
type: host_path
|
||||
status: active
|
||||
fabric_id: fabric.railiance.primary
|
||||
owner_actor_id: actor.railiance.king
|
||||
owner_actor_id: actor.railiance.primary-lord
|
||||
source:
|
||||
path: /home/worsch
|
||||
patterns:
|
||||
@@ -146,7 +146,7 @@ discovery_roots:
|
||||
type: deployment_automation
|
||||
status: active
|
||||
fabric_id: fabric.railiance.primary
|
||||
owner_actor_id: actor.railiance.king
|
||||
owner_actor_id: actor.railiance.primary-lord
|
||||
source:
|
||||
path: /home/worsch
|
||||
patterns:
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,140 @@
|
||||
{
|
||||
"apiVersion": "railiance.fabric/v1alpha2",
|
||||
"change_sets": {
|
||||
"blockers": [],
|
||||
"containment": [],
|
||||
"ownership": [],
|
||||
"review_state": []
|
||||
},
|
||||
"current": {
|
||||
"generated_at": "2026-05-24T08:26:01Z",
|
||||
"manifest_fingerprint": "dd279b655d68222a99671c1c875afdaa70ae2f907fd526e6673ddf756bc90dae",
|
||||
"manifest_id": "railiance.accountability-roots"
|
||||
},
|
||||
"edge_delta": {
|
||||
"added": [
|
||||
"candidate-edge:d448183c64bba5c0"
|
||||
],
|
||||
"changed": [],
|
||||
"removed": [],
|
||||
"unchanged": []
|
||||
},
|
||||
"generated_at": "2026-05-24T08:26:31Z",
|
||||
"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-hosts",
|
||||
"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: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": 97,
|
||||
"nodes_added": 96,
|
||||
"nodes_changed": 0,
|
||||
"nodes_removed": 0,
|
||||
"nodes_unchanged": 0,
|
||||
"promotion_needed": true
|
||||
}
|
||||
}
|
||||
@@ -634,7 +634,7 @@ def _identity_from_evidence(root: dict[str, Any], item: dict[str, Any]) -> dict[
|
||||
"subfabric_id": subfabric_id,
|
||||
"owner_actor_id": owner_actor_id,
|
||||
"evidence_ids": evidence_ids,
|
||||
"aliases": [path, Path(path).stem],
|
||||
"aliases": [path],
|
||||
"attributes": {**attributes, "source_evidence_type": evidence_type},
|
||||
"confidence": 0.75,
|
||||
}
|
||||
@@ -1096,7 +1096,11 @@ def _glob_root_evidence(root: dict[str, Any], evidence_type: str, *, max_items:
|
||||
return [_declared_evidence(root, f"{evidence_type}_missing", "unavailable", f"Root path missing: {base}")]
|
||||
matches: list[Path] = []
|
||||
for pattern in patterns:
|
||||
matches.extend(sorted(base.glob(str(pattern))))
|
||||
matches.extend(
|
||||
path
|
||||
for path in sorted(base.glob(str(pattern)))
|
||||
if not _is_noise_match(evidence_type, path)
|
||||
)
|
||||
if len(matches) >= max_items:
|
||||
break
|
||||
evidence = [
|
||||
@@ -1117,6 +1121,26 @@ def _glob_root_evidence(root: dict[str, Any], evidence_type: str, *, max_items:
|
||||
return evidence
|
||||
|
||||
|
||||
def _is_noise_match(evidence_type: str, path: Path) -> bool:
|
||||
if evidence_type not in {"deployment_automation", "infrastructure_manifest", "service_config", "endpoint_contract"}:
|
||||
return False
|
||||
parts = path.parts
|
||||
noisy_parts = {
|
||||
".cache",
|
||||
".mypy_cache",
|
||||
".nvm",
|
||||
".pytest_cache",
|
||||
".tox",
|
||||
".venv",
|
||||
"__pycache__",
|
||||
"node_modules",
|
||||
"site-packages",
|
||||
}
|
||||
if any(part in noisy_parts for part in parts):
|
||||
return True
|
||||
return any(parts[index : index + 3] == ("go", "pkg", "mod") for index in range(max(len(parts) - 2, 0)))
|
||||
|
||||
|
||||
def _state_hub_evidence(root: dict[str, Any], *, include_remote: bool) -> list[dict[str, Any]]:
|
||||
source = _source(root)
|
||||
if not include_remote:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
@@ -67,8 +68,7 @@ def financial_export_from_legacy(
|
||||
],
|
||||
"unresolved": [],
|
||||
}
|
||||
if legacy_graph.get("generated_at"):
|
||||
graph["generated_at"] = legacy_graph["generated_at"]
|
||||
graph["generated_at"] = legacy_graph.get("generated_at") or _utc_now()
|
||||
materialized = materialize_financial_graph_export(graph)
|
||||
errors = financial_graph_errors(materialized)
|
||||
if errors:
|
||||
@@ -135,3 +135,7 @@ def _has_value(value: Any) -> bool:
|
||||
if isinstance(value, list):
|
||||
return any(_has_value(item) for item in value)
|
||||
return value not in (None, "")
|
||||
|
||||
|
||||
def _utc_now() -> str:
|
||||
return datetime.now(timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")
|
||||
|
||||
@@ -63,6 +63,85 @@ def test_identity_projection_is_stable_and_reviewable(tmp_path: Path) -> None:
|
||||
assert first["candidate_graph"]["edges"]
|
||||
|
||||
|
||||
def test_deployable_identity_ignores_generic_filename_alias_ambiguity(tmp_path: Path) -> None:
|
||||
workspace = tmp_path / "workspace"
|
||||
for name in ("service-a", "service-b"):
|
||||
service = workspace / name
|
||||
service.mkdir(parents=True)
|
||||
(service / "Dockerfile").write_text("FROM python:3.12-slim\n", encoding="utf-8")
|
||||
manifest_path = _minimal_manifest(
|
||||
tmp_path,
|
||||
"""
|
||||
- id: root.fixture.deployables
|
||||
type: deployment_automation
|
||||
status: active
|
||||
fabric_id: fabric.fixture.primary
|
||||
owner_actor_id: actor.fixture.lord
|
||||
source:
|
||||
path: {workspace}
|
||||
patterns:
|
||||
- "*/Dockerfile"
|
||||
safe_discovery: local_files
|
||||
evidence_scope:
|
||||
- deployment_topology
|
||||
""".format(workspace=workspace),
|
||||
)
|
||||
manifest = load_accountability_root_manifest(manifest_path)
|
||||
|
||||
projection = build_identity_projection(collect_accountability_root_evidence(manifest_path), manifest)
|
||||
|
||||
deployables = [
|
||||
candidate
|
||||
for candidate in projection["identity_candidates"]
|
||||
if candidate["identity_type"] == "Deployable"
|
||||
]
|
||||
assert len(deployables) == 2
|
||||
assert all("ambiguous_aliases" not in candidate.get("attributes", {}) for candidate in deployables)
|
||||
|
||||
|
||||
def test_deployment_evidence_skips_dependency_cache_noise(tmp_path: Path) -> None:
|
||||
workspace = tmp_path / "workspace"
|
||||
(workspace / "service").mkdir(parents=True)
|
||||
(workspace / "service" / "Dockerfile").write_text("FROM python:3.12-slim\n", encoding="utf-8")
|
||||
(workspace / ".venv" / "lib" / "python3.12" / "site-packages" / "pkg").mkdir(parents=True)
|
||||
(workspace / ".venv" / "lib" / "python3.12" / "site-packages" / "pkg" / "Dockerfile").write_text(
|
||||
"FROM ignored\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
(workspace / "go" / "pkg" / "mod" / "example").mkdir(parents=True)
|
||||
(workspace / "go" / "pkg" / "mod" / "example" / "Dockerfile").write_text(
|
||||
"FROM ignored\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
manifest_path = _minimal_manifest(
|
||||
tmp_path,
|
||||
"""
|
||||
- id: root.fixture.deployables
|
||||
type: deployment_automation
|
||||
status: active
|
||||
fabric_id: fabric.fixture.primary
|
||||
owner_actor_id: actor.fixture.lord
|
||||
source:
|
||||
path: {workspace}
|
||||
patterns:
|
||||
- "**/Dockerfile"
|
||||
safe_discovery: local_files
|
||||
evidence_scope:
|
||||
- deployment_topology
|
||||
""".format(workspace=workspace),
|
||||
)
|
||||
|
||||
evidence = collect_accountability_root_evidence(manifest_path, max_items_per_root=20)
|
||||
paths = [
|
||||
item["source"]["path"]
|
||||
for root in evidence["roots"]
|
||||
for item in root["evidence"]
|
||||
if item["evidence_type"] == "deployment_automation"
|
||||
]
|
||||
|
||||
assert paths == [str(workspace / "service" / "Dockerfile")]
|
||||
|
||||
|
||||
def test_evidence_store_persists_runs_items_and_identities(tmp_path: Path) -> None:
|
||||
manifest_path = _fixture_manifest(tmp_path)
|
||||
manifest = load_accountability_root_manifest(manifest_path)
|
||||
@@ -381,3 +460,46 @@ refresh:
|
||||
encoding="utf-8",
|
||||
)
|
||||
return manifest
|
||||
|
||||
|
||||
def _minimal_manifest(tmp_path: Path, discovery_roots: str) -> Path:
|
||||
manifest = tmp_path / "minimal-accountability-roots.yaml"
|
||||
manifest.write_text(
|
||||
"""
|
||||
apiVersion: railiance.fabric/v1alpha2
|
||||
kind: AccountabilityRootManifest
|
||||
metadata:
|
||||
id: fixture.minimal-accountability-roots
|
||||
name: Fixture Minimal Accountability Roots
|
||||
netkingdom:
|
||||
id: fixture.netkingdom
|
||||
name: Fixture Netkingdom
|
||||
king_actor_id: actor.fixture.king
|
||||
actors:
|
||||
- id: actor.fixture.king
|
||||
role: king
|
||||
name: Fixture King
|
||||
- id: actor.fixture.lord
|
||||
role: lord
|
||||
name: Fixture Lord
|
||||
fabrics:
|
||||
- id: fabric.fixture.primary
|
||||
kind: Fabric
|
||||
name: Fixture Primary Fabric
|
||||
netkingdom_id: fixture.netkingdom
|
||||
lord_actor_id: actor.fixture.lord
|
||||
parent_fabric_id: null
|
||||
status: active
|
||||
boundary:
|
||||
boundary_type: fabric
|
||||
criterion: financial_and_operational_accountability
|
||||
discovery_roots:
|
||||
{discovery_roots}
|
||||
refresh:
|
||||
cadence: manual
|
||||
triggers:
|
||||
- operator_request
|
||||
""".format(discovery_roots=discovery_roots.rstrip()),
|
||||
encoding="utf-8",
|
||||
)
|
||||
return manifest
|
||||
|
||||
@@ -329,6 +329,7 @@ def test_current_graph_projects_to_financial_baseline() -> None:
|
||||
assert list(validator.iter_errors(financial_graph)) == []
|
||||
assert financial_graph["netkingdom"]["id"] == "railiance.netkingdom"
|
||||
assert financial_graph["fabrics"][0]["id"] == "fabric.railiance.primary"
|
||||
assert financial_graph["generated_at"].endswith("Z")
|
||||
assert financial_graph["unresolved"] == []
|
||||
assert all(node["containment"]["fabric_id"] == "fabric.railiance.primary" for node in financial_graph["nodes"])
|
||||
assert all(node["ownership"]["owner_actor_id"] == "actor.railiance.primary-lord" for node in financial_graph["nodes"])
|
||||
|
||||
@@ -4,11 +4,11 @@ type: workplan
|
||||
title: "Accountability Root Discovery And Update Loop"
|
||||
domain: railiance
|
||||
repo: railiance-fabric
|
||||
status: active
|
||||
status: finished
|
||||
owner: codex
|
||||
topic_slug: railiance
|
||||
created: "2026-05-23"
|
||||
updated: "2026-05-23"
|
||||
updated: "2026-05-24"
|
||||
state_hub_workstream_id: "651185b5-83fe-4aef-b29d-617b2bc48c7a"
|
||||
---
|
||||
|
||||
@@ -280,7 +280,7 @@ Result:
|
||||
|
||||
```task
|
||||
id: RAIL-FAB-WP-0018-T06
|
||||
status: todo
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "0d05ee40-0823-473f-9c87-0ed964e8900c"
|
||||
```
|
||||
@@ -302,6 +302,33 @@ Done when:
|
||||
- State Hub can import the resulting export after `STATE-WP-0051`;
|
||||
- operator docs explain how to rerun the rebuild and update loop.
|
||||
|
||||
Result:
|
||||
|
||||
- Tightened deployable identity normalization so generic filenames such as
|
||||
`Dockerfile` no longer create false ambiguous identity blockers.
|
||||
- Filtered dependency-cache deployment matches from accountability-root
|
||||
deployable/config evidence.
|
||||
- Aligned repository inventory, Gitea, host-path, and deployment roots to use
|
||||
`actor.railiance.primary-lord` as the default financial owner for discovered
|
||||
candidates.
|
||||
- Saved the 2026-05-24 bootstrap artifacts:
|
||||
`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`,
|
||||
and `exports/state-hub/2026-05-24-railiance-financial-fabric-v1.json`.
|
||||
- The bootstrap ownership review produced 96 candidates, zero unresolved
|
||||
ownership items, zero ambiguous containment items, and four explicit
|
||||
duplicate repository identity blockers.
|
||||
- Created `RAIL-FAB-WP-0019` to resolve those duplicate repository identities
|
||||
instead of hiding them.
|
||||
- Imported the financial Fabric export into State Hub after applying the
|
||||
`STATE-WP-0051` migration; State Hub accepted the export as valid with 2
|
||||
actors, 1 fabric, 49 nodes, 58 edges, and 0 unresolved items.
|
||||
- Added `generated_at` stamping for financial bridge exports so saved snapshot
|
||||
files carry export time.
|
||||
- Verified with focused accountability/registry tests, artifact schema
|
||||
validation, State Hub import/readback, and full `python3 -m pytest`.
|
||||
|
||||
## Acceptance
|
||||
|
||||
- Fabric discovery starts from accountability roots and deployment automation.
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
---
|
||||
id: RAIL-FAB-WP-0019
|
||||
type: workplan
|
||||
title: "Duplicate Repository Identity Review"
|
||||
domain: railiance
|
||||
repo: railiance-fabric
|
||||
status: ready
|
||||
owner: codex
|
||||
topic_slug: railiance
|
||||
created: "2026-05-24"
|
||||
updated: "2026-05-24"
|
||||
state_hub_workstream_id: "bc69549c-3cbc-4a7d-8766-b84added1133"
|
||||
---
|
||||
|
||||
# RAIL-FAB-WP-0019 - Duplicate Repository Identity Review
|
||||
|
||||
## Goal
|
||||
|
||||
Resolve the duplicate repository identity blockers found during the
|
||||
`RAIL-FAB-WP-0018` bootstrap run.
|
||||
|
||||
The 2026-05-24 accountability-root ownership review resolved ownership and
|
||||
containment for all candidates, but flagged four repository identities as
|
||||
ambiguous because registry inventory evidence maps two repo slugs onto the same
|
||||
local checkout path.
|
||||
|
||||
## T01 - Inspect Duplicate Repo Path Evidence
|
||||
|
||||
```task
|
||||
id: RAIL-FAB-WP-0019-T01
|
||||
status: todo
|
||||
priority: high
|
||||
state_hub_task_id: "63c5ee1e-6c9f-4d63-b0b4-61308e833ac2"
|
||||
```
|
||||
|
||||
Review the duplicate path evidence for:
|
||||
|
||||
- `identity:repository:railiance-hosts`
|
||||
- `identity:repository:railiance-infra`
|
||||
- `identity:repository:vergabe-teilnahme`
|
||||
- `identity:repository:vergabe_teilnahme`
|
||||
|
||||
Done when the intended canonical repo identity, alias, or split-identity rule is
|
||||
known for `/home/worsch/railiance-infra` and `/home/worsch/vergabe-teilnahme`.
|
||||
|
||||
## T02 - Encode Canonical Identity Decisions
|
||||
|
||||
```task
|
||||
id: RAIL-FAB-WP-0019-T02
|
||||
status: todo
|
||||
priority: high
|
||||
state_hub_task_id: "bd0496f2-9a95-4487-9620-eabbf0e78c6b"
|
||||
```
|
||||
|
||||
Apply the chosen resolution in the durable source of truth.
|
||||
|
||||
Candidate options include:
|
||||
|
||||
- fix duplicate entries in `registry/local-repos.yaml`;
|
||||
- add explicit repository alias/canonicalization support to the identity
|
||||
projection;
|
||||
- persist review decisions for the affected stable identity keys.
|
||||
|
||||
Done when duplicate repo path evidence no longer produces ambiguous repository
|
||||
identity blockers.
|
||||
|
||||
## T03 - Refresh Bootstrap Review Artifacts
|
||||
|
||||
```task
|
||||
id: RAIL-FAB-WP-0019-T03
|
||||
status: todo
|
||||
priority: medium
|
||||
state_hub_task_id: "2c90c5c1-46be-41b7-8854-602eea0e3aaf"
|
||||
```
|
||||
|
||||
Rerun the accountability-root bootstrap review and update the saved discovery
|
||||
snapshot artifacts.
|
||||
|
||||
Done when `fabric/discovery/snapshots/*bootstrap-ownership-review.json` shows
|
||||
zero ambiguous repository identity blockers, or documents any remaining blocker
|
||||
as intentionally unresolved.
|
||||
Reference in New Issue
Block a user