Dispositions for per-line tax codes: the three design rounds and the build
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
1 file changed,
+40
−0
docs/superpowers/specs/DISPOSITIONS-per-line-tax-codes.md+40 −0
CI passed — run details
diff --git a/docs/superpowers/specs/DISPOSITIONS-per-line-tax-codes.md b/docs/superpowers/specs/DISPOSITIONS-per-line-tax-codes.md| new file mode 100644 |
| index 000000000..b9fef7b99 |
| --- /dev/null |
| +++ b/docs/superpowers/specs/DISPOSITIONS-per-line-tax-codes.md |
| @@ -0,0 +1,40 @@ |
| +# Dispositions: per-line tax codes |
| + |
| +Branch `design-per-line-tax-codes`, off the launch branch at `29ea6676`. Design `2026-10-03-per-line-tax-codes-design.md` (revision 4), plan `../plans/2026-10-03-per-line-tax-codes-plan.md`. Reports are in the run directory's logs (`astra-taxcodes-design-review{1,2,3}.md`) and, from the first code review on, in this directory. |
| + |
| +## Design review one (revision 1; Astra: reject, two P1, four P2, one P3) |
| + |
| +| Finding | Disposition | |
| +| --- | --- | |
| +| P1: the invoice engine keys a line's operation, recovery and draft validation by meter alone; two lines of one meter cannot pass. | A two-code line's kind is `line-<meter>-<code>`, its request carries `metadata[tax_code]`, and the POST answer, the recovery match and the draft validation require it (revision 2; built in Task 2, tested in Task 4). | |
| +| P1: a month already held cannot resume by itself. | No automatic resolution; the operator door resolves the review, with the pass's conditions stated (16d). | |
| +| P2: an older worker files a durable account-wide review. | The roll rule: older invoice workers stopped before activation, no rollback past it; the older reader's behaviour tested (Task 4). | |
| +| P2: the whole-paid-day eligibility rule must come before attribution. | Eligibility first, as today; attribution against unmerged half-open spans; a fully covered month takes the whole month as its interval (Task 3). | |
| +| P2: midnight attribution, gross-usage weighting and the no-paid-plan month end are policy. | 16a to 16d in `DECISIONS-FOR-PAUL.md`; the design chooses none; the bodies exist behind the hold. | |
| +| P2: the apportionment was imprecise (five meters to four axes, rounding, ties, aggregation, zero weights). | Stated exactly and built: per (code, meter) sums in date order, one floor each, transfer added per code; floor and largest remainder within the axis, byte-order ties, zero shares omitted, an amount with no weight an error (Task 3). | |
| +| P3: a zero-usage statement has no `Days`. | Kept as today: usable when every billed meter is zero, a hold otherwise. | |
| + |
| +## Design review two (revision 2; Astra: accept with fixes, three P2, two P3) |
| + |
| +| Finding | Disposition | |
| +| --- | --- | |
| +| P2: a universal daily-data requirement would regress one-code months. | `Days` are read where they are today and, new, only for a two-code whole month under the split answer; a fixture of a fully covered month with usage and no `Days` is pinned (Task 0). | |
| +| P2: the line identity was not checked on the POST answer and the draft. | Both check `metadata[tax_code]` (Task 2); corruption on each path tested (Task 4); mutants M8 and M10 die. | |
| +| P2: two readings of the transfer arithmetic. | Floor each meter, then add, per code (Task 3); the fractional-boundary test; mutant M16 dies. | |
| +| P3: 16a to 16d and the roll rule not yet written. | 16a to 16d are on the launch branch (`27419dcf`); the roll rule is Task 5 at the merge. | |
| +| P3: "the next pass" promised without its conditions. | Stated in 16d: no other open review, the backoff, the twelve-month lookback. | |
| + |
| +## Design review three (revision 3, confirming; Astra: accept with fixes, one P2) |
| + |
| +| Finding | Disposition | |
| +| --- | --- | |
| +| P2: the month-end answer's daily-data exemption contradicted partial-month pricing. | Revision 4: the month-end answer adds no requirement of its own; partly covered months keep today's under either answer. | |
| +| The waiver sentence and the older worker's nonterminal records. | Qualified in revision 4. | |
| + |
| +Revision 4's corrections were not sent for a fourth design round; the first code review reads the design with the code. |
| + |
| +## The build |
| + |
| +Tasks 0 to 4 and the mutants of Task 6 are committed; Task 5 (the records on the launch branch) comes at the merge. `wellFormed` kept its money shape and the tax shape is `taxShapeOK`, asked beside it at the entry guard, as the second review's note on "`wellFormed` alone" asked; the design's "gains the tax shape" is met by the guard, not by one function. Mutants: twenty-three in a git-less tree copy, each with its killing tests logged (`taxcodes-mutants-round1.txt`); twenty-two die, M14 is equivalent (reasoned in the log). Every one-code month's bytes, digest, request hashes and operation kinds are the ones pinned in Task 0 from the unchanged code. |
| + |
| +What a reader of the invoice should know: a two-code month does not exist until decision 16 is taken and `taxCodesForLines` is switched, after the roll rule; nothing on this branch changes a one-code month, an amount, the floor, or the price book. |