nx_honesty_grader.nx source
↩ module page · 184 lines · 7972 B
1// nx_honesty_grader.nx -- aggregate honesty score per repo + per arc.
2//
3// module: nishi-core.audit.honesty_grader
4// depends: nishi-core.audit.claim_audit, nishi-core.audit.dependency_audit
5// disk_kb: 4
6// capability: CORE_IO
7// wired_status: PARTIAL_WIRED
8//
9// license_tier: PUBLIC_NISHI_SUBSTRATE
10// genealogy_id: nishi_no_false_ok_cardinal_2026
11//
12// Per cardinal [[feedback-no-false-ok-substrate-honesty-audit]]:
13// aggregate report combining nx_claim_audit + nx_dependency_audit
14// outputs into a single per-arc honesty score.
15//
16// Substrate refuses to allow descriptive verbs ("shipped", "wired",
17// "off C") in external prose above the honest tier. The grader
18// emits the MAX-CLAIMABLE-VERB per primitive + per arc; downstream
19// prose generation (commit messages, README updates, status reports
20// to user) must respect the grader output.
21
22import "nx_claim_audit.nx"
23import "nx_dependency_audit.nx"
24import "nx_wired_status.nx"
25
26// ===== Honesty tier sealed enum ===================================
27
28const NX_HONESTY_PRISTINE: i64 = 1 // >= 95% claim-honest; zero overstated
29const NX_HONESTY_NOMINAL: i64 = 2 // >= 80% claim-honest
30const NX_HONESTY_DRIFT_PRESENT: i64 = 3 // 60-80%; overstated detected
31const NX_HONESTY_SIGNIFICANT_DRIFT: i64 = 4 // 40-60%; multiple overstated
32const NX_HONESTY_LIE_RICH: i64 = 5 // <40%; substrate-level pause on prose generation
33
34func nx_honesty_tier_name(t: i64) -> *u8 {
35 if t == NX_HONESTY_PRISTINE { return "PRISTINE" }
36 if t == NX_HONESTY_NOMINAL { return "NOMINAL" }
37 if t == NX_HONESTY_DRIFT_PRESENT { return "DRIFT_PRESENT" }
38 if t == NX_HONESTY_SIGNIFICANT_DRIFT { return "SIGNIFICANT_DRIFT" }
39 if t == NX_HONESTY_LIE_RICH { return "LIE_RICH" }
40 return "UNKNOWN"
41}
42
43func nx_honesty_tier_from_score(score_q10: i64) -> i64 {
44 if score_q10 >= 973 { return NX_HONESTY_PRISTINE } // >= 95%
45 if score_q10 >= 819 { return NX_HONESTY_NOMINAL } // >= 80%
46 if score_q10 >= 614 { return NX_HONESTY_DRIFT_PRESENT } // >= 60%
47 if score_q10 >= 410 { return NX_HONESTY_SIGNIFICANT_DRIFT } // >= 40%
48 return NX_HONESTY_LIE_RICH
49}
50
51// ===== Honesty audit per arc ======================================
52
53struct ArcHonestyReport {
54 report_hk: i64,
55 arc_name_ptr: *u8,
56 files_total: i64,
57 files_claim_honest: i64,
58 files_overstated: i64,
59 files_understated: i64,
60 files_missing_header: i64,
61 n_deps_wheeler_anchored: i64,
62 n_deps_cardinal_violations: i64,
63 overall_honesty_q10: i64,
64 overall_tier: i64,
65 audited_at_unix: i64,
66 verdict: i64,
67}
68
69const NX_ARC_HONESTY_REPORT_BYTES: i64 = 96 // 12 fields * 8 bytes
70
71// ===== Compose claim + dep audits into arc report ================
72
73func nx_honesty_arc_report(
74 claim_report: *ClaimAuditReport,
75 dep_report: *DepAuditReport,
76 arc_name_ptr: *u8,
77 now_unix: i64
78) -> *ArcHonestyReport {
79 let raw: *u8 = sys_mmap(NX_ARC_HONESTY_REPORT_BYTES)
80 let r: *ArcHonestyReport = raw as *ArcHonestyReport
81 r.report_hk = 0
82 r.arc_name_ptr = arc_name_ptr
83 r.files_total = 0
84 r.files_claim_honest = 0
85 r.files_overstated = 0
86 r.files_understated = 0
87 r.files_missing_header = 0
88 r.n_deps_wheeler_anchored = 0
89 r.n_deps_cardinal_violations = 0
90 r.overall_honesty_q10 = 0
91 r.overall_tier = NX_HONESTY_LIE_RICH
92 r.audited_at_unix = now_unix
93 r.verdict = NX_CA_OK
94
95 if claim_report != 0 as *ClaimAuditReport {
96 r.files_total = claim_report.files_scanned
97 r.files_overstated = claim_report.n_overstated
98 r.files_understated = claim_report.n_understated
99 r.files_missing_header = claim_report.files_missing_header
100 // ONE line -- a continuation line starting with a binary op parses as a SEPARATE statement (the
101 // statement-boundary trap): the four deductions were silently DROPPED, so every scanned file counted
102 // as claim-honest. Found 2026-07-09 by the runtime-wide sweep after the same trap hit nx_matrix_det_2x2.
103 let n_honest: i64 = claim_report.files_scanned - claim_report.n_overstated - claim_report.n_understated - claim_report.files_missing_header - claim_report.n_drift_detected
104 r.files_claim_honest = n_honest
105 r.overall_honesty_q10 = claim_report.honesty_score_q10
106 }
107
108 if dep_report != 0 as *DepAuditReport {
109 r.n_deps_wheeler_anchored = dep_report.n_wheeler_anchors
110 r.n_deps_cardinal_violations = dep_report.n_cardinal_violations
111 }
112
113 r.overall_tier = nx_honesty_tier_from_score(r.overall_honesty_q10)
114 return r
115}
116
117// ===== Max-claimable-verb for an arc ==============================
118//
119// Given an arc report, returns the highest descriptive verb that
120// external prose can honestly use ABOUT THE ARC AS A WHOLE.
121
122func nx_honesty_arc_max_verb(report: *ArcHonestyReport) -> i64 {
123 if report == 0 as *ArcHonestyReport { return NX_VERB_SCAFFOLDED }
124 if report.n_deps_cardinal_violations > 0 { return NX_VERB_SCAFFOLDED }
125 if report.overall_tier == NX_HONESTY_LIE_RICH { return NX_VERB_SCAFFOLDED }
126 if report.overall_tier == NX_HONESTY_SIGNIFICANT_DRIFT { return NX_VERB_STUBBED }
127 if report.overall_tier == NX_HONESTY_DRIFT_PRESENT { return NX_VERB_PARTIAL }
128 if report.overall_tier == NX_HONESTY_NOMINAL { return NX_VERB_WIRED }
129 return NX_VERB_SHIPPED // PRISTINE only
130}
131
132// ===== Prose-generation gate ======================================
133//
134// Substrate primitive: before publishing prose, caller passes the
135// arc report + intended verb tier; primitive returns whether the
136// claim is honest given the audit.
137//
138// If audit says max-verb is STUBBED but user wants to write SHIPPED,
139// substrate REFUSES + suggests the honest alternative.
140
141const NX_PROSE_GATE_PASS: i64 = 1
142const NX_PROSE_GATE_BLOCK_OVERSTATED: i64 = 2
143const NX_PROSE_GATE_WARN_UNDERSTATED: i64 = 3
144const NX_PROSE_GATE_AUDIT_UNAVAILABLE: i64 = 4
145
146func nx_prose_gate_check(
147 arc_report: *ArcHonestyReport,
148 intended_verb: i64
149) -> i64 {
150 if arc_report == 0 as *ArcHonestyReport { return NX_PROSE_GATE_AUDIT_UNAVAILABLE }
151 let max_verb: i64 = nx_honesty_arc_max_verb(arc_report)
152 if intended_verb > max_verb { return NX_PROSE_GATE_BLOCK_OVERSTATED }
153 if intended_verb < max_verb { return NX_PROSE_GATE_WARN_UNDERSTATED }
154 return NX_PROSE_GATE_PASS
155}
156
157// ===== Honest tier for THIS arc (this session's deliverables) ====
158//
159// Running the audit logic over the substrate primitives shipped this
160// arc (substrate-level self-assessment):
161//
162// ~86 .nx files shipped across the arc
163// Headers with wired_status: declared: ZERO (cardinal landed THIS turn)
164// Headers without wired_status: 86 (all pre-cardinal)
165// files_missing_header verdict: applies to all 86
166//
167// Honest score for this arc, AT TIME OF CARDINAL LANDING: 0% (no
168// files yet have the wired_status header). Going forward, new files
169// declare wired_status; existing files get audited + annotated in
170// subsequent passes.
171//
172// Honest_off_c_score: 0% (every build path passes through gcc /
173// binutils / qemu Wheeler anchors). Long-arc target: 100% once
174// nxc2/self_host + nxasm_v2 + nx_elf_writer + NishiOS close.
175
176// ===== Substrate-level prose-discipline ===========================
177//
178// The grader's substrate output drives my external-prose verb
179// choice. Before writing "shipped" in a status update, the audit
180// runs. If audit says max-verb is PARTIAL, prose must use PARTIAL.
181//
182// This is a MECHANICAL check, not self-discipline-dependent. The
183// cardinal is enforced by the substrate scanning the diff + the
184// prose, not by me being careful.