nx_privlog_gate.nx source
↩ module page · 110 lines · 7461 B
1// nx_privlog_gate.nx -- INDEPENDENT GATE: privilege assertion, waiver, and the FRCP 26(b)(5)(A) log.
2// ZERO storage. Teeth: attorney-client needs ALL FIVE elements (a lawyer copied on a business email is
3// NOT privileged); OPINION work product survives ANY showing of need and hardship while FACT work
4// product yields to both; FRE 502(b) needs all THREE prongs or the disclosure is a waiver; and a
5// withheld document with no log entry is counted as exposure, because withholding without logging is
6// itself a route to waiver.
7//
8// The attorney-client test is swept EXHAUSTIVELY over all 32 element combinations and work product
9// over every (tier x need x hardship) cell, so the invariants -- exactly one AC combination qualifies,
10// and opinion work product is NEVER discoverable anywhere -- are proven rather than sampled.
11// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
12
13import "nx_privlog_lib.nx"
14import "nx_gate_verdict.nx"
15
16func main(argc: i64, argv: *i64) -> i64 {
17 let ctr: *i64 = gv_ctr()
18 let lbl: *u8 = sys_mmap(32)
19
20 gv_head("NISHI-PRIVLOG-GATE (attorney-client + work product + FRE 502(b) + FRCP 26(b)(5)(A) log)" as *u8)
21
22 // ---- A: attorney-client, EXHAUSTIVE over all 32 combinations ----
23 var qualifies: i64 = 0
24 var waived_but_privileged: i64 = 0
25 var i: i64 = 0
26 while i < 32 {
27 let comm: i64 = (i / 16) % 2
28 let rel: i64 = (i / 8) % 2
29 let adv: i64 = (i / 4) % 2
30 let conf: i64 = (i / 2) % 2
31 let waived: i64 = i % 2
32 let r: i64 = pl_ac_pure(comm, rel, adv, conf, waived)
33 qualifies = qualifies + r
34 if waived == 1 {
35 if r == 1 { waived_but_privileged = waived_but_privileged + 1 }
36 }
37 i = i + 1
38 }
39 gv_check("A1 exactly ONE of 32 element combinations is privileged" as *u8, qualifies == 1, ctr)
40 gv_check("A2 a WAIVED document is never privileged, in any of the 16 waived cells" as *u8, waived_but_privileged == 0, ctr)
41 gv_check("A3 all five elements -> privileged" as *u8, pl_ac_pure(1, 1, 1, 1, 0) == 1, ctr)
42 gv_check("A4 a lawyer copied on BUSINESS advice is NOT privileged" as *u8, pl_ac_pure(1, 1, 0, 1, 0) == 0, ctr)
43 gv_check("A5 legal advice that was NOT confidential is not privileged" as *u8, pl_ac_pure(1, 1, 1, 0, 0) == 0, ctr)
44 gv_check("A6 no attorney-client relationship -> not privileged" as *u8, pl_ac_pure(1, 0, 1, 1, 0) == 0, ctr)
45 gv_check("A7 a document that is not a communication -> not privileged" as *u8, pl_ac_pure(0, 1, 1, 1, 0) == 0, ctr)
46 gv_check("A8 four of five elements -> deficiency count 4" as *u8, pl_ac_elements_pure(1, 1, 0, 1, 0) == 4, ctr)
47
48 // ---- W: work product, EXHAUSTIVE over (tier x need x hardship) ----
49 var opinion_pierced: i64 = 0
50 var t: i64 = 0
51 while t < 3 {
52 var n: i64 = 0
53 while n < 2 {
54 var h: i64 = 0
55 while h < 2 {
56 if t == PL_OPINION_WP {
57 if pl_wp_discoverable_pure(t, n, h) == 1 { opinion_pierced = opinion_pierced + 1 }
58 }
59 h = h + 1
60 }
61 n = n + 1
62 }
63 t = t + 1
64 }
65 gv_check("W1 OPINION work product is NEVER discoverable, in all 4 need/hardship cells" as *u8, opinion_pierced == 0, ctr)
66 gv_check("W2 anticipation + mental impressions -> OPINION work product" as *u8, pl_wp_tier_pure(1, 1) == PL_OPINION_WP, ctr)
67 gv_check("W3 anticipation alone -> FACT work product" as *u8, pl_wp_tier_pure(1, 0) == PL_FACT_WP, ctr)
68 gv_check("W4 no anticipation of litigation -> no protection" as *u8, pl_wp_tier_pure(0, 1) == PL_NONE, ctr)
69 gv_check("W5 FACT work product yields to need AND hardship" as *u8, pl_wp_discoverable_pure(PL_FACT_WP, 1, 1) == 1, ctr)
70 gv_check("W6 need WITHOUT hardship does not pierce fact work product" as *u8, pl_wp_discoverable_pure(PL_FACT_WP, 1, 0) == 0, ctr)
71 gv_check("W7 hardship WITHOUT need does not pierce it either" as *u8, pl_wp_discoverable_pure(PL_FACT_WP, 0, 1) == 0, ctr)
72 gv_check("W8 unprotected material is plainly discoverable" as *u8, pl_wp_discoverable_pure(PL_NONE, 0, 0) == 1, ctr)
73 pl_tier_label(PL_OPINION_WP, lbl)
74 gv_check("W9 opinion tier label" as *u8, mt_streq(lbl, "OPINION-WP" as *u8) == 1, ctr)
75
76 // ---- V: waiver and the FRE 502(b) rescue ----
77 gv_check("V1 no third-party disclosure -> no waiver" as *u8, pl_waived_pure(0, 0, 0, 0, 0) == 0, ctr)
78 gv_check("V2 bare third-party disclosure -> WAIVED" as *u8, pl_waived_pure(1, 0, 0, 0, 0) == 1, ctr)
79 gv_check("V3 common interest covers the disclosure -> no waiver" as *u8, pl_waived_pure(1, 1, 0, 0, 0) == 0, ctr)
80 gv_check("V4 all three 502(b) prongs -> rescued" as *u8, pl_waived_pure(1, 0, 1, 1, 1) == 0, ctr)
81 gv_check("V5 inadvertent but NO reasonable steps -> still waived" as *u8, pl_waived_pure(1, 0, 1, 0, 1) == 1, ctr)
82 gv_check("V6 inadvertent, steps taken, but NOT promptly rectified -> waived" as *u8, pl_waived_pure(1, 0, 1, 1, 0) == 1, ctr)
83 gv_check("V7 deliberate disclosure cannot use 502(b)" as *u8, pl_waived_pure(1, 0, 0, 1, 1) == 1, ctr)
84
85 // ---- L: the log entry ----
86 gv_check("L1 nothing recorded -> six fields missing" as *u8, pl_entry_missing_pure(0, 0, 0, 0, 0, 0) == 6, ctr)
87 gv_check("L2 all six recorded -> none missing" as *u8, pl_entry_missing_pure(1, 1, 1, 1, 1, 1) == 0, ctr)
88 gv_check("L3 a complete, non-revealing entry is adequate" as *u8, pl_entry_adequate_pure(0, 0) == 1, ctr)
89 gv_check("L4 an incomplete entry is NOT adequate" as *u8, pl_entry_adequate_pure(1, 0) == 0, ctr)
90 gv_check("L5 a COMPLETE entry that reveals the privileged content is NOT adequate" as *u8, pl_entry_adequate_pure(0, 1) == 0, ctr)
91
92 // ---- G: the log as a whole ----
93 gv_check("G1 10 withheld, 10 logged -> 0 unlogged" as *u8, pl_unlogged_pure(10, 10) == 0, ctr)
94 gv_check("G2 10 withheld, 7 logged -> 3 unlogged" as *u8, pl_unlogged_pure(10, 7) == 3, ctr)
95 gv_check("G3 over-logging never reports negative" as *u8, pl_unlogged_pure(5, 9) == 0, ctr)
96 gv_check("G4 fully logged and all adequate -> log ADEQUATE" as *u8, pl_log_adequate_pure(10, 10, 0) == 1, ctr)
97 gv_check("G5 three withheld docs never logged -> NOT adequate" as *u8, pl_log_adequate_pure(10, 7, 0) == 0, ctr)
98 gv_check("G6 fully logged but one entry inadequate -> NOT adequate" as *u8, pl_log_adequate_pure(10, 10, 1) == 0, ctr)
99 gv_check("G7 exposure = unlogged + inadequate" as *u8, pl_exposure_pure(10, 7, 2) == 5, ctr)
100 gv_check("G8 a clean log has zero exposure" as *u8, pl_exposure_pure(10, 10, 0) == 0, ctr)
101
102 // ---- H: the withholding decision composes both doctrines ----
103 gv_check("H1 attorney-client privilege alone justifies withholding" as *u8, pl_may_withhold_pure(1, PL_NONE, 1, 1) == 1, ctr)
104 gv_check("H2 opinion work product alone justifies withholding" as *u8, pl_may_withhold_pure(0, PL_OPINION_WP, 1, 1) == 1, ctr)
105 gv_check("H3 fact work product pierced by need+hardship -> must produce" as *u8, pl_may_withhold_pure(0, PL_FACT_WP, 1, 1) == 0, ctr)
106 gv_check("H4 fact work product not pierced -> may withhold" as *u8, pl_may_withhold_pure(0, PL_FACT_WP, 1, 0) == 1, ctr)
107 gv_check("H5 neither doctrine applies -> must produce" as *u8, pl_may_withhold_pure(0, PL_NONE, 0, 0) == 0, ctr)
108
109 return gv_verdict("PRIVILEGE-LOG" as *u8, ctr, "1 of 32 AC combos qualifies; opinion WP never pierced; 502(b) needs all three" as *u8)
110}