Skip to content

paths templates: 3 incorporations + 2 new (it-dependency-mapping, cybersecurity-attack-paths), on relationalai 1.15#87

Merged
cafzal merged 26 commits into
mainfrom
paths/energy-telco-bom-itdep
Jun 26, 2026
Merged

paths templates: 3 incorporations + 2 new (it-dependency-mapping, cybersecurity-attack-paths), on relationalai 1.15#87
cafzal merged 26 commits into
mainfrom
paths/energy-telco-bom-itdep

Conversation

@cafzal

@cafzal cafzal commented Jun 16, 2026

Copy link
Copy Markdown
Collaborator

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 to relationalai==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 follow sample-template structure throughout.

Test plan (done)

  • User test — runbooks paste-tested: a fresh agent loaded only with the finalized #109 skill, given each runbook's prompts (no access to the script or README), generated its own code and reproduced every documented number — with independent NetworkX / DFS / pandas cross-checks — across all five runbooks.
  • Each script runs end-to-end on the pinned relationalai==1.15.0 and 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.
  • Each README's "Expected output" matches the script's actual output.
  • py_compile + ruff clean; dev-templates-review + dev-writing-review clean.

…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).
@github-actions

github-actions Bot commented Jun 16, 2026

Copy link
Copy Markdown

The docs preview for this pull request has been deployed to Vercel!

✅ Preview: https://relationalai-docs-hm91x0hh9-relationalai.vercel.app/build/templates
🔍 Inspect: https://vercel.com/relationalai/relationalai-docs/Cp8qVKdJ56pYbk4sz2Z8F4a7u12k

- 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.
cafzal added 2 commits June 16, 2026 10:12
….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).
cafzal added 2 commits June 22, 2026 09:18
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.
@cafzal cafzal changed the title paths incorporations: energy / telco / bom-reachability / it-dependency-mapping (1.13) paths templates: 4 incorporations + 2 new (it-dependency, cybersecurity-attack-paths), on relationalai 1.15 Jun 22, 2026
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).
@cafzal cafzal changed the title paths templates: 4 incorporations + 2 new (it-dependency, cybersecurity-attack-paths), on relationalai 1.15 paths templates: 3 incorporations + 2 new (it-dependency-mapping, cybersecurity-attack-paths), on relationalai 1.15 Jun 23, 2026
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).
cafzal added 2 commits June 25, 2026 11:13
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.
@cafzal

cafzal commented Jun 26, 2026

Copy link
Copy Markdown
Collaborator Author

For review: verify and ruff are green. The red preview (Vercel docs deploy) check is a repo-wide infra cap — the external relationalai-docs site exceeds Vercel's 15,000-file upload limit — not anything in this PR; it fails the same way on other recent PRs and isn't a required check. Tracked in #91.

… 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 somacdivad left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 cafzal merged commit 38e7489 into main Jun 26, 2026
2 of 3 checks passed
@cafzal cafzal deleted the paths/energy-telco-bom-itdep branch June 26, 2026 19:17
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants