RealmPath
untyped stringRealmPath is this realm's own path, used to build Render links.
Value
"/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/payslips"
PayrollPath
untyped stringPayrollPath is the wage source every figure here is read from. It is taken BY VALUE from that realm's own exported constant rather than typed out again, so this is the compile-time pin itself and not a second copy that could drift. The convention is r/receivables' InvoicesPath.
Value
"/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/payroll"
RateScale
int64RateScale is the unit of a withholding rate, re-exported by value from [p/tiers](/p/tiers): a rate of 2500 is 25%. Re-exported because every rate in this realm's API is in these units and a caller should not have to find the other package to learn the denominator.
Value
10000
MaxTiers
untyped bigintMaxTiers is the widest schedule [p/tiers](/p/tiers) will build, by value. A schedule has one rate per tier and one edge between each adjacent pair, so an employer may name at most MaxTiers rates and MaxTiers-1 edges.
Value
(16 <untyped> bigint)
PlatformFeeBps
int64PlatformFeeBps is the accrual fee r/payroll charges, taken by value from that realm's own constant. Taking it by value is sound here for a reason worth stating rather than assuming: payroll is LIVE and a realm's bytes are immutable after addpkg, so that constant cannot change for the payroll this realm imports. A future payroll version would be a different path and a different import.
Value
100
MaxEmployeesPerCall
untyped bigintMaxEmployeesPerCall caps how many employees one [Publish](#Publish) may name, and it is r/payroll's own per-employer roster cap taken by value. That is the right bound and not an arbitrary one: payroll refuses a Hire past MaxRoster open positions, so an employer cannot have more than MaxRoster employees to report on, and a cap above it would admit a call that must contain a duplicate or an absent position. A cap below it would make some rosters unreportable in one call, which is the under-report this realm exists to avoid.
Value
(64 <untyped> bigint)
PayslipsAreUncapped
untyped boolPayslipsAreUncapped records a decision by its absence: there is no limit on how many payslips one employer may publish. Each one is a fresh record and the storage deposit for it is paid by the caller at publish time, so the chain already prices the only resource at stake. A cap here would cause the one failure this realm cannot tolerate — an employer unable to publish the statement that would have disclosed an omission.
Value
true
RenderPayslipLimit
untyped bigintRenderPayslipLimit is how many payslips an employer's Render page lists. Not a storage cap — see [PayslipsAreUncapped](#PayslipsAreUncapped).
Value
(20 <untyped> bigint)
line
typeline is one employee's statement within a payslip. Every field is derived from r/payroll's views at the payslip's own height; none is supplied by the caller.
Value
payslips.line
payslip
typepayslip is one published statement. Its totals are stored rather than recomputed so a reader gets the numbers as published, not as re-derived under a later schedule.
Value
payslips.payslip
payslips
*v0.Tree// "\<employer>|\<padded seq>" -> \*payslip
- OID
- 0f4c53…775d:4
payslips details
schedules
*v0.Tree// employer string -> tiers.Schedule
- OID
- 0f4c53…775d:7
schedules details
counts
*v0.Tree// employer string -> int
- OID
- 0f4c53…775d:10
counts details
slipCount
intValue
3
platformFee
tiers.Schedule- OID
- 0f4c53…775d:14
platformFee details
mustFlat
func(bps int64) tiers.Schedule- OID
- 0f4c53…775d:17
mustFlat details
refuseCoins
func()refuseCoins aborts when a direct EOA MsgCall attaches coins to an entrypoint here. This realm has no custody and no withdrawal path, so a send would be unrecoverable by anyone — including the sender. The IsCurrent() check is not decoration. Every call site forwards a crossing entrypoint's own live cur, so it cannot fire today; it exists so a future refactor that hands this helper a stale realm value fails closed instead of trusting it. That shape is security.md's Class 2 and it has been found in this portfolio's own realms more than once.
- OID
- 0f4c53…775d:19
refuseCoins details
SetSchedule
func(edges string, rates string) intSetSchedule installs the caller's own withholding schedule and returns its tier count. edges and rates are comma-separated int64 lists in [p/tiers](/p/tiers)'s units: rates are of [RateScale](#RateScale), edges are gross amounts in ugnot. There is one more rate than there are edges, because the last tier is unbounded. An EMPTY edges string is legal and means a one-tier schedule — a flat rate — which is the shape to use for a flat withholding and the shape this realm uses internally for the platform fee. SetSchedule(cross(cur), "1000000,5000000", "500,1500,2500") is 5% on the first 1,000,000 ugnot of gross, 15% on the next 4,000,000, and 25% above 5,000,000. REPLACING A SCHEDULE DOES NOT RE-PRICE ANYTHING. Every published payslip carries the schedule that priced it, so this only affects payslips published after it. That is a design requirement rather than a convenience: a published statement whose numbers change under it is not a record. A FALLING RATE ARRAY IS ACCEPTED, because [p/tiers](/p/tiers) accepts one — it is a volume discount, which is a real schedule. The consequence is that a transposed array is a silent authoring error here, and neither this realm nor tiers can detect it. Read back [ScheduleOf](#ScheduleOf) after setting one.
- OID
- 0f4c53…775d:20
SetSchedule details
Publish
func(employees string) int64Publish prices the named employees under the caller's own roster and records a payslip. It returns the payslip's sequence number, which is per-employer and starts at 1. employees is a comma-separated list of addresses, at most [MaxEmployeesPerCall](#MaxEmployeesPerCall) of them. Order is the caller's and is preserved in the record, so a payslip reads in the order it was requested. THREE REFUSAL RULES, AND THE ASYMMETRY BETWEEN THEM IS THE POINT: - An employee with NO OPEN POSITION under the caller PANICS and fails the whole call. A silently-dropped line is an under-report, and under- reporting is the one error this product cannot detect after the fact. A caller that wants to skip an absent position must leave it out, which is a decision in the transaction rather than a silence in the record. - A DUPLICATE is dropped, counted in the coverage line, and does not fail the call. Dropping it cannot under-report: the employee is still priced once, and double-counting them would be worse. - An employee with ZERO SETTLED GROSS is PRICED, not filtered. A payslip for a position that has settled nothing yet is a correct payslip with a gross of zero, and filtering it would turn a true statement into a missing line. An empty list is refused. Nothing here filters a list down to nothing, so after deduplication a call always prices at least one employee.
- OID
- 0f4c53…775d:21
Publish details
priceOne
func(employer .uverse.address, who .uverse.address, s tiers.Schedule, now int64) *payslips.linepriceOne builds one line from r/payroll's views. Every arithmetic refusal here is a panic rather than a zero, because a view that refuses is recoverable and a view that lies is not — payroll's own DueAmount states the same rule for the same reason.
- OID
- 0f4c53…775d:22
priceOne details
crossFoot
func(lines []*payslips.line, gross int64, withheld int64, feeLo int64, feeHi int64, dueGross int64)- OID
- 0f4c53…775d:23
crossFoot details
PublishedAt
func(employer .uverse.address, seq int64) int64PublishedAt is the height a payslip was published at, which is the height every figure in it was read at.
- OID
- 0f4c53…775d:24
PublishedAt details
GrossOf
func(employer .uverse.address, seq int64) int64GrossOf is a payslip's total SETTLED gross. Read it beside [UnsettledGrossOf](#UnsettledGrossOf) and [OmittedRoster](#OmittedRoster): neither is an error, and both change what this number means.
- OID
- 0f4c53…775d:25
GrossOf details
WithheldOf
func(employer .uverse.address, seq int64) int64WithheldOf is the schedule's total charge on the gross.
- OID
- 0f4c53…775d:26
WithheldOf details
PlatformFeeRange
func(employer .uverse.address, seq int64) (lo int64, hi int64)PlatformFeeRange bounds the accrual fee r/payroll already took on this gross. It is an interval because the fee depends on accrual batching, which payroll does not expose — see the package doc. lo == hi is common and means the batching could not have mattered.
- OID
- 0f4c53…775d:27
PlatformFeeRange details
NetRange
func(employer .uverse.address, seq int64) (lo int64, hi int64)NetRange bounds what the employee kept: gross, less the schedule's withholding, less payroll's fee. The interval is inherited whole from [PlatformFeeRange](#PlatformFeeRange) — the withholding itself is exact. IT CAN BE NEGATIVE, and that is a finding rather than a bug. A schedule may legally charge up to 100%, and payroll's fee is taken on top of whatever this realm withholds, so a schedule at or near the ceiling withholds more than the employee actually received. [OverWithheld](#OverWithheld) names that case.
- OID
- 0f4c53…775d:28
NetRange details
UnsettledGrossOf
func(employer .uverse.address, seq int64) int64UnsettledGrossOf is gross that had completed and not been accrued at the payslip's height, and is therefore EXCLUDED from [GrossOf](#GrossOf). Non-zero is normal: payroll accrues on demand.
- OID
- 0f4c53…775d:29
UnsettledGrossOf details
OverWithheld
func(employer .uverse.address, seq int64) boolOverWithheld reports whether this payslip's withholding plus payroll's largest possible fee exceeds the gross. True is almost always a transposed or mis-scaled rate array, which [p/tiers](/p/tiers) cannot detect, so this realm surfaces it instead of refusing to publish it — a refusal would lose the evidence.
- OID
- 0f4c53…775d:30
OverWithheld details
FeeBpsAt
func(employer .uverse.address, seq int64) int64FeeBpsAt is the platform fee rate this payslip was priced against.
- OID
- 0f4c53…775d:31
FeeBpsAt details
ScheduleAt
func(employer .uverse.address, seq int64) (edges string, rates string)ScheduleAt is the schedule that priced this payslip, as comma-separated lists that round-trip exactly through [SetSchedule](#SetSchedule). The snapshot, not the employer's current schedule — see [ScheduleOf](#ScheduleOf) for that.
- OID
- 0f4c53…775d:32
ScheduleAt details
Coverage
func(employer .uverse.address, seq int64) (listed int, priced int, zeroGross int, withDue int, ended int, dupes int, rosterAt int, openAt int)Coverage is the payslip's coverage line, and it is the number to read before any total. listed employees the caller named, duplicates included priced lines in the record zeroGross priced lines whose settled gross is zero withDue priced lines with gross due and not accrued ended priced lines whose position's clock had stopped dupes duplicate names dropped rosterAt open positions the employer held at this height openAt open positions across every employer at this height listed == priced + dupes always, by construction: nothing else is dropped. rosterAt - priced is [OmittedRoster](#OmittedRoster).
- OID
- 0f4c53…775d:33
Coverage details
OmittedRoster
func(employer .uverse.address, seq int64) intOmittedRoster is how many of the employer's open positions this payslip did not price. It is the one number that says whether a payslip is complete, and a total read without it is being read wrongly. It cannot be negative: every priced line has an open position under this employer at the payslip's height, duplicates are dropped before pricing, so priced is a count of distinct open positions and rosterAt is their total.
- OID
- 0f4c53…775d:34
OmittedRoster details
Lines
func(employer .uverse.address, seq int64) intLines is how many employees a payslip prices.
- OID
- 0f4c53…775d:35
Lines details
LineAt
func(employer .uverse.address, seq int64, i int) (employee .uverse.address, paidPeriods int64, perPeriod int64, gross int64, withheld int64, feeLo int64, feeHi int64, dueGross int64)- OID
- 0f4c53…775d:36
LineAt details
LineEnded
func(employer .uverse.address, seq int64, i int) boolLineEnded reports whether this line's position had been terminated or had passed its end height when the payslip was published. An ended position can still carry unsettled gross: payroll keeps the obligation alive past Terminate on purpose.
- OID
- 0f4c53…775d:37
LineEnded details
LineNetRange
func(employer .uverse.address, seq int64, i int) (lo int64, hi int64)LineNetRange bounds what this employee kept. Same interval as [NetRange](#NetRange), one line.
- OID
- 0f4c53…775d:38
LineNetRange details
TierBreakdown
func(employer .uverse.address, seq int64, i int) stringTierBreakdown is the withholding on one line split by bracket, as a comma-separated list in tier order — the column a payslip reader actually wants, because it shows which brackets the gross reached. It is recomputed from the payslip's own schedule snapshot rather than stored, so it is exact for the schedule that priced the line and costs no storage. It cross-foots the column against the stored total before returning it: [p/tiers](/p/tiers) DOCUMENTS that Charge is defined as the sum of ChargeByTier, and a documented identity across a package boundary is worth one loop to assert.
- OID
- 0f4c53…775d:39
TierBreakdown details
ScheduleOf
func(employer .uverse.address) (edges string, rates string)ScheduleOf is an employer's CURRENT schedule, as lists that round-trip through [SetSchedule](#SetSchedule). It is not what priced any published payslip — see [ScheduleAt](#ScheduleAt).
- OID
- 0f4c53…775d:40
ScheduleOf details
NumTiersOf
func(employer .uverse.address) intNumTiersOf is how many brackets an employer's current schedule has.
- OID
- 0f4c53…775d:41
NumTiersOf details
HasSchedule
func(employer .uverse.address) boolHasSchedule reports whether an employer has set a schedule, without panicking on absence — every other schedule accessor panics, which makes them unusable as an existence probe.
- OID
- 0f4c53…775d:42
HasSchedule details
Has
func(employer .uverse.address, seq int64) boolHas reports whether a payslip exists, so the record accessors can be pre-checked rather than recovered from. Every one of them panics on an absent record, which is deliberate — returning a zero figure for a payslip that was never published is the exact silent under-report this realm exists to refuse — but a panic is only a usable contract when the caller has a way not to hit it. It is here before the first deploy rather than in a successor because a realm's bytes are frozen by addpkg: an accessor a consumer needs cannot be added afterwards.
- OID
- 0f4c53…775d:43
Has details
ChargeOn
func(employer .uverse.address, gross int64) int64ChargeOn quotes an employer's current schedule against an arbitrary gross without publishing anything. The quote a caller needs before choosing a schedule, and the one view here that is not about a record.
- OID
- 0f4c53…775d:44
ChargeOn details
MarginalRateOf
func(employer .uverse.address, gross int64) int64MarginalRateOf is the rate an employer's current schedule would charge on the next ugnot of gross past the given amount, of [RateScale](#RateScale).
- OID
- 0f4c53…775d:45
MarginalRateOf details
Count
func(employer .uverse.address) intCount is how many payslips an employer has published. Sequence numbers run 1..Count with no gaps: a payslip is never removed.
- OID
- 0f4c53…775d:46
Count details
Payslips
func() intPayslips is how many payslips exist across every employer.
- OID
- 0f4c53…775d:47
Payslips details
Employers
func() intEmployers is how many addresses have set a schedule here. Note the tense: a schedule survives, so this is not a count of employers with payslips.
- OID
- 0f4c53…775d:48
Employers details
Height
func() int64Height is the current chain height, exposed so a caller can see the clock this realm reads payroll against.
- OID
- 0f4c53…775d:49
Height details
parseEmployees
func(s string) ([].uverse.address, int)- OID
- 0f4c53…775d:50
parseEmployees details
parseInt64List
func(s string, max int, what string) []int64- OID
- 0f4c53…775d:51
parseInt64List details
formatInt64List
func(v []int64) string- OID
- 0f4c53…775d:52
formatInt64List details
slipKey
func(employer string, seq int64) stringslipKey left-pads seq to the width of MaxInt64 so that an employer's payslips sort in numeric order under the tree's lexical key order. NOTHING IN THIS REALM CONSUMES THAT ORDER TODAY, and the padding is in the source anyway. The tree is only ever Set and Get here — renderEmployer walks the sequence numbers it already knows from [Count](#Count) rather than iterating — so unpadded keys would produce byte-identical output from every view, and no test can distinguish the two. It is kept because the bytes freeze at addpkg: an enumerator added in a successor realm, or an off-chain indexer doing a prefix scan over this realm's storage, would read "10" before "9" forever, and the fix would be unavailable. Twelve bytes of padding now against a defect that cannot be repaired later. Stated this way deliberately. The comment here used to claim the padding is "what makes a prefix iteration in Render read in sequence", which is a reachability argument for a prefix iteration that does not exist.
- OID
- 0f4c53…775d:53
slipKey details
employerCount
func(employer string) int- OID
- 0f4c53…775d:54
employerCount details
mustSchedule
func(employer .uverse.address) tiers.Schedule- OID
- 0f4c53…775d:55
mustSchedule details
mustPayslip
func(employer .uverse.address, seq int64) *payslips.payslip- OID
- 0f4c53…775d:56
mustPayslip details
mustLine
func(employer .uverse.address, seq int64, i int) *payslips.line- OID
- 0f4c53…775d:57
mustLine details
checkedAdd
func(a int64, b int64) (int64, bool)- OID
- 0f4c53…775d:58
checkedAdd details
checkedMul
func(a int64, b int64) (int64, bool)checkedMul is written for the non-negative operands this realm has — every multiplicand is a period count or a per-period amount, both of which r/payroll refuses to make negative. The division test is exact for those.
- OID
- 0f4c53…775d:59
checkedMul details
Render
func(path string) stringRender serves the index at "", an employer's page at "\<address>", and one payslip at "\<address>/\<seq>". Every caller-supplied string reaching the output goes through the sanitizer. This realm stores no free text, so the untrusted bytes are the path itself and the addresses in a record — and that is still the one injection-shaped surface a realm with no custody has.
- OID
- 0f4c53…775d:60
Render details
renderIndex
func() string- OID
- 0f4c53…775d:61
renderIndex details
renderEmployer
func(employer .uverse.address) string- OID
- 0f4c53…775d:62
renderEmployer details
renderPayslip
func(employer .uverse.address, seq int64) string- OID
- 0f4c53…775d:63