Skip to content

feat(conformance): lifecycle-family tracer and shared Electron-arm recorder for the two-arm harness — main-process lifecycle fixtures (including first-launch activate) recorded under verified Electron 44.4.5 on macOS arm64, replayed under @keld/elect #495

Description

@0monish

Generated by an AI agent (Claude Code) on behalf of @0monish during Wayfinder charting of the Electron compatibility program; rewritten 2026-10-07 by the doctrine-audit repair pass (change log at the end). Planning only — no implementation is authorized by this issue.

Parent

Epic #493 · Map #391 · Unit X01 · Kind: feature · Tier: Tier 1 · Maturity target: L2 · Size: L · Milestone: next

What to build

Implement the X01-T1 harness for main-process-only lifecycle fixtures: quit order, before-ready, the window-all-closed control, and whether activate is emitted at first launch on macOS (the F01-T10 launch-time cell).

  • Record goldens on macOS arm64 with a developer command that runs the SHA-256-verified 44.4.5 zip. It refuses to run when the zip is absent or mismatched.
  • The recorder command accepts any fixture packaged per X01-T1, including one with a CommonJS preload and a static page, and captures its renderer rows. F03-T6, F04-T20 and F08-T3 own their family fixtures and record them through this command. Keld-arm replay and comparison here stay main-process-only.
  • Commit goldens, manifest and receipts through the shared X01-T4 manifest owner.
  • Replay under @keld/electron inside the keld-compat test target.
  • Compare with declared normalisers and emit KEL-74 records.
  • Own each arm as a child process that is killed and reaped on timeout.
    The conformance entries for these members belong to F01-T1. This ticket supplies only their recorded evidence-of-record.

Spec gate: the first deliverable is a spec from docs/agents/spec-template.md, opened as a PR and stopped for human approval; implementation starts only at Status: approved.

Acceptance criteria

  • The keld-compat test target replays every committed lifecycle golden offline on each OS lane that has a golden (macOS arm64 first); a lane without a golden emits unknown for that cell and is never skipped
  • A golden with two rows swapped fails the comparator, and a one-byte change to the manifest fails the exact-bytes digest assertion
  • A transcript field that varies between the golden and the replay without a declared normaliser fails the comparator deterministically with a named undeclared-nondeterministic-field error
  • Every record carries authority_profile legacy_sandbox_off, the corpus's declared engine identity, and the v44.4.5 tag commit as oracle revision; every receipt carries the darwin-arm64 zip SHA-256
  • A cell with no doc citation is emitted unknown, never pass
  • A fixture that fails to link in the Keld arm because of a missing named export is recorded fail with a KELD code, and the other fixtures still run
  • When an arm hits the kill-switch timeout, its process is killed and reaped before the test fails, so no Electron or Bun child outlives the test
  • The committed lifecycle goldens include a first-launch activate fixture whose transcript records whether activate is emitted at first launch and its position relative to ready
  • The recorder command records a fixture with a CommonJS preload and a static page, and the resulting golden contains rows whose process field is the renderer

Negative controls (each names the one mutation that must fail)

  • Removing the pid normaliser declaration while the pid field still varies fails with the named undeclared-field error rather than flaking
  • Swapping before-quit and will-quit in a copy of the golden fails the comparator
  • Changing the comparator to emit pass for an uncited cell fails the observed-only criterion
  • Removing the kill-on-drop guard leaves a live child after a forced timeout, which fails the reaping criterion
  • Deleting the first-launch activate fixture fails the activate-golden criterion
  • Capturing only main-process output drops the renderer rows and fails the renderer-capture criterion

External predecessors (outside this tracker)

  • Electron v44.4.5 release SHASUMS256 darwin-arm64 line a212eee63ba2f45fd83bd28f77a3e3313a336ad17a4c25adf617942eef5e0e2c (external fact, fetched 2026-10-07)

Ownership and gates

The authoritative agent contract is the latest Agent Brief comment on this issue (triage skill); this body is the planning record.

Out of scope

Keld-arm replay, comparison and scoring of renderer/preload/BrowserWindow cells (no Keld arm exists yet). The family fixtures and their cells, owned by F03-T6, F04-T20 and F08-T3. Corpus apps: the X02-T4 manifest and the X02-T6 scoring run. The scheduled lane (X01-T5). Fixing the keld-core quit-in-progress state (F01-T3).

Notes

Not a gate for X02-T4 or X02-T6: the product cells reuse the KEL-237 runner pattern, and the X02-T6 scoring run consumes the X01-T4 validator, not lifecycle goldens. The X02 repair owner removes any edge to this ticket. The members recorded here (ready, before-quit, will-quit, quit, window-all-closed, and first-launch activate) are owned and counted by F01. The live waiter's orphan-child leak in the existing lifecycle test is a KEL-237 defect. This ticket's new runner must not inherit it. Known agent-shell trap: with CLAUDECODE=1, Bun hides passing test names (KEL-237 comment 6964244b), so run gates with CLAUDECODE and AI_AGENT unset, as hosted CI does.

