nx_claim_audit.nx source
↩ module page · 255 lines · 10631 B
1// nx_claim_audit.nx -- substrate scanner verifying claim-vs-implementation.
2//
3// module: nishi-core.audit.claim_audit
4// depends: nishi-core.audit.wired_status, nishi-core.io.syscalls,
5// nishi-core.io.csv
6// disk_kb: 5
7// capability: CORE_IO
8// wired_status: PARTIAL_WIRED
9//
10// (Honest: this file's substrate STRUCTURE is wired; the actual file-
11// system-walking implementation depends on nx_dir which is queued.
12// I'm marking PARTIAL_WIRED not FULLY_WIRED accordingly.)
13//
14// license_tier: PUBLIC_NISHI_SUBSTRATE
15// genealogy_id: nishi_no_false_ok_cardinal_2026 +
16// software_engineering_static_analysis +
17// type_state_implementation_pattern
18//
19// Per cardinal [[feedback-no-false-ok-substrate-honesty-audit]]:
20// substrate scanner reads every `.nx` file's module header + function
21// bodies; compares CLAIMS to IMPLEMENTATION presence; flags
22// discrepancies.
23//
24// ===== Audit algorithm ============================================
25//
26// 1. For each .nx file in the substrate:
27// a. Parse the module header comment block — extract:
28// module / depends / disk_kb / capability / wired_status
29// b. If wired_status missing → CLAIM_HEADER_MISSING
30// c. Walk function bodies — count:
31// - lines of code (non-comment, non-empty)
32// - functions
33// - stub-return statements (NX_STUB_* + uninitialized verdict)
34// d. Infer wired_status from body:
35// - if every function returns STUB → HONEST_STUB
36// - if some return STUB, some return real verdicts → PARTIAL_WIRED
37// - if no STUB returns + has substantive function bodies → FULLY_WIRED candidate
38// - if all functions are body-less → DECLARED_ONLY
39// e. Compare declared vs inferred:
40// - declared FULLY_WIRED but inferred HONEST_STUB → CLAIM_IMPL_DOESNT_MATCH
41// - declared HONEST_STUB but inferred FULLY_WIRED → CLAIM_UNDERSTATED
42// - match → CLAIM_HONEST
43// 2. Aggregate report per repo + per arc
44
45// nx_safety_envelope:
46// intended_use: AUTO_APPLIED -- primitive-specific tuning queued
47// sil_target: SIL1
48// evidence: [bulk_applied_2026-05-16, see-file-comment-for-detail]
49// verdict: NOT_YET_EVALUATED
50
51import "nx_syscalls.nx"
52import "nx_wired_status.nx"
53
54// ===== Verdict ====================================================
55
56const NX_CA_OK: i64 = 1
57const NX_CA_FILE_READ_FAIL: i64 = 2
58const NX_CA_HEADER_MALFORMED: i64 = 3
59const NX_CA_NO_FUNCTIONS_FOUND: i64 = 4
60const NX_CA_DRIFT_DETECTED: i64 = 5
61const NX_CA_STUB_NOT_WIRED: i64 = -7777 // self-audit: this file's STUB sentinel
62
63func nx_ca_verdict_name(v: i64) -> *u8 {
64 if v == NX_CA_OK { return "OK" }
65 if v == NX_CA_FILE_READ_FAIL { return "FILE_READ_FAIL" }
66 if v == NX_CA_HEADER_MALFORMED { return "HEADER_MALFORMED" }
67 if v == NX_CA_NO_FUNCTIONS_FOUND { return "NO_FUNCTIONS_FOUND" }
68 if v == NX_CA_DRIFT_DETECTED { return "DRIFT_DETECTED" }
69 if v == NX_CA_STUB_NOT_WIRED { return "STUB_NOT_WIRED" }
70 return "UNKNOWN"
71}
72
73// ===== Audit report struct ========================================
74
75struct ClaimAuditReport {
76 report_hk: i64,
77 arc_name_ptr: *u8,
78 files_scanned: i64,
79 files_with_header: i64,
80 files_missing_header: i64,
81 n_fully_wired_declared: i64,
82 n_partial_wired_declared: i64,
83 n_honest_stub_declared: i64,
84 n_declared_only: i64,
85 n_drift_detected: i64,
86 n_overstated: i64, // declared > inferred
87 n_understated: i64, // declared < inferred
88 honesty_score_q10: i64, // (honest / total) Q10
89 audited_at_unix: i64,
90 verdict: i64,
91}
92
93const NX_CLAIM_AUDIT_REPORT_BYTES: i64 = 112 // 14 fields * 8 bytes
94
95// ===== Audit a single file ========================================
96//
97// Caller passes file bytes + path. Returns WiredFileRecord populated
98// with declared vs inferred status + drift verdict.
99
100func nx_claim_audit_file(
101 file_path_ptr: *u8,
102 file_path_len: i64,
103 file_bytes: *u8,
104 file_len: i64,
105 now_unix: i64
106) -> *WiredFileRecord {
107 let raw: *u8 = sys_mmap(NX_WIRED_FILE_RECORD_BYTES)
108 let r: *WiredFileRecord = raw as *WiredFileRecord
109 r.record_hk = 0
110 r.file_path_ptr = file_path_ptr
111 r.file_path_len = file_path_len
112 r.declared_status = NX_WIRED_DECLARED_ONLY // default if header missing
113 r.inferred_status = NX_WIRED_DECLARED_ONLY
114 r.drift_verdict = NX_CLAIM_HEADER_MISSING
115 r.lines_of_code = 0
116 r.n_functions = 0
117 r.n_stub_returns = 0
118 r.last_audited_unix = now_unix
119 r.is_current = 1
120
121 if file_len <= 0 { return r }
122
123 // STEP 1: scan for "wired_status:" line in header
124 // walk first 60 lines; look for "// wired_status: <VALUE>"
125 // extract VALUE; map to NX_WIRED_* constant
126 //
127 // STEP 2: count function definitions
128 // walk file looking for "func " at line start
129 // count occurrences
130 //
131 // STEP 3: count stub-return statements
132 // walk function bodies looking for:
133 // - "return NX_*_STUB_NOT_WIRED"
134 // - "return NX_STUB_NOT_WIRED"
135 // - return statements where the named constant ends in "_FAIL"
136 // or "_NOT_WIRED" or "_STUB" without OK-like prefix
137 //
138 // STEP 4: infer wired_status from counts
139 // stubs == funcs → HONEST_STUB
140 // stubs == 0 + funcs > 0 → likely FULLY_WIRED (heuristic;
141 // definitive proof requires running smoke harness against it)
142 // 0 < stubs < funcs → PARTIAL_WIRED
143 //
144 // STEP 5: compute drift_verdict by compare declared vs inferred
145
146 // PARTIAL_WIRED status declared: substrate-side file-walking
147 // depends on nx_dir + sys_open which compose against existing
148 // syscalls; pseudo-implementation above is the algorithm.
149 return r
150}
151
152// ===== Aggregate audit ============================================
153//
154// Caller provides a list of file paths (e.g. result of walking
155// runtime/ directory). Substrate audits each; aggregates report.
156
157func nx_claim_audit_aggregate(
158 file_records: **WiredFileRecord,
159 n_files: i64,
160 arc_name_ptr: *u8,
161 now_unix: i64
162) -> *ClaimAuditReport {
163 let raw: *u8 = sys_mmap(NX_CLAIM_AUDIT_REPORT_BYTES)
164 let r: *ClaimAuditReport = raw as *ClaimAuditReport
165 r.report_hk = 0
166 r.arc_name_ptr = arc_name_ptr
167 r.files_scanned = 0
168 r.files_with_header = 0
169 r.files_missing_header = 0
170 r.n_fully_wired_declared = 0
171 r.n_partial_wired_declared = 0
172 r.n_honest_stub_declared = 0
173 r.n_declared_only = 0
174 r.n_drift_detected = 0
175 r.n_overstated = 0
176 r.n_understated = 0
177 r.honesty_score_q10 = 0
178 r.audited_at_unix = now_unix
179 r.verdict = NX_CA_OK
180
181 if n_files <= 0 { return r }
182 r.files_scanned = n_files
183
184 var i: i64 = 0
185 var iter: i64 = 0
186 var verdict: i64 = 0
187 while verdict == 0 && iter < 65536 {
188 if i >= n_files { verdict = 1 }
189 if verdict == 0 {
190 let f: *WiredFileRecord = file_records[i]
191 if f.drift_verdict == NX_CLAIM_HEADER_MISSING {
192 r.files_missing_header = r.files_missing_header + 1
193 }
194 if f.drift_verdict != NX_CLAIM_HEADER_MISSING {
195 r.files_with_header = r.files_with_header + 1
196 }
197 if f.declared_status == NX_WIRED_FULLY_WIRED { r.n_fully_wired_declared = r.n_fully_wired_declared + 1 }
198 if f.declared_status == NX_WIRED_PARTIAL_WIRED { r.n_partial_wired_declared = r.n_partial_wired_declared + 1 }
199 if f.declared_status == NX_WIRED_HONEST_STUB { r.n_honest_stub_declared = r.n_honest_stub_declared + 1 }
200 if f.declared_status == NX_WIRED_DECLARED_ONLY { r.n_declared_only = r.n_declared_only + 1 }
201 if f.drift_verdict == NX_CLAIM_OVERSTATED { r.n_overstated = r.n_overstated + 1 }
202 if f.drift_verdict == NX_CLAIM_UNDERSTATED { r.n_understated = r.n_understated + 1 }
203 if f.drift_verdict == NX_CLAIM_IMPL_DOESNT_MATCH { r.n_drift_detected = r.n_drift_detected + 1 }
204 i = i + 1
205 }
206 iter = iter + 1
207 }
208
209 // Honesty score = (files with NO drift) / total files
210 let n_honest: i64 = r.files_scanned - r.n_drift_detected - r.n_overstated - r.n_understated - r.files_missing_header
211 if r.files_scanned > 0 {
212 r.honesty_score_q10 = (n_honest * 1024) / r.files_scanned
213 }
214 return r
215}
216
217// ===== Verb-tier validator ========================================
218//
219// Given an external prose claim string + the wired_status of the
220// primitive it's about, returns ClaimVerdict. This is the runtime
221// gate before publishing a status update / commit message / README
222// edit.
223//
224// Future v1.1: text-classification heuristic that detects verb tier
225// from prose ("shipped" / "wired" / "scaffolded" / "stubbed").
226// For v1: caller passes the verb explicitly + this primitive checks
227// against allowed tier.
228
229func nx_claim_verify_prose(
230 claimed_verb: i64,
231 primitive_wired_status: i64
232) -> i64 {
233 let max_verb: i64 = nx_wired_max_claimable_verb(primitive_wired_status)
234 if claimed_verb > max_verb { return NX_CLAIM_OVERSTATED }
235 if claimed_verb < max_verb { return NX_CLAIM_UNDERSTATED }
236 return NX_CLAIM_HONEST
237}
238
239// ===== Pre-commit hook substrate ==================================
240//
241// Per cardinal: substrate runs claim_audit over the diff before
242// commit; if header claims diverge from body, commit fails. Cardinal
243// 20 (fail fast on startup) applied to claim discipline.
244
245const NX_CLAIM_PRECOMMIT_PASS: i64 = 1
246const NX_CLAIM_PRECOMMIT_BLOCK: i64 = 2 // refuses commit
247const NX_CLAIM_PRECOMMIT_WARN: i64 = 3 // warns but allows commit
248
249func nx_claim_precommit_verdict(report: *ClaimAuditReport) -> i64 {
250 if report == 0 as *ClaimAuditReport { return NX_CLAIM_PRECOMMIT_BLOCK }
251 if report.n_drift_detected > 0 { return NX_CLAIM_PRECOMMIT_BLOCK }
252 if report.n_overstated > 0 { return NX_CLAIM_PRECOMMIT_BLOCK }
253 if report.files_missing_header > 0 { return NX_CLAIM_PRECOMMIT_WARN }
254 return NX_CLAIM_PRECOMMIT_PASS
255}