nx_manga_rating_gate.nx source
↩ module page · 89 lines · 7954 B
1// nx_manga_rating_gate.nx -- REFEREE for mangagen MG24 (mr_rate_row) and MG32 (mr_depiction_legal).
2// IN-PROCESS against nx_manga_rating_lib: the decision has ONE home, so the CLI and this gate cannot
3// drift into two different answers.
4//
5// It proves the done-rules pre-declared on /compare/mangagen before the organ existed:
6// MG24 -- a rating row bound to the ASSET at emit, never to the account; a family-tier viewer cannot
7// be served an adult-rated asset, and an UNRATED asset is treated as GATED rather than safe.
8// MG32 -- the adult invariant fails closed at CONSTRUCTION, not by policy.
9//
10// ANTI-VACUITY IS THE POINT. A guard that DENIES EVERYTHING passes every deny test ever written, so
11// every refusal tooth below is PAIRED with a positive control that must be ALLOWED: T2 against T1,
12// T12 against T11, T13 against T14. T10 requires the ladder to actually discriminate -- an
13// implementation that mapped every rating to the gated area would satisfy T5, T8 and T9 and still be
14// useless, and only T6, T7 and T10 refute it.
15// T17 is a CROSS-IDENTITY: this lane must never grow its own copy of the adult age, so the gate asserts
16// the imported WS_ADULT_AGE is still 18. If the character lane moves it, this gate says so.
17// license_tier: ORIGINAL expect_exit: 0
18import "nx_syscalls.nx"
19import "nx_gate_verdict.nx"
20import "nx_manga_rating_lib.nx"
21
22func mrg_eq(a: i64, b: i64) -> i64 { if a == b { return 1 } return 0 }
23
24func main(argc: i64, argv: *i64) -> i64 {
25 let ctr: *i64 = gv_ctr()
26 gv_head("nx_manga_rating_lib -- rating is DATA on the asset, unrated is GATED, the adult invariant fails closed at construction" as *u8)
27
28 // ---- MG32 AXIS 2: WHAT MAY BE DEPICTED -- age x EXPOSURE, never age x rating --------------
29 gv_check("T1 neg-control-minor-exposed: below the adult age AND exposed refuses with MR_E_MINOR -- the one hard line" as *u8, mrg_eq(mr_depiction_legal(17, MR_EXPOSED), MR_E_MINOR), ctr)
30 gv_check("T2 pos-control-minor-clothed: below the adult age and CLOTHED is OK -- minor characters exist in ordinary comics and a gate refusing this would over-block lawful work" as *u8, mrg_eq(mr_depiction_legal(17, MR_CLOTHED), MR_OK), ctr)
31 gv_check("T3 pos-control-adult-exposed: at or above the adult age is OK unconditionally -- a declared adult is an adult, no appearance test, no hold" as *u8, mrg_eq(mr_depiction_legal(21, MR_EXPOSED), MR_OK), ctr)
32 gv_check("T4 BOUNDARY: WS_ADULT_AGE itself counts as ADULT, not one year short of it" as *u8, mrg_eq(mr_depiction_legal(WS_ADULT_AGE, MR_EXPOSED), MR_OK), ctr)
33 gv_check("T4b BOUNDARY: one year below WS_ADULT_AGE and exposed still refuses -- the boundary is tested from BOTH sides" as *u8, mrg_eq(mr_depiction_legal(WS_ADULT_AGE - 1, MR_EXPOSED), MR_E_MINOR), ctr)
34 var tdisc: i64 = 0
35 if mr_depiction_legal(17, MR_EXPOSED) != mr_depiction_legal(17, MR_CLOTHED) { tdisc = 1 }
36 gv_check("T4c ANTI-VACUITY: EXPOSURE is what decides for a minor -- a rule that ignored it would answer the same for both and dies here" as *u8, tdisc, ctr)
37
38 // ---- THE LOAD-BEARING PROPERTY: unrated is gated, never safe ------------------------------
39 gv_check("T5 LOAD-BEARING: an UNRATED asset maps to the GATED area -- an absent rating is not evidence of innocence" as *u8, mrg_eq(mr_area_for_rating(MR_RATE_UNRATED), NX_TAREA_NSFW), ctr)
40 gv_check("T6 ALLAGES maps to the SFW area" as *u8, mrg_eq(mr_area_for_rating(MR_RATE_ALLAGES), NX_TAREA_SFW), ctr)
41 gv_check("T7 TEEN maps to the SFW area" as *u8, mrg_eq(mr_area_for_rating(MR_RATE_TEEN), NX_TAREA_SFW), ctr)
42 gv_check("T8 MATURE maps to the gated area" as *u8, mrg_eq(mr_area_for_rating(MR_RATE_MATURE), NX_TAREA_NSFW), ctr)
43 gv_check("T9 ADULT maps to the gated area" as *u8, mrg_eq(mr_area_for_rating(MR_RATE_ADULT), NX_TAREA_NSFW), ctr)
44 var t10: i64 = 0
45 if mr_area_for_rating(MR_RATE_ALLAGES) != mr_area_for_rating(MR_RATE_ADULT) { t10 = 1 }
46 gv_check("T10 ANTI-VACUITY: the ladder DISCRIMINATES -- map-everything-to-gated satisfies T5 T8 T9 and dies here" as *u8, t10, ctr)
47
48 // ---- MG24 serving, composed onto the incumbent access ruler -------------------------------
49 gv_check("T11 neg-control-family-unrated: a FAMILY viewer is DENIED an unrated asset" as *u8, mrg_eq(mr_may_serve(NX_TACCESS_FAMILY, MR_RATE_UNRATED), NX_TACCESS_DENY), ctr)
50 gv_check("T12 pos-control-family-allages: a FAMILY viewer IS served an allages asset -- the deny path is not universal" as *u8, mrg_eq(mr_may_serve(NX_TACCESS_FAMILY, MR_RATE_ALLAGES), NX_TACCESS_ALLOW), ctr)
51 gv_check("T13 pos-control-owner-adult: an OWNER IS served an adult asset -- the gate is a level test, not a ban" as *u8, mrg_eq(mr_may_serve(NX_TACCESS_OWNER, MR_RATE_ADULT), NX_TACCESS_ALLOW), ctr)
52 gv_check("T14 neg-control-anon-allages: an ANON viewer is DENIED even allages -- the SFW area still requires FAMILY" as *u8, mrg_eq(mr_may_serve(NX_TACCESS_ANON, MR_RATE_ALLAGES), NX_TACCESS_DENY), ctr)
53 gv_check("T15 a MALFORMED rating denies even for the OWNER -- an unreadable row is not a permissive one" as *u8, mrg_eq(mr_may_serve(NX_TACCESS_OWNER, 99), NX_TACCESS_DENY), ctr)
54 var tindep: i64 = 0
55 if mr_depiction_legal(17, MR_CLOTHED) == MR_OK { if mr_area_for_rating(MR_RATE_MATURE) == NX_TAREA_NSFW { tindep = 1 } }
56 gv_check("T16 THE TWO AXES ARE INDEPENDENT: a CLOTHED minor figure is lawfully depicted even inside a MATURE-rated work, and that work is STILL gated to an owner. Rating governs WHO MAY VIEW, exposure governs WHAT MAY BE DEPICTED -- the first cut conflated them and would have over-blocked ordinary lawful content" as *u8, tindep, ctr)
57
58 // ---- CROSS-IDENTITY with the character lane ----------------------------------------------
59 gv_check("T17 CROSS-IDENTITY: the imported WS_ADULT_AGE is still 18 -- this lane never grows its own copy of the threshold" as *u8, mrg_eq(WS_ADULT_AGE, 18), ctr)
60
61 // ---- MG24 the row is the artifact --------------------------------------------------------
62 let row: *u8 = sys_mmap(MR_ROWCAP)
63 let rc: i64 = mr_rate_row("nxc1-deadbeef" as *u8, MR_RATE_MATURE, "mangadex" as *u8, 1788639000, row, MR_ROWCAP)
64 gv_check("T18 mr_rate_row emits a row and returns its length" as *u8, mrg_eq(rc > 0, 1), ctr)
65 var t19: i64 = 0
66 let head: *u8 = "rate" as *u8
67 if rc > 4 {
68 var ok: i64 = 1
69 var i: i64 = 0
70 while i < 4 { if row[i] != head[i] { ok = 0; i = 4 } else { i = i + 1 } }
71 if row[4] == (MR_PIPE as u8) { t19 = ok }
72 }
73 gv_check("T19 the emitted row is pipe-delimited and opens with the rate tag" as *u8, t19, ctr)
74 gv_check("T20 mr_rate_row REFUSES an out-of-ladder rating rather than writing a row nobody can read" as *u8, mrg_eq(mr_rate_row("nxc1-deadbeef" as *u8, 99, "mangadex" as *u8, 1, row, MR_ROWCAP), MR_E_RATING), ctr)
75 gv_check("T21 mr_rate_row REFUSES when the row would not fit rather than truncating it silently" as *u8, mrg_eq(mr_rate_row("nxc1-deadbeef" as *u8, MR_RATE_TEEN, "mangadex" as *u8, 1, row, 8), MR_E_ROW), ctr)
76
77 // ---- VALUES, so an outside method can contradict this gate rather than trust it -----------
78 gv_values_head()
79 gv_kv("adult_age" as *u8, WS_ADULT_AGE)
80 gv_kv("area_unrated" as *u8, mr_area_for_rating(MR_RATE_UNRATED))
81 gv_kv("area_allages" as *u8, mr_area_for_rating(MR_RATE_ALLAGES))
82 gv_kv("area_adult" as *u8, mr_area_for_rating(MR_RATE_ADULT))
83 gv_kv("serve_family_unrated" as *u8, mr_may_serve(NX_TACCESS_FAMILY, MR_RATE_UNRATED))
84 gv_kv("serve_family_allages" as *u8, mr_may_serve(NX_TACCESS_FAMILY, MR_RATE_ALLAGES))
85 gv_kv("serve_owner_adult" as *u8, mr_may_serve(NX_TACCESS_OWNER, MR_RATE_ADULT))
86 gv_kv("row_bytes" as *u8, rc)
87
88 return gv_verdict("MANGA-RATING-GATE" as *u8, ctr, "unrated is gated, the ladder discriminates, the adult invariant fails closed at construction, and every refusal is paired with a positive control" as *u8)
89}