pay-now pays back-dated periods the scheduler would skip #4

Open
opened 2026-08-31 21:21:59 +00:00 by padreug · 0 comments
Owner

The inconsistency

For a contract with backfill off and a start date in the past, the two settlement paths disagree about the same period:

  • the scheduler — _settle skips any period whose payday predates contract.created_at, recording it as skipped and consuming it. That guard exists so a new contract with a back-dated start (an anchoring choice — "we pay on the 15th") does not fire months of surprise back-pay on its first tick.
  • pay-now — pay_now calls pay_period directly and bypasses that check entirely, so it pays the same period.

The window is real but narrow: between creating the contract and the first tick that consumes those periods, roughly five minutes.

It is deliberate — pay_now's docstring argues an operator explicitly asking to pay is not the surprise the guard was built to prevent — but the result is that clicking a button inside that window produces a materially different outcome from waiting, with nothing saying so.

Options

  1. Make pay-now respect the skip. Consistent, but removes the only way to deliberately pay a back-dated period before the tick writes it off.
  2. Keep the behaviour, make it explicit. The pay-now dialog already names the payday; it could add "this payday predates the contract and backfill is off — the scheduler would skip it; paying now overrides that."
  3. Fold into #3. If a first-class "add a past payout" lands, pay-now no longer needs to be the escape hatch and option 1 becomes clean.

Leaning 2 short-term, 1 once #3 exists.

🤖 Generated with Claude Code

https://claude.ai/code/session_018jy52j9GRZ6XKa1Zt21LLj

## The inconsistency For a contract with `backfill` **off** and a start date in the past, the two settlement paths disagree about the same period: - **the scheduler** — `_settle` skips any period whose payday predates `contract.created_at`, recording it as `skipped` and consuming it. That guard exists so a new contract with a back-dated start (an *anchoring* choice — "we pay on the 15th") does not fire months of surprise back-pay on its first tick. - **pay-now** — `pay_now` calls `pay_period` directly and bypasses that check entirely, so it *pays* the same period. The window is real but narrow: between creating the contract and the first tick that consumes those periods, roughly five minutes. It is deliberate — `pay_now`'s docstring argues an operator explicitly asking to pay is not the surprise the guard was built to prevent — but the result is that clicking a button inside that window produces a materially different outcome from waiting, with nothing saying so. ## Options 1. **Make pay-now respect the skip.** Consistent, but removes the only way to deliberately pay a back-dated period before the tick writes it off. 2. **Keep the behaviour, make it explicit.** The pay-now dialog already names the payday; it could add "this payday predates the contract and backfill is off — the scheduler would skip it; paying now overrides that." 3. **Fold into #3.** If a first-class "add a past payout" lands, pay-now no longer needs to be the escape hatch and option 1 becomes clean. Leaning 2 short-term, 1 once #3 exists. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_018jy52j9GRZ6XKa1Zt21LLj
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
aiolabs/payroll#4
No description provided.