code wiki / _hdl_build / nx_auction_2ndchance.nx
nx_auction_2ndchance.nx source
↩ module page · 125 lines · 7030 B
1// nx_auction_2ndchance.nx -- MANHEIM-BUILD-L1: SECOND-CHANCE / POST-SALE NEGOTIATION (Manheim's "If-bid"
2// / 2nd-Chance Offer channel -- what happens to a lot that DOESN'T meet reserve), COMPOSED on the shared
3// nx_auction_core engine. Sovereign (nx_cc->nxasm, no gcc), pure integer-exact + deterministic.
4//
5// FLOW (genuinely distinct from the live-bidding channels -- this is a POST-auction step):
6// 1. settle the primary auction via core at_resolve (reusing out[6]=high_amount, out[7]=high_bidder --
7// a NO-SALE still has a high bidder to negotiate with).
8// 2. if the primary SOLD (high >= reserve) -> PRIMARY sale, no second chance needed.
9// 3. if the primary NO-SALE -> offer the lot to the high bidder at their bid; the seller ACCEPTS iff
10// that high bid >= seller_min_accept (a private floor below the public reserve) -> SECOND-CHANCE SALE
11// at the high bid; else NO-DEAL (seller holds the unit).
12// result codes: R_PRIMARY=1, R_2NDCHANCE=2, R_NODEAL=0. out[]: [result, price, winner]
13//
14// EXCEED axis (honest): turns dead NO-SALE inventory into deterministic, auditable post-sale matches at a
15// disclosed seller floor -- no opaque back-room "if" negotiation; the buyer pays exactly their standing high.
16//
17// GATE (self-validating): A a NO-SALE lot CONVERTS via second chance (high 950000 >= floor 940000);
18// B NO-DEAL (high 950000 < floor 970000, seller holds); C control = a primary SALE (high >= reserve)
19// BYPASSES second chance (result=PRIMARY, proving the channel only fires on NO-SALE). A broken rule
20// diverges a checked value -> verdict=RED. Evidence -> knowledge/status/auction_2ndchance.log.
21// license_tier: ORIGINAL
22import "nx_syscalls.nx"
23import "nx_auction_core.nx"
24const SC_MAGIC_900000: i64 = 900000
25const SC_MAGIC_925000: i64 = 925000
26const SC_MAGIC_950000: i64 = 950000
27const SC_MAGIC_25000: i64 = 25000
28const SC_MAGIC_1000000: i64 = 1000000
29const SC_MAGIC_940000: i64 = 940000
30const SC_MAGIC_970000: i64 = 970000
31const SC_MAGIC_1050000: i64 = 1050000
32
33const SC_LOG: *u8 = "knowledge/status/auction_2ndchance.log"
34const SC_NODEAL: i64 = 0
35const SC_PRIMARY: i64 = 1
36const SC_2NDCHANCE: i64 = 2
37
38func sc_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 sc_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// settle the primary auction (core) then apply the second-chance rule. writes [result, price, winner].
42func sc_resolve(opening: i64, increment: i64, reserve: i64, start: i64, end: i64, seller_min_accept: i64, bidder: *i64, amount: *i64, time: *i64, n: i64, out3: *i64) -> i64 {
43 let core: *i64 = sys_mmap(8 * 8) as *i64
44 at_resolve(opening, increment, reserve, start, end, 0, 0, bidder, amount, time, n, core)
45 let status: i64 = core[2]
46 let high: i64 = core[6]
47 let high_bidder: i64 = core[7]
48 if status == AT_SOLD {
49 out3[0] = SC_PRIMARY; out3[1] = core[1]; out3[2] = core[0] // primary sale stands, no 2nd chance
50 return 0
51 }
52 // primary NO-SALE -> second-chance offer to the standing high bidder
53 if high > 0 {
54 if high >= seller_min_accept {
55 out3[0] = SC_2NDCHANCE; out3[1] = high; out3[2] = high_bidder
56 return 0
57 }
58 }
59 out3[0] = SC_NODEAL; out3[1] = 0; out3[2] = 0
60 return 0
61}
62
63func main() -> i64 {
64 let bidder: *i64 = sys_mmap(8 * 16) as *i64
65 let amount: *i64 = sys_mmap(8 * 16) as *i64
66 let time: *i64 = sys_mmap(8 * 16) as *i64
67 let out3: *i64 = sys_mmap(8 * 4) as *i64
68
69 // shared listing: opening 900000, increment 25000, reserve 1000000, window [100,200]
70 // --- Scenario A: primary NO-SALE (top 950000 < reserve), seller floor 940000 -> SECOND-CHANCE SALE ---
71 bidder[0]=1; amount[0]=SC_MAGIC_900000; time[0]=110
72 bidder[1]=2; amount[1]=SC_MAGIC_925000; time[1]=120
73 bidder[2]=1; amount[2]=SC_MAGIC_950000; time[2]=140
74 sc_resolve(SC_MAGIC_900000, SC_MAGIC_25000, SC_MAGIC_1000000, 100, 200, SC_MAGIC_940000, bidder, amount, time, 3, out3)
75 let ar: i64 = out3[0]; let ap: i64 = out3[1]; let aw: i64 = out3[2]
76
77 // --- Scenario B: same NO-SALE, seller floor 970000 > high 950000 -> NO-DEAL (seller holds) ---
78 bidder[0]=1; amount[0]=SC_MAGIC_900000; time[0]=110
79 bidder[1]=2; amount[1]=SC_MAGIC_925000; time[1]=120
80 bidder[2]=1; amount[2]=SC_MAGIC_950000; time[2]=140
81 sc_resolve(SC_MAGIC_900000, SC_MAGIC_25000, SC_MAGIC_1000000, 100, 200, SC_MAGIC_970000, bidder, amount, time, 3, out3)
82 let br: i64 = out3[0]; let bp: i64 = out3[1]; let bw: i64 = out3[2]
83
84 // --- Control C: primary SALE (top 1050000 >= reserve) -> PRIMARY, second chance NOT invoked ---
85 bidder[0]=1; amount[0]=SC_MAGIC_900000; time[0]=110
86 bidder[1]=2; amount[1]=SC_MAGIC_1050000; time[1]=120
87 sc_resolve(SC_MAGIC_900000, SC_MAGIC_25000, SC_MAGIC_1000000, 100, 200, SC_MAGIC_940000, bidder, amount, time, 2, out3)
88 let cr: i64 = out3[0]; let cp: i64 = out3[1]; let cw: i64 = out3[2]
89
90 // --- assertions (tight, hand-computed) ---
91 var ok: i64 = 1
92 // A: SECOND-CHANCE sale to bidder 1 at the high bid 950000
93 if ar != SC_2NDCHANCE { ok = 0 }
94 if ap != SC_MAGIC_950000 { ok = 0 }
95 if aw != 1 { ok = 0 }
96 // B: NO-DEAL, no winner, no price (floor not met)
97 if br != SC_NODEAL { ok = 0 }
98 if bp != 0 { ok = 0 }
99 if bw != 0 { ok = 0 }
100 // C: PRIMARY sale to bidder 2 at 1050000 -- second chance bypassed
101 if cr != SC_PRIMARY { ok = 0 }
102 if cp != SC_MAGIC_1050000 { ok = 0 }
103 if cw != 2 { ok = 0 }
104 if cr == ar { ok = 0 } // primary-sale path MUST differ from the 2nd-chance path (rule-sensitivity)
105
106 sc_w(1, "SECONDCHANCEGATE engine=nx_auction_2ndchance A{result=" as *u8); sc_wn(1, ar)
107 sc_w(1, " price=" as *u8); sc_wn(1, ap); sc_w(1, " winner=" as *u8); sc_wn(1, aw)
108 sc_w(1, "} B{result=" as *u8); sc_wn(1, br); sc_w(1, " price=" as *u8); sc_wn(1, bp)
109 sc_w(1, "} C{result=" as *u8); sc_wn(1, cr); sc_w(1, " price=" as *u8); sc_wn(1, cp)
110 sc_w(1, " winner=" as *u8); sc_wn(1, cw); sc_w(1, "}" as *u8)
111 if ok == 1 { sc_w(1, " verdict=GREEN\n" as *u8) } else { sc_w(1, " verdict=RED\n" as *u8) }
112
113 let lf: i64 = sys_openat_append(SC_LOG, 420)
114 if lf >= 0 {
115 sc_w(lf, "SECONDCHANCEGATE engine=nx_auction_2ndchance A{result=" as *u8); sc_wn(lf, ar)
116 sc_w(lf, " price=" as *u8); sc_wn(lf, ap); sc_w(lf, " winner=" as *u8); sc_wn(lf, aw)
117 sc_w(lf, "} B{result=" as *u8); sc_wn(lf, br); sc_w(lf, "} C{result=" as *u8); sc_wn(lf, cr)
118 sc_w(lf, " price=" as *u8); sc_wn(lf, cp); sc_w(lf, "}" as *u8)
119 if ok == 1 { sc_w(lf, " verdict=GREEN\n" as *u8) } else { sc_w(lf, " verdict=RED\n" as *u8) }
120 sys_close(lf)
121 }
122
123 if ok == 1 { return 0 }
124 return 1
125}