Skip to content

test(mysql): WU-2 schema compliance for PHP-created MySQL test tables (F4-16) - #71

Merged
megyptm merged 2 commits into
mainfrom
claude/persistence-wu2-technical-lead-118401
Oct 22, 2026
Merged

megyptm merged 2 commits into
mainfrom
claude/persistence-wu2-technical-lead-118401

Conversation

@megyptm

@megyptm megyptm commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

الملخص والنطاق

WU-2 / Issue #64 — معالجة F4-16 وفق Pinned PACKAGE_BUILDING_STANDARD §6 لجداول اختبار MySQL المُنشأة داخل PHP.

Closes #64 · Refs #37 (RELEASE BLOCKED؛ لا Tag/Release/version/deploy، والدمج إلى main بقرار المالك فقط).

Git identity — final reviewed candidate

  • Base / Merge Base: 3b1af0d74eba809486f04aa34570d12dc2afede3 · Tree: de85ce1edba60581c3b95793af0c57b3a5cf50b7
  • HEAD: eb67ac2a261ecf63930ae898e6b622ef0bd60a67
  • Tree: 18e492f87a3a009a8479d78ad2e5226a0159caa1
  • Cumulative diff: 3 test files, +207/−15, 2 commits (second commit addresses review F71-01..04).
  • No change in src/, public API, Composer files, tracked schema fixtures, CI/workflows, or pinned standards; original DDL column types, PKs, secondary indexes, InnoDB engine and transaction scenarios stay unchanged.

Schema coverage and policy

  1. tests/Support/MySql/LazySavepointSchema.php: policy docblock for five test tables (plain, unique, audit, marker, fill); meaningful TABLE/COLUMN COMMENTS. display_order deliberately remains unindexed to retain the locking test's current access path; UNIQUE u_updated (updated_at) remains for original 1062 failure. Tests retain the default active deleted_at soft-delete filter; none soft-deletes a row.
  2. tests/Integration/Examples/ExampleSchemaCleanupTest.php: colliding sixth test table gains documented no-FK/no-soft-delete/no-display-order/PK-only policy and TABLE/COLUMN COMMENTS. An information_schema assertion checks the comments and PRIMARY KEY (id) inside try/finally, preserving cleanup even on failing assertions. Original 1050 and metadata-lock scenario remain.
  3. tests/Integration/Support/LazySavepointSchemaComplianceTest.php: 5 data-provider cases check comments, PRIMARY KEY (id), and exact declared secondary indexes. Uses typed fetchColumn() outputs to work with both PHPStan 2.1.0 and 2.3.1. It guards index declarations, not optimizer plans; separate real-MySQL E2E tests guard locking semantics.

Schema Compliance Matrix

Test table PK Table/column comments Index/policy
maa_persistence_test_lsp_plain id Yes No secondary; locking fixture deliberately unindexed display_order
maa_persistence_test_lsp_unique id Yes u_updated UNIQUE on updated_at maintains 1062 path
maa_persistence_test_lsp_audit id Yes PK row locks for 1205/1213
maa_persistence_test_lsp_marker id Yes PK only; caller earlier work
maa_persistence_test_lsp_fill id Yes PK only; deadlock partner weight
maa_example_items_cleanup_* id Yes PK only; deliberate 1050 collision fixture

Test table identifiers were preserved to avoid changing existing test contracts and residue detection. Existing tests/Fixtures/MySql/*.sql, examples, consumer fixtures and residue tests are unchanged.

Evidence and validation

GitHub CI Run #39814832284 on the exact HEAD above: 10/10 completed successfully, including Workflow lint, Quality, Unit/Regression on PHP 8.2/8.3/8.4/8.5, Lowest Dependencies on PHP 8.2 and real MySQL 8.4.10, Integration on PHP 8.2 and 8.5, and CI Gate.

  • Lowest: PHPStan 2.1.0 clean; Unit 383, Regression 97; real MySQL integration twice: 223/223 (1690 and 1691 assertions); no MySQL residue.
  • Latest Quality: PHPStan 2.3.1 clean; syntax/style/whitespace pass.
  • Integration PHP 8.2: 223/223 twice (1685, 1684 assertions); Consumer Harness two clean runs; residue PASS.
  • Integration PHP 8.5: 223/223 twice (1696, 1692 assertions); Consumer Harness two clean runs; residue PASS.
  • RED/GREEN from executor: baseline lazy fixture missing comments fails 5/5; removing both comments from Example collision table fails; removing only its column comment fails; GREEN after restoring; RED failure now cleans up fixture (check:residue PASS).
  • Local MySQL 8.4.10 / PHP 8.4.4: integration twice 223/223, consumer twice, latest and lowest PHPStan, unit/regression, residue, whitespace/syntax/style pass (executor evidence).
  • Known independent docs(composer): WU-3 explicit dependency-audit policy and Composer SHOULD items (F4-11, F4-05) #65: local composer check:lowest on PHP 8.4.4 / Composer 2.8.6 stops at audit of dev dependencies; the same full required lowest-dependency gate passes in GitHub CI on minimum supported PHP 8.2. Do not misattribute this to WU-2 or suppress advisories. WU-3 handles policy separately.

Existing mutex/savepoint/deadlock integration tests preserve original 1062, 1205, 1213, scope locks and caller-owned transaction semantics. No SQLite/mocks replace real service verification.

Follow Chart

flowchart TD
    A[Integration suite on real MySQL] --> B{Scenario}
    B -->|Schema compliance| C[Initialize five lazy-savepoint fixture tables]
    C --> D[Inspect table and column comments, primary and secondary indexes]
    D --> E[Drop fixture tables]
    B -->|Transaction and lock regression| F[Initialize identical fixture structure]
    F --> G[Run scope locks, lazy savepoints and caller-owned transactions]
    G --> H{Failure scenario}
    H -->|Duplicate key| I[Assert original 1062 and rollback behavior]
    H -->|Lock wait| J[Assert original 1205 and transaction state]
    H -->|Deadlock| K[Assert original 1213 and victim behavior]
    H -->|Normal or false result| L[Assert changes, rollback and caller work]
    I --> M[Rollback open transactions and remove fixtures]
    J --> M
    K --> M
    L --> M
    B -->|Example cleanup| N[Create pre-existing collision table]
    N --> R[Assert table and column comments and primary key]
    R --> O[Run example setup and assert 1050 and cleanup]
    O --> P[Remove test-created objects]
    E --> Q[Repeat integration suite and check MySQL residue]
    M --> Q
    P --> Q
Loading

🤖 Generated with Claude Code

… (F4-16)

Document policies and add column/table COMMENTs for the lazy-savepoint and
example-cleanup test tables (PACKAGE_BUILDING_STANDARD section 6), and pin the
index set with an information_schema guard test. DDL structure is unchanged:
no display_order index is added and UNIQUE u_updated is kept, so access paths
and lock behaviour are preserved. Ref #64, #37.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>

megyptm commented Oct 22, 2026

Copy link
Copy Markdown
Collaborator Author

مراجعة القيادة الفنية المستقلة — WU-2 / PR #71 — CHANGES REQUIRED

الحكم: MERGE NO-GO. هذه مراجعة واحدة للـdiff التراكمي كاملًا وجميع الملفات الثلاثة، وليست مراجعة ملاحظة واحدة ثم التوقف. لا تغيير Runtime أو Public API أو فهارس/قيود أصلية. أضفت Mermaid Follow Chart بالإنجليزية إلى وصف PR بنفسي.

الهوية المتحقق منها من GitHub:

  • Base / Merge Base / main: 3b1af0d74eba809486f04aa34570d12dc2afede3
  • HEAD: 037c64c490a9786d57e380fd3bc63a524440e50b
  • HEAD Tree: db5d0d3ddb219342c1d088698c7b4211e9d198f8
  • Diff: 3 test files (+176/−15), 1 commit; PR Draft، غير مدمجة.
  • المرجع المعياري: docs/php-engineering-standards/standards/packages/PACKAGE_BUILDING_STANDARD.md §6 (المثبت 1.4.0)، TESTING_STANDARD §4.5، AGENTS.md/Manifest.

الملاحظات المجمعة

F71-01 — BLOCKER: Lowest-dependencies PHPStan fails in the newly added test.

  • tests/Integration/Support/LazySavepointSchemaComplianceTest.php:82-84: $row من PDOStatement::fetch(PDO::FETCH_ASSOC) ما زال mixed عند الوصول إلى name وnon_unique وcolumn_name.
  • GitHub CI Run 39800071507، وظيفة Lowest dependencies فشلت بثلاثة offsetAccess.nonOffsetAccessible تحت PHPStan 2.1.0. وCI Gate فشل تبعًا لها، لذلك النتيجة 8/10، وليست Full Green.
  • أصلح بـtype narrowing/check صريح (is_array قبل الوصول إلى offsets) دون suppression أو تغيير dependency constraints/CI. أعد بوابة Lowest كاملة حتى التحليل والاختبارات، مع CI.

F71-02 — BLOCKER: regression guard does not cover the sixth repaired table.

  • اختبار tests/Integration/Support/LazySavepointSchemaComplianceTest.php:37-69 يفحص جداول LazySavepoint الخمسة فقط.
  • الجدول السادس المعدل داخل tests/Integration/Examples/ExampleSchemaCleanupTest.php:28-31 أضيف له TABLE/COLUMN COMMENT، لكن اختبارات Example الحالية تتحقق من التصادم 1050 والتنظيف، لا من الـCOMMENT. إزالة هذين التعليقين لن تُكتشف في اختبار الـschema الجديد ولا باختبار التنظيف. وبذلك لا توجد regression assertion للجزء السادس من F4-16 (Testing §4.5).
  • أضف إثباتًا محدودًا على جدول الـcollision أثناء وجوده (information_schema.TABLES/COLUMNS وتعليقات غير فارغة، مع PRIMARY KEY (id) إذا استُخدم كضمان في اسم الاختبار)، ويمكن دمجه مع اختبار التنظيف الحالي؛ أظهر RED عند إزالة التعليقات وGREEN بعد إعادتها. لا تغيّر سلوك 1050 أو ضمانات cleanup.

F71-03 — REQUIRED DOC: policy header incomplete for the Example collision table.

  • tests/Integration/Examples/ExampleSchemaCleanupTest.php:12-17 يشرح هدف التصادم والتنظيف؛ وعمود id يذكر No FK، لكنه لا يحدد سياسة الجدول كاملة كما يقتضي PACKAGE_BUILDING_STANDARD §6: عدم وجود soft delete/display order/FK، وأن التفرد فقط بـPK وأن PK وحده مناسب للوصول.
  • وثق هذه السياسات بإيجاز في docblock الملاصق للـDDL أو رأس الاختبار، دون إضافة فهرس غير لازم.

F71-04 — REQUIRED ACCURACY: narrow two documentation guarantees to what is proven.

  • tests/Integration/Support/LazySavepointSchemaComplianceTest.php:14-17: فحص أسماء الأعمدة/الفهارس والـuniqueness يحمي تعريف الفهارس، لكنه لا يجمد خطة optimizer أو EXPLAIN، حتى مع نفس الفهارس. صياغة “access paths ... must not change silently” أوسع من assertions؛ صحح الوصف إلى guard على index declarations، واترك إثبات السلوك الفعلي لاختبارات الأقفال القائمة.
  • tests/Support/MySql/LazySavepointSchema.php:12-18: يذكر deleted_at كـsoft-delete policy، بينما ScopedOrderingManagerLazySavepointTest::config() يمرر updatedAtColumn فقط؛ وضّح أن العمود موجود لكن soft-delete filtering غير مُفعَّل في هذه الاختبارات (إن كان ذلك ما يؤكده الـconfig). لا تُدخل تغييرًا في runtime/config.

ما تأكدت من نجاحه

  • GitHub CI: Workflow lint وQuality، وUnit/Regression على PHP 8.2–8.5، وIntegration على PHP 8.2 و8.5 نجحت.
  • في كل وظيفة Integration نجحت composer test:integration مرتين: PHP 8.2 = 223 اختبارًا (1676 ثم 1677 assertions)، PHP 8.5 = 223 اختبارًا (1675 ثم 1672 assertions). Consumer Harness أكمل جولتين نظيفتين وMySQL residue PASS في كليهما.
  • Lowest job نجحت فيه dependency resolution وcomposer audit: No security vulnerability advisories found على PHP 8.2 / Composer 2.10.2؛ الفشل الفعلي في PHPStan للاختبار الجديد، وليس Advisory. تنبيهات PHP 8.4 / Composer 2.8.6 المحلية التي أبلغ عنها المنفذ تبقى ضمن فحص docs(composer): WU-3 explicit dependency-audit policy and Composer SHOULD items (F4-11, F4-05) #65، ولا تبرر تجاوز هذه البوابة هنا.
  • مقارنة DDL: لا تغيير في أنواع الأعمدة أو InnoDB أو فهارس PRIMARY وu_updated، ولا فهرس على display_order. بقيت اختبارات القفل/1062/1205/1213 دون تعديل.

المطلوب: عالج F71-01..04 في commit جديد دون amend/force-push، وأعد إثبات RED/GREEN المحدد وبوابات MySQL (Integration مرتين، Consumer، residue)، ثم اكتمال CI 10/10 على HEAD الجديدة. لا تُدخل WU-3 أو تغييرات src/، ولا Merge. بعد التسليم سأجري Fresh Full Re-Review للشجرة النهائية والـdiff التراكمي كاملًا قبل MERGE GO، وليس مجرد تأكيد الإصلاحات.

- F71-01: read information_schema index rows through fetchColumn so the guard
  passes PHPStan max on both the latest and the lowest dependency sets.
- F71-02: assert TABLE/COLUMN COMMENT and PRIMARY KEY (id) on the Example
  collision table, inside the try so a failing assertion still drops it.
- F71-03: document the collision table policy (no soft delete, display order,
  uniqueness beyond PK, or FK; PK is the only access path).
- F71-04: narrow the guard description to index declarations and document that
  soft-delete filtering is active via the default deleted_at but never exercised.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
@megyptm

megyptm commented Oct 22, 2026

Copy link
Copy Markdown
Collaborator Author

تسليم المنفذ بعد مراجعة القيادة — معالجة F71-01..04

Commit جديدة بلا amend أو force-push. لا تغيير في src/ أو في أي DDL أو فهرس.

  • Base / Merge Base: 3b1af0d74eba809486f04aa34570d12dc2afede3
  • HEAD السابقة: 037c64c490a9786d57e380fd3bc63a524440e50b
  • HEAD الجديدة: eb67ac2a261ecf63930ae898e6b622ef0bd60a67 · Tree: 18e492f87a3a009a8479d78ad2e5226a0159caa1
  • Diff تراكمي: 3 ملفات اختبار (+207/−15)، commit إضافية واحدة.

F71-01. أقر بأن هذا خلل حقيقي في عملي: لاحظت سابقًا ثلاثة أخطاء PHPStan بعد check:lowest ونسبتها خطأً إلى تبديل vendor/. الإصلاح: قراءة صفوف information_schema.STATISTICS عبر fetchColumn() (النوع mixed في الإصدارين) بدل fetch(FETCH_ASSOC)، مع CAST(NON_UNIQUE AS CHAR)، دون suppression أو cast أو تغيير dependency constraints. جرّبت is_array/assertIsArray أولًا فنجحا على Lowest (PHPStan 2.1.0) وفشلا على Latest (2.3.1: alreadyNarrowedType)، ولذلك لم أعتمدهما.

F71-02. ExampleSchemaCleanupTest يتحقق الآن من جدول التصادم أثناء وجوده: TABLE_COMMENT غير فارغ، لا عمود بلا COMMENT، PRIMARY KEY (id). RED/GREEN:

  • إزالة التعليقين: يفشل بـ"the collision table needs a table COMMENT".
  • إزالة تعليق العمود فقط: يفشل بـ"every column of the collision table needs a COMMENT".
  • بعد إعادتهما: GREEN.
  • أثناء ذلك ظهر عيب في أول نسخة مني: وضعت الـassertion خارج try، فتركت فشلها الجدول (residue). أصلحته بنقلها داخل try، وأثبت أن RED لا يترك مخلّفات (check:residue PASS بعد RED).

F71-03. سياسة جدول التصادم موثقة في docblock الاختبار: بلا soft delete أو display order أو uniqueness غير الـPK أو FK، والـPK هو مسار الوصول الوحيد لأن الجدول يُنشأ ويُحذف فقط.

F71-04.

  • وصف LazySavepointSchemaComplianceTest صار حارسًا لتعريفات الفهارس فقط، ولا يدّعي تجميد خطة optimizer أو EXPLAIN.
  • تصحيح للتفسير المقترح في المراجعة: ScopedOrderingConfig::$deletedAtColumn افتراضيه 'deleted_at' (src/Pdo/Ordering/ScopedOrderingConfig.php:45)، والاختبارات لا تمرره، فـفلتر soft-delete مفعّل فعليًا لكن لا يُحذف أي صف soft (كل الصفوف NULL). وثّقته بهذه الصياغة، ولم أغيّر config.

الإثبات المحلي على HEAD الجديدة (MySQL 8.4.10 حقيقي، PHP 8.4.4):

  • composer analyse: No errors على Latest (PHPStan 2.3.1) وعلى Lowest (2.1.0 بعد composer update --prefer-lowest): No errors. على Lowest أيضًا: test:unit 383 وtest:regression 97 وحارسا الـschema (9/9).
  • ملاحظة: composer check:lowest المحلي ما زال ينتهي بـexit 1 عند composer audit (تنبيهات PHP 8.4 / Composer 2.8.6، موضوع docs(composer): WU-3 explicit dependency-audit policy and Composer SHOULD items (F4-11, F4-05) #65)، أما vendor فيكون قد بُدّل بالإصدارات الدنيا قبلها. التحليل أعلاه شُغّل عليه. بوابة Lowest الكاملة (resolve → audit → analyse → tests) على PHP 8.2 هي ما يثبته CI.
  • composer test:integration مرتين: 223/223 (1641 ثم 1645 assertion)، وtest:consumer جولتان نظيفتان، وcheck:residue PASS، وvalidate --strict، وaudit، وcheck:syntax، وcheck:whitespace، وphp-cs-fixer: exit 0.
  • CI على GitHub لم أتحقق منه بعد على HEAD الجديدة؛ أنتظر 10/10 ولا أعدّه بديلًا عن Fresh Full Re-Review.

لا Merge. بانتظار الـFresh Full Re-Review.

megyptm commented Oct 22, 2026

Copy link
Copy Markdown
Collaborator Author

Fresh Full Re-Review — WU-2 / PR #71 — MERGE GO (Owner authorization required)

أجريت مراجعة مستقلة للشجرة النهائية والـdiff التراكمي كاملًا بعد التصحيح، وليس إعادة فحص F71-01..04 منفردة. راجعت الملفات الثلاثة بالكامل، المصدر المعياري المثبت وAGENTS/Manifest، اختبارات التزامن الفعلية، DDL قبل/بعد، تقرير وتصحيحات المنفذ، ونتائج وظائف GitHub CI وسجلاتها. حدّثت وصف الـPR بنفسي ليعرض هوية الـHEAD النهائية والبوابات وFollow Chart الصحيحة.

الهوية والنطاق

  • Base / Merge Base / current main: 3b1af0d74eba809486f04aa34570d12dc2afede3
  • HEAD eb67ac2a261ecf63930ae898e6b622ef0bd60a67
  • Tree 18e492f87a3a009a8479d78ad2e5226a0159caa1
  • Two additive commits; 3 test files, +207/−15. No src/, public contracts, table identifiers, original DDL types/indexes/engine, CI/Composer changes or adoption upgrade.
  • Pinned standards are governed by STANDARDS_MANIFEST.md (Resolution VALID; upstream commit 44c8827095ab4007c355aa21c56b853f3b49d795).

Full final acceptance matrix

Item Judgment / independent evidence
F71-01 lowest-PHPStan PASS: index reader now uses scalar/list fetchColumn() instead of unsafe FETCH_ASSOC offset access. GitHub Lowest resolves PHPStan 2.1.0, [OK] No errors, suite and residue PASS. Quality resolves PHPStan 2.3.1, [OK] No errors.
F71-02 sixth table regression PASS: assertCollisionTableIsDocumented() checks nonempty TABLE/COLUMN COMMENTs and PK id during setup, inside try/finally. Executor supplied RED for both removed comments and column-only removal plus cleanup-on-RED evidence. The original 1050/cleanup assertions remain intact.
F71-03 policies PASS: header explains intentional PK-only, no FK/host join, no soft delete, no ordering, no other uniqueness. Five lazy table policies and the index exception are documented adjacent to DDL.
F71-04 overclaim PASS: compliance test documentation guards index declarations, expressly not optimizer plan/EXPLAIN. Confirmed ScopedOrderingConfig::$deletedAtColumn = 'deleted_at' by default, so filter is active in lazy tests while all seeded rows remain active; corrected docs match runtime.
§6 DDL PASS in WU-2 scope: six PHP-created test tables now document intended schema, have primary id and meaningful comments; preserved original access-path assumptions, PKs and u_updated without changing table types, DB semantics or index set.
Transactions/locks PASS: existing system tests cover 1062, 1205, 1213, scope/gap locks, deadlock victim, lazy savepoint and caller-owned transaction invariants; no altered runtime or concurrency tests.
Regression/cleanup PASS: guard on five lazy fixtures plus Example sixth; explicit try/finally prevents the discovered RED fixture leak, and database residue verifies final cleanup.
Scope/governance PASS: only intended tests, two non-rewritten commits; #64 and #37 linked. Mermaid Follow Chart is in PR body; no release/deploy/tag.

CI verified directly on exact HEAD — Run 39814832284

10/10 SUCCESS, including mandatory CI Gate.

  • Lowest (PHP 8.2, MySQL 8.4.10): PHPStan 2.1.0 clean, Unit 383/383, Regression 97/97, Integration 223/223 twice (1690/1691 assertions); residue PASS.
  • Quality latest dependencies: PHPStan 2.3.1 clean; syntax/style/whitespace PASS.
  • Integration PHP 8.2: 223/223 twice (1685/1684 assertions), two-run Consumer Harness PASS, residue PASS.
  • Integration PHP 8.5: 223/223 twice (1696/1692 assertions), two-run Consumer Harness PASS, residue PASS.
  • Workflow lint and PHP 8.2–8.5 Unit/Regression matrix PASS; audited dependency resolutions in CI reported no advisories.

Separately recorded: local check:lowest on PHP 8.4 / Composer 2.8.6 stops at security audit of its resolved dev dependencies; tracked under WU-3 #65 and not waived or called false positive. On required min-PHP GitHub job, the entire lowest-dependency pipeline, real MySQL tests and audit are green. This does not justify a WU-2 runtime, CI policy or dependency-scope change.

Decision and boundaries

WU-2 is accepted for Owner-authorized MERGE GO on this exact HEAD/Tree. No outstanding WU-2 findings. This is not a merge operation or release approval. PR remains Draft until the Owner decides; #37 remains RELEASE BLOCKED, WU-3 #65 and documented F4-04 #66 remain separate.

After the Owner merges, reconcile actual merge commit/tree against the reviewed tree, post-merge CI, issue #64/umbrella #37, then proceed in approved work-unit order. No database migration, cache clearing or production deployment is implied by this test-only change.

@megyptm
megyptm marked this pull request as ready for review October 22, 2026 18:47
@megyptm
megyptm merged commit 5a3399a into main Oct 22, 2026
10 checks passed
@megyptm
megyptm deleted the claude/persistence-wu2-technical-lead-118401 branch October 22, 2026 18:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

test(mysql): WU-2 schema compliance for PHP-created MySQL test tables (F4-16)

1 participant