Repository navigation
Rust #325: accept completions and parallel groups over 100 - #851
Conversation
|
At exact The scalar transport rules allow positive signed 64-bit integers with no upper bound below {
"parallel_group_id": "select-calls:1:2",
"parallel_group_kind": "activity",
"parallel_group_mode": "select",
"parallel_group_base_sequence": 1,
"parallel_group_size": 2,
"parallel_group_index": 0,
"selection_member_key": "a",
"selection_member_index": 0,
"selection_member_base_sequence": 1,
"selection_member_size": 9223372036854775807,
"selection_member_kind": "activity"
}The new code reaches I executed exact published Core {"commands.0.parallel_group_path":["Parallel workflow commands require complete top-level metadata and a non-empty group path."]}Please add an extreme-integer regression/differential case alongside the 1,001-size case. Verification here is an executed published-Core preflight control plus exact Rust source inspection; no native or installed Server HTTP execution is claimed. A related integer-range correction is needed for Re-review of Please retain the offered published/native HTTP refusal recordings for the three extreme cases, including their path errors and absence of created work. Preserve Update for exact ecaf587, including e95cd2f: the requested HTTP regression coverage is now present. I statically checked all three raw command strings, their matching top/path fields, literal integer key 9223372036854775808 in both locations, and expected 422 path errors with zero created tasks and unchanged start-only history. The probe sends the JSON text unchanged with application/json. This resolves the request-shape concern without executing PHP or Rust in this re-review. The published/native seven-case recording remains author-attributed in the linked qualification receipt. The timeout change applies only to this fixture's overall runner budget (150 seconds plus the existing five-second wrapper margin). Hosted corpus failures at acd020b remain failed historical evidence; the author's locally reproduced 45-second timeout is a plausible cause, not confirmed identification of the failed hosted fixture. Normal exact-head CI is still required. A separate runner diagnostic gap explains how fixture identity can disappear from retained summaries: the runner-blocked catch writes a raw record but no bounded failure outline, while artifact-summary intentionally excludes raw records. The existing failureExcerpt helper can preserve the current fixture/outcome/error heading for that path. This is a confirmed source-level evidence gap, not proof of the old corpus failure's cause. Re-review of exact 2184ca9 after rebasing onto merged main: Git range-diff preserves the reviewed behavioral patches; integration differences retain the new query-contract fixture/CI entries and port-log additions. The fixture-count and timeout-cause wording are corrected. The new blocked-probe commit writes the existing bounded failure outline before throwing, registers a regression that runs the actual recorder with a failing PHP stand-in, and gives the database test steps accurate names. This addresses the retained-evidence finding by source review. The author's Node result and old-code failure remain attributed; I did not rerun the tests. No targeted source or fixture finding remains from this review. Prior corpus failures stay failed evidence at their original heads. Source review and the new diagnostic regression do not prove their cause or replace normal exact-head hosted and cumulative qualification. Final selector-only re-review at fd2a4b5: compared with 2184ca9, only ServerParityPartsTest.mjs changes. Its common-step matcher and three database-step lookups now use the renamed Bootstrap published prefix. This fixes the test selector mismatch introduced by the accurate step names; no production or probe behavior changes in this amendment. The author reports 78/78 aggregate/parts tests passing; I inspected the exact diff without rerunning them. Normal hosted checks on this head and protected cumulative qualification remain required. Hosted qualification at exact fd2a4b5 is now terminal: independently read 56 successful checks and one expected skip, with no open or failed check. On October 29 at 05:35 UTC the pull request was in protected merge-queue position 1, awaiting cumulative checks. This clears the head-level CI gate; merge and cumulative qualification are still pending. No published-artifact or installed acceptance is implied. Subsequent protected cumulative qualification at fd06b41 did not pass. Shared run 40824302270 ended with 40 successful jobs and three failures: SQLite corpus job 123284839194 failed the actual execute-and-compare step; MariaDB restart job 123284839698 failed the shared-node startup step; job 123290355973 is the aggregate failure. The primary annotations only report exit 1. Cumulative PHPUnit Feature 40824302255 and Public Boundary 40824302337 succeeded. At the post-failure read the PR remained open on fd2a4b5 and its queue entry was absent. The head-level pass above does not clear this failed cumulative gate. Exact fixture/startup causes remain under investigation; no rerun, budget increase, merge or installed acceptance is claimed. The second cumulative attempt at 24f3607 also has a failed required SQLite corpus check: job 123292898252 failed the actual execute-and-compare step. Its annotation reports only exit 1; at the 06:32 read the run still had ten other jobs in progress. That overall in-progress state does not establish merge readiness. Exact-head CI repair #852 at 1dae4ff has separately reached 56 successful checks / one skip, but its protected cumulative qualification is still required. No new fixture cause is inferred here. Re-review at exact 0cbdefb clears the fixture-cleanup change. The only delta from fd2a4b5 is ten lines after every case has captured its completion response, described state and paginated history counts. Cleanup uses the same fresh namespace/client and the same unique case workflow IDs, rejects responses outside 200/202, and then returns the already captured observations. The request bodies, raw integer tokens, comparison expectations and recorded pre-cleanup state are unchanged. This addresses the actual leftover-task load behind the scheduler failure; extending the separate observer timeout alone was not that cleanup. The published/native large-batches-to-schedule recording remains author-attributed. I inspected source without executing either target. No targeted source finding remains; normal checks on 0cbdefb and protected cumulative qualification are still required. Normal qualification at cleanup head 0cbdefb is terminal: 56 successful checks and one expected skip. The primary read at 07:24 UTC shows the PR in protected queue position 1, awaiting cumulative checks. The earlier fd2a cumulative failures are preserved above; they are not failures of this new cleanup head. No targeted source finding remains from this review, and protected cumulative qualification is still required. Protected qualification and merge are now verified at final cumulative 7825a8c: Shared Server fixtures 40834910755 succeeded at 07:43:00 UTC, PHPUnit Feature 40834910751 at 07:37:26 and Public Boundary 40834910741 at 07:22:11. PR #851 merged at 07:43:24 UTC as that same commit. This completes this source slice; it does not claim a published native image, full select execution, installed Server acceptance or cutover. |
From #851 review. The parallel preflight's selection member checks added base + size and member base + member size without overflow checks, so a member size of i64::MAX overflowed. It also accepted a numeric member key above i64::MAX, which PHP decodes as a float and refuses. Published PHP refuses both with the group path message; use checked sums and the signed 64-bit range. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Pushed
|
The group test counted members with payload LIKE, which PostgreSQL refuses on its json payload column (operator does not exist: json ~~ unknown), failing both PostgreSQL native-test lanes on #851. Read the run's history through the API instead, the same on every database. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From #851 review. The large-command-batches fixture gains three raw-HTTP cases that published 2.11.5 refuses in its parallel preflight with the group path message and no created work: a selection member size of i64::MAX, a group base of i64::MAX, and a numeric member key of 2^63. Each case's commands are sent as written JSON text, so the 2^63 key reaches the server as a literal integer rather than a PHP float. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Pushed
|
The probe now runs seven cases, five of them with 150 commands each. Against published PHP it took 18 seconds on an idle host, but timed out at the runner's 45-second default on a loaded one (spawnSync php ETIMEDOUT), which matches #851's corpus failures. Give it a 150-second budget, as other long probes declare. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Published PHP 2.11.5 accepts a workflow task completion with any non-empty number of commands; each command meets the run's structural limits instead (2,000 pending activities and timers by default). Native refused more than 100 with invalid_commands, and its timer, activity and external-wait summaries gave up past 100 open waits, so such a run was described without its wait. Remove both command caps and the three summary bounds. PHP bounds a parallel group's declared size by the command batch size (1,000 by default), checked in WorkflowCommandNormalizer's preflightParallelMetadata. WorkerController runs it after the transport rules and before any guard, and it collects one of three validation_failed messages per command across the batch. Native capped groups at 100 and answered any invalid metadata with development_parallel_group_unqualified. Port the preflight into completion_rules and share one COMMAND_BATCH_SIZE constant. The large-command-batches fixture records 150 timers, 150 activities, a 150-member group and a refused 1,001-member group; published PHP and native both pass it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
updates_have_no_lifetime_cap_and_preserve_accepted_work_after_wait_timeout runs 64 update round trips without a worker heartbeat. On a loaded host the loop outlasts the worker's staleness window, and the server then correctly refuses the stale lease owner's completion (409 stale_worker_registration) or hands out a different task. Eight concurrent runs all failed before; with a heartbeat per iteration all eight pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From #851 review. The parallel preflight's selection member checks added base + size and member base + member size without overflow checks, so a member size of i64::MAX overflowed. It also accepted a numeric member key above i64::MAX, which PHP decodes as a float and refuses. Published PHP refuses both with the group path message; use checked sums and the signed 64-bit range. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The group test counted members with payload LIKE, which PostgreSQL refuses on its json payload column (operator does not exist: json ~~ unknown), failing both PostgreSQL native-test lanes on #851. Read the run's history through the API instead, the same on every database. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From #851 review. The large-command-batches fixture gains three raw-HTTP cases that published 2.11.5 refuses in its parallel preflight with the group path message and no created work: a selection member size of i64::MAX, a group base of i64::MAX, and a numeric member key of 2^63. Each case's commands are sent as written JSON text, so the 2^63 key reaches the server as a literal integer rather than a PHP float. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ecaf587 to
a5cf0ee
Compare
The probe now runs seven cases, five of them with 150 commands each. Against published PHP it took 18 seconds on an idle host, but timed out at the runner's 45-second default on a loaded one (spawnSync php ETIMEDOUT), which matches #851's corpus failures. Give it a 150-second budget, as other long probes declare. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Rebased onto main after #850 merged; the head is now |
The probe now runs seven cases, three of them with 150 commands each. Against published PHP it took 18 seconds on an idle host, but timed out at the runner's 45-second default on a loaded one (spawnSync php ETIMEDOUT), the likely cause of #851's corpus failures. Give it a 150-second budget, as other long probes declare. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
a5cf0ee to
2184ca9
Compare
From #851 review. When a probe fails before it observes anything, the runner writes a runner-blocked record and stops, but only the product-fail path wrote the failure excerpt that the CI artifact summary keeps. A timed-out probe therefore left no fixture name in the retained artifacts, as in #851's corpus failures. Write the bounded excerpt for a blocked record too; the new runner test drives the recorder with a failing fake php and checks the excerpt names the fixture. Also rename the MySQL and PostgreSQL bootstrap steps to say they run the native tests, since a failed native test was reported under "Bootstrap". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From #851 review. When a probe fails before it observes anything, the runner writes a runner-blocked record and stops, but only the product-fail path wrote the failure excerpt that the CI artifact summary keeps. A timed-out probe therefore left no fixture name in the retained artifacts, as in #851's corpus failures. Write the bounded excerpt for a blocked record too; the new runner test drives the recorder with a failing fake php and checks the excerpt names the fixture. Also rename the MySQL and PostgreSQL bootstrap steps to say they run the native tests, since a failed native test was reported under "Bootstrap". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2184ca9 to
fd2a4b5
Compare
#851's merge-queue corpus failed twice on schedule-fixed-rate-one- occurrence: published PHP's installed scheduler did not fire within the probe's ten seconds. The large-command-batches fixture, which the corpus runs before it, left several hundred open timers and never-polled activity tasks behind. PHP's maintenance loop then repaired 25 of them per pass; one pass took 19.4 seconds locally and held up the scheduler evaluation that follows it. The probe now terminates each of its runs after recording them. Locally the passes after the fixture return to zero repair candidates and about 1.7 seconds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Pushed The cause is in this PR. The The probe now terminates each of its runs after recording them. Recorded locally on the new head:
#852, now in the merge queue, separately retries the Composer floor build and widens the scheduler wait to 25 seconds. I'll re-enqueue this after #852 merges. |
|



