[codex] Expand merge smoke and conflict audit coverage#251
Merged
Conversation
c65ee7c to
61d02cf
Compare
ff01bda to
bec8908
Compare
bec8908 to
89b5ffc
Compare
e90235d to
15454d7
Compare
…ck-merge-smoke # Conflicts: # docs/merge-reliability.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
wp_navigationblock creation where pages reference branch-local navigation blocks throughcore/navigationcomments.wp_navigationrow conflicts with a target deletion and target page cleanup.core/audio,core/cover, andcore/videopages with attachment rows,_wp_attached_filemetadata, and upload files on both branches.post_parent,comment_parent, andpost_authorgraphs.sticky_posts,site_icon,theme_mods_*custom_logo,widget_media_image, andwidget_nav_menudisagreement coverage: object graphs survive, while singleton/serialized option values stay reviewable with target kept before resolution.wp_termsimports, so embedded menu term IDs remain review-held instead of silently applying orphaned serialized data.merge-audit --revalidation-class <class>and--group-by revalidation-classfor conflicts, backed by the latest recorded revalidation result, so reviewers can queue conflicts by classes likecompatible-target-drift,missing,incompatible, orreplacement-evidencewithout client-side JSON scanning.merge-audit --latest-revalidation-status <status>and--group-by latest-revalidation-status, so callers can queue conflicts whose last after-revalidate guard is stillcurrent, has source/target drift, or has no latest revalidation record without client-side filtering.merge-audit --stale-status <status>and--group-by stale-status, so callers can query live fresh/stale/error/unknown conflict queues without client-side filtering.merge-audit --conflict-id <id>support for conflicts, conflict events, and resolutions, so UI/API callers can fetch one first-class conflict and its history by the same numeric id used by review/resolve commands.forkpress branch revalidate-reviews --conflict-id <id>andforkpress branch merge-audit --revalidate --conflict-id <id>carry one reviewed conflict back to needs-action without revalidating the whole run.--conflict-key <key>with the same unambiguous logical-conflict guard used by review and resolve, so UI/API callers can revalidate by stable conflict identity.merge-audit --conflict-key <key>support for conflicts, conflict-events, and resolutions, including conflict lineage on resolution rows so UI/API callers can focus one logical conflict group across repeated runs.merge-resolve conflict-key <key> [--run <id>]validate or apply conflict choices by first-class logical conflict key when the key selects exactly one unresolved conflict, with ambiguity errors that direct callers back to--runor exact conflict ids.merge-review conflict-key <key> [--run <id>]attach review status by first-class logical conflict key with the same ambiguity guard, so UI/API callers can mark a logical conflict without scraping numeric row ids.merge-audit --lifecycle-state <state>support for conflict queues and conflict-event history, coveringunreviewed,deferred,needs-action,reviewed,validated, andresolvedstates without client-side lifecycle inference.merge-audit --records conflicts --group-by lifecycleand--group-by conflict-key, and--scope plugin --group-by plugin,--group-by plugin-object,--group-by plugin-severity, or--group-by plugin-logical-identityso callers can summarize current conflict queues by lifecycle state, logical conflict key, validator plugin, validator object, plugin severity, or plugin logical identity without client-side aggregation, defaulting those queue groupings to conflict records, and exposes conflict-key, plugin scope, lifecycle filter/group, and plugin logical-identity filtering plus conflict and event grouping through the Rust CLI wrapper, help text, and parser tests.conflict_keyand same-runprevious_conflict_id, so--conflict-keycan show original and replacement plugin evidence together.severity,resolution_policy,suggested_action, andmanual_review_reason) in conflict payloads, and adds media coverage that missing original, metadata-original, generated, original_image, and backup upload files are explicitly review-only, and that non-image upload MIME drift such as PDF attachments is caught rather than auto-regenerated.merge-auditrecords (plugin,plugin_object,plugin_tables,plugin_files,plugin_validator,plugin_severity,plugin_logical_identity, and review guidance fields), adds first-class plugin, plugin-object, plugin-severity, and plugin-logical-identity filters, queue groupings, conflict-event metadata, and resolution metadata, resolution filters, resolution-status shortcuts, and resolution queue grouping by plugin fields across all plugin identity dimensions, including resolution row text metadata and text output for resolution groupings, and normalizes validatorpathsaliases into structuredplugin_filesso UIs do not scrape previews.merge-resolve --after-revalidatecan source-apply that object while cyclic or unproven schema drift stays review-only.forkpress branch merge-auditaccept--flag=valueforms for valued audit filters, including conflict-key, lifecycle, grouping, path, review, decision, and resolution filters.forkpress branch merge-audit --revalidateand directphp scripts/cow/merge.php audit --revalidatereject normal audit filters they would ignore, so stale-audit revalidation cannot appear narrower than it actually is.needs_action_conflicts,carried_conflicts, andalready_needs_action_conflictswith conflict ids, classifiers, drift reasons, revalidation records, and replacement conflict ids.--quiet, includingforkpress branch revalidate-reviews --quietandforkpress branch merge-audit --revalidate --quiet.blocked_resolution_choicesin JSON and text audit output instead of being advertised as executablesourcechoices.sourceagain after those dependency conflicts are resolved.row-target-constraintconflicts whose audited source row or source row deletion would fail against the current target foreign-key state; audit output hidessourceuntil the missing parent or blocking child dependency is resolved.sourceas blocked in audit output and are rejected before resolver mutation starts.merge-resolveenforce blocked choices through that same conflict contract before entering schema mutation/validation paths, so audit and resolver behavior share one source of truth.merge-audit --resolution-choice source|targetand--blocked-resolution-choice source|target, backed by the live conflict contract and direct PHP CLI regression coverage, so UI/API callers can query currently executable source choices separately from source-blocked review items.merge-audit --next-action <action>and--group-by next-action, backed by the live conflict lifecycle contract, so UI/API callers can query actionable queues likeresolve,wait, andrevalidatedirectly.core/navigation-submenupost-type and taxonomy object refs behind the same review boundary ascore/navigation-link, covering both explicit-ID merge gating and discovered WordPress semantic validators.core/template-parttheme/slug refs in discovered WordPress semantic validators, so block-theme templates left pointing at deleted template parts become plugin-scoped review conflicts.core/querytaxQuerytaxonomy refs behind the same review boundary as legacy category and tag query filters, covering both explicit-ID merge gating and discovered WordPress semantic validators.core/latest-postsauthor and category filters behind the same review boundary, covering both explicit-ID merge gating and discovered WordPress semantic validators.nav_menu_optionsauto-add menu refs behind the same review boundary as theme mod and nav widget menu refs, covering both explicit-ID merge gating and discovered WordPress semantic validators.widget_blockblock content refs behind the same review boundary as post content block refs, covering both explicit-ID merge gating and discovered WordPress semantic validators.widget_pagespage exclusions behind the same page review boundary, covering both explicit-ID merge gating and discovered WordPress semantic validators.widget_textandwidget_custom_htmlblock-content refs behind the same attachment review boundary as post content block refs, covering both explicit-ID merge gating and discovered WordPress semantic validators.core/imageblock left pointing at a deleted attachment.Why
The cheap local gate now covers more WordPress object graph cases before slower runtime E2E jobs run, including branch-local IDs embedded in block JSON, PHP serialization, media metadata, menus, authors, comments, and global options/widgets. The explicit-ID addition covers the unsafe case where serialized menu option payloads point at an out-of-band imported term: those references must remain review-held because ForkPress deliberately does not rewrite embedded IDs.
The conflict-key, lifecycle filters, lifecycle grouping, next-action filters and grouping, resolution-choice filters, conflict-key resolution, and plugin audit scope continue the first-class conflict model: callers no longer need to scan every conflict row, infer grouping from raw payloads, recompute conflict queue state, reconstruct event timelines, aggregate queue summaries, or guess how to request plugin-scoped conflicts in a UI. Conflict-key review/resolution stays deliberately bounded: ambiguous keys must be disambiguated by run or exact id, so repeated conflicts and identical payloads across branch pairs cannot be resolved accidentally. Plugin replacement findings now share that same lineage model, so changed validator evidence is not detached from the reviewed conflict it supersedes.
Plugin validator findings can now carry explicit review guidance without hiding it inside candidate-specific blobs. That matters for media uploads: missing generated derivatives should remain auditable review-only findings unless a future media repair driver can prove exact, deterministic regeneration.
Plugin audit records now expose the validator's plugin/object identity, owned tables/files, logical identity, and review guidance as structured fields, with first-class filters and queue groupings for plugin, plugin object, severity, and logical identity. That keeps the UI/API side aligned with the first-class conflict model instead of forcing clients to parse human previews or decode raw payload JSON.
The stale-audit guard makes revalidation intent explicit in both entry points:
--revalidateis a mutation/checking flow over reviewed conflicts, not a filtered read-only audit report. The new result summaries make that flow operationally useful by showing the exact conflicts that were carried or were already open inneeds-action, without requiring a second audit query just to find the next review ids.Blocked choices keep audit and resolver behavior aligned: callers should not offer resolution actions that the merge layer already knows are blocked for a specific payload, or discover blocked schema choices only by attempting the mutation. The resolution-choice filters make that contract queryable without forcing clients to fetch and classify every conflict row themselves.
The Git-created branch cleanup change keeps branch birth atomic from the metadata side: failed publication should not leave orphaned birth audit rows that make later retries or audits look like a branch partly existed.
The release-build retry is a narrow guard for the transient upstream/network failure seen in the release workflow while downloading static-php-cli sources. It does not retry the whole release job or hide deterministic build failures.
Adds
merge-audit --event-typeso conflict event history can be filtered directly by recorded/review/revalidation/resolution lifecycle events.Adds conflict-event grouping so audit consumers can summarize recorded/review/revalidation/resolution event history without client-side aggregation.
Adds resolver-contract grouping for conflicts by resolution strategy, generic resolver support, and after-revalidate support.
Adds resolver-contract filters so audit consumers can focus conflicts and conflict events by resolution strategy, generic resolver support, and after-revalidate support.
Documents the resolver-contract audit filters in the merging guide so UI/API clients can build queues from first-class conflict fields.
Records blocked conflict resolution attempts as first-class
resolution-blockedconflict events, including audit filtering and docs.Aligns Rust CLI help and parser tests with the
resolution-blockedconflict-event type.Adds a PHP CLI regression for auditing
resolution-blockedconflict events through JSON output.Adds legacy metadata migration coverage proving existing conflict-event tables accept
resolution-blockedafter schema migration.Queues blocked resolver attempts as first-class
needs-actionconflicts so lifecycle/next-action filters and groups stop advertising stale validated applies.Adds CLI regression coverage for blocked-resolution queues with
--lifecycle-state=needs-actionplus--next-action=manual-review.Adds schema-conflict coverage proving blocked source schema choices enter the same
needs-action/manual-reviewqueues as row conflicts.Extends first-class blocked source-choice contracts to target-side row
CHECKconstraints and target trigger rewrites, preserving FK cases that become executable after dependencies are reviewed.Adds focused media-validator coverage for URL-like and Windows drive-letter upload metadata, keeping those as unsafe upload-path conflicts instead of treating them as missing files.
Adds focused plugin-validator coverage for URL-like and Windows drive-letter plugin-owned file references, preserving them as unsafe plugin graph findings with structured file evidence.
Adds focused ID-band audit coverage for plugin tables that use plain
INTEGER PRIMARY KEY, proving skipped-band decisions name the table and explain why no durablesqlite_sequencereservation exists.Validation
php -l tests/cow/merge_smoke.phpmake test-cow-merge-smoke(593 assertions)php -l scripts/cow/merge.phpFORKPRESS_RUNTIME_BUNDLE=/dev/null cargo test -p forkpress-cli branch_merge_auditphp -l tests/cow/merge.phpphp -l tests/cow/filesystem.phpphp tests/cow/filesystem.php(78 assertions)make test-cow-branch-birth(32 assertions)make test-cow-branch-ui(branch UI/router/lock focused tests)php -l tests/cow/schema_review.phpphp tests/cow/schema_review.php(179 assertions)php tests/cow/merge.php(3182 assertions)php -l tests/cow/wp_semantic_validator.phpphp tests/cow/wp_semantic_validator.php(328 assertions)php -l tests/cow/media_validator.phpphp tests/cow/media_validator.php(123 assertions)php -l tests/cow/plugin_validator.phpphp tests/cow/plugin_validator.php(193 assertions)FORKPRESS_RUNTIME_BUNDLE=/dev/null cargo test -p forkpress-cli parses_branch_merge_audit_plugin_resolution_groupingFORKPRESS_RUNTIME_BUNDLE=/dev/null cargo test -p forkpress-cli parses_cow_branch_merge_audit_resolution_plugin_groupingFORKPRESS_RUNTIME_BUNDLE=/dev/null cargo test -p forkpress-cli parses_cow_branch_merge_audit_resolution_plugin_filtersFORKPRESS_RUNTIME_BUNDLE=/dev/null cargo test -p forkpress-cli parses_cow_branch_merge_audit_id_band_skip_shortcutphp -l tests/cow/stale_audit.phpphp tests/cow/stale_audit.php(240 assertions)php -l tests/cow/explicit_ids.phpmake test-cow-explicit-ids(76 assertions)php -l tests/cow/id_bands.phpphp tests/cow/id_bands.php(34 assertions)php -l scripts/cow/git_server.phpphp -l tests/cow/git_server.phpphp tests/cow/git_server.php(257 assertions)bash -n scripts/build-dist.shbash -n tests/release/build-dist-preflight.shmake test-releaseFORKPRESS_RUNTIME_BUNDLE=/dev/null cargo test -p forkpress-cli(91 tests)FORKPRESS_RUNTIME_BUNDLE=/dev/null cargo test -p forkpress-cli branch_help_lists_review_revalidation_commandcargo fmt --checkcargo test -p forkpress-storage(16 tests)git diff --check