Skip to content

Inspect stored PHP state before native upgrade - #460

Draft
rmcdaniel wants to merge 26 commits into
mainfrom
rust-325-upgrade-inspect
Draft

rmcdaniel wants to merge 26 commits into
mainfrom
rust-325-upgrade-inspect

Conversation

@rmcdaniel

@rmcdaniel rmcdaniel commented Oct 15, 2026 •

Copy link
Copy Markdown
Member

Adds development-only read-only commands for an existing PHP database: exact known catalog/count inventory, bounded database-queue binding, and recorded-codec Avro/root external-reference inspection. Dedicated connections never construct a runtime pool or mutate source rows. Reports keep backup, writer quiescence, complete representation and takeover explicitly false.

SQLite WAL, special files, unknown layouts/permissions/ownership and unsupported stored representations refuse. Queue parsing never executes PHP objects. Root inline frames are capped at 64 KiB before transfer, with bounded schema traversal and a separately verified Apache allocation ceiling. Source observation retains its original 30-second budget.

Current candidate 7066a50ef10cd25958fc6ad5bfd305a7d901e969 / whole 4c3394c728f7f60be3e0b0d59da89a4b5f76f6b3 / native 302571a379fe5bbf05dcc41f20b47a3770e3b670 is isolated on qualified query main 0934c46d. It contains neither pending activity endpoint. PHP application, Composer, OpenAPI, release and frozen actor bytes match main.

The previous 58542a5e passes all 13 hosted jobs across six databases, but a separate constructed path-replacement control creates WAL/shared-memory sidecars on a writable mount before catalog refusal. Promotion is held. This correction enforces read-only mounts for both the source file and resolved parent directory before the CLI opens SQLite, preserving locking and the original total budget. The first mounted payload/special-source component passes 2 CLI controls; a later component passes 109 library tests with 18 existing ignores. The final local batch was terminated during CLI validation at the overdue cleanup checkpoint. There is no completed final-head CLI/execution acceptance. Exact new hosted qualification is pending; 6197072693 records those limits. No earlier pass is carried. The original source/recorder/upload failures stay failed and unexplained where recorded.

Prior combined source03b3 independently passes stopped published PHP2.8.5 SQLite DELETE/MySQL8.4/PostgreSQL17: six pending raw-protocol originals, nine inline argument frames, three canonical timer bindings and applicable refusal controls, with unchanged source fingerprints. Its native029 component passes112 library/2CLI/133SQLite tests, with18 existing library ignores. Those are earlier components, not qualification of this changed native tree.

The existing published PHP2.8.0 recipe remains the CI default; an explicit immutable official-image override supports separate current-release observation. Cleanup always runs, and bounded hosted summaries exclude raw databases/payload journals. No new native release/capability, backup restore, SDK takeover, full stored-state parity or migration is claimed. Refs #325.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Actual published Server 2.8.0 source preparation passes: one original leased activity and a separate pending timer; explicit SIGTERM exits 0 without OOM. Initial cd455 inspection refuses. Read-only directory mounting prevented WAL sidecar creation, but a separate writable-directory countercontrol created empty WAL/shared-memory sidecars despite SQLite read_only=true (main database SHA unchanged). Prospective contract: refuse WAL from its header before opening SQLite; rollback-journal inventory only until a consistent WAL snapshot path is independently qualified. Separately, exact current PHP catalog differs from the old compiled physical baseline: service-call deadline column/index plus Worker registration-token/incarnation table/indexes. Unknown current layout remains refused; no schema difference will be discarded to manufacture acceptance. Original failure and both original run identities stay recorded. Takeover/backup/quiescence authority remains false.

@rmcdaniel

Copy link
Copy Markdown
Member Author

86d5 local source profile passes SQLite, including unknown-column and malformed ownership-marker refusals with before/after byte equality. Its MariaDB first inventory refuses: complete definitions match the exact variant, but MariaDB information_schema orders underscore-containing table names differently from Rust byte ordering. Prospective metadata disposition: canonicalize both complete source catalog row lists by exact table-name bytes before comparison/fingerprinting. Preserve every name/definition, table count, constraint and index; do not alter any business event or row ordering, native migration/catalog or frozen differential actor. The original MariaDB refusal remains failed. Separately, repository isolation policy correctly rejects the profile stop command redirecting to a variable output path; the new runner discards that redundant stop output and keeps independently checked stopped-state JSON. No policy relaxation or resource/budget change.

@rmcdaniel

rmcdaniel commented Oct 15, 2026 •

Copy link
Copy Markdown
Member Author

Published-source inventory acceptance is local only; candidate all-six qualification remains pending in 38668390692.

