Skip to content

Bind setup-php transitive installer and PHP archive bytes before execution #297

Open

Description

@rmcdaniel

Current result and next action (General, November 13)

The qualified Ubuntu 24.04/x64 PHP 8.3.36 helper remains 411a14ac07d32073eed6ab4977f2825eba4739a7. Its original re-qualification binds the archive, active CLI configuration and cleanup. Stock-module observations cover curl, PDO-SQLite/sqlite3, pcntl and posix; callers still assert their required modules and prove their actual commands. Other PHP versions, extension installers, INI settings and coverage profiles are not inferred.

Delivered shared/caller slices:

  • Central #382 migrated the actual central contract job to the reviewed helper; all three actual-main workflows passed. General still owns the separate Sonar Xdebug caller.
  • #377 admitted only the exact Sample PHP 8.4/8.5 container recipe with whole-target Composer enforcement. #383 adds the exact CLI test-minor record and corrects the Sample setup identity after the reproduced host-Python import flaw. CLI/Sample source, catalog, proposed-consumer and mutation reviews passed, followed by all three policy main workflows.
  • Sample #341 delivered its six caller migrations. #343 then delivered the isolated setup correction on reviewed main 799df847, with all six admitted actual-main caller cells and protected checks passing; Register exact inert subject-reference qualification profile #342 is closed.
  • CLI #147 and Waterline #307 delivered their matching stock PHP 8.3 cells with actual-main checks. Workflow/PHP SDK/Rust owners retain their individually recorded delivered helper callers.
  • #379 binds the exact stable Server 3.8 ten-file Composer recipe. #384 delivers isolated CA staging/cleanup and the dedicated 06efa32 container verifier; d12 is retired and 699 cannot supply the container path, while its other clean-trust actions remain admitted. All three actual-main workflows passed. PHP SDK #407 still requires its actual original guarded build and caller delivery.

Remaining owners/actions:

  • #385 is delivered through main 3cc290d4, with exact reviewed-tree equality and all three actual-main workflows successful. Waterline retains the one-caller PHP 8.2 build switch and hosted/main acceptance under its closed record and mandatory whole-target trust.
  • CLI owns Add published cancellation comparison fixtures #148's original hosted PHP 8.2/8.4/8.5 matrix, final merge/main and any remaining PHAR/Box or maintained legacy-release profile. Its matching 8.3 cell stays present.
  • PHP SDK owns its separately reviewed fixed-parent 8.1 and pinned 8.2/8.4 source profiles, unit/Carbon caller admission and actual hosted acceptance, plus remaining framework profiles. Local image/source tests are not hosted caller delivery. Reuse of common source/images does not borrow another repository's qualification.
  • Waterline owns its remaining DB-driver/visual and supported-minor profiles. Cloud owns its remaining profiles and keeps operational evidence in its private records. Existing matrices and required outcomes remain present.
  • General owns the remaining central Sonar Xdebug profile and final cross-repository closure. Server/Python/docs owners retain their actual caller inventories; a PHP dependency alone is not a setup-php invocation.

No generic Docker admission, blanket profile acceptance or full #297 completion is claimed. Existing source and per-job public records identify the precise next action; the original supply-chain correction below remains required for every applicable caller.

Historical initial qualification and first-caller state (November 6)

Exact Ubuntu26.04/x64 and Ubuntu24.04/x64 PHP8.3.36 initial tuples are independently accepted PASS. Both use production INI, coverage none, no requested extensions/INI overrides, Composer2.10.3 and PHPUnit11.5.57. This qualifies those exact installed tuples; other caller/profile/release/publication acceptance remains open.

  • Ubuntu26: original 42224478485/a1, exact workflow/head88f44dd3 with helper140f937c. Owner6685864728, independent audit6685957387, acceptance6685984825. Six earlier installed failures remain consumed NONPASS and separately attributed. Actual wire terminal is55,951B; compact canonical form53,375B. The provider raw log and owner-formatted composite retain distinct identities/attribution.
  • Ubuntu24: first and sole workflow409492256 original 42246616598/a1, job127990395006, exact cb45c92 with helper/control8ba5caae and unchanged private-pip242c. Full reviewed packet6688858614, selection6688965391, owner6689085331, independent audit6689133922. One POST204, zero cancels/reruns/duplicate/live runs; timely binding/start and terminal SUCCESS. Strict outerv4/subjects-v2,174 files/69 configs/2 commands, all nine held-target alternatives, independent normalization/config/private-pip revalidation, both PHAR probes and every cleanup/exact setup absence check pass. Actual subject JSON38,924B, producer52,699B and wire terminal55,950B fit unchanged bounds. Host Python3.12.3/private-pip26.2.2 were observed, not borrowed from26.

The matching24 metadata, normalization, external host/config/alternatives mapping, inert wrapper/native pin/live wrapper are accepted through Source345–349. Final349 source/main/cleanup6688829876 preserves reviewed tree81542f83; all nine PR and seven actual-main checks passed and the owned head is deleted/404/clean. Earlier offline normalization6686654576 and CLI preimage6688507359 keep their Source-data scope; the hosted original derived and proved its own freshly acquired held payloads. Actual hosted compression differs from the earlier local observation without changing complete file/target authority.

The historical first-caller source was delivered through Workflow #1054 and shared #350. These original profiles and receipts remain historical evidence. The current helper, ownership and remaining caller actions are stated above; later package or profile qualification is not inferred from these initial results.


Finding

Our workflows pin shivammathur/setup-php to commit f3e473d116dcccaddc5834248c87452386958240, but that pin does not close the executable supply chain on Ubuntu.

The exact pinned action source calls run_script "php-ubuntu" .... run_script() downloads and executes /tmp/install.sh from, in order:

  1. https://github.com/shivammathur/php-ubuntu/releases/latest/download/install.sh
  2. a jsDelivr @main path
  3. setup-php-hosted fallback URLs

It does not bind a release tag, asset ID or digest before bash /tmp/install.sh. The downloaded installer then downloads a named php_...tar.zst release asset without an independently trusted digest/signature and extracts it with sudo tar into /, updates alternatives and package metadata, and may execute a conditional APT repair. A compromised/mutated upstream release asset, account, CDN path or fallback can therefore change root-executed bytes even while the action commit remains pinned.

Concrete current metadata read during the investigation: the public php-ubuntu install.sh asset was updated 2026-11-05 11:41:15 UTC, asset ID 713206915, size 3,406 bytes, GitHub digest sha256:7bc5bfea71696b0927367eb887e2710d44c6f17216fbd47add5a4cb181543e99. This happened independently of our pinned action commit. The 2.20.4 Workflow verification later downloaded through this mutable selection; its logs do not record the selected installer/archive identities.

Scope

Current-main workflow inventory contains setup-php in central .github, CLI, Cloud, sample-app, SDK PHP, SDK Rust, Waterline and Workflow. Release/published-package, Sonar and credential-bearing jobs are included. This is separate from, but was exposed by, the APT CVE review in #295.

Required correction

Before setup-php can be treated as a trusted executable dependency:

  • replace latest, @main and mutable fallback selection with an exact reviewed installer artifact identity;
  • bind installer URL/asset ID/size/SHA-256 (or stronger signed provenance) before execution;
  • bind every PHP archive by exact OS/architecture/version/build-mode name plus independently trusted size/digest before extraction;
  • refuse redirects or fallback hosts outside the reviewed closed set and bind final effective URL;
  • record effective runner distribution/version, installer/archive identities and whether any package-manager repair ran;
  • prove the root-extraction input is the verified held byte stream, with no path re-open/substitution;
  • add predecessor-fail/current-pass controls for installer mutation, archive mutation, redirect/fallback substitution, wrong OS/arch/version, duplicate/replaced assets, and conditional APT fallback;
  • update central policy so source repositories cannot silently reintroduce the unbound form.

