Commit Graph
460 Commits
Author SHA1 Message Date
Marius CiepluchandClaude Opus 5 8ff1d9a638 feat(pre-push-safety-net): scope comparison completeness and ambiguity (M1b 10.2, 10.3)
Two vetoes M1a recorded were global where the evidence is local.

Comparison required every selected base question to complete, so one unsupported
family anywhere prevented an otherwise complete target comparison. Completeness
is now demanded over the required scope: the counterpart question plus the
dependencies the change context actually recorded for it. Every other gap stays
in aggregate coverage and is still reported, never discharged. An incomplete
counterpart, an incomplete recorded dependency, an unknown-ownership boundary
and a truncated base scan all still yield unknown.

Correspondence ambiguity was recorded file-wide and inherited by every question,
so repeated unchanged lines in one file invalidated every question in the
repository and blocked the whole transaction comparison. It is now decided per
operation by the correspondence classifier: an operation needing an ambiguous
anchor stays uncomparable, while a uniquely mapped or newly introduced operation
in the same file is unaffected. The mapping is still withheld and still reported.

On the NodeGoat case the ambiguity is on the target's own file, so file-level
scoping would not have been enough; only per-operation resolution is.

1,347 tests passed, nine skipped. No capability enabled; rollout stays NO-GO.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
2026-09-16 15:45:57 +02:00
Marius CiepluchandClaude Opus 5 7e0d01d9e8 feat(pre-push-safety-net): classify an operation the change introduced (M1b 10.1)
M1a measured that a newly introduced operation sits on a changed line, has no
base line anchor, and therefore stayed unclassified even with every completeness
veto lifted. Establish absence over the complete counterpart answer instead of
over a line anchor.

Correspondence now reports why a head operation does not map: `changed_line`
inside a recorded head edit, `ambiguous` where several base lines could
correspond, or `unmapped` where no anchor exists. Only the first supports
reasoning about an introduced operation, and only when the base counterpart
answer is complete and contains no operation with that spelling.

Movement is matched on the operation spelling alone, so a benign identifier
rename that changes only the source text reads as movement rather than a new
flow. The existing rename control caught that; the key was too brittle before.

One prior control is superseded and updated with its reason: a new operation on
a changed line in a comparable existing file is now new rather than unknown.
Movement, ambiguity, unmapped operations, discharged or unentailed claims and an
incomplete or failed base all remain unknown.

1,337 tests passed, nine skipped. No capability enabled; rollout stays NO-GO.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
2026-09-16 15:38:13 +02:00
Marius CiepluchandClaude Opus 5 3224884d8f feat(pre-push-safety-net): record admission vetoes and meet M1a on NodeGoat
Add group 9 to the approved task plan as the bounded owner amendment release
milestone M1a requires, implement the task-local recorded-veto evaluation flag,
and run the three pinned NodeGoat revisions under it.

The flag re-runs the production comparison and admission over a lifted copy of
the same evidence and records each veto instead of applying it. Recognized
completeness vetoes are lifted and logged; failures never are, because silence
from a failure is not a quiet fixed twin. It is off by default, accepted only on
explicit base/head replay, refused in Git stdin mode, labels every payload it
produces, and admits no defect even when a lifted candidate otherwise would.

M1a outcome, inside its one-week box and with expectations frozen on disk first:
the three entailed <lambda>2 witnesses are present at contributions.js 32-34; the
fixed twin was genuinely analyzed and quiet, answering its target question with
zero rows and no deadline reason while the same findings appear as base-only; the
unchanged revision was analyzed and recorded unchanged. The kill criterion did
not trigger.

Five vetoes fired and were recorded. M1a also corrected the diagnosis: with all
five lifted the detection still stops at operation_correspondence_unresolved,
because a newly introduced operation sits on a changed line and has no base
anchor. The unchanged revision resolves its base location on the same lines and
classifies as unchanged, which isolates correspondence as the mechanism. That
fifth veto was not in the earlier four-veto diagnosis and is now M1b's central
repair.

Diagnosis only. No defect admitted, no capability enabled, no gate changed, no
latency claim; the 900-second development budget cannot measure the hook gate.
Rollout and task 8.3 remain NO-GO.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
2026-09-16 15:31:34 +02:00
Marius CiepluchandClaude Fable 5.1 8b66d5cb75 spec(pre-push-safety-net): record M1–M5 release milestones and split M1 into M1a/M1b
Add release-milestones.md as the executable outcome contract: prove one useful
Node detection, make it fast, verify PHP/Python transfer, qualify on untouched
cases, then enable a narrow advisory rollout. Link it from the roadmap, safety-net
steering, requirements, tasks, status and spec.json.

Split M1 after review. The raw NodeGoat <lambda>2 witness already exists in the
2026-09-14 post-census bundle; four admission vetoes discard it. M1a runs the
vulnerable/fixed/unchanged revisions under a task-local experimental flag that
records each veto instead of applying it, with a one-week box and a kill
criterion if the fixed twin is not quiet. M1b repairs only the vetoes that fired
and reruns through production rules. Existing approvals and thresholds unchanged.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
2026-09-14 20:48:23 +02:00
Marius Ciepluch 1ad472c68d test(release): measure repaired reuse and local Joern lifecycle 2026-09-14 13:18:51 +02:00
Marius Ciepluch 04f888019b release: prepare v1.2.0-alpha.1 and record rollout blockers v1.2.0-alpha.1 2026-09-14 08:13:26 +02:00
Marius Ciepluch 7c1c2d4475 fix(contributor-scan): retain declared Gruntfile and report census gaps honestly 2026-09-14 08:07:06 +02:00
Marius Ciepluch 88216c5072 test(pre-push-safety-net): validate packaged outcome and retain rollout no-go 2026-09-13 19:39:19 +02:00
Marius Ciepluch b506516d87 feat(pre-push-safety-net): enforce evidence eligibility and record blocked qualification 2026-09-13 19:32:43 +02:00
Marius Ciepluch 2491ce497c feat(pre-push-safety-net): measure frozen runtime feasibility and retain no-go 2026-09-13 19:06:02 +02:00
Marius Ciepluch 4e3b19da5b feat(pre-push-safety-net): cover combined push failure paths 2026-09-13 18:43:13 +02:00
Marius Ciepluch fa074dd197 feat(pre-push-safety-net): bound optional assistance to admitted witnesses 2026-09-13 18:03:31 +02:00
Marius Ciepluch 749c7ab45d feat(pre-push-safety-net): preserve existing hooks during explicit integration 2026-09-13 17:51:28 +02:00
Marius Ciepluch f04955c367 feat(pre-push-safety-net): execute full Git push transactions 2026-09-13 17:45:16 +02:00
Marius Ciepluch 530b9c9879 feat(pre-push-safety-net): reuse compatible artifacts throughout replay 2026-09-13 17:08:49 +02:00
Marius Ciepluch 0ab5d56618 feat(pre-push-safety-net): key evidence reuse by compatible semantics 2026-09-13 16:16:19 +02:00
Marius Ciepluch 6fb5ad2cff feat(pre-push-safety-net): publish and evict complete local artifacts safely 2026-09-13 16:11:19 +02:00
Marius Ciepluch 8c9c91be91 feat(pre-push-safety-net): validate graph identity and isolated leases 2026-09-13 16:05:51 +02:00
Marius Ciepluch 78a7dfc8c4 feat(pre-push-safety-net): measure frozen PMPro and Node replay feasibility 2026-09-13 15:24:06 +02:00
Marius Ciepluch 8fe3a7e51e fix(pre-push-safety-net): stop semantic planning at the shared deadline 2026-09-13 15:11:42 +02:00
Marius Ciepluch 31e5ec7430 feat(pre-push-safety-net): replay immutable revisions through the full transaction 2026-09-13 14:50:25 +02:00
Marius Ciepluch 6b12b73411 feat(pre-push-safety-net): render bounded reports and preserve full evidence 2026-09-13 13:25:44 +02:00
Marius Ciepluch d0e0ecad78 feat(pre-push-safety-net): admit only supported actionable changes 2026-09-13 12:56:55 +02:00
Marius Ciepluch eb320730b6 feat(pre-push-safety-net): compare targeted base and head evidence 2026-09-13 12:42:15 +02:00
Marius Ciepluch 6ba2b06353 feat(pre-push-safety-net): exclude vendor inputs and partition frontend coverage 2026-09-13 11:53:29 +02:00
Marius Ciepluch 51fabef9ea feat(contributor-scan): retain first-party JavaScript tests in graphs 2026-09-13 11:29:48 +02:00
Marius Ciepluch d02406e758 docs(pre-push-safety-net): record frontend retention prerequisite 2026-09-13 11:05:44 +02:00
Marius Ciepluch ebad83009e feat(pre-push-safety-net): connect change context to ranked questions 2026-09-13 10:41:32 +02:00
Marius Ciepluch 546db24b8e feat(pre-push-safety-net): preserve exact ranker scope and outcomes 2026-09-13 10:16:22 +02:00
Marius Ciepluch bd53b6dc9d feat(pre-push-safety-net): bound backend execution by one deadline 2026-09-13 10:03:03 +02:00
Marius Ciepluch 948ee020db feat(pre-push-safety-net): retain bounded change and rename context 2026-09-12 21:12:45 +02:00
Marius Ciepluch 97fd6336f1 feat(pre-push-safety-net): materialize bounded isolated snapshots 2026-09-12 20:55:09 +02:00
Marius Ciepluch 05da202d67 feat(pre-push-safety-net): resolve immutable push comparisons 2026-09-12 20:43:51 +02:00
Marius Ciepluch 14a2a60e52 feat(pre-push-safety-net): establish shared push and engine contracts 2026-09-12 19:21:31 +02:00
Marius Ciepluch 051f3b0058 feat(pre-push-safety-net): preserve uncertainty in benchmark scoring 2026-09-12 19:04:20 +02:00
Marius Ciepluch 8acada0d98 feat(pre-push-safety-net): pin labeled evaluation inputs 2026-09-12 18:45:54 +02:00
Marius Ciepluch 56cfc9da89 feat(pre-push-safety-net): reproduce evaluated Joern runtime 2026-09-12 18:32:18 +02:00
Marius Ciepluch 7e3b3bbc8b docs(pre-push-safety-net): record approved design and implementation plan 2026-09-12 18:27:14 +02:00
Marius CiepluchandClaude Fable 5.1 a8069acb41 bench(ranking): phase 2 with the layout facts -- wpstatistics 173 -> 91, mwwpform 68 -> 54, pmpro 82
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01T7XD7x5KonMdmGRkp63EQG
2026-09-11 14:42:44 +02:00
Marius CiepluchandClaude Fable 5.1 7411f3568a bench(ranking): the phase-2 baseline on Joern 4.0.625 -- pmpro 82, wpstatistics 173, mwwpform 68, vampi 16
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01T7XD7x5KonMdmGRkp63EQG
2026-09-11 14:39:22 +02:00
Marius CiepluchandClaude Fable 5.1 ee693eec26 docs(flow-aware-ranking): the three decisions -- 4.0.625 as baseline, vendored out, tests not product
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01T7XD7x5KonMdmGRkp63EQG
2026-09-11 14:28:18 +02:00
Marius CiepluchandClaude Fable 5.1 b821ac6e4e feat(facts): the [[layout]] fact -- vendored trees are out, test paths are not product
Two decisions the maintainer made, as rows rather than constants. A vendored tree (vendor/, node_modules/,
third_party/) is somebody else's unit: out of the targets in preprocess and out of the graph through the
frontend's --exclude, which the scan hands to the backend because the CPG seam imports only the standard
library. A test path (tests/, test-*.php, *Test.php) stays in scope -- a test that reaches a sink still
names the sink -- but its regions are not shipped and order after the product's. Measured before the row:
207 of WP Statistics's 357 PHP files were vendored, and 14 of the 67 regions ahead of MW WP Form's CVE
were test files. The position benchmark applies both, so it measures the order the scan spends.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01T7XD7x5KonMdmGRkp63EQG
2026-09-11 14:27:50 +02:00
Marius CiepluchandClaude Fable 5.1 9142cb1fb4 docs(flow-aware-ranking): v6 measured -- identical to v5, and why; the layout fact table proposed
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01T7XD7x5KonMdmGRkp63EQG
2026-09-11 14:15:12 +02:00
Marius CiepluchandClaude Fable 5.1 3b3b96be5f fix(cpg): the interpreter precondition probes the frontend's own parser script; 4.0.625 verified
php2cpg drives PHP-Parser through `php` from a script inside its own install. A second install the
containerised interpreter had no mount for parsed 1 of 637 files and exited 0 -- caught by the build
census, and now refused by name before any build. On 4.0.625 with the closure exclusion gated off:
pmpro 637 of 637 in 100 s, WP Statistics 115 s with only the two data tables excluded. Phase-2 v5
verdict and the within-tier reading recorded in the brief.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01T7XD7x5KonMdmGRkp63EQG
2026-09-11 13:52:17 +02:00
Marius CiepluchandClaude Fable 5.1 2de873274f feat(model): shipped joins the evidence vector as a within-tier weight; v5 baseline
v5 (parameter-fed carried confirmed by the exact flow): pmpro 69, wpstatistics 172, mwwpform 68,
vampi 16. Reading the recorded head of each order: every region ahead of a CVE is in its tier on a tied
or higher score, and 10 of the 67 ahead of MW WP Form's are test-mail.php. The build's own word on what
is product was on the region and not in the vector; it is now, at -2.0 for an unshipped file. Orders
only, never promotes.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01T7XD7x5KonMdmGRkp63EQG
2026-09-11 13:45:00 +02:00
Marius CiepluchandClaude Fable 5.1 983eda5886 feat(model): v4 measured; a parameter-fed field becomes strong carried only when the exact flow confirms it
v4 (provenance split): pmpro 69 and wpstatistics 172 unchanged -- their tier-4 members are source-fed
through same-file helpers that read the request; mwwpform 68 -> 248, because its CVE's region is fed by
a constructor parameter, the shape the split demotes and the exact flow had put at 30. v5 asks the flow
for exactly the parameter-fed fields a sink-bearing region reads, memoised per (family, file, field),
and reports carriedBy for diagnosis.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01T7XD7x5KonMdmGRkp63EQG
2026-09-11 13:27:49 +02:00
Marius CiepluchandClaude Fable 5.1 20d53f1c4d perf(cpg): the field and hook memos live at batch scope, keyed by what the answer depends on
methodsByFile, seedsByFile, fieldTaintMemo and hookKeysMemo were declared inside rowsFor and so memoised
nothing across a batch's requests: every pair re-walked the file's methods and re-ran the join's flow
queries. Hoisted, with the family's sources, sanitizers and parameterSources in the key.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01T7XD7x5KonMdmGRkp63EQG
2026-09-11 13:14:21 +02:00
Marius CiepluchandClaude Fable 5.1 d1f37abadd feat(model): carried with provenance -- source-fed promotes a tier, parameter-fed only orders
Structural carried (v3) measured: pmpro 391 -> 69, wpstatistics 504 -> 172, mwwpform 513 -> 68 -- and
tier 4 swollen to 555 and 569 regions, because "assigned from a parameter" was folded in with "assigned
from a source" and every constructor does the former. The query now reports carriedKind; the vector
promotes on "source" and gives "parameter" a within-tier weight of 0.75.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01T7XD7x5KonMdmGRkp63EQG
2026-09-11 13:11:00 +02:00
Marius CiepluchandClaude Fable 5.1 ce49bd877c perf(cpg): carried for evidence mode is structural, not a flow
The flow form -- a reachableByFlows per candidate assignment -- turned pmpro's evidence pass from 255 s
into one that did not finish in 1,800 s. Evidence may be a structural proxy, so stage one of the join is
now asked as structure: a field the region reads is assigned, in its file, from a source expression, from
a parameter of the assigning method, or from a same-file method that reads a source; a hook applied in
scope has a registered callback holding a source or such a field read. Memoised per file and per
callback for the batch. Verified on WP Statistics's record(): carried = true, 36 s including the JVM.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01T7XD7x5KonMdmGRkp63EQG
2026-09-11 12:53:22 +02:00
Marius CiepluchandClaude Fable 5.1 c8e2ed21aa bench(ranking): the position benchmark sets its own query ceiling; v2 partials in the brief
A pass over every region of pmpro (22,315 pairs) took 255 s without the join facts and past the scan's
300 s default with them, and a timed-out pass answers nothing -- reported once as tiers={} and the static
order. mwwpform with carried: 292 -> 30.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01T7XD7x5KonMdmGRkp63EQG
2026-09-11 12:01:55 +02:00