Final head c3f09fd, whole tree 2fc44702, native tree cad3a39e. Local profiles execute ddd696c; the final commit changes only documentation. The native binary stays da65ea076edb48764d9b13ef4aa922afa72b46c0526843eb5679394faee7822e. Source is normally published PHP 2.8.0 / dd720e6, immutable index cba7c4c6732529293ef6c2625a64785dcb21b4f7fe0013fdc74f1af466f534ac.

Database Original activity run Original timer run
SQLite DELETE 01m4ym1mjzr4z6kb45abg6xzbt 01m4ym1n6rxjq17gk80yk3zhm1
MySQL 8.4.5 01m4ym3vqx67qypsq73v0cq53r 01m4ym3w88p81qn2cjb5fawghr
MariaDB 10.11.19 01m4ym72k9v0yzyctxks6taw92 01m4ym737hjp5vt7bezyq5yqgz
PostgreSQL 17 01m4yky3caaesj57x2k3xdg7gb 01m4yky421vxhxtf8kfheptqy1

Each profile checks the exact 50-table layout, two pending runs, one leased activity, PHP SIGTERM/exit 0/no OOM, source rows/sequence positions or SQLite bytes unchanged, and all takeover/backup/quiescence/representation flags false. The raw public-protocol author is not an SDK continuation or completed workflow claim. Original preparation retains its 30-second deadline; inspection retains 30 seconds plus separate one-second connection retirement. The eight-minute hosted phase and three-minute cleanup bound are new prospective allocations, with existing job/scenario budgets unchanged.

Twelve actual refusals pass: unknown column and malformed ownership marker in all four databases; denied network roles in three; PostgreSQL row security. Every inspection/refusal has a before/after source-state comparison. Foreign-owner cleanup refuses without mutation, and actual MariaDB cleanup is idempotent. Native library tests pass 73/73, 18 explicit ignores. The preceding SQLite component passes 105/105 before the MariaDB/catalog-order-only changes. Isolation policy and 72/72 controls pass; PHP syntax and Rust formatting pass.

Initial cd455 WAL/source-catalog failures remain failed on original runs 01m4yjxkt1mwtpads4vxhma8mc / 01m4yjxmhq9g7tga1c1fk77zs0. The writable-directory countercontrol created WAL/SHM sidecars despite read_only; the main database hash stayed unchanged. The corrected path refuses WAL before opening, including a committed live WAL unit case, without using immutable mode to omit data. Initial 86d5 MariaDB refusal on 01m4ykdr3cd1gkgm01yv108gbr / 01m4ykdrrc49nvxqv0sn2ztcae exposed metadata collation order; canonicalizing both complete catalog lists fixes presentation only. Those original refusals are not rescued. Early development executions do not supply exact-tree acceptance; the committed profile captures source/binary identities at admission and checks them unchanged before reporting success.

No production migration, WAL snapshot, SQL/external backup restoration, stored-representation conversion, interruption recovery, native capability/release, matched performance gain or cutover qualification is claimed. Existing PHP ownership guards require no change for this inventory step.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Cleanup independently completed at 02:00:05 UTC, before the 02:15 boundary: all task HTTP/DB containers, network, owned MariaDB image, local databases, compiler/target/registry cache, formatter and raw source/transport files are removed. All three DB servers stopped with exit 0/no OOM. The task GHCR input reference is removed while the separate shared Docker Hub reference is preserved. Only the clean unfinished source worktree remains; no bulk retention is claimed. Code/countercontrols and readable outcomes above remain. Exact-head hosted qualification is queued in 38668390692; no pass is carried from another head.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Current-main integration is now 68c42b1 / whole 68541db92c98a2577d20963352fef967676e7c99, merging delivered #457 main303. Native subtree stays exactly cad3a39e; local component acceptance above is unchanged, while the combined whole tree needs new qualification. Fresh shared 38669154951/source38669155000/boundaries38669154885+38669149206 are live/queued. Earlier c3 shared38668390692 was cancelled during SDK setup: dependent execution/storage/codec/MySQL placeholders have zero steps, so no database scenario was admitted. It remains cancelled, not passed. Documentation conflict was resolved to retain failure/retention limits and current delivery status; only the new task state ignore was added. No local runtime/cache/raw resources were recreated.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Current 68 original SQLite job 116210443742 is failed, not qualified: library 73 pass/18 explicit ignores; HTTP 104 pass/1 fail. The existing stalled-upload control returns 503/external_payload_unavailable instead of 201 for its fresh three-byte upload under the unchanged 100ms timeout (external_payloads.rs:1354). The stalled first upload correctly refuses; no narrower cause is established. The codec step exits before creating the deployment network, so later source-inventory/marker/external-consumer steps report missing network and do not qualify their scenarios. Other original database jobs continue. I read the bounded 21KiB test summary and removed the downloaded archive immediately. No source, budget or expectation has been changed to rescue this original.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Source review separates two checks that the failed control conflates. The stalled request must still stop on its original 100ms deadline. A fresh durable upload is allowed to return unavailable when its own 100ms filesystem/SQL budget expires, so that response alone does not prove a leaked capacity slot. I will keep the failed original and replace the speed assumption with a fresh request using the normal 30s policy while sharing the exact same one-slot semaphore. A retained slot must still make that control fail. No runtime timeout default or existing admitted request is changed. I am also checking special-file refusal in the new read-only CLI before claiming its observation bound.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Revised source 4459140 / whole a2f44281bcacc3e0667a00595106694f484b31a7 / native a21b69a1be1cc1190d6df12d3b935c6c2da4b77d is pushed. Local component checks pass 73 library cases/18 explicit database-only ignores, 105 HTTP cases and one real CLI process control. The previous inspector fails that FIFO process control (killed at its 3s refusal ceiling); regular-file checks plus nonblocking Unix open pass it. Existing lockfile libc is now an explicit Unix dependency, with no transitive version update. Formatting and the action-policy validator pass. The stalled upload keeps 100ms; a fresh normal-policy request shares its exact one-slot semaphore. New hosted whole-tree qualification remains required, and old 68 database originals continue unchanged. Inventory runs now require successful deployment prerequisites and retain always-run cleanup. Source docs identify PHP queue/class/codec/cache representation gates without claiming conversion or takeover.

