nx_mvault_caption.nx source
↩ module page · 71 lines · 2613 B
1// nx_mvault_caption.nx -- the comprehensive per-item CAPTURE assembler.
2//
3// This is the write-API the (future) NishiCaption tagger calls to persist its
4// comprehensive first-pass output for ONE item: N measurements (95 axes) + M
5// tags + K captions, all keyed under the item's CID on the sovereign seg-store
6// with a per-item field index, so the whole capture is enumerable and NOTHING
7// from the expensive VLM/math pass is lost. Additive (rule 13).
8//
9// entries: key = "cap:<cid>:<field>" value = the B7/B8 string
10// index: "cap:<cid>:idx" newline-separated field list
11// field convention: "meas:<axis>" | "tag:<n>" | "cap:<mode>"
12//
13// Composes nx_registry (reg_put/reg_get/reg_index) + nx_mvault_tag/measure.
14// license_tier: ORIGINAL
15
16import "nx_syscalls.nx"
17import "nx_registry.nx"
18import "nx_mvault_tag.nx"
19import "nx_mvault_measure.nx"
20
21func cp_cat(dst: *u8, off: i64, s: *u8) -> i64 {
22 var i: i64 = 0
23 while s[i] != (0 as u8) { dst[off + i] = s[i]; i = i + 1 }
24 return off + i
25}
26
27// "cap:<cid>:" -> out ; returns length (position of the terminating NUL).
28func mv_cap_kp(out: *u8, cid: *u8) -> i64 {
29 let p: *u8 = "cap:" as *u8
30 let c: *u8 = ":" as *u8
31 var o: i64 = cp_cat(out, 0, p)
32 o = cp_cat(out, o, cid)
33 o = cp_cat(out, o, c)
34 out[o] = 0 as u8
35 return o
36}
37
38// "cap:<cid>:idx" -> out
39func mv_cap_idxkey(out: *u8, cid: *u8) -> i64 {
40 let o: i64 = mv_cap_kp(out, cid)
41 let ix: *u8 = "idx" as *u8
42 let o2: i64 = cp_cat(out, o, ix)
43 out[o2] = 0 as u8
44 return o2
45}
46
47// Persist one capture field (measurement/tag/caption) for an item; additive,
48// advances the per-item field index atomically.
49func mv_cap_put(prefix: *u8, cid: *u8, field: *u8, value: *u8, vlen: i64) -> i64 {
50 let kp: *u8 = sys_mmap(256)
51 mv_cap_kp(kp, cid)
52 let ix: *u8 = sys_mmap(256)
53 mv_cap_idxkey(ix, cid)
54 return reg_put(prefix, kp, ix, field, value, vlen)
55}
56
57// Read one capture field back: outp[0]=addr, outl[0]=len; 1=found.
58func mv_cap_get(prefix: *u8, cid: *u8, field: *u8, outp: *i64, outl: *i64) -> i64 {
59 let kp: *u8 = sys_mmap(256)
60 mv_cap_kp(kp, cid)
61 return reg_get(prefix, kp, field, outp, outl)
62}
63
64// The item's field list (newline-separated) into buf; returns length, or -1 if
65// it does not fit in cap. The caller states its own capacity: this used to be an
66// unbounded copy into whatever buffer it was handed (see nx_registry 2026-07-31).
67func mv_cap_fields(prefix: *u8, cid: *u8, buf: *u8, cap: i64) -> i64 {
68 let ix: *u8 = sys_mmap(256)
69 mv_cap_idxkey(ix, cid)
70 return reg_index(prefix, ix, buf, cap)
71}