Skip to content

backends: resolve the exec wrapper from the host's app config instead of process.env #1429

Closed

Description

@schlessera

Current verification handoff — 2026-10-22

Root-reviewed local source is retained at d6e1e88990c30d422b1cb746e50756f9f7258657, tree f8d39cb4ecb0b5dba7e17ece3c26262d7cb6b2d6, selected base b17e349b7c8ff0f69c4cade3a953c86008d3ede8. Draft #2397 still preserves remote head f462a8f84bbe1d296a55c1f3f45e8d8475c6ab04; the local candidate is not published. Normal ancestry retains that original head and b17. This issue stays open with required verification incomplete.

The maintainer ruling explicitly removed #2396 as a blocker. Its historical native exit-137 preflight failures remain failed and its quiet controls remain NONREPRO. That ruling does not clear the new setup failure below.

Local source carries the host configuration through both backends, preserving explicit-empty and late omitted fallback. R1 corrected actual worker helper visibility and pre-relay initialization ordering: five expected behavioral reds on fd46, then 5 passes / 28 assertions on 40528. R2 rejects direct/symlink directory helper targets before relay acquisition and either read view: eight intended refusal reds on 40528, then 13 passes / 60 assertions on 7627. The following typecheck exposed a missing required restricted field in the new ordinary test fixture. Current d6 adds only restricted: false; product bytes and assertions remain unchanged. Current 13-case proof, strict types and API generation pass, with no tracked API delta.

Current required default preflight remains failed/incomplete. Hygiene/environment/changeset checks and 744 fast invariants / 4,704 assertions across 36 files pass. Import-graph feedback was stopped after 1,167 observed pass lines and one setup-hook failure in draft-runtime.test.ts at 180005.85 ms. Its last retained build state is ui-backend-pi TSC start about 173.733 s from setup start, with no recorded compiler exit. The cause of the overrun is unknown; no deadline extension or retry occurred. #2279 already covers this 180 s hook/build class; #2458's invocation-scoped build correction remains draft. Existing foreign custody must disposition the receipt before any new writer/proof allocation; no formal dependency or ownership change is made by this handoff.

The actual default plan selects 48 changed paths, 7 affected packages, 36 fast-invariant files and 1,076 complete-suite paths. All six hosted categories and packing qualification remain pending. The earlier 40528 batch (151 tests / 576 assertions, including both provider-history files) is historical context rather than current-head qualification. Original f462 preflight (730 fast; 3,378 feedback passes / two native exit-137 failures), older 4,362-test proof and all cancellations retain their source/outcome identities.

Found while working #1363. Part of #1343. Delivered #1363/#1430 is prerequisite context; per-app state #1364 stays separate. Milestone 0.44.0 is retained.

Context and scope

The pinned b17 baseline diagnosis has five ambient-resolution edges: Claude module runtime probe, SDK spawn and per-turn runtime probe; Pi grep and bash. Two apps configured with different host wrappers could therefore spawn with one process-wide ambient wrapper. Use existing BackendModuleContext and backend factory/probe paths; do not add a registration/configuration seam. The local candidate described above implements this propagation and its narrowly attributed worker-view/refusal corrections; publication and full verification remain open.

Baseline source coordinates verified against b17 (historical diagnosis, not current candidate call contents):

  • Claude (resolveExecConfig(), packages/ui-backend-claude/src/module.ts:170), (createWorkerSpawn, packages/ui-backend-claude/src/sdk-options.ts:356), and (exec: resolveExecConfig(), packages/ui-backend-claude/src/turn-runner.ts:416).
  • Pi (const exec = resolveExecConfig();, packages/ui-backend-pi/src/tools.ts:385) and (const exec = resolveExecConfig();, packages/ui-backend-pi/src/tools.ts:566).
  • Existing context (export interface BackendModuleContext, packages/ui-sdk/src/server/backend-module.ts:96).

Out of scope

New configuration/extensibility APIs, dependencies, provider-facing notes or changed history; weakening permissions, masks, argv validation, deadlines or offline/native/browser guards; unrelated ui-server spawning work owned by #1363; adopting another active implementation or changing its custody. Host-owned helper targets remain stable through launch; no generalized TOCTOU framework is selected.