@rmcdaniel

Copy link
Copy Markdown
Member Author

All local verification resources were retired at 02:37:29 UTC, ahead of the 03:00 ceiling: task containers, compiler/target/registry cache, formatter, counterfactual source copy and logs are gone. Only the clean unfinished source worktree remains; root is 66% with 33GiB available. Exact-head hosted 38671922377 plus normal source/boundary checks are queued. Earlier 68 originals are not cancelled or rescued; no bulk retention is claimed.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Revised head 4459140 / run 38671922377 has a separate failed SQLite original: execution-and-codec job 116222559598 fails in restart.php prepare while polling restart-old/restart-v1 activity work from the frozen published PHP target, http://parity-server:8080. The actual response is 503/backend lock pressure; the SDK exception is at restart.php:109. The workflow identifies that target from the unchanged PHP 2.5.14 / Workflow 2.5.5 baseline (amd64 image 28fa0f39). Native preparation is a separate preceding invocation.

The upgrade-inspection step is SKIPPED because its prerequisite failed. No SQLite inventory or takeover acceptance is inferred. The later corrected-marker phase also fails with cURL52/empty reply from its native endpoint; its cause is not established or equated to the PHP lock observation. The job has 22 passing scenario outcome records before/around these failures, which do not rescue it.

The complete job log has been read; the small failure artifact is being retrieved for a further bounded audit. Other admitted database cells continue unchanged. No retry, allocation/timeout change, frozen retuple, current-release correction or shared-cause claim is made by this checkpoint.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Bounded artifact audit completed through the GitHub connector after the host artifact download hit an Azure TCP timeout. Artifact 11946313344 is 187,387 compressed bytes, not a bulk SDK archive. It independently confirms 73 library passes / 18 explicit ignores, all 105 native HTTP passes, and the real FIFO/directory process control pass. The revised 100ms/fresh-normal-budget capacity test passes in this execution; the earlier failed original remains failed.

The installed local external-consumer comparison also completes all five original workflows per PHP/native target with original 30-second budgets and all seven reader refusals. These passed components do not rescue the failed shared restart or establish the skipped upgrade inspection. Corrected-profile PHP maintenance logs include a SQLite error5 during child-projection timeout publication; that is a separate profile observation, not proof of the primary poll cause or later native empty-reply cause. Original native exit/OOM state is not present in this thin artifact, so that cause remains unestablished. No CI/runtime restart or retuple was used to obtain the artifact; the local ZIP is being deleted after this audit.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Correction to the follow-on empty-reply disposition: workflow/source inspection establishes the missing prerequisite. The failed PHP restart preparation is before creation of parity-recovered; that creation command never executes. The corrected-marker step nevertheless uses !cancelled() and invokes corrected-marker-shared-profile.sh against http://parity-recovered:8080. Its native phase therefore has no prepared recovered target. The proxy empty reply is a derived absent-baseline failure, not a qualified observation of native execution or an established native crash/OOM.

