Skip to content

Commit b20a942

Browse files
committed
Clarify stale repair report metrics
1 parent 6abd1ed commit b20a942

11 files changed

Lines changed: 31 additions & 20 deletions

analysis/document.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -794,7 +794,7 @@ def write_pdf_report(
794794
styles,
795795
"Routing-Fitness Stale Repair Summary",
796796
stale_block.lines,
797-
["Family", "Engine Set", "Persist", "Recov.", "Unrec.", "Loss", "Churn"],
797+
["Family", "Engine Set", "Persist", "Route", "Unrec.", "Loss", "Churn"],
798798
routing_fitness_stale_repair_table_rows(routing_fitness_stale_repair_summary),
799799
[3.0 * cm, 2.8 * cm, 1.4 * cm, 1.4 * cm, 1.5 * cm, 1.3 * cm, 1.4 * cm],
800800
table_counter,
@@ -1026,7 +1026,7 @@ def write_pdf_report(
10261026
styles,
10271027
"Routing-Fitness Stale Repair Summary",
10281028
stale_ref_block.lines,
1029-
["Family", "Engine Set", "Persist", "Recov.", "Unrec.", "Loss", "Churn"],
1029+
["Family", "Engine Set", "Persist", "Route", "Unrec.", "Loss", "Churn"],
10301030
routing_fitness_stale_repair_table_rows(routing_fitness_stale_repair_summary),
10311031
[3.0 * cm, 2.8 * cm, 1.4 * cm, 1.4 * cm, 1.5 * cm, 1.3 * cm, 1.4 * cm],
10321032
table_counter,

analysis/plots.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2435,12 +2435,16 @@ def render_routing_fitness_stale_repair(
24352435
"family_label": row["family_label"],
24362436
"engine_key": row["comparison_engine_set"],
24372437
"engine_label": engine_display_label(row["comparison_engine_set"]),
2438+
"route_presence": float(
2439+
row["route_present_total_window_permille_mean"] or 0.0
2440+
)
2441+
/ 10.0,
24382442
"stale_persistence": persistence,
24392443
"label_x": label_x,
24402444
"recovery_success": float(row["recovery_success_permille_mean"] or 0.0)
24412445
/ 10.0,
2442-
"recovery_label": (
2443-
f"recov={float(row['recovery_success_permille_mean'] or 0.0) / 10.0:.1f}%"
2446+
"route_label": (
2447+
f"route={float(row['route_present_total_window_permille_mean'] or 0.0) / 10.0:.1f}%"
24442448
),
24452449
"detail_label": (
24462450
f"unrec={int(round(row['unrecovered_after_loss_count_mean'] or 0.0))} "
@@ -2465,7 +2469,8 @@ def render_routing_fitness_stale_repair(
24652469
alt.Tooltip("family_label:N", title="Family"),
24662470
alt.Tooltip("engine_label:N", title="Engine"),
24672471
alt.Tooltip("stale_persistence:Q", title="Stale persistence", format=".1f"),
2468-
alt.Tooltip("recovery_success:Q", title="Recovery success", format=".1f"),
2472+
alt.Tooltip("route_presence:Q", title="Route presence", format=".1f"),
2473+
alt.Tooltip("recovery_success:Q", title="Recovery event success", format=".1f"),
24692474
alt.Tooltip("control_activity:Q", title="Control activity", format=".1f"),
24702475
alt.Tooltip("detail_label:N", title="Detail"),
24712476
],
@@ -2490,7 +2495,7 @@ def render_routing_fitness_stale_repair(
24902495
clip=False,
24912496
).encode(
24922497
x=alt.X("label_x:Q", scale=alt.Scale(domain=[0, x_limit])),
2493-
text="recovery_label:N",
2498+
text="route_label:N",
24942499
),
24952500
base.mark_text(
24962501
align="left",

analysis/sections.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -861,7 +861,7 @@ def routing_fitness_takeaway_lines(
861861
routing_fitness_stale_repair_summary,
862862
filters=[("family_label", "Recovery window")],
863863
sort_columns=[
864-
"recovery_success_permille_mean",
864+
"route_present_total_window_permille_mean",
865865
"stale_persistence_round_mean",
866866
],
867867
descending=[True, False],
@@ -908,7 +908,8 @@ def routing_fitness_takeaway_lines(
908908
"fit-for-purpose inside the tested search-plus-maintenance envelope"
909909
if (
910910
maintenance_high["comparison_engine_set"] == "pathway-batman-bellman"
911-
and float(stale_best["recovery_success_permille_mean"] or 0.0) >= 700.0
911+
and float(stale_best["route_present_total_window_permille_mean"] or 0.0)
912+
>= 900.0
912913
)
913914
else "directionally supported, but still carrying one unresolved routing-risk regime"
914915
)
@@ -939,11 +940,11 @@ def routing_fitness_takeaway_lines(
939940
[row["comparison_engine_set"] or "none" for row in stale_best_rows]
940941
),
941942
stale_best_persistence=f"{float(stale_best['stale_persistence_round_mean'] or 0.0):.1f}",
942-
stale_best_recovery=stale_best["recovery_success_permille_mean"],
943+
stale_best_route=stale_best["route_present_total_window_permille_mean"],
943944
worst_stale_family=worst_stale["family_label"],
944945
worst_stale_engine=worst_stale["comparison_engine_set"] or "none",
945946
worst_stale_persistence=f"{float(worst_stale['stale_persistence_round_mean'] or 0.0):.1f}",
946-
worst_stale_recovery=worst_stale["recovery_success_permille_mean"],
947+
worst_stale_route=worst_stale["route_present_total_window_permille_mean"],
947948
routing_fitness_envelope=envelope,
948949
)
949950

analysis/tables.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,7 @@ def routing_fitness_stale_repair_table_rows(
533533
row["family_label"],
534534
engine_display_label(row["comparison_engine_set"]),
535535
_format_table_number(row["stale_persistence_round_mean"]),
536-
_format_table_number(row["recovery_success_permille_mean"]),
536+
_format_table_number(row["route_present_total_window_permille_mean"]),
537537
_format_table_number(row["unrecovered_after_loss_count_mean"]),
538538
_format_table_number(row["first_loss_round_mean"]),
539539
f"{row['route_churn_count_mean']:.1f}",

analysis/tests/test_scoring.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,12 +1049,14 @@ def test_routing_fitness_takeaways_close_with_tested_envelope(self) -> None:
10491049
{
10501050
"family_label": "Recovery window",
10511051
"comparison_engine_set": "pathway-batman-bellman",
1052+
"route_present_total_window_permille_mean": 930.0,
10521053
"stale_persistence_round_mean": 2.0,
10531054
"recovery_success_permille_mean": 900.0,
10541055
},
10551056
{
10561057
"family_label": "Delayed observation",
10571058
"comparison_engine_set": "pathway",
1059+
"route_present_total_window_permille_mean": 640.0,
10581060
"stale_persistence_round_mean": 4.0,
10591061
"recovery_success_permille_mean": 600.0,
10601062
},
@@ -1136,12 +1138,14 @@ def test_routing_fitness_takeaways_keep_tied_best_engine_labels_stable(self) ->
11361138
{
11371139
"family_label": "Recovery window",
11381140
"comparison_engine_set": "pathway-batman-bellman",
1141+
"route_present_total_window_permille_mean": 930.0,
11391142
"stale_persistence_round_mean": 2.0,
11401143
"recovery_success_permille_mean": 900.0,
11411144
},
11421145
{
11431146
"family_label": "Delayed observation",
11441147
"comparison_engine_set": "pathway",
1148+
"route_present_total_window_permille_mean": 640.0,
11451149
"stale_persistence_round_mean": 4.0,
11461150
"recovery_success_permille_mean": 600.0,
11471151
},
@@ -1183,6 +1187,7 @@ def test_routing_fitness_renderers_keep_deterministic_family_order(self) -> None
11831187
stale_rows = stale["datasets"][stale["data"]["name"]]
11841188
self.assertEqual(stale_rows[0]["family_label"], "Recovery window")
11851189
self.assertEqual(stale_rows[0]["engine_key"], "pathway")
1190+
self.assertIn("route=", stale_rows[0]["route_label"])
11861191

11871192
def test_comparison_config_sensitivity_marks_flat_and_separating_families(self) -> None:
11881193
aggregates = pl.from_dicts(

analysis/text.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,7 @@ Compact fairness view for the shared-broker families. Column guide: Min and Max
496496

497497
@table routing_fitness_stale_repair_summary
498498

499-
Compact stale-information repair view. Column guide: Persist is the mean bad-route persistence after the first disruptive topology change, Recov. is recovery success, Unrec. is mean unrecovered-after-loss count, Loss is the first-loss round, and Churn is mean route churn.
499+
Compact stale-information repair view. Column guide: Persist is the mean bad-route persistence after the first disruptive topology change, Route is total-window route presence, Unrec. is mean unrecovered-after-loss count, Loss is the first-loss round, and Churn is mean route churn. Recovery-event success is still exported in the CSV, but it is not used as the headline because many stale scenarios never enter a loss/recovery event path.
500500

501501
### Routing-Fitness Figure Context
502502

@@ -519,15 +519,15 @@ The broker detail labels summarize how much of the visible route activity still
519519

520520
@figure routing_fitness_stale_repair
521521

522-
Bad-route persistence after delayed or asymmetric observations. Shorter bars are better because they mean the engine stops trusting stale routing state quickly after disruption. The labels show recovery success and unrecovered counts so the figure separates fast cleanup from cleanup that still fails to recover.
522+
Bad-route persistence after delayed or asymmetric observations. Shorter bars are better because they mean the engine stops trusting stale routing state quickly after disruption. The labels show total-window route presence and unrecovered counts so the figure separates fast cleanup from cleanup that still leaves the objective unavailable.
523523

524524
### Routing-Fitness Takeaways
525525

526526
- In the high search-burden crossover band, {search_high_engines} lead at {search_high_route} permille total-window route presence with {search_high_recovery} permille recovery success.
527527
- In the high maintenance-benefit crossover band, {maintenance_high_engines} lead at {maintenance_high_route} permille total-window route presence with {maintenance_high_recovery} permille recovery success.
528528
- Under shared-broker contention, `Shared corridor` is best handled by {shared_corridor_engines} at {shared_corridor_min_route} permille minimum per-flow route presence, while `Detour choice` is best handled by {detour_choice_engines} at {detour_choice_min_route} permille.
529529
- The harshest fairness tail is currently `{worst_starvation_family}`, where `{worst_starvation_engine}` still records {worst_starvation_value} starved objectives on average.
530-
- In the stale-repair surface, `Recovery window` is best handled by {stale_best_engines} at {stale_best_persistence} rounds of stale persistence and {stale_best_recovery} permille recovery success, while the worst stale overcommit is `{worst_stale_family}` under `{worst_stale_engine}` at {worst_stale_persistence} rounds and only {worst_stale_recovery} permille recovery success.
530+
- In the stale-repair surface, `Recovery window` is best handled by {stale_best_engines} at {stale_best_persistence} rounds of stale persistence and {stale_best_route} permille route presence, while the worst stale overcommit is `{worst_stale_family}` under `{worst_stale_engine}` at {worst_stale_persistence} rounds and only {worst_stale_route} permille route presence.
531531
- Taken together, the new evidence says the candidate direction is {routing_fitness_envelope}.
532532

533533
## Part III. Diffusion Calibration

docs/305_profile_reference.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,4 @@ graph LR
4848

4949
The reference end-to-end examples are the split `reference-client` tests in [`crates/reference-client/tests/client_builder.rs`](../crates/reference-client/tests/client_builder.rs), [`crates/reference-client/tests/e2e_pathway_shared_network.rs`](../crates/reference-client/tests/e2e_pathway_shared_network.rs), [`crates/reference-client/tests/e2e_batman_pathway_handoff.rs`](../crates/reference-client/tests/e2e_batman_pathway_handoff.rs), [`crates/reference-client/tests/e2e_olsrv2_shared_network.rs`](../crates/reference-client/tests/e2e_olsrv2_shared_network.rs), and [`crates/reference-client/tests/e2e_olsrv2_pathway_handoff.rs`](../crates/reference-client/tests/e2e_olsrv2_pathway_handoff.rs), plus the shared scenarios in [`crates/testkit/src/reference_client_scenarios.rs`](../crates/testkit/src/reference_client_scenarios.rs). They show how to add a new client runtime to the same in-memory network without bypassing the bridge-owned ingress path or the router-owned canonical path.
5050

51-
For walkthroughs on implementing a custom link or a custom node profile, see [Custom Transport](505_custom_transport.md) and [Custom Device](506_custom_device.md). For the full dependency graph and ownership rules the profile crates fit into, see [Crate Architecture](999_crate_architecture.md).
51+
For custom link or node profile work, start from the in-tree builders in `jacquard-mem-link-profile` and `jacquard-mem-node-profile`, then validate the ownership boundaries against [Crate Architecture](999_crate_architecture.md).

docs/307_experimental_methodology.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ The same discipline applies to policy parameters when a comparison covers polici
3838

3939
## The Pipeline From Experiment To Report
4040

41-
A simulator run produces `runs.jsonl`, `aggregate_summary.json`, and `breakdown_summary.json` under the run directory. Diffusion runs add `diffusion_runs.jsonl` plus the diffusion aggregate and boundary summaries. Head-to-head runs add `head_to_head_summary.csv`. Model-lane runs add `model_artifacts.jsonl` as a validation companion rather than a scoring input.
41+
A simulator run produces a per-run log plus aggregate and breakdown JSON files under the run directory. Diffusion runs add their own per-run log plus diffusion aggregate and boundary summaries. Head-to-head reductions are exported into the generated report directory. Model-lane runs add model artifacts as validation companions rather than scoring inputs.
4242

4343
The `analysis/` Python package reads those artifacts. `data.py` loads them into Polars frames. `scoring.py` derives per-run metrics. `tables.py` produces CSV tables. `plots.py` produces vector plots. `sections.py` composes report sections. `report.py` is the entry that assembles the PDF.
4444

docs/505_custom_transport.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,4 +104,4 @@ The composed profile plugs into the reference client's `ClientBuilder` or into a
104104

105105
The minimum composition wires three things together. First, a router that owns canonical route publication. Second, one or more engines registered on that router, each holding a queue-backed `TransportSenderEffects` handle. Third, a host bridge that owns the `TransportDriver`, drains ingress, stamps `Tick`, and advances the router through synchronous rounds.
106106

107-
For the full capstone that composes a custom transport, a custom engine, and a custom device profile end to end, see [Bringing It Together](507_bringing_it_together.md).
107+
For end-to-end host composition patterns, see [Client Assembly](503_client_assembly.md) and [Crate Architecture](999_crate_architecture.md).

docs/506_custom_device.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ let node = NodePreset::route_capable(options, &PATHWAY_ENGINE_ID).build();
5151

5252
Engine eligibility is encoded through the node's service descriptors. Only engines whose `RoutingEngineId` appears in the node's service surface are eligible to produce route candidates toward that node. A custom device that implements a custom engine tags the engine id in its service descriptor; see [Custom Engine](504_custom_engine.md).
5353

54-
For a device profile to advertise multiple services or multi-engine eligibility, compose the descriptors manually through `SimulatedServiceDescriptor` builders. `ServiceKind` distinguishes `Discover`, `Move`, `Hold`, and other service classes.
54+
For a device profile to advertise multiple services or multi-engine eligibility, compose the descriptors manually through `SimulatedServiceDescriptor` builders. `RouteServiceKind` distinguishes `Discover`, `Move`, `Hold`, and other service classes.
5555

5656
## Node State
5757

0 commit comments

Comments
 (0)