Change log (doctrine-audit repair, 2026-10-07)

  • Milestone set to next (critic yagni X01-T2; X02 critic: the first proof's product cells do not consume lifecycle goldens).
  • Negative control replaced: an undeclared varying field must fail deterministically with a named error, not flake (critic quality X01-T2).
  • AC1 scoped to the OS lanes that have goldens; unrun lanes emit unknown (critic quality X01-T2).
  • Narrowed to main-process-only fixtures, because the Keld arm has no preload, renderer or BrowserWindow (refuter A2 lens-2 correction 3; sequencing/sizing extra finding).
  • Recording is a developer command that runs the verified zip; the weekly lane moved to parked X01-T5 (rule 2 split; refuter A4 corrections).
  • Added the reaping criterion: the live waiter panics without killing the child, re-checked as FACT (refuter extra 'reaping gap'; X01-A5 packet unknown).
  • Added observed-only = unknown and link-failure = fail criteria (refuter A1 corrections; exports-only-app extra finding).
  • Edges added: X01-A5 (critic PANEL-P3 edge finding) and X06-D7 (no live owner; X06-D6/D7).
  • Recorded that X01-T2 is not a gate for X02-T4 (critic edge finding X02-T4).
  • External predecessors named as task-level artifacts (program-wide finding).
  • Removed X06-D7 from blocked_by_keys: Linear owner for repo-writing Electron-compat slices (owner decision: align to nearest Linear issue, else GitHub is the tracker of record) #517 is CLOSED (gh, fetched 2026-10-07) with an adopted resolution; rule 4 forbids a closed decision as a blocker. Its resolution is consumed as text in linear_owner (GitHub issue is tracker of record; Linear reference on KEL-237, fallback KEL-127) (cross-checker finding: blocked_by names a closed decision).
  • Notes and out_of_scope now name X02-T6 as the scoring run alongside the X02-T4 manifest, since X02-T6 is the ticket that flips the product cells (cross-checker finding: X02-T6 is the flipping ticket).
  • title set: C9-recordings residual 2 (nobody owns producing the recordings): X01-T2 now records first-launch activate and its recorder command is the one family tickets record through (final residual fix C9-recordings)
  • what_to_build replace: C9-recordings residual 2: F01-T10 AC4 says the activate cell stays unknown until X01-T2 records it, but activate was not in X01-T2's fixture list (final residual fix C9-recordings)
  • what_to_build replace: C9-recordings residual 2: no ticket recorded webContents, IPC or diagnostics transcripts; the family tickets own their fixtures, and this recorder must be able to run them on the Electron arm (final residual fix C9-recordings)
  • acceptance_criteria add: C9-recordings residual 2: makes the activate recording and the renderer-capable recorder observable (final residual fix C9-recordings)
  • negative_controls add: C9-recordings residual 2: one single-mutation negative control per new criterion (final residual fix C9-recordings)
  • out_of_scope replace: C9-recordings residual 2: only the Keld arm stays main-process-only; the Electron-arm recorder accepts renderer fixtures that the family tickets own (final residual fix C9-recordings)
  • notes replace: C9-recordings residual 2: activate at first launch joins the recorded members (owned by F01-T10) (final residual fix C9-recordings)

Activity

  1. added theissue type on Oct 6, 2026
  2. added
    electron-compatElectron compatibility program area
    compat:tier-1Electron compat Tier 1 (arch 04 §4)
    needs-specNeeds an approved docs/agents/spec-template.md spec before implementation
    on Oct 6, 2026
  3. added
    milestone:nextNeeded after the first proof (Zettlr or strict profile)
    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.

    Doctrine audit findings for this issue

    • Quality: Negative control 'removing the normaliser declaration makes a pid-bearing row flake — the design test must fail deterministically instead' is self-contradictory. AC1 demands replay 'on all three OS lanes' for goldens recorded on macOS only. → Fix: Negative control: a golden containing an un-normalised pid field fails the comparator with a named 'undeclared nondeterministic field' error. Scope AC1 to the lanes that have goldens.

    YAGNI classification: next — Lifecycle-family recorder + replayer + comparator; the first proof's product cells do not consume recorded lifecycle goldens (the X02-T4 (#500) edge to it is not a real gate).

    Disposition: each finding stays open on this issue until its fix is applied to the body or refuted with evidence.

  5. changed the title [-]feat(conformance): recorder + replayer + comparator for the app-lifecycle family (first end-to-end cells) with the committed goldens[/-] [+]feat(conformance): lifecycle-family tracer and shared Electron-arm recorder for the two-arm harness — main-process lifecycle fixtures (including first-launch activate) recorded under verified Electron 44.4.5 on macOS arm64, replayed under @keld/elect[/+] on Oct 6, 2026
  6. 0monish commented on Oct 6, 2026

    @0monish
    MemberAuthor

    This was generated by AI during triage.

    Triage Notes

    What we've established so far:

    • The slice is specified in the issue body (what to build, binary acceptance criteria, negative controls, ownership and gates).
    • Milestone next; tracker of record as stated in the body.

    What we still need from you (@0monish):

    Once those resolve, this ticket moves to ready-for-agent with an Agent Brief.

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

    compat:tier-1Electron compat Tier 1 (arch 04 §4)electron-compatElectron compatibility program areaenhancementNew feature or requestmilestone:nextNeeded after the first proof (Zettlr or strict profile)needs-infoWaiting on more informationneeds-specNeeds an approved docs/agents/spec-template.md spec before implementation

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions