Skip to content

Commit ba63349

Browse files
authored
feat(federation): activate verified corpus graphs (#464)
## Stack 1. #462 — ratify graph decisions 2. #463 — graph foundation 3. **This PR — activate the verified graph engine** 4. #465 — profile guidance and DecisionGrounding evidence ## What this implements - manifest v2 with multiple direct parents and bounded recursive DAG composition - independently verified physical routes, cycle/divergent-pin detection, and diamond deduplication - global `corpus.source::canonical-id` resolution with source-contextual aliases - equal cross-source IDs as deterministic ambiguity rather than precedence - explicit Decision-backed override chains and diamond convergence - one catalog/effective/root-local model across validation, resolution, retrieval, routing, gate, Sentry, exports, MCP, and audit - closure generation v3 and isolated `store/v3` persistence with fail-closed freshness and corruption repair - complete source/layer/pin, override-chain, and topology-route provenance - read-only enforcement across every direct, transitive, and duplicate materialisation route - additive viewer/documents/graph exports and source-aware Portal navigation - exact v1 and no-manifest compatibility paths ## Hardening The implementation uses stable captured bytes throughout digesting, parsing, validation, composition, persistence, and serving. It rejects unsafe YAML, symlink/reparse traversal, hard-linked inherited files, mount boundaries, path escapes, stale pins, invalid topology, and unsafe output/cache targets. ## Validation - `cargo test --workspace --all-targets --locked --no-fail-fast` — passed - `cargo clippy --workspace --all-targets --locked -- -D warnings` — passed - graph CLI contract — 9/9 - graph MCP contract — 5/5 - v1 federation CLI — 14/14 - v1 federation MCP — 8/8 - `decided validate decisions/` — 468 valid, 0 invalid, 12 skipped - `decided relationships decisions/ --validate` — 3,055 checked, 0 issues - `decided gate decisions/ --json` — 0 blocking, 134 existing advisories - `decided review decisions/ --json` — 508 non-blocking issues, health 96 - agent-rules drift check — in sync - Linux, Windows, and macOS cross-platform certification — passed Review and merge after #462 and #463. Closes #270 Closes #272
1 parent 508b664 commit ba63349

44 files changed

Lines changed: 9159 additions & 504 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

rust/Cargo.lock

Lines changed: 74 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rust/decided-mcp/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,6 @@ publish = ["crates-io"]
1616
rac-engine = { package = "asdecided-core", version = "=0.28.0", path = "../rac-engine" }
1717
serde = { version = "1", features = ["derive"] }
1818
serde_json = { version = "1", features = ["preserve_order"] }
19+
20+
[dev-dependencies]
21+
sha2 = "0.10"

rust/decided-mcp/src/graph.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,14 @@ impl GraphView {
146146
)
147147
}
148148

149+
pub fn from_graph(corpus: &rac_engine::graph_composition::GraphComposition) -> Self {
150+
Self::new_with_history(
151+
corpus.identity_index(),
152+
corpus.relationships(),
153+
Some(corpus.catalog_relationships_compatible()),
154+
)
155+
}
156+
149157
pub fn new(entries: Vec<IndexEntry>, relationships: Vec<Relationship>) -> Self {
150158
Self::new_with_history(entries, relationships, None)
151159
}
@@ -703,6 +711,34 @@ impl GraphCache {
703711
self.view.as_ref().expect("federated graph view built")
704712
}
705713

714+
pub fn view_for_graph(
715+
&mut self,
716+
generation: &str,
717+
corpus: &rac_engine::graph_composition::GraphComposition,
718+
) -> &GraphView {
719+
if self.federated_generation.as_deref() != Some(generation)
720+
|| self.generation.is_some()
721+
|| self.view.is_none()
722+
{
723+
let started = rac_engine::timing::start();
724+
let replacement = GraphView::from_graph(corpus);
725+
rac_engine::timing::emit_since(
726+
"graph.view_build",
727+
started,
728+
&[
729+
("entries", replacement.entry_count() as u64),
730+
("relationships", replacement.relationship_count() as u64),
731+
("payload_bytes", replacement.estimated_payload_bytes() as u64),
732+
],
733+
);
734+
self.view = Some(replacement);
735+
self.generation = None;
736+
self.federated_generation = Some(generation.to_string());
737+
self.builds += 1;
738+
}
739+
self.view.as_ref().expect("graph federation view built")
740+
}
741+
706742
#[cfg(test)]
707743
pub fn builds(&self) -> u64 {
708744
self.builds

0 commit comments

Comments
 (0)