Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions docs/merge-reliability.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ when there is a test or document that exercises the specific merge invariant.
| 4. Filesystem merge hardening | `tests/cow/filesystem.php` is a focused fast gate for safe source text/binary file application, unsafe absolute symlinks staying as auditable file conflicts, and directory/file type replacements staying review-held until an explicit audited source resolution applies them. `tests/cow/media_validator.php` fast-gates discovered upload validators for incomplete generated-size metadata, missing original upload files, and `_wp_attached_file` versus `_wp_attachment_metadata['file']` drift. `tests/cow/merge.php` covers file adds/deletes/conflicts, binary hash comparisons, symlink safety, directory/file and file/directory replacement review, rollback artifacts, upload-file validators, generated attachment file checks, original/generated dimension drift, generated-size filename drift, featured-image/image-block/media metadata drift, and unsafe metadata paths. `tests/cow/e2e.sh` verifies real merged upload originals and generated thumbnails. | Add stricter uploads-specific validators for more drift shapes and explicit attachment-regeneration decisions. |
| 5. Crash consistency across DB/files/metadata/Git | `docs/merge-crash-consistency.md` lists the covered boundaries. `tests/cow/merge.php` covers target DB, metadata, file, rollback-failure, ID-band, and whole-branch rollback paths. `tests/cow/e2e.sh` drives public merge/create/reset/recover crash/retry flows for DB, metadata, before-file, after-file, recovery-cleanup, branch-birth, branch-reset publication failpoints, and actual smart-HTTP Git-created branch pushes interrupted before branch-birth metadata, before branch-list publication, and after branch-list publication, each verified after a fresh server restart. `tests/cow/git_server.php` covers Git-created branch birth, Git update/delete, stale cleanup, and object-prune interruption. | Broaden external kill harness coverage across the remaining Git-push failpoints and platform-specific APFS/cleanup checkpoints, then verify post-crash state from a fresh process. |
| 6. Branch birth always captures merge bases | `crates/forkpress-storage/src/lib.rs` requires branch birth metadata for branch reuse/merge and blocks pending reset states. `tests/cow/git_server.php` covers Git-created branch DB/file base, ID-band, row identity, and cleanup/rollback paths. `tests/cow/e2e.sh` covers public create retry after interrupted birth metadata, public reset retry after interrupted reset publication, and remote-cache branch creation followed by AUTOINCREMENT-band insertion and mergeback to `main`. | Keep every new creation/reuse/reset path under the same invariant and add regressions whenever a new branch publication path is introduced. |
| 7. ID-band enforcement beyond happy paths | `tests/cow/id_bands.php` is a focused fast gate for separate branch AUTOINCREMENT bands, JSON/serialized references that keep branch IDs distinct without rewrite, and review-held non-AUTOINCREMENT `INTEGER PRIMARY KEY` plugin collisions. `tests/cow/merge.php` covers AUTOINCREMENT allocation, rollback, reset below old bands, independent branch IDs, explicit out-of-band source IDs, child rows behind held explicit post/term/user IDs, inserted and updated scalar/serialized/theme/widget `wp_options`, `wp_posts`, `wp_postmeta`, `wp_comments`, `wp_commentmeta`, `wp_usermeta`, `wp_termmeta`, `wp_term_taxonomy`, `wp_term_relationships`, post-author, taxonomy menu-item, reusable/media/avatar/navigation/query block `post_content`, and comment-user references behind held explicit post/term/user IDs, JSON/serialized references that keep branch IDs distinct, plugin validator review for no-FK child rows behind held explicit plugin AUTOINCREMENT parents, and non-AUTOINCREMENT `INTEGER PRIMARY KEY` plugin graph collisions as review-held. `tests/cow/e2e.sh` verifies runtime branch post IDs fall inside branch bands and requires an independently banded source/target WordPress post merge to finish with `status: completed` and zero recorded conflicts while preserving embedded JSON/serialized post IDs. | Expand explicit-ID/import handling beyond currently covered AUTOINCREMENT row-insert/rewrite cases and enforce review for more plugin/custom logical identities that are not safely bandable. |
| 7. ID-band enforcement beyond happy paths | `tests/cow/id_bands.php` is a focused fast gate for separate branch AUTOINCREMENT bands, JSON/serialized references that keep branch IDs distinct without rewrite, reset/reuse protection that allocates fresh bands when a branch DB drops below its old reservation, and review-held non-AUTOINCREMENT `INTEGER PRIMARY KEY` plugin collisions. `tests/cow/merge.php` covers AUTOINCREMENT allocation, rollback, reset below old bands, independent branch IDs, explicit out-of-band source IDs, child rows behind held explicit post/term/user IDs, inserted and updated scalar/serialized/theme/widget `wp_options`, `wp_posts`, `wp_postmeta`, `wp_comments`, `wp_commentmeta`, `wp_usermeta`, `wp_termmeta`, `wp_term_taxonomy`, `wp_term_relationships`, post-author, taxonomy menu-item, reusable/media/avatar/navigation/query block `post_content`, and comment-user references behind held explicit post/term/user IDs, JSON/serialized references that keep branch IDs distinct, plugin validator review for no-FK child rows behind held explicit plugin AUTOINCREMENT parents, and non-AUTOINCREMENT `INTEGER PRIMARY KEY` plugin graph collisions as review-held. `tests/cow/e2e.sh` verifies runtime branch post IDs fall inside branch bands and requires an independently banded source/target WordPress post merge to finish with `status: completed` and zero recorded conflicts while preserving embedded JSON/serialized post IDs. | Expand explicit-ID/import handling beyond currently covered AUTOINCREMENT row-insert/rewrite cases and enforce review for more plugin/custom logical identities that are not safely bandable. |
| 8. Better stale-audit workflow | `docs/stale-audit-workflow.md` describes the revalidation model. `scripts/cow/merge.php` implements `revalidate-reviews`, `merge-audit --revalidate`, `merge-resolve --after-revalidate`, revalidation classes, source/target drift checks, plugin validator replacement evidence, and plugin replacement conflict links. `tests/cow/stale_audit.php` is a focused fast gate for reviewed cell conflicts, target drift detection, source cell/row drift detection, `needs-action` carry-forward, idempotent revalidation, audit-visible revalidation classes, and guarded `--after-revalidate` source resolution. `tests/cow/merge.php` covers stale row/cell/file drift, source drift, deleted targets, no-PK rowid replacement, supported WordPress semantic fingerprints, guarded resolution, idempotent carried notes, plugin validator rerun evidence through direct and `merge-audit --revalidate` paths, duplicate identical validator rerun handling, and replacement validator conflict ids. | Add broader plugin/schema source-drift evidence, more custom logical-identity classifiers, and guarded plugin/schema-specific resolution flows where appropriate. |
| 9. Release gate issue | `scripts/build-dist.sh` and release preflight tests fail earlier when static-PHP prerequisites are missing, avoid macOS bash empty-array expansion under `set -u` while wrapping Apple Silicon `spc` commands in `arch -arm64`, and `docs/merge-reliability.md` tracks aarch64 macOS as a release gate. Trunk CI run `25952935740` passed `Build production dist bundle` and release-built COW APFS sparsebundle E2E on `aarch64-apple-darwin` and `x86_64-apple-darwin`, plus Linux COW E2E and Windows checks. The mac APFS e2e now tolerates only the known transient `hdiutil compact` "Resource temporarily unavailable" failure after storage has already detached. | Keep aarch64 macOS release and APFS sparsebundle E2E green on trunk before treating Mac artifacts as trustworthy; do not treat a transient compact skip as proof that compaction itself succeeded. |