Acceptance criteria

  • Two differently configured apps in one process use wrapper A/C while ambient configuration names B. Exercise real backend spawn paths with controlled keyless collaborators and observe executable/argv at the lowest shared boundary; context-object or validator-only tests are insufficient.
  • Cover Claude module runtime probe, per-turn probe and SDK spawn, plus Pi grep/bash and worker initialization, through standalone factories and module construction.
  • Explicit host configuration, including {}, remains authoritative. Omitted standalone configuration retains late ambient fallback: change B to C after construction and observe C at the next actual turn/worker boundary. Pi selects once per worker and serializes that selection into worker-local tools.
  • Remove host propagation at an actual call site, observe its named intended assertion fail, then restore; retain the existing original controls. Audit sibling ambient-resolution occurrences rather than fixing one instance only. The source search for resolveExecConfig() in both backend source trees must return no no-argument calls; that search remains supporting evidence alongside runtime controls.
  • Helpers required by worker-local execution are visible in ordinary and restricted views without exposing parents/private siblings. Regular-file aliases retain real worker execution and killer cancellation. Nonregular targets in either role are refused before relay/worker acquisition. Relative ambient errors start no relay. Preserve actual refusal and positive execution oracles.
  • Preserve existing permissions, credential selection, provider-history append-only behavior, abort/error classification, cleanup and original deadlines. Tests use no real provider credential or external network and restore environment/doubles completely.
  • Run the required backend/server verification suites, strict typecheck, API report and selected current PR proof. Failed, cancelled and unexecuted proof stays explicitly incomplete.
  • Optional backend context/factory fields are additive supported API: retain the contract index/component, reviewed three public signature reports and the appropriate minor changeset. No breaking change is approved.

Verification

bun run test packages/ui-backend-claude packages/ui-backend-pi packages/ui-server
bun run typecheck
bun run api-report
bun run check:pr --base <explicit-reviewed-base>

Use exact tested source/base identities and complete selected hosted job checkouts. Existing failing-first/mutation and final 13-case receipts are retained; this handoff allocates no runtime replay or corrective source change.

Contract impact and remaining action

Additive optional exec configuration through existing supported context/construction types; four-package minor changeset retained. No provider-facing conversation or compatibility shape is intentionally broken.

Next action: root routes the retained setup/build evidence to existing #2279/#2457 coordination for disposition of #2458 and its outstanding proof. Explicit custody is needed before further work on those foreign scopes. No new issue is proposed for the already-covered class, and no previous failure is waived. Full current proof, source publication, milestone readback, matching-head integration and automatic-main verification remain outstanding.

2026-10-22 proposed body correction: folds the explicit #2396 blocker-removal ruling into current state, records local source/R1/R2/type correction and exact new failed preflight, and preserves original acceptance obligations and historical outcomes. No new dependency, assignment, readiness or cause ruling is made.

