fix(config): report every permissive setting in a file, not the first one

NodeGoat's server.js configures a permissive session at line 78 and disables template
auto-escaping at line 135, both inside the same function. The arbiter returned one verdict per
question, so the escaping defect that task 14.3 added was detected on every run and reported on
none: which of two real defects a contributor saw depended on where in the file it sat.

Configuration now returns one verdict per setting whose value the model could read. The pipeline
already emitted one finding per entailed answer, so this arbiter was the only place still folding
them to one.

Three boundaries are drawn rather than assumed.

- A setting whose value is COMPUTED stays one verdict per region. That band is a question for the
  judge rather than a finding, and returning every undecided setting would multiply model calls
  for claims the graph did not establish.
- A call carrying two permissive literals is one finding. cors({origin: true, credentials: true})
  is one misconfiguration, not two.
- Config verdicts now carry a path:line:function location. Without one they shared the region's
  identity and the deduplicator kept a single finding, so the plural answer collapsed straight
  back to one. That is the same gap dominance carried until its findings stopped arriving with no
  line at all.

Dominance is left answering once per region, and that is settled rather than pending: its claim is
that a region contradicts itself, so the region is the unit and a second verdict would restate the
same inconsistency. The pipeline now says so where it used to call this a known gap.

Measured: NodeGoat's config_secrets goes from one finding to two, server.js:78 for the session and
server.js:135 for the disabled escaping, with the applied marked.setOptions fix between them
staying silent. VAmPI is unchanged and no other family moved.

1,417 tests pass, seventeen skipped; thirteen Joern-gated query tests pass in the image.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
This commit is contained in:
Marius Ciepluch
2026-09-20 16:30:04 +02:00
co-authored by Claude Opus 5
parent e6bdac46e2
commit 3bd844055c
6 changed files with 167 additions and 20 deletions
+7 -1
View File
@@ -183,6 +183,11 @@ public routes and both wrong, and an application-wide scope entails four true de
same two wrong ones. Neither scope can tell a public route from a protected one, so the carried
rung stays capped and that question stays with the judge.
Configuration reports every setting it decides, not the first one in the file. NodeGoat's
server.js now carries both its permissive session and its disabled template auto-escaping, each
with its own site; the escaping defect had been detected on every run since task 14.3 and
reported on none, because an earlier setting in the same function won the single verdict.
Closing the second gap surfaced four defects, three of which were false positives it would
otherwise have shipped: a permissive-value set shared across settings whose booleans have
opposite polarity, a dotted setting matched on its trailing segment alone, a flow query asked of
@@ -196,4 +201,5 @@ Evidence: [family detection census](../../../benchmarks/measurements/2026-09-19-
[output encoding family](../../../benchmarks/measurements/2026-09-19-output-encoding-family.json),
[access control across the module split](../../../benchmarks/measurements/2026-09-20-access-control-module-split.json),
[collection read obligation](../../../benchmarks/measurements/2026-09-20-collection-read-obligation.json),
[sibling scope and identity](../../../benchmarks/measurements/2026-09-20-sibling-scope-and-identity.json).
[sibling scope and identity](../../../benchmarks/measurements/2026-09-20-sibling-scope-and-identity.json),
[every permissive setting](../../../benchmarks/measurements/2026-09-20-every-permissive-setting.json).