chore: recover v0.3.0 CHANGELOG promotion (PR #23 merge anomaly)#25
Conversation
Cuts v0.3.0 — collapses three contractual rule widenings into a single Major bump per ADR-0021 §Versioning: 1. EnforceResourceDataValidatorOptInRule (queue #55 Phase-2 promotion, ADR-0009 §EAGER_LOAD validator opt-in) — Phase 2 rule 2. LogRule static-call expansion (issue #4, ADR-0001 §Append-only) — Model::destroy() / Model::forceDestroy() shapes 3. LogBuilderTruncateRule (issue #8, ADR-0001 §Append-only) — Builder->truncate() on table('<log-named>') chains Each rule's pre-cascade audit returned 0 violators across all 5 consumer territories (kendo, entreezuil, emmie, ublgenie, brick-inventory-orchestrator): - ResourceDataValidator audit: campaigns/phpstan-warroom-rules/2026-05-08-pre-cascade-audit-resource-data-validator-opt-in.md - LogRule static-call audit: campaigns/phpstan-warroom-rules/2026-05-13-pre-cascade-audit-log-rule-static-call.md - LogBuilderTruncate audit: campaigns/phpstan-warroom-rules/2026-05-13-pre-cascade-audit-log-builder-truncate.md No consumer-side ignoreErrors migrations required. The Major represents the contract widening, not empirical violation count. Phase A pin sweep (^0.1.x → ^0.2) closed pre-release — all 4 laggard consumers bumped via independent dispatches between 2026-05-06 and 2026-05-08; verified by 4-territory Medic wave 2026-05-13 (no-op). Phase B pin sweep (^0.2 → ^0.3) follows post-tag as a separate war-room dispatch. This PR is STACKED on PR #22 (engineer/log-builder-truncate-rule). GitHub auto-retargets to main when PR #22 merges. Tag v0.3.0 on the release-PR merge commit; release.yml's webhook auto-publishes to Packagist. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PR Reviewer · claimed
|
PR Reviewer · 9/10 · PASS
Findings
Actionmerge-ready |
jasperboerhof
left a comment
There was a problem hiding this comment.
Auto-approved by /review-open-prs — review verdict is PASS. See the verdict comment for the per-reviewer breakdown.
Goosterhof
left a comment
There was a problem hiding this comment.
One concern, one nit, two pieces of praise — zero blockers. I'll be explicit about the blocker I went looking for and did not find, because it's the tempting wrong read of this PR.
No changelog data loss — the clean MERGEABLE status here is genuinely clean. I ran the merge in a throwaway clone against current origin/main and diffed the result: the promotion moves the existing [Unreleased] block (EnforceResourceDataValidatorOptInRule, the LogRule / LogBuilderTruncateRule BREAKING entries, and the CI/governance items) down under a new [0.3.0] heading without dropping any of it. The rules from the in-flight sibling PRs #27 (EnforceAuditTransactionScopeRule) and #28 (ForbidEloquentMutationInControllersRule) are not on main — both PRs are still open — so they were never in this [Unreleased] block and there is nothing for the promotion to clobber. origin/main is still at the PR #22 merge commit 3555946, i.e. this branch's fork point, so there's no stale-base drift either. The boundary is correct as drawn.
Concern
The ## [0.3.0] — 2026-05-13 heading date will not match the commit that actually carries the v0.3.0 tag. The recovery merge (and therefore the tag, per the PR body's "tag on the recovery merge commit") lands 2026-05-29, not 05-13. Keep-a-Changelog dates are by convention the release date, so a backdated 0.3.0 reads oddly against a tag created two weeks later — a future reader cross-referencing the GitHub release timestamp against the changelog will see a 16-day gap with no explanation. Either set the date to the actual tag date, or add a one-line note that 05-13 is the original content-freeze date the merge anomaly delayed. Not a blocker — purely a provenance-legibility call.
Nit
composer.json correctly carries no version field (tag-driven via the Packagist webhook), so there's no version-string consistency check to fail here. Noting it because a reviewer scanning for "did they bump composer.json" should know the absence is intentional, not an omission.
Praise
The PR body's forensic reconstruction of the merge anomaly is load-bearing and correct — tracing ac035f8's unreachability from main through its parent commits and identifying that PR #22 snapshotted the engineer branch before PR #23's merge into it landed is the right diagnosis, not the easier "PR #23 just didn't merge" misread. That diagnosis is what makes this a targeted recovery rather than a guess.
Sequencing note for when #27/#28 land (not a finding): their entries belong in a fresh [Unreleased] block above this [0.3.0] section — the natural changelog flow, no action needed here.
Verdict: COMMENT — ship it. The recovery is sound, the merge is genuinely clean, and the only open item is the cosmetic date-provenance call above.
Summary
Recovers the v0.3.0 CHANGELOG promotion that PR #23 was supposed to land but didn't reach
maindue to a merge sequencing race.Underlying diff is identical to PR #23's reviewed state (cherry-pick of commit
4c804ae). Reopening here against currentmainonly.What happened
engineer/log-builder-truncate-rule) merged tomainas3555946on 2026-05-20 14:55 UTC.chore/release-v0.3.0, stacked on PR engineer: add LogBuilderTruncateRule (closes #8) #22) showsstate: MERGEDin the GitHub API with merge commitac035f8on 2026-05-20 14:56 UTC.ac035f8is not reachable frommain. `git log v0.2.0..main` does not contain any commit by PR chore: release v0.3.0 #23.ac035f8's parents (c929e88+4c804ae) reveals: PR chore: release v0.3.0 #23 was merged into theengineer/log-builder-truncate-rulebranch state atc929e88("Merge branch 'main' into engineer/..."). PR engineer: add LogBuilderTruncateRule (closes #8) #22 had already snapshotted the engineer branch atc929e88for its own merge; the subsequent PR chore: release v0.3.0 #23 merge into the engineer branch (atac035f8) was never picked up by PR engineer: add LogBuilderTruncateRule (closes #8) #22's path tomain.LogBuilderTruncateRule.phpand the rule's### ChangedCHANGELOG entry are onmain(PR engineer: add LogBuilderTruncateRule (closes #8) #22 carried them), but the[0.3.0] — 2026-05-13heading promotion + link footer + audit-verdict rewordings that PR chore: release v0.3.0 #23 added are absent.v0.3.0was never tagged. Packagist still serves onlydev-main.Why this matters
Five downstream work items gate strictly post-v0.3.0-tag (war-room enforcement queue tracking):
^0.2→^0.3pin sweep across 5 consumer territorieskendoAnthropic Managed Agents PHPStan errors investigation (106 errors ondevelopment)All have been paused since 2026-05-20 waiting on the v0.3.0 tag that never landed.
What's in this PR
Single-file change:
CHANGELOG.md. 9 insertions, 4 deletions. Identical to PR #23's reviewed diff (cherry-pick).## [0.3.0] — 2026-05-13heading with the release-as-a-whole MAJOR paragraphEnforceResourceDataValidatorOptInRule→ 2026-05-08 cascade audit (0 violators across 5 territories)LogRule (BREAKING)→ 2026-05-13 cascade audit (0 violators)LogBuilderTruncateRule (BREAKING)→ 2026-05-13 cascade audit (0 violators)[0.3.0], updates[Unreleased]compare rangePost-merge
Tag
v0.3.0on the recovery merge commit. Packagist webhook auto-publishes. Phase B pin sweep dispatches.References
🤖 Generated with Claude Code