• v0.1.0 e77f431d47

    padreug released this 2026-08-31 21:02:45 +00:00 | 0 commits to main since this release

    Found by tracing what happens when a back-dated backfill contract cannot
    fetch a historical rate. The failure handling itself was fine — period 0
    fails, the backlog halts so nothing settles out of order, five ledger rows
    record the reason, no money moves, and the contract auto-pauses once the
    retry budget is spent. The recovery was not.

    The operator fixes the cause (switches to a stated rate, or to current),
    clicks Resume, and periods_done jumps 0 -> 6: every unpaid payday silently
    written off, contract back to looking healthy, employee never paid. The
    confirm dialog even asserted the missed paydays "are written off" — true of
    one kind of pause and a lie about the other.

    Two features colliding. "Do not backfill a deliberate pause" is right when
    the operator paused: the pause was the decision not to pay. It is wrong
    when payroll paused, because nobody decided anything — the money is still
    owed and the operator has just removed whatever blocked it.

    Contracts now carry paused_reason, set only when payroll pauses them and
    cleared by a deliberate pause. Resume infers from it, and an explicit
    catch_up still overrides either way. The console asks a different question
    for each, quoting the reason, and flags a payroll-paused contract in the
    table so the distinction is visible before anyone clicks.

    Verified end to end: five failing ticks leave periods_done at 0 and pause
    with "period 0 (2026-08-01) failed 5 times: no historical EUR rate
    available for 2026-08-01"; resuming after switching to a manual rate keeps
    the position at 0, and the next tick settles all seven owed periods.

    Co-Authored-By: Claude Opus 5 noreply@anthropic.com
    Claude-Session: https://claude.ai/code/session_018jy52j9GRZ6XKa1Zt21LLj

    Downloads