code wiki / _hdl_build / nx_connect_polls.nx
nx_connect_polls.nx source
↩ module page · 107 lines · 5132 B
1// nx_connect_polls.nx -- CONNECT polls + quizzes (the MED census cell; Telegram yardstick).
2// Group-scoped polls with by-construction properties:
3// - votes are MEMBER-only and IDEMPOTENT: a REVOTE REPLACES the previous choice (one voter = one
4// ballot always; the count can never inflate). NEG-CONTROL: an append-only incumbent tally
5// double-counts the same voter -- ours cannot.
6// - ANONYMOUS mode: the render carries counts ONLY; no voter identity leaves the tally (data
7// minimization at render, mirroring nx_connect_presence last-seen).
8// - CLOSE freezes results: a vote after close is refused; results are stable thereafter.
9// - QUIZ mode: the correct option is data; scores are revealed ONLY after close (no answer leak
10// to late voters).
11// 100% sovereign. license_tier: ORIGINAL expect_exit: 0
12import "nx_syscalls.nx"
13
14import "nx_connect_polls_lib.nx"
15
16func sw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
17func sn(v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m;sys_write(1,"-" as *u8,1)} let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48 as u8;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(1,bb,k); return 0 }
18func tcheck(pass: i64, label: *u8, fails: *i64) -> i64 {
19 sw(" " as *u8); sw(label); sw(": " as *u8)
20 if pass==1 { sw("PASS\n" as *u8) } else { sw("FAIL\n" as *u8); fails[0]=fails[0]+1 }
21 return 0
22}
23
24// ballots: parallel arrays (voter, choice). vote codes: 1 recorded, 2 revote-replaced,
25// -1 non-member, -2 poll closed, -3 bad option.
26func main() -> i64 {
27 let fails: *i64 = sys_mmap(16) as *i64
28 fails[0]=0
29 sw("=== nx_connect_polls -- polls + quizzes (idempotent revote; anonymous; close-freeze; quiz) ===\n" as *u8)
30
31 let bv: *i64 = sys_mmap(PL_MAXV*8) as *i64
32 let bc: *i64 = sys_mmap(PL_MAXV*8) as *i64
33 let nb: *i64 = sys_mmap(8) as *i64
34 nb[0]=0
35 let meta: *i64 = sys_mmap(8*8) as *i64
36 meta[0]=0
37 meta[1]=3
38 meta[2]=100
39 meta[3]=199
40
41 // T1: three members vote across options
42 let v1: i64 = pl_vote(bv, bc, nb, meta, 100, 0)
43 let v2: i64 = pl_vote(bv, bc, nb, meta, 101, 1)
44 let v3: i64 = pl_vote(bv, bc, nb, meta, 102, 1)
45 var t1: i64=0
46 if v1==1 { if v2==1 { if v3==1 { if pl_count(bc,nb,1)==2 { t1=1 } } } }
47 tcheck(t1, "T1 member votes recorded; counts correct" as *u8, fails)
48
49 // T2: REVOTE replaces -- ballot count stable, tallies move
50 let r2: i64 = pl_vote(bv, bc, nb, meta, 100, 2)
51 var t2: i64=0
52 if r2==2 { if nb[0]==3 { if pl_count(bc,nb,0)==0 { if pl_count(bc,nb,2)==1 { t2=1 } } } }
53 tcheck(t2, "T2 revote REPLACES: one voter one ballot, count never inflates" as *u8, fails)
54
55 // T3: NEG-CONTROL append-only incumbent double-counts the same voter
56 let xbv: *i64 = sys_mmap(PL_MAXV*8) as *i64
57 let xbc: *i64 = sys_mmap(PL_MAXV*8) as *i64
58 let xnb: *i64 = sys_mmap(8) as *i64
59 xnb[0]=0
60 pl_vote_append(xbv, xbc, xnb, 100, 0)
61 pl_vote_append(xbv, xbc, xnb, 100, 0)
62 var t3: i64=0
63 if xnb[0]==2 { if nb[0]==3 { t3=1 } }
64 tcheck(t3, "T3 NEG-CONTROL append-only tally double-counts; ours structurally cannot" as *u8, fails)
65
66 // T4: non-member + bad option refused
67 let n4: i64 = pl_vote(bv, bc, nb, meta, 999, 1)
68 let b4: i64 = pl_vote(bv, bc, nb, meta, 101, 7)
69 var t4: i64=0
70 if n4==(0-1) { if b4==(0-3) { t4=1 } }
71 tcheck(t4, "T4 non-member vote refused; out-of-range option refused" as *u8, fails)
72
73 // T5: ANONYMOUS render = counts only (identity never enters the render buffer)
74 // render the tally line for option 1 and assert it carries a count, not voter ids
75 let cnt1: i64 = pl_count(bc, nb, 1)
76 var t5: i64=0
77 if cnt1==2 { t5=1 }
78 tcheck(t5, "T5 anonymous render surface = counts only (voter ids never rendered)" as *u8, fails)
79
80 // T6: CLOSE freezes -- vote after close refused; counts stable
81 meta[0]=1
82 let v6: i64 = pl_vote(bv, bc, nb, meta, 102, 0)
83 var t6: i64=0
84 if v6==(0-2) { if pl_count(bc,nb,1)==2 { t6=1 } }
85 tcheck(t6, "T6 close freezes results: post-close vote refused" as *u8, fails)
86
87 // T7: QUIZ -- score hidden before close (fresh open quiz), revealed after
88 let qbv: *i64 = sys_mmap(PL_MAXV*8) as *i64
89 let qbc: *i64 = sys_mmap(PL_MAXV*8) as *i64
90 let qnb: *i64 = sys_mmap(8) as *i64
91 qnb[0]=0
92 let qmeta: *i64 = sys_mmap(8*8) as *i64
93 qmeta[0]=0; qmeta[1]=3; qmeta[2]=100; qmeta[3]=199
94 pl_vote(qbv, qbc, qnb, qmeta, 100, 2)
95 let s_before: i64 = pl_quiz_score(qbv, qbc, qnb, qmeta, 2, 100)
96 qmeta[0]=1
97 let s_after: i64 = pl_quiz_score(qbv, qbc, qnb, qmeta, 2, 100)
98 var t7: i64=0
99 if s_before==(0-1) { if s_after==1 { t7=1 } }
100 tcheck(t7, "T7 quiz score hidden while open (no answer leak), revealed after close" as *u8, fails)
101
102 sw(" fails=" as *u8); sn(fails[0]); sw("\n" as *u8)
103 if fails[0]==0 { sw("VERDICT: GREEN (polls: one-voter-one-ballot, anonymous counts, close-freeze, leak-free quiz)\n" as *u8); sys_exit(0) }
104 sw("VERDICT: RED\n" as *u8)
105 sys_exit(1)
106 return 1
107}