Activity

  1. added
    type: fixSomething is broken and must behave the way it is documented.
    area: backendsAgentBackend implementations and the seam they share.
    priority: p2Wanted, not scheduled. Pulled in when a milestone has room.
    securityAuth, isolation, egress, secrets, or anything in the threat model.
    on Oct 9, 2026
  2. added
    area: ui-sdkWire protocol, runtime schemas, the server and client SDK surfaces.
    area: ui-serverHono app factory: turn coordinator, auth, session catalog, routes, cron.
    contractTouches the integration contract: CONTRACT: commit, contract doc updated in the same commit.
    blockedWaiting on another issue or an upstream dependency. Say which in the body.
    agent-readyContext and acceptance criteria are complete enough for an agent to take this unattended.
    on Oct 9, 2026
  3. schlessera commented on Oct 9, 2026

    @schlessera
    OwnerAuthor

    Unblocked: #1363 is closed, so scripts/sync-project.ts is removing the blocked label.

  4. removed
    blockedWaiting on another issue or an upstream dependency. Say which in the body.
    on Oct 9, 2026
  5. added
    priority: p1Scheduled into the current or next milestone.
    and removed
    priority: p2Wanted, not scheduled. Pulled in when a milestone has room.
    on Oct 17, 2026
  6. schlessera commented on Oct 17, 2026

    @schlessera
    OwnerAuthor

    2026-10-17 priority reconciliation: raised to priority: p1 as a required open child of P1 epic brain-kit#1343. This applies the maintainer's blocker-priority ruling recorded in AGENTS.md and the request to align P1 epic subissues. Required unfinished children block their epic's outcome. Existing ownership, scope, readiness, dependencies and release commitments remain unchanged.

  7. 5 remaining items

  8. schlessera commented on Oct 17, 2026

    @schlessera
    OwnerAuthor

    Continuation receipts for claim p1-1429-20261017-k6w3:

    • Preserved implementation f7f3b3f1d390081ac54aa52dccb4389316d86ecc on base 0d780605fe1ea9a281cce947b1f0074f3f3e7acc completed the required Claude/Pi/server suites: 4,362 pass, zero fail, 28,452 assertions across 386 files. Both app-level wrapper cases and both provider-history guards passed. This is the original candidate's receipt, not proof of a later combined tree.
    • Fresh main 498270fbdc4ef2788fdd3babb259b647d77f6c77 (CONTRACT: fix(ui-sdk): qualify separate-UID native maintenance inputs #2361) changes app/worker/maintenance inputs. Integrated it as db37ddcb6a47c5255bb2d15fc8875329b4ec9482, preserving the implementation. Reconciled four citation conflicts and additional moved citations against actual source. The app delta against main remains only the two host exec propagation changes.
    • The combined candidate passes 87 focused tests / 328 assertions across six files, including actual app A/C turns, explicit empty/omitted behavior, Claude probes/SDK argv, Pi grep/bash/worker init and all decision citations. Removing SDK host exec propagation again failed the named SDK_WORKER_HOST_ARGV assertion; byte-for-byte restoration passes 1 test / 22 assertions.
    • The native-diagram qualification self-test passes on the original candidate (1 test / 13 assertions). Neither backends: resolve the exec wrapper from the host's app config instead of process.env #1429 nor the integrated main change modifies its frozen source families/pins; current local evidence does not establish ci: native diagram qualification self-test rejects legitimate source drift #2365 as a blocker here. Full selected hosted proof remains required.
    • The first continuation preflight failed its leakage gate on owned artifacts left inside the checkout by the cancelled campaign. Those artifacts were moved intact outside the source tree; the strict leakage gate now passes. It finished before the planned cancellation and is retained as failed, not cancelled. Earlier exit-137, quota/body-restoration and incomplete suite history remain unchanged.

    Dependencies now use frozen private file copies. Combined strict typecheck, API-report and mandatory preflight are in progress; no current-candidate hosted proof or merge is claimed. Local cgroup memory/pids/CPU controls were reported unavailable; passing native/rlimit tests do not qualify those absent controls.

  9. schlessera commented on Oct 17, 2026

    @schlessera
    OwnerAuthor

    Compatibility correction within #1429: the partial factory implementation snapshotted omitted ambient exec at construction, although the baseline resolves it at turn/spawn boundaries. Fresh controls that switch ambient B to C after construction fail the intended OMITTED_HOST_EXEC_REMAINS_LIVE (Claude SDK argv) and PI_WORKER_OMITTED_EXEC_REMAINS_LIVE (Pi worker init) assertions.

    Factories now preserve omission and clone only explicitly supplied exec. Claude keeps its existing per-turn fallback; Pi resolves the host fallback for each worker-init payload, while direct Pi tools retain their existing spawn fallback. Explicit host configuration and {} remain authoritative. Restored focused proof passes 87 tests / 328 assertions; repeated SDK propagation removal still fails SDK_WORKER_HOST_ARGV and restoration passes 1 test / 22 assertions. Strict types/API-report are running before committing the correction.

    The earlier cd980abec preflight passed 730 fast invariants and several real-browser controls, then was deliberately stopped for this compatibility correction. Its descendant processes were captured and verified stopped before the new repros; that overall preflight remains incomplete. Required preflight and hosted proof must qualify the final corrected candidate. The body now makes this existing compatibility requirement checkable; scope, ownership and earlier failed receipts are preserved.

  10. added
    blockedWaiting on another issue or an upstream dependency. Say which in the body.
    on Oct 18, 2026
  11. schlessera commented on Oct 18, 2026

    @schlessera
    OwnerAuthor

    Terminal blocked handoff for campaign claim p1-1429-20261017-k6w3: draft PR #2397 preserves head f462a8f84bbe1d296a55c1f3f45e8d8475c6ab04, original f7f3b3f1d and compatibility correction b4cf5234c. Required preflight completed exit 1 (730 fast passes; 3,378 feedback passes / 2 native CLI exit-137 failures). #2396 is the P1 diagnostic prerequisite. Bounded isolated controls pass but do not establish a cause or replace the failed broad receipt. No blind green retry or gate relaxation was used.

    Focused corrected proof: 87 pass / 328 assertions; strict types/API-report pass; named intended-red compatibility and SDK propagation controls restore to green; final provider-history guards 25 pass / 135 assertions. Older 4,362-test proof belongs only to its original tree, and historical failures/cancellations remain distinct. Target main advances proof inputs; complete selected current-candidate hosted proof and merge remain missing. See the issue's active handoff and PR for exact identities and remaining actions.

    No competing ownership was found on fresh claim reconciliation. Releasing only this campaign's assignment; the issue stays open and blocked, with its existing release milestone. The preserved branch remains available for resumption. Nonblocking pre-existing citation work is separately recorded in #2383.

  12. removed their assignment
    on Oct 18, 2026
  13. removed
    blockedWaiting on another issue or an upstream dependency. Say which in the body.
    on Oct 21, 2026
  14. schlessera commented on Oct 21, 2026

    @schlessera
    OwnerAuthor

    2026-10-21 (maintainer-approved triage, 2026-10-21): dropped Blocked by #2396. That attribution is a single local exit-137 observation in the leaked-mount period, with no hosted occurrence, and is now an ordinary p2 item. This issue proceeds on its own required proof.

  15. schlessera commented on Oct 22, 2026

    @schlessera
    OwnerAuthor

    Session takeover handoff — 2026-10-22

    This session has ended; all workers, runtime processes and workspace leases are drained. Its coordination hold on #1429 / draft #2397 is released for takeover after fresh claim/metadata checks. This does not release the existing #2279/#2457/#2458 coordination or any other owner's work. No completion or readiness is claimed.

    The clean unpublished branch is fix/1429-root-source-b17-r1, head d6e1e88990c30d422b1cb746e50756f9f7258657, tree f8d39cb4ecb0b5dba7e17ece3c26262d7cb6b2d6, checkout /var/tmp/1429-source-reconcile-20261022/checkout. It descends normally from original remote f462a8f84bbe1d296a55c1f3f45e8d8475c6ab04 and frozen base b17e349b7c8ff0f69c4cade3a953c86008d3ede8. The remote is unchanged; never force-push or rebuild this contribution from only the old remote. Full current patch and proof index are in /var/tmp/1429-fixture-type-fix-20261022-r1.

    Preserved repairs: late omitted ambient fallback versus explicit {} across both backends; real Pi worker wrapper/killer visibility without exposing parent directories; validation before relay acquisition; refusal of directory/symlink-directory helper targets. R1 had five intended red failures then 5 passes / 28 assertions. R2 had eight intended red failures then 13 passes / 60 assertions. The final test-only restricted: false correction has 13/13 passes, clean strict types and API generation without tracked changes. Prior 151-pass provider-history/backend/shutdown proof belongs to 40528, not silently to the final head.

    Current blocker: required default preflight is failed/incomplete. It passed 744 fast tests / 4,704 assertions, then draft-runtime beforeAll exceeded its original 180-second setup deadline during its mandatory package build. The Pi TSC child started about 173.733 seconds into that budget; its exit is not recorded. Builder 143 preceded output EOF by 44.442 seconds. Cause remains unknown; 1,167 observed feedback passes plus one hook failure are partial counts, not a completed suite. No unchanged retry or deadline increase followed.

    Next action: existing #2279/#2457 coordination must disposition this exact build/setup recurrence against #2458's scope and provide any required explicit custody handoff. The request and evidence are already posted. Later app-close cancellation criteria do not automatically cover this pre-startup failure. Do not take over their active work, invent a causal waiver or attach a speculative build fix here. The maintainer's removal of older #2396 blocking status does not clear this new failed preflight.

    Takeover evidence: /var/tmp/1429-r1-fix-20261022-r1/report.md, /var/tmp/1429-r2-fix-20261022-r1/report.md, /var/tmp/1429-fixture-type-fix-20261022-r1/report.md, /var/tmp/1429-readonly-build-handoff-20261022-r1/report.md and /var/tmp/1429-publication-20261022-r1/report.md. All 115 original custody hashes and old failures remain preserved. Partial fixture-build outputs are not reusable qualified output. Revalidate the private install/environment rather than copying foreign outputs. Successful current preflight, complete selected hosted/type/pack/provider-history proof, publication, matching-head merge and automatic-main verification remain outstanding. Keep the PR draft and #2284 stopped.

    Local takeover index: /var/tmp/release044-session-handoff-final-6czoa6tr/HANDOFF.json. If these machine-local artifacts are unavailable, recover the original source/receipts or requalify; comment summaries are not substitute raw proof.

  16. schlessera commented on Oct 22, 2026

    @schlessera
    OwnerAuthor

    Resuming #1429 / draft #2397 for 0.44.0. Claim token: release044-1429-r2-opus. Branch: fix/1429-host-exec-k6w3 (published head f462a8f84). The unpublished d6e1e889 candidate is not available to this session, so its R1/R2 worker-view and refusal corrections will be re-derived from the published head and requalified, with fresh failing-first receipts. Earlier receipts keep their original identities.

  17. self-assigned this
    on Oct 22, 2026
  18. schlessera commented on Oct 22, 2026

    @schlessera
    OwnerAuthor

    Status for claim release044-1429-r2-opus: draft #2397 now has head f5684ceddacceafdf7292d675b753264507bb471, which merges origin/main at aa8c8966b and includes #2377. The worker-view corrections have been re-derived and pushed: helper files are visible in ordinary and restricted Pi workers, validation runs before any relay, and nonregular helpers are refused (including an ordinary Claude wrapper). They come with a fresh failing-first receipt (12 intended reds) and six restored mutations. Default check:pr passed on this head (run 4: 744 fast, 3,503 / 0 feedback). Two earlier runs on the same head each hit one intermittent failure outside this diff, recorded as #2655 and on #2412. Draft gates are green. Hosted ready-candidate proof, confirmation and merge remain coordinator-owned. Receipts are in the PR body.

  19. schlessera commented on Oct 22, 2026

    @schlessera
    OwnerAuthor

    Delivered by #2397 (squash aeaaf77, CONTRACT:). Both backends now resolve the exec wrapper and killer from the host's app config instead of process.env. Each helper file is mounted read-only into the governed, strict and restricted views (the file, never its directory), and a directory wrapper or killer is refused up front. Failing first: the new real-bubblewrap worker-host-exec.test.ts gave 12 intended failures against the published code; with the fix, 13 pass. Six mutation receipts are in the PR. Hosted verification: main CI on the merge passes (https://github.com/schlessera/brain-kit/actions/runs/39803872921).

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

Metadata

Metadata

Assignees

Labels

agent-readyContext and acceptance criteria are complete enough for an agent to take this unattended.area: backendsAgentBackend implementations and the seam they share.area: ui-sdkWire protocol, runtime schemas, the server and client SDK surfaces.area: ui-serverHono app factory: turn coordinator, auth, session catalog, routes, cron.contractTouches the integration contract: CONTRACT: commit, contract doc updated in the same commit.priority: p1Scheduled into the current or next milestone.securityAuth, isolation, egress, secrets, or anything in the threat model.type: fixSomething is broken and must behave the way it is documented.

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions