diff --git a/.kiro/specs/pre-push-safety-net/tasks.md b/.kiro/specs/pre-push-safety-net/tasks.md index 519bbc6..4007543 100644 --- a/.kiro/specs/pre-push-safety-net/tasks.md +++ b/.kiro/specs/pre-push-safety-net/tasks.md @@ -457,7 +457,7 @@ Preserve all completed task evidence below. - _Measured 2026-09-17, PHP transfer NOT established._ All three comparisons exhausted a 3000-second deadline with a 1200-second query ceiling and produced no artifact, so there is no target evidence at all. The engine reports `cpg batch taint failed` twice per case on the 1,274-file PMPro tree: first an exception whose trace runs through ujson array transformation, then a timeout on the retry. Budgets tried: 900 s, 1200 s and 3000 s deadlines against 300 s and 1200 s query ceilings. Pins, source receipts and the declared target are all correct, so the question was asked properly and the engine could not answer it. This is a runtime blocker on a large repository, not evidence about whether the design transfers to PHP. Evidence: `benchmarks/measurements/2026-09-17-m3-php-transfer.json`. - _Two harness defects found and fixed on the way, each of which had made an earlier run look like a transfer failure:_ the manifest labels a case by what it is while the id says what the comparison does, and filtering on one while keying expectations by the other ran a single case; and the per-query ceiling is taken as the minimum with the remaining transaction time, so raising only the deadline could never have helped. - _Retried 2026-09-18 with batch splitting, still not established._ A batch that fails whole is now retried in eight parts, which a probe made look promising: the evidence pass answers all 4,425 PMPro regions in one batch in 29.7 s with a 681 KB response, and cost is fixed rather than per request, so neither count nor size is near a limit. That probe sent `evidenceOnly=true` and therefore measured the structural pass, not the failing one; recorded because those numbers would otherwise read as evidence that PMPro's taint work is cheap. With a 4500-second deadline and a 900-second query ceiling the run was stopped after 26 minutes with no case completed. Splitting also makes an unrecoverable batch slower to abandon, since each part burns its own share of the ceiling. - - **Blocker named: the execution pass, which runs `reachableByFlows` per candidate.** Not batch size, not serialization, not the deadline. Evidence: `benchmarks/measurements/2026-09-18-php-batch-diagnosis.json`. + - **Blocker still unidentified; investigation paused 2026-09-19 to return to vulnerability work.** Six hypotheses were measured and eliminated: batch size (17,700 requests answer in 44 s with a 2.6 MB response), dataflow cost (50 execution requests in 24 s), call depth 3 with parameter sources (24.7 s for 20), argument length (a 16 KB hook table against a 128 KB cap), hook callback resolution (1 s difference with 233 hooks), and build or sharding (79 s, no shards). Preparation measures 273.5 s. Every reproduction of the failing 22,125-request batch outside the push path answers in under a minute, and the difference from the production invocation is not known. The exception has never been read, because the backend logged a stack trace's tail and the corrected extractor reports its head, which on this engine is JVM startup noise. Evidence: `benchmarks/measurements/2026-09-19-php-blocker-open.json`. - _Boundary: Evaluation harness, full-run integration_ - _Depends: 13.1_ - _Requirements: 6.2, 6.3, 8.1, 8.2_ diff --git a/benchmarks/measurements/2026-09-19-php-blocker-open.json b/benchmarks/measurements/2026-09-19-php-blocker-open.json new file mode 100644 index 0000000..1eb4bc5 --- /dev/null +++ b/benchmarks/measurements/2026-09-19-php-blocker-open.json @@ -0,0 +1,30 @@ +{ + "schema_version": 1, + "experiment": "php-blocker-investigation", + "status": "OPEN, investigation paused by the maintainer to return to vulnerability work", + "what_is_measured": { + "preparation_stage": "273.5 s, snapshot materialization of both revisions plus region discovery over 637 PHP files twice", + "production_build": "78.8 s, no sharding, 638 files, 7,339 methods, 106,112 calls", + "census": "18.2 s", + "evidence_batch_at_production_size": "17,700 requests answered in 43.8 s, 2.6 MB response, exit 0", + "same_batch_with_the_233_hook_table": "44.9 s, answered, no exception", + "execution_pass": "50 dataflow requests in 23.9 s", + "entry_point_shape": "20 requests at call depth 3 with parameter sources in 24.7 s" + }, + "hypotheses_eliminated": [ + "Batch too large to serialize: 17,700 requests answer in 44 s with a 2.6 MB response.", + "Dataflow too slow: 50 execution requests in 24 s.", + "Call depth 3 explodes: 24.7 s for 20 entry-point requests.", + "Argument length: the hook table is 16 KB against a 128 KB single-argument cap.", + "Hook callback resolution: the same batch with 233 hooks costs 1 s more.", + "Build or sharding: 79 s, no shards." + ], + "what_remains_unknown": "Production reports `cpg batch taint failed` on a 22,125-request batch inside the head stage, and every reproduction of that batch outside the push path answers in under a minute. The difference between the reproduction and the production invocation has not been identified. The exception itself has never been read: the backend logged the last 400 characters of a stack trace, which is frames, and the corrected extractor now reports the first non-frame lines, which on this engine are JVM startup noise.", + "instrument_defects_found_and_fixed": [ + "Failure detail logged the tail of a stack trace, so the exception that names the cause was discarded.", + "No stage reported its cost, so a killed run left no account of where the budget went.", + "Nothing configured logging, so the stage lines added for this investigation could not emit at all.", + "The transfer harness buffers each case's stderr until the case ends, so nothing is visible during a long run." + ], + "next_step_when_resumed": "Read the actual exception. Extract the line matching an exception pattern anywhere in stderr rather than assuming it comes first or last, then reproduce the exact production invocation including its hoisted shared parameters." +}