The original PHP activity-poll 503 remains failed with its cause unestablished. I am preparing a narrow explicit prerequisite guard for the dependent corrected-marker steps across the three backend job definitions. Independent cohorts/cleanup remain separate. Already-admitted original jobs stay intact; no new head, retry, budget or frozen tuple is submitted while their execution continues.

@rmcdaniel

Copy link
Copy Markdown
Member Author

The prerequisite guard is now prepared locally: each backend comparison step has an explicit ID, and the corrected-marker step requires that prerequisite outcome=success. This applies to the prepared native-b targets on MySQL/PostgreSQL and recovered target on SQLite; independent isolated cohorts and all cleanup guards are unchanged. Central action-policy validation and diff checks pass. It is not pushed yet, so run 38671922377 and all already-admitted originals remain the same source. The original PHP 503 and derived absent-target failure remain failed; this guard is not a runtime correction or a rescue of those observations.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Run 38671922377 is terminal and unsuccessful at unchanged head 4459140cd. All five network database cells pass their 46 recorded observations; I read every terminal job log independently. MariaDB10.11, MySQL8.0/8.4 and PostgreSQL16/17 all execute the read-only inventory, preserve takeover_allowed=false, php_quiescence_verified=false and stored_representation_compatibility_verified=false, and pass their separate installed external consumers.

SQLite remains failed at frozen PHP restart preparation's 503/backend_lock_pressure. Upgrade inspection was not reached. As corrected above, later cURL52 reflects the never-created recovered target after that prerequisite failure, not a proven native crash. The independent SQLite external-consumer cohort passes; neither that nor the five network cells rescues the failed whole run. No cause is established for the frozen PHP503.

The prepared workflow correction guards the dependent marker comparison on successful restart preparation while preserving independent cohorts and always-run cleanup. No changed-head rerun has started. I will integrate the coordinated qualified PHP tree once it is handed off, then qualify the resulting exact source. No backup, migration, takeover or native release is authorized by this inventory result.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Actual stored-representation audit on the isolated immutable published PHP Server 2.8.0 image: the unchanged raw public-protocol author prepares its original activity and timer runs in 1.40s under the original 30s preparation deadline, then the sole fixture API writer stops with SIGTERM/exit 0/no OOM. This is not an SDK continuation or a completed workflow workload.

The strict read-only SQLite reader observes two waiting runs, four canonical tasks (two completed workflow tasks, one stored leased activity, one ready timer), one activity execution and seven history events. Official installed Avro decoding preserves 9007199254740993, null and Unicode in both run and activity arguments. Original SQL timestamps retain six fractional digits, the activity policy keeps the full recorded eight-field snapshot, and no deadline/attempt is rebased.

The database queue contains an actual serialized Workflow\\V2\\Jobs\\RunTimerTask with a Carbon object and Illuminate\\Queue\\CallQueuedHandler@call. A non-evaluating fixture observation matches its public task-ID property to the original canonical timer task; this is not a general serialized-object validator or a conversion routine. Six mounted file-cache entries contain expiry-prefixed opaque serialized strings. Query/poll/receipt meaning, Redis, legacy closures/classes, completed results and external bytes are not qualified by this sample. No PHP queue/cache object is deserialized or executed.

The final strict reader passes without warnings and preserves the exact database SHA-256 before/after. Initial reader probes used the wrong attempt column; corrected reader uses attempt_count and treats warnings as failures. That was a reader-only error, not a Server defect. The sample confirms compatibility boundaries to validate before mutation; backup, representation compatibility, quiescence certification and takeover remain false. Reusable fixture recipe source is being retained; raw database/journals/logs and task resources are removed immediately after audit. No native/SDK/shared/frozen source or ownership change follows.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Next source-only migration gate: inspect known V2 workflow/activity/timer queue commands with the released phpserz token parser, disabling its optional Serde feature. Bound bytes, nesting and token counts; retain byte-string properties and refuse duplicate keys, references, custom serialization, trailing values and unknown classes. Known class/task metadata remains an observation until separately joined to canonical SQL task/run state. No PHP object execution, command replay, mutation, backup approval or takeover authority is introduced. Actual published-image serialized job fixtures and malformed controls will qualify the decoder independently before any migration path uses it.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Prepared source ed686fc (tree 2865f097a3d4cfe0c49706bae9f80956ecba99ac) is pushed on rust-325-upgrade-source-preparation for review. Seven focused decoder controls pass using the normal phpserz 0.3.0 crate and the project-selected serde_json version. They cover the three real published-class fixtures, every truncated prefix, malformed/overflowing lengths and integers, binary strings, duplicate/hidden properties, references/custom/unknown objects and byte/depth/token limits. Regenerating fixtures in the immutable PHP image is byte-identical. Rustfmt and diff checks pass. The lock adds only phpserz and fast-float2; existing package identities remain unchanged. The 65 MiB task compiler/cache/harness/raw inputs are removed. This is an independently tested source module plus the earlier read-only fixture hook, not a full native build, row binding, migration, backup or takeover pass. The PR head and its old hosted failure records are unchanged pending the qualified parent/source integration.

