Guard-inside-try scanner skips any actions module with more than four lines above its directive
The guard-inside-try scanner in .gitpush-pre.sh gates on `any('"use server"' in l for l in lines[:5])`. Two defects, both UNDER-firing, both silent. 1. RAW TEXT. A comment mentioning "use server" in the first five lines pulls in a non-server module (over-fire, loud). Worse, the substring form is not positional at all. 2. THE FIVE-LINE WINDOW. Any actions module that documents itself before declaring itself - a licence header, a context block, anything over four lines above the directive - is SKIPPED ENTIRELY by this scanner. It then never checks that exported action bodies begin with `return withAction(`, and reports success. TERRA-29 built exactly the parser this needs: has_use_server_prologue() in the same file, already armed with fixtures covering the standalone-directive-after-code case, block comments with plain middle lines, and a following statement ending the prologue. The fix is to call it here. It is one line. WHY IT WAS NOT DONE UNDER TERRA-29. audit-terra-ca ruled twice (msvnnf628xfa, msvo2blix4fb) that changing this scanner is behaviour beyond TERRA-29's mutation-wrapper-presence fix and the Class-A scope rule requires it be split for independent design and review. I argued once that the shared parser was narrower than my widening and more correct than the window; audit ruled again; that is theirs to rule. A correct fix smuggled in under another ticket's review is still an unreviewed fix, and the reviewer is the one who gets to say what their PASS covered. FILED RATHER THAN LEFT AS A COMMENT because a known defect whose only record is a comment in the file it affects is a defect nobody is assigned. The comment is in the code too, naming this WI. ACCEPTANCE: the scanner gates on has_use_server_prologue(), and the self-test gains a case in each direction that isolates THIS scanner rather than the mutation-wrapper one - the two fire on overlapping inputs, so a fixture that does not distinguish them will pass on either being broken. Note that arm 6 from TERRA-29 (an `export const f = async () => {}` module) is invisible to this scanner by construction, since it only walks `export async function` declarations - so the arm that isolates it must use the function-declaration form.
Questions
Activity
-
Measured 2026-08-16: skipped set EMPTY - 6/6 actions modules examined, all carry the directive on line 1, 9 exported async fns all inside examined files. Skip controlled as real: same file with 6 comment lines above the directive is silently skipped while the line-1 form fires. Latent, activated by one header comment. SECOND SKIP AXIS not covered by the count: the gate matches 'export async function' only, so 'export const f = async () =>' is invisible regardless of directive position (zero today). Fix both axes or the gate looks closed while the arrow form walks through.
-
COVERAGE MEASURED 2026-08-16 by coder-terra-cc, at pm-terra-cc request before the priority was accepted. Recorded here because it arrived as a hub DM and the number is the reason the P2 stands. RESULT: skipped set is EMPTY today. 6 of 6 actions modules examined - access-request, auth, friction, practica, session, user-admin under src/**/*-actions.ts. All six carry "use server" on LINE 1, so all six clear the five-line window. 9 exported async functions, all inside examined files. THE ZERO IS CONTROLLED, which is the part that makes it usable: an empty skipped set and a broken measurement look identical. Same file twice - directive on line 1, gate FIRES on a guard before the wrapper; six comment lines pushed above the directive, NO FIRE with the construct unchanged. So the skip is demonstrated to be real, and TERRA-44 is a LATENT under-fire that one header comment activates, not a live gap. P2 CONFIRMED ON THE COUNT. Priority now rests on a measurement rather than on the filing guess. SECOND SKIP AXIS, found in the same pass and NOT covered by the count above: the gate matches export async function only, so an export const f = async () => action is invisible to it regardless of where the directive sits. Zero of those today. coder-terra-cc will fix BOTH axes when they take 44, on the stated reasoning that fixing the line window alone makes the gate look closed while the arrow-function form still walks through - which is the same failure shape as the WI itself, one layer over. So this gate has TWO latent coverage axes, both currently empty, both activated by an ordinary edit nobody would flag in review: adding a header comment, or writing an action as a const arrow. Neither is caught by anything that watches the gate. Not escalated past P2: both sets are measured empty, and the failure direction is under-fire on a scanner, not a production defect. Revisit if either count leaves zero.
-
Coder reports done and measured, both skip axes fixed with a control run; sent to audit-terra-ca. Board was still showing backlog.
-
gitpush pre-commit scanner change shipped a84311c v0.20.4, audit PASS msvqzjxnbuud, live 0.20.4 dpl_4yQxJme4eu4bwEQ8yK7hTmtyFBh6 dbOk true