Skip to content

child_process replacement under strict: host process broker row (KEL-76) with a child_process-shaped facade conforming to KEL-77 oracles — scope and owner #413

Description

@0monish

Generated by an AI agent (Claude Code, Fable 5.1) on behalf of @0monish during Wayfinder charting of the Electron compatibility program, 2026-10-06. Evidence-backed; every resolved decision was taken under explicit user delegation and cites its sources. Planning only — no implementation is authorized by this issue.

Parent map: #391 · Unit: X03 (node-bun-native-addons) · Wayfinder type: research · Status: open (not resolvable from current evidence)

Question

Both corpus apps spawn executables (draw.io: Windows attrib.exe + one execFile that tolerates failure; Zettlr: pandoc/quick-look). Under strict, raw spawn is never; a host process broker with executable allow-list + argument schema + cwd/env policy is proposed. Confirm KEL-76 ownership and the facade's KEL-77 five-oracle conformance; under legacy record Bun gaps.

What is known / why it is still open

No evidence-backed resolution yet; see the unit research note for the proposed answer and refuter verdicts.

Context

Epic #501 · research note wayfinder/electron-compat/notes/X03.md on the research branch.

Activity

  1. added theissue type on Oct 6, 2026
  2. 0monish commented on Oct 6, 2026

    @0monish
    MemberAuthor

    Generated by an AI agent (Claude Code, Fable 5.1) on behalf of @0monish, 2026-10-06, under the map's execution doctrine. Statements are labelled FACT / INFERENCE / UNKNOWN by their author; nothing here authorizes implementation.

    Decision packet

    Decision: Under the strict profile, a migrated main's Node child_process use is replaced by the host process broker row owned by KEL-76 with a child_process-shaped facade; the decision is who owns it and whether any of it is designed now.

    Classification: decided · Milestone (YAGNI test against the first proof): parked · Reversible: Yes. Parking writes no code and no contract; the owner can re-scope KEL-76 or name another owner at any time. · Owner: KEL-76 (Backlog, unassigned; owner STOP comments of 2026-08-19/20 stand) for the broker; KEL-78 (In Progress) for tool-child containment; KEL-77 (In Progress) for the lifecycle oracles. Linear, fetched 2026-10-06.

    Facts

    • LINEAR AVAILABILITY (for the swarm): Linear team KELD was live and readable for this whole run on 2026-10-06. list_teams returned KELD and GYLDLAB; get_issue succeeded on KEL-74, 75, 76, 77, 78, 79, 80, 86, 90, 97, 102, 127, 129, 142, 208, 212, 237; list_comments succeeded on KEL-76 and KEL-208; three list_issues searches succeeded. Zero failed calls, zero writes. The mempalace MCP server failed to connect (executable not found) and was not needed.
    • Architecture 05 section 3 defines a process module row ('scoped executable launch, env/stdio, child lifecycle and immutable process-tree snapshots') whose Electron facade is 'strict-profile child_process/utilityProcess broker facades', and states that KEL-76 must approve and ship real behavior for process/pty rather than placeholder identifiers (Keld main b4b907c, read 2026-10-06).
    • KEL-76 is in Backlog, unassigned, titled 'Native: guarded PTY/ConPTY service with compatibility facades'; its acceptance says 'Guard evaluates executable, args, cwd, env and principal before creating a PTY or child' and its out-of-scope line excludes 'a generic unrestricted child_process escape hatch' (Linear, fetched 2026-10-06).
    • KEL-76 carries two owner comments (2026-08-19 and 2026-08-20) saying STOP: no implementation, no PR, no worktree; post-v0 YAGNI until an approved spec with a real T1 (guard on executable/args/cwd/env/principal before any PTY or child exists) after role identity (KEL-75) is a live host path (Linear, fetched 2026-10-06). No KEL-76 spec file exists in docs/specs.
    • Live owner statuses: KEL-75 In Progress, KEL-77 In Progress, KEL-78 In Progress, KEL-97 (wire RoleRegistry into the host app-link) Backlog (Linear, fetched 2026-10-06).
    • The keld-native MODULES registry has no process or pty entry, and keld-guard has no consumer of a spawn grant (grep on main b4b907c).
    • Architecture 03 section 2's manifest example already spells a launch grant as app.shell.spawn: [{cmd, args: "reviewed"}]; architecture 05 names the module process. The two documents use different names for the same authority and neither is live.
    • draw.io imports spawn and execFile from child_process. Two spawn sites run attrib.exe (Windows only). One execFile runs PowerShell on Windows and fc-list on every other platform including macOS, with a 30 s timeout (drawio-desktop@2edf9fb main source, read 2026-10-06). The published ticket text calling the spawns Windows-only is wrong for the execFile.
    • keld-compat's AuthorityProfile already has the value user_approved_tool_child (keld-compat evidence module, main b4b907c).
    • Refuter probes (Bun 1.4.2, macOS arm64, not re-run by me): a runtime plugin never sees node:child_process; a node_modules package named child_process does not shadow the builtin; a preload that replaces the builtin's exports is observed by ESM and CJS importers.

    Inferences

    • Under the legacy first proof, Bun's own child_process serves the fc-list call, so the broker is not needed for that milestone. fc-list is not part of a stock macOS install, so the call most likely errors and draw.io resolves an empty font list; not executed by me.
    • The architecture 05 row and the KEL-76 issue title disagree about scope (process plus pty versus PTY only); the acceptance line 'PTY or child' suggests the issue intends both, but the title and the August comments discuss PTY only.

    Unknowns

    • Which mechanism delivers a child_process facade to app code under strict. The only probed path is a preload that replaces the builtin, which is a second injection mechanism with no named owner.
    • Containment profile of a host-launched tool child (pandoc for Zettlr) and the deputy-escalation negative control that KEL-78 requires.
    • Whether {shell: true} command strings (Zettlr run-command) are expressible as an allow-listed interpreter or are a documented refusal under strict.
    • Whether the grant is spelled under app.shell.spawn (architecture 03 example) or a process capability (architecture 05 module name).
    • The X03 semantics-lens refuter verdict for A5 was truncated in the task input and was not available to me.

    Alternatives

    Option Cost New invariant created Existing invariant at risk
    Host process broker under KEL-76 with a child_process-shaped facade, specified later inside the KEL-76 spec (recommended, parked) No work now. Later: one approved spec, a guard-before-spawn T1, a three-OS differential against Node; strict-profile Zettlr export stays unscored until then. Every executable launch from a strict role is a guard decision on executable, args, cwd, env and principal, and the launched child is labelled user_approved_tool_child in evidence. None while parked. When built: the preload shim must stay compatibility routing only, never enforcement (OS denial under KEL-78 remains the boundary).
    Design the broker and facade now, ahead of the first proof Speculative design against an owner that has an explicit STOP comment and no live role identity path (KEL-97 Backlog); violates the YAGNI test. None that the first proof needs. Spec plus Linear gate; KEL-76's recorded 'do not pick up'.
    A polyfill that throws under strict with no broker Zettlr export and draw.io Windows backup paths fail at first use with no migration path. child_process is a documented refusal under strict. None for security; compatibility promise for the second corpus app.
    A generic process.spawn: true capability None to build; hands the role ambient launch authority. A boolean grant that names no executable. Default-deny; KEL-76's explicit out-of-scope line; unique two (zero ambient OS authority).

    Recommendation

    Close the open question as decided and parked. Owner is KEL-76 per architecture 05; nothing is designed before the first proof. Correct the ticket's corpus fact (fc-list on macOS and Linux, failure tolerated). Record the four unknowns above as required contents of the future KEL-76 spec, with brokered launches labelled user_approved_tool_child. Under legacy, the only first-proof action is that the PANEL-P3 (#420) boot trace records the execFile row and its outcome under Bun.

    Falsifier: The PANEL-P3 (#420) trace shows the draw.io macOS install, activation or 4-step workflow failing because of a child_process behavior that Bun's built-in does not provide under legacy; or the KEL-76 owner states in Linear that non-PTY process launch is out of scope for that issue.

    Missing evidence: An owner statement on KEL-76 confirming that the non-PTY process row is in scope; an executed fc-list observation on macOS under Bun (covered by PANEL-P3 (#420)).

    Next action: Orchestrator (single Linear writer) posts one comment on KEL-76 quoting the architecture 05 process row and asking the owner to confirm the non-PTY row is in scope or name another owner; first completion check is an owner reply on KEL-76, after which #413 is closed as decided and parked with the corrected fc-list fact.

  3. added
    milestone:parkedParked by the YAGNI test until a current requirement proves it
    on Oct 6, 2026
  4. 0monish commented on Oct 6, 2026

    @0monish
    MemberAuthor

    Generated by an AI agent (Claude Code, Fable 5.1) on behalf of @0monish, 2026-10-06, under the map's execution doctrine. Statements are labelled FACT / INFERENCE / UNKNOWN by their author; nothing here authorizes implementation.

    Resolution

    Close the open question as decided and parked. Owner is KEL-76 per architecture 05; nothing is designed before the first proof. Correct the ticket's corpus fact (fc-list on macOS and Linux, failure tolerated). Record the four unknowns above as required contents of the future KEL-76 spec, with brokered launches labelled user_approved_tool_child. Under legacy, the only first-proof action is that the PANEL-P3 (#420) boot trace records the execFile row and its outcome under Bun.

    Falsifier (reopen if observed): The PANEL-P3 (#420) trace shows the draw.io macOS install, activation or 4-step workflow failing because of a child_process behavior that Bun's built-in does not provide under legacy; or the KEL-76 owner states in Linear that non-PTY process launch is out of scope for that issue.

    Resolved under the user's delegation on the evidence in the decision packet above, after independent refutation of the underlying research. Reopen by comment with contrary primary evidence.

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

    electron-compatElectron compatibility program areamilestone:parkedParked by the YAGNI test until a current requirement proves itwayfinder:researchWayfinder research decision

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions