feat(planner): progress the dose weekly, habituate a beginner's BASE, and put easy aerobic work on the wall - #126
Merged
Conversation
… and put easy aerobic work on the wall PR 2 of the doctrine-audit tail, at v8.12.0. Rulings 35-38 and 41 in ct_plan_doctrine.md, plus rulings 46-48 taken while building it. Nothing here was decided in this commit; the amendments record what measured differently. - #117 (rulings 36, 46): a dose now moves week to week inside a block. The rule is keyed on the (aspect_key, protocol_kind) PAIR, never on aspect_key alone — `power` holds lactic An Pow AND alactic max-effort work, which the sources progress in opposite directions. `power` x `intervals` is the only cell holding both, so that cell alone reads work_seconds, split at 15 s, and a guard pins the cell to its two rows so a third is a decision, not a pass. An Cap scales work AND both rest fields together, so "longer work" and "never less rest" hold at once and §7's 2-4x band holds by construction (2.00-3.00x, n=1353). Absence from the rule table IS the not-a-volume-multiplier invariant, and a guard asserts it. No migration: UniqueConstraint (exercise_id, phase) is untouched and week_no reaches the dose seam instead. Dose cells identical across a week-pair 78.9% -> 60.6%; 0 of 1192 cells carrying a sourced rule remain identical. The second, mechanical cause too: `spread % len(pool)` cancelled the week term wherever a pool's length matched the stride. All four sites now route through one `_pool_index`, `_spread`'s own two terms swapped, no new constant. - #118 + guard 5 (ruling 35): BASE draws `hangboard_density_hangs`. The beginner zero was never the gate — `_fill_finger_strength` returns before it, so a beginner's finger work always arrived through the ordinary supplementary slot, and 115 of 115 swept BASE finger blocks were max hangs or repeaters. So this scales CONTENT, which is what the sources scale: HABITUATION_PROTOCOLS / HABITUATION_PHASES filter that one pool. BASE occurrences 0 -> 70, grade gap 1-2 0 -> 28, plans drawing it in BASE 0/60 -> 40/60. The guard reads PER LEVEL because the seven-profile union could never assert one band. Guard 5's strict `<` gains its written reason at both ends now that the zero is a decision. - Ruling 41: `easy_climbing_flush`, the on-wall easy-climbing `endurance` row STRENGTH and POWER had no candidate for, at §7's 600 s floor exactly. An Cap weeks carrying no aerobic work 39.4% -> 12.5% (strength 61.1% -> 2.8%, power 77.5% -> 9.8%), POWER_ENDURANCE out of scope by ruling 24. It PAYS INTO F14 rather than deepening it: general_strength +144 blocks in strength, +120 in power, strength share 3.87% -> 6.14% — the opposite of the rejected `_try_supplementary` override, which cost general_strength 57%. - F11 (rulings 38, 47): closed as a DECLARED divergence. Ruling 38's instruction was refused by measurement — seven readings against the whole suite and only the current cap is green; uncapped turns 9 guards red, including ruling 30's out-training invariant. `_rotated_pool` enters at `spread % len(ring)`, so a 2-session week reads 2 of 16 positions at an offset set by the week number: re-weighting moves presence, not proportion. Delivered instead: one shared `aspect_rank()` across both surfaces, three guards making the flattening a decision, three false docstrings corrected. Prose corrections, none of them catchable by any guard: a comment cited a `rest_seconds` column CHECK that does not exist (the floor is ours; the table checks sets, intensity_pct and target_rpe only); "eleven rows" was fourteen; "BASE authors two HOLD rows" — it authors seven, two of them finger; and `easy_climbing_flush`'s copy said "ten unhurried minutes" while the row is expandable to 1200 s, so it says "a few" instead. Two things a reviewer should know. Ruling 41's row re-based #117's shorter-rest arm from 57 cells to 15 and `boulders_on_the_two_minute` now contributes none, so that arm reads one exercise and stayed green throughout — recovering it is tied to F26. And F11's first measurement round read byte-identical across all six readings because `import server.domain.planner.generate as G` binds the function re-exported by `planner/__init__.py`, not the module: the harness was measuring nothing. Sabotage and confirm red before trusting a null result. Every guard added or touched was shown red first; the red is in the PR body. Co-authored-by: Kilian Mateo <13885240+kilianmc@users.noreply.github.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This was referenced Sep 6, 2026
This branch was successfully deployed
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.
What and why
PR 2 of the doctrine-audit tail, at v8.12.0: issues #117 and #118 plus guard 5, ruling 41's authoring, and F11 closed as a declared divergence. Rulings 35–38 and 41 in
ct_plan_doctrine.md; rulings 46–48 were taken while building it, and three amendments record what measured differently from the rulings that ordered the work. Server-only — noweb/, no migration, no codegen.BASEoccurrences 0 → 70, grade gap 1–2 0 → 28, plans drawing it inBASE0/60 → 40/60,BASEfinger blocks that are max hangs/repeaters 115/115 → 0/115easy_climbing_flushPlan digest
f95ff03297ba02db→dd29d23ad1962160. Every weekly ceiling holds: hard-energy days >3 outside the taper 0 → 0; An Cap sessions over their phase ceiling 0 → 0. Breadth up, 73.9 → 74.9 distinct exercises per plan, min 52 → 54.Three findings worth reading before the diff
Ruling 41's row pays into F14 instead of deepening it.
general_strength+144 blocks in strength and +120 in power,finger_strength+114 in strength; strength-aspect share ofstrengthminutes 3.87% → 6.14%. A 10-minute wall block fills less of a session than the technique/power blocks it displaces, so the supplementary pass gets more room. This is the opposite of the rejected_try_supplementaryoverride, which costgeneral_strength57% — an on-wall row and an off-wall override are not two routes to one outcome.Ruling 38's instruction was refused by measurement. Seven readings against the whole suite: cap 5 → 14 red, cap 6 → 9 red, cap 8 → co-occurrence red weeks 26 → 128, uncapped → 9 red including ruling 30's out-training invariant, two dense weightings → 8 red each, proportional-to-rank → 5 red. Only the current cap is green. The cause no ruling had:
_rotated_poolenters atspread % len(ring), so a 2-session week reads 2 of 16 positions at an offset set by the week number — re-weighting moves presence, not proportion, and presence at 2–3 sessions is what rulings 23/24/30/35 pin. Per ruling 38's own instruction the number was brought back. Closed as a declared divergence (ruling 47); the_spread/_rotated_poolroute was deliberately not filed.PR 2 hollowed one of its own guards, and it stayed green. Ruling 41's row re-based #117's shorter-rest arm from 57 cells to 15, and
boulders_on_the_two_minute— 30 of the original 57 — now contributes none, so the arm readsshort_rest_boulder_setsalone. Floors re-based 51 → 13 and 448 → 394 with the cause recorded. Recovering the coverage is tied to F26 (ruling 48).A harness trap, recorded because it nearly cost a wrong conclusion
F11's first measurement round returned all six readings byte-identical — which reads exactly like the five genuinely inert mechanisms already measured in this area.
import server.domain.planner.generate as Gbinds the function re-exported byplanner/__init__.py, not the module, so the patch was inert and the harness was measuring nothing. Sabotage the harness and confirm it goes red before trusting a null result here.CLAUDE.mdissuesplan.mdandct_plan_doctrine.md, and duplicating them as prose is what that section exists to prevent)Comment budget
BASELINE_RATCHETintests/test_comment_budget.pylowered to matchFour new
[[exception]]rows and one limit raised, each carrying a measured negative rather than a restatement — including why the cheaper_wall_picks-only aliasing fix must not be re-attempted. Two comments went over their caps during review and were trimmed rather than allowlisted, per the guard's own message that an exception is not a licence to keep going.Checks
npm run checkgreen, run once at the end — 1313 passed, ruff and mypy cleanReds captured with production reverted, then restored and re-confirmed green:
traverse_intervals is dosed (5, 40, None, 100) in week 5 and (5, 40, None, 100) in week 6 of the same strength block; its longer_work rule moved nothing.rest_between_sets_seconds fell 100 s -> 90 s. An Cap progresses by harder or longer work and never by less rest.(base, sport, endurance) is a pool of 7 and session 0 draws index {0} in all 3 loading weeks: the week term cancelled out.a 6a beginner at 5x, gap 1 is prescribed ['hangboard_repeaters', 'max_hangs_20mm', 'no_hang_edge_lifts'] in BASE.a 6c 5x plan holds ['hangboard_density_hangs', 'self_resisted_finger_isometrics'] as its whole BASE finger content at gap 1.22 strength week(s) at 5x a week train anaerobic capacity with no aerobic capacity anywhere in the weekMAX_WALL_TURNS is 10, not 4·the phases whose wall ring is perfectly flat are (), not ('strength', 'taper')easy_climbing_flush is ruling 27's fill at 1200 s and spent 2 sets, not the 1 a 30-minute chunk impliesProse corrections, none of them catchable by any guard
A comment cited a
rest_secondscolumn CHECK that does not exist (prescription_templatecheckssets,intensity_pctandtarget_rpeonly — the one-second floor is ours); "these eleven rows" was fourteen; "BASE authors two HOLD rows" — it authors seven, two of them finger; andeasy_climbing_flush's user-facing copy said "ten unhurried minutes" while the row is expandable to 1200 s, so it now says "a few" — the same call PR #125 made forlead_endurance_pyramid. Two further false docstrings were corrected by the ranking work, and one test docstring claimed its shape arm "cannot become a hole for a padded authored block" when the rest-freeendurancerow reached it.🤖 Generated with Claude Code