nx_fsops_gate.nx source
↩ module page · 293 lines · 21039 B
1// nx_fsops_gate.nx -- gates the consolidated fs tool on synthetic fixtures, asserting RETURN VALUES:
2// exact byte-count read, MARKED truncation, secret DENY (compiled default), DATA-DRIVEN deny toggled
3// ON->OFF via fs_read_deny.conf (both directions = discriminating), absent-path grace, dir listing count,
4// and TRUE SIZE (lseek to EOF, zero bytes read; absent -1 vs a real empty file 0).
5// Runner must clean /tmp/fsgate first. The conf is written in CWD (prod lookup path) and REMOVED after.
6// Exit 0 only on all-PASS. license_tier: ORIGINAL expect_exit: 0
7import "nx_fsops_lib.nx"
8import "nx_fio.nx" // fio_unlink -- conf lifecycle cleanup
9import "nx_seg_store.nx" // ss_writefile -- fixture author
10import "nx_gate_verdict.nx" // D001 MIGRATE-ON-TOUCH: inherit the base class, do not roll a verdict
11
12const GATE_CHECKS: i64 = 46
13const DIR_MODE: i64 = 0x1ed // 0755
14const FIX_BYTES: i64 = 9 // len("hello-fs\n")
15const SMALL_CAP: i64 = 4 // forces the truncation path
16const FIX_ENTRIES: i64 = 3 // files authored into the fixture dir
17const FG_RB_CAP: i64 = 256 // read-back buffer for write/edit content assertions
18
19// read path into a NUL-terminated buffer and compare to expect (1 = byte-identical)
20func fg_readback_eq(path: *u8, expect: *u8) -> i64 {
21 let b: *u8 = sys_mmap(FG_RB_CAP)
22 let n: i64 = vw_read(path, b, FG_RB_CAP - 1)
23 if n < 0 { return 0 }
24 b[n] = 0 as u8
25 return fsx_seq(b, expect)
26}
27
28// D001: delegate to the base class instead of counting by hand. Kept as a thin SHIM rather than renaming
29// 28 call sites, so this migration is provably behaviour-only -- not one tooth is touched by it.
30func fg_check(name: *u8, ok: i64, pass: *i64) -> i64 { return gv_check(name, ok, pass) }
31func fg_write(path: *u8, body: *u8) -> i64 {
32 var n: i64 = 0
33 while body[n] != (0 as u8) { n = n + 1 }
34 return ss_writefile(path, body, n)
35}
36// write via the tool-under-test with the length computed (no magic byte counts in checks)
37func fg_put(path: *u8, body: *u8) -> i64 { return fsx_write(path, body, vw_slen(body)) }
38
39func main(argc: i64, argv: *i64) -> i64 {
40 let pass: *i64 = gv_ctr() // [0]=passed [1]=EXECUTED -- the base class owns both counters
41 sys_mkdir("/tmp/fsgate" as *u8, DIR_MODE)
42 // IDEMPOTENCY (rule 10), fixed 2026-07-31. /tmp/fsgate PERSISTS between runs and the LATER tests
43 // author w.txt / blockw.txt / d.txt / e.txt / lines.txt into it, so ls-entry-count saw 8 entries
44 // instead of FIX_ENTRIES=3. This gate therefore PASSED EXACTLY ONCE, on a clean machine, and has
45 // FAILED EVERY RUN SINCE -- a verdict that depends on whether the gate has run before is not
46 // measuring the code under test. Reset every path this gate ever authors, not just the 3 fixtures.
47 fio_unlink("/tmp/fsgate/normal.txt" as *u8)
48 fio_unlink("/tmp/fsgate/mysecret_key.bin" as *u8)
49 fio_unlink("/tmp/fsgate/blockme.txt" as *u8)
50 fio_unlink("/tmp/fsgate/w.txt" as *u8)
51 fio_unlink("/tmp/fsgate/blockw.txt" as *u8)
52 fio_unlink("/tmp/fsgate/d.txt" as *u8)
53 fio_unlink("/tmp/fsgate/e.txt" as *u8)
54 fio_unlink("/tmp/fsgate/lines.txt" as *u8)
55 fio_unlink("/tmp/fsgate/tail.txt" as *u8)
56 fio_unlink("/tmp/fsgate/empty.txt" as *u8)
57 fio_unlink("/tmp/fsgate/empty.txt" as *u8) // authored by T27, AFTER T7 -- reset here, BEFORE it
58 fio_unlink("/tmp/fsgate/j.log" as *u8) // authored by T29-T31 (append journal) -- same law
59 fio_unlink("/tmp/fsgate/t.log" as *u8) // authored by T32 (unterminated-tail heal)
60 // T13c's fixture now lives OUTSIDE this directory (/tmp/fsgate_ins.txt) so it can never inflate
61 // ls-entry-count by construction. This unlink clears the STRAY left by the runs before that move.
62 // THE COMMENT ABOVE SAYS IN PLAIN WORDS TO RESET EVERY PATH THIS GATE EVER AUTHORS, AND ON 2026-09-04
63 // I AUTHORED ONE INSIDE THE COUNTED DIR AND DID NOT ADD IT HERE -- the same defect this block exists
64 // for, committed again by the next author, which is exactly what a reset LIST invites. The durable
65 // shape is a fixture directory emptied wholesale rather than name by name.
66 fio_unlink("/tmp/fsgate/ins.txt" as *u8)
67 fg_write("/tmp/fsgate/normal.txt" as *u8, "hello-fs\n" as *u8)
68 fg_write("/tmp/fsgate/mysecret_key.bin" as *u8, "SHOULD-NEVER-PRINT\n" as *u8)
69 fg_write("/tmp/fsgate/blockme.txt" as *u8, "hello-fs\n" as *u8)
70
71 // T1 exact read
72 fg_check("read-exact-bytes" as *u8, (fsx_read("/tmp/fsgate/normal.txt" as *u8, 0) == FIX_BYTES) as i64, pass)
73 // T2 bounded read hits the cap (truncation path, MARKED)
74 fg_check("read-truncation-marked" as *u8, (fsx_read("/tmp/fsgate/normal.txt" as *u8, SMALL_CAP) == SMALL_CAP) as i64, pass)
75 // T3 compiled deny needle ("key") refuses secret material
76 fg_check("deny-default-key" as *u8, (fsx_read("/tmp/fsgate/mysecret_key.bin" as *u8, 0) == 0 - (2 as i64)) as i64, pass)
77 // T4 DATA-DRIVEN deny ON: conf needle blocks an otherwise-fine file
78 fg_write("fs_read_deny.conf" as *u8, "blockme\n" as *u8)
79 fg_check("deny-conf-on" as *u8, (fsx_read("/tmp/fsgate/blockme.txt" as *u8, 0) == 0 - (2 as i64)) as i64, pass)
80 // T5 DATA-DRIVEN deny OFF: removing the conf restores the read (proves the conf DRIVES the policy)
81 fio_unlink("fs_read_deny.conf" as *u8)
82 fg_check("deny-conf-off" as *u8, (fsx_read("/tmp/fsgate/blockme.txt" as *u8, 0) == FIX_BYTES) as i64, pass)
83 // T6 absent path is graceful
84 fg_check("read-absent-graceful" as *u8, (fsx_read("/tmp/fsgate/nope.txt" as *u8, 0) == (0 - 1)) as i64, pass)
85 // T7 ls counts the 3 fixture entries (. and .. skipped)
86 fg_check("ls-entry-count" as *u8, (fsx_ls("/tmp/fsgate" as *u8) == FIX_ENTRIES) as i64, pass)
87
88 // ==== write/edit half (nx_fs_write) ==== (lengths computed with vw_slen -- no magic byte counts)
89 // T8 atomic write + byte-identical read-back
90 var wr: i64 = fg_put("/tmp/fsgate/w.txt" as *u8, "alpha beta gamma\n" as *u8)
91 var ok8: i64 = 0
92 if wr == vw_slen("alpha beta gamma\n" as *u8) { ok8 = fg_readback_eq("/tmp/fsgate/w.txt" as *u8, "alpha beta gamma\n" as *u8) }
93 fg_check("write-roundtrip" as *u8, ok8, pass)
94 // T9 overwrite lands whole (atomic replace, not append/partial)
95 wr = fg_put("/tmp/fsgate/w.txt" as *u8, "second\n" as *u8)
96 var ok9: i64 = 0
97 if wr == vw_slen("second\n" as *u8) { ok9 = fg_readback_eq("/tmp/fsgate/w.txt" as *u8, "second\n" as *u8) }
98 fg_check("write-overwrite-whole" as *u8, ok9, pass)
99 // T10 write DENIED on secret-needle path AND nothing created (negative control)
100 var ok10: i64 = 0
101 if fg_put("/tmp/fsgate/deploy.pem" as *u8, "x" as *u8) == 0 - (2 as i64) {
102 let probe: *u8 = sys_mmap(FG_RB_CAP)
103 if vw_read("/tmp/fsgate/deploy.pem" as *u8, probe, FG_RB_CAP - 1) < 0 { ok10 = 1 }
104 }
105 fg_check("write-deny-secret-nocreate" as *u8, ok10, pass)
106 // T11 write DENIED in the OS device namespace (rule 26 never-brick, seam-enforced)
107 fg_check("write-deny-devns" as *u8, (fg_put("/dev/null" as *u8, "x" as *u8) == 0 - (2 as i64)) as i64, pass)
108 // T12 data-driven WRITE deny: conf ON blocks, then conf OFF restores (both directions discriminate)
109 fg_write("fs_write_deny.conf" as *u8, "blockw\n" as *u8)
110 var ok12: i64 = 0
111 if fg_put("/tmp/fsgate/blockw.txt" as *u8, "x\n" as *u8) == 0 - (2 as i64) {
112 fio_unlink("fs_write_deny.conf" as *u8)
113 if fg_put("/tmp/fsgate/blockw.txt" as *u8, "x\n" as *u8) == vw_slen("x\n" as *u8) { ok12 = 1 }
114 }
115 fg_check("write-deny-conf-both-ways" as *u8, ok12, pass)
116 // T13 edit UNIQUE match replaces and preserves the rest
117 fg_put("/tmp/fsgate/e.txt" as *u8, "alpha beta gamma\n" as *u8)
118 var ok13: i64 = 0
119 if fsx_edit("/tmp/fsgate/e.txt" as *u8, "beta" as *u8, "BETA" as *u8, 0) == vw_slen("alpha BETA gamma\n" as *u8) {
120 ok13 = fg_readback_eq("/tmp/fsgate/e.txt" as *u8, "alpha BETA gamma\n" as *u8)
121 }
122 fg_check("edit-unique-replaces" as *u8, ok13, pass)
123 // T13b NEG-CONTROL FIRST: a predicate that fires on everything discriminates nothing, so prove it
124 // answers 0 on a true replace BEFORE trusting it to answer 1 on an insert.
125 var ok13b: i64 = 0
126 if fsx_edit_self_anchored("beta" as *u8, "BETA" as *u8) == 0 {
127 if fsx_edit_self_anchored("beta" as *u8, "beta gamma" as *u8) == 1 { ok13b = 1 }
128 }
129 fg_check("neg-control-selfanchor-predicate-discriminates" as *u8, ok13b, pass)
130 // T13c THE HAZARD, WITNESSED RATHER THAN ASSERTED. The SAME self-anchored edit applied TWICE succeeds
131 // BOTH times and the row lands twice -- this is precisely the re-issue that estate doctrine calls free,
132 // and until this tooth existed the four edit teeth had only ever seen data on which the contract holds.
133 // A green that never had a corresponding red is not evidence.
134 fg_put("/tmp/fsgate_ins.txt" as *u8, "head\ntail\n" as *u8)
135 var ok13c: i64 = 0
136 if fsx_edit("/tmp/fsgate_ins.txt" as *u8, "head\n" as *u8, "head\nNEW\n" as *u8, 0) > 0 {
137 if fsx_edit("/tmp/fsgate_ins.txt" as *u8, "head\n" as *u8, "head\nNEW\n" as *u8, 0) > 0 {
138 ok13c = fg_readback_eq("/tmp/fsgate_ins.txt" as *u8, "head\nNEW\nNEW\ntail\n" as *u8)
139 }
140 }
141 fg_check("selfanchored-retry-DOUBLE-APPLIES-hazard-witnessed" as *u8, ok13c, pass)
142 // T14 (declared after the self-anchored-edit teeth) NOMATCH leaves the file untouched
143 var ok14: i64 = 0
144 if fsx_edit("/tmp/fsgate/e.txt" as *u8, "zeta" as *u8, "x" as *u8, 0) == 0 - FSX_RC_NOMATCH {
145 ok14 = fg_readback_eq("/tmp/fsgate/e.txt" as *u8, "alpha BETA gamma\n" as *u8)
146 }
147 fg_check("edit-nomatch-unchanged" as *u8, ok14, pass)
148 // T15 edit AMBIGUOUS without `all` refuses and leaves the file untouched
149 fg_put("/tmp/fsgate/d.txt" as *u8, "dup dup\n" as *u8)
150 var ok15: i64 = 0
151 if fsx_edit("/tmp/fsgate/d.txt" as *u8, "dup" as *u8, "x" as *u8, 0) == 0 - FSX_RC_AMBIG {
152 ok15 = fg_readback_eq("/tmp/fsgate/d.txt" as *u8, "dup dup\n" as *u8)
153 }
154 fg_check("edit-ambiguous-unchanged" as *u8, ok15, pass)
155 // T16 edit `all` replaces every occurrence
156 var ok16: i64 = 0
157 if fsx_edit("/tmp/fsgate/d.txt" as *u8, "dup" as *u8, "x" as *u8, 1) == vw_slen("x x\n" as *u8) {
158 ok16 = fg_readback_eq("/tmp/fsgate/d.txt" as *u8, "x x\n" as *u8)
159 }
160 fg_check("edit-all-replaces-every" as *u8, ok16, pass)
161
162 // T17 lines returns the EXACT requested window (line-addressed read: grep's file:LINE now composes)
163 fg_write("/tmp/fsgate/lines.txt" as *u8, "L1\nL2\nL3\nL4\nL5\n" as *u8)
164 var ok17: i64 = 0
165 if fsx_read_lines("/tmp/fsgate/lines.txt" as *u8, 2, 2) == vw_slen("L2\nL3\n" as *u8) { ok17 = 1 }
166 fg_check("lines-exact-window" as *u8, ok17, pass)
167 // T18 lines BEYOND EOF fails LOUD (0 bytes + explicit banner) -- never a silent empty window
168 var ok18: i64 = 0
169 if fsx_read_lines("/tmp/fsgate/lines.txt" as *u8, 99, 5) == 0 { ok18 = 1 }
170 fg_check("lines-beyond-eof-loud" as *u8, ok18, pass)
171 // T19 lines INHERITS the secret deny-list -- a NEW read path must never become a key-theft primitive
172 var ok19: i64 = 0
173 if fsx_read_lines("/tmp/fsgate/mysecret_key.bin" as *u8, 1, 5) == 0 - (2 as i64) { ok19 = 1 }
174 fg_check("lines-inherits-secret-deny" as *u8, ok19, pass)
175
176 // T34-T38 TAIL (2026-09-03): the end of a file is a question with ONE right answer, and this verb exists
177 // because a hand-chosen `lines` window was published as a log's end while its envelope said otherwise.
178 // T34 the last two lines, exactly -- the count walks BACKWARD from the file's end, never forward from a guess
179 var ok34: i64 = 0
180 if fsx_tail("/tmp/fsgate/lines.txt" as *u8, 2) == vw_slen("L4\nL5\n" as *u8) { ok34 = 1 }
181 fg_check("tail-last-two-lines-exact" as *u8, ok34, pass)
182 // T35 a count past the file's line total returns the WHOLE file, never an error and never a partial window
183 var ok35: i64 = 0
184 if fsx_tail("/tmp/fsgate/lines.txt" as *u8, 99) == vw_slen("L1\nL2\nL3\nL4\nL5\n" as *u8) { ok35 = 1 }
185 fg_check("tail-count-past-total-returns-whole-file" as *u8, ok35, pass)
186 // T36 an UNTERMINATED last line is still a line: "A\nB\nC" tail 2 is "B\nC" (5 bytes), and the envelope
187 // must say last_line_terminated=0 -- a partial last line is evidence of a writer mid-flight
188 fg_write("/tmp/fsgate/tail.txt" as *u8, "A\nB\nC" as *u8)
189 var ok36: i64 = 0
190 if fsx_tail("/tmp/fsgate/tail.txt" as *u8, 2) == vw_slen("B\nC" as *u8) { ok36 = 1 }
191 fg_check("tail-unterminated-last-line-counts" as *u8, ok36, pass)
192 // T37 tail INHERITS the secret deny-list -- a new read path must never become a key-theft primitive
193 var ok37: i64 = 0
194 if fsx_tail("/tmp/fsgate/mysecret_key.bin" as *u8, 2) == 0 - (2 as i64) { ok37 = 1 }
195 fg_check("tail-inherits-secret-deny" as *u8, ok37, pass)
196 // T38 neg-control: an EMPTY file yields 0 bytes WITH a banner -- loud, never a silent nothing, never a crash
197 fg_write("/tmp/fsgate/empty.txt" as *u8, "" as *u8)
198 var ok38: i64 = 0
199 if fsx_tail("/tmp/fsgate/empty.txt" as *u8, 3) == 0 { ok38 = 1 }
200 fg_check("neg-control-tail-empty-file-is-loud-zero" as *u8, ok38, pass)
201
202 // T20-T23 COMPARE-AND-SWAP, and T20 is the whole point (seq1422): the CAS
203 // guard shipped REFUSING every correct expectation because only its refusal
204 // path had ever been driven. ★LAW: A GUARD'S SUCCESS PATH MUST BE TESTED,
205 // NOT JUST ITS REFUSAL PATH -- an always-refusing guard is not safety, it is
206 // a bypass generator (it drove authors to raw scp/ssh, the unguarded write
207 // path that destroyed shipped work in seq1439/seq1392).
208 var ok20: i64 = 0
209 if fsx_cas_ok(5986, "expect=5986" as *u8) == 1 { ok20 = 1 }
210 fg_check("cas-correct-expect-ALLOWS" as *u8, ok20, pass)
211 var ok21: i64 = 0
212 if fsx_cas_ok(5986, "expect=42" as *u8) == 0 { ok21 = 1 }
213 fg_check("cas-stale-expect-REFUSES" as *u8, ok21, pass)
214 var ok22: i64 = 0
215 if fsx_cas_ok(5986, "expect=any" as *u8) == 1 { ok22 = 1 }
216 fg_check("cas-any-is-the-declared-escape-hatch" as *u8, ok22, pass)
217 // a token carrying no digits must REFUSE, never silently read as 0 == size
218 var ok23: i64 = 0
219 if fsx_cas_ok(0, "expect=" as *u8) == 0 { ok23 = 1 }
220 fg_check("cas-empty-value-REFUSES-not-zero-match" as *u8, ok23, pass)
221
222 // ==== T24-T28 TRUE SIZE (debt 1786054029). fsx_size lseeks to EOF and reads ZERO bytes. ====
223 fg_check("size-exact-bytes" as *u8, (fsx_size("/tmp/fsgate/normal.txt" as *u8) == FIX_BYTES) as i64, pass)
224 // T25 IS THE LOAD-BEARING ONE. The obvious WRONG implementation of `size` is "count the bytes I managed
225 // to read", and it passes T24 on every file smaller than its cap -- which is every fixture here. Driving
226 // the SAME file through a DELIBERATELY SMALL read cap forces the two answers apart (4 vs 9), so only a
227 // real lseek can satisfy both halves. LAW: A TOOTH THE WRONG IMPLEMENTATION ALSO PASSES IS NOT A TOOTH.
228 var ok25: i64 = 0
229 if fsx_read("/tmp/fsgate/normal.txt" as *u8, SMALL_CAP) == SMALL_CAP {
230 if fsx_size("/tmp/fsgate/normal.txt" as *u8) == FIX_BYTES { ok25 = 1 }
231 }
232 fg_check("size-is-not-a-capped-read" as *u8, ok25, pass)
233 // T26/T27 are a PAIR and neither means anything alone: absent must be -1 while a real zero-byte file
234 // must be 0. fsx_read folds BOTH to -1 by design (see fsx_fail), so only asserting the two together
235 // proves fsx_size did not inherit that fold. A reader that conflates them cannot tell a lane that never
236 // wrote from a lane whose file vanished.
237 fg_check("size-absent-is-minus-one" as *u8, (fsx_size("/tmp/fsgate/nope.txt" as *u8) == (0 - 1)) as i64, pass)
238 fg_write("/tmp/fsgate/empty.txt" as *u8, "" as *u8)
239 fg_check("size-empty-is-zero-not-absent" as *u8, (fsx_size("/tmp/fsgate/empty.txt" as *u8) == 0) as i64, pass)
240 // T28 a NEW read path must never become a key-theft primitive -- even a metadata-only one (cf. T19)
241 fg_check("size-inherits-secret-deny" as *u8, (fsx_size("/tmp/fsgate/mysecret_key.bin" as *u8) == 0 - (2 as i64)) as i64, pass)
242 // ==== T29-T33 APPEND (2026-09-02): the coordination verb. A board is a journal; journals are appended. ====
243 // T29 append creates an absent file and lands the row whole
244 var ok29: i64 = 0
245 if fsx_append("/tmp/fsgate/j.log" as *u8, "row-1\n" as *u8, vw_slen("row-1\n" as *u8)) == vw_slen("row-1\n" as *u8) { ok29 = fg_readback_eq("/tmp/fsgate/j.log" as *u8, "row-1\n" as *u8) }
246 fg_check("append-creates-and-lands-whole" as *u8, ok29, pass)
247 // T30 THE COORDINATION PROPERTY: a second append lands AFTER the first and rewrites nothing
248 var ok30: i64 = 0
249 if fsx_append("/tmp/fsgate/j.log" as *u8, "row-2\n" as *u8, vw_slen("row-2\n" as *u8)) == vw_slen("row-2\n" as *u8) { ok30 = fg_readback_eq("/tmp/fsgate/j.log" as *u8, "row-1\nrow-2\n" as *u8) }
250 fg_check("append-orders-after-existing-rows-rewrites-nothing" as *u8, ok30, pass)
251 // T31 neg-control: an unterminated row is REFUSED by name and the file is untouched
252 var ok31: i64 = 0
253 if fsx_append("/tmp/fsgate/j.log" as *u8, "glue" as *u8, vw_slen("glue" as *u8)) == FSX_APP_NONL { ok31 = fg_readback_eq("/tmp/fsgate/j.log" as *u8, "row-1\nrow-2\n" as *u8) }
254 fg_check("neg-control-append-refuses-unterminated-row-file-unchanged" as *u8, ok31, pass)
255 // T32 a tail left unterminated by a rewrite is healed INSIDE the same locked write (bytes = row + 1)
256 fg_write("/tmp/fsgate/t.log" as *u8, "tail-no-nl" as *u8)
257 var ok32: i64 = 0
258 if fsx_append("/tmp/fsgate/t.log" as *u8, "row\n" as *u8, vw_slen("row\n" as *u8)) == vw_slen("row\n" as *u8) + 1 { ok32 = fg_readback_eq("/tmp/fsgate/t.log" as *u8, "tail-no-nl\nrow\n" as *u8) }
259 fg_check("append-heals-an-unterminated-tail-in-one-write" as *u8, ok32, pass)
260 // T33 neg-control: a NEW write path must never become a way into the secret namespace (cf. T10/T19/T28)
261 fg_check("neg-control-append-inherits-secret-deny" as *u8, (fsx_append("/tmp/fsgate/mysecret_key.bin" as *u8, "x\n" as *u8, vw_slen("x\n" as *u8)) == 0 - (2 as i64)) as i64, pass)
262 // ==== T34-T39 JOB, the claim-or-out verb (ES26, 2026-09-06): ONE call, six NAMED states, on a fixture dir OUTSIDE
263 // /tmp/fsgate so ls-entry-count cannot be inflated by construction (the T13c lesson) ====
264 sys_mkdir("/tmp/fsgate_jobs" as *u8, DIR_MODE)
265 fio_unlink("/tmp/fsgate_jobs/job_1.claim" as *u8)
266 fio_unlink("/tmp/fsgate_jobs/job_2.claim" as *u8)
267 fio_unlink("/tmp/fsgate_jobs/job_2.out" as *u8)
268 fio_unlink("/tmp/fsgate_jobs/job_3.claim" as *u8)
269 fio_unlink("/tmp/fsgate_jobs/job_4.claim" as *u8)
270 fio_unlink("/tmp/fsgate_jobs/job_5.claim" as *u8)
271 // T34 an id nobody claimed is NOSUCH, never RUNNING
272 fg_check("job-unclaimed-id-is-nosuch-never-running" as *u8, (fsx_job_at("/tmp/fsgate_jobs/" as *u8, "1" as *u8) == FSX_JOB_NOSUCH) as i64, pass)
273 // T35 a DONE marker with bytes>0 reads the output in the SAME call
274 fg_write("/tmp/fsgate_jobs/job_2.claim" as *u8, "state=DONE rc=0 exit=0 bytes=6\n" as *u8)
275 fg_write("/tmp/fsgate_jobs/job_2.out" as *u8, "hello\n" as *u8)
276 fg_check("job-done-marker-reads-the-output-in-one-call" as *u8, (fsx_job_at("/tmp/fsgate_jobs/" as *u8, "2" as *u8) == FSX_JOB_DONE) as i64, pass)
277 // T36 a DONE marker with bytes=0 is DONE-EMPTY: produced nothing, NOT still working
278 fg_write("/tmp/fsgate_jobs/job_3.claim" as *u8, "state=DONE rc=0 exit=0 bytes=0\n" as *u8)
279 fg_check("job-done-empty-is-named-not-running" as *u8, (fsx_job_at("/tmp/fsgate_jobs/" as *u8, "3" as *u8) == FSX_JOB_DONE_EMPTY) as i64, pass)
280 // T37 a CLAIMED marker is RUNNING and reads no output
281 fg_write("/tmp/fsgate_jobs/job_4.claim" as *u8, "state=CLAIMED ts=1788700000\n" as *u8)
282 fg_check("job-claimed-marker-is-running" as *u8, (fsx_job_at("/tmp/fsgate_jobs/" as *u8, "4" as *u8) == FSX_JOB_RUNNING) as i64, pass)
283 // T38 a marker with no known state token is UNPARSED, printed as data, never guessed DONE
284 fg_write("/tmp/fsgate_jobs/job_5.claim" as *u8, "state=WEIRD\n" as *u8)
285 fg_check("job-unknown-state-is-unparsed-never-guessed" as *u8, (fsx_job_at("/tmp/fsgate_jobs/" as *u8, "5" as *u8) == FSX_JOB_UNPARSED) as i64, pass)
286 // T39 neg-control: a path-shaped id is REFUSED before any file is opened (the verb cannot leave its directory)
287 fg_check("neg-control-job-path-shaped-id-refused" as *u8, (fsx_job_at("/tmp/fsgate_jobs/" as *u8, "../fsgate/normal.txt" as *u8) == FSX_JOB_REFUSED) as i64, pass)
288 // ANTI-VACUITY. gv_verdict judges passed-vs-EXECUTED, so a tooth that silently stops running lowers
289 // BOTH numbers and the gate still reads GREEN. GATE_CHECKS is the DECLARED count, so assert that the
290 // executed count equals it. A GATE THAT ONLY COMPARES PASSED TO EXECUTED CANNOT SEE A MISSING TOOTH.
291 gv_check("all-declared-teeth-ran" as *u8, (pass[1] == GATE_CHECKS) as i64, pass)
292 return gv_verdict("FSOPS-GATE" as *u8, pass, "read/lines/ls/write/edit/CAS/size/append" as *u8)
293}