nx_doc_decision.nx source
↩ module page · 198 lines · 6875 B
1// nx_doc_decision.nx -- D20 first stone of V5 docs doctrine.
2//
3// ADR-shape decision-record primitive. Every substrate decision
4// carries a reasoning chain: problem -> alternatives -> chosen ->
5// formula -> physics_justification -> research_opportunities.
6// Composes with Provenance tier (queued D21) + multi-incumbent
7// benchmark (queued D22) + dashboard (queued D23).
8//
9// Per [[feedback-substrate-knowledge-system-s-class-reasoning-
10// provenance-dashboard]] cardinal. Research absorbed: Architecture
11// Decision Records (Cognitect/Nygard 2011+, adr.github.io,
12// Microsoft Azure Well-Architected); MADR template.
13//
14// **Quadrant:** REFERENCE (Diátaxis)
15// **Topic Type:** REFERENCE (DITA)
16// **Status:** DRAFT (D20 first stone)
17// **Trust State:** WRITTEN_UNTESTED
18// **Competitive State:** UNCLASSIFIED (no benchmark vs adr-tools yet)
19
20import "nx_syscalls.nx"
21import "nx_string_ops.nx"
22
23// ===== Decision status sealed enum ===============================
24//
25// MADR template's standard status lifecycle. Substrate adopts
26// directly; Cardinal 13 (additive: SUPERSEDED preserved not deleted).
27
28const NX_DECISION_PROPOSED: i64 = 0 // under consideration
29const NX_DECISION_ACCEPTED: i64 = 1 // active, current substrate decision
30const NX_DECISION_SUPERSEDED: i64 = 2 // replaced by a later ADR (id in supersedes_by field)
31const NX_DECISION_DEPRECATED: i64 = 3 // no longer relevant; preserved for genealogy
32const NX_DECISION_REJECTED: i64 = 4 // proposed but not accepted
33const NX_DECISION_N: i64 = 5
34
35func nx_decision_status_is_valid(s: i64) -> i64 {
36 if s < 0 { return 0 }
37 if s >= NX_DECISION_N { return 0 }
38 return 1
39}
40
41func nx_decision_status_name(s: i64) -> *u8 {
42 if s == NX_DECISION_PROPOSED { return "PROPOSED" }
43 if s == NX_DECISION_ACCEPTED { return "ACCEPTED" }
44 if s == NX_DECISION_SUPERSEDED { return "SUPERSEDED" }
45 if s == NX_DECISION_DEPRECATED { return "DEPRECATED" }
46 if s == NX_DECISION_REJECTED { return "REJECTED" }
47 return "UNKNOWN"
48}
49
50// ===== NxDecisionRecord ==========================================
51//
52// All string fields are caller-owned pointers + lengths. Substrate-
53// honest: this struct holds pointers, not copies; caller manages
54// lifetime. For persistence, substrate emits the record to fd 1
55// (or future fd) in MADR-shaped Markdown.
56
57struct NxDecisionRecord {
58 id: i64, // substrate-unique ADR number
59 title_ptr: *u8,
60 title_len: i64,
61 status: i64, // NX_DECISION_*
62 problem_ptr: *u8,
63 problem_len: i64,
64 alternatives_ptr: *u8,
65 alternatives_len: i64,
66 chosen_ptr: *u8,
67 chosen_len: i64,
68 formula_ptr: *u8,
69 formula_len: i64,
70 physics_justification_ptr: *u8,
71 physics_justification_len: i64,
72 research_opportunities_ptr: *u8,
73 research_opportunities_len: i64,
74 supersedes_id: i64, // prior ADR id, 0 if first
75 timestamp_q14: i64,
76}
77
78func nx_decision_record_init(
79 r: *NxDecisionRecord,
80 id: i64,
81 timestamp_q14: i64
82) {
83 r.id = id
84 r.title_ptr = 0 as *u8
85 r.title_len = 0
86 r.status = NX_DECISION_PROPOSED
87 r.problem_ptr = 0 as *u8
88 r.problem_len = 0
89 r.alternatives_ptr = 0 as *u8
90 r.alternatives_len = 0
91 r.chosen_ptr = 0 as *u8
92 r.chosen_len = 0
93 r.formula_ptr = 0 as *u8
94 r.formula_len = 0
95 r.physics_justification_ptr = 0 as *u8
96 r.physics_justification_len = 0
97 r.research_opportunities_ptr = 0 as *u8
98 r.research_opportunities_len = 0
99 r.supersedes_id = 0
100 r.timestamp_q14 = timestamp_q14
101}
102
103// ===== Completeness check =========================================
104//
105// An ADR is COMPLETE if title + problem + chosen are non-empty.
106// Alternatives + formula + physics + research are OPTIONAL but
107// substrate-honest convention: provide them or explicitly write
108// "n/a" (substrate-honest: nothing is hidden by omission).
109//
110// Returns 0 if complete; positive code identifies missing field.
111
112func nx_decision_record_completeness(r: *NxDecisionRecord) -> i64 {
113 if r.title_len <= 0 { return 1 }
114 if r.problem_len <= 0 { return 2 }
115 if r.chosen_len <= 0 { return 3 }
116 if nx_decision_status_is_valid(r.status) != 1 { return 4 }
117 return 0
118}
119
120// ===== Markdown emitter ===========================================
121//
122// MADR-shaped output written to fd 1. Format:
123//
124// ## ADR <id> — <title>
125//
126// **Status:** <status_name>
127// **Supersedes:** ADR <supersedes_id> (if non-zero)
128//
129// ### Problem
130// <problem>
131//
132// ### Alternatives considered
133// <alternatives>
134//
135// ### Chosen
136// <chosen>
137//
138// ### Formula / proof
139// <formula>
140//
141// ### Physics justification
142// <physics_justification>
143//
144// ### Research opportunities
145// <research_opportunities>
146
147func _docdec_write_section(
148 label: *u8, n_label: i64,
149 body: *u8, n_body: i64
150) {
151 if n_body <= 0 { return }
152 sys_write(1, "### ", 4)
153 sys_write(1, label, n_label)
154 sys_write(1, "\n", 1)
155 sys_write(1, body, n_body)
156 sys_write(1, "\n\n", 2)
157}
158
159func nx_decision_record_emit(r: *NxDecisionRecord) -> i64 {
160 let comp: i64 = nx_decision_record_completeness(r)
161 if comp != 0 { return comp }
162
163 // Header line: "## ADR <id> — <title>"
164 sys_write(1, "## ADR ", 7)
165 let id_buf: *u8 = sys_mmap(32)
166 let n_id: i64 = nx_str_format_int(r.id, id_buf, 32)
167 sys_write(1, id_buf, n_id)
168 sys_write(1, " — ", 5)
169 sys_write(1, r.title_ptr, r.title_len)
170 sys_write(1, "\n\n", 2)
171
172 // Status line
173 sys_write(1, "**Status:** ", 12)
174 let status_name: *u8 = nx_decision_status_name(r.status)
175 let n_status: i64 = nx_str_len(status_name)
176 sys_write(1, status_name, n_status)
177 sys_write(1, "\n", 1)
178
179 // Supersedes line (if applicable)
180 if r.supersedes_id > 0 {
181 sys_write(1, "**Supersedes:** ADR ", 20)
182 let sup_buf: *u8 = sys_mmap(32)
183 let n_sup: i64 = nx_str_format_int(r.supersedes_id, sup_buf, 32)
184 sys_write(1, sup_buf, n_sup)
185 sys_write(1, "\n", 1)
186 }
187 sys_write(1, "\n", 1)
188
189 // Sections (each emits "### Label\nbody\n\n")
190 _docdec_write_section("Problem", 7, r.problem_ptr, r.problem_len)
191 _docdec_write_section("Alternatives considered", 23, r.alternatives_ptr, r.alternatives_len)
192 _docdec_write_section("Chosen", 6, r.chosen_ptr, r.chosen_len)
193 _docdec_write_section("Formula / proof", 15, r.formula_ptr, r.formula_len)
194 _docdec_write_section("Physics justification", 21, r.physics_justification_ptr, r.physics_justification_len)
195 _docdec_write_section("Research opportunities", 22, r.research_opportunities_ptr, r.research_opportunities_len)
196
197 return 0
198}