* test(#4130): failing-first regressions for --context flag + parseDecisions hardening
Block A (flag): check decision-coverage-plan --context <path> must route
identically to the positional form; flag wins over positional context;
valueless --context falls through to the #2770 fail-closed caller error;
verify keeps its positional surface (flag is plan-only). RED on base:
the flag token lands in the args[2] phase slot (false uncovered) or the
args[3] context slot (silent CONTEXT.md-missing skip).
Block B (hardening): regex-lattice asserts pin the atomic-ID wrapper
(?=(X))\1 and the em-dash first-separator narrowing [^*—–]*[—–] plus the
no-adjacent-overlap property; a differential property compares the module
against a frozen copy of the pre-hardening grammars (reference validated
against the base build: 60k generated lines, 0 mismatches); 40k cliff
shapes assert correct outcomes with no wall-time asserts (repo rule).
A12: partitionPredicateArgs keeps one parser behind parsePredicateFlags.
* fix(#4130): --context flag for check decision-coverage-plan + quadratic-backtracking hardening in parseDecisions
(A) check decision-coverage-plan --context <path> — sibling convention
(check predicate, #2008): --flag value pairs parsed by the new shared
partitionPredicateArgs (parsePredicateFlags reimplemented as its flags
half — one parser, cannot diverge), the flag winning over a same-purpose
positional, positionals kept (no sibling deprecates them; the plan-phase
workflow caller passes positionals), valueless --context falls through
to the #2770 fail-closed caller error. Repair of the routing accident
where --context landed in the args[2] phase slot (false uncovered) or
the literal token in the args[3] context slot (silent green skip).
(B) parseDecisions regex seam hardened, byte-identical on all legal
inputs: the three bullet grammars consume the ID atomically via the
(?=(X))\1 lookahead emulation (kills the tail/[^:*]* O(n^2) re-split,
~1.1s @ 40k), and the em-dash first separator narrows [^*]*[—–] to
[^*—–]*[—–] (kills the dash-position O(n^2) retry, ~1.7s @ 40k). Group
indices unchanged (handlers untouched). Pinned by regex-lattice tests,
a differential fast-check property vs the frozen pre-hardening grammars,
and 40k cliff/legal-shape outcome tests (no wall-time asserts per repo
rule — no deterministic engine step counter exists in Node).
* docs+test(#4130): document --context invocation; harden lattice test tooling
- docs/CONFIGURATION.md Decision Coverage Gates: new 'Invoking the plan
gate directly' block documenting both the positional and --context
forms, flag precedence, and the valueless-flag fail-closed semantics
(same place the gate's behavior is documented; sibling check predicate
documents its flags the same way).
- Two changeset fragments per the maintainer brief (Added: flag; Fixed:
hardening), PR numbers to be backfilled.
- tests/decisions.test.cjs review fixes: readRegExpTemplate template
escaping (bare ')' SyntaxError), range-aware lattice checker with
backreference skip and template unescape, honest A1 contract, lint
escape warning.
* fix(#4130): valueless --context fails closed per #2770; A8 isolates flag-vs-positional context
Suite-caught fixes from the first verify run:
- cmdDecisionCoveragePlan now refuses a flag-shaped token as the
positional context path: a bare valueless --context stays a positional
(sibling parser semantics, unchanged) but reading it as a PATH would
turn a caller mistake into a silent 'CONTEXT.md missing' green skip —
exactly what #2770's fail-closed law forbids. Now falls through to
the missing-context-argument error, as documented.
- A8 test compares decoy-positional+flag against flag-with-phase (phase
held constant) so the row isolates WHICH context was read; the old
form compared against a no-phase invocation that could never match.
* chore(#4130): backfill PR number in changeset fragments (PR #4374)
---------
Co-authored-by: sim <sim@local>