@rmcdaniel

Copy link
Copy Markdown
Member Author

The separate migration preparation now binds a known PHP queue envelope to its original canonical task/run in source 624700c9a (branch rust-325-upgrade-source-preparation). Twelve focused decoder/binding controls pass using the real source modules and selected parser/Serde versions. Full native build and CLI integration remain pending.

A genuine published PHP 2.8.2 source (7e215d29, image index 91a5bb87dbf280c1966693af3eb1d13eac6912d88fd82ae2095f05830a38dab0) prepared two original waiting workflows through the public protocol, one leased activity and one pending timer, within the original 30-second author budget. The sole source API then exited 0 without OOM. A read-only export preserved database SHA-256 d0e6b4697bc58e7d3770a8d8beb39b01111d25614855002de18795ef41411cdc before/after. This is a raw-protocol author, not an SDK-continuation claim.

The actual timer uses canonical SDK queue upgrade-source, while its Laravel transport job uses queue default. Its canonical availability is 08:16:21.566122 UTC; the Carbon and integer transport wakeup is 08:16:22 UTC. These routing/timing domains remain separate. The binding checks the exact handler/class, supported transport policy, task ID/kind/run/namespace and configured transport connection/queue. It returns borrowed original rows without replacing attempts, status, lease or deadlines. The separate activity retains its original attempt 1 and 08:11:21.169593 UTC lease; elapsed historical time is not rebased.

Controls refuse changed identity/kind/run/namespace/SDK queue, wrong outer handler/policy/transport scope, duplicate or unknown envelope fields, oversized bodies and absent canonical identity. The small genuine source fixture and reproducible read-only exporter are committed. An initial image setup used a configuration digest as a manifest and failed before any application or original was admitted; the separate correct-index setup is the producer above.

This proves the recorded source/decoder/binding component only. It does not scan every source row, validate every timestamp or PHP/embedded representation, restore a backup, prove writer quiescence or execute the originals in Rust. upgrade-inspect remains the earlier read-only catalog/count command with takeover/backup/representation flags false. The old frozen PHP bootstrap 503 and dependent absence remain failed. The next migration work is complete stored-state validation and integration, then backup verification and actual sequential takeover. Completed raw/build resources are being removed immediately after this audit.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Read-only queue inspection is now implemented in preparation source 5d54f25ed62ed155b67406fe9e12cbeb1d752fef, native tree cdaec3a2274f586a7ba63187205b815bac4bb753, binary SHA-256 617ac5b30d7517337cfa4b68cf68bf78e1b75217d7751c938989f4c762528a31. Source plus the result documentation is pushed as aa3876480 on rust-325-upgrade-source-preparation. This remains separate from the old PR head and its failed originals.

upgrade-queue-inspect requires the original transport connection/defaults explicitly, scans every database-queue row in the existing read-only snapshot, caps payload transfer at 128 KiB per job and uses 32-row primary-key pages. It validates the known envelope and joins the original task/run without claiming, deleting or executing work. Unknown data refuses without a partial success report. Ordinary inventory remains available separately.

Local checks pass 93 library cases (18 existing explicit database/subprocess ignores), including 23 focused decoder/binding/inventory cases, and the process refusal test for both commands. Multi-page unknown jobs, orphan/foreign bindings, nonpositive IDs and oversized bodies refuse without changing database bytes or leaving a reader.

The committed published-source recipe then passes on SQLite DELETE, MySQL 8.4.5 and PostgreSQL 17 against published PHP 2.8.0 image index cba7c4c6732529293ef6c2625a64785dcb21b4f7fe0013fdc74f1af466f534ac. Each database has two genuine pending originals, one leased activity and one ready timer, 50 tables and one bound timer queue job. Nine refusal controls across the three databases cover access, catalog, ownership and PostgreSQL row security. Each sole source API exits 0 without OOM before native inspection; snapshots remain exact before/after. SQLite database SHA-256 is 7b0a543e4d8d20214a32740275184b6cf318636521ef1ef5b332daf8f4ca718b.

Two PostgreSQL setup attempts failed at a custom Unix-socket configuration before any application or workflow admission. The fresh default-socket setup supplies the passing PostgreSQL originals. Neither failed setup is counted as a workload or product finding.

These are raw-protocol source authors and read-only queue checks, not SDK continuation or Rust execution of the originals. Full hosted version-matrix integration, complete stored-state validation, verified backup/restore, writer quiescence and actual sequential takeover remain pending; their flags stay false. All completed databases/raw state are removed immediately after audit, with the remaining task build scratch being retired now. No bulk retention is claimed.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Source preparation b6df9cd / whole9dc089f5721193e245089ca6952cc108fcdc09c3 / native3f4f20c3ea5b3acf92317c80aef4ff889e11e6ad joins the current API preparation3211c65b with read-only inspection preparation b34e74a. All API query SQL, namespace timer routing, activity metadata/result modules and corrected activity producers match3211 byte-for-byte. PHP application/Composer/OpenAPI files remain unchanged. The only merge conflict was the running log; current foundation/qualification limits are preserved alongside the inspector record. The existing frozen PHP2.8.0 inventory profile remains unchanged, including its failed originals and all false takeover/backup/quiescence/representation flags.

A fresh local compiler-only phase will check this integration with library tests, actual CLI filesystem-refusal processes and the SQLite execution suite. This source has not compiled or qualified yet. No old hosted head is updated or cancelled; no schema mutation, migration, PHP takeover or release is authorized by the merge.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Combined preparation b6df9cd / whole 9dc089f5721193e245089ca6952cc108fcdc09c3 / native 3f4f20c3ea5b3acf92317c80aef4ff889e11e6ad now passes 109 library tests (18 existing explicit database/subprocess ignores), the actual CLI filesystem-refusal test and all 133 SQLite execution tests. Both upgrade shell scripts pass separate bash syntax checks; diff checks pass. One existing unused-import warning in worker_incarnations remains. Debug binary SHA-256: bb30b67792e1ee88d5130b45542fd0acebba23af08d8df0ea357e7f7a7491999.

Documentation-only successor aa495eb / whole ed7533e0383ddfb5ee4cd3dfb87fb978a83ec64d retains the same native tree and updates the current work order. Query SQL, namespace timer routing, activity metadata/result code and corrected producers remain byte-identical to API preparation3211c65b. PHP application, Composer and OpenAPI are unchanged.

This is local source integration, not a new published-source inspection or migration. Earlier PHP2.8.0 source/SELECT-only network observations and PHP2.8.5 TCP consumers stay tied to their original components. All takeover, backup, writer-quiescence and complete-representation gates remain open. Existing hosted query/metadata originals are unchanged; combined hosted and fresh-main acceptance remain pending. Compiler/cache/raw cleanup follows immediately.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Compiler-only cleanup completed at 12:34:50 UTC, before the 13:00 bound. The compiler and shell-check containers are absent; all Cargo/target/temp files and raw output are deleted, and the scratch directory is absent. Two superseded clean preparation worktrees were then removed only after verifying no tracked, untracked or ignored changes and that both parent commits are ancestors of pushed aa495eb. Their commits and branch references remain available; the consolidated source worktree is clean. Admitted PR heads and other owners were untouched. No application/database server, paid resource or migration was started in this phase.

@rmcdaniel

Copy link
Copy Markdown
Member Author

A separate current published PHP 2.8.5 PostgreSQL 17 observation now passes on combined preparation 6720274cd, native tree 3f4f20c3. It reuses the completed six-original PHP consumer database only after its API exits. The three existing CLI commands run with a SELECT-only role and no provider/state mount: upgrade-inspect, upgrade-queue-inspect and upgrade-payload-inspect.

All three recognize the exact published layout, catalog SHA-256 0249d1d3f6ad3d2edb5fbb4f98041042309ce0a78ff57a2670d1a393d35a7065. The payload scan recognizes two genuine persisted external-result references from executed normal SDK workflows, without resolving them. Twenty-two inline root values remain explicitly unvalidated. The queue is empty, so this supplies no new queue-binding or pending-resumption proof.

Data-only PostgreSQL dumps are streamed directly to SHA-256 before/after, with the same explicit psql restrict key and no content filters or retained dump. Both hashes equal 87d42b6508e53343f71431521b3734beaf427f732441a9d33ee8ad492d61dba7. No inspection-role connection remains afterward. This is logical data preservation, not physical database-byte identity or a restored backup.

