BUILD NOTE

What this build does not know

The working specification carries thirty-seven numbered gaps, six of them blockers. Every one of them is on this page. All six blockers now carry an answer, and every one of those answers is a working decision by the platform owner rather than an opinion from counsel — they are recorded here as assumptions on exactly that footing. Nineteen carry a decision in all, and sixteen needed engineering rather than a decision and are built. Two are open again: GAP-12 and GAP-13, reopened on 2026-10-20 when the owner chose to pay facilities on payment rather than on clearance. The rule this codebase follows is that a gap is never silently resolved: where an answer was missing, the data model made room for it and the interface said so, rather than a plausible default being picked and carried on with.

Assumed — implemented, and flagged as an assumption

These are recommendations standing in for a missing decision. They are built, they work, and every one of them is a configuration value that can be changed the moment somebody decides differently — without touching a historical auction.

GapThe questionWhat this build assumes
GAP-01 Is a non-judicial sale of a tenant's goods lawful at all? Not the platform's question to answer, and the platform no longer takes any part in answering it. A self-storage agreement is in substance a lease and the tenant's goods fall under the landlord's tacit hypothec, which appears not to be enforceable by self-help — so what a facility may sell under is a matter for that facility and its own attorney. Bid Budi provides the venue and conducts the auction. On every unit it lists, a named person at the facility confirms that the facility has the legal authority to sell those contents and indemnifies Bid Budi against any claim arising from the sale; the platform records the confirmation, the name, the date and the exact wording agreed to, and a unit nobody has confirmed cannot be submitted. Until this was settled the platform went further: it held a legal-basis record on every auction — the basis type, the storage agreement, the arrears, the notice with proof of delivery, the redemption window — required what each basis type needed before a unit could be submitted or released, and staffed a queue to check it in. That is a platform taking a view on whether a sale is lawful, and one that refuses a sale on its paperwork has approved every sale it did not refuse. All of it is removed. The consequences are recorded rather than buried: the platform no longer holds the tenant's redemption window and no longer refuses to release or close a sale inside it, no longer holds the arrears and so no longer discloses an indicative tenant surplus on a settlement, and no longer holds a lien-holder confirmation, so clause 4.2 of the Rules of Auction now always states that none is recorded. Auctions released before this are frozen and are not rewritten.
GAP-02 Who is the auctioneer under CPA section 45? The platform is. It is the choice the build had already made everywhere else — the bidders' record is platform-held, the Rules of Auction are generated centrally, and the vendor roll export is gated at platform scope, so no other party could discharge the obligations the document imposes. The auctioneer is a configuration value, snapshotted at release, so an auction already published keeps the auctioneer it was published with whatever a later answer says. Auctions released before this was answered still read OUTSTANDING in their frozen document, because that is what was true when they ran.
GAP-03 Where does the defaulting tenant sit in this model? The surplus over arrears plus commission is the facility's obligation to its former tenant under its own storage agreement, not money this platform distributes. The facility is paid its whole share and the surplus is calculated and shown on its statement as an amount it may owe onwards. Nothing is posted to tenant_surplus and nothing should be — the platform has never held this money. What has changed with GAP-01 is the DISCLOSURE, not the duty: the platform no longer holds the arrears, the notice or the redemption window, so it no longer calculates the indicative surplus it used to show on a facility statement. That figure came from a number the facility typed about a debt between it and a person this platform has never identified, and publishing it implied a platform that had checked. The obligation is unchanged and it is the facility's. The tenant remains a data subject with no platform login, and since GAP-01 not even a pseudonymous reference is held.
GAP-04 Who holds buyer funds between payment and settlement? The platform does, and the position is accepted rather than open. PayFast pays into a single merchant account, so between a buyer paying and a facility being settled Bid Budi holds the bid and the cleaning deposit. The exposure is measured and aged on /admin/finance/custody every day instead of being carried quietly. What the ledger does not do is bank it: the cleaning deposit sits in a deposit_held account of its own and is never mixed into proceeds until the settlement passes it on to the facility (0062), and no posting depends on whose balance sheet the money sat on. A split-settlement provider — PayFast's own facility, or another PSP — drops in behind one class without a ledger entry changing, so this is reversible without touching the arithmetic.
GAP-05 VAT treatment of the bid, the commission and the deposit. VAT is a configurable rule, currently switched off, and it is driven by who is registered rather than by one platform-wide answer. The bid is VAT-INCLUSIVE — a buyer pays what they bid, and their arithmetic does not change depending on the facility they bid with. Where the facility is a registered vendor the tax is extracted from the hammer price and stays inside what it is paid, because it is theirs to remit and this platform is not their tax agent. Where Bid Budi is registered, output VAT on commission posts to its own vat_control account and is never counted as revenue; commission itself is charged on the amount excluding the facility's VAT, so registering does not increase what a facility pays. A buyer's registration drives no arithmetic at all — output VAT is a property of the supplier — so there is deliberately no switch for it. Every one of these is snapshotted at release. A buyer is issued an invoice for the goods on the facility's behalf, titled a tax invoice only where the facility was a registered vendor at the moment of supply, serially numbered per facility and frozen at issue; the cleaning deposit is not on it, because it is not consideration for the goods. Still outstanding: VAT on the listing fee, and the platform's own tax invoice to a facility for commission.
GAP-06 Does the "no reserve" model comply with the auction regulations? What the regulations restrict is the CLAIM, not the model. These auctions genuinely carry no reserve — auction.reserve_enabled is false and the schema has no reserve field to set — so the answer is to say so only where the platform is entitled to. Clause 4.2 of the Rules of Auction states plainly that no written confirmation from the lien holder is recorded and makes no claim either way. It was briefly rendered per auction — with a confirmation captured on the legal basis it stated there was no reserve and cited the reference — but that record went with GAP-01, so the platform has nothing to cite and says so. Until template v2 the clause asserted "There is no reserve on this auction" on every auction released, which is the assertion §6.7 says not to make unconfirmed; those documents are frozen at release and are not rewritten, and their own rules page says so.
GAP-07 Notice period and redemption cut-off undefined The platform takes no view on it, which is the same answer as GAP-01 and arrived with it. Bid Budi used to hold the tenant's redemption window on every auction and refuse to release or close a sale inside it. Deciding whether a tenant's window has run is deciding whether the sale is lawful, and a platform that refuses one sale on that basis has approved every sale it did not refuse. The facility warrants its authority to sell and indemnifies the platform; observing the notice period and the redemption cut-off is part of the authority it warranted. If a tenant redeems, the facility cancels the auction — which tells every bidder the sale is off, rather than handing the unit to one of them.
GAP-14 What may be charged to a buyer beyond the bid and the deposit Nothing. A buyer pays what they bid plus the cleaning fee, and there is no buyer's premium, no processing fee and nothing else on top — decided, not merely unbuilt. The fee engine enforces it rather than trusting the setting: a non-zero premium rate does not quietly start charging buyers, it takes down the auction page, the bid panel and the payment screen until somebody puts it back to zero. There is no premium account in the ledger and none is wanted.
GAP-15 A flat R500 deposit does not scale to the unit The facility sets it. By the owner's decision of 2026-10-20 (0062) the deposit is chosen by the facility on its own listing, between a configured floor and ceiling: blank keeps the platform standard, zero means no deposit, and out-of-range is refused rather than clamped. The facility is the party that knows the unit and is left with whatever is not cleared, and it is now also the party that keeps or returns the deposit, so it is the right one to size it. The figure is snapshotted at release so a buyer is charged what the listing said. Auctions released before this had their deposit set by the reviewer at release, and keep it.
GAP-17 A discrepancy is recorded but no remedy is defined Settled between the buyer and the facility. By the owner's decision of 2026-10-20 (0062), a unit that is not what it was photographed as is still logged at the joint opening, with a photograph where one was taken, and that record is the evidence both sides use — but Bid Budi refunds no part of the price of a completed sale and nets no remedy off the facility's payment. The facility either misrepresented the sale or something happened to the contents under its lock, and it answers to the buyer directly. Auctions released before 0062 keep the old mechanism, because their Rules of Auction promised it: platform staff may record a partial refund to the buyer, funded out of the facility's settlement, plus a configurable handling fee that posts to its own account, and a remedy larger than the facility is owed is refused.
GAP-24 The unit contents are the tenant's personal information The facility's responsibility where it is acting for the tenant, and it is told so at the moment it uploads. Documents, screens, labelled boxes and paperwork are all personal information under POPIA and no tenant has agreed to any of it being published. Bid Budi publishes what a facility uploads and does not review it for personal information, which is stated on the listing form rather than buried in terms — along with the one instruction that actually helps: photograph the unit, not the paperwork in it.
GAP-29 Risk of loss and insurance before collection The facility's, and it is told so on the screen that lists the window. From the moment a unit is sealed until a buyer has emptied it, goods somebody has already paid for sit under the facility's lock. Bid Budi does not insure them and does not carry the loss if they are damaged, destroyed or stolen in that window.
GAP-34 Restricted items are defined only in outline Identity documents, firearms and other restricted items do not pass to the purchaser — that much is the law and not a platform undertaking, and a buyer is entitled to read it before bidding rather than at a roller door. Dealing with them is the facility's own obligation under the law. Clause 5.3 used to promise that they were "dealt with under the platform's restricted-items process"; there was no such process and there never had been, so the clause now states the facility's duty instead. Documents frozen before that still carry the old promise and their rules page says so.
GAP-11 The 2-hour cascade produces unfair defaults Payment clock runs inside service hours (07:00–21:00), starts on notification delivery rather than auction close, cascaded awards must be accepted before their clock starts, and lapsed is a different state from defaulted. Only the original winner's non-payment counts as a default. The window is no longer fixed at two hours either: it is a configuration default with a floor and a ceiling, a facility may set its own per auction, and it is snapshotted at release like every other term.
GAP-19 Nothing defines what happens to a unit nobody bids on Auto-relist at a 20% lower opening bid, up to twice, then withdraw. A relist is a NEW auction with its own reference and its own snapshot.
GAP-22 Section 45 bid retraction versus a binding-bid model Retraction is permitted up to 30 minutes before close. The cut-off is configuration, snapshotted per auction, and the sentence the buyer reads is rendered from that snapshot rather than hard-coded.
GAP-23 Default charges likely exceed the 10% cap For auctions released before 0062, Bid Budi forfeits at most the lesser of the deposit and 10% of the purchase price: on a R2 000 unit the forfeiture is R200 and the balance is refunded. From 0062 (owner decision 2026-10-20) Bid Budi forfeits nothing — the deposit is passed on to the facility, which decides whether to refund it — so the platform applies no default charge for the cap to bound. Whether a facility keeping a deposit is itself held to the cap is a question for the facility and its attorney, and the platform does not enforce one on its behalf.
GAP-30 Every rule value is hard-coded in the vision Nothing is hard-coded. Every value is a config key, and the whole rule set is snapshotted onto the auction at release. A historical auction always renders the terms it was actually sold under.
GAP-31 Auction duration and anti-sniping undecided 7 days, with a bid inside the last 5 minutes extending the close by 5 minutes. Both are configuration and both are snapshotted.

