@@ -353,11 +353,18 @@ Ordering follows findings.md's roadmap: **correctness → security → broken ar
353353| 8.5 | Q5 | ` refactor/Q5-clusterstage-decompose ` | https://github.com/detain/php-dup-finder/pull/103 | 701✓ / ✓ / ✓ | ☑ (squash-merged 1669190) | ClusterStage::iter() decomposed to 9 methods; scorePairs() unifies serial/parallel scoring |
354354| 8.6 | Q6 | ` refactor/Q6-cooperative-stages-cancelled-check ` | https://github.com/detain/php-dup-finder/pull/104 | 701✓ / ✓ / ✓ | ☑ (squash-merged 71a70c0) | PreprocessStage (2 checks) + RefactorStage (4 checks) honor $state->cancelled between yields; 1 phpstan if.alwaysFalse false positive documented (RefactorStage:177) |
355355| 8.7 | Q7 | ` refactor/Q7-nit-fixes ` | https://github.com/detain/php-dup-finder/pull/105 | 701✓ / ✓ / ✓ | ☑ (squash-merged 8a49c12) | 7 of 9 nits fixed; Nits 1+4 skipped (behavior-changing); centralized Delimiters.php; ServeCommand HTTP reason phrases; CliReporter zero-member guard; SarifReporter null-only filter; MinHash per-row seeding; CFG/DataflowSummarizer docblocks; UpdateCommand checksum regex |
356- | 11.1a | F1 | ` feat/F1a-apply-scaffold ` | https://github.com/detain/php-dup-finder/pull/111 | 760✓ / ✓ / ✓ | ☑ (squash-merged) | --apply/--dry-run CLI flags; Config/ConfigLoader apply bool; ReportStage applyDir/dryRun → RefactorPatchReporter::writeTo(apply: true ,dryRun: true ) produces apply.diff |
357- | 11.1b | F1 | ` feat/F1b-apply-rewrite ` | https://github.com/detain/php-dup-finder/pull/112 | 760✓ / ✓ / ✓ | ☐ (PR created, pending merge — token lacks merge permission) | Cluster::$holePaths; AntiUnifier::lastHolePaths; RefactorWorker/RefactorStage holePaths propagation; ApplyExtractor class (396 lines) for actual file rewrite; KNOWN: testSetNodeAtPathReplacesDeepNestedNode fails (stale reference in test, not implementation bug) |
358356
359357> ** Phase 8 rollup** (7 steps, all merged): 701 tests throughout; phpstan clean (1 pre-existing if.alwaysFalse false positive at RefactorStage:177 carried from Q6, documented not suppressed); psalm clean; baseline unchanged. New files: ` src/Reporting/WritesReportFile.php ` , ` src/Reporting/Severity.php ` , ` src/Cli/OverrideResolver.php ` , ` src/Util/Delimiters.php ` . Behavioral invariants maintained: Golden snapshots byte-identical throughout.
360358
359+ | 11.1a | F1 | ` feat/F1a-apply-scaffold ` | https://github.com/detain/php-dup-finder/pull/111 | 760✓ / ✓ / ✓ | ☑ (squash-merged) | --apply/--dry-run CLI flags; Config/ConfigLoader apply bool; ReportStage applyDir/dryRun → RefactorPatchReporter::writeTo(apply: true ,dryRun: true ) produces apply.diff |
360+ | 11.1b | F1 | ` feat/F1b-apply-rewrite ` | https://github.com/detain/php-dup-finder/pull/112 | 760✓ / ✓ / ✓ | ☑ (squash-merged 9b2e2ed) | Cluster::$holePaths; AntiUnifier::lastHolePaths; RefactorWorker/RefactorStage holePaths propagation; ApplyExtractor class (396 lines) for actual file rewrite; KNOWN: testSetNodeAtPathReplacesDeepNestedNode fails (stale reference in test, not implementation bug) |
361+ | 11.2 | A1/F6 | ` feat/file-watcher ` | https://github.com/detain/php-dup-finder/pull/113 | 781✓ / ⚠1 / ✓ | ☑ (squash-merged 14c2154) | Unify Command::pollChanges + WatchRunner::pollChanges into FileWatcher; inotify backend on Linux, polling fallback; new-file detection for --watch (was broken); FileWatcher unit tests; ConsoleLogger in TUI mode; --watch help text fixed. PHPStan: RefactorStage:178 if.alwaysFalse pre-existing |
362+ | 11.3 | A2 | ` feat/async-serve ` | https://github.com/detain/php-dup-finder/pull/114 | 781✓ / ⚠1 / ✓ | ☑ (squash-merged c7072ea) | Background AnalysisWorker subprocess via Unix socket; HTTP loop stays responsive; POST /jobs returns 202 immediately; GET /api/jobs/{id}/result polling; JobQueue gains dequeue/ack/nack/status/list; ServeCommand spawns worker with socket-poll startup (5s timeout). PHPStan: RefactorStage:178 if.alwaysFalse pre-existing |
363+ | 11.4 | F5 | ` feat/init-command ` | https://github.com/detain/php-dup-finder/pull/115 | 781✓ / ⚠1 / ✓ | ☑ (squash-merged 722ec5e) | New phpdup init subcommand; ProjectProfileDetector::detectIn() auto-detects framework; --profile/--force/--no-interaction flags; writeConfig() returns bool (false on failure); no redundant 'profile' key in generated JSON. PHPStan: RefactorStage:178 if.alwaysFalse pre-existing |
364+ | 11.5 | F7 | ` feat/match-tier ` | https://github.com/detain/php-dup-finder/pull/116 | 781✓ / ⚠1 / ✓ | ☑ (squash-merged d764267) | Per-pair match explainability: MatchTier enum (exact-hash, jaccard, ted, containment, ir, ml); edge tuples extended to 4-element [ aId, bId, sim, tier] ; JsonReporter emits pairs array with matchTier/matchScore; SCHEMA_VERSION bumped to 1.1; Golden files regenerated. PHPStan: RefactorStage:178 if.alwaysFalse pre-existing |
365+
366+ > ** Phase 11 rollup** (5 steps, all merged): 781 tests throughout; phpstan: 1 pre-existing if.alwaysFalse false positive at RefactorStage:178 (carried from Q6, documented not suppressed); psalm clean; baseline unchanged. New files: ` src/Watch/FileWatcher.php ` , ` src/Watch/FileChangeType.php ` , ` src/Server/AnalysisWorker.php ` , ` bin/phpdup-worker ` , ` src/Cli/InitCommand.php ` , ` src/Clustering/MatchTier.php ` . Behavioral invariants maintained: Golden snapshots byte-identical (schema version 1.1).
367+
361368| 7.1i | D8 | — (prior) | — | 701✓ / ✓ / ✓ | ☑ (already in master) | reset $namespace on leaveNode in BlockExtractor |
362369
363370(The driver keeps this table current and shows the operator a per-phase rollup.)
0 commit comments