Part of #325.
What changed
Native now accepts a workflow task completion with more than 100 commands, and a parallel group with more than 100 members, as published PHP 2.11.5 does.
Completions
422 invalid_commandspast 100 commands. The check was in two places: the completion itself (store.rs) and external payload preparation (external_resolution.rs).commandsmust be a non-empty array, with no count limit.StructuralLimits::guardCommandBatchSizeapplies only to the embedded executor. Each command meets the run's structural limits instead (2,000 pending activities and timers by default), and the run is described as waiting on its first open wait.Parallel groups
Before: native capped a group's declared size at 100 (
all_groups.rs). It answered any invalid group metadata with422 development_parallel_group_unqualified.Contract (published PHP):
WorkerControllerrunsWorkflowCommandNormalizer::preflightParallelMetadataafter the transport rules and integer normalization, before its own scope checks and any ownership guard. The preflight:422 validation_failed, collected across the batch.A group's declared size is bounded by
StructuralLimits::commandBatchSizeLimit, 1,000 by default.Native:
completion_rules.rsports the preflight at the same point. The batch-size limit is now one shared constant (memo_limits::COMMAND_BATCH_SIZE), used by the group, cooperative-cancellation and cancellation-scope checks; native already refuses to start with another value. A valid group that native does not run, such as a child group, is still refused later asdevelopment_parallel_group_unqualified.Evidence
Fixture
large-command-batches: raw worker HTTP on protocol 1.20, four cases. Each records the completion answer, the description (wait_kind, reason) and paged history counts by event type and group:start_timercommands;schedule_activitycommands;parallel_group_path;Recorded locally against published 2.11.5 and against a native image built from this branch: both pass.
Tests:
rust/tests/execution/large_command_batches.rs(both tests) fail on the previous source and pass now.Full native suites, run locally: execution 623 passed, 1 ignored; lib 347 passed, 42 ignored.
Contract unit tests: 9 pass.
Also: a load-sensitive test
updates_have_no_lifetime_cap_and_preserve_accepted_work_after_wait_timeoutran 64 update round trips without a worker heartbeat. On a loaded host the loop can outlast the worker's staleness window, and the server then correctly refuses the stale lease owner's completion (409 stale_worker_registration). The test now heartbeats each iteration. Eight concurrent local runs: 8 of 8 failed before, 8 of 8 pass after.The port log's structural-limits entry also drops a stale claim: the 64-update lifetime cap was removed on October 23.
Not covered
409 stale_worker_registrationfor it on SQLite, so there is no usable reference.🤖 Generated with Claude Code