All backup, quiescence, complete representation and takeover flags remain false. Catalog recognition does not infer a package version; the immutable input image binds the actual version separately. No schema/ledger/marker conversion, provider-byte/registry qualification, cache transfer or upgrade mutation occurs. All local runtime/data/compiler/raw resources are retired; frozen source cohorts and failed originals remain unchanged.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Next scoped read-only increment, before implementation: validate inline Avro in the same four enumerated root columns through the existing official Apache Avro traversal. Require the recorded row codec, retain original encoded bytes and distinguish absent values, validated inline frames and explicit unqualified values. Keep the current SQL transfer bounds (32 rows/page, 64KiB/value) and whole30s inspection budget; oversized inline values, unknown/missing codecs and malformed frames remain unqualified. No PHP object deserialization, payload logging, value rewriting or rejection of legitimate binary data based on PHP-looking contents. External-reference metadata continues through its separate existing validator. Nested task/history values, registry/provider binding, independent restore, PHP quiescence and takeover remain unverified/false. This remains preparation under325, without PHP/schema/SDK/dependency/frozen changes.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Bounded inline-payload inspection source checkpoint: preparation ceab667, whole tree fc28afbf0afc74054e855a1275c1e4fb6585759f, native tree 029ab98191647ec6a52db420095049f89fc4400a. The tested implementation is c12fe08; ceab adds only documentation and exact current source dispositions.

The standalone upgrade-payload-inspect command now validates the recorded Avro codec and complete frames in the four enumerated run/activity argument/result columns. Apache owns schema traversal. The command sets and verifies its process-wide 64 KiB scalar allocation limit before creating a decoder; the visitor retains no arrays/maps and refuses more than 64 traversal levels or 16,384 visits. SQL masks values over 64 KiB before client transfer, with 32 rows per page and the existing 30-second inspection budget. Unknown/missing codecs and malformed/trailing/oversized frames remain explicit unqualified reports with nonzero exit. HTTP runtime allocation policy is unchanged.

Local exact-code checks PASS: 112 library tests (18 existing ignores), both actual CLI tests (zero ignores), and all 133 SQLite execution tests (zero ignores). CLI controls preserve exact source bytes for valid frames and a malformed frame declaring a 500 MiB scalar, and observe the actual 65,536-byte allocation cap. Typed bigint/null/Unicode/bytes plus deep/wide/truncated controls are included. The first deep-fixture producer overflow is a failed test-development observation; the corrected encoder runs on a separate larger producer stack, while validation stays on the ordinary test stack. The first CLI test incorrectly expected success on an existing unqualified refusal; corrected expectations preserve that nonzero product behavior. Early Apache writer import/constructor build failures are corrected to its documented API.

This is constructed-source qualification, not actual current-PHP inline data or hosted acceptance. The earlier 672 source observation still has 22 inline values explicitly unvalidated at that earlier source. Nested history, provider bytes, registry binding, complete representation, backup, writer quiescence and takeover remain unqualified/false. No source data is rewritten. The optimized runtime/HTTP deep-value boundary is not qualified by the fixture producer control. Documentation now records these bounds and the independently delivered #463 fresh-main result.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Actual published-source follow-through PASS at 03b3bd3cd75c57a5a4135b2568e5c20ab492473e, whole tree 39ca0c7e50e8c26d58d1d62d511b60e7368c3e7d, native tree 029ab98191647ec6a52db420095049f89fc4400a. Binary SHA-256: 4472655a329a06f80d2502c4a5b2307ad1926e92dfc254a2f1fff6db2165f908.

The normal immutable PHP 2.8.5 image is f6a6507a5a424dfad03e636ec690b0f1e813d385be9940691c59116446dfd1cc, revision f7d1bfc7. Loaded Core 2.5.22 Avro/ExternalPayloads/ExternalPayloadReference bytes independently match published 908e2db9; its intentional Composer path reference remains distinct. The source recipe retains its pinned PHP 2.8.0 default; this is an explicitly selected current-image cohort.

SQLite DELETE, MySQL 8.4.5 and PostgreSQL 17 pass: six actual pending raw-protocol originals, nine inline argument frames and three queued timers bound to their canonical tasks. All three inspector commands pass under the actual 65,536-byte scalar ceiling. Source fingerprints match before/after: SQLite bytes and network logical rows/sequences. Denied readers, unknown catalogs, ownership markers and PostgreSQL row security refuse where applicable. Every API/database exits 0 without OOM.

Arguments contain int64/null/Unicode; workflow outputs and activity results are absent. This qualifies the structural root-column boundary. Completed results, nested history, provider contents, full representation and SDK continuation remain open. The earlier 22 inline values remain their earlier unvalidated observation. Backup, quiescence, representation and takeover flags stay false; no physical network-file, backup or performance claim follows.

All phase databases, build/cache files, raw output and the newly pulled image are removed after audit. Next preparation isolates the inspector for independent hosted qualification, preserving the separate API endpoint branches and their failed originals.

@rmcdaniel rmcdaniel changed the title Inspect existing PHP databases before native upgrade Inspect stored PHP state before native upgrade Oct 15, 2026
@rmcdaniel

Copy link
Copy Markdown
Member Author

