Context
Split from #15684 (the desktop-topology successor). Re-scoped per Euclid's Drop+Supersede review on PR #15729 (review, author acceptance comment): the first slice's newest-timestamp selection was falsified at exact head (two top-level sessions → wrong sibling selected, written-probed reported anyway), and its prose claimed "no listing heuristics" while sorting GET /session. Session identity must come from an owner event, never from a listing. The owner-native boundary already exists in-repo: ai/services/fleet/opencodeWakeEnvelopePlugin.mjs receives session.created with the exact top-level session ID and the child exclusion.
The Problem
The operator-launched OpenCode desktop rotates port + credentials + session id on every restart, and a fresh session inherits a stale per-session envelope. The manual heal works (verified 2026-07-22) but is a human ritual. The plugin that owns the correct boundary never loads on this seat (@opencode-ai/plugin@local unresolvable — the load-path repair is #15697's generator emission). This ticket owns the repo-side half: making the owner-event path correct and witnessed, so that once the plugin loads, the boot self-write is automatic and probe-verified.
The Fix (this slice)
- Extend
ai/services/fleet/opencodeWakeEnvelopePlugin.mjs's session.created write path with the salvaged mechanics from PR #15729: atomic tmp+rename at 0600 (already present), $XDG_DATA_HOME honored, and a mandatory self-injected probe against the event-supplied exact session ID — written-probed only when the route verifies end-to-end (204 + in-session landing), otherwise a loud written-probe-failed degraded outcome. At this boundary the probe becomes genuine caller-identity evidence, not route-liveness on a guess.
- Unit witnesses with an injected temp root and stubbed plugin events (never a live seat envelope):
- two-sibling witness:
ses_a created, then ses_b created — each event binds its own exact ID; no cross-targeting is possible by construction
- child-exclusion witness: a
parentID-bearing event writes nothing
- probe witnesses: 204 + landing →
written-probed; probe failure → written-probe-failed with the envelope still written
- No session listing, no timestamp sort, no context-recovery-as-boot wiring anywhere in the slice.
Acceptance Criteria
Out of Scope
- The plugin load-path repair (
@opencode-ai/plugin@^1.18.4 pin emission; #15697, Iris's lane) — the final AC's live receipt depends on it
- The daemon coordinate belt (#15677's Fence 1)
- Session-identity inference of any kind (the parent ticket's fence — now enforced by construction, not by filter)
Related
- #15684 (parent ticket), #15677 (fences), #15665 (twin/split-brain invariant), #15697 (generator emission / load path)
- PR #15729 (superseded first slice — salvage map in Euclid's review)
Origin Session ID: 72c8c42d-f18a-408c-97c8-aeb1f82dd276
Retrieval Hint: "wake envelope session.created owner event probe opencode-server plugin child exclusion XDG 0600"
Context
Split from #15684 (the desktop-topology successor). Re-scoped per Euclid's Drop+Supersede review on PR #15729 (review, author acceptance comment): the first slice's newest-timestamp selection was falsified at exact head (two top-level sessions → wrong sibling selected,
written-probedreported anyway), and its prose claimed "no listing heuristics" while sortingGET /session. Session identity must come from an owner event, never from a listing. The owner-native boundary already exists in-repo:ai/services/fleet/opencodeWakeEnvelopePlugin.mjsreceivessession.createdwith the exact top-level session ID and the child exclusion.The Problem
The operator-launched OpenCode desktop rotates port + credentials + session id on every restart, and a fresh session inherits a stale per-session envelope. The manual heal works (verified 2026-07-22) but is a human ritual. The plugin that owns the correct boundary never loads on this seat (
@opencode-ai/plugin@localunresolvable — the load-path repair is #15697's generator emission). This ticket owns the repo-side half: making the owner-event path correct and witnessed, so that once the plugin loads, the boot self-write is automatic and probe-verified.The Fix (this slice)
ai/services/fleet/opencodeWakeEnvelopePlugin.mjs'ssession.createdwrite path with the salvaged mechanics from PR #15729: atomic tmp+rename at 0600 (already present),$XDG_DATA_HOMEhonored, and a mandatory self-injected probe against the event-supplied exact session ID —written-probedonly when the route verifies end-to-end (204+ in-session landing), otherwise a loudwritten-probe-faileddegraded outcome. At this boundary the probe becomes genuine caller-identity evidence, not route-liveness on a guess.ses_acreated, thenses_bcreated — each event binds its own exact ID; no cross-targeting is possible by constructionparentID-bearing event writes nothingwritten-probed; probe failure →written-probe-failedwith the envelope still writtenAcceptance Criteria
session.createdevent's exact session ID (noGET /sessionselection of any kind)session.createdevents each bind their own IDparentID-bearing events are ignoredwritten-probed; failure →written-probe-failed(loud, envelope still written)$XDG_DATA_HOMEhonored; credential-bearing temp never exists at 0644written-probedenvelope for the fresh session with zero human interventionOut of Scope
@opencode-ai/plugin@^1.18.4pin emission; #15697, Iris's lane) — the final AC's live receipt depends on itRelated
Origin Session ID: 72c8c42d-f18a-408c-97c8-aeb1f82dd276
Retrieval Hint: "wake envelope session.created owner event probe opencode-server plugin child exclusion XDG 0600"