P3: odd cents split the same running way everywhere (defect 17, D-38)
check / check (push) Canceled after 0s

Members' shares of earnings are split cumulatively by largest remainder in
the closes, the members' equity statement, the K-1 worksheet and the
viewer, so a member's capital on a given day never moves by a cent when its
month is later closed. Old closes replay as they were; the first P3 close
carries any true-up. Feature members_cumulative. Kani and Lean proofs of
the bounded drift; bookspec examples.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T3gXMVt7XJPi6ens1or9Dj
This commit is contained in:
swaitsandClaude Opus 5.5 committed 2026-10-20 21:35:00 -06:00
1 parent 2390dc6553
commit a7f3cc09a9
44 files changed
+6636 -195

No files matched your search

@@ -0,0 +1,129 @@
id = "members-close.odd-cent-across-closes"
title = "An odd cent split cumulatively across closes, a close to retained earnings between"
rule = "Each close to the members MUST give each member their largest-remainder split of everything closed to the same members and shares so far, to the minor unit, less what earlier closes gave them; a close to retained earnings allocates nothing to the members and MUST NOT restart the count."
status = "CHOICE"
sources = ["26 U.S.C. §704(a)", "Treas. Reg. §1.704-1(b)(2)(iv)(b)"]
tags = ["partnership", "close", "rounding", "book", "us"]
# The regression this example comes from (wanderbooks P3 defect 17, audit
# F52, anonymized): a net loss of 399.23 at 50/50, closed in January and
# again in March, with February closed to retained earnings. Restarting the
# count at March gave A the tied cent twice (A −399.24, B −399.22).
#
# By hand, from the rule:
# January: −399.23 × 0.5 = −199.615 each; rounded toward zero, −199.61
# each, one cent short; the remainders tie (0.005), so the cent goes to
# the member listed first: A −199.62, B −199.61.
# February: 10.00 to retained earnings; the members' count skips it.
# March: the count's running total is −798.46, −399.23 each exactly;
# less January's −199.62 / −199.61, March gives A −199.61, B −199.62.
# Each member ends at −399.23, their exact share.
[setup]
currency = "USD"
fiscal_year_start = "01-01"
basis = "accrual"
rounding = "largest-remainder" # odd cents to the largest remainders, ties
# to the member listed first, cumulatively
[[setup.accounts]]
code = "1000"
name = "Cash"
type = "asset"
[[setup.accounts]]
code = "3000"
name = "Capital, A"
type = "equity"
[[setup.accounts]]
code = "3001"
name = "Capital, B"
type = "equity"
[[setup.accounts]]
code = "3999"
name = "Retained earnings"
type = "equity"
[[setup.accounts]]
code = "6000"
name = "Fees"
type = "expense"
[[setup.members]]
name = "A"
capital_account = "3000"
share = "0.5"
[[setup.members]]
name = "B"
capital_account = "3001"
share = "0.5"
[[events]] # event 1
date = "2026-01-15"
description = "January's fees"
lines = [
{ account = "6000", side = "debit", amount = "399.23" },
{ account = "1000", side = "credit", amount = "399.23" },
]
[[events]] # event 2: the closing entry
date = "2026-01-31"
description = "Close January to the members"
close = { start = "2026-01-01", to = "members" }
[[events]] # event 3
date = "2026-02-15"
description = "February's fees"
lines = [
{ account = "6000", side = "debit", amount = "10.00" },
{ account = "1000", side = "credit", amount = "10.00" },
]
[[events]] # event 4
date = "2026-02-28"
description = "Close February to retained earnings"
close = { start = "2026-02-01", to = "retained_earnings" }
[[events]] # event 5
date = "2026-03-15"
description = "March's fees"
lines = [
{ account = "6000", side = "debit", amount = "399.23" },
{ account = "1000", side = "credit", amount = "399.23" },
]
[[events]] # event 6
date = "2026-03-31"
description = "Close March to the members"
close = { start = "2026-03-01", to = "members" }
[[expect]]
query = "entry"
entry = 2
[expect.values]
"6000.credit" = "399.23"
"3000.debit" = "199.62"
"3001.debit" = "199.61"
[[expect]]
query = "entry"
entry = 6
[expect.values]
"6000.credit" = "399.23"
"3000.debit" = "199.61"
"3001.debit" = "199.62"
[[expect]]
query = "balances"
as_of = "2026-03-31"
[expect.values]
"3000" = "-399.23"
"3001" = "-399.23"
"3999" = "-10.00"
"1000" = "-808.46"
@@ -0,0 +1,113 @@
id = "members-close.statement-before-and-after-a-close"
title = "A member's capital on a day is the same before and after its month closes"
rule = "The statement of members' equity MUST split earnings not yet closed the way the next close to the members will (each member's split of everything closed plus those earnings, less their split of what was closed), so a member's capital as of a day MUST NOT change when a period ending on or before it is closed."
status = "CHOICE"
sources = ["Treas. Reg. §1.704-1(b)(2)(iv)(b)"]
tags = ["partnership", "close", "rounding", "statement", "book", "us"]
# Two members at 50/50; January's cent is closed to them, February's is
# earned but not yet closed (event 3), then closed (event 4).
#
# By hand, from the rule:
# January's close: 0.01 is 0.005 each; the tied cent to A (listed first):
# A 0.01, B 0.00.
# As of Feb 28, February not yet closed: closed 0.01, unclosed 0.01. The
# split of everything, 0.02, is 0.01 / 0.01; of the closed part, 0.01 /
# 0.00; so the unclosed cent is B's: A 0.01 + 0.00, B 0.00 + 0.01.
# (Splitting February's cent on its own would give it to A: A 0.02,
# B 0.00, and the close would then move it to B.)
# February's close gives the running 0.02, 0.01 each, less 0.01 / 0.00:
# B 0.01. As of Feb 28: A 0.01, B 0.01, as before the close.
[setup]
currency = "USD"
fiscal_year_start = "01-01"
basis = "accrual"
rounding = "largest-remainder"
[[setup.accounts]]
code = "1000"
name = "Cash"
type = "asset"
[[setup.accounts]]
code = "3000"
name = "Capital, A"
type = "equity"
[[setup.accounts]]
code = "3001"
name = "Capital, B"
type = "equity"
[[setup.accounts]]
code = "4000"
name = "Sales"
type = "revenue"
[[setup.members]]
name = "A"
capital_account = "3000"
share = "0.5"
[[setup.members]]
name = "B"
capital_account = "3001"
share = "0.5"
[[events]] # event 1
date = "2026-01-10"
description = "January's sale"
lines = [
{ account = "1000", side = "debit", amount = "0.01" },
{ account = "4000", side = "credit", amount = "0.01" },
]
[[events]] # event 2
date = "2026-01-31"
description = "Close January to the members"
close = { start = "2026-01-01", to = "members" }
[[events]] # event 3
date = "2026-02-10"
description = "February's sale"
lines = [
{ account = "1000", side = "debit", amount = "0.01" },
{ account = "4000", side = "credit", amount = "0.01" },
]
[[events]] # event 4
date = "2026-02-28"
description = "Close February to the members"
close = { start = "2026-02-01", to = "members" }
[[expect]]
query = "members_equity"
from = "2026-01-01"
to = "2026-02-28"
after = 3 # the books before February's close
[expect.values]
"A.ending" = "0.01"
"B.ending" = "0.01"
"A.net_income" = "0.01"
"B.net_income" = "0.01"
[[expect]]
query = "members_equity"
from = "2026-01-01"
to = "2026-02-28" # after every event: February closed
[expect.values]
"A.ending" = "0.01"
"B.ending" = "0.01"
"A.net_income" = "0.01"
"B.net_income" = "0.01"
[[expect]]
query = "entry"
entry = 4
[expect.values]
"4000.debit" = "0.01"
"3001.credit" = "0.01"
@@ -0,0 +1,288 @@
id = "members-close.thirds-over-twelve-months"
title = "Three members at a third each, twelve monthly closes"
rule = "Each monthly close to the members MUST give each member their largest-remainder split of everything closed so far, to the minor unit, less what earlier closes gave them, so after every close each member's total is less than one minor unit from their exact share."
status = "CHOICE"
sources = ["26 U.S.C. §704(a)", "Treas. Reg. §1.704-1(b)(2)(iv)(b)"]
tags = ["partnership", "close", "rounding", "book", "us"]
# A third each can't be written as decimal shares summing to one, so the
# members hold 33.33%, 33.33% and 33.34%. Twelve months, each closed to
# them: 100.00, 0.01, 0.02, 33.33, -0.05, 0.10, 1.00, 0.07, 0.01, 12.34,
# -5.00, 0.02 (141.85 in all).
#
# By hand, from the rule (the running total, its exact shares, the floors
# to the cent, then the left-over cents to the largest remainders):
# January, 100.00: 33.33 / 33.33 / 33.34 exactly.
# February, running 100.01: 33.333333 / 33.333333 / 33.343334; floors
# 33.33 / 33.33 / 33.34 leave a cent for the largest remainder, C's
# .003334: 33.33 / 33.33 / 33.35, so February gives C 0.01.
# March, running 100.03: 33.339999 / 33.339999 / 33.350002; floors 33.33
# / 33.33 / 33.35 leave two cents for A's and B's .009999: 33.34 /
# 33.34 / 33.35, so March gives A 0.01 and B 0.01.
# November, running 141.83: 47.271939 / 47.271939 / 47.286122; floors
# 47.27 / 47.27 / 47.28 leave a cent for C's .006122: 47.27 / 47.27 /
# 47.29.
# December, running 141.85: 47.278605 / 47.278605 / 47.29279; floors
# 47.27 / 47.27 / 47.29 leave two cents for A's and B's .008605: 47.28
# / 47.28 / 47.29, so December gives A 0.01 and B 0.01.
[setup]
currency = "USD"
fiscal_year_start = "01-01"
basis = "accrual"
rounding = "largest-remainder"
[[setup.accounts]]
code = "1000"
name = "Cash"
type = "asset"
[[setup.accounts]]
code = "3000"
name = "Capital, A"
type = "equity"
[[setup.accounts]]
code = "3001"
name = "Capital, B"
type = "equity"
[[setup.accounts]]
code = "3002"
name = "Capital, C"
type = "equity"
[[setup.accounts]]
code = "4000"
name = "Sales"
type = "revenue"
[[setup.accounts]]
code = "6000"
name = "Fees"
type = "expense"
[[setup.members]]
name = "A"
capital_account = "3000"
share = "0.3333"
[[setup.members]]
name = "B"
capital_account = "3001"
share = "0.3333"
[[setup.members]]
name = "C"
capital_account = "3002"
share = "0.3334"
[[events]] # event 1
date = "2026-01-10"
description = "January's sales"
lines = [
{ account = "1000", side = "debit", amount = "100.00" },
{ account = "4000", side = "credit", amount = "100.00" },
]
[[events]] # event 2
date = "2026-01-31"
description = "Close January to the members"
close = { start = "2026-01-01", to = "members" }
[[events]] # event 3
date = "2026-02-10"
description = "February's sales"
lines = [
{ account = "1000", side = "debit", amount = "0.01" },
{ account = "4000", side = "credit", amount = "0.01" },
]
[[events]] # event 4
date = "2026-02-28"
description = "Close February to the members"
close = { start = "2026-02-01", to = "members" }
[[events]] # event 5
date = "2026-03-10"
description = "March's sales"
lines = [
{ account = "1000", side = "debit", amount = "0.02" },
{ account = "4000", side = "credit", amount = "0.02" },
]
[[events]] # event 6
date = "2026-03-31"
description = "Close March to the members"
close = { start = "2026-03-01", to = "members" }
[[events]] # event 7
date = "2026-04-10"
description = "April's sales"
lines = [
{ account = "1000", side = "debit", amount = "33.33" },
{ account = "4000", side = "credit", amount = "33.33" },
]
[[events]] # event 8
date = "2026-04-30"
description = "Close April to the members"
close = { start = "2026-04-01", to = "members" }
[[events]] # event 9
date = "2026-05-10"
description = "May's fees"
lines = [
{ account = "6000", side = "debit", amount = "0.05" },
{ account = "1000", side = "credit", amount = "0.05" },
]
[[events]] # event 10
date = "2026-05-31"
description = "Close May to the members"
close = { start = "2026-05-01", to = "members" }
[[events]] # event 11
date = "2026-06-10"
description = "June's sales"
lines = [
{ account = "1000", side = "debit", amount = "0.10" },
{ account = "4000", side = "credit", amount = "0.10" },
]
[[events]] # event 12
date = "2026-06-30"
description = "Close June to the members"
close = { start = "2026-06-01", to = "members" }
[[events]] # event 13
date = "2026-07-10"
description = "July's sales"
lines = [
{ account = "1000", side = "debit", amount = "1.00" },
{ account = "4000", side = "credit", amount = "1.00" },
]
[[events]] # event 14
date = "2026-07-31"
description = "Close July to the members"
close = { start = "2026-07-01", to = "members" }
[[events]] # event 15
date = "2026-08-10"
description = "August's sales"
lines = [
{ account = "1000", side = "debit", amount = "0.07" },
{ account = "4000", side = "credit", amount = "0.07" },
]
[[events]] # event 16
date = "2026-08-31"
description = "Close August to the members"
close = { start = "2026-08-01", to = "members" }
[[events]] # event 17
date = "2026-09-10"
description = "September's sales"
lines = [
{ account = "1000", side = "debit", amount = "0.01" },
{ account = "4000", side = "credit", amount = "0.01" },
]
[[events]] # event 18
date = "2026-09-30"
description = "Close September to the members"
close = { start = "2026-09-01", to = "members" }
[[events]] # event 19
date = "2026-10-10"
description = "October's sales"
lines = [
{ account = "1000", side = "debit", amount = "12.34" },
{ account = "4000", side = "credit", amount = "12.34" },
]
[[events]] # event 20
date = "2026-10-31"
description = "Close October to the members"
close = { start = "2026-10-01", to = "members" }
[[events]] # event 21
date = "2026-11-10"
description = "November's fees"
lines = [
{ account = "6000", side = "debit", amount = "5.00" },
{ account = "1000", side = "credit", amount = "5.00" },
]
[[events]] # event 22
date = "2026-11-30"
description = "Close November to the members"
close = { start = "2026-11-01", to = "members" }
[[events]] # event 23
date = "2026-12-10"
description = "December's sales"
lines = [
{ account = "1000", side = "debit", amount = "0.02" },
{ account = "4000", side = "credit", amount = "0.02" },
]
[[events]] # event 24
date = "2026-12-31"
description = "Close December to the members"
close = { start = "2026-12-01", to = "members" }
[[expect]]
query = "entry"
entry = 2
[expect.values]
"4000.debit" = "100.00"
"3000.credit" = "33.33"
"3001.credit" = "33.33"
"3002.credit" = "33.34"
[[expect]]
query = "entry"
entry = 4
[expect.values]
"4000.debit" = "0.01"
"3002.credit" = "0.01"
[[expect]]
query = "entry"
entry = 6
[expect.values]
"4000.debit" = "0.02"
"3000.credit" = "0.01"
"3001.credit" = "0.01"
[[expect]]
query = "entry"
entry = 24
[expect.values]
"4000.debit" = "0.02"
"3000.credit" = "0.01"
"3001.credit" = "0.01"
[[expect]]
query = "balances"
as_of = "2026-11-30"
[expect.values]
"3000" = "47.27"
"3001" = "47.27"
"3002" = "47.29"
[[expect]]
query = "balances"
as_of = "2026-12-31"
[expect.values]
"3000" = "47.28"
"3001" = "47.28"
"3002" = "47.29"
@@ -0,0 +1,157 @@
id = "members-close.true-up-of-a-per-close-split"
title = "Closes rounded one at a time, trued up by the first cumulative close"
rule = "When earlier closes split each close's net on its own, the first cumulative close that posts an entry MUST give each member their split of everything closed to the members, less what the earlier closes gave them, so it trues up the rounding they left; until it posts, the statement of members' equity MUST show the capital those closes posted, not the pending true-up."
status = "CHOICE"
sources = ["Treas. Reg. §1.704-1(b)(2)(iv)(b)"]
tags = ["partnership", "close", "rounding", "statement", "book", "us"]
# Books migrated from an engine that rounded each close on its own: three
# months of one cent at 50/50, each tie to A. April's cent is closed by the
# cumulative rule, counting from the first close.
#
# By hand, from the rule:
# January to March, each close on its own: 0.005 each, the tie to A, so
# A 0.03, B 0.00 (exact: 0.015 each).
# As of Apr 30, April's cent not yet closed: the split of everything,
# 0.04, is 0.02 / 0.02; of the closed 0.03, 0.02 / 0.01 (the tie to
# A); the unclosed cent is B's (0.02 − 0.01): A 0.03, B 0.01. The
# rounding the earlier closes left (A 0.01 ahead) shows only once
# posted.
# April's close: the running 0.04 is 0.02 / 0.02, less what was given
# (0.03 / 0.00): A −0.01, B +0.02. The entry: Dr 4000 0.01, Dr 3000
# 0.01, Cr 3001 0.02. As of Apr 30: A 0.02, B 0.02, each exact; as of
# Mar 31, still A 0.03, B 0.00.
[setup]
currency = "USD"
fiscal_year_start = "01-01"
basis = "accrual"
rounding = "largest-remainder"
[[setup.accounts]]
code = "1000"
name = "Cash"
type = "asset"
[[setup.accounts]]
code = "3000"
name = "Capital, A"
type = "equity"
[[setup.accounts]]
code = "3001"
name = "Capital, B"
type = "equity"
[[setup.accounts]]
code = "4000"
name = "Sales"
type = "revenue"
[[setup.members]]
name = "A"
capital_account = "3000"
share = "0.5"
[[setup.members]]
name = "B"
capital_account = "3001"
share = "0.5"
[[events]] # event 1
date = "2026-01-10"
description = "January's sale"
lines = [
{ account = "1000", side = "debit", amount = "0.01" },
{ account = "4000", side = "credit", amount = "0.01" },
]
[[events]] # event 2
date = "2026-01-31"
description = "Close January, rounded on its own"
close = { start = "2026-01-01", to = "members", rounding = "per-close" }
[[events]] # event 3
date = "2026-02-10"
description = "February's sale"
lines = [
{ account = "1000", side = "debit", amount = "0.01" },
{ account = "4000", side = "credit", amount = "0.01" },
]
[[events]] # event 4
date = "2026-02-28"
description = "Close February, rounded on its own"
close = { start = "2026-02-01", to = "members", rounding = "per-close" }
[[events]] # event 5
date = "2026-03-10"
description = "March's sale"
lines = [
{ account = "1000", side = "debit", amount = "0.01" },
{ account = "4000", side = "credit", amount = "0.01" },
]
[[events]] # event 6
date = "2026-03-31"
description = "Close March, rounded on its own"
close = { start = "2026-03-01", to = "members", rounding = "per-close" }
[[events]] # event 7
date = "2026-04-10"
description = "April's sale"
lines = [
{ account = "1000", side = "debit", amount = "0.01" },
{ account = "4000", side = "credit", amount = "0.01" },
]
[[events]] # event 8
date = "2026-04-30"
description = "Close April, cumulatively"
close = { start = "2026-04-01", to = "members" }
[[expect]]
query = "balances"
as_of = "2026-03-31"
after = 6
[expect.values]
"3000" = "0.03"
"3001" = "0.00"
[[expect]]
query = "members_equity"
from = "2026-01-01"
to = "2026-04-30"
after = 7
[expect.values]
"A.ending" = "0.03"
"B.ending" = "0.01"
[[expect]]
query = "entry"
entry = 8
[expect.values]
"4000.debit" = "0.01"
"3000.debit" = "0.01"
"3001.credit" = "0.02"
[[expect]]
query = "members_equity"
from = "2026-01-01"
to = "2026-04-30"
[expect.values]
"A.ending" = "0.02"
"B.ending" = "0.02"
[[expect]]
query = "members_equity"
from = "2026-01-01"
to = "2026-03-31"
[expect.values]
"A.ending" = "0.03"
"B.ending" = "0.00"