From 0c97f5d5cbf88862ea9b9a81209a67cf67c39edf Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 23 Apr 2026 21:47:00 -0400 Subject: [PATCH 01/15] feat(spec): add InteractionSurface schema for keyboard-first surfaces --- schemas/InteractionSurface.json | 210 ++++++++++++++++++++++++++++++++ 1 file changed, 210 insertions(+) create mode 100644 schemas/InteractionSurface.json diff --git a/schemas/InteractionSurface.json b/schemas/InteractionSurface.json new file mode 100644 index 0000000..190eeec --- /dev/null +++ b/schemas/InteractionSurface.json @@ -0,0 +1,210 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.srcos.ai/v2/InteractionSurface.json", + "title": "InteractionSurface", + "description": "A typed keyboard-first interaction surface that participates in the SourceOS / SociOS focus, host-boundary, and command-routing model across launcher, browser, shell, terminal, editor, and overlay contexts.", + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "name", + "surfaceType", + "platform", + "modalities", + "focusPolicy", + "hostBoundaryPolicy", + "commandBinding" + ], + "properties": { + "id": { + "type": "string", + "pattern": "^urn:srcos:interaction-surface:" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "surfaceType": { + "type": "string", + "enum": [ + "launcher", + "browser", + "editor", + "terminal", + "command-surface", + "shortcut-overlay", + "panel", + "workspace-controller", + "compositor" + ] + }, + "platform": { + "type": "string", + "enum": [ + "sourceos", + "socios-linux", + "linux", + "web", + "wayland", + "x11", + "gnome", + "pantheon", + "cross-platform" + ] + }, + "modalities": { + "type": "array", + "minItems": 1, + "items": { + "type": "string", + "enum": [ + "keyboard", + "pointer", + "touch", + "voice", + "hybrid" + ] + } + }, + "focusPolicy": { + "type": "object", + "additionalProperties": false, + "required": [ + "owner", + "escapeBehavior", + "tabBehavior", + "multilineBoundaryHistory" + ], + "properties": { + "owner": { + "type": "string", + "enum": [ + "host", + "local-surface", + "shell-overlay", + "pass-through", + "completion-surface", + "modal-review" + ] + }, + "escapeBehavior": { + "type": "string", + "enum": [ + "layered-unwind", + "local-only", + "host-only" + ] + }, + "tabBehavior": { + "type": "string", + "enum": [ + "completion-first", + "focus-cycle", + "local-insert" + ] + }, + "multilineBoundaryHistory": { + "type": "boolean" + }, + "arrowKeyPolicy": { + "type": "string", + "enum": [ + "local-region-navigation", + "caret-or-local", + "delegated" + ] + } + } + }, + "hostBoundaryPolicy": { + "type": "object", + "additionalProperties": false, + "required": [ + "nativeShortcutPolicy", + "passThroughInput" + ], + "properties": { + "nativeShortcutPolicy": { + "type": "string", + "enum": [ + "preserve", + "mirror", + "replace-opt-in" + ] + }, + "passThroughInput": { + "type": "boolean" + }, + "protectedNamespaces": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "commandBinding": { + "type": "object", + "additionalProperties": false, + "required": [ + "defaultInterpretation", + "scopePrefix", + "explicitCommandPrefix" + ], + "properties": { + "defaultInterpretation": { + "type": "string", + "enum": [ + "search", + "literal-input", + "local-action" + ] + }, + "scopePrefix": { + "type": "string" + }, + "explicitCommandPrefix": { + "type": "string" + }, + "commandBusRef": { + "type": [ + "string", + "null" + ] + }, + "launcherRef": { + "type": [ + "string", + "null" + ] + }, + "shortcutOverlayRef": { + "type": [ + "string", + "null" + ] + }, + "keymapProfileRef": { + "type": [ + "string", + "null" + ] + } + } + }, + "evidenceRefs": { + "type": "array", + "items": { + "type": "string" + } + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + } + } +} From e3a1cc1739040abada040bab2304f24e09d1ea79 Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 23 Apr 2026 21:47:38 -0400 Subject: [PATCH 02/15] feat(spec): add InteractionSurface example payload --- examples/interaction_surface.json | 47 +++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 examples/interaction_surface.json diff --git a/examples/interaction_surface.json b/examples/interaction_surface.json new file mode 100644 index 0000000..269d8a0 --- /dev/null +++ b/examples/interaction_surface.json @@ -0,0 +1,47 @@ +{ + "id": "urn:srcos:interaction-surface:emvi-shell", + "name": "EMVI Shell Surface", + "description": "Keyboard-first command and navigation surface spanning browser, shell, terminal, and overlay contexts while preserving host-native ownership where required.", + "surfaceType": "command-surface", + "platform": "socios-linux", + "modalities": [ + "keyboard", + "hybrid" + ], + "focusPolicy": { + "owner": "shell-overlay", + "escapeBehavior": "layered-unwind", + "tabBehavior": "completion-first", + "multilineBoundaryHistory": true, + "arrowKeyPolicy": "local-region-navigation" + }, + "hostBoundaryPolicy": { + "nativeShortcutPolicy": "preserve", + "passThroughInput": true, + "protectedNamespaces": [ + "terminal.pass-through", + "editor.insert", + "browser.text-field", + "password-field", + "accessibility" + ] + }, + "commandBinding": { + "defaultInterpretation": "search", + "scopePrefix": "/", + "explicitCommandPrefix": ">", + "commandBusRef": "urn:srcos:command-bus:emvi", + "launcherRef": null, + "shortcutOverlayRef": "urn:srcos:interaction-surface:shortcut-overlay", + "keymapProfileRef": "urn:srcos:keymap-profile:mac-linux-primary" + }, + "evidenceRefs": [ + "urn:srcos:session:emvi-proof-slice" + ], + "tags": [ + "keyboard-nav", + "cross-surface", + "host-boundary", + "command-bus" + ] +} From 354a7a318535eabfe1287c4163d165b483f35873 Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 23 Apr 2026 21:51:53 -0400 Subject: [PATCH 03/15] docs(spec): add InteractionSurface contract note --- .../contract-additions/interaction-surface.md | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 docs/contract-additions/interaction-surface.md diff --git a/docs/contract-additions/interaction-surface.md b/docs/contract-additions/interaction-surface.md new file mode 100644 index 0000000..3a2322b --- /dev/null +++ b/docs/contract-additions/interaction-surface.md @@ -0,0 +1,31 @@ +# InteractionSurface contract addition + +This addition introduces `InteractionSurface` as the first canonical contract for +keyboard-first cross-surface interaction ownership in SourceOS / SociOS. + +## Why this contract exists + +Existing contract families already describe execution, policy, provenance, and +agent-session behavior. What was missing was a typed description of the user-facing +surface itself: launcher, browser, shell, terminal, editor, overlay, and related +host-boundary contexts. + +`InteractionSurface` fills that gap by making these aspects explicit: + +- surface type and platform +- focus ownership policy +- host-boundary preservation vs mirroring vs opt-in replacement +- command binding defaults (`/` scope, `>` explicit command mode, etc.) +- optional command-bus / overlay / keymap references + +## Intended use + +- canonical specification lives here in `sourceos-spec` +- Linux-side implementation may live in SourceOS / SociOS Linux repos +- execution/control-plane repos may consume evidence or policy hooks later, but do not own this contract + +## Current scope + +This is intentionally the first slice, not the full interaction model. Follow-on +contracts may add richer focus-state, command-bus, keymap-profile, and surface- +discoverability types once they stabilize. From 234db4c46e2b2c48a0dfc4c108c1c988f7bedb39 Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Fri, 24 Apr 2026 07:05:45 -0400 Subject: [PATCH 04/15] feat(spec): add CommandBus schema for cross-surface command routing --- schemas/CommandBus.json | 97 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 schemas/CommandBus.json diff --git a/schemas/CommandBus.json b/schemas/CommandBus.json new file mode 100644 index 0000000..ae1190a --- /dev/null +++ b/schemas/CommandBus.json @@ -0,0 +1,97 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.srcos.ai/v2/CommandBus.json", + "title": "CommandBus", + "description": "A typed command-routing surface for keyboard-first interaction across launcher, browser, shell, terminal, editor, overlay, and workspace contexts in SourceOS / SociOS.", + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "name", + "defaultInterpretation", + "scopePrefix", + "explicitCommandPrefix", + "dispatchMode", + "surfaces" + ], + "properties": { + "id": { + "type": "string", + "pattern": "^urn:srcos:command-bus:" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "defaultInterpretation": { + "type": "string", + "enum": [ + "search", + "literal-input", + "local-action" + ] + }, + "scopePrefix": { + "type": "string" + }, + "explicitCommandPrefix": { + "type": "string" + }, + "dispatchMode": { + "type": "string", + "enum": [ + "focus-owner-first", + "shell-overlay-first", + "local-surface-first" + ] + }, + "surfaces": { + "type": "array", + "minItems": 1, + "items": { + "type": "string", + "pattern": "^urn:srcos:interaction-surface:" + } + }, + "deictics": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "current", + "selection", + "recent", + "here" + ] + } + }, + "commandNamespaces": { + "type": "array", + "items": { + "type": "string" + } + }, + "protectedNamespaces": { + "type": "array", + "items": { + "type": "string" + } + }, + "handoffPolicy": { + "type": "string", + "enum": [ + "preserve-host-boundary", + "prompt-before-handoff", + "policy-gated" + ] + }, + "evidenceRefs": { + "type": "array", + "items": { + "type": "string" + } + } + } +} From ea5978bde02b90e5771c4fc56e17e67a15e0865c Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Fri, 24 Apr 2026 07:07:57 -0400 Subject: [PATCH 05/15] feat(spec): add CommandBus example payload --- examples/command_bus.json | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 examples/command_bus.json diff --git a/examples/command_bus.json b/examples/command_bus.json new file mode 100644 index 0000000..b4f000c --- /dev/null +++ b/examples/command_bus.json @@ -0,0 +1,38 @@ +{ + "id": "urn:srcos:command-bus:emvi", + "name": "EMVI Command Bus", + "description": "Cross-surface command routing for SourceOS / SociOS keyboard-first interaction across launcher, browser, shell, terminal, editor, and overlay contexts.", + "defaultInterpretation": "search", + "scopePrefix": "/", + "explicitCommandPrefix": ">", + "dispatchMode": "focus-owner-first", + "surfaces": [ + "urn:srcos:interaction-surface:emvi-shell", + "urn:srcos:interaction-surface:shortcut-overlay", + "urn:srcos:interaction-surface:browser-surface", + "urn:srcos:interaction-surface:terminal-surface" + ], + "deictics": [ + "current", + "selection", + "recent", + "here" + ], + "commandNamespaces": [ + "browser", + "shell", + "terminal", + "collection", + "workspace" + ], + "protectedNamespaces": [ + "terminal.pass-through", + "editor.insert", + "browser.text-field", + "accessibility" + ], + "handoffPolicy": "preserve-host-boundary", + "evidenceRefs": [ + "urn:srcos:session:emvi-proof-slice" + ] +} From e05bd400b205b3ccf92115c4eabc2088b9f92bcb Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Fri, 24 Apr 2026 07:47:51 -0400 Subject: [PATCH 06/15] docs(spec): add CommandBus contract note --- docs/contract-additions/command-bus.md | 32 ++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 docs/contract-additions/command-bus.md diff --git a/docs/contract-additions/command-bus.md b/docs/contract-additions/command-bus.md new file mode 100644 index 0000000..454a5e8 --- /dev/null +++ b/docs/contract-additions/command-bus.md @@ -0,0 +1,32 @@ +# CommandBus contract addition + +This addition introduces `CommandBus` as the typed routing contract for keyboard-first +cross-surface command dispatch in SourceOS / SociOS. + +## Why this contract exists + +`InteractionSurface` describes a specific user-facing surface and its ownership +policies. What it does not describe on its own is the shared routing layer that +interprets command prefixes, deictics, namespace handoff, and dispatch across +multiple surfaces. + +`CommandBus` fills that gap by making these aspects explicit: + +- default interpretation (`search`, `literal-input`, `local-action`) +- scope and explicit-command prefixes +- dispatch ordering (`focus-owner-first`, etc.) +- participating interaction surfaces +- protected namespaces and host-boundary handoff policy + +## Intended use + +- canonical specification lives here in `sourceos-spec` +- Linux / browser / shell implementations bind to this contract downstream +- execution/control-plane repos may consume command-bus evidence later, but do not own this contract + +## Relationship to InteractionSurface + +- `InteractionSurface` = a typed surface with focus/host-boundary/command binding rules +- `CommandBus` = the shared routing and interpretation layer that spans those surfaces + +Both are needed for the keyboard-navigation model, but they serve different roles. From 18c7bb376e88d9c45698aab173b99ac4a88a366c Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Fri, 24 Apr 2026 08:12:26 -0400 Subject: [PATCH 07/15] feat(spec): add FocusState schema for keyboard ownership --- schemas/FocusState.json | 102 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 schemas/FocusState.json diff --git a/schemas/FocusState.json b/schemas/FocusState.json new file mode 100644 index 0000000..92e014a --- /dev/null +++ b/schemas/FocusState.json @@ -0,0 +1,102 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.srcos.ai/v2/FocusState.json", + "title": "FocusState", + "description": "A typed focus/ownership state for keyboard-first interaction across SourceOS / SociOS surfaces.", + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "surfaceRef", + "owner", + "mode", + "printableInputOwner", + "escapeBehavior", + "tabBehavior" + ], + "properties": { + "id": { + "type": "string", + "pattern": "^urn:srcos:focus-state:" + }, + "surfaceRef": { + "type": "string", + "pattern": "^urn:srcos:interaction-surface:" + }, + "owner": { + "type": "string", + "enum": [ + "host", + "local-surface", + "shell-overlay", + "pass-through", + "completion-surface", + "modal-review" + ] + }, + "mode": { + "type": "string", + "enum": [ + "idle", + "input", + "results", + "preview", + "action-sheet", + "insert", + "normal", + "pass-through", + "completion", + "confirmation", + "plan-review" + ] + }, + "printableInputOwner": { + "type": "string", + "enum": [ + "host", + "local-surface", + "pass-through", + "shell-overlay" + ] + }, + "escapeBehavior": { + "type": "string", + "enum": [ + "layered-unwind", + "local-only", + "host-only" + ] + }, + "tabBehavior": { + "type": "string", + "enum": [ + "completion-first", + "focus-cycle", + "local-insert" + ] + }, + "arrowKeyPolicy": { + "type": "string", + "enum": [ + "local-region-navigation", + "caret-or-local", + "delegated" + ] + }, + "multilineBoundaryHistory": { + "type": "boolean" + }, + "completionActive": { + "type": "boolean" + }, + "selectionActive": { + "type": "boolean" + }, + "evidenceRefs": { + "type": "array", + "items": { + "type": "string" + } + } + } +} From ead0824bc2674a891092ad3c2d0d8be4185fb5bb Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Fri, 24 Apr 2026 08:13:11 -0400 Subject: [PATCH 08/15] feat(spec): add FocusState example payload --- examples/focus_state.json | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 examples/focus_state.json diff --git a/examples/focus_state.json b/examples/focus_state.json new file mode 100644 index 0000000..fdaf144 --- /dev/null +++ b/examples/focus_state.json @@ -0,0 +1,16 @@ +{ + "id": "urn:srcos:focus-state:emvi-shell-input", + "surfaceRef": "urn:srcos:interaction-surface:emvi-shell", + "owner": "shell-overlay", + "mode": "input", + "printableInputOwner": "shell-overlay", + "escapeBehavior": "layered-unwind", + "tabBehavior": "completion-first", + "arrowKeyPolicy": "local-region-navigation", + "multilineBoundaryHistory": true, + "completionActive": false, + "selectionActive": false, + "evidenceRefs": [ + "urn:srcos:session:emvi-proof-slice" + ] +} From db070853d81ed1392e1d8b0bc237e1c68a1ea1c7 Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Fri, 24 Apr 2026 08:13:48 -0400 Subject: [PATCH 09/15] docs(spec): add FocusState contract note --- docs/contract-additions/focus-state.md | 33 ++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 docs/contract-additions/focus-state.md diff --git a/docs/contract-additions/focus-state.md b/docs/contract-additions/focus-state.md new file mode 100644 index 0000000..4886a6b --- /dev/null +++ b/docs/contract-additions/focus-state.md @@ -0,0 +1,33 @@ +# FocusState contract addition + +This addition introduces `FocusState` as the typed ownership/state record for +keyboard-first cross-surface interaction in SourceOS / SociOS. + +## Why this contract exists + +`InteractionSurface` describes a surface and its high-level policies. +`CommandBus` describes routing and interpretation across multiple surfaces. +What was still missing was an explicit typed record for **who owns the keyboard right now**. + +`FocusState` fills that gap by making these aspects explicit: + +- current surface reference +- ownership mode (`host`, `local-surface`, `shell-overlay`, `pass-through`, etc.) +- printable-input ownership +- escape and tab behavior +- completion and selection activity +- multiline boundary-history semantics + +## Intended use + +- canonical specification lives here in `sourceos-spec` +- Linux / browser / shell implementations bind to this state model downstream +- execution/control-plane repos may consume focus-state evidence later, but do not own the contract + +## Relationship to the other keyboard-navigation contracts + +- `InteractionSurface` = what the surface is and what high-level policies it carries +- `CommandBus` = how commands route across surfaces +- `FocusState` = who owns keyboard behavior in the current moment + +All three are needed for the cross-surface keyboard-navigation model. From 03e4d755b5c11972c5d286a58f90f3923d4cccbb Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Fri, 24 Apr 2026 08:26:00 -0400 Subject: [PATCH 10/15] feat(spec): add FocusTransition schema --- schemas/FocusTransition.json | 79 ++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 schemas/FocusTransition.json diff --git a/schemas/FocusTransition.json b/schemas/FocusTransition.json new file mode 100644 index 0000000..4e5ed59 --- /dev/null +++ b/schemas/FocusTransition.json @@ -0,0 +1,79 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.srcos.ai/v2/FocusTransition.json", + "title": "FocusTransition", + "description": "A typed transition between two keyboard-focus ownership states in SourceOS / SociOS interaction flows.", + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "fromStateRef", + "toStateRef", + "trigger", + "priority", + "allowed" + ], + "properties": { + "id": { + "type": "string", + "pattern": "^urn:srcos:focus-transition:" + }, + "fromStateRef": { + "type": "string", + "pattern": "^urn:srcos:focus-state:" + }, + "toStateRef": { + "type": "string", + "pattern": "^urn:srcos:focus-state:" + }, + "trigger": { + "type": "string", + "enum": [ + "summon", + "dismiss", + "select-result", + "open-preview", + "enter-insert", + "enter-pass-through", + "start-completion", + "accept-completion", + "cancel-completion", + "request-confirmation", + "accept-confirmation", + "cancel-confirmation", + "escape", + "tab", + "shift-tab", + "return" + ] + }, + "priority": { + "type": "integer", + "minimum": 0 + }, + "allowed": { + "type": "boolean" + }, + "conditions": { + "type": "array", + "items": { + "type": "string" + } + }, + "ownershipEffect": { + "type": "string", + "enum": [ + "retain-owner", + "handoff-to-local", + "handoff-to-shell", + "return-to-host" + ] + }, + "evidenceRefs": { + "type": "array", + "items": { + "type": "string" + } + } + } +} From ac1c2442418ddfa2e8db42af431cd0129e5384f1 Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Fri, 24 Apr 2026 08:26:54 -0400 Subject: [PATCH 11/15] feat(spec): add KeymapProfile schema --- schemas/KeymapProfile.json | 98 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 schemas/KeymapProfile.json diff --git a/schemas/KeymapProfile.json b/schemas/KeymapProfile.json new file mode 100644 index 0000000..47dc71e --- /dev/null +++ b/schemas/KeymapProfile.json @@ -0,0 +1,98 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.srcos.ai/v2/KeymapProfile.json", + "title": "KeymapProfile", + "description": "A typed keyboard mapping profile for SourceOS / SociOS host, browser, shell, terminal, and editor surfaces.", + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "name", + "platform", + "primaryModifierStrategy", + "guiProfile", + "terminalProfile", + "protectedNamespaces" + ], + "properties": { + "id": { + "type": "string", + "pattern": "^urn:srcos:keymap-profile:" + }, + "name": { + "type": "string" + }, + "platform": { + "type": "string", + "enum": [ + "sourceos", + "socios-linux", + "linux", + "cross-platform" + ] + }, + "primaryModifierStrategy": { + "type": "string", + "enum": [ + "mac-linux-primary", + "linux-native-primary", + "app-local-only" + ] + }, + "guiProfile": { + "type": "object", + "additionalProperties": false, + "required": [ + "physicalCtrl", + "physicalAlt", + "physicalSuper" + ], + "properties": { + "physicalCtrl": {"type": "string"}, + "physicalAlt": {"type": "string"}, + "physicalSuper": {"type": "string"} + } + }, + "terminalProfile": { + "type": "object", + "additionalProperties": false, + "required": [ + "physicalCtrl", + "physicalAlt", + "physicalSuper" + ], + "properties": { + "physicalCtrl": {"type": "string"}, + "physicalAlt": {"type": "string"}, + "physicalSuper": {"type": "string"} + } + }, + "launcherRefs": { + "type": "array", + "items": { + "type": "string" + } + }, + "overlayRefs": { + "type": "array", + "items": { + "type": "string" + } + }, + "remapEngineRef": { + "type": ["string", "null"] + }, + "protectedNamespaces": { + "type": "array", + "items": { + "type": "string" + } + }, + "evidenceRefs": { + "type": "array", + "items": { + "type": "string" + } + } + } +} From e1288bc8aa06a67bf40681620ce5730224d4d1a6 Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Fri, 24 Apr 2026 08:28:00 -0400 Subject: [PATCH 12/15] feat(spec): add FocusTransition example payload --- examples/focus_transition.json | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 examples/focus_transition.json diff --git a/examples/focus_transition.json b/examples/focus_transition.json new file mode 100644 index 0000000..de635e5 --- /dev/null +++ b/examples/focus_transition.json @@ -0,0 +1,15 @@ +{ + "id": "urn:srcos:focus-transition:example-1", + "fromStateRef": "urn:srcos:focus-state:emvi-shell-input", + "toStateRef": "urn:srcos:focus-state:emvi-shell-input", + "trigger": "escape", + "priority": 1, + "allowed": true, + "conditions": [ + "completionInactive" + ], + "ownershipEffect": "retain-owner", + "evidenceRefs": [ + "urn:srcos:session:emvi-proof-slice" + ] +} From 4723545ec05d82873a25f383159f250f3286f202 Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Fri, 24 Apr 2026 08:28:31 -0400 Subject: [PATCH 13/15] feat(spec): add KeymapProfile example payload --- examples/keymap_profile.json | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 examples/keymap_profile.json diff --git a/examples/keymap_profile.json b/examples/keymap_profile.json new file mode 100644 index 0000000..328402c --- /dev/null +++ b/examples/keymap_profile.json @@ -0,0 +1,30 @@ +{ + "id": "urn:srcos:keymap-profile:mac-linux-primary", + "name": "Mac/Linux Primary Profile", + "platform": "socios-linux", + "primaryModifierStrategy": "mac-linux-primary", + "guiProfile": { + "physicalCtrl": "Super", + "physicalAlt": "Alt", + "physicalSuper": "Ctrl" + }, + "terminalProfile": { + "physicalCtrl": "Ctrl", + "physicalAlt": "Alt", + "physicalSuper": "RightCtrl" + }, + "launcherRefs": [], + "overlayRefs": [ + "urn:srcos:interaction-surface:shortcut-overlay" + ], + "remapEngineRef": "urn:srcos:remap-engine:kinto", + "protectedNamespaces": [ + "terminal.pass-through", + "editor.insert", + "browser.text-field", + "accessibility" + ], + "evidenceRefs": [ + "urn:srcos:session:emvi-proof-slice" + ] +} From 5ef795d34e41859b367af3a216d2b0e3dcf759ea Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Fri, 24 Apr 2026 08:29:12 -0400 Subject: [PATCH 14/15] docs(spec): add FocusTransition contract note --- docs/contract-additions/focus-transition.md | 30 +++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 docs/contract-additions/focus-transition.md diff --git a/docs/contract-additions/focus-transition.md b/docs/contract-additions/focus-transition.md new file mode 100644 index 0000000..8cb23c6 --- /dev/null +++ b/docs/contract-additions/focus-transition.md @@ -0,0 +1,30 @@ +# FocusTransition contract addition + +This addition introduces `FocusTransition` as the typed transition edge between +keyboard-focus ownership states in SourceOS / SociOS. + +## Why this contract exists + +`FocusState` describes who owns the keyboard right now. What it does not capture +on its own is how ownership changes over time. + +`FocusTransition` fills that gap by making these aspects explicit: + +- source and destination focus states +- transition trigger +- priority ordering +- whether the transition is allowed +- conditions and ownership effect + +## Intended use + +- canonical specification lives here in `sourceos-spec` +- Linux / browser / shell implementations bind to this transition model downstream +- execution/control-plane repos may consume transition evidence later, but do not own the contract + +## Relationship to the other keyboard-navigation contracts + +- `InteractionSurface` = what the surface is +- `CommandBus` = how commands route across surfaces +- `FocusState` = who owns the keyboard right now +- `FocusTransition` = how ownership changes from one state to another From 0d591a36efd8aca3c646389dfa1ce00dc46d4f1e Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Fri, 24 Apr 2026 08:30:48 -0400 Subject: [PATCH 15/15] docs(spec): add KeymapProfile contract note --- docs/contract-additions/keymap-profile.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 docs/contract-additions/keymap-profile.md diff --git a/docs/contract-additions/keymap-profile.md b/docs/contract-additions/keymap-profile.md new file mode 100644 index 0000000..ae63b37 --- /dev/null +++ b/docs/contract-additions/keymap-profile.md @@ -0,0 +1,16 @@ +# KeymapProfile contract addition + +`KeymapProfile` is the typed mapping profile for keyboard-first interaction in SourceOS and SociOS. + +It records: +- platform and modifier strategy +- GUI profile +- terminal profile +- launcher and overlay references +- remap-engine reference +- protected namespaces + +Placement rule: +- canonical schema lives in `sourceos-spec` +- Linux-side implementations bind to it downstream +- donor/remap repositories may inform values but do not own the contract