Promotion of inspector candidate 58542a5e is held for a separately reproduced read-only boundary gap. The admitted 38754495860 originals remain unchanged and qualify only that exact source.

Using its exact optimized binary 6b019c27cc6adb0dff16bf21434ef17b01c037a03001bfa1ccf4ae22fbab79c6 / native tree 180e0104, a private constructed-file control pauses the later SQLite open after the regular-file/header/sidecar checks. Replacing the checked DELETE-journal file with a stopped WAL-header database then lets SQLite create -wal and -shm files before the unknown catalog is refused. The substituted main-file hash remains exact. This is a deterministic path-replacement control, not a claim about the published PHP source cohort, a live writer, migration or customer state.

The existing static FIFO/directory and WAL controls do not cover this check-to-open gap. No takeover or source-mutation authority is granted. Next: correct and test the actual file-opening boundary, retain the failed control, and qualify a new source revision before merge. The current main-image/frozen references remain unchanged.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Prepared correction 7066a50ef10cd25958fc6ad5bfd305a7d901e969 / whole tree 4c3394c728f7f60be3e0b0d59da89a4b5f76f6b3 / native tree 302571a379fe5bbf05dcc41f20b47a3770e3b670 is pushed for a new qualification.

All three SQLite inspection commands now require the documented kernel read-only source mount before opening SQLite. The check uses live descriptors and includes the resolved parent directory, since a file-only read-only bind mount can still leave a writable sidecar location. SQLite locking and change detection remain enabled. The outer 30-second budget covers the mount check and inventory. The report still cannot certify another process's writer quiescence, a backup or takeover.

The first mounted valid/malformed payload and special-source process controls passed (2 tests), before the later expanded three-command writable-source assertions. A later library component passes 109 tests with 18 existing explicit ignores. Its broader local batch was terminated during the CLI stage at the overdue cleanup checkpoint, so there is no completed final-head CLI/execution acceptance. The expanded test and exact hosted whole tree remain pending. The previous 58542a5e all-13/all-six result stays its own, with the constructed writable-path side effects recorded at 6196263885.

CI maps one private fixture directory through writable and read-only aliases, so normal hosted execution checks both writable refusal and actual valid/malformed Avro decoding. PHP source, Composer, OpenAPI, frozen actors and takeover flags are unchanged. No merge, image, migration or release is qualified.

@rmcdaniel

Copy link
Copy Markdown
Member Author

The exact optimized artifact for correction 7066a50ef now passes three constructed filesystem controls. Source is CI merge 5fb06d74132f280d4c77995387e769d722e59d75, whole tree 4c3394c728f7f60be3e0b0d59da89a4b5f76f6b3, native tree 302571a379fe5bbf05dcc41f20b47a3770e3b670, binary SHA-256 db69ec5708dd7e1b1be02958afbccfd5daed971af120c0b3aaac61e468b116a2. Artifact 11990534206 has SHA-256 c07fef3357d399e858cc0e083261bbbf86752260d30e3134bde0385ee45de19c; archive/build/binary identities were independently checked.

  • A writable source mount refuses upgrade_source_readonly_filesystem_required before SQLite opens.
  • A read-only file bind with a writable parent refuses the same reason before SQLite opens. The control independently verifies the two different kernel mount flags.
  • After the header checks on a read-only directory, a test-only open barrier replaces the original DELETE file through its separate writable alias with a stopped WAL file. Inspection refuses upgrade_inspection_unavailable, creates no WAL/shared-memory sidecars and preserves the substituted file's exact SHA-256. This covers the required mount boundary without asserting that another process has stopped writing.

Each basic upgrade-inspect process exits 1 as expected, and the controller exits 0. These are private constructed-file controls, not a published PHP inventory, queue/payload command acceptance, backup or takeover. The original writable-path failure and terminated local Cargo batch remain unchanged.

All binary, C test shim, source files and SQLite state were removed and the isolated phase was verified empty at 16:45:04 UTC, before its 17:00 bound. Fresh hosted 38769642932 remains in progress; promotion still requires its exact final acceptance.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Additional inspector review is incomplete. This draft remains unpromoted even if its current hosted matrix passes. Existing completed controls retain their stated scope; the unfinished review supplies no confirming or clearing evidence. Next work is the separate Server API and Waterline consumer qualification under #325. No migration, backup or takeover authority is claimed.

@sonarqubecloud

sonarqubecloud Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Quality Gate Passed Quality Gate passed

Issues
68 New issues
2 Accepted issues

Measures
0 Security Hotspots
No data about Coverage
0.0% Duplication on New Code

See analysis details on SonarQube Cloud

This branch has not been deployed

No deployments
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.

2 participants