aboutsummaryrefslogtreecommitdiff
path: root/CLAUDE.md
diff options
context:
space:
mode:
Diffstat (limited to 'CLAUDE.md')
-rw-r--r--CLAUDE.md76
1 files changed, 76 insertions, 0 deletions
diff --git a/CLAUDE.md b/CLAUDE.md
index f4f6b7b..5047e93 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -881,6 +881,82 @@ original, distinct architectural reason.
dedicated unit test alone. Full account:
`.superpowers/sdd/2026-08-12-colitur-rg16a/bvm-saturday-report.md`.
+10. **OF W1 — Normae n. 56(f), St Joseph anticipated onto Palm Sunday —
+ RESOLVED (`of-normae-56f`, 2026-08-26), and the kernel contract change
+ it forced.** `Rite.t.transfer_target`'s own obligation used to require
+ the result be **strictly later** than the impeded date, justified
+ purely from the EF's RG 96 (rite.mli's own comment cited it, "the same
+ class of item CLAUDE.md tracks under 'EF-shaped things still in
+ rite-agnostic kernel code'" — item 8 above). This is the FIFTH
+ EF-shaped kernel misfit found while building OF (after `Preface.t`,
+ `Mass_formulary.source`, `transfer_target`'s own strictly-later
+ contract, and `citation_shapes`) and the SECOND fixed rather than only
+ documented — `citation_shapes` was the first.
+
+ **The rule that forced it**: *"Sollemnitas S. Ioseph, ubi est de
+ praecepto servanda, si cum Dominica in palmis de Passione Domini
+ occurrit, anticipatur sabbato praecedenti, die 18 martii"* — St Joseph
+ impeded by Palm Sunday is ANTICIPATED BACKWARD to the preceding
+ Saturday, the one clause in the whole Tabula/Normae transfer machinery
+ that names an earlier date, not a later one. Live in 16 of 1583–2100
+ (1595, 1606, 1617, 1690, 1758, 1769, 1780, 1815, 1826, 1837, 1967,
+ 1978, 1989, 2062, 2073, 2084) — colitur previously sent Joseph forward
+ to Easter+9 instead (past the Annunciation's own Easter+8, since both
+ solemnities were impeded that year and collided on the same forward
+ target).
+
+ **The alternative rejected**: leaving it documented-but-unimplemented
+ indefinitely, precedence_of.mli's own status quo before this task. No
+ rite-local workaround exists instead — `Calendar.place_transfers` is
+ the only channel that ever places a transferred candidate, so a rule
+ the kernel contract forbids from returning cannot be smuggled in
+ beside it.
+
+ **What it actually costs**: traced against `Calendar`'s real placement
+ pass (calendar.ml's `place_transfers`/`year`), not assumed unsafe by
+ inheritance from the EF-only citation that wrote the original text.
+ The round loop re-resolves the WHOLE year fresh every round from the
+ currently-settled assignment, and its two safety nets — the
+ `~start`/`~stop` domain bound and `max_transfer_rounds`'s round-count
+ guard — both test the target's own value with no comparison against
+ `origin` anywhere, so a bounded backward jump converges exactly the
+ way a bounded forward one does, and "resurrecting a superseded
+ occupant" cannot occur (a day's occupant is decided fresh each round
+ by the same contest every other day is). The ONE requirement that
+ really is load-bearing: `target <> origin`, not merely `target >
+ origin` — `Precedence.resolve` never deduplicates by slug, so a
+ candidate returning its own argument unchanged would be handed to the
+ RG 91/Tabula contest twice in the same round, a genuine self-collision
+ (disposed of as both `winner` and `loser` against itself), not a
+ docstring worry. The relaxed obligation is `Rite.t.transfer_target`'s
+ new text (rite.mli); it does NOT license an unbounded backward
+ SEARCH as safe merely because a bounded one is proven so — the
+ termination obligation still falls entirely on the rite, exactly as it
+ always did for a forward search, and the only shape actually verified
+ is a CONSTANT one-shot displacement for a specifically-named collision
+ (`Precedence_of.transfer_target`'s own Rule 0, `Date.add_days origin
+ (-1)`, no internal search at all). `calendar.ml` itself needed NO
+ logic change — only two comments correcting a blanket "every genuine
+ transfer moves forward" claim that the trace showed no longer holds
+ literally.
+
+ **Blast radius, measured**: EF untouched — `git diff --stat
+ v1.0.0..HEAD -- data/ef/` and `lib/rites/rite_ef/` both empty (the
+ field's TYPE is unchanged, only its doc comment; no new required
+ field), and `colitur day`/`colitur readings` for 2026, 1583 and 9999
+ are byte-`cmp`-identical between this change and a `git worktree`
+ build of the commit immediately before it. OF's own 2005–2050
+ differential-testing window (CLAUDE.md's own oracle range) carries
+ zero of the 16 affected years, and a full sweep of it shows zero
+ unexpected diffs either. Each affected year's own diff is exactly two
+ lines (18 March gains Joseph; whichever memorial or feria previously
+ occupied the old, wrong Easter+9 target resurfaces there instead) —
+ confirmed on 2062 by direct `cmp` against the pre-fix binary. The
+ whole domain's transfer placement still reaches a fixed point:
+ `Validate.run`'s "unconverged" check stayed clean across the full
+ 1583–9999 exhaustive sweep (`COLITUR_EXHAUSTIVE_SWEEP=1 dune test
+ --force`, part of `make check`).
+
## How to work here
- **Superpowers workflow**: `brainstorming` → `writing-plans` → `executing-plans`