chore(rebase): the Quebec-grounded topology re-base, and the 42 pins it moves - #52
Merged
Merged
Conversation
…agship configs
The data half of the single topology re-base (bd 4os.7, 4os.14, 4os.6). The
flagship's pins and CALIBRATION entry follow in this branch after the full run;
nothing here is re-pinned yet.
- ev_hosting_flex synthetic_network_config.json:
- capacitated LV assignment, at most 10 homes per MV/LV unit;
- block penalty 0.005 and street siting, both from a pinned street layer;
- external_grid.vm_pu 1.04.
The limit comes from Hydro-Quebec's own guide (100 kVA serves up to ten
houses), cross-checked on metered HQ electric-heated homes (100 kVA at
nameplate: 9 at P95, 11 at P50). The study rates each unit from its kVA
ladder, so the partition limit is the largest residential unit's. 1.04 is the
slackVmPu the study already declares.
- inputs/streets.geojson: 5103 drive_service segments written by
tools/snapshot_streets.py, sha256 declared in the config, with ODbL
attribution in inputs/README.md and a streetLayer entry in project.yaml.
- configs/grid/config.json (SDK default):
- capacitated, at most 20 per 210 kVA unit (20 metered HQ electric-heated
homes peak at 190.6 kW P95 against 205.8 kW usable);
- external_grid 1.04;
- no street layer, since the config serves arbitrary footprints.
Removes sizing_capacity_kva and mv_hv.count, which nothing reads (bd 4os.6).
- Tests that copy either config for an unrelated purpose now strip its
topology block, so they keep testing what they tested.
Measured through PR #50's API on the real footprints:
- flagship: homes per unit 1-10 (mean 5.99, unchanged), forced block crossings
308 -> 38, 503 of 540 clusters inside one block, every transformer on a street;
- SDK default at 1.04 pu: 0 transformers above 100%, 0 LV buses below 0.95.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…pare_workspace prepare_workspace runs `gridalyn project prepare-workspace`, which creates the SDK's default output directories (data, figures, manifests, operations, reports, cache). outputs/json is not one of them. The stage declared it anyway, and since the runner enforces declared outputs, a run on a clean tree fails at stage 1: "stage 'prepare_workspace' exited 0 but did not produce outputs/json". Every run so far used a checkout where an earlier run had already left outputs/json behind, so none of them saw the failure. The first cold run in a fresh worktree did (re-base run, eff31e8b). Nothing reads the directory before a stage writes into it: every writer goes through ProjectScript.write_json, which creates the parent. The declaration was false, so it is removed rather than made true by creating an empty directory. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…and record why One cold full run from committed code: 25 stages, no stage filter, manifest completed, git_commit 6de591bd, 2026-09-15 19:02-22:26Z, in a dedicated worktree. Regression is 94/94 valid against the re-based pins, the flagship sweep is 157 passed, and check_calibration_claims gates 33 claims OK. WHAT MOVED (42 of 94). Not the hosting headlines: annual.*, cred.*, insurance.*, coldcoupling.* and flexincentive.* are value-identical, because the worked example is still a 6-home 71.25 kW physical twin (idx-0 now, idx-10 before). What moved is everything computed over the fleet and over the whole network: pf 6, netchar 5, cluster 6, perf 2, congestion 3, phase 2, voltage 2, voltage_net 4, nonwires 4, fleet 8. The two numbers to carry: voltage_net.p_undervolt_at_ref 0.0 -> 0.11273 (first risk 1.563 -> 0.943 EV/home) fleet.n_at_risk_at_1ev_static 500 -> 506 WHY. The four model changes of bd 4os.7 / 4os.14, declared in the study's grid config: a capacity-limited LV partition at 10 homes per unit (Hydro-Quebec's subdivision guide, cross-checked on metered HQ data), transformers sited on the street instead of on the building they serve, a block penalty that cuts partition-forced block crossings 308 -> 38, and a slack declared at 1.04 pu instead of an implicit 1.0. The undervoltage move is the honest consequence of modelling service drops as conductor rather than as 1 m stubs. RECORDED. CALIBRATION.md carries a dated section with the evidence, the per-family moves and the limits (including that per-change attribution was NOT measured: the four moved together in one run). REBASE_LOG.md carries the entry and the new digest. README findings that quoted moved numbers are updated. tests/test_ev_hosting_flex_phase.py asserted a balanced min voltage <= 1.01 pu, which pinned the old implicit 1.0 slack. It now bounds by the declared setpoint. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Sep 16, 2026
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.
The data half of the single topology re-base (bd 4os.7, 4os.14, 4os.6), on the mechanism merged in #50. This one moves the flagship's numbers: 42 of its 94 pins, re-based on one cold full run and recorded with their rationale.
What the study now declares
projects/ev_hosting_flex/inputs/synthetic_network_config.json:topology.lv_assignment: capacitatedwithmax_customers_per_transformer: 10topology.block_penalty_km2: 0.005andsnap_transformers_to_streets: truetopology.street_layer:streets.geojsonpinned by sha256external_grid.vm_pu: 1.04— the setpointstudyConfig.slackVmPualready declared for the study's own solvesconfigs/grid/config.json(SDK default): capacitated at 20 per 210 kVA unit,external_grid.vm_pu 1.04, no street layer (it serves arbitrary footprints). It also dropssizing_capacity_kvaandmv_hv.count, which nothing reads (bd 4os.6).Why 10 homes, and not a formula
Three independent sources agree, and none of them is this feeder:
datasets/hq, 573 metered electric-heated homesThe study rates each unit from its own
transformerKvaLadder, so its partition limit is the largest residential unit's, not the 75 kVA placeholder's.What the re-base did to the network
What it did to the results
Hosting headlines did not move: firm 11 EVs, flexible 16, every
cred.*andinsurance.*pin value-identical, because the worked example is still a 6-home 71.25 kW physical twin.The two numbers to carry:
voltage_net.p_undervolt_at_ref0.0 → 0.113, first risk 1.563 → 0.943 EV/home, binding bus on a 10-home cluster. The old "no undervoltage risk at 1 EV/home" was a property of service drops modelled as 1 m stubs.fleet.n_at_risk_at_1ev_static500 → 506, with deferrals 73 → 66; underhourly_kt, 185 → 199 and 182 → 195. Deferral value rises with them:nonwires.total_deferral_npv6,359.52 → 14,448.16 $.Losses rise 3.24% → 4.15% at 0 EV: the new LV conductor being modelled rather than assumed away.
Verification
completed,git_commit6de591bd, 19:02-22:26Z, in a dedicated worktree withPYTHONPATHforced to it.check_calibration_claims --checkgates 33 claims OK; sense-check valid, score 1.0.CALIBRATION.mdcarries a dated section with the evidence, the per-family moves and the limits — including that per-change attribution was not measured, since the four changes moved together in one run.REBASE_LOG.mdcarries the entry and the new digest.Also here
fix(ev_hosting_flex):prepare_workspacedeclaredoutputs/json, whichproject prepare-workspacenever creates. Every earlier run reused a checkout where a previous run had left the directory behind; the first cold run in a fresh worktree failed at stage 1. The false declaration is removed.tests/test_ev_hosting_flex_phase.pyasserted a balanced min voltage ≤ 1.01 pu, which pinned the old implicit 1.0 slack. It now bounds by the declared setpoint.Follow-ups, not in this PR
flagship-reproduceverification receipt: its gate requires the commit it names to lead to HEAD, and a squash merge discards this branch's commits. It gets updated to the merge commit right after this lands.🤖 Generated with Claude Code