nx_twincard.nx source
↩ module page · 199 lines · 11221 B
1// nx_twincard.nx -- CLI over nx_twincard_lib (aesthetictwin AT23, 2026-09-16): the twin card the operator asked for, "more
2// comprehensive than the illusion cards" -- and unlike those, every value carries its side, unit, method and source, and the card
3// prints how much of itself is still eyeball and how many of its rulers exist.
4// nx_twincard axes -> the sections the schema declares (face from the canon) with their value counts, and the
5// RULER CENSUS: every ruler row judged by the estate's one symbol ruler (present/absent/unjudged)
6// nx_twincard check <slug> -> validate knowledge/twincard/<slug>.card: every refusal named; coverage per section;
7// method partition (measured + observed + declared + generated = valid); completed L/R pairs
8// nx_twincard new <slug> <display> <class> <sex> <licence> -> write a header-only card (refuses to clobber an existing card)
9// exit: 0 ok | 2 usage | 3 schema or canon unreadable | 4 no such card | 6 card refused (defects named) | 7 card exists
10// license_tier: ORIGINAL No hw writes (Rule 26).
11import "nx_syscalls.nx"
12import "nx_twincard_lib.nx"
13
14const TCC_EXIT_USAGE: i64 = 2
15const TCC_EXIT_SCHEMA: i64 = 3
16const TCC_EXIT_NOCARD: i64 = 4
17const TCC_EXIT_REFUSED: i64 = 6
18const TCC_EXIT_EXISTS: i64 = 7
19const TCC_ARGC_NEW: i64 = 7
20const TCC_A_SLUG: i64 = 2
21const TCC_A_DISPLAY: i64 = 3
22const TCC_A_CLASS: i64 = 4
23const TCC_A_SEX: i64 = 5
24const TCC_A_LIC: i64 = 6
25const TCC_CENSUS_N: i64 = 4
26
27func tcc_usage() -> i64 {
28 ri_puts("usage: nx_twincard axes | check <slug> | new <slug> <display> <class> <sex> <licence> -- schema knowledge/twincard.axes, canon knowledge/facecanon.conf, cards knowledge/twincard/<slug>.card\n" as *u8)
29 return TCC_EXIT_USAGE
30}
31// one line per section (schema sections, then face from the canon); tot[0] = declared values, tot[1] = filled values
32func tcc_coverage(schema: *u8, sn: i64, canon: *u8, kn: i64, card: *u8, cn: i64, tot: *i64) -> i64 {
33 let list: *u8 = sys_mmap(TC_LISTB)
34 let count: i64 = tc_sections(schema, sn, list, TC_LISTB)
35 tot[0] = 0
36 tot[1] = 0
37 var k: i64 = 0
38 while k <= count {
39 var s: *u8 = TC_FACE
40 if k < count { s = tc_list_at(list, k) }
41 let d: i64 = tc_declared_count(schema, sn, canon, kn, s)
42 var f: i64 = 0
43 if cn > 0 { f = tc_filled_count(card, cn, schema, sn, canon, kn, s) }
44 ri_puts("TWINCARD section=" as *u8); ri_puts(s)
45 ri_puts(" declared=" as *u8); ri_putn(d)
46 ri_puts(" filled=" as *u8); ri_putn(f)
47 ri_puts(" permil=" as *u8); ri_putn(tc_permil(f, d))
48 ri_puts("\n" as *u8)
49 tot[0] = tot[0] + d
50 tot[1] = tot[1] + f
51 k = k + 1
52 }
53 return count + 1
54}
55func tcc_rulers(schema: *u8, sn: i64) -> i64 {
56 let cen: *i64 = sys_mmap(TCC_CENSUS_N * RI_I64) as *i64
57 tc_ruler_census(schema, sn, cen)
58 ri_puts("TWINCARD rulers=" as *u8); ri_putn(cen[0])
59 ri_puts(" present=" as *u8); ri_putn(cen[1])
60 ri_puts(" absent=" as *u8); ri_putn(cen[2])
61 ri_puts(" unjudged=" as *u8); ri_putn(cen[3])
62 ri_puts(" (present = the symbol is declared in the named organ today; absent = the organ exists and lacks it; unjudged = no such organ file at the path or under buildroot/, i.e. a build contract with its name chosen)\n" as *u8)
63 return cen[0]
64}
65// every declared axis must have a ruler: the unruled ones are printed as a worklist before the summary line
66func tcc_ruler_coverage(schema: *u8, sn: i64, canon: *u8, kn: i64) -> i64 {
67 let cov: *i64 = sys_mmap(TCC_CENSUS_N * RI_I64) as *i64
68 tc_ruler_coverage(schema, sn, canon, kn, 1, cov)
69 ri_puts("TWINCARD ruler-coverage axes=" as *u8); ri_putn(cov[0])
70 ri_puts(" ruled=" as *u8); ri_putn(cov[1])
71 ri_puts(" unruled=" as *u8); ri_putn(cov[2])
72 ri_puts(" permil=" as *u8); ri_putn(tc_permil(cov[1], cov[0]))
73 ri_puts(" (an axis is ruled when a ruler row names its measurer, exactly or through its section wildcard; the census above says which of those measurers exist)\n" as *u8)
74 return cov[2]
75}
76func tcc_check(schema: *u8, sn: i64, canon: *u8, kn: i64, slug: *u8) -> i64 {
77 let path: *u8 = sys_mmap(RI_PATHB)
78 tc_card_path(slug, path)
79 let lenp: *i64 = sys_mmap(RI_I64) as *i64
80 let card: *u8 = ri_load(path, lenp)
81 if lenp[0] <= 0 { ri_puts("TWINCARD check slug=" as *u8); ri_puts(slug); ri_puts(" verdict=NO-SUCH-CARD path=" as *u8); ri_puts(path); ri_puts("\n" as *u8); return TCC_EXIT_NOCARD }
82 let cn: i64 = lenp[0]
83 let rep: *i64 = sys_mmap(TC_R_N * RI_I64) as *i64
84 let bad: *u8 = sys_mmap(RI_ROWB)
85 let defects: i64 = tc_validate(card, cn, schema, sn, canon, kn, rep, bad)
86 ri_puts("TWINCARD check slug=" as *u8); ri_puts(slug)
87 ri_puts(" cards=" as *u8); ri_putn(rep[TC_R_CARDS])
88 ri_puts(" header=" as *u8); ri_putn(rep[TC_R_HEADER])
89 ri_puts(" axes=" as *u8); ri_putn(rep[TC_R_AXES])
90 ri_puts(" valid=" as *u8); ri_putn(rep[TC_R_VALID])
91 ri_puts(" undeclared=" as *u8); ri_putn(rep[TC_R_UNDECLARED])
92 ri_puts(" range=" as *u8); ri_putn(rep[TC_R_RANGE])
93 ri_puts(" method=" as *u8); ri_putn(rep[TC_R_METHOD])
94 ri_puts(" classword=" as *u8); ri_putn(rep[TC_R_CLASSWORD])
95 ri_puts(" side=" as *u8); ri_putn(rep[TC_R_SIDE])
96 ri_puts(" dup=" as *u8); ri_putn(rep[TC_R_DUP])
97 ri_puts(" features=" as *u8); ri_putn(rep[TC_R_FEATURES])
98 ri_puts(" badfeature=" as *u8); ri_putn(rep[TC_R_BADFEATURE])
99 ri_puts(" refs=" as *u8); ri_putn(rep[TC_R_REFS])
100 ri_puts(" badref=" as *u8); ri_putn(rep[TC_R_BADREF])
101 ri_puts(" shots=" as *u8); ri_putn(rep[TC_R_SHOTS])
102 ri_puts(" badshot=" as *u8); ri_putn(rep[TC_R_BADSHOT])
103 ri_puts("\n" as *u8)
104 let msum: i64 = rep[TC_R_MEASURED] + rep[TC_R_OBSERVED] + rep[TC_R_DECLARED] + rep[TC_R_GENERATED]
105 ri_puts("TWINCARD methods measured=" as *u8); ri_putn(rep[TC_R_MEASURED])
106 ri_puts(" observed=" as *u8); ri_putn(rep[TC_R_OBSERVED])
107 ri_puts(" declared=" as *u8); ri_putn(rep[TC_R_DECLARED])
108 ri_puts(" generated=" as *u8); ri_putn(rep[TC_R_GENERATED])
109 ri_puts(" sum=" as *u8); ri_putn(msum)
110 ri_puts(" valid=" as *u8); ri_putn(rep[TC_R_VALID])
111 ri_puts(" (the four methods partition the valid rows; measured is the only class above eyeball evidence)\n" as *u8)
112 let pairs: *i64 = sys_mmap(RI_I64) as *i64
113 let done: i64 = tc_pairs_complete(card, cn, schema, sn, pairs)
114 ri_puts("TWINCARD pairs declared=" as *u8); ri_putn(pairs[0])
115 ri_puts(" complete=" as *u8); ri_putn(done)
116 ri_puts(" (a pair is complete when both a left and a right row exist; left-right asymmetry is recordable only there)\n" as *u8)
117 let tot: *i64 = sys_mmap(TC_POS_N * RI_I64) as *i64
118 tcc_coverage(schema, sn, canon, kn, card, cn, tot)
119 ri_puts("TWINCARD coverage declared=" as *u8); ri_putn(tot[0])
120 ri_puts(" filled=" as *u8); ri_putn(tot[1])
121 ri_puts(" permil=" as *u8); ri_putn(tc_permil(tot[1], tot[0]))
122 ri_puts("\n" as *u8)
123 if defects > 0 {
124 ri_puts("TWINCARD verdict=REFUSED defects=" as *u8); ri_putn(defects)
125 ri_puts(" first=" as *u8); ri_puts(bad)
126 ri_puts(" -- refused by name: an undeclared axis (a group label is not an axis), a value outside its band, a class word not declared, a method outside measured/observed/declared/generated, a side that contradicts the pairing, a duplicate axis-and-side, a feature of unknown kind or region or outside its chart, a shot naming no ref, a malformed ref or header\n" as *u8)
127 return TCC_EXIT_REFUSED
128 }
129 ri_puts("TWINCARD verdict=OK\n" as *u8)
130 return 0
131}
132func tcc_new(argv: *i64) -> i64 {
133 let slug: *u8 = argv[TCC_A_SLUG] as *u8
134 let display: *u8 = argv[TCC_A_DISPLAY] as *u8
135 let cls: *u8 = argv[TCC_A_CLASS] as *u8
136 let sex: *u8 = argv[TCC_A_SEX] as *u8
137 let lic: *u8 = argv[TCC_A_LIC] as *u8
138 var okw: i64 = tc_word_in(TC_CLASSES, cls)
139 if tc_word_in(TC_SEXES, sex) == 0 { okw = 0 }
140 if tc_word_in(TC_LICENCES, lic) == 0 { okw = 0 }
141 if okw == 0 { ri_puts("TWINCARD new verdict=REFUSED class must be one of real anime fantasy synth, sex one of F M X, licence one of REVIEW SHIP_OK REFUSED\n" as *u8); return TCC_EXIT_USAGE }
142 let path: *u8 = sys_mmap(RI_PATHB)
143 tc_card_path(slug, path)
144 let lenp: *i64 = sys_mmap(RI_I64) as *i64
145 ri_load(path, lenp)
146 if lenp[0] > 0 { ri_puts("TWINCARD new verdict=EXISTS path=" as *u8); ri_puts(path); ri_puts(" (a card is never clobbered; edit it)\n" as *u8); return TCC_EXIT_EXISTS }
147 sys_mkdir(TC_DIR, RI_MODE755)
148 let row: *u8 = sys_mmap(RI_ROWB)
149 var o: i64 = ri_cat(row, 0, "card|" as *u8)
150 o = ri_cat(row, o, slug)
151 row[o] = RI_PIPE as u8; o = o + 1
152 o = ri_cat(row, o, display)
153 row[o] = RI_PIPE as u8; o = o + 1
154 o = ri_cat(row, o, cls)
155 row[o] = RI_PIPE as u8; o = o + 1
156 o = ri_cat(row, o, sex)
157 row[o] = RI_PIPE as u8; o = o + 1
158 o = ri_cat(row, o, lic)
159 row[o] = RI_PIPE as u8; o = o + 1
160 o = ri_catn(row, o, TC_SCHEMA_V)
161 row[o] = RI_NL as u8; o = o + 1
162 let fd: i64 = sys_openat_wr(path, RI_MODE644)
163 if fd < 0 { ri_puts("TWINCARD new verdict=WRITE-FAIL path=" as *u8); ri_puts(path); ri_puts("\n" as *u8); return TCC_EXIT_SCHEMA }
164 let w: i64 = sys_write(fd, row, o)
165 sys_close(fd)
166 ri_puts("TWINCARD new slug=" as *u8); ri_puts(slug)
167 ri_puts(" path=" as *u8); ri_puts(path)
168 ri_puts(" bytes=" as *u8); ri_putn(w)
169 ri_puts(" verdict=OK (header only; add axis rows on declared axes with a side, feature rows per freckle or mole, ref rows for every reference, shot rows per reference each carrying its presentation, makeup, hair_state and retouch words)\n" as *u8)
170 return 0
171}
172
173func main(argc: i64, argv: *i64) -> i64 {
174 if argc < 2 { return tcc_usage() }
175 let verb: *u8 = argv[1] as *u8
176 let sl: *i64 = sys_mmap(RI_I64) as *i64
177 let schema: *u8 = ri_load(TC_AXES, sl)
178 if sl[0] <= 0 { ri_puts("TWINCARD schema unreadable: " as *u8); ri_puts(TC_AXES); ri_puts("\n" as *u8); return TCC_EXIT_SCHEMA }
179 let kl: *i64 = sys_mmap(RI_I64) as *i64
180 let canon: *u8 = ri_load(TC_CANON, kl)
181 if kl[0] <= 0 { ri_puts("TWINCARD canon unreadable: " as *u8); ri_puts(TC_CANON); ri_puts("\n" as *u8); return TCC_EXIT_SCHEMA }
182 if ri_streq(verb, "axes" as *u8) == 1 {
183 let tot: *i64 = sys_mmap(TC_POS_N * RI_I64) as *i64
184 let sections: i64 = tcc_coverage(schema, sl[0], canon, kl[0], 0 as *u8, 0, tot)
185 tcc_rulers(schema, sl[0])
186 tcc_ruler_coverage(schema, sl[0], canon, kl[0])
187 ri_puts("TWINCARD axes sections=" as *u8); ri_putn(sections)
188 ri_puts(" declared=" as *u8); ri_putn(tot[0])
189 ri_puts(" (a paired axis declares two values; face values are the canon rows of knowledge/facecanon.conf; every other section is knowledge/twincard.axes)\n" as *u8)
190 return 0
191 }
192 if argc < 3 { return tcc_usage() }
193 if ri_streq(verb, "check" as *u8) == 1 { return tcc_check(schema, sl[0], canon, kl[0], argv[2] as *u8) }
194 if ri_streq(verb, "new" as *u8) == 1 {
195 if argc < TCC_ARGC_NEW { return tcc_usage() }
196 return tcc_new(argv)
197 }
198 return tcc_usage()
199}