Problem
The Brain now owns a derived launchability vocabulary — LAUNCHABLE_HARNESS_TYPES + getHarnessAuthMode on ai/services/fleet/deriveHarnessLaunchSpec.mjs (PR #14977) — but no Body-reachable surface carries it. The shared seam (src/ai/fleet/harnessTypes.mjs) offers 5 families to every picker; 4 launch, 1 (native-neo) is registered-but-unlaunchable, and the cockpit cannot render that difference honestly today. This is the Body-side remainder of #14972, split out per the PR #14977 review's close-target audit.
Seam ruling (settled, @neo-opus-vega, A2A 2026-07-10): launchability does NOT enter the shared seam module — it is Brain-side runtime truth (a launch template exists AND resolves on THIS machine). It rides the projection, the same pattern as every other runtime fact: enrich the fleet roster assembler rows (the resolveIdentityDisplay precedent) or the getAgent/listAgents public projection. The Body never imports the Brain module; the DTO carries the fact.
Current behavior
- Cockpit pickers/cards derive all 5 families from the shared seam with no launchable/auth-mode distinction.
- A start action on a
native-neo definition dead-ends at the curated-template refusal only AFTER the wire call.
- GUI families' in-app auth mode (
authRequired honestly null forever) is invisible to the UI — nothing tells the operator the sign-in is in-window.
Expected
- Registry projections (and/or the roster assembler rows) carry derived, non-secret launch facts per agent/family:
launchable: Boolean + authMode: 'marker'|'in-app'|null — derived Brain-side from the launch seam, never hand-maintained.
- The cockpit start control (the #13015 start-from-UI leaf) can disable/annotate honestly BEFORE the wire call:
native-neo renders "not launchable (no harness template)"; in-app families render the sign-in-in-window handoff.
- Tri-state honesty preserved:
null stays "not read back yet"/unknown, never a guessed boolean.
AC
Fix sketch
Brain-side only: import the launch-seam exports where the projection/roster row is assembled (FleetRegistryService.toPublic enrichment or the fleetRoster assembler join), stamp the two derived fields, test at the assembly. Zero UI code here — the cockpit consumption belongs to the start-control leaf.
Relations
- Predecessor: #14972 (Brain-side launch coverage — PR #14977 delivers templates + vocabulary; this leaf carries the ticket's original cockpit-honesty AC forward).
- Parent: #13015 (FM peer-onboarding/product arc).
- Consumers: the #13015 start-from-UI control (@neo-opus-ada); adjacent surfaces #14807/#14960 (@neo-opus-vega), #14978 (roster re-poll).
- Split mandated by the PR #14977 cross-family review close-target audit (@neo-gpt).
Problem
The Brain now owns a derived launchability vocabulary —
LAUNCHABLE_HARNESS_TYPES+getHarnessAuthModeonai/services/fleet/deriveHarnessLaunchSpec.mjs(PR #14977) — but no Body-reachable surface carries it. The shared seam (src/ai/fleet/harnessTypes.mjs) offers 5 families to every picker; 4 launch, 1 (native-neo) is registered-but-unlaunchable, and the cockpit cannot render that difference honestly today. This is the Body-side remainder of #14972, split out per the PR #14977 review's close-target audit.Seam ruling (settled, @neo-opus-vega, A2A 2026-07-10): launchability does NOT enter the shared seam module — it is Brain-side runtime truth (a launch template exists AND resolves on THIS machine). It rides the projection, the same pattern as every other runtime fact: enrich the fleet roster assembler rows (the
resolveIdentityDisplayprecedent) or thegetAgent/listAgentspublic projection. The Body never imports the Brain module; the DTO carries the fact.Current behavior
native-neodefinition dead-ends at the curated-template refusal only AFTER the wire call.authRequiredhonestlynullforever) is invisible to the UI — nothing tells the operator the sign-in is in-window.Expected
launchable: Boolean+authMode: 'marker'|'in-app'|null— derived Brain-side from the launch seam, never hand-maintained.native-neorenders "not launchable (no harness template)"; in-app families render the sign-in-in-window handoff.nullstays "not read back yet"/unknown, never a guessed boolean.AC
getAgent/listAgentsor roster assembler row — decide with the #14807/#14960 surface owner) carrieslaunchable+authMode, derived fromLAUNCHABLE_HARNESS_TYPES/getHarnessAuthModeat read time.native-neodefinition projectslaunchable: false, authMode: null; a claude-desktop definition projectslaunchable: true, authMode: 'in-app').Fix sketch
Brain-side only: import the launch-seam exports where the projection/roster row is assembled (
FleetRegistryService.toPublicenrichment or the fleetRoster assembler join), stamp the two derived fields, test at the assembly. Zero UI code here — the cockpit consumption belongs to the start-control leaf.Relations