A custody ledger for third-party logistics warehousing, where the operator holds goods it does not own. Stock is a derived balance and never an editable field: there is no quantity input anywhere in the system, and the roles matrix marks setting one Impossible for every role including Tenant Admin. Fifty-one screens across four shells, each annotated with the requirement it exists to make visible. You can walk all of it on this page.
A design prototype on mock data, not a production system.

The real prototype, not a recording. It opens on the controller's dashboard. The tabs above switch shells: the handheld is a real 390px layout, and the client portal is a separate application on the same ledger. Runs entirely in your browser.The real prototype, not a recording. It opens over this page, and closing it brings you straight back here.
OmniStock isn't an inventory manager. It's a custody instrument for a logistics operator holding somebody else's goods, and when you're liable for stock you don't own, one rule governs everything: nobody, at any privilege level, gets to type a number that isn't the sum of events someone actually signed for. Try to PATCH an item's stock count directly and the API returns 422 quantity_not_settable, naming the only real alternative in the same response. Even the roles matrix admits it: setting a stock quantity reads Impossible in all six columns, Tenant Admin included. There's no admin flag, no support tool, no migration path that turns this off. That is the whole product.

This is the mechanism behind Nobody gets to just declare a number, and it is enforced by what got drawn rather than by anything running. The one screen that edits an item carries eleven controls: SKU, GTIN, description, owner, handling class, unit of measure, four dimensions, and a reorder trigger that names itself as one. None of them is a count, and the banner at the top of the form says so before you go looking for it.
<div class="banner banner--teal" style="margin-bottom:var(--s5)"> <svg aria-hidden="true"><use href="#i-info"></use></svg> <div><div class="banner__title">There is no quantity field on this form</div> <!-- … not hidden, not disabled, not permission-gated: it does not exist. --></div><form class="card" style="max-width:760px" action="09-item-detail.html" method="get" novalidate> <div class="card__head"><h2 class="card__title">Identity</h2></div> <div class="card__body grid grid-2"> <div class="field"><label class="field__label" for="sku">SKU</label> <input class="input mono" id="sku" value="88213-K" readonly> <!-- … GTIN, description, owner and handling class. None of them a count. --> </div> <div class="card__head" style="border-top:1px solid var(--hairline)"><h2 class="card__title">Physical</h2></div> <div class="card__body grid grid-4"> <div class="field"><label class="field__label" for="uom">UoM</label> <select class="select" id="uom"><option>EA</option><option>CS</option><option>RL</option><option>PAL</option></select></div> <!-- … length, width, height and gross weight. All of them dimensions. --> <div class="field"><label class="field__label" for="min">Min level</label><input class="input mono" id="min" inputmode="numeric" value="400"> <span class="field__help">A reorder trigger, not a stock value.</span></div> </div>Worth being exact about what this is and is not. Nothing here computes a balance from movements and nothing rejects a bad write, because nothing here submits to a backend at all, which the study admits a few paragraphs down. The discipline lives in the drawing. Three inputs in the whole prototype ask for a quantity, out of thirty-two, and every one of them sits on a document that also demands where the units came from and where they went: a movement needs a from-account, a to-account and a reason code before it will post, a title transfer needs a contract reference and a second approver who cannot be you. A bare quantity box on an item form would be a fourth kind of number, one with no counterparty and no stated cause, and that is precisely the number this product exists to make unavailable. The roles matrix argues the same thing from the other side, and the 422 quantity_not_settable block on the API screen is a specification printed on a page, not a response anything here returns.
On the Console tab, open Catalog, click SKU 88213-K, then Edit catalog fields. Read down the form: identity, owner, handling class, dimensions, and then it stops. The closest thing to a count is Min level, and its own help text says what it is, a reorder trigger, not a stock value. Now open Post movement from the left rail. The quantity field exists there, between a From account and a To account, with the reason code already sitting in its error state. Then open Roles and read the second row from the bottom, where Set a stock quantity is Impossible across all six columns, Tenant Admin included.
Prototype code · runs in the demo above

An operator taps 1,192 into a handheld keypad. What actually gets stored isn't a corrected number, it's a movement: 12 units, tagged with a reason, an operator, a device, and two timestamps: when the device says it happened and when the server recorded it, usually a few seconds apart, and that gap is logged too, because a tamper-evident record can't be ordered by a clock the client controls. A second operator counts the same bin and gets 1,204. Both counts survive; the system doesn't quietly pick a winner, because the disagreement itself is the useful signal, and the queue of these gets ranked by money at risk, not by how recently they happened. Warehouses have dead zones and cold rooms that swallow signal, so instead of rejecting writes it can't verify, the system quarantines them: 27 movements currently sit pending rather than bounced, because a rejected write is an unknown unknown, which is worse than a delayed one.

A client's own statement shows the operator's bad news too: units under investigation and units awaiting reconciliation appear on their record rather than getting netted out of the total, because 'unaccounted for' isn't a state this system is willing to hide. Most tools, this project argues, would just print the clean number and leave it there.

Nothing here submits to a real backend yet: the database rules described above are specified and argued for on screen, not running, and three of six planned integrations are stubs. The thresholds are invented placeholders, explicitly marked for replacement once there's real data to test them against. One question stays open even in the project's own notes: reservations currently sit beside the ledger rather than inside it, and there's at least one case where an expired reservation silently stopped applying, an unrecorded state change the design hasn't solved yet.
