Skip to content

Prepare Workflow 2.29.0 and fixed installed-upgrade runtimes - #1130

Draft
rmcdaniel wants to merge 5 commits into
mainfrom
release/2.29.0-timeout-cleanup
Draft

rmcdaniel wants to merge 5 commits into
mainfrom
release/2.29.0-timeout-cleanup

Conversation

@rmcdaniel

@rmcdaniel rmcdaniel commented Nov 13, 2026 •

Copy link
Copy Markdown
Member

Prepare Workflow 2.29.0 for the opt-in embedded timeout-cleanup behavior merged in #1129 / #863. The committed product train is exactly 2.29.0; the notes require migration and retain experimental embedded queue scope. Runtime src is unchanged from approved b930facd.

The existing published-package verifier now runs nine actual installed queue scenarios: completed/failed/rethrown cleanup, expiry, no worker, first detection after the hard cap, hard cancellation, SIGKILL/cold replacement while cleanup waits on a timer, and an active-worker legacy no-opt-in control. It requires the exact registry ZIP/source references, product train and complete runtime-tree equality with the immutable tag before bootstrap. A source prototype passed all nine cases; a failed assertion exits1 and the published verifier rejects its explicitly non-published receipt. This remains source evidence until the registry release is tested.

The initial published-package/probe caller keeps the exact qualified helper411a14ac Ubuntu24/PHP8.3/no-overrides/coverage-none profile and original Composer/PHPUnit inputs. Its original qualification43277662273 includes the required SQLite/pcntl/POSIX surfaces.

Final release-path review found an existing shared#297 supply gap in the subsequent Laravel upgrade job. General confirmed the tag hold. Current source 035a086a unconditionally migrates that job to fixed PHP containers on Ubuntu24 while preserving all five committed cells: PHP8.2/Laravel12, PHP8.3/Laravel12+13 and PHP8.4/Laravel12+13. The product-derived matrix, original upgrade/downgrade commands and optional two-worker outcomes remain. Source/tracing profiles are outside this migration.

Seven neutral Docker/INI/CA/Brotli inputs match reviewed SDK sourcee6494b86 byte for byte. Workflow reuses the existing8.2/8.4 local image IDs and owns the added official8.3.36 Bookworm input plus its actual caller proof. The launcher uses an inspected immutable config ID, caller UID, bounded resources, private state, selected read-only trust inputs and an owned SQLite directory that preserves the original host shared-memory database/sidecars. Accepted Composer trust verification runs before each networked upgrade operation.

Validation:

  • Deadline-triggered timeout cleanup, embedded (#863) #1129 completed the full local ECS/Stan/unit/coverage/feature cycle, required CI and exact-head Security. Runtime source remains identical.
  • New PHP8.3 config1c991a1b passes actual module/function, production INI/defaults, no-coverage and Composer TLS controls. The generic Trixie digest was rejected during parent inspection; the committed Bookworm index23233111 reports fixed APT2.6.2 before networked APT.
  • Seven launcher controls, all23 existing routing tests, four APT policy tests, shell/diff/public-boundary and added-line credential/private-path checks pass.
  • The preceding release-only headade3 completed25 successful checks and6 intended skips plus source Security PASS. The new runtime delta requires fresh review and exact-head checks; its central preflight currently awaits the closed caller/runtime record. That earlier PASS does not admit this caller.

Draft; no tag or publication. Workflow owns its real five-cell installed baseline upgrade journeys, then the actual2.29 registry matrix and nine-case timeout probe. General owns the single closed central admission record and integration; Security has been asked to review035a. Frozen source/provenance and next actions remain on this PR. Documentation534 stays unreleased pending the actual installed receipt. Native/server1201 and the separate legacy Ready/Leased defect1116 remain open; embedded publication alone will not close863.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Security release-source review: PASS for final main-based head ade3f8d2db8954ac91923931c581b796c82e8e2c (tree 1e824dfad611147878d730b9983e31588dbfd045). The tree is byte-identical to the requested 6f3013270731694288e46a10d71eeac626fa756a; only the accepted #1129/main ancestry changed.

Reviewed boundaries:

  • The five-file delta is release metadata plus the published-package qualification path; runtime src is the accepted Deadline-triggered timeout cleanup, embedded (#863) #1129 tree. The 2.29.0 notes retain the opt-in, embedded-only, migration-required scope and do not claim poll/service admission or a successful business outcome.
  • The existing release verifier still uses the qualified Ubuntu 24 / system Python / PHP 8.3 / private Composer state and authenticated Composer trust boundary. Product commands run with GitHub credential variables emptied, and terminal PHP/trust revalidation plus owned-state cleanup remain unchanged.
  • The installed probe requires a stable exact version, exact InstalledVersions reference, one registry ZIP lock entry whose dist/source references equal the immutable product revision, a normal vendor install, exact product train, and byte-for-byte inventory equality between installed and immutable-tag src (including the package migrations/config under that tree) before application bootstrap.
  • Prototype mode is explicitly non-published: it skips the registry-only assertion but emits source-prototype-pass / composer-path-prototype. The release path does not select it, requires outcome=pass, and checks exact version/source plus all nine results. A prototype receipt therefore cannot satisfy the published gate.
  • The nine real database-queue scenarios cover completed, failed, rethrown, expired, no-worker, late-detection, hard-preemption, SIGKILL/cold replacement and legacy no-opt-in behavior. Each scenario bounds wall time; preserves the original hard deadline; checks terminal business status/event, cleanup outcome, delivery/entry cardinality and durable effect count; and terminates any remaining owned worker in finally.
  • The result contains only bounded qualification identities/counts/timestamps and hashes, not request headers or credentials.

Independent source checks: final-tree equality and git diff --check pass; YAML/JSON and shell syntax parse; added-line credential scan is clean. The committed harness SHA-256 is c0e9e85577d2b8547ac2319a04edca5e777b7992c20c9620c25f5bddd65493a6, and an independent inventory calculation reproduces the prototype runtime-tree SHA-256 669e6650a30408ba5fa4fe37ee90379b68e92642d1f828cc4b1c5b3534301b05 recorded in the PR.

This does not convert the prototype into registry qualification. All required exact-head CI must finish green before merge; no tag/publication is approved by this source review. After publication, the unchanged verifier must pass against the real registry ZIP and immutable tag before timeout-cleanup delivery or downstream release claims.

@sonarqubecloud

Copy link
Copy Markdown

@rmcdaniel

Copy link
Copy Markdown
Member Author

Release-path supply follow-up to shared #297: source is frozen at 035a086af8949cbff3f261abe77d2278b264cfab. The prior release source at ade3f8d2 completed all 25 successful checks / 6 intended skips, but its existing Laravel upgrade caller lacked a qualified supply path. General confirmed the tag hold and the exact committed five cells (no PHP 8.5 expansion).

The upgrade job now unconditionally uses fixed container runtimes on Ubuntu 24, preserving 8.2/Laravel12, 8.3/Laravel12+13 and 8.4/Laravel12+13, the derived product matrix, original upgrade/downgrade commands and optional two-worker outcomes. Initial published-package/timeout-probe helper411a and its profile are unchanged. Runtime library src is unchanged from accepted1129.

Seven neutral Docker/INI/CA/Brotli inputs match reviewed SDK source e6494b86 byte for byte; the known local 8.2/8.4 image IDs are reused. Workflow owns the new 8.3.36 Bookworm input (php official index 232331112d3a7c5b98edeeddc3b85f610172f99352c0635fe6b3e166e47062cb, amd64 child b2d2be78de4de803e20d1ae3df91c196e332a40cc851754472be4fab0fac1f03, fixed Bookworm parent c67e92c8). The actual parent reports APT2.6.2 before any networked APT. The fixed APT source remains18783be6/helper2a36a241; Composer is the same immutable2.10.3 input.

The new8.3 build config sha256:1c991a1bd0dbe36526f8d51af5ab1bd0f00d06e26babfe70400944f8cb808896 passes actual module/function, production INI/defaults, no-coverage and Composer TLS controls. Seven launcher controls, all23 existing routing tests and4 APT policy tests pass; shell/diff/public-boundary and added-line credential/private-path scans pass. The first routing invocation lacked host PHP; the complete rerun through the new inspected runtime passes unchanged tests. The generic PHP digest628102 is Trixie, so it was rejected during parent inspection and was not used as the Bookworm source.

Workflow's launcher forwards only actual upgrade fixture inputs and private dependency/trust state, with caller UID, immutable config ID and bounded containers. It mounts the owned private SQLite directory so the original host shared-memory database and WAL sidecars persist across invocations. Composer's accepted verifier is read-only and runs before each networked upgrade operation.

Next: Workflow runs its own real five-cell installed baseline upgrade journeys, then the actual2.29 registry journeys after publication. General owns one closed central caller/runtime record and integration; Security must counter-review this new exact head. SDK image proofs and the earlier ade3 Security PASS do not admit this caller. No tag/publication/installed2.29 acceptance is claimed.

@rmcdaniel rmcdaniel changed the title Release Workflow 2.29.0 with installed timeout cleanup qualification Prepare Workflow 2.29.0 and fixed installed-upgrade runtimes Nov 13, 2026
@rmcdaniel

Copy link
Copy Markdown
Member Author

Security HOLD on exact head 035a086af8949cbff3f261abe77d2278b264cfab for a host/container trust-boundary escape in the new PHP runner. The earlier release/probe PASS at ade3f8d2 remains valid; it does not cover this new launcher delta.

scripts/ci/run-php-container.sh bind-mounts both of these paths read-write into every package/application container:

--mount type=bind,source=$root,target=$root
--mount type=bind,source=$state,target=$state

The host then executes $state/bin/php and $state/bin/composer, which are symlinks to $root/scripts/ci/run-php-container.sh, on every later php, Composer, and Composer-trust-verifier call. The container runs as the same UID. Code reached through composer create-project, package scripts, application bootstrap, or the installed package can therefore:

  1. infer $state from the forwarded COMPOSER_HOME;
  2. replace $state/bin/php or $state/bin/composer, or follow those symlinks and replace the writable launcher in $root;
  3. return to the host shell;
  4. have the next nominal php "$WORKFLOW_COMPOSER_TRUST_VERIFIER" ... invocation execute the substituted file directly on the host, outside the container, allowing the guard to be forged and later host steps/source/evidence to be altered.

The accepted verifier file's nested read-only bind does not close this: the attacker replaces the host executable used to invoke it. Empty GitHub/Composer token variables reduce impact but do not restore the container boundary or evidence integrity. This is statically reachable before the second networked Composer operation in the unchanged upgrade journey.

Required correction before source approval:

  • mount repository/product/control source read-only;
  • keep the host launcher directory and launcher target outside package-writable mounts, or overlay $state/bin read-only while the target source is also read-only;
  • expose only the specific writable Composer home/cache/temp, application fixture, private SQLite directory, and bounded evidence output needed by the journey. Move the optional queue evidence out of the repository mount rather than keeping the whole checkout writable;
  • add predecessor-failing controls showing code inside the real container cannot replace either host launcher/symlink or its target, cannot alter source/control bytes, and that the next host verifier still executes the exact reviewed launcher and verifier;
  • preserve the existing image-ID binding, caps, environment allowlist, selected-CA mounts, private database checks, fixed APT guard, and per-request Composer verification.

The copied neutral build inputs do match SDK source e6494b86..., but the unsafe read-write root/state pattern is inherited by that SDK launcher and also appears in the pending CLI, Waterline, and Sample callers. Those caller activations and their central source records need a coordinated corrected-source/hash refresh; inheritance is not an approval.

The current required central policy failure is independently non-waivable: no Workflow caller activation or tag may proceed until the corrected source has an accepted closed central record, exact-head green policy gate, real five-cell installed results, and a Security successor review. No runtime/library finding is asserted here.

@rmcdaniel

Copy link
Copy Markdown
Member Author

The current launcher-boundary qualification step is policy-blocked; release activation remains held.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant