Skip to content

Commit 6464476

Browse files
authored
Update to v0.14.0 (#102)
- Restructured Monte Carlo results: `baseline` is returned separately, and `results` now contains deduplicated failure patterns with `occurrence_count`. - Removed `baseline` parameter from Monte Carlo APIs; baseline now runs implicitly. - Added `FlowIterationResult.occurrence_count` to track how many iterations produced each failure pattern.
1 parent 6e71a1f commit 6464476

Some content is hidden

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

43 files changed

+2190
-758
lines changed

.claude/skills/netgraph-dsl/SKILL.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ workflow:
250250
mode: pairwise
251251
failure_policy: single_link
252252
iterations: 1000
253-
baseline: true # Include no-failure baseline
253+
seed: 42 # Optional: for reproducibility
254254
```
255255

256256
**Step types**: `BuildGraph`, `NetworkStats`, `MaxFlow`, `TrafficMatrixPlacement`, `MaximumSupportedDemand`, `CostPower`
@@ -345,4 +345,4 @@ Overrides only affect entities that exist at their processing stage.
345345
## More Information
346346

347347
- [Full DSL Reference](references/REFERENCE.md) - Complete field documentation, all operators, workflow steps
348-
- [Working Examples](references/EXAMPLES.md) - 11 complete scenarios from simple to advanced
348+
- [Working Examples](references/EXAMPLES.md) - 17 complete scenarios from simple to advanced

.claude/skills/netgraph-dsl/references/EXAMPLES.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ workflow:
256256
mode: pairwise
257257
failure_policy: single_link_failure
258258
iterations: 1000
259-
baseline: true
259+
seed: 42
260260
```
261261
262262
## Example 6: Attribute-Based Selectors
@@ -455,7 +455,7 @@ workflow:
455455
failure_policy: single_link
456456
iterations: 1000
457457
parallelism: 7
458-
baseline: true
458+
include_flow_details: true
459459
alpha_from_step: msd_baseline
460460
alpha_from_field: data.alpha_star
461461
```

.claude/skills/netgraph-dsl/references/REFERENCE.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -752,11 +752,15 @@ workflow:
752752
```yaml
753753
- step_type: NetworkStats
754754
name: stats
755-
include_disabled: false # Include disabled nodes/links in stats
755+
include_disabled: false # Include disabled nodes/links in stats
756+
excluded_nodes: [] # Optional: temporary node exclusions
757+
excluded_links: [] # Optional: temporary link exclusions
756758
```
757759

758760
### MaxFlow Parameters
759761

762+
Baseline (no failures) is always run first as a reference. The `iterations` parameter specifies how many failure scenarios to run.
763+
760764
```yaml
761765
- step_type: MaxFlow
762766
name: capacity_analysis
@@ -766,7 +770,7 @@ workflow:
766770
failure_policy: policy_name
767771
iterations: 1000
768772
parallelism: auto # or integer
769-
baseline: true # Include baseline (no failures) iteration
773+
seed: 42 # Optional: for reproducibility
770774
shortest_path: false # Restrict to shortest paths only
771775
require_capacity: true # Path selection considers capacity
772776
flow_placement: PROPORTIONAL # PROPORTIONAL | EQUAL_BALANCED
@@ -777,6 +781,8 @@ workflow:
777781

778782
### TrafficMatrixPlacement Parameters
779783

784+
Baseline (no failures) is always run first as a reference. The `iterations` parameter specifies how many failure scenarios to run.
785+
780786
```yaml
781787
- step_type: TrafficMatrixPlacement
782788
name: tm_placement
@@ -785,7 +791,7 @@ workflow:
785791
iterations: 100
786792
parallelism: auto
787793
placement_rounds: auto # or integer
788-
baseline: false
794+
seed: 42 # Optional: for reproducibility
789795
include_flow_details: true
790796
include_used_edges: false
791797
store_failure_patterns: false

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [0.14.0] - 2025-12-20
9+
10+
### Changed
11+
12+
- **BREAKING**: Monte Carlo results restructured: `baseline` returned separately; `results` contains deduplicated failure patterns with `occurrence_count`
13+
- **BREAKING**: `baseline` parameter removed from Monte Carlo APIs; baseline always runs implicitly
14+
15+
### Added
16+
17+
- `FlowIterationResult.occurrence_count`: how many iterations produced this failure pattern
18+
- `FlowIterationResult.failure_trace`: mode/rule selection details when `store_failure_patterns=True`
19+
820
## [0.13.0] - 2025-12-19
921

1022
### Changed

docs/reference/api-full.md

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Quick links:
1212
- [CLI Reference](cli.md)
1313
- [DSL Reference](dsl.md)
1414

15-
Generated from source code on: December 20, 2025 at 00:19 UTC
15+
Generated from source code on: December 20, 2025 at 04:32 UTC
1616

1717
Modules auto-discovered: 49
1818

@@ -635,7 +635,7 @@ Attributes:
635635

636636
**Methods:**
637637

638-
- `apply_failures(self, network_nodes: 'Dict[str, Any]', network_links: 'Dict[str, Any]', network_risk_groups: 'Dict[str, Any] | None' = None, *, seed: 'Optional[int]' = None) -> 'List[str]'` - Identify which entities fail for this iteration.
638+
- `apply_failures(self, network_nodes: 'Dict[str, Any]', network_links: 'Dict[str, Any]', network_risk_groups: 'Dict[str, Any] | None' = None, *, seed: 'Optional[int]' = None, failure_trace: 'Optional[Dict[str, Any]]' = None) -> 'List[str]'` - Identify which entities fail for this iteration.
639639
- `to_dict(self) -> 'Dict[str, Any]'` - Convert to dictionary for JSON serialization.
640640

641641
### FailureRule
@@ -1114,6 +1114,9 @@ MaxFlow workflow step.
11141114
Monte Carlo analysis of maximum flow capacity between node groups using FailureManager.
11151115
Produces unified `flow_results` per iteration under `data.flow_results`.
11161116

1117+
Baseline (no failures) is always run first as a separate reference. The `iterations`
1118+
parameter specifies how many failure scenarios to run.
1119+
11171120
YAML Configuration Example:
11181121

11191122
workflow:
@@ -1130,7 +1133,6 @@ YAML Configuration Example:
11301133
shortest_path: false
11311134
require_capacity: true # false for true IP/IGP semantics
11321135
flow_placement: "PROPORTIONAL"
1133-
baseline: false
11341136
seed: 42
11351137
store_failure_patterns: false
11361138
include_flow_details: false # cost_distribution
@@ -1140,18 +1142,21 @@ YAML Configuration Example:
11401142

11411143
Maximum flow Monte Carlo workflow step.
11421144

1145+
Baseline (no failures) is always run first as a separate reference. Results are
1146+
returned with baseline in a separate field, and failure iterations in a 0-indexed
1147+
list that corresponds 1:1 with failure_patterns.
1148+
11431149
Attributes:
11441150
source: Source node selector (string path or selector dict).
11451151
sink: Sink node selector (string path or selector dict).
11461152
mode: Flow analysis mode ("combine" or "pairwise").
11471153
failure_policy: Name of failure policy in scenario.failure_policy_set.
1148-
iterations: Number of Monte Carlo trials.
1154+
iterations: Number of failure iterations to run.
11491155
parallelism: Number of parallel worker processes.
11501156
shortest_path: Whether to use shortest paths only.
11511157
require_capacity: If True (default), path selection considers capacity.
11521158
If False, path selection is cost-only (true IP/IGP semantics).
11531159
flow_placement: Flow placement strategy.
1154-
baseline: Whether to run first iteration without failures as baseline.
11551160
seed: Optional seed for reproducible results.
11561161
store_failure_patterns: Whether to store failure patterns in results.
11571162
include_flow_details: Whether to collect cost distribution per flow.
@@ -1171,7 +1176,6 @@ Attributes:
11711176
- `shortest_path` (bool) = False
11721177
- `require_capacity` (bool) = True
11731178
- `flow_placement` (FlowPlacement | str) = 1
1174-
- `baseline` (bool) = False
11751179
- `store_failure_patterns` (bool) = False
11761180
- `include_flow_details` (bool) = False
11771181
- `include_min_cut` (bool) = False
@@ -1309,17 +1313,23 @@ TrafficMatrixPlacement workflow step.
13091313
Runs Monte Carlo demand placement using a named traffic matrix and produces
13101314
unified `flow_results` per iteration under `data.flow_results`.
13111315

1316+
Baseline (no failures) is always run first as a separate reference. The `iterations`
1317+
parameter specifies how many failure scenarios to run.
1318+
13121319
### TrafficMatrixPlacement
13131320

13141321
Monte Carlo demand placement using a named traffic matrix.
13151322

1323+
Baseline (no failures) is always run first as a separate reference. Results are
1324+
returned with baseline in a separate field, and failure iterations in a 0-indexed
1325+
list that corresponds 1:1 with failure_patterns.
1326+
13161327
Attributes:
13171328
matrix_name: Name of the traffic matrix to analyze.
13181329
failure_policy: Optional policy name in scenario.failure_policy_set.
1319-
iterations: Number of Monte Carlo iterations.
1330+
iterations: Number of failure iterations to run.
13201331
parallelism: Number of parallel worker processes.
13211332
placement_rounds: Placement optimization rounds (int or "auto").
1322-
baseline: Include baseline iteration without failures first.
13231333
seed: Optional seed for reproducibility.
13241334
store_failure_patterns: Whether to store failure pattern results.
13251335
include_flow_details: When True, include cost_distribution per flow.
@@ -1338,7 +1348,6 @@ Attributes:
13381348
- `iterations` (int) = 1
13391349
- `parallelism` (int | str) = auto
13401350
- `placement_rounds` (int | str) = auto
1341-
- `baseline` (bool) = False
13421351
- `store_failure_patterns` (bool) = False
13431352
- `include_flow_details` (bool) = False
13441353
- `include_used_edges` (bool) = False
@@ -1968,8 +1977,14 @@ Args:
19681977
Container for per-iteration analysis results.
19691978

19701979
Args:
1971-
failure_id: Stable identifier for the failure scenario (e.g., "baseline" or a hash).
1980+
failure_id: Stable identifier for the failure scenario (hash of excluded
1981+
components, or "" for no exclusions).
19721982
failure_state: Optional excluded components for the iteration.
1983+
failure_trace: Optional trace info (mode_index, selections, expansion) when
1984+
store_failure_patterns=True. None for baseline or when tracing disabled.
1985+
occurrence_count: Number of Monte Carlo iterations that produced this exact
1986+
failure pattern. Used with deduplication to avoid re-running identical
1987+
analyses. Defaults to 1.
19731988
flows: List of flow entries for this iteration.
19741989
summary: Aggregated summary across ``flows``.
19751990
data: Optional per-iteration extras.
@@ -1978,6 +1993,8 @@ Args:
19781993

19791994
- `failure_id` (str)
19801995
- `failure_state` (Optional[Dict[str, List[str]]])
1996+
- `failure_trace` (Optional[Dict[str, Any]])
1997+
- `occurrence_count` (int) = 1
19811998
- `flows` (List[FlowEntry]) = []
19821999
- `summary` (FlowSummary) = FlowSummary(total_demand=0.0, total_placed=0.0, overall_ratio=1.0, dropped_flows=0, num_flows=0)
19832000
- `data` (Dict[str, Any]) = {}
@@ -2801,12 +2818,12 @@ Attributes:
28012818

28022819
**Methods:**
28032820

2804-
- `compute_exclusions(self, policy: "'FailurePolicy | None'" = None, seed_offset: 'int | None' = None) -> 'tuple[set[str], set[str]]'` - Compute set of nodes and links to exclude for a failure iteration.
2821+
- `compute_exclusions(self, policy: "'FailurePolicy | None'" = None, seed_offset: 'int | None' = None, failure_trace: 'Optional[Dict[str, Any]]' = None) -> 'tuple[set[str], set[str]]'` - Compute set of nodes and links to exclude for a failure iteration.
28052822
- `get_failure_policy(self) -> "'FailurePolicy | None'"` - Get failure policy for analysis.
2806-
- `run_demand_placement_monte_carlo(self, demands_config: 'list[dict[str, Any]] | Any', iterations: 'int' = 100, parallelism: 'int' = 1, placement_rounds: 'int | str' = 'auto', baseline: 'bool' = False, seed: 'int | None' = None, store_failure_patterns: 'bool' = False, include_flow_details: 'bool' = False, include_used_edges: 'bool' = False, **kwargs) -> 'Any'` - Analyze traffic demand placement success under failures.
2807-
- `run_max_flow_monte_carlo(self, source: 'str | dict[str, Any]', sink: 'str | dict[str, Any]', mode: 'str' = 'combine', iterations: 'int' = 100, parallelism: 'int' = 1, shortest_path: 'bool' = False, require_capacity: 'bool' = True, flow_placement: 'FlowPlacement | str' = <FlowPlacement.PROPORTIONAL: 1>, baseline: 'bool' = False, seed: 'int | None' = None, store_failure_patterns: 'bool' = False, include_flow_summary: 'bool' = False, **kwargs) -> 'Any'` - Analyze maximum flow capacity envelopes between node groups under failures.
2808-
- `run_monte_carlo_analysis(self, analysis_func: 'AnalysisFunction', iterations: 'int' = 1, parallelism: 'int' = 1, baseline: 'bool' = False, seed: 'int | None' = None, store_failure_patterns: 'bool' = False, **analysis_kwargs) -> 'dict[str, Any]'` - Run Monte Carlo failure analysis with any analysis function.
2809-
- `run_sensitivity_monte_carlo(self, source: 'str | dict[str, Any]', sink: 'str | dict[str, Any]', mode: 'str' = 'combine', iterations: 'int' = 100, parallelism: 'int' = 1, shortest_path: 'bool' = False, flow_placement: 'FlowPlacement | str' = <FlowPlacement.PROPORTIONAL: 1>, baseline: 'bool' = False, seed: 'int | None' = None, store_failure_patterns: 'bool' = False, **kwargs) -> 'dict[str, Any]'` - Analyze component criticality for flow capacity under failures.
2823+
- `run_demand_placement_monte_carlo(self, demands_config: 'list[dict[str, Any]] | Any', iterations: 'int' = 100, parallelism: 'int' = 1, placement_rounds: 'int | str' = 'auto', seed: 'int | None' = None, store_failure_patterns: 'bool' = False, include_flow_details: 'bool' = False, include_used_edges: 'bool' = False, **kwargs) -> 'Any'` - Analyze traffic demand placement success under failures.
2824+
- `run_max_flow_monte_carlo(self, source: 'str | dict[str, Any]', sink: 'str | dict[str, Any]', mode: 'str' = 'combine', iterations: 'int' = 100, parallelism: 'int' = 1, shortest_path: 'bool' = False, require_capacity: 'bool' = True, flow_placement: 'FlowPlacement | str' = <FlowPlacement.PROPORTIONAL: 1>, seed: 'int | None' = None, store_failure_patterns: 'bool' = False, include_flow_summary: 'bool' = False, **kwargs) -> 'Any'` - Analyze maximum flow capacity envelopes between node groups under failures.
2825+
- `run_monte_carlo_analysis(self, analysis_func: 'AnalysisFunction', iterations: 'int' = 1, parallelism: 'int' = 1, seed: 'int | None' = None, store_failure_patterns: 'bool' = False, **analysis_kwargs) -> 'dict[str, Any]'` - Run Monte Carlo failure analysis with any analysis function.
2826+
- `run_sensitivity_monte_carlo(self, source: 'str | dict[str, Any]', sink: 'str | dict[str, Any]', mode: 'str' = 'combine', iterations: 'int' = 100, parallelism: 'int' = 1, shortest_path: 'bool' = False, flow_placement: 'FlowPlacement | str' = <FlowPlacement.PROPORTIONAL: 1>, seed: 'int | None' = None, store_failure_patterns: 'bool' = False, **kwargs) -> 'dict[str, Any]'` - Analyze component criticality for flow capacity under failures.
28102827
- `run_single_failure_scenario(self, analysis_func: 'AnalysisFunction', **kwargs) -> 'Any'` - Run a single failure scenario for convenience.
28112828

28122829
---

docs/reference/dsl.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -670,7 +670,6 @@ workflow:
670670
matrix_name: baseline_traffic_matrix
671671
failure_policy: weighted_modes
672672
iterations: 1000
673-
baseline: true
674673
```
675674

676675
**Common Steps:**

docs/reference/workflow.md

Lines changed: 30 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ workflow:
2626
matrix_name: baseline_traffic_matrix
2727
failure_policy: random_failures
2828
iterations: 1000
29-
baseline: true
3029
```
3130
3231
## Execution Model
@@ -71,7 +70,7 @@ Parameters:
7170

7271
### MaxFlow
7372

74-
Monte Carlo maximum flow analysis between node groups.
73+
Monte Carlo maximum flow analysis between node groups. Baseline (no failures) is always run first as a separate reference.
7574

7675
```yaml
7776
- step_type: MaxFlow
@@ -80,9 +79,8 @@ Monte Carlo maximum flow analysis between node groups.
8079
sink: "^storage/.*"
8180
mode: "combine" # combine | pairwise
8281
failure_policy: random_failures
83-
iterations: 1000
82+
iterations: 1000 # Number of failure iterations
8483
parallelism: auto # or an integer
85-
baseline: true
8684
shortest_path: false
8785
require_capacity: true # false for true IP/IGP semantics
8886
flow_placement: PROPORTIONAL # or EQUAL_BALANCED
@@ -93,17 +91,16 @@ Monte Carlo maximum flow analysis between node groups.
9391

9492
### TrafficMatrixPlacement
9593

96-
Monte Carlo placement of a named traffic matrix with optional alpha scaling.
94+
Monte Carlo placement of a named traffic matrix with optional alpha scaling. Baseline (no failures) is always run first as a separate reference.
9795

9896
```yaml
9997
- step_type: TrafficMatrixPlacement
10098
name: tm_placement
10199
matrix_name: default
102100
failure_policy: random_failures # Optional: policy name in failure_policy_set
103-
iterations: 100
101+
iterations: 100 # Number of failure iterations
104102
parallelism: auto
105103
placement_rounds: auto # or an integer
106-
baseline: false
107104
include_flow_details: true # cost_distribution per flow
108105
include_used_edges: false # include per-demand used edge lists
109106
store_failure_patterns: false
@@ -115,7 +112,7 @@ Monte Carlo placement of a named traffic matrix with optional alpha scaling.
115112

116113
Outputs:
117114

118-
- metadata: iterations, parallelism, baseline, analysis_function, policy_name,
115+
- metadata: iterations, parallelism, analysis_function, policy_name,
119116
execution_time, unique_patterns
120117
- data.context: matrix_name, placement_rounds, include_flow_details,
121118
include_used_edges, base_demands, alpha, alpha_source
@@ -266,9 +263,8 @@ source:
266263

267264
```yaml
268265
mode: combine # combine | pairwise (default: combine)
269-
iterations: 1000 # Monte Carlo trials (default: 1)
266+
iterations: 1000 # Failure iterations to run (default: 1)
270267
failure_policy: policy_name # Name in failure_policy_set (default: null)
271-
baseline: true # Include baseline iteration first (default: false)
272268
parallelism: auto # Worker processes (default: auto)
273269
shortest_path: false # Restrict to shortest paths (default: false)
274270
require_capacity: true # Path selection considers capacity (default: true)
@@ -279,6 +275,8 @@ include_flow_details: false # Emit cost_distribution per flow
279275
include_min_cut: false # Emit min-cut edge list per flow
280276
```
281277

278+
Note: Baseline (no failures) is always run first as a separate reference. The `iterations` parameter specifies the number of failure scenarios to run.
279+
282280
## Results Export Shape
283281

284282
Exported results have a fixed top-level structure. Keys under `workflow` and `steps` are step names.
@@ -328,41 +326,39 @@ Exported results have a fixed top-level structure. Keys under `workflow` and `st
328326
}
329327
```
330328

331-
- `MaxFlow` and `TrafficMatrixPlacement` write per-iteration entries under `data.flow_results`:
329+
- `MaxFlow` and `TrafficMatrixPlacement` write results with baseline separate from failure iterations:
332330

333331
```json
334332
{
333+
"baseline": {
334+
"failure_id": "",
335+
"failure_state": { "excluded_nodes": [], "excluded_links": [] },
336+
"failure_trace": null,
337+
"occurrence_count": 1,
338+
"flows": [ ... ],
339+
"summary": { "total_demand": 10.0, "total_placed": 10.0, "overall_ratio": 1.0 }
340+
},
335341
"flow_results": [
336342
{
337-
"failure_id": "baseline",
338-
"failure_state": null,
339-
"flows": [
340-
{
341-
"source": "A", "destination": "B", "priority": 0,
342-
"demand": 10.0, "placed": 10.0, "dropped": 0.0,
343-
"cost_distribution": { "2": 6.0, "4": 4.0 },
344-
"data": { "edges": ["(u,v,k)"] }
345-
}
346-
],
347-
"summary": {
348-
"total_demand": 10.0, "total_placed": 10.0,
349-
"overall_ratio": 1.0, "dropped_flows": 0, "num_flows": 1
350-
},
351-
"data": { }
352-
},
353-
{ "failure_id": "d0eea3f4d06413a2", "failure_state": null, "flows": [],
354-
"summary": { "total_demand": 0.0, "total_placed": 0.0, "overall_ratio": 1.0, "dropped_flows": 0, "num_flows": 0 },
355-
"data": {} }
343+
"failure_id": "d0eea3f4d06413a2",
344+
"failure_state": { "excluded_nodes": ["nodeA"], "excluded_links": [] },
345+
"failure_trace": { "mode_index": 0, "selections": [...], ... },
346+
"occurrence_count": 5,
347+
"flows": [ ... ],
348+
"summary": { "total_demand": 10.0, "total_placed": 8.0, "overall_ratio": 0.8 }
349+
}
356350
],
357351
"context": { ... }
358352
}
359353
```
360354

361355
Notes:
362356

363-
- Baseline: when `baseline: true`, the first entry has `failure_id: "baseline"`.
364-
- `failure_state` may be `null` or an object with `excluded_nodes` and `excluded_links` lists.
365-
- Per-iteration `data` can include instrumentation (e.g., `iteration_metrics`).
366-
- Per-flow `data` can include instrumentation (e.g., `policy_metrics`).
357+
- Baseline is always returned separately in the `baseline` field.
358+
- `flow_results` contains K unique failure patterns (deduplicated), not N iterations.
359+
- `occurrence_count` indicates how many iterations produced each unique failure pattern.
360+
- `failure_id` is a hash of exclusions (empty string for no exclusions).
361+
- `failure_trace` contains policy selection details when `store_failure_patterns: true`.
362+
- `failure_state` contains `excluded_nodes` and `excluded_links` lists.
367363
- `cost_distribution` uses string keys for JSON stability; values are numeric.
368364
- Effective `parallelism` and other execution fields are recorded in step metadata.

ngraph/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
__all__ = ["__version__"]
44

5-
__version__ = "0.13.0"
5+
__version__ = "0.14.0"

0 commit comments

Comments
 (0)