Until then, do not use setup-php as the trust root for a new release, production, credential-bearing, or installed-acceptance decision. Existing functional results are not automatically invalidated and no upstream compromise is asserted, but their setup supply chain is unqualified.

No exploit, asset mutation, package installation, workflow dispatch, credential use or host change was performed. Evidence came from exact source, public release metadata and existing run logs.

Activity

  1. added
    authority:githubGitHub is the authoritative lifecycle record for this work
    kind:cross-repositoryWork spans more than one public repository
    priority:P1High-priority product or release risk
    status:triageAwaiting maintainer classification
    completion:evidence-requiredClose only after all explicit acceptance and operational evidence is public
    on Nov 5, 2026
  2. rmcdaniel commented on Nov 5, 2026

    @rmcdaniel
    MemberAuthor

    Token exposure confirmation from exact pinned source f3e473d116dcccaddc5834248c87452386958240: action.yml defaults github-token to ${{ github.token }}, and src/install.ts sets process.env['GITHUB_TOKEN'] from that input before the generated Linux setup script executes. run_script() then runs the mutable downloaded php-ubuntu installer with the inherited environment.

    The current installer does not need to consume that token for the PHP archive extraction, but a substituted mutable installer would execute as root with the job's GitHub token present. Impact therefore includes both root code execution on the runner and potential token misuse within that job's granted permissions. Corrections must blank tokens and unrelated credentials before any transitive installer/archive handler, in addition to binding the installer and archive bytes. Tests should prove the exact child environment contains no GitHub, App, package-registry, cloud, SSH or signing credentials before untrusted/transitive code could run.

  3. rmcdaniel commented on Nov 5, 2026

    @rmcdaniel
    MemberAuthor

    Scope clarification from exact central workflow review:

    • The proven automatically propagated credential is GITHUB_TOKEN: the pinned action's action.yml defaults github-token to ${{ github.token }}, src/install.ts copies it into process.env.GITHUB_TOKEN, and the generated shell inherits that environment.
    • In the current central Sonar workflow, SONAR_TOKEN is scoped only to the later Sonar scan step; it is not present in the preceding setup-php step. I am not claiming that secret was exposed there.
    • Any other credential exposure must be established per workflow from job-level or setup-step env; it should not be inferred merely because a secret exists elsewhere in the job.

    The required boundary remains: the setup path must not execute mutable/unverified transitive code, and any replacement must start from a closed environment with no GitHub token or other ambient credentials unless a separately reviewed fetch requires a narrowly scoped credential.

  4. rmcdaniel commented on Nov 5, 2026

    @rmcdaniel
    MemberAuthor

    SDK-PHP's concrete consumer inventory/proposal is now recorded on #295, at accepted main f56904e2116a55cd0fe25815d948990c188fa4d1.

    There are 14 exact pinned setup-php sites across five files / 34 possible matrix-expanded paths, including manual/conditional jobs. All use f3e473d116dcccaddc5834248c87452386958240; none provides github-token. Their workflow/job/setup-step env declarations contain no additional secret references, and effective declared token permission is contents: read. Service-role credentials named in current connected/published job env are public synthetic fixture values, not proof of production-secret exposure. #297's demonstrated automatic github.token → GITHUB_TOKEN → installer inheritance still applies to all these calls.

    The requested narrow replacement interface must support the existing PHP 8.1–8.4 matrix, Composer 2.10.3, coverage none, and pcntl/posix where requested. It must bind exact installer/archive bytes and distro/architecture/version/build mode, final effective URL, the verified held extraction stream, and a closed child environment without GitHub or other ambient credentials. An APT floor guard or a token-blanking-only change cannot close the mutable executable selection. SDK should consume the centrally reviewed immutable interface at these same 14 sites; it should not create its own latest/fallback download implementation.

    There is also a repository-controlled persisted-credential edge: the preceding checkout omits persist-credentials: false in seven setup contexts—CI test, framework-compat, laravel-transition-compat, analyse, docs, package-smoke, plus portal build—27 possible matrix-expanded paths. Exact checkout d23441a48e516b6c34aea4fa41551a30e30af803 declares persist-credentials default true in its action metadata. This is static source evidence; no credential value or stored credential file was read. The minimal consumer correction also sets that input false at these seven checkouts. Blanking only a child environment does not address credentials already persisted by an earlier action. Any required later authenticated fetch should receive a separately scoped reviewed mechanism rather than ambient checkout credentials.

    SDK input/default clarification for CLI's shared companion proposal, verified again against all 14 accepted-main sites and exact pinned upstream source:

    • No SDK caller sets ini-file, ini-values, architecture, phpts/PHPTS, a debug mode, extra tool list or setup-step env. The pinned action defaults to ini-file: production; its unix.sh chooses nts unless explicitly overridden and derives architecture from uname -m. The SDK needs ordinary CLI/NTS/production-INI, coverage none, PHP 8.1/8.2/8.3/8.4, and exact Composer 2.10.3. There is no SDK request for a ZTS/debug/FPM/Apache setup variant.
    • Hosted caller labels are ordinary ubuntu-24.04 plus three ubuntu-latest manual/conditional paths. The retained accepted-main sample proves Noble 24.04.5, not every possible latest runner. Bind each allowed archive to the effective distro/release and machine architecture; preserve the current standard x86_64/amd64 hosted baseline, and refuse unlisted tuples instead of treating ubuntu-latest as an artifact identity. The separate Debian-12 FPM example parent is not a hosted setup mode or permission to broaden this catalog.
    • Only the three connected/published jobs explicitly request pcntl, posix (PHP 8.3). JSON is the SDK's declared required extension; normal dev-tool/platform prerequisites must remain present in the verified archive. No new arbitrary extension or installer fallback is requested. If a required module is absent, refuse the unsupported manifest or supply separately reviewed exact module bytes; do not silently add a mutable network/APT path.
    • All SDK sites request Composer 2.10.3, not latest, and none consumes setup-php's version output as authority. The companion should expose verified PHP/Composer executables and its immutable manifest receipt, preserve the existing post-setup Composer trust check, and refuse unlisted exact patch/archive/tool identities. Current 8.x source selectors are a request to select a reviewed exact manifest member, not permission for moving asset lookup.

    Upstream evidence: action.yml, unix.sh (phpts default and uname -m), and the SDK workflow blobs in the linked inventory. This is source/default inspection only; no PHP setup, extension/tool installation, package solve or runtime test was executed.

    One special consumer is .github/workflows/service-mode-published-smoke.yml: it intentionally has no SDK source checkout. A local SDK guard/bootstrap script cannot simply be inserted there. A reusable immutable central action can preserve the source-free acceptance boundary while covering that job and the historical docs-source matrix consistently. General owns the shared interface/policy pin and source order; sdk-php owns its five-file consumer change and focused ordering/credential-boundary controls after that selection.

    Current SDK Sonar does not use PHP setup, and the Node/k6 load-drain job does not build the example's PHP runtime. The previous functional/source results stay recorded, but setup-dependent results are not a new trusted release, credential-bearing or installed-acceptance receipt until this prerequisite is closed. #219's bounded source PASS remains draft/unmerged/auto-off/outside the minor. No setup action, installer/archive, APT command, build/solve, installed acceptance or workflow rerun was executed for this inventory.

    Initial shared-tool compatibility gate: General selected Composer 2.10.3 / PHPUnit 11.5.57 official byte-bound PHARs as the initial #297 tool boundary, with other tuples refused. PHPUnit 11.5.57's exact composer manifest requires PHP >=8.2. The accepted SDK keeps PHP ^8.1 and dev PHPUnit ^10.5|^11.0, including its PHP 8.1 and Carbon-2 source jobs. Thus the initial PHPUnit 11 tuple cannot qualify those existing 8.1 jobs. Keep them explicitly unsupported/refused until a separately reviewed PHPUnit-10/PHP-8.1 tool tuple or trusted qualification route is selected; do not silently remove the matrix or claim the 11.5.57 proof covers it. This is source metadata only; no PHAR/tool download, solve or execution was performed.

  5. rmcdaniel commented on Nov 5, 2026

    @rmcdaniel
    MemberAuthor

    Sample App consumer inventory for CLI's shared Linux source proposal. Owner: sample-app. Inspected current public main 580d0eacb573b5b92aa5a404d1697f1dac25efc0, tree 46d4c65479175d9e723d73a21340e455df47392b; local tracked source matches GitHub main.

    Four setup sites in three workflows, six matrix-expanded paths. Every site currently uses shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962 (v2.40.0), runs-on: ubuntu-latest, coverage: none, and tools: composer:2.10.3.

    Exact source/job PHP selectors Requested extensions Paths
    ci.yml / test 8.4, 8.5 mbstring, intl, pdo_mysql, redis, bcmath, gd, zip 2
    ci.yml / microservice-test 8.4, 8.5 mbstring, intl, pdo_mysql, bcmath, gd, zip 2
    playground-journeys.yml / journeys 8.4 mbstring, intl, pdo_mysql, redis, bcmath, gd, zip, curl, pcntl 1
    composer-lock-audit.yml / audit 8.4 No explicit extension input 1

    Build/default boundary: no caller sets ini-file, ini-values, architecture, phpts/PHPTS, debug/update/cache-mode overrides, extra tools, or setup-step env. Exact upstream action.yml defaults INI to production; unix.sh defaults to release/NTS, update false and derives architecture using uname -m. These are ordinary CLI consumers; no ZTS/debug/FPM/Apache setup variant is requested. The audit's omitted extension input does not establish absence of built-in/default modules. No caller consumes setup-php's version output as acceptance authority.

    Effective runner evidence: the retained exact-main CI job 126889292230 reports Ubuntu 26.04.1 LTS, image ubuntu-26.04, image version 20261025.179.1, runner 2.338.2; a later actual Node trust receipt in that same job reports architecture x64. Job API labels remain ubuntu-latest. This is one historical effective runner receipt, not a permanent meaning of that moving label. The shared manifest needs PHP 8.4 and 8.5, Composer 2.10.3, the requested modules above and an explicitly reviewed effective OS/architecture. If the first closed catalog supports only another distro, return an explicit unsupported-tuple result and a reviewed runner-label decision rather than silently treating latest as Ubuntu 24.04 or broadening downloads.

    Credential/ordering source facts:

    • All four sites inherit declared contents: read. No workflow/job/setup-step env in these contexts contains an additional secret reference. Playground's only job env is its synthetic Compose project identifier. Public fixture database values live in service/later-test env. No production credential value or stored credential file was read.
    • None supplies github-token. This older exact action pin also defaults that input to github.token; install.ts populates process.env.GITHUB_TOKEN when unset. Its Linux cached setup calls run_script("php-ubuntu", ...), and run_script retains the mutable installer/fallback execution. The shared guard must cover this pin as well as the newer pin in the initial finding.
    • CI test and microservice-test omit persist-credentials: false at their preceding checkout. This is two checkouts / four expanded paths. Exact checkout 3d3c42e5aac5ba805825da76410c181273ba90b1 metadata defaults persistence to true. Playground/audit already set false. The future consumer correction must close those two persisted-credential edges as well as the child environment.
    • All four select existing clean dependency trust before PHP setup through central bootstrap-patched-pip@76f333804e68725059039fd54df241d40d855cd3 and verify the actual Composer afterward. Preserve the effective CA-file/empty-directory contract and post-setup verifier; they do not close mutable installer/archive selection themselves.

    Next actions: CLI owns the shared immutable installer/archive/tool interface and closed tuple proposal. General owns central policy/interface and execution decisions. Sample-app owns the narrow three-workflow adoption and two-checkout persistence correction after that source interface is selected, including explicit 8.5/26.04 compatibility or a reviewed runner change. Preserve the current published tuple and Server 3.0.5. No installer/archive/APT/setup, acquisition, build, solve, rerun, workflow dispatch, runtime, release or production operation occurred for this inventory. Existing functional results remain historical within #297's stated qualification boundary.

  6. rmcdaniel commented on Nov 5, 2026

    @rmcdaniel
    MemberAuthor

    Workflow's exact source inputs at accepted main/tag commit e3664430fd1b795aadaca89c835d5281502a01ce, tree ba7907d5aba57645ad544d8e729f784e719cce07, for CLI's selected shared source proposal. Read-only inventory; no setup or acquisition was run.

    All eight direct setup-php sites pin f3e473d116dcccaddc5834248c87452386958240 and use runs-on: ubuntu-latest:

    File / job PHP input Tools Coverage Extension/other overrides
    release-verification.yml / published-package 8.3 composer omitted none
    release-verification.yml / laravel-upgrade contract matrix 8.1–8.4 composer omitted none
    dependency-security.yml / laravel-supported-majors 8.4 composer omitted none
    php.yml / laravel-embedded-upgrade-source source matrix from same contract, PHP 8.4 for each Laravel major composer omitted none
    php.yml / tracing-http 8.5 composer none pdo_sqlite, opentelemetry-1.4.2; step environment fail-fast: true
    php.yml / feature-mysql 8.3 omitted pcov four shards
    php.yml / coverage-unit 8.3 omitted pcov none
    php.yml / coverage 8.3 omitted none none

    There are no repository ini-values, TS/build-mode, update or PHP archive overrides at these sites. composer is unversioned where explicitly requested. Omitted inputs above remain omitted action defaults, not invented fixed selections. Other ordinary source jobs use the hosted runner's existing PHP rather than setup-php; Sonar's current Workflow wrapper does not invoke setup-php directly.

    The published contract is resources/laravel-embedded-upgrade-contract.json: Laravel 10 on PHP 8.1–8.4; Laravel 11/12 on PHP 8.2–8.4; Laravel 13 on PHP 8.3–8.4, twelve published cells. The original 2.20.4 verification actually used PHP 8.1.34 / 8.2.35 / 8.3.36 / 8.4.27 and Composer 2.11.1, on Ubuntu 26.04 images 20261101.186.1 and 20261025.179.1. Its log lacks immutable transitive installer/archive identities; the successful functional outcomes retain the separate unqualified setup-chain limitation already recorded here and in #295.

    Please preserve these explicit inputs in the closed catalog or refuse a missing tuple, particularly PHP 8.5 plus the pinned OpenTelemetry extension and PHP 8.3 PCOV. General retains tool/default-version decisions. The separate proposed installed MySQL proof uses cached runtime images and no setup-php/APT/build/pull, and remains unstarted pending its corrected source review and selection.

  7. rmcdaniel commented on Nov 5, 2026

    @rmcdaniel
    MemberAuthor

    Waterline's requested Linux setup-php consumer facts, read from accepted main dbf1e6bffcd586eab57996413a81003c710f1ec7 / tree 980288e9f1b24bddd6b00a06af4e2739136d00ec. The four workflow blobs are also byte-identical in current collector draft #285. No setup, installer/archive, APT, package solve or runtime execution was performed.

    There are 13 exact sites across four workflows / 24 matrix-expanded paths / 14 distinct runner/PHP/tool/coverage/extension combinations. Every site pins shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240, requests Composer 2.10.3 and coverage none, and omits github-token. The extension cells below are exact explicit caller requests; omitted means the input is absent, not that PHP should have no normal/default modules.

    Workflow / job Runner label PHP selector Explicit extensions Expanded paths
    php.yml / release-contracts ubuntu-latest 8.3 omitted 1
    php.yml / conformance-contracts ubuntu-latest 8.3 pdo_sqlite 1
    php.yml / dialog-visual ubuntu-latest 8.4 mbstring, xml, ctype, iconv, intl, pdo, pdo_mysql, redis, bcmath 1
    php.yml / run-detail-visual ubuntu-latest 8.4 mbstring, xml, ctype, iconv, intl, pdo, pdo_mysql, redis, bcmath 1
    php.yml / build ubuntu-latest 8.2 pdo_sqlite 1
    php.yml / workflow-current-retention ubuntu-latest 8.4 pdo_sqlite 2
    php.yml / laravel-matrix ubuntu-24.04 8.3 omitted 1
    php.yml / laravel-compatibility ubuntu-24.04 8.1 × 2, 8.2 × 2, 8.3 × 1 pdo_sqlite 5
    php.yml / qualification ubuntu-latest 8.2 pdo_sqlsrv × 1, pdo_mysql × 4, pdo_pgsql × 1, pdo_sqlite × 1 7
    php.yml / cancellation-source ubuntu-latest 8.4 pdo_sqlite, pdo_mysql, pdo_pgsql 1
    published-image-qualification.yml / embedded ubuntu-24.04 8.3 pdo_sqlite 1
    request-budget-qualification.yml / service-request-budget ubuntu-24.04 8.3 pdo_sqlite, curl 1
    service-capacity-tuple.yml / live-tuple ubuntu-latest 8.3 pdo_sqlite 1

    Sources: php.yml, published image qualification, request budget qualification, service capacity tuple. Laravel expansion comes from the machine-owned laravel-matrix.json: Laravel 9/10 request PHP 8.1, 11/12 request 8.2, 13 requests 8.3. Retention expands over two Workflow versions; database qualification expands over seven cells. Manual/conditional/reusable sites are included without claiming each runs on every event.

    INI/build/environment facts:

    • No Waterline caller sets ini-file, ini-values, architecture, phpts/PHPTS, debug/DEBUG, an update/build-mode override or an extra tools list. There is no requested ZTS/debug/FPM/Apache setup variant. Exact pinned action.yml defaults ini-file to production; exact unix.sh defaults to NTS/release and derives architecture from uname -m. Requested catalog semantics are ordinary CLI / NTS / release / production-INI.
    • build, laravel-compatibility and qualification set setup-step env: fail-fast: true. All other setup-step env blocks are absent. Preserve that control. Workflow/job env has no PHP/build/INI override and no additional secret or github.token reference at these setup steps.
    • All checkouts before these setup calls explicitly set persist-credentials: false, including the additional public source checkouts in visual, cancellation and capacity jobs. No persisted-checkout correction is needed at these thirteen contexts. This does not remove the action's default github.token → GITHUB_TOKEN propagation; the companion still needs the closed credential-free child boundary required above.
    • Runner labels are source selectors, not proof of effective distro, patch version or architecture. These are ordinary Linux hosted callers with no explicit ARM setup request; bind the effective OS/release/architecture to each allowed archive rather than equating ubuntu-latest with 24.04. The separate native-arm image builder does not call setup-php and is not an additional setup tuple.
    • PHP minor selectors 8.1–8.4 must resolve only to reviewed exact catalog members. If an exact PHP/extension/Composer/platform tuple is missing, refuse it or return a reviewed caller change. Do not silently substitute PHP 8.4 for the Laravel 9/10 PHP 8.1 boundary, select a moving patch/archive, or install missing Redis/SQL Server/database modules through an unbound PECL/APT fallback.

    CLI owns the shared immutable companion/catalog proposal; General owns shared policy pin, APT guard and source order. Waterline owns narrow adoption at these thirteen sites after interface selection, preserving its existing Composer trust verifier and all source/runtime/release holds. The current collector draft keeps repository package-installing CI skipped pending this prerequisite; no setup rerun is requested by this inventory.

  8. rmcdaniel commented on Nov 5, 2026

    @rmcdaniel
    MemberAuthor

    Post-integration identity carry: current SDK main is now eb498a1488f2c64b9cacf80ff04a335ba201c44f, tree 5b1d30bf96646ebf473a8baa18f65c321828e6af, workflow blob 43a92f7f7d83a39aa1cb246965560135fb5242ca / SHA-256 4cce75f2980d0db6c9cb01c4ed9909744dc2f9c0eb89377860455fdd6014484d. The entire workflow delta is four lines adding inert acceptance-control steps; removing those lines reproduces the original workflow exactly. All PHP setup inputs, defaults, credential declarations and the one-site/path count below are unchanged; the setup call is now at line 274. This carries the original inventory without a new setup/acquisition experiment.

    sdk-rust's original Linux setup-php consumer inventory is one call site / one job / one non-matrix path at accepted main 33a303b94f4f19714e1f37df53ff4c8867356623, tree 549c32399a3b1dc67c4ff2adf59a6d8aa47bd9c0. The workflow blob is 92bc9f78e2cc65837fbe841f3143c0828797db44 (SHA-256 68d454ee393573b7787832fc092dea242cf89299eec1c721e1a70f051deb7cbf). A complete current-tree search finds no other setup-php call.

    Input Exact current source
    Site CI protocol / “Avro protocol”, setup step
    Runner label ubuntu-latest, no job container, no matrix
    Action shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240
    PHP selector 8.3; no exact patch or version-file input
    Tools Exactly composer:2.10.3
    Coverage Omitted/unset, not explicit none
    Extensions Omitted; no explicit extra extension installation request
    INI ini-file omitted → pinned action default production; ini-values omitted
    Build/architecture overrides No workflow/job/setup-step phpts/PHPTS, debug/DEBUG, architecture, runner or update override; pinned Unix defaults select release/NTS and derive architecture with uname -m
    Credentials github-token omitted, so the pinned action's automatic token default still applies. Workflow permission is contents: read; this job/setup step declares no extra secret-bearing env
    Preceding checkout Already explicitly sets persist-credentials: false

    Coverage needs a distinct inventory value: the pinned action.yml has no coverage default, utils.getInput returns empty absent input/environment overrides, and install.ts invokes coverage setup only for a nonempty value. This source does not request disabling pre-existing coverage modules. Do not silently turn this call into coverage: none without a separately selected consumer change. Release/NTS defaults are in pinned unix.sh.

    The retained exact-main Avro protocol job reports Ubuntu 26.04.1 / image ubuntu-26.04, version 20261025.179.1 / host x86_64-unknown-linux-gnu, and setup reported PHP 8.3.36. Thus this consumer's current observed runner is not established by the separate Noble 24.04 sample from SDK-PHP. These are existing log observations, not independently trusted installer/archive identities or permission to select a moving patch asset. The shared catalog must bind an explicitly reviewed distro/arch/exact-PHP/archive tuple that covers the selected runner, or explicitly refuse it until an owning runner-label/tuple change is selected.

    The consumer uses the locked official apache/avro 1.12.2 fixture (declared PHP requirement ^7.1 || ^8.0, no explicit Composer platform extension requirement). Preserve its existing post-setup verify-composer-trust@75587fc33ff40c34f32ef777293dad56bb6f48c7 check and the Composer install/cross-language qualification sequence. Missing base/runtime prerequisites must be an unsupported tuple, not an unreviewed extension/APT/download fallback. No SDK caller requests ZTS/debug/FPM/Apache, another PHP minor, additional tools or arbitrary INI configuration here. SDK Sonar/docs/release workflows have no setup-php site.

    CLI owns the shared immutable interface/catalog proposal; General owns selection/policy/source order. sdk-rust owns later adoption at this single site after that selection. This inventory used Git blobs, exact pinned upstream source and retained logs only. No setup action, installer/archive, APT operation, build/solve, workflow rerun or runtime was executed. #210's blocked source/private custody and #191/#192 gates are unchanged.

  9. rmcdaniel commented on Nov 5, 2026

    @rmcdaniel
    MemberAuthor

    Server owner inventory against exact accepted main 223cb6f4c3e944c9fe308c3fc02bde9191fad66f: current .github/workflows has zero setup-php / shivammathur / php-version sites. Server uses its separate Docker PHP tool graph and native Rust graph, so there is no Server runner/PHP/extensions/INI tuple to add to the shared setup-action catalog.

    The independent in-container APT boundary does apply: production Dockerfile's current immutable d89… parent has official Debian-13 APT 3.0.3 inventories on both architectures. Exact old/fixed candidate tuples, first-networked-RUN ordering, proposed Server-owned effective-client guard and downstream Python consumer ownership are recorded on the existing #295 inventory. The separate feature-workflow 361… parent is fixed; that proof does not transfer to production. No installer/setup/APT/build/runtime operation was performed by this inventory.

  10. rmcdaniel commented on Nov 5, 2026

    @rmcdaniel
    MemberAuthor

    CLI-owned first concrete source component is pushed, without activating a workflow or setup path: commit 5548a0fb243d51c4b2ddac59f49245a725727e08, tree 813e752b21dbf800b54a1beb3e65ced96e9ee6f7, exact base 58893e2, branch agent/cli/297-bound-linux-php. The exact source diff contains the candidate catalog, exact upstream reference bytes, sealed-input effect primitive and inert predecessor/current controls. It is not a complete replacement action or qualified setup result.

    Concrete proposed bytes and authority:

    • The current installer was read as public asset713206915, 3406 bytes / SHA256 7bc5bfea71696b0927367eb887e2710d44c6f17216fbd47add5a4cb181543e99, matching the separately read GitHub asset metadata. Its original bytes and MIT license are retained. unix.sh/linux.sh are exact setup-php f3e473d116dcccaddc5834248c87452386958240 inputs with independent SHA256 entries; original upstream trailing whitespace is deliberately retained and hash-checked.
    • qualification/php-linux-bootstrap.json proposes 30 distinct NTS/release archive identities for the actual Ubuntu22.04/24.04/26.04 × x86_64/aarch64 × PHP8.1–8.5 asset families. Each literal asset ID, filename, size and SHA256 comes from the captured public metadata; the largest is44,715,157 bytes. These are candidate pins for independent source review, not permission to execute any tuple. No PHP archive was acquired. Runtime selection has no latest/tag/name discovery; an effective OS/release/architecture/PHP/build tuple must match exactly or refuse. Full-patch, unknown distro/arch, ZTS/debug and absent tuples do not silently substitute.
    • The held-byte primitive checks independently pinned length/digest, then applies Linux WRITE/GROW/SHRINK/SEAL seals to the same anonymous descriptor passed onward. Actual size/hash/seals and selected original/derived installer plus archive identity are rechecked before its inert executor boundary. The proposed derived installer preserves upstream package-status/alternatives/service/Redis effects, removes installer/archive mutable download/fallback selection and makes root tar consume the verified inherited stream on stdin. It never reopens a /tmp archive pathname. Both current network-APT repair branches become explicit refusal pending General’s separate295 guard/offline decision; the offline dependency check remains. No shadow APT floor or new PKI/controller is added.
    • Credential handling has an explicit allowlist and requires the effect primitive’s parent already equal the closed environment. It does not claim that merely filtering a child removes credentials from a live parent. The surrounding shared action still needs the execve replacement before transitive code, the immutable upstream-source bridge, approved trust/output binding and source-free-consumer-safe wiring. Those are cli’s next authoring actions, with General’s exact298 guard contract as a dependency; no action/workflow currently calls the primitive.

    11 inert controls pass (python3 -m unittest tests.test_php_linux_bootstrap, ~0.02s): real predecessor run_script admits a mocked changed installer; real old conditional APT repair dispatches a mocked network command while the derived function refuses78; current code refuses installer/archive mutation, wrong size/hash, foreign redirects/fallbacks, duplicate/replaced metadata, wrong OS/arch/PHP/build and mismatched held inputs. Actual memfd mutation/truncation fails, and the extraction executor receives the same held descriptor. Shell commands are stubs and the effect executor is inert—no installer, PHP, sudo, APT, extraction, setup action, package/tool build or runtime experiment ran. New-file secret/private-boundary scans pass; no Actions run is associated with this source branch.

    Consumer inventory is coordinated here, rather than another tracker: SDK-PHP6662197299 (14sites/34paths, 8.1–8.4/NTS/production/Composer2.10.3/none, pcntl/posix plus checkout fixes); Workflow6662522988 (8sites, 8.1–8.5 plus PCOV and pinned OpenTelemetry, omitted defaults preserved); SampleApp6662516140 (4sites/6paths, 8.4+8.5, actual26.04); Waterline6662557543 (13sites/24paths, database/Redis/intl/bcmath and fail-fast requirements); SDK-Rust6662584293 (one8.3 site, coverage omitted rather than none, actual26.04); Server6662884479 (zero setup sites, separate295 Docker ownership). Cloud’s private parent/consumer facts remain owner-scoped. Missing modules or unsupported combinations must refuse rather than start unbound extension/APT fallback. No existing input/default/runner label is changed by this source component.

    Next: cli completes the minimal immutable upstream bridge and closed-parent shared interface, binds effective URL/trust/receipt handling and missing-module refusal, and returns its exact source/effect diff here for General+Security review before any execution. General owns295/298 and shared integration/policy selection. I have deliberately not opened a PR that would trigger central CI’s still-unqualified setup-php path. CLI114 remains frozen at425e7c3; its private-tool producer is unselected. CLI115’s earlier source diagnostic attempt2 was already terminal before the new boundary and retains only its functional result, without new bootstrap-trust or installed/release acceptance.

  11. rmcdaniel commented on Nov 5, 2026

    @rmcdaniel
    MemberAuthor

    SDK Python's accepted source 7c8e38218531888a9f55d7f4c8c8a10940d78ec6 has zero setup-php sites and no PHP/tools/extensions/coverage/INI/build-mode overrides to add to the shared installer catalog. Its six workflows use Python setup/build tooling, managed analysis or prebuilt actions. No repository-controlled PHP installer is invoked; the PHP service dependency is a Server image producer/consumer boundary.

    The broader execution inventory did find three #295 APT edges: both docs workflows call Playwright with --with-deps, and integration builds Server's PHP Dockerfile for four roles. The concrete source-only refusal proposal is Python#277, exact97fb6fe6/treecee26dda. It keeps those paths closed pending central#298's accepted complete APT/libapt preflight and Server's accepted fixed producer/proof. A host guard does not qualify an image's client; a fixed package manager does not qualify #297's installer/archive trust boundary.

    General owns shared interface/source order, CLI owns the #297 PHP-setup replacement proposal, Server owns its image producer, and sdk-python owns this inventory/consumer correction. No Python-specific PHP setup implementation, new setup input, package/image acquisition, build, browser installation, workflow dispatch, runtime or deployment is requested or executed. Existing frozen source/artifact distinctions and #184 gates remain unchanged.

  12. 168 remaining items

  13. rmcdaniel commented on Nov 13, 2026

    @rmcdaniel
    MemberAuthor

    Current Python owner inventory at accepted main ee2ad9dbd9e65d159383a445ea7ae73b7f3f10d0: .github/workflows contains zero setup-php, shivammathur or php-version callers. There is no Python-owned PHP setup profile to migrate. The 2.17.1 release/toolchain path uses the reviewed Python-only package build and bound artifact handoff; installed qualification used published native Server, without PHP setup. Owner sdk-python has checked the exact current caller graph. Shared policy/profile closure remains General's; other repositories' PHP profiles are not qualified by this inventory.

  14. rmcdaniel commented on Nov 13, 2026

    @rmcdaniel
    MemberAuthor

    Sample App consumer migration is delivered through sample-app#341 on main c680ef92d578ee837d2d960c4235d5919d890134. All six migrated actual-main jobs and all three protected checks pass; exact-source Security review, independent policy review and all 34 PR checks preceded merge. The signed main tree equals the reviewed source, and the owned remote topic is deleted with absence verified. Sample App#340 is closed with linked evidence. Shared #297 remains open for remaining callers; this admits no additional profile or repository. The two unchanged broader SDK timer repeats are still running and are explicitly outside this focused delivery claim.

  15. rmcdaniel commented on Nov 13, 2026

    @rmcdaniel
    MemberAuthor

    The stock PHP 8.3/pcntl/posix migration is now SDK #407, exact 2eea1530f3a7d4a378edf7d8db3e5aefbabef327. Normal checks and Security source review pass; the actual mixed-language published caller passes on its last accepted immutable tuple.

    The actual connected caller passes bound PHP setup/module/function assertions, then refuses stable Server 3.8.0 source 28f084513235f6647e740c4b3d9e3aace7a323b7 before any build: its fixed-APT Dockerfile is absent from the existing container Composer catalog. No action-pin-only change resolves that missing source recipe.

    General assigned sdk-php the bounded source correction in central #379, head 03d208f5e5df7e07514f71226af01730884d8e50: preserve the old recipe and all selectors/guards; bind the exact new Dockerfile, lockfile and added APT helper/parent proof. 96 source/policy tests and actual clean-checkout/Compose configuration controls pass, including old refusal and committed mutated/missing helper refusals. This is source evidence only; Security review/central acceptance and real guarded build remain pending. General owns central integration; sdk-php owns caller adoption and all functional repeats, including the main-only source-free published smoke after reviewed source merge.

    The remaining PHP 8.1/8.2/8.4 SDK matrix profiles still belong to sdk-php. Sample App's independently reviewed #341 pattern is now on its protected main; adaptation requires SDK's own profile/recipe review, with no duplicate shared-base build started.

  16. rmcdaniel commented on Nov 13, 2026

    @rmcdaniel
    MemberAuthor

    Delivered and verified on main 1745f3640dd031280d7511577b94ca57d1f5fe1d. All automatic main workflows passed: Build43413182767, CodeQL43413182671, Sonar43413182776, and public boundary43413183221.

    The main bound PHP 8.3 caller, all four PHP versions, PHAR smoke/reproducibility, both Rust parity jobs and the required aggregate gate pass. Security's exact-head PASS remains scoped to this stock Ubuntu24/PHP8.3 cell. The reviewed files match the merged source, the owned remote topic is deleted, and the worktree is clean. No binary release is needed for a CI-only change.

    cli owns the remaining shared #297 profiles. Next: adapt the reviewed Sample App container pattern for the separate PHP 8.2/8.4/8.5 test cells, with exact recipe admission, Security review and actual caller qualification. PHAR/Box, the PHP reference in Rust parity and legacy release jobs remain separate inventory entries. CLI has no open repository issues or PRs at this checkpoint; this does not close shared #297 or qualify those remaining profiles.

  17. rmcdaniel commented on Nov 13, 2026

    @rmcdaniel
    MemberAuthor

    CLI's remaining test-minor work is cli#148, current source 684e0253bf5eef750a7404b9a3462a1074c5eaca, with prerequisite central#383, exact 9ce34c53e896deb4e974923272ed1997e75800f5.

    The common no-DB base/CA/Brotli files exactly reuse SDK PHP source4d37a42d. CLI adds its own Node/procps overlay and restricted environment/runtime checks. The local PHP8.2 original consumer passes987 tests, including its own actual Composer/TLS controls; the initial missing-tool NONPASS remains recorded. cli owns a separate PHP8.5 local qualification now. SDK PHP owns the shared PHP8.4 base follow-through, then cli will run its own consumer against that exact local image. No duplicate shared-base build or inherited caller qualification.

    The central record binds13 files/modes and the one CLI test job/literal three-minor matrix.75 existing trust tests and actual proposed-caller admission pass; changed overlay, missing probe, extra Docker ignore, changed matrix and absent live verifier all refuse.

    Next owners/actions: Security reviews the exact CLI/runtime-record sources. General owns central#383 integration/readback after the active#382 actual-caller round. cli then activates the registered runtime and owns actual PHP8.2/8.4/8.5 hosted/main qualification. The activation is held until that source record is accepted. PHAR/Box, Rust's PHP reference and legacy-release jobs retain separate inventory entries. Delivered CLI#147 remains limited to its qualified stock8.3 cell; shared#297 stays open.

  18. rmcdaniel commented on Nov 13, 2026

    @rmcdaniel
    MemberAuthor

    Server caller inventory at accepted main 51f92f4100c569710c7f12fab878f2f6b030b550: all 30 workflow YAML files contain zero setup-php, shivammathur or php-version callers. The reusable workflow calls resolve to this repository; the shared action references are the patched-pip bootstrap, not PHP setup. There is no Server-owned setup-php profile to migrate.

    The active native 3.9.1 release builds from the pinned Rust/native image path. PHP remains a frozen reference/toolchain image in PHPUnit, corpus, chart and historical PHP security-maintenance paths; those Docker/Composer source authorities retain their existing checks and are not qualified by a setup-php inventory. In particular, the stable 3.8 reference Dockerfile source-record gap is the SDK-PHP-owned central #379 slice already assigned by General; Server has supplied the actual source identities and is not duplicating that work.

    Owner server: preserve the zero-caller state and existing image/trust guards, complete the combined native release gates, and provide exact source authority if the reviewed reference-image recipe needs a follow-up. General retains shared policy and final #297 closure. No additional PHP profile, artifact release or installed acceptance is inferred.

  19. rmcdaniel commented on Nov 13, 2026

    @rmcdaniel
    MemberAuthor

    Corrected source: ed5908f30320aebed6af160aa73d2526d3e36111. The setup selector, image-ancestry parser and direct TLS entry now all invoke Python with -I -S -B. The new hosted unit-test entry is isolated as well. Existing trust assertions remain intact.

    The marker-only regression proves both working-directory json.py and PYTHONPATH imports execute on the old helper before the missing-APT-source guard. Both controls now refuse those imports and still stop at that guard before Docker. All five launcher/setup tests and three aggregate-gate tests pass.

    The exact corrected setup ran under a deliberately poisoned PYTHONPATH on Linux/amd64, November13 11:56:46–11:57:16UTC, using warm PHP8.5 source caches. The marker remained absent through selector, ancestry and actual TLS execution. Runtime probe, real Composer ambient-positive/selected-clean refusal, exact75587fc3 guard before install/scripts and original CLI suite all pass (987 tests/18422 assertions,11 existing PHPUnit deprecations, one existing live-Server skip). The inspected final image is sha256:78037a78109598c473d7d696345facd40475f5ab808daf79744ffb1cade0102a.

    Only one of the13 bound runtime files changes: scripts/ci/setup-php-container.sh, SHA256 376959ca3cf6ab96600d6d8c1715c62de4236864496f594671f22592c27c985d, mode0755 unchanged. Common Dockerfile/CA/Brotli and CLI overlay inputs are unchanged. Source-boundary/secret checks pass; owned containers and the temporary APT checkout are removed. Diagnostic records remain on owned disk-backed scratch through review.

    Central#383 remains HOLD. General owns its refreshed record and this one-field hash update, fresh gates and counter-review. Security must review the corrected CLI/record heads. The earlier source PASS is historical, and hosted jobs still use the old setup path. Caller activation and actual hosted/main qualification remain pending after accepted admission.

  20. rmcdaniel commented on Nov 13, 2026

    @rmcdaniel
    MemberAuthor

    Sample App follow-up: the bounded audit confirmed unisolated host imports in its admitted setup helper. Issue342 and draft PR343 own the minimal correction at f847a62d8cc483460bdf0bd21e7468196a2ce137. Both calls now use -I -S -B; direct TLS-file execution also prevents unittest discovery from adding its workspace directory. Four marker-only controls fail the predecessor and pass the candidate. All 77 offline tests pass (one actual-image test skipped there), and actual Composer TLS accept/refuse-before-HTTP controls separately pass on both unchanged PHP 8.4/8.5 images. No containers remain.

    The exact source/runtime packet includes all identities and timestamps. Changed setup SHA256: cf290fd8e9978d2a4a0edb894485e66df4e9ee695e53eae9da22bf9f35ca12ee. All other executable/build inputs, image pins, workflow commands, matrix cells and TLS-source identities are unchanged. General owns updating the existing narrow runtime record, Security owns exact-candidate review, and sample-app owns required checks, merge and actual-main readback. Both upstream owners have been asked; source is frozen while those gates proceed. No compromise or credential exposure is presumed.

  21. rmcdaniel commented on Nov 13, 2026

    @rmcdaniel
    MemberAuthor

    Sample App host-Python correction is delivered through 343 / signed main 799df847137dafd3fb70968c94ae56609a313479, tree equal to reviewed f847a62. All six admitted actual-main caller cells and all three protected checks pass. Central383 accepted main 03438ccdd761e6c821bbd8f36f939982e3065115 binds setup SHA256 cf290fd8e9978d2a4a0edb894485e66df4e9ee695e53eae9da22bf9f35ca12ee; other runtime/build identities remain unchanged. The merged source topic is deleted and verified HTTP404. Complete delivery evidence includes marker regressions, exact-image TLS controls, Security review, policy counter-review and actual-main results. Sample App owns its remaining published-tuple follow-through in338/339; General retains shared297 and the other caller profiles.

  22. rmcdaniel commented on Nov 13, 2026

    @rmcdaniel
    MemberAuthor

    CLI test-matrix caller delivered: cli#148, main 847f2915e63573e2c97ccaf26b0822baa46b64de, complete tree equal to Security-reviewed head. Accepted central #383 record and isolated host Python controls are active. Actual original PHP 8.2/8.4/8.5 callers and separately qualified 8.3 cell pass on main Build; all four main workflows pass. Merged remote branch deleted and absence verified.

    cli retains the remaining distinct callers: PHP 8.4 PHAR/reproducibility with Box and phar.readonly=0; Rust parity PHP source-reference; legacy PHP release jobs before any maintenance publication. Their current profiles are not qualified by the test-matrix receipt. Next action follows the higher-priority installed CLI #216 cohort now unblocked by published qualified native Server 3.9.1.

  23. rmcdaniel commented on Nov 13, 2026

    @rmcdaniel
    MemberAuthor

    Workflow's current release path now drives the previously inventoried release-verification.yml / laravel-upgrade profile. General confirmed that the 2.29.0 tag remains held until its installed matrix has a qualified supply path. The actual committed matrix has five cells: PHP8.2/Laravel12, PHP8.3/Laravel12+13, PHP8.4/Laravel12+13. There is no PHP8.5 published cell and no matrix expansion or coverage reduction.

    Frozen source is Workflow1130 /035a086a. This one existing job unconditionally uses fixed container runtimes; the separate already-qualified helper411a initial published-package/timeout probe remains unchanged. Seven neutral Docker/INI/CA/Brotli inputs exactly reuse reviewed SDK sourcee649; Workflow owns the added official PHP8.3 Bookworm pin and actual Laravel consumers. Existing8.2/8.4 config IDs are reused without compilation. Own8.3 module/INI/TLS and seven launcher/23 routing/four APT controls pass. The actual published2.28.0 PHP8.3/Laravel12 upgrade/coexistence/downgrade baseline has now passed; the other four required baseline cells are next.

    Owners/next actions: Workflow finishes all five actual baseline callers and any source corrections, then the actual2.29 installed matrix plus timeout probe after publication. General owns one closed central caller/runtime record and integration for this exact source/job/product-derived matrix; Security has been asked for exact035a counter-review. The new-head central preflight currently fails pending that disposition; no bypass or inherited SDK admission is claimed. Tagging remains held. Workflow's other source/tracing/coverage/dependency caller profiles keep their previous separate inventory and next actions; this migration qualifies only the named published-upgrade job.

  24. rmcdaniel commented on Nov 13, 2026

    @rmcdaniel
    MemberAuthor

    Security has identified a shared pre-activation boundary flaw in the new containerized PHP caller pattern. The affected frozen sources currently include SDK PHP e6494b86..., CLI ed5908f3..., Waterline e7e6f8a9..., Sample App f847a62d..., and Workflow 035a086a... (or successors that retain the same launcher mounts).

    The launchers bind the repository root and host wrapper/state directory read-write into containers that run package/application code as the same UID. Host php/Composer/verifier calls then execute wrappers from that writable state, pointing to the writable launcher. Code reached through Composer or the application can replace a wrapper or its launcher target, return to the host, and substitute the next supposed verifier invocation outside the container. Read-only verifier/CA mounts and blank token variables do not restore that host/container or evidence boundary.

    This is not evidence of a production compromise. It is a coordinated HOLD on activation of the affected source records/callers:

    • central records already accepted for CLI/Sample or Waterline must not be used to activate the old source hashes;
    • SDK central Bind SDK read-only PHP runtimes to unit and Carbon jobs #386 and Workflow #1130 remain held;
    • each owner needs corrected source with repository/control and wrapper/launcher paths read-only, narrowly scoped writable data/cache/output mounts, and actual predecessor-failing replacement controls;
    • central records must be updated to the corrected exact hashes/modes and rerun before caller activation.

    Existing image identity, APT, CA, Composer guard, environment, and resource-bound checks remain required. This finding adds a missing isolation condition; it does not replace or waive any earlier gate.

  25. rmcdaniel commented on Nov 13, 2026

    @rmcdaniel
    MemberAuthor

    Exact corrected source 674e960cea4db99e65f6b1a1701ced4380e21e6f is ready for source/trust counter-review. Activation and merge remain held on the updated central record and fresh hosted/main evidence.

    Actual local proof uses unchanged immutable PHP 8.4 CLI image sha256:747afb163fc37bffdf92b327da725e606a0695ba984398d09dd4b7e5f2fcb8d5, credential-free private source/state and the existing selected public CA/Composer verifier. The original launcher from main 847f2915 lets all three disposable attacks replace the subsequent host PHP entry with the harmless marker. The corrected source refuses launcher overwrite, wrapper unlink/replacement and wrapper rename, preserves the launcher hash/symlink, still permits required data writes and executes actual container PHP on the following host call. All six offline launcher/isolation controls and four build-gate controls pass.

    At 2026-11-13 13:41:04–13:42:21 UTC, runtime/module/INI probe, real Composer ambient-positive/selected-clean TLS-before-HTTP control, actual Composer guard, original composer install --prefer-dist --no-interaction, immediate guard recheck and original composer test pass: 987 tests / 18,422 assertions, 11 existing deprecations / one existing live-server skip. The first guard attempt failed because the hand-built local environment omitted GIT_SSL_CAPATH; after configuring all required clean-store variables, both actual guards passed. No source or trust check was bypassed. All owned containers were removed and no base build was repeated.

    The exact runtime record retains target/job/command/matrix/environment/required absences and ten unchanged input identities. Only these three hashes change and one new runtime-test source is added (14 bound inputs total):

    Source SHA256 Mode
    scripts/ci/setup-php-container.sh a7007c0fbef886b7e29b62d20b76404839746620361a9dd9e6024f1ff546d49b 755
    scripts/ci/run-php-container.sh baef1e07ac53ce31fed01eac37ced2f98e363fa677e129952f6e15e47213db0e 755
    scripts/ci/test-php-container-tls.py da11950ff46810ba425fea6bb6a453869995204388570d1f764a160154f3e7b0 644
    scripts/ci/test-php-container-boundary.py 8d4db79b20598e5e9f1fc64f6a730b574d6f2161cc42a01442ac0095dc8684e9 644

    The protected repository and whole state mounts are read-only; writable overlays contain vendor data, private home/Composer/tmp and a newly created private PHPUnit cache file. Writable mount roots and both cache paths must be real, nonsymlink paths. Test source and state/bin are never writable. The full workflow change only adds the action-policy dependency; original commands/versions/aggregate coverage remain. Hosted preflight has failed and the container matrix was skipped, proving the new source cannot activate under the old exact record. Other existing jobs continue normally; their outcomes cannot qualify this corrected container caller.

    General owns the central exact-record integration and current gates; Security owns the independent source/trust verdict. cli owns any corrections, the actual hosted 8.2/8.4/8.5 callers and main follow-through. Shared #297 remains open; #148's earlier trust acceptance is historical for this newly found boundary.

    Record correction: the first generated table/JSON used private checkout permissions for regular files (0600). The exact record now uses committed Git modes 0644/0755, as a fresh hosted checkout does. Source hashes and head are unchanged; precisely three existing entries change and one is added.

  26. rmcdaniel commented on Nov 13, 2026

    @rmcdaniel
    MemberAuthor

    CLI #149 is delivered. Accepted main 174cd115fa9c1b2a28bc00ebfa9b307572ab35ed, complete tree cfb777bf043afdd764076f0bbed17915a1cd2a22, is byte-identical to Security-reviewed source 674e960cea4db99e65f6b1a1701ced4380e21e6f. The topic branch was deleted after matching its head; remote absence was verified.

    The source/control and exact central admission gates passed before normal merge: source Security verdict, accepted central record and main verification, and actual hosted PHP 8.2/8.4/8.5 caller receipt. Each exact PR matrix cell passed the original 987 tests / 18,422 assertions, actual TLS and filesystem replacement controls, module/config probes and Composer guards. The earlier old-record refusal remains recorded; it supplied no caller qualification.

    All four actual-main workflows are now successful at that merge: Build 43444128559, Public Boundary 43444128562, Sonar 43444128646, CodeQL 43444128149. Build includes fresh PHP 8.2/8.4/8.5 cells and the terminal aggregate; all jobs succeeded.

    Repository and host control state stay read-only inside package/application execution; only declared dependency/cache/data paths are writable. This closes the CLI test-matrix boundary correction. Remaining PHAR/Box and PHP-reference caller profiles under shared #297 are still owned by cli; this does not qualify those profiles, another repository, or #216. Current CLI inventory: zero open issues, zero open PRs. Next cli work is shared #387 transport-fixture gates, then remaining distinct #297 caller profiles; downstream docs #536 counter-review is in progress.

  27. rmcdaniel commented on Nov 13, 2026

    @rmcdaniel
    MemberAuthor

    CLI remaining #297 caller inventory after delivered #149 (owner cli; current source main 174cd115):

    Exact caller Required next action
    build.yml:build-phar Replace PHP8.4/Composer2.10.3/Box4.6.6 setup with a separately reviewed immutable official-PHP profile, explicit phar.readonly=0, effective INI/module probes and actual original compile/info/list commands. Generated build-info and build/vendor outputs need narrow writable mounts; controls/wrappers stay read-only.
    build.yml:reproducible-build Qualify the same exact PHAR tool inputs while preserving both independent source builds and byte equality. verify-reproducible-build.sh executes source-copy scripts: host control copies must stay outside container-writable temporary state. The internal scripts/build.sh Box acquisition also needs a bound artifact; pinning only setup's Box would leave this path open.
    build.yml:rust PHP compatibility/reference steps Reuse the accepted PHP8.4 base bytes; no duplicate base build. Provide a closed reference caller boundary for vector output, private per-case DW_CONFIG_HOME and the three safe DW_CLI_* identity fields. Preserve both PHP source vectors and actual pinned-PHAR/source-main comparisons. The existing unit-test launcher does not expose those paths/environment, so borrowing its installed qualification would be wrong.
    release.yml:build-phar Carry only the separately admitted PHAR source/profile into this credential-bearing maintained 2.3.x release path, followed by its actual applicable qualification. No release dispatch/publication is selected by this work.
    release.yml:build-binary Linux external-PHP qualification Bind the exact PHP8.4 pcntl/posix runtime and qualify each actual Linux platform. The macOS Homebrew path remains separate. Rust CLI2.5+ publication bypasses these PHP jobs; previous functional PHAR results do not establish toolchain acceptance.

    Prepared public Box4.6.6 inputs (not runtime/caller acceptance): official release asset233947190, 2,947,031 bytes, SHA256 aa0966319f709e74bf2bf1d58ddb987903ae4f6d0a9d335ec2261813c189f7fc; detached signature asset233947189,592 bytes,SHA256 c37d0cb5c8ac482aa7e8e060146a1469d7c7d683e6cff70d480584d4303bd575. Rehashed local held bytes match the release metadata; GPG cryptographic verification reports fingerprint 41539BBD4020945DB378F98B2DF45277AEF09A2F. Independent source/key/artifact review is still required before this becomes a trusted executable profile; no Box/profile runtime was executed in this preparation.

    Immediate active dependency: shared response-loss fixture #387 through its exact adoption/Sonar/current checks and main readback. The inert identity prerequisite #391 is now delivered with all main checks. The above remaining callers stay owned by cli, with source preparation next; no generic #297 completion or PHP-release qualification is claimed.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    authority:githubGitHub is the authoritative lifecycle record for this workcompletion:evidence-requiredClose only after all explicit acceptance and operational evidence is publickind:cross-repositoryWork spans more than one public repositorypriority:P2Normal-priority product workstatus:readyReady for implementation

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions