code wiki / _hdl_build / nx_auction_timed.nx
nx_auction_timed.nx source
↩ module page · 129 lines · 8130 B
1// nx_auction_timed.nx -- MANHEIM-BUILD-L1: the TIMED WHOLESALE-AUCTION ENGINE, the defining
2// marketplace primitive of a vehicle remarketing exchange (Manheim Timed Sales / OVE). Sovereign
3// (nx_cc->nxasm, no gcc), pure integer-exact + deterministic -- the EXCEED axis vs opaque proprietary
4// auction engines: every bid's accept/reject and the final settlement are a REPRODUCIBLE verdict
5// (auditable), and the anti-snipe end-extension is a DETERMINISTIC fairness rule, not a human gavel.
6//
7// MODEL (all money in integer cents, all time in integer ticks):
8// listing = {opening, increment, reserve, start, end, snipe_window, extension}
9// bids = parallel arrays bidder[]/amount[]/time[], GIVEN IN TIME ORDER (the run-list is ordered).
10// rules (at_resolve):
11// * a bid is VALID iff start <= t <= effective_end AND amount >= required-min, where
12// required-min = (no high bid yet ? opening : high + increment).
13// * an accepted bid sets the new high (amount, bidder).
14// * ANTI-SNIPE: an accepted bid landing within snipe_window of the close EXTENDS the close to
15// t + extension (gives other dealers a fair chance -- kills last-tick sniping deterministically).
16// * at close: SOLD to the high bidder iff high >= reserve, else NO-SALE (reserve not met).
17// outputs via out[6]: [winner_bidder, winning_price, status(1=SOLD/0=NOSALE), final_end, accepted, rejected]
18//
19// main() is the SELF-VALIDATING GATE: two hand-computed scenarios with TIGHT expected values --
20// (A) a sale where a 195-tick bid extends the 200-tick close to 225, letting a 215-tick bid win
21// (proves anti-snipe: WITHOUT extension that bid is after-close and a different bidder wins);
22// (B) a no-sale where the top bid is below reserve.
23// Plus reject controls (below-increment + after-close bids MUST be rejected). A broken rule diverges
24// a checked value -> verdict=RED. Evidence -> knowledge/status/auction_timed.log. license_tier: ORIGINAL
25import "nx_syscalls.nx"
26import "nx_auction_core.nx"
27const AT_MAGIC_900000: i64 = 900000
28const AT_MAGIC_925000: i64 = 925000
29const AT_MAGIC_930000: i64 = 930000
30const AT_MAGIC_950000: i64 = 950000
31const AT_MAGIC_1000000: i64 = 1000000
32const AT_MAGIC_1025000: i64 = 1025000
33const AT_MAGIC_1030000: i64 = 1030000
34const AT_MAGIC_25000: i64 = 25000
35
36const AT_LOG: *u8 = "knowledge/status/auction_timed.log"
37
38func at_w(fd: i64, s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(fd, s, n); return 0 }
39func at_wn(fd: i64, v: i64) -> i64 { let bb: *u8 = sys_mmap(28); var m: i64=v; if m<0 {m=0-m; sys_write(fd,"-" as *u8,1)}; let t: *u8 = sys_mmap(28); var k: i64=0; if m==0 {t[0]=48;k=1}; while m>0 {t[k]=(48+(m%10)) as u8; m=m/10; k=k+1}; var i: i64=0; while i<k {bb[i]=t[k-1-i]; i=i+1}; sys_write(fd, bb, k); return 0 }
40
41// the settlement engine at_resolve + AT_SOLD/AT_NOSALE now live in nx_auction_core (DRY: shared by
42// every auction channel). This organ is the TIMED-SALE gate that proves the core via tight scenarios.
43func main() -> i64 {
44 let bidder: *i64 = sys_mmap(8 * 16) as *i64
45 let amount: *i64 = sys_mmap(8 * 16) as *i64
46 let time: *i64 = sys_mmap(8 * 16) as *i64
47 let out: *i64 = sys_mmap(8 * 8) as *i64
48
49 // --- Scenario A: anti-snipe sale (opening 900000, incr 25000, reserve 1000000, [100,200], snipe 10, ext 30) ---
50 // bids in time order: A=1, B=2
51 bidder[0]=1; amount[0]=AT_MAGIC_900000; time[0]=110 // accept high=AT_MAGIC_900000 A
52 bidder[1]=2; amount[1]=AT_MAGIC_925000; time[1]=120 // accept high=AT_MAGIC_925000 B
53 bidder[2]=1; amount[2]=AT_MAGIC_930000; time[2]=130 // REJECT (min AT_MAGIC_950000)
54 bidder[3]=1; amount[3]=AT_MAGIC_950000; time[3]=140 // accept high=AT_MAGIC_950000 A
55 bidder[4]=2; amount[4]=AT_MAGIC_1000000; time[4]=195 // accept high=AT_MAGIC_1000000 B; within snipe -> extend end to 225
56 bidder[5]=1; amount[5]=AT_MAGIC_1025000; time[5]=215 // accept high=AT_MAGIC_1025000 A (only valid BECAUSE of extension)
57 bidder[6]=2; amount[6]=AT_MAGIC_1030000; time[6]=230 // REJECT (after extended close 225)
58 at_resolve(AT_MAGIC_900000, AT_MAGIC_25000, AT_MAGIC_1000000, 100, 200, 10, 30, bidder, amount, time, 7, out)
59 let aw: i64 = out[0]; let ap: i64 = out[1]; let as_: i64 = out[2]; let ae: i64 = out[3]; let aa: i64 = out[4]; let ar: i64 = out[5]
60
61 // --- Control C: SAME bids, anti-snipe DISABLED (snipe_window=0). The outcome MUST differ from A
62 // (the 215-tick bid is now after the un-extended 200 close -> bidder 2 wins at 1000000).
63 // Proves the engine RESPONDS to its rules (no constant outputs) + that anti-snipe is material. ---
64 bidder[0]=1; amount[0]=AT_MAGIC_900000; time[0]=110
65 bidder[1]=2; amount[1]=AT_MAGIC_925000; time[1]=120
66 bidder[2]=1; amount[2]=AT_MAGIC_930000; time[2]=130
67 bidder[3]=1; amount[3]=AT_MAGIC_950000; time[3]=140
68 bidder[4]=2; amount[4]=AT_MAGIC_1000000; time[4]=195
69 bidder[5]=1; amount[5]=AT_MAGIC_1025000; time[5]=215
70 bidder[6]=2; amount[6]=AT_MAGIC_1030000; time[6]=230
71 at_resolve(AT_MAGIC_900000, AT_MAGIC_25000, AT_MAGIC_1000000, 100, 200, 0, 30, bidder, amount, time, 7, out)
72 let cw: i64 = out[0]; let cp: i64 = out[1]; let ce: i64 = out[3]
73
74 // --- Scenario B: no-sale (same listing, top bid below reserve) ---
75 bidder[0]=1; amount[0]=AT_MAGIC_900000; time[0]=110 // accept
76 bidder[1]=2; amount[1]=AT_MAGIC_925000; time[1]=120 // accept
77 bidder[2]=1; amount[2]=AT_MAGIC_950000; time[2]=140 // accept high=AT_MAGIC_950000 < reserve AT_MAGIC_1000000
78 at_resolve(AT_MAGIC_900000, AT_MAGIC_25000, AT_MAGIC_1000000, 100, 200, 10, 30, bidder, amount, time, 3, out)
79 let bw: i64 = out[0]; let bp: i64 = out[1]; let bs: i64 = out[2]; let be: i64 = out[3]; let ba2: i64 = out[4]; let br: i64 = out[5]
80
81 // --- assertions (tight, hand-computed) ---
82 var ok: i64 = 1
83 // A: SOLD to bidder 1 at 1025000, close extended to 225, 5 accepted / 2 rejected
84 if aw != 1 { ok = 0 }
85 if ap != AT_MAGIC_1025000 { ok = 0 }
86 if as_ != AT_SOLD { ok = 0 }
87 if ae != 225 { ok = 0 }
88 if aa != 5 { ok = 0 }
89 if ar != 2 { ok = 0 }
90 // B: NO-SALE, no winner, close NOT extended (no late bid), 3 accepted / 0 rejected
91 if bw != 0 { ok = 0 }
92 if bs != AT_NOSALE { ok = 0 }
93 if be != 200 { ok = 0 }
94 if ba2 != 3 { ok = 0 }
95 if br != 0 { ok = 0 }
96 // C (neg control): anti-snipe OFF flips the winner -- proves rule-sensitivity (not constant output)
97 if cw != 2 { ok = 0 }
98 if cp != AT_MAGIC_1000000 { ok = 0 }
99 if ce != 200 { ok = 0 }
100 if cw == aw { ok = 0 } // the control MUST differ from the positive scenario, else the gate is vacuous
101
102 at_w(1, "AUCTIONGATE engine=nx_auction_timed scenarioA winner=" as *u8); at_wn(1, aw)
103 at_w(1, " price=" as *u8); at_wn(1, ap)
104 at_w(1, " status=" as *u8); at_wn(1, as_)
105 at_w(1, " end=" as *u8); at_wn(1, ae)
106 at_w(1, " accepted=" as *u8); at_wn(1, aa)
107 at_w(1, " rejected=" as *u8); at_wn(1, ar)
108 at_w(1, " | scenarioB winner=" as *u8); at_wn(1, bw)
109 at_w(1, " status=" as *u8); at_wn(1, bs)
110 at_w(1, " end=" as *u8); at_wn(1, be)
111 at_w(1, " | ctrlC(no-snipe) winner=" as *u8); at_wn(1, cw)
112 at_w(1, " price=" as *u8); at_wn(1, cp)
113 at_w(1, " end=" as *u8); at_wn(1, ce)
114 if ok == 1 { at_w(1, " verdict=GREEN\n" as *u8) } else { at_w(1, " verdict=RED\n" as *u8) }
115
116 let lf: i64 = sys_openat_append(AT_LOG, 420)
117 if lf >= 0 {
118 at_w(lf, "AUCTIONGATE engine=nx_auction_timed A{winner=" as *u8); at_wn(lf, aw)
119 at_w(lf, " price=" as *u8); at_wn(lf, ap); at_w(lf, " status=" as *u8); at_wn(lf, as_)
120 at_w(lf, " end=" as *u8); at_wn(lf, ae); at_w(lf, " acc=" as *u8); at_wn(lf, aa)
121 at_w(lf, " rej=" as *u8); at_wn(lf, ar); at_w(lf, "} B{winner=" as *u8); at_wn(lf, bw)
122 at_w(lf, " status=" as *u8); at_wn(lf, bs); at_w(lf, " end=" as *u8); at_wn(lf, be); at_w(lf, "}" as *u8)
123 if ok == 1 { at_w(lf, " verdict=GREEN\n" as *u8) } else { at_w(lf, " verdict=RED\n" as *u8) }
124 sys_close(lf)
125 }
126
127 if ok == 1 { return 0 }
128 return 1
129}