When the bank message for the recipient starts with other:, inference no longer tries to find a month. It copies the message into Purpose, so the payment is linked to the person as an "other" transaction and is not counted as a monthly fee.
Reconcile already treated a Purpose starting with other: this way; until now that only happened when someone typed the purpose by hand.
Behaviour
Trigger: the message, trimmed, starts with other: (case-insensitive). A message that contains other: later in the text is inferred the old way.
Purpose: the trimmed message, unchanged. No month parsing and no fallback to the payment date.
Person: inferred as before.
No person found: Purpose is still written and the row appears under unmatched for a manual fix.
Rows not yet processed by inference follow the same rule inside reconcile.
Existing rows are not re-inferred. To reprocess one, clear its Person and Purpose cells.
Implemented in both Go and legacy Python.
Also in this MR
fix(go): the junior cell tooltip showed Expected: 0 instead of Expected: ? when a month with an unknown expected fee had a payment. Found because it made make parity fail on /api/juniors with current data. No unit test added for this one; it is covered by the live parity check only.
Testing
make go-test-all and make test (44 Python tests) pass.
Four new parity fixtures (three for inference, one for the reconcile fallback); existing fixtures are unchanged.
Dry-run inference on the live sheet in both implementations proposes no changes.
Live parity between the two servers: 3/3 routes match.
Note on live data
The payments sheet has one row from 2026-10-08 whose message starts with other:. It was inferred before this change and is booked against 2026-10. It needs a manual correction (or clearing Person and Purpose so it is re-inferred).
## What
When the bank message for the recipient starts with `other:`, inference no longer tries to find a month. It copies the message into Purpose, so the payment is linked to the person as an "other" transaction and is not counted as a monthly fee.
Reconcile already treated a Purpose starting with `other:` this way; until now that only happened when someone typed the purpose by hand.
## Behaviour
- Trigger: the message, trimmed, starts with `other:` (case-insensitive). A message that contains `other:` later in the text is inferred the old way.
- Purpose: the trimmed message, unchanged. No month parsing and no fallback to the payment date.
- Person: inferred as before.
- No person found: Purpose is still written and the row appears under unmatched for a manual fix.
- Rows not yet processed by inference follow the same rule inside reconcile.
- Existing rows are not re-inferred. To reprocess one, clear its Person and Purpose cells.
Implemented in both Go and legacy Python.
## Also in this MR
- `fix(go)`: the junior cell tooltip showed `Expected: 0` instead of `Expected: ?` when a month with an unknown expected fee had a payment. Found because it made `make parity` fail on `/api/juniors` with current data. No unit test added for this one; it is covered by the live parity check only.
## Testing
- `make go-test-all` and `make test` (44 Python tests) pass.
- Four new parity fixtures (three for inference, one for the reconcile fallback); existing fixtures are unchanged.
- Dry-run inference on the live sheet in both implementations proposes no changes.
- Live parity between the two servers: 3/3 routes match.
## Note on live data
The payments sheet has one row from 2026-10-08 whose message starts with `other:`. It was inferred before this change and is booked against 2026-10. It needs a manual correction (or clearing Person and Purpose so it is re-inferred).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
A junior month with one session has an unknown expected fee. When such
a month had a payment, the Go tooltip printed "Expected: 0" where
Python prints "Expected: ?", which made make parity fail on
/api/juniors.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
When the bank message starts with "other:" (case-insensitive),
inference does not look for a month, neither in the text nor from the
payment date. The trimmed message is written to Purpose, so reconcile
books the payment as an "other" transaction for the person instead of
a monthly fee. Messages containing "other:" elsewhere are unchanged.
- matching.IsOtherPurpose / is_other_purpose shared by inference and
reconcile
- reconcile applies the rule to rows not yet processed by inference
- no person found: Purpose is still written, row shows as unmatched
- implemented in Go and legacy Python; four new parity fixtures
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kacerr
merged commit 7d55eca189 into main2026-10-08 12:40:29 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
What
When the bank message for the recipient starts with
other:, inference no longer tries to find a month. It copies the message into Purpose, so the payment is linked to the person as an "other" transaction and is not counted as a monthly fee.Reconcile already treated a Purpose starting with
other:this way; until now that only happened when someone typed the purpose by hand.Behaviour
other:(case-insensitive). A message that containsother:later in the text is inferred the old way.Implemented in both Go and legacy Python.
Also in this MR
fix(go): the junior cell tooltip showedExpected: 0instead ofExpected: ?when a month with an unknown expected fee had a payment. Found because it mademake parityfail on/api/juniorswith current data. No unit test added for this one; it is covered by the live parity check only.Testing
make go-test-allandmake test(44 Python tests) pass.Note on live data
The payments sheet has one row from 2026-10-08 whose message starts with
other:. It was inferred before this change and is booked against 2026-10. It needs a manual correction (or clearing Person and Purpose so it is re-inferred).🤖 Generated with Claude Code