Built — the specification asked, and it is done

These needed engineering rather than a decision. They are here because a register that lists only what is wrong is not a register: this page showed six problems and seven assumptions for a long time while all of these had quietly been closed.

GapThe questionWhat the build does
GAP-08 A tenant redeems after payment but before collection A unit that has been awarded cannot be cancelled from the console, and the refusal says why: what a buyer is owed when a sale is taken back from them is not decided, so the platform escalates rather than half-reversing a sale.
GAP-09 Bidders' record and identity verification Registration, identity capture and verification before a first bid, with IP logging per bid and bidder numbers per auction.
GAP-10 Rules of Auction not in scope A versioned template with per-auction substitution, rendered once and frozen onto the auction at release so a historical sale can be reproduced exactly.
GAP-16 Refunds assumed a card; no partial-refund model The refund destination is a property of the payment method, captured at selection time and required before a bankless method is accepted. Partial refunds are capped against both the payment and the deposit held.
GAP-20 Notification is on the legal critical path The payment clock starts on delivery rather than on send, delivery is recorded per notification, and an award notice is mandatory. The second mandatory channel it asks for is answered by WhatsApp rather than SMS, and that half is still being built — see GAP-41. Channel 'sms' remains a log line and is now legacy.
GAP-21 Public bidders' record versus POPIA No public bidder list exists. Bidders appear by screen name (their first name unless they choose another); full names appear only in a platform-scoped export to somebody holding the permission to see them.
GAP-25 Second-Hand Goods Act dealer registration Dealer status and registration number are captured on the bidders' record, where a buyer is told plainly that repeat resale carries its own SAPS duties.
GAP-26 Photograph integrity and conflict of interest Capture window, minimum angles, distance from the branch, device and time recorded per photograph, with a SHA-256 hash taken on arrival and originals never edited.
GAP-27 Platform review does not scale nationally A review queue with the decision, the reasons and the reviewer recorded. A trusted tier with sampled review is the next thing to build.
GAP-28 No on-platform messaging; audit hole and disintermediation A per-auction thread between the buyer and the facility, append-only and retained, with both sides notified. Disintermediation is measured rather than blocked: the first time facility staff see a buyer's contact details it is recorded once, with a name.
GAP-32 A buyer sends a driver An authorised collector is nominated against the collection and checked at the door.
GAP-33 The facility representative is not a verified user The joint opening records a named platform user holding the collection permission, not whoever was on shift.
GAP-35 Proxy bidding under concurrency Serialised per auction: a transaction, a row lock on the auction, an idempotency key per submission, and proxy resolution ordered by bid id so it replays deterministically.
GAP-36 Facility staff bidding on their own units A hard block on self-bidding, checked in the domain rather than the screen.
GAP-37 A facility cancels and sells privately after seeing bids Cancelling is a platform act with a reason recorded against the person who asked, and every bidder is told the sale is off.
GAP-38 No reputation or rating in either direction Both directions, computed rather than typed. A buyer's reliability is read off four things the platform already recorded for other reasons — winning a unit and not paying, paying late, missing a booked collection, losing the deposit at clearance — and a facility's clearance record off the two discretionary decisions it makes about every buyer it deals with: whether the unit is clear, and whether the deposit comes back. Nobody rates anybody, so there is no review to moderate, nothing to game by asking nicely and nothing to retaliate with after a clearance goes badly. Signed-in buyers see a facility's record on its auction pages; facility staff see a buyer's only on a collection they are party to, and the reading is itself audited. Below a configured number of completed dealings there is no score at all rather than a poor one, because one forfeited deposit out of one clearance is arithmetically nought out of a hundred and says nothing true about anybody. Discrepancies logged at the joint opening are shown beside a facility's score and deliberately never folded into it — facility staff raise those against their own employer, and a rating that fell every time they told the truth would reward the facility that quietly stopped logging them. A buyer sees their own reliability on their account, with the same breakdown a facility gets and a plain sentence saying when a facility can read it — a derived judgement shown to a third party and withheld from the person it describes is the arrangement POPIA is least comfortable with, and the answer is that they see it rather than that the facility does not. One thing is worth naming as unfinished: the weights and the two minimums are configuration, and are working defaults nobody has yet tested against real data.

Still open — nobody has answered these

Stated as plainly as the answered ones. Where a decision is missing the code refuses rather than picking a plausible default, or says out loud which choice it is running on.

GAP-12 UNRESOLVED

Settling before delivery likely conflicts with the regulations

Reopened by the owner's decision of 2026-10-20 (0062). settlement.trigger is now "payment": a facility becomes payable settlement.delay_days after the buyer's payment, with the cleaning deposit passed on to it, rather than after clearance. The register's concern — that the auction regulations restrict commission on movable goods until delivery — has not been answered by counsel; the owner has chosen to pay earlier anyway. The setting still offers "clearance", and putting it back changes when a facility is paid without changing who refunds the deposit. Auctions released before 0062 are still paid on clearance.

GAP-13 UNRESOLVED

Chargeback exposure after settlement

Reopened with GAP-12. It was closed because a facility was only paid after clearance, so a buyer's chargeback always landed on money the platform still held. Paying on payment plus settlement.delay_days means a chargeback raised after that can now land on money already paid out. No reserve is held against it. Auctions released before 0062 are still paid on clearance and keep the old protection.

GAP-41 UNRESOLVED

Can somebody choose how the platform reaches them?

Answered and switched off. Every role can choose email, WhatsApp or both on their account, a mobile number has to be confirmed with a code before it can carry a notice, and exactly one message per notice is the notice of record whose delivery starts a payment clock — the email wherever email is on, because the email carries the full text while a WhatsApp message is a paraphrase inside a template WhatsApp approved. The transport, the four templates and the delivery webhook are built. What is missing is outside this repository: a Meta business account and its approvals. Until then nobody can select WhatsApp and every notice goes by email, which is also what happens to any notice with no approved WhatsApp version.

Not legal advice. The specification's legal sections summarise publicly available sources and are flagged for a South African attorney with auction and consumer-law experience. Treat every legal statement as a question to put to counsel, not an answer.