Expand Down Expand Up @@ -112,8 +112,9 @@ For branch-birth metadata validation without the Git publication harness, run:
make test-cow-branch-birth
```

For ID-band allocation, JSON/serialized branch ID preservation, and
non-bandable `INTEGER PRIMARY KEY` plugin collision checks, run:
For ID-band allocation, branch-reset reuse protection, JSON/serialized branch
ID preservation, and non-bandable `INTEGER PRIMARY KEY` plugin collision
checks, run:

```bash
make test-cow-id-bands
Expand Down
19 changes: 19 additions & 0 deletions tests/cow/id_bands.php
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,25 @@ function create_id_band_db(string $path): void {
1,
'plain INTEGER PRIMARY KEY plugin collision is recorded as a review conflict'
);

$reset = $tmp . '/reset.sqlite';
copy($base, $reset);
$reset_band = cow_merge_allocate_autoincrement_bands($reset, $metadata, 'feature-source');
assert_same($reset_band['allocated'], 2, 'reset branch DB below its old band gets fresh AUTOINCREMENT bands');
assert_same($reset_band['reused'], 0, 'reset branch DB below its old band does not reuse possibly published bands');
assert_true(
(int)scalar($reset, "SELECT seq FROM sqlite_sequence WHERE name = 'wp_posts'") > $target_post_id,
'fresh reset post band is above previously allocated branch post IDs'
);
assert_true(
(int)scalar($reset, "SELECT seq FROM sqlite_sequence WHERE name = 'wp_options'") >= (int)scalar($metadata, "SELECT band_start - 1 FROM merge_autoincrement_bands WHERE branch_name = 'feature-source' AND table_name = 'wp_options'"),
'fresh reset option band is recorded in the app DB sequence'
);
assert_same(
(int)scalar($metadata, "SELECT COUNT(*) FROM merge_runs WHERE source_branch = 'feature-source' AND policy = 'autoincrement-id-band-allocation' AND status = 'id_bands_allocated'"),
2,
'reset-safe AUTOINCREMENT allocation runs are auditable'
);
} finally {
remove_tree($tmp);
}
Expand Down
Loading