Changelog¶
0.1.0¶
First release.
Architecture¶
LangGraph, mermaid or specification-dict extraction into a ported component model; conditional edges materialised as router components with their own failure logic.
Shared-resource detection from node source and from live model objects, producing common-cause groups.
Feedback-loop elimination by unrolling to depth k plus a feedback-cut component, so a loop’s contribution is preserved rather than deleted.
LangGraphExtractorfor applying one set of conventions across several graphs.plot_architecturedraws the extracted model rather than the source graph, so the picture and the analysis are the same object. Conditional edges are dashed; feedback edges and any edge that skips a layer — an early exit to__end__is the common case — are routed around the side in their own lane, because drawn straight they are a vertical line hidden behind every component they pass, with the branch label landing on top of one of them.
Fault trees¶
Six failure classes; an archetype library covering LLM agent, tool, router, aggregator, transform, boundary and feedback cut.
Compositional synthesis with shared sub-trees; minimal cut sets by MOCUS with absorption; MCUB quantification; Birnbaum and Fussell–Vesely importance; single points of failure; a generated FMEA.
Exports: mermaid, Graphviz DOT, JSON, Open-PSA MEF XML, Markdown, CSV.
Reliability¶
OperationalProfilewith recorded provenance; empirical, uniform and declared constructors; astratifyhelper that refuses labels outside the profile.EvidenceCalibrator: HIP-LLM’s imprecise posterior per component, written onto basic events through an exact union-splitting rule, plus a report naming every component and event it did not touch.The whole of HIP-LLM re-exported under one namespace, with a test asserting the re-export stays complete.
Bayesian networks¶
fault_tree_to_cpts: deterministic AND/OR, k-of-n, and noisy-OR with leak.BayesianNetwork: exact inference through pyAgrum or NumPy enumeration, cross-checked against each other; posterior over causes given evidence; most probable explanation.ImpreciseBayesianNetwork: the lower/upper pair, licensed by a monotonicity test over the basic events.learn_cpt/learn_gate/fit_cpts: tables fitted from observed outcomes, with Dirichlet smoothing, coverage reporting, and a refusal to fit on a test split.BayesNetView: pyAgrum where Graphviz exists, matplotlib where it does not, with a barycentre layout pass and posterior shading.
Pipeline¶
AgenticReliabilityStudy: the whole chain behind one chainable object, which refuses to calibrate without outcomes or without an operational profile, and printsNOT CALIBRATEDuntil it has both.
Testing¶
736 tests, 94% line coverage, every module above 88%. CI runs them on Python 3.10–3.13 (Ubuntu) plus Windows and macOS, once more with pyAgrum uninstalled to keep that dependency genuinely optional, and enforces a 90% overall / 80% per-module coverage floor.
Fixed in the underlying analysis code¶
Six defects found while packaging and while writing the unit tests, each of which failed silently:
A router node declared explicitly lost its incoming edge. The
node -> node::routerconnection was emitted only when the router component was created, so pre-declaring one (to attach its source) disconnected the graph — and every feedback loop through that router vanished from the analysis with no warning.The specification-dict extraction path discarded every option.
role_overrides,resource_overrides,globals_ns,node_functionsandmaterialise_routerswere all dropped, because the dict branch short-circuited tofrom_specinstead of going throughbuild_system_model.probability_overridesignored an unknown basic-event id. A typo left the placeholder in place while the analyst believed it replaced. It now raises and lists the ids the model does have, and rejects values outside[0, 1].Resource detection could never match a variable named
modelortokenizer. The patterns required at least one character before the word, so they matchedmy_modelbut notmodelormodel_deep— the names the source notebook actually uses. Two agents generating through the same shared variable therefore produced no common-cause group, which is precisely the error that turns a single point of failure into an apparently redundant architecture.source_of_functiondid not unwrap its argument. A partial or Runnable wrapper — the usual shape of a LangGraph node payload — yielded no source, and so no role hint and no detected resources, while looking like a node that simply had none._resolve_callableexisted for exactly this and was not being called.Calibrating twice compounded. The union split weighted events by their current probability, so a second
calibrate()split already-split values and silently moved numbers that were already measured. Events now carry abaseline_probrecorded once.
Two smaller inconsistencies, also silent:
cross_check()returned three keys without pyAgrum and six with it, so callers had to branch on the shape. It now always returns the same keys, with acomparedflag andagreeas NaN when the comparison could not run.EvidenceCalibrator(bound=...)was accepted and ignored on the approximate (Jeffreys) path, which has only one envelope. It now says so in the evidence string it writes.