Let the fleet finish minutesAfterSunset after sunset, default 8
With limitBySunset, the slowest boat may be expected home up to
minutesAfterSunset after sunset: twilight outlasts it. The same allowance
caps the next race's target when a race's time adjustments become TCFs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gregw
committed
Oct 16, 2026
0da6f20
Bring the slowest boat home by sunset, and keep penalties whole under the cap
The sunset cap now limits the slowest boat's expected time, not the median
boat's: t_target_elapsed <= floor(daylight x TCF_min / TCF_med). Capping the
target itself let the fleet finish after sunset.
Time adjustments are converted against the next race's target after that
cap, so a five-minute penalty still starts the boat five minutes late on a
night sunset shortens.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gregw
committed
Oct 16, 2026
9159a80
Describe the four sign-in tiers
Anyone reads the races; anyone signed in also sees the boat register; a
race officer (club domain or named) runs a race night; an admin owns the
season.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q5SF9GPvxbBeU9qcHhjVCA
gregw
committed
Oct 6, 2026
772e806
Serve the duty boat, then DNS and RET, before the boats at home
After the racers have had their minute, what is left goes to the duty
boat (AVG), then to boats that did not start or retired (DNS, RET), each
capped at a minute, and only then evenly to the DNCs. Adds a worked
table for a thirty-boat fleet.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gregw
committed
Oct 5, 2026
20780e5
Use the committee's revised elevator pitch
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01USJqVVgZxkzFLmkD4kcpJ5
gregw
committed
Sep 29, 2026
e6ad25c
Give the penalties back a minute at a time
Top five pay 5, 4, 3, 2, 1; the minutes come back one per boat, DNFs first,
then the last boat home working forwards; leftovers are shared evenly by the
boats that stayed home. The TCF change is measured against the next race's
expected duration. The weighted giveback, its variants and knobs are retired.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01USJqVVgZxkzFLmkD4kcpJ5
gregw
committed
Sep 29, 2026
483d288
Giveback goes to the entry list, not to the starters
The pool of penalty minutes was shared among the boats that raced, which divided
a fixed pool by a varying fleet: what a boat gained went as 1/turnout. Five boats
of thirty out on a filthy night and the same fifteen minutes came straight back
to the five that had just been charged them, with the boat finishing last of five
collecting six against a one-minute penalty - a better handicap outcome than
winning, while the twenty-five at home did not move.
It now comes back to everybody entered, by weights counted in ordinary finishers:
a penalty place 0
any other finisher 1 + gamma * gap/maxGap
ran out of time (DNF) the last finisher's weight + (dnfWeight - 1)
never came (DNC) dncWeight * (stayed home / entered)
RET, DSQ, DNS, ABN 0, frozen
A non-starter's weight rises as the fleet empties, so a thin night sends most of
the pool out of the racing fleet - a de facto scaling of the penalties that never
has to appear on a start sheet as a fraction.
Retires dnfAllowance, which said the same thing as a distance and so depended on
how spread out the fleet was that night, and givebackFleet, which has no
well-defined meaning once the pool reaches boats with no finish gap. The default
variant moves B -> A: gamma = 1 existed to stop the winner drawing its own
penalty back, and weight zero on the penalty places does that directly.
Adds the ladder sizing rule (about one rung per six boats) and the case where
nobody may receive, which charges nothing rather than keeping the pool.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U2kYoSyx6LHgkkwEK1jEnt
gregw
committed
Sep 9, 2026
41c6e63
Fix the elevator pitch in §1
The penalty may be absolute or per hour of race duration, which the first bullet
did not say.
The second bullet still described the retired winner ramp — a share running from
half an even share down to zero as the race approached idealRaceLength, a knob
that no longer exists. It now describes givebackGamma, and notes that under the
default the winner draws nothing back because its gap from itself is zero.
gregw
committed
Aug 24, 2026
22bc355
The handicap button is called Process Results
Renamed on the race page; §5 described it by name.
gregw
committed
Aug 24, 2026
036f6da
Variant B is the default: fixed penalties, given back by finish gap
Marks B as the default in the knobs table and the parameter defaults, and
retitles 6.6 to "variant C" — that example is still C's arithmetic and stays
correct as an illustration of it.
Adds 6.7: the same fleet under B. The winner's gap is zero by definition so it
draws nothing back, and the penalty is the penaltyList entry rather than that
entry scaled by how long the night turned out to be.
7.3 argued that C should be the default because a race run twice as slowly gives
an identical correction. That argument is still true and still load-bearing
wherever perHour is selected, so it is retitled rather than dropped: exact
duration-independence is the one thing B knowingly gives up.
gregw
committed
Aug 23, 2026
2d821ad
Use finish delta rather than elapsed time for jinx give back
gregw
committed
Aug 23, 2026
b54f684
Spec 6.5: casuals are handicapped by a second pass
gregw
committed
Aug 21, 2026
6234bf2
Spec: variants as two knobs, measured raceDuration, and the giveback the code actually does
gregw
committed
Aug 21, 2026
fce3ffe
Retire V0: the TCF conversion is anchored to median(TCF x elapsed)
gregw
committed
Aug 21, 2026
19c2341
Storyboard: series are editable, and why a rename keeps the old id
gregw
committed
Aug 21, 2026
67263bb
Storyboard: the two locks, typed HH:MM, and what a dash in Spin means
gregw
committed
Aug 21, 2026
5efa720
Storyboard: column order, renamed filters, and the start-times lock
gregw
committed
Aug 21, 2026
3ac1ef4
Storyboard: the NOW log, the filter tick boxes, and the H:MM setup fields
gregw
committed
Aug 21, 2026
36035d8
Storyboard: entered boats are not suggested; the casual tick box
gregw
committed
Aug 21, 2026
7b33fdc
Process handicaps is one step; time boxes assist entry
gregw
committed
Aug 20, 2026
677ad20
Sunset caps the target, casuals do not seed, start sheet sorts
gregw
committed
Aug 20, 2026
ebba62a
Imports come from the sailing-pf handicap export
Two of them, because the file mixes identity with entry terms: the Boats
page reads identity only, and the race page reads the same file for TCFs
and spinnaker.
gregw
committed
Aug 20, 2026
238e4a0
Add-a-boat is three linked fields
Sail number, name and design each suggest from their own column; picking
one fills the others. Only the applicable button is offered once the
fields name a boat the register already has.
gregw
committed
Aug 19, 2026
9af4df3
Handicap, division and spinnaker belong to the entry
A boat does not have a TCF - it has one for a given series, and a
different one by the end of it. The same hull can sail one season in
Division 1 with a kite and the next in Division 2 without. The Boats page
holds identity only; the terms are set on the series roster.
gregw
committed
Aug 19, 2026
46f14e0
Document boat identity and the CSV import
sail-jinx now identifies boats the same way sailing-pf does, sharing the
alias seed, so the same hull gets the same id in both. Home.md explains
what that means in practice; the storyboard covers the Boats page's bulk
import, the per-row results, and why designs are learned rather than
entered.
gregw
committed
Aug 19, 2026
a7c13ef
Document the standalone architecture
sail-jinx 2.0 has no SailSys integration. Results reach SailSys by a
human reading a printed report and typing them in.
- Home: rewritten for the standalone app.
- Jinx-Handicaps 5.1: adds corrected_finish_time, the report column,
which gives back the head start from crossing early but deliberately
omits the 5-min OCS penalty - that is implied by the flag beside it and
applied on entry. Including it in both places would apply it twice.
- Jinx-Handicaps 5.2: places are computed locally; there is no external
system to defer to and no SailSys-authoritative mode.
- Jinx-Handicaps 8.1: each race's entrant list carries the TCF it was
sailed on, so that file IS the handicap history. The separate snapshot
file existed only because SailSys kept the latest value.
- Jinx-Handicaps 11: rewritten for the real implementation, including
where the algorithm lives (arithmetic in Java, 5.1 primitives in
static/scoring.js, shared by the race page and the finish report).
- Storyboard: rewritten as the actual race-night workflow.
- sailsys-api-reference: marked historical.
Flags an unresolved question in 6.3/6.4: the spec describes a
winner_factor and gap-anchored redistribution that PursuitHandicapEngine
does not implement - it weights by elapsed^gamma with no winner anchor,
for a reason argued in the code. The divergence predates this work and
needs a decision rather than a silent edit.
gregw
committed
Aug 18, 2026
cbbe539
Removed the calibration mechanism
gregw
committed
Jun 30, 2026
d987d01
Work in progress on handicap
Signed-off-by: Greg Wilkins <gregw@webtide.com>
gregw
committed
Jun 6, 2026
020ea3e