paths templates: 3 incorporations + 2 new (it-dependency-mapping, cybersecurity-attack-paths), on relationalai 1.15#87
Merged
Conversation
…ontingency), bump to 1.13 WIP checkpoint - code + pin + docstring. README/runbook + full-template live-run pending. Stage 2.5 composes on Stage 2 betweenness; logic live-validated standalone (421 corridors, max betweenness-load 99.833, top-substation removal reroutes).
|
The docs preview for this pull request has been deployed to Vercel!
|
- How it works: Stage 2.5 subsection (transmission corridors + contingency) with verbatim snippet; chain-composition bullet for Substation.fragility_load. - Runbook: step 5b 'Trace fragile transmission corridors' (question-shaped, betweenness anchored by structural test; 421 corridors, load 99.833, DFW contingency reroutes).
Derive SKU.feeds (input_sku -> output_sku) from BillOfMaterials, enumerate assembly paths on the BOM DAG, add a maximal-paths view, persist SKU.assembly_depth. Mirrors the live-validated Q4 pattern (18 paths -> finished goods). py_compile + ruff green; full-template live-run is the pre-merge gate.
Arity-3 Subscriber.calls_via edge (caller via routed_through tower -> callee) from CallDetailRecord; enumerate call paths from the top-PageRank hub (scoped; the call graph is large/cyclic), recover the routing tower per hop via relationship_fields, rank by PageRank summed along the route, persist Subscriber.top_call_path_influence. Refactored to the live-validated explicit-src + pandas-field_index form (matches telco_validate.py: 6376 simple <=3-hop paths, 120 towers). py_compile + ruff green; pin already 1.13. Full-template live-run is the pre-merge gate.
Single-reasoner (Graph/paths) template, Technology & Telecom domain. Feature .contributes_to self-relationship (acyclic DAG); model.path(Feature.contributes_to .repeat(1,N)).all_paths() enumerates downstream dependency paths, reduces to maximal chains, persists Feature.max_downstream_depth. 14 features / 15 edges; 46 paths -> 6 maximal, longest 5 hops. Uses the live-validated single-relationship path form. py_compile + ruff green; pin 1.13.0. Full-template live-run is the pre-merge gate.
….5 paths Runbook: question-shaped 'trace most-influential call paths' step (PageRank anchored by structural test, scoped to a seed hub). README: Subscriber .top_call_path_influence row in the concepts table.
…3 run) The end-to-end run surfaced a bug py_compile/ruff missed: selecting p.length alongside p.nodes fanned out the node rows, so maximal chains showed repeated nodes and wrong hop counts. Drop p.length from the select, dedupe (path_id, step), derive hops = max(step). Re-run verified: 46 paths -> 6 maximal, longest 5 hops (Clickstream Ingest -> ... -> Retention Dashboard, 6 features / 5 owners).
…plate 1.13 run) End-to-end run surfaced that n_corridors counted all enumerated walks (8844), mislabeled 'simple' and mismatching the runbook's 421. Count only simple corridors (len([...]), not the shadowed sum). Re-run confirmed: 421 simple corridors, max betweenness-load 99.833, DFW contingency 5 reroute / 1 lose all -- matches the runbook + paste-test.
…13 run) End-to-end run confirms the bundled data matches the eval (same seed/counts), so the 6b response now carries the verified output: seed SUB-CON-00900, 198 simple <=3-hop call paths, 54 towers, top route SUB-CON-00900 -> SUB-CON-00814 -> SUB-ENT-0038 -> SUB-CON-00644 (PageRank sum 0.009041).
Re-ran all four end-to-end on pyrel 1.15; path counts reproduce exactly under the RPQ translator (no regression): - bom-reachability: 18 assembly paths, 8 maximal - it-dependency-mapping: 46 paths, 6 maximal, 5-hop longest - energy_grid_planning: 421 corridors, fragility 99.833, Stage 4 OPTIMAL - telco_network_recovery: 198 call paths, 54 towers, Stage 4 MIP OPTIMAL Notably the telco arity-3 calls_via edge (caller, tower, callee -- entity last) enumerates correctly under RPQ; the entity-last ordering is the safe shape.
Net-new graph-paths template showcasing the multi-relationship-sequence capability in pyrel 1.15: an attack chain composes DISTINCT technique edges in kill-chain order (exploit a perimeter host, reuse credentials inward, then pivot laterally), which a single unioned edge or a flat join cannot express. - 12-asset enterprise estate, 16 technique-tagged steps; one edge per technique (exploit_to / cred_to / pivot_to) plus a can_reach union. - Multi-edge kill-chain: model.path(a.exploit_to, b.cred_to, c.pivot_to.repeat(1,2), dst) filtered to internet-facing source + crown-jewel dst -> 3 chains; p.relationships labels the technique per hop. - Point query: all web-01 -> db-01 routes over can_reach (<=6 hops, simple) -> 7 routes. - Exposure ranking (28/26/25) and persisted Asset.on_attack_path (11 of 12 assets). Runs clean on 1.15 (py_compile + ruff); runbook paste-tested by a fresh agent that reproduced all documented numbers (3 chains, 7 routes, 28/26/25, 11 assets) without seeing the script.
it-dependency-mapping README: the 'How it works' enumeration snippet was teaching the p.length-fanout anti-pattern the script avoids -- replaced with the script's actual select (no p.length) + dedupe + max(step) reassembly. Version refs: bump the two hard prereq contradictions (energy ==1.11.0, telco ==1.12.0) and the paths PREVIEW notes (>=1.13) to match the ==1.15.0 pin; kept the accurate 'introduced in 1.13' history and the >=1.12 member-mapping note. cybersecurity-attack-paths: dedupe the per-chain exposure sum (set()) to match the 'distinct assets' claim; anchor technique_label to a trailing '_to' suffix so a custom mid-string technique isn't mangled. bom-reachability: single pandas import style (pd.read_csv). All five py_compile + ruff clean; bom re-run unchanged (18 paths / 8 maximal); cybersecurity re-run unchanged (3 chains, exposure 28/26/25, 7 routes, 11/12).
These two single-capability paths templates were the only ones in the paths set without an analyst runbook. Each now follows the cybersecurity-attack-paths runbook shape (intro + chain diagram + numbered Prompt/Response steps) and walks the build -> examine -> paths flow, with every figure reproduced on relationalai 1.15.0. Both were paste-tested: a fresh agent generated its own code from the prompts alone (without the template script) and reproduced every number - bom-reachability: 27 reachable pairs, 7 deps/finished-good, top bottleneck Mobile Processor A15 (betweenness 4.0), 18 assembly paths -> 8 maximal, assembly_depth 2. - it-dependency-mapping: 46 downstream paths, longest chain 5 hops over 6 features / 5 owners, 6 of 46 maximal.
The verify check (generate_version_indexes.py --check) was failing: the new cybersecurity-attack-paths and it-dependency-mapping templates were added without regenerating the indexes. Adds both to the Technology & Telecom section of README.md and v1/README.md (count 9 -> 11).
The merge of main (which added defect_root_cause, entity_resolution, transaction_screening_local) auto-merged the index tables textually but left the Financial Services count stale (8 -> 9). Regenerated from the full merged template set so generate_version_indexes.py --check passes on the PR's merge-with-main result (the ref CI verifies).
Add the canonical sections the paths templates were missing so they match sample-template/README.md and the recently-merged templates: - bom-reachability: Template structure, Sample data, Model overview, Learn more, Support - it-dependency-mapping: Sample data, Model overview, Learn more, Support - cybersecurity-attack-paths: Sample data, Model overview, Learn more, Support - energy_grid_planning: Sample data, Model overview, Learn more, Support (telco_network_recovery was already compliant.) Concept tables match each template's script; sample-data sections match the CSVs; Learn more / Support copied from the entity_resolution and telco exemplars. Also drop the mechanical "introduced in 1.13, validated on 1.15" version provenance in favor of stating relationalai >= 1.15.
Apply the recurring feedback jablonskidev gives on template PRs (#80, #88, #89) to the paths templates before review: - Prerequisites split into ### Access / ### Tools (bom-reachability, it-dependency-mapping, cybersecurity-attack-paths; energy/telco already had it) - Quickstart ends with a tiny "Expected output" snippet (bom, it-dependency, telco; cybersecurity/energy already had one) - Drop the H1 title from energy_grid_planning (body starts at the first ##) - "Who this is for" names assumed knowledge; "What you'll build" names the RelationalAI features used, high level - Words, not symbols, in prose (telco arrows + x; energy glyphs done earlier) Regenerate the template index (telco description x -> x, ASCII).
Apply the rest of the recurring jablonskidev review conventions (from PRs #77/#80/#88/#89) proactively so the paths READMEs match the sample-template: - Customize this template -> ### Use your own data / ### Tune parameters / ### Extend the model / ### Scale up / productionize (bom-reachability, it-dependency-mapping, cybersecurity-attack-paths, energy_grid_planning; telco already had it) - Template structure ends with a "Start here" pointer to the one end-to-end command - Model overview opens with Key entities / Primary identifiers / Important invariants (it-dependency-mapping) - "What you'll build" lists outcomes, not steps (it-dependency-mapping) - Spell out acronyms on first use: DAG, MIP, GNN, PUE in body prose; GNN in the telco front-matter description Regenerate the template index for the telco description change.
…banners) Rename data_dir -> DATA_DIR and split the header into the canonical single-reasoner banners (# Configure inputs for DATA_DIR; # Define semantic model & load data for Model + concepts), matching the other templates and the script-structure checklist. Pure rename + comment restructure, no behavior change.
…art, constants) - Trim "What this template is for" to two paragraphs (business problem + one bold reasoning-approach sentence). The per-stage breakdown already lives in the Reasoner overview table and How it works; the one unique point (a Stage-1 forecast change propagates through rules + optimizer with no code changes) moved into How it works. - Trim Quickstart "Expected output" from the full ~67-line log to an ~8-line confirming snippet that points to runbook.md. - Lift the Stage-1 GNN Snowflake database/schema/model names to labelled top-of-file constants (GNN_DATABASE etc.). Pure refactor, no behavior change.
…09) — PyRel, not pandas The finalized #109 skill moves path scoring and filtering into PyRel. Update the four templates whose paths code did them in pandas to the native forms the skill now teaches (all 1.15-valid; bom-reachability already matched): - it-dependency-mapping: per-feature path count -> aggs.count(p).per(src); max downstream depth -> aggs.max(p.length).per(src) defined onto Feature. - cybersecurity-attack-paths: exposure sum -> aggs.sum(Asset(kill.nodes).exposure_score).per(kill); point-query simple-path filter -> not_(where(i<j, route.nodes(i)==route.nodes(j))). - energy_grid_planning: corridor betweenness sum -> aggs.sum(...).per(p); simple-path filter -> native; per-DC most-fragile -> aggs.max(total).per(dst). Corridor count stays pandas (native count(p) fans out under the simple filter). - telco_network_recovery: per-route PageRank sum -> aggs.sum(...).per(p); simple-path filter -> native; folded into one scoped query. Each script was run end-to-end against the engine and reproduces its documented numbers exactly (it-dep 46/6; cyber 3/7/28-26-25/11-of-12; energy 421/99.833; telco 198 paths/54 towers). Per-path aggregate queries are kept separate from the node-sequence projection to avoid the p.nodes row fan-out. py_compile + ruff clean.
…sist The 'Persist Longest Downstream Depth' snippet still showed the old pandas model.data(depth_rows) round-trip; update it to the native form the script now uses (aggs.max(p.length).per(src) defined straight onto Feature), matching the finalized #109 skill. Docs-only; verbatim from the script.
Collaborator
Author
|
For review: |
… stages) The paths stage was labeled "Stage 2.5" (energy) / "Stage 3.5" (telco) with "5b"/"6b" runbook steps. Promote it to a first-class whole-numbered stage and renumber the chain so it reads 1, 2, 3, 4, 5 contiguously: - energy: 1 Predict, 2 Graph, 3 Paths, 4 Rules, 5 Prescriptive (steps 1-10) - telco: 1 Predict, 2 Rules, 3 Graph, 4 Paths, 5 Prescriptive (steps 1-10) Updated consistently across each script (docstring, banner comments, STAGE-N print banners), README (reasoner-overview table gains a Paths row, How-it-works headings, property-stage tags, Expected-output banners), and runbook (chain ASCII gains a Paths stage, workflow step headings). Also surfaced the paths result in each README (energy 421 corridors / 99.833; telco 198 paths / 54 towers). Pure renumbering + doc text — no computation changed; py_compile + ruff clean; script print banners match the README Expected-output.
somacdivad
approved these changes
Jun 26, 2026
somacdivad
left a comment
Collaborator
There was a problem hiding this comment.
Looks good, thanks @cafzal!
Some of the README's feel like they've become a bit bulky and maybe not quite what humans need in the docs, but I think it makes more sense to publish them as is and come back later to try and clean up READMEs in bulk.
cafzal
added a commit
that referenced
this pull request
Jun 26, 2026
The three single-capability runbooks (bom-reachability, it-dependency-mapping, cybersecurity-attack-paths) had bare analyst prompts that never invoked a rai skill, unlike the energy/telco runbooks. Prefix each prompt with the skill it needs (build -> /rai-build-starter-ontology, examine -> /rai-querying, the reachability / betweenness / paths analyses -> /rai-graph-analysis) and add the "paste into a fresh agent session loaded with the named /rai-* skill" preface; also add that preface to the energy runbook. Docs-only -- prompt asks, Response text, and numbers unchanged. Verified by a faithful paste-test: with the skill-invoking prompts, a fresh agent reproduces the cybersecurity results (3 kill-chains, 7 routes, exposure 28/26/25, 11 of 12 assets) on relationalai 1.15.0.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The v1 templates had no runnable example of the paths (variable-length traversal) capability that shipped in
relationalai==1.15.0, so customers learning it had nothing to copy. This adds paste-tested paths coverage — incorporated into three existing templates and shown standalone in two new ones. Companion to the skills + evals in rai-agent-evals#109.Changes
Five
v1/templates, all pinned torelationalai==1.15.0.Paths incorporated into three existing templates — paths is one component of a larger chain that was already on
main:energy_grid_planning(predictive + graph + rules + prescriptive chain) — a new transmission-corridor fragility stage: betweenness summed along generator→DC corridors.telco_network_recovery(predictive + rules + graph + prescriptive chain) — a new call-path enumeration stage over an arity-3 caller-via-tower-callee edge.bom-reachability(reachability + betweenness graph template) — added bottom-up assembly-path enumeration + maximal chains.Two new templates focused on paths:
it-dependency-mapping— downstream dependency-path enumeration + blast radius (pure paths).cybersecurity-attack-paths— multi-edge kill-chains + point query + exposure ranking (the multi-relationship-sequence showcase).Across all five: paths code uses the native PyRel forms the finalized #109 skill teaches —
aggregates.sum/count/max(...).per(p),not_(where(i < j, p.nodes(i) == p.nodes(j))); pandas only where PyRel can't on 1.15 (maximal-paths reduction, chain labels, simple-path counts). Each ships an analyst runbook; READMEs followsample-templatestructure throughout.Test plan (done)
relationalai==1.15.0and reproduces its documented numbers: energy 421 corridors / 99.833; telco 198 paths / 54 towers; bom 18 → 8 maximal / depth 2; it-dependency 46 → 6 maximal / 5-hop; cybersecurity 3 kill-chains / 7-route point query / exposure 28-26-25 / 11-of-12.py_compile+ruffclean;dev-templates-review+dev-writing-reviewclean.