RealmPath
untyped stringRealmPath is this realm's own path, used to build Render links.
Value
"/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/inventory"
InventoryCode
untyped stringThe fixed chart. The codes follow r/books' convention, where an account's LEADING DIGIT fixes its kind: 1 asset, 2 liability, 3 equity, 4 revenue, 5 expense. A six-series code would be an invalid account under that convention, which is why cost of goods sold is 5000 and not the 6000 some charts use.
Value
"1300"
InventoryName
untyped stringThe fixed chart. The codes follow r/books' convention, where an account's LEADING DIGIT fixes its kind: 1 asset, 2 liability, 3 equity, 4 revenue, 5 expense. A six-series code would be an invalid account under that convention, which is why cost of goods sold is 5000 and not the 6000 some charts use.
Value
"Inventory"
COGSCode
untyped stringThe fixed chart. The codes follow r/books' convention, where an account's LEADING DIGIT fixes its kind: 1 asset, 2 liability, 3 equity, 4 revenue, 5 expense. A six-series code would be an invalid account under that convention, which is why cost of goods sold is 5000 and not the 6000 some charts use.
Value
"5000"
COGSName
untyped stringThe fixed chart. The codes follow r/books' convention, where an account's LEADING DIGIT fixes its kind: 1 asset, 2 liability, 3 equity, 4 revenue, 5 expense. A six-series code would be an invalid account under that convention, which is why cost of goods sold is 5000 and not the 6000 some charts use.
Value
"Cost of goods sold"
ContribCode
untyped stringThe fixed chart. The codes follow r/books' convention, where an account's LEADING DIGIT fixes its kind: 1 asset, 2 liability, 3 equity, 4 revenue, 5 expense. A six-series code would be an invalid account under that convention, which is why cost of goods sold is 5000 and not the 6000 some charts use.
Value
"3900"
ContribName
untyped stringThe fixed chart. The codes follow r/books' convention, where an account's LEADING DIGIT fixes its kind: 1 asset, 2 liability, 3 equity, 4 revenue, 5 expense. A six-series code would be an invalid account under that convention, which is why cost of goods sold is 5000 and not the 6000 some charts use.
Value
"Inventory contributed"
MaxItemsPerRegister
untyped bigintMaxItemsPerRegister caps one owner's SKU count. Every register-wide cross-foot walks every item's lots, and this bound is half of what keeps those reads affordable for everyone.
Value
(64 <untyped> bigint)
MaxLotsPerItem
untyped bigintMaxLotsPerItem caps one item's LIVE lots, well below p/lots' MaxLotsLimit of 1024. It is the other half of the read bound: the worst case a register-wide walk must visit is MaxItemsPerRegister\*MaxLotsPerItem lots. Exhausted lots are dropped by p/lots, so this bounds concurrent lots and not the number of receipts an item may ever take. A WAVG item merges every receipt into one lot and so can never reach it — which means this is NOT the binding constraint for a WAVG item, and that item has a merge-overflow refusal of its own instead. See the package doc.
Value
(64 <untyped> bigint)
MaxEntriesPerRegister
untyped bigintMaxEntriesPerRegister caps one owner's journal, far below journal's MaxEntriesLimit of 1000000 because Rederive is linear in the posting count and is a free read here. A register that fills refuses further receipts and shipments rather than dropping history. There is deliberately no Archive — it would destroy the record the invariants are checked against — so the remedy is a second register under a second address, which is a real limitation and not a hidden one.
Value
(8192 <untyped> bigint)
MaxSKULen
untyped bigintMaxSKULen bounds a SKU, which is an avl key, a Render table cell and a Render path component all at once.
Value
(32 <untyped> bigint)
MaxItemNameLen
untyped bigintMaxItemNameLen bounds an item's human name. Every name is a candidate for Render output.
Value
(64 <untyped> bigint)
RenderItemLimit
untyped bigintRenderItemLimit caps how many items one register page tabulates.
Value
(25 <untyped> bigint)
RenderLotLimit
untyped bigintRenderLotLimit caps how many lots one item page tabulates.
Value
(20 <untyped> bigint)
maxInt64
int64maxInt64 is the largest int64. It is a precondition of the counter guards below, so it is pinned BY BEHAVIOUR in the suite rather than by a test that restates the literal: TestMaxInt64IsTheInt64Maximum proves it wraps when incremented.
Value
9223372036854775807
register
typeregister is one owner's inventory sub-ledger and the book its postings go to. The book and every pool are POINTERS and none is ever returned by any exported function — p/journal consumer obligation 4 and the identical rule for p/lots: a \*Book is a mutable handle and a \*Pool is a mutable handle, and handing either across a realm boundary would hand out the right to post or to consume.
Value
inventory.register
item
typeitem is one stock-keeping unit and its cost pool.
Value
inventory.item
regs
*v0.Treeregs maps an owner's address string to that owner's \*register.
- OID
- 0399f7…936d:4
regs details
regCount
intregCount is maintained alongside the tree so the index page never has to iterate it.
Value
0
refuseCoins
func()refuseCoins panics if a user call arrives carrying coins. This realm has no withdrawal path, so accepted coins would be stranded permanently. The guard is on IsUserCall rather than IsUser deliberately: OriginSend is only meaningful for a direct MsgCall, and the MsgRun ephemeral can consume the envelope before forwarding control, so IsUser would be the wrong predicate. The IsCurrent() check is a separate concern and is not about coins: this is a non-crossing helper reading identity off a realm PARAMETER, which is the designation-forgery shape (security.md Class 2) whether or not a caller exercising it exists today. It is a no-op at every call site here, and that claim has one more hop in this realm than in its siblings: addItem is itself non-crossing and forwards the cur it was given, so the chain is AddFIFO/AddLIFO/AddWAVG -> addItem -> here. Every link forwards a crossing entrypoint's OWN first cur, which is runtime-current by construction and stays current through any number of non-crossing calls — so the guard still never fires, and the extra hop is exactly why having it at the point of USE rather than at the entrypoints is the right placement. It is kept because this realm is IMMUTABLE after addpkg. p/coinio guards the same shape in Receive, Payout and Sweep; this is that house precedent applied. No count of the call sites is written down, per CLAUDE.md § 4a.
- OID
- 0399f7…936d:7
refuseCoins details
mustOwnRegister
func() *inventory.registermustOwnRegister returns the CALLER'S register, and there is no variant that returns anyone else's. Every mutating entrypoint goes through this, so ownership is implicit in the call. "Ownership is never a parameter" is what this comment used to conclude, and it is true of the SIGNATURE and was never true of the realm VALUE: the owner is derived from cur, so an uncurrent cur IS an ownership parameter. That is the same Class 2 shape refuseCoins carries above and the more consequential half of it, because this is the function that decides who owns the register rather than one that only refuses coins. The addItem hop described above applies here too. The guard is a no-op today for the same reason, kept for the same reason, and its call sites are likewise not counted here. See AUDIT.md.
- OID
- 0399f7…936d:9
mustOwnRegister details
reg
func(owner .uverse.address) (*inventory.register, bool)reg looks an owner's register up. avl's Get returns a bare \`any\` and signals absence with nil, so the nil test IS the lookup result and not a defensive extra — every value this realm stores is a non-nil pointer.
- OID
- 0399f7…936d:10
reg details
mustReg
func(owner .uverse.address) *inventory.register- OID
- 0399f7…936d:11
mustReg details
mustItem
func(r *inventory.register, sku string) *inventory.item- OID
- 0399f7…936d:12
mustItem details
checkSKU
func(sku string)checkSKU validates a SKU against a deliberately narrow charset: A-Z, a-z, 0-9, '.', '\_' and '-'. The restriction buys three things at once, which is why it is worth imposing on a caller. A SKU is an avl KEY, so its byte order is the Render table's row order. It is a Render PATH COMPONENT, so a '/' would forge a route and a '?' or '#' would truncate one. And it is a markdown TABLE CELL, so a '|' would forge a column. Escaping at each use site would be three chances to miss one; a charset is checked once, here, on the way in. Case is significant and "sku-1" and "SKU-1" are different items. That is a real sharp edge for a human operator and is the honest reading of a key: folding case would mean this realm, not the owner, decides which SKUs collide.
- OID
- 0399f7…936d:13
checkSKU details
checkItemName
func(name string)- OID
- 0399f7…936d:14
checkItemName details
OpenRegister
func()OpenRegister creates the caller's register and opens its three accounts. It panics if the caller already has one. The chart is opened HERE rather than on demand, and the book is created with a cap of exactly three accounts. Both facts are load-bearing: they are why this realm is its book's only writer and why the cross-foot identities are exact rather than approximate.
- OID
- 0399f7…936d:15
OpenRegister details
AddFIFO
func(sku string, name string)AddFIFO adds an item whose shipments are costed oldest-lot-first.
- OID
- 0399f7…936d:16
AddFIFO details
AddLIFO
func(sku string, name string)AddLIFO adds an item whose shipments are costed newest-lot-first.
- OID
- 0399f7…936d:17
AddLIFO details
AddWAVG
func(sku string, name string)AddWAVG adds an item whose receipts are merged into a single re-anchored lot and whose shipments are costed at the blended unit cost. A WAVG item holds exactly one lot however many receipts it takes, so it can never reach MaxLotsPerItem. It can still refuse a receipt: the MERGE has an overflow precondition the other two methods never evaluate, and it is a property of the pool's accumulated history rather than of the receipt. See the package doc; the practical consequence is that [LotCapacity](#LotCapacity) is not the figure to watch for a WAVG item.
- OID
- 0399f7…936d:18
AddWAVG details
addItem
func(sku string, name string, m lots.Method)- OID
- 0399f7…936d:19
addItem details
Receive
func(sku string, qty int64, cost int64) uint64Receive takes qty units costing cost in total into the item's pool and posts debit 1300 / credit 3900, returning the entry id. A cost of ZERO is accepted — free goods — and posts nothing; the returned id is then 0, which is not a valid entry id and is the signal that no entry was made. See the package doc. Panics if the item does not exist, if qty is not positive, if cost is negative, if the pool's lot cap is reached, if a WAVG merge would breach the per-lot overflow precondition — a refusal that depends on the item's history and not on this receipt, see [AddWAVG](#AddWAVG) — or if the book is full. Every one of those aborts the whole transaction, which is what makes the pool-then-post order safe: an error return would NOT revert the pool update, a panic does.
- OID
- 0399f7…936d:20
Receive details
Ship
func(sku string, qty int64) int64Ship consumes qty units from the item's pool and posts debit 5000 / credit 1300 for the cost it DERIVED, returning that cost. The cost is never a parameter. It is whatever the item's costing method charges against the lots on hand, which is the whole product. A derived cost of ZERO posts nothing — goods that cost nothing to acquire cost nothing to ship. The return value is then 0 and so is indistinguishable from "no entry made", deliberately: both facts are the same fact here. Panics if the item does not exist, if qty is not positive, if qty exceeds the quantity on hand (p/lots fails closed with ErrInsufficient and consumes nothing), or if the book is full.
- OID
- 0399f7…936d:21
Ship details
Rename
func(sku string, name string)Rename changes an item's human name. The SKU, the costing method and every lot are immutable; a name is presentation only and nothing derives from it.
- OID
- 0399f7…936d:22
Rename details
HasRegister
func(owner .uverse.address) boolHasRegister reports whether an address has opened a register.
- OID
- 0399f7…936d:23
HasRegister details
Registers
func() intRegisters is how many registers exist across the realm.
- OID
- 0399f7…936d:24
Registers details
OpenedAt
func(owner .uverse.address) int64OpenedAt is the height an owner's register was opened at.
- OID
- 0399f7…936d:25
OpenedAt details
ItemCount
func(owner .uverse.address) intItemCount is how many items an owner's register holds.
- OID
- 0399f7…936d:26
ItemCount details
Height
func() int64Height is the current chain height, so a reader can date every other figure on this page without a second query.
- OID
- 0399f7…936d:27
Height details
SKUs
func(owner .uverse.address, from string, limit int) []stringSKUs lists an owner's SKUs in key order, starting at or after from and returning at most limit of them. An empty from starts at the beginning. This enumerator exists because its absence is a known defect elsewhere in this portfolio: r/books exposes no account enumerator, so a third party cannot discover what to ask it about without already knowing. A sub-ledger whose invariants are per-item is useless to a verifier who cannot list the items, so the list is part of the product rather than an afterthought. A non-positive limit returns nothing rather than everything. The cap is the item cap, so a caller may always page the whole register.
- OID
- 0399f7…936d:28
SKUs details
HasItem
func(owner .uverse.address, sku string) boolHasItem reports whether an owner's register holds a SKU.
- OID
- 0399f7…936d:29
HasItem details
ItemName
func(owner .uverse.address, sku string) stringItemName is an item's human name.
- OID
- 0399f7…936d:30
ItemName details
Method
func(owner .uverse.address, sku string) stringMethod is an item's costing method, as "fifo", "lifo" or "weighted-average".
- OID
- 0399f7…936d:31
Method details
AddedAt
func(owner .uverse.address, sku string) int64AddedAt is the height an item was added at.
- OID
- 0399f7…936d:32
AddedAt details
OnHand
func(owner .uverse.address, sku string) int64OnHand is the quantity of an item on hand, DERIVED by walking its live lots rather than read from a counter — which is what makes [ItemCrossFootQty](#ItemCrossFootQty) a comparison rather than a tautology.
- OID
- 0399f7…936d:33
OnHand details
CostOnHand
func(owner .uverse.address, sku string) int64CostOnHand is the carrying value of an item's live lots: the figure this item contributes to the 1300 balance. Derived, for the same reason as [OnHand](#OnHand).
- OID
- 0399f7…936d:34
CostOnHand details
Received
func(owner .uverse.address, sku string) (qty int64, cost int64)Received is an item's cumulative received quantity and cost.
- OID
- 0399f7…936d:35
Received details
Charged
func(owner .uverse.address, sku string) (qty int64, cost int64)Charged is an item's cumulative shipped quantity and the cost charged out for it. The cost figure is derived: no caller has ever supplied it.
- OID
- 0399f7…936d:36
Charged details
Receipts
func(owner .uverse.address, sku string) int64Receipts is how many receipts an item has taken, including those whose lots are exhausted and dropped. It is NOT the live lot count — see [LotCount](#LotCount).
- OID
- 0399f7…936d:37
Receipts details
LotCount
func(owner .uverse.address, sku string) intLotCount is how many LIVE lots an item holds. Exhausted lots are dropped.
- OID
- 0399f7…936d:38
LotCount details
LotAt
func(owner .uverse.address, sku string, i int) (qty int64, cost int64, consumed int64, remaining int64, remainingCost int64, ok bool)LotAt reports the i'th live lot of an item in receipt order, and whether i was in range. It returns primitives rather than a p/lots.Lot so that the figures are readable from vm/qeval without the caller knowing that type.
- OID
- 0399f7…936d:39
LotAt details
Capacity
func(owner .uverse.address) (itemsLeft int, entriesLeft int)Capacity reports how much room an owner's register has left.
- OID
- 0399f7…936d:40
Capacity details
LotCapacity
func(owner .uverse.address, sku string) intLotCapacity reports how many further live lots one item can hold. A WAVG item merges into one lot, so its figure is a bound it will never approach — and reading headroom off it for a WAVG item is therefore reading the wrong limit, because the refusal that CAN bind there is a merge overflow this figure knows nothing about. See [AddWAVG](#AddWAVG).
- OID
- 0399f7…936d:41
LotCapacity details
Balance
func(owner .uverse.address, code string) (int64, bool)Balance returns an account's balance in its NORMAL direction and whether the code exists. All three of this realm's accounts are normal, so all three read non-negative.
- OID
- 0399f7…936d:42
Balance details
RawBalance
func(owner .uverse.address, code string) (int64, bool)RawBalance returns debits minus credits regardless of kind. Summed over the three accounts it is exactly zero in a balanced book, which is what makes it the useful figure for a consistency check and the wrong one for a report.
- OID
- 0399f7…936d:43
RawBalance details
AccountKind
func(owner .uverse.address, code string) (string, bool)AccountKind returns an account's kind as a word, and whether it exists.
- OID
- 0399f7…936d:44
AccountKind details
InventoryDebit
func(owner .uverse.address) int64InventoryDebit is the 1300 balance: the value of goods on hand per the ledger.
- OID
- 0399f7…936d:45
InventoryDebit details
COGSDebit
func(owner .uverse.address) int64COGSDebit is the 5000 balance: everything ever charged out as cost of goods sold.
- OID
- 0399f7…936d:46
COGSDebit details
ContributedCredit
func(owner .uverse.address) int64ContributedCredit is the 3900 balance. Read it as "goods arrived from somewhere this ledger does not model" — see the package doc on why 3900 is a plug this realm is forced to pick.
- OID
- 0399f7…936d:47
ContributedCredit details
EntryCount
func(owner .uverse.address) intEntryCount is how many entries an owner's book holds.
- OID
- 0399f7…936d:48
EntryCount details
Totals
func(owner .uverse.address) (debits int64, credits int64)Totals are the book's total debits and credits.
- OID
- 0399f7…936d:49
Totals details
IsBalanced
func(owner .uverse.address) boolIsBalanced reports whether total debits equal total credits.
- OID
- 0399f7…936d:50
IsBalanced details
Equation
func(owner .uverse.address) (debitNormal int64, creditNormal int64, offsets bool)Equation reports the accounting equation: debit-normal against credit-normal, and whether they offset. For this realm that is 1300 + 5000 against 3900, which offsets at 0 = 0 on an empty register and after every posting. READ THE SIGN BEFORE PRESENTING EITHER FIGURE. journal partitions RAW DELTAS — debits minus credits — so creditNormal is NEGATIVE whenever 3900 carries a credit balance, and \`offsets\` means debitNormal + creditNormal == 0, not debitNormal == creditNormal. The textbook "assets = equity" has both sides positive; this does not. A caller rendering a balance sheet wants -creditNormal. The first test written against this function asserted the right magnitude with the wrong sign and was red for it, which is why this paragraph exists rather than a reader discovering it. What \`offsets\` does NOT prove is journal's obligation 7, inherited here verbatim: the two subtotals are a partition of the same addends, so reclassifying every account in the chart changes both and leaves \`offsets\` true. A Kind set wrongly at Open time is invisible to it. What pins this realm's chart is the PAIR — debitNormal == InventoryDebit + COGSDebit and creditNormal == -ContributedCredit — and the suite asserts exactly that. Sharper than that, because the partition is arithmetically inert: the two subtotals are added back together, so \`offsets\` reduces to Σ debits == Σ credits over the whole chart, which is the FIRST of the three conjuncts [IsBalanced](#IsBalanced) checks. A balanced book therefore always offsets, and \`offsets\` carries no fact [IsBalanced](#IsBalanced) has not already carried more strongly. The informative half of this function is the PAIR OF FIGURES, not the boolean — the figures move when a Kind changes and the boolean does not. (The two walks accumulate in different orders, so a mid-sum overflow could in principle separate them. At 8192 entries it would take amounts no register can reach, and it is not a second independent check.)
- OID
- 0399f7…936d:51
Equation details
Rederive
func(owner .uverse.address) (debits int64, credits int64, agrees bool)Rederive re-walks every posting in the book and reports whether the account totals agree with the journal. It is a FREE read, unlike r/books' owner-only equivalent, for the reason given in the package doc. The cost is linear in the posting count, which is what MaxEntriesPerRegister bounds.
- OID
- 0399f7…936d:52
Rederive details
Invariant
func(owner .uverse.address, sku string) (posted int64, derived int64, agrees bool)Invariant is the per-item derivation check, and it is this realm's central claim: postedCOGS == pool.ChargedCost() The left figure is what this realm posted to 5000 for the item; the right is what the pool says it charged. They are maintained by different code in different packages, so a false here means the realm posted an amount its own lots do not imply — which no code path in this realm can produce, and which is exactly why it is worth exporting. A claim is worth more checkable by a stranger than asserted in a comment. The receipt side is checked the same way by [InvariantReceipts](#InvariantReceipts).
- OID
- 0399f7…936d:53
Invariant details
InvariantReceipts
func(owner .uverse.address, sku string) (posted int64, derived int64, agrees bool)InvariantReceipts is [Invariant](#Invariant) for the receipt side: postedRecv == pool.ReceivedCost()
- OID
- 0399f7…936d:54
InvariantReceipts details
ItemCrossFoot
func(owner .uverse.address, sku string) (received int64, charged int64, onHand int64, foots bool)ItemCrossFoot is p/lots' own cost identity for one item: receivedCost == chargedCost + costOnHand Received and charged are counters; on-hand is a walk of the live lots. The identity therefore compares two independently maintained things, which is why p/lots keeps them apart.
- OID
- 0399f7…936d:55
ItemCrossFoot details
ItemCrossFootQty
func(owner .uverse.address, sku string) (received int64, consumed int64, onHand int64, foots bool)ItemCrossFootQty is the quantity identity for one item: receivedQty == consumedQty + qtyOnHand It is not implied by [ItemCrossFoot](#ItemCrossFoot): costs and quantities can disagree independently, and a bug that moved cost without moving quantity would be invisible to the cost identity alone.
- OID
- 0399f7…936d:56
ItemCrossFootQty details
CrossFootInventory
func(owner .uverse.address) (sumOnHand int64, balance int64, agrees bool)CrossFootInventory is the register-wide check on 1300: the sum of every item's carrying value against the ledger balance. The identity is EXACT, not approximate, and the reason is structural: this realm exposes no general posting entrypoint, so it is its book's only writer. Adding a general Post would destroy this check, which is the cost of adding one.
- OID
- 0399f7…936d:57
CrossFootInventory details
CrossFootCOGS
func(owner .uverse.address) (sumCharged int64, balance int64, agrees bool)CrossFootCOGS is the register-wide check on 5000: the sum of every item's charged cost against the ledger balance.
- OID
- 0399f7…936d:58
CrossFootCOGS details
CrossFootContributed
func(owner .uverse.address) (sumReceived int64, balance int64, agrees bool)CrossFootContributed is the register-wide check on 3900: the sum of every item's received cost against the ledger balance.
- OID
- 0399f7…936d:59
CrossFootContributed details
CrossFoot
func(owner .uverse.address) (inventoryAgrees bool, cogsAgrees bool, contributedAgrees bool, equationOffsets bool)CrossFoot reports all four register-wide agreements as separate bools. They are returned SEPARATELY and there is deliberately no single aggregate bool: a one-word verdict over four checks is the shape that gets quoted without its coverage, and a reader who wants the figures behind any one of these has [CrossFootInventory](#CrossFootInventory), [CrossFootCOGS](#CrossFootCOGS), [CrossFootContributed](#CrossFootContributed) and [Equation](#Equation).
- OID
- 0399f7…936d:60
CrossFoot details
Render
func(path string) stringRender shows the realm index at "/", one owner's register at "/\<address>", and one item at "/\<address>/\<sku>".
- OID
- 0399f7…936d:61
Render details
renderIndex
func() string- OID
- 0399f7…936d:62
renderIndex details
renderRegister
func(owner .uverse.address) string- OID
- 0399f7…936d:63
renderRegister details
renderItem
func(owner .uverse.address, sku string) string- OID
- 0399f7…936d:64
renderItem details
cell
func(s string) stringcell renders a caller-supplied string into a table cell. A blank value would collapse the column, so it is shown as a dash.
- OID
- 0399f7…936d:65
cell details
yesno
func(b bool) string- OID
- 0399f7…936d:66