code wiki / _hdl_build / nx_connect_wards_lib.nx
nx_connect_wards_lib.nx source
↩ module page · 73 lines · 3173 B
1// nx_connect_wards_lib.nx -- WARD & BRANCH COMMUNITY groups, extracted as a shared library so the
2// verifying gate (nx_connect_wards) and the LIVE app (nx_connect_serve /community) bind ONE
3// implementation. Before this split the live page merely ASSERTED "this group holds no callings,
4// records, attendance, or donations by construction" -- prose, with no registry actually enforcing it.
5//
6// THE BOUNDARY, enforced as data rather than promised in copy: a group's schema is a FIELD REGISTRY
7// (rule 11) where every field carries a CLASS, and the community layer may carry ONLY class 0. A checker
8// scans the registry and refuses any congregation-administration class. The same checker flags an
9// incumbent-style ward-admin schema, which is what makes the boundary load-bearing rather than decorative.
10// classes: 0=community-safe 1=calling 2=membership-record 3=attendance 4=ordinance 5=donation
11//
12// Joining is faith-revealing, so it requires explicit faith consent (GDPR Art.9 idiom): without consent
13// the join is REFUSED and the person never appears in any roster. Joins are idempotent (rule 10).
14// The youth-channel rule delegates to the ONE two-deep wall rather than re-deriving it here.
15// license_tier: ORIGINAL
16import "nx_connect_youth_lib.nx"
17
18const WD_MAX: i64 = 8
19const WM_MAX: i64 = 64
20const FR_MAX: i64 = 16
21
22// field classes
23const WD_CLASS_SAFE: i64 = 0
24const WD_CLASS_CALLING: i64 = 1
25const WD_CLASS_RECORD: i64 = 2
26const WD_CLASS_ATTENDANCE: i64 = 3
27const WD_CLASS_ORDINANCE: i64 = 4
28const WD_CLASS_DONATION: i64 = 5
29
30// join outcomes
31const WD_JOINED: i64 = 1
32const WD_ALREADY: i64 = 2
33const WD_NO_CONSENT: i64 = 0-1
34
35func wd_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
36func wd_streq(a: *u8, b: *u8) -> i64 {
37 var i: i64=0
38 while a[i]!=(0 as u8) { if a[i]!=b[i] { return 0 } i=i+1 }
39 if b[i]!=(0 as u8) { return 0 }
40 return 1
41}
42
43// count fields whose class is NOT community-safe. Non-zero => this schema is a congregation-admin model
44// and must be refused at the community layer.
45func wd_forbidden_count(classes: *i64, n: i64) -> i64 {
46 var c: i64=0
47 var i: i64=0
48 while i<n { if classes[i]>0 { c=c+1 } i=i+1 }
49 return c
50}
51
52// join a ward community group. Requires faith consent; idempotent.
53// returns WD_JOINED | WD_ALREADY | WD_NO_CONSENT.
54func wd_join(mw: *i64, mu: *i64, nm: *i64, ward: i64, user: i64, consent: i64) -> i64 {
55 if consent!=1 { return WD_NO_CONSENT }
56 var i: i64=0
57 while i<nm[0] { if mw[i]==ward { if mu[i]==user { return WD_ALREADY } } i=i+1 }
58 let k: i64=nm[0]
59 mw[k]=ward; mu[k]=user
60 nm[0]=k+1
61 return WD_JOINED
62}
63func wd_in(mw: *i64, mu: *i64, nm: *i64, ward: i64, user: i64) -> i64 {
64 var i: i64=0
65 while i<nm[0] { if mw[i]==ward { if mu[i]==user { return 1 } } i=i+1 }
66 return 0
67}
68
69// a youth channel inside a ward group is a VISIBLE GROUP context, so this delegates to the single
70// two-deep wall instead of re-deriving ">= 2 adults" a third time.
71func wd_youth_channel_ok(adults_present: i64) -> i64 {
72 return yw_may_channel(YW_BAND_ADULT, YW_BAND_MINOR, 0, YW_CTX_GROUP, adults_present)
73}