diff --git a/docs/workstation-contract-family.md b/docs/workstation-contract-family.md new file mode 100644 index 0000000..8c2ba7f --- /dev/null +++ b/docs/workstation-contract-family.md @@ -0,0 +1,56 @@ +# Workstation Contract Family + +This note documents the first workstation-facing contract family for SourceOS Linux developer/operator environments. + +## Added schemas + +- `schemas/LauncherAction.json` +- `schemas/LauncherProvider.json` +- `schemas/PackageManifest.json` +- `schemas/DesktopProfile.json` +- `schemas/WorkstationProfile.json` + +## Added examples + +- `examples/launcheraction.json` +- `examples/launcherprovider.json` +- `examples/packagemanifest.json` +- `examples/desktopprofile.json` +- `examples/workstationprofile.json` + +## Purpose + +These contracts promote workstation profile semantics from implementation-local YAML and shell scripts into canonical typed objects. + +They are intended to support: +- reproducible workstation profile descriptions +- launcher/action-bus interoperability +- package layer and desktop posture reuse across repos +- typed validation, rendering, and SDK generation downstream +- alignment between Linux realization and the SourceOS contract layer + +## Boundary rule + +These workstation-facing types describe **what a workstation exposes and installs**. +They do not replace execution/audit contracts already owned by the execution plane. + +Specifically: +- `LauncherAction` describes a user/operator-facing action surface, not a full execution receipt. +- `LauncherProvider` describes routing and invariants, not search index internals. +- `PackageManifest` describes layered packages, not image-level substrate identity. +- `DesktopProfile` describes the desktop posture, not a policy canon. +- `WorkstationProfile` ties these together for a workstation lane while referencing—not redefining—execution/audit semantics elsewhere. + +## Immediate alignment target + +This family is intended to align with the current Linux realization in `SociOS-Linux/source-os`, including: +- workstation-v0 package layering +- GNOME desktop defaults and extension pinset +- SourceOS palette / command-bus posture +- Lampstand-backed local file search + +## Follow-on contract work + +1. Add richer search-provider and validation sub-objects once the shell/runtime product repo stabilizes. +2. Add typed references for doctor/fix report families and runtime execution surfaces. +3. Bind these objects into OpenAPI / AsyncAPI surfaces when the first product/runtime consumers are ready. diff --git a/examples/desktopprofile.json b/examples/desktopprofile.json new file mode 100644 index 0000000..ad72aaf --- /dev/null +++ b/examples/desktopprofile.json @@ -0,0 +1,28 @@ +{ + "id": "urn:srcos:desktop-profile:gnome-workstation-v0", + "type": "DesktopProfile", + "specVersion": "2.1.0", + "desktopEnvironment": "gnome", + "extensionSet": [ + "dash-to-dock@micxgx.gmail.com", + "appindicatorsupport@rgcjonas.gmail.com" + ], + "keybindings": [ + { + "name": "SourceOS Files", + "binding": "e", + "command": "nautilus --new-window" + }, + { + "name": "SourceOS Terminal", + "binding": "Return", + "command": "gnome-terminal" + } + ], + "input": { + "primaryBackend": "input-remapper", + "compatibilityBackends": ["xremap", "kinto"], + "gestures": "fusuma" + }, + "launcherProviderRef": "urn:srcos:launcher-provider:sourceos-palette" +} diff --git a/examples/launcheraction.json b/examples/launcheraction.json new file mode 100644 index 0000000..51c1bc9 --- /dev/null +++ b/examples/launcheraction.json @@ -0,0 +1,14 @@ +{ + "id": "urn:srcos:launcher-action:search-files", + "type": "LauncherAction", + "specVersion": "2.1.0", + "title": "Search files (Lampstand)", + "subtitle": "Prompt for a local file search and open the report artifact", + "scope": "files", + "command": ["sourceos", "search", "--prompt", "--snippet", "--open"], + "opensArtifact": true, + "capabilityRefs": [ + "urn:srcos:launcher-provider:sourceos-palette", + "urn:srcos:workstation-profile:workstation-v0" + ] +} \ No newline at end of file diff --git a/examples/launcherprovider.json b/examples/launcherprovider.json new file mode 100644 index 0000000..c06f83a --- /dev/null +++ b/examples/launcherprovider.json @@ -0,0 +1,17 @@ +{ + "id": "urn:srcos:launcher-provider:sourceos-palette", + "type": "LauncherProvider", + "specVersion": "2.1.0", + "name": "SourceOS Palette", + "providerKind": "command-bus", + "trigger": "space", + "binary": "sourceos", + "scopes": { + "apps": "launcher", + "files": "linux-native-only", + "web": "browser-agent" + }, + "invariants": [ + "no_redundant_file_search" + ] +} diff --git a/examples/packagemanifest.json b/examples/packagemanifest.json new file mode 100644 index 0000000..df07cb5 --- /dev/null +++ b/examples/packagemanifest.json @@ -0,0 +1,18 @@ +{ + "id": "urn:srcos:package-manifest:workstation-v0", + "type": "PackageManifest", + "specVersion": "2.1.0", + "name": "workstation-v0", + "layers": { + "system": { + "rpm_ostree": ["git", "podman", "toolbox", "wl-clipboard", "fuzzel", "input-remapper"], + "dnf": ["git", "podman", "toolbox", "wl-clipboard", "fuzzel", "input-remapper"] + }, + "user": { + "brew": ["fzf", "atuin", "bat", "zoxide", "yazi", "eza", "direnv", "tmux", "lazygit", "rclone", "minio-mc", "rsync"] + }, + "toolbox": { + "aur": ["ruby-fusuma"] + } + } +} diff --git a/examples/workstationprofile.json b/examples/workstationprofile.json new file mode 100644 index 0000000..c92d1a0 --- /dev/null +++ b/examples/workstationprofile.json @@ -0,0 +1,18 @@ +{ + "id": "urn:srcos:workstation-profile:workstation-v0", + "type": "WorkstationProfile", + "specVersion": "2.1.0", + "name": "workstation-v0", + "channel": "linux-dev", + "packageManifestRef": "urn:srcos:package-manifest:workstation-v0", + "desktopProfileRef": "urn:srcos:desktop-profile:gnome-workstation-v0", + "launcherProviderRef": "urn:srcos:launcher-provider:sourceos-palette", + "launcherActionRefs": [ + "urn:srcos:launcher-action:search-files" + ], + "validation": { + "doctorCommand": "sourceos doctor --json", + "statusCommand": "sourceos status --json", + "searchCommand": "sourceos search --snippet" + } +} diff --git a/schemas/DesktopProfile.json b/schemas/DesktopProfile.json new file mode 100644 index 0000000..d7bda2e --- /dev/null +++ b/schemas/DesktopProfile.json @@ -0,0 +1,70 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.srcos.ai/v2/DesktopProfile.json", + "title": "DesktopProfile", + "description": "A typed desktop-environment profile for workstation realization, including extensions, input posture, and launcher defaults.", + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "type", + "specVersion", + "desktopEnvironment" + ], + "properties": { + "id": { + "type": "string", + "pattern": "^urn:srcos:desktop-profile:", + "description": "Stable URN identifier. Pattern: urn:srcos:desktop-profile:." + }, + "type": { + "const": "DesktopProfile", + "description": "Discriminator constant — always \"DesktopProfile\"." + }, + "specVersion": { + "type": "string", + "description": "Spec version of this document, e.g. \"2.1.0\"." + }, + "desktopEnvironment": { + "type": "string", + "enum": ["gnome", "kde", "cosmic", "sway", "other"], + "description": "Desktop environment or shell family." + }, + "extensionSet": { + "type": "array", + "items": { "type": "string", "minLength": 1 }, + "description": "Pinned shell extension identifiers or package names." + }, + "keybindings": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "required": ["name", "binding", "command"], + "properties": { + "name": { "type": "string", "minLength": 1 }, + "binding": { "type": "string", "minLength": 1 }, + "command": { "type": "string", "minLength": 1 } + } + }, + "description": "Declarative desktop keybindings." + }, + "input": { + "type": "object", + "additionalProperties": false, + "properties": { + "primaryBackend": { "type": "string" }, + "compatibilityBackends": { + "type": "array", + "items": { "type": "string" } + }, + "gestures": { "type": "string" } + }, + "description": "Keyboard remap and gesture posture." + }, + "launcherProviderRef": { + "type": ["string", "null"], + "description": "Optional reference to the primary LauncherProvider." + } + } +} diff --git a/schemas/LauncherAction.json b/schemas/LauncherAction.json new file mode 100644 index 0000000..07169c5 --- /dev/null +++ b/schemas/LauncherAction.json @@ -0,0 +1,59 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.srcos.ai/v2/LauncherAction.json", + "title": "LauncherAction", + "description": "A typed launcher or command-bus action exposed to workstation users and operators.", + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "type", + "specVersion", + "title", + "command" + ], + "properties": { + "id": { + "type": "string", + "pattern": "^urn:srcos:launcher-action:", + "description": "Stable URN identifier. Pattern: urn:srcos:launcher-action:." + }, + "type": { + "const": "LauncherAction", + "description": "Discriminator constant — always \"LauncherAction\"." + }, + "specVersion": { + "type": "string", + "description": "Spec version of this document, e.g. \"2.1.0\"." + }, + "title": { + "type": "string", + "minLength": 1, + "description": "Human-readable action title." + }, + "subtitle": { + "type": ["string", "null"], + "description": "Optional secondary text shown in the launcher or command palette." + }, + "scope": { + "type": "string", + "enum": ["apps", "files", "web", "system", "workspace", "operator"], + "description": "Primary routing scope for this action." + }, + "command": { + "type": "array", + "minItems": 1, + "items": { "type": "string", "minLength": 1 }, + "description": "Executable command vector to invoke." + }, + "opensArtifact": { + "type": "boolean", + "description": "Whether this action is expected to write and/or open a local artifact for inspection." + }, + "capabilityRefs": { + "type": "array", + "items": { "type": "string" }, + "description": "Optional references to capability, policy, or contract identifiers." + } + } +} diff --git a/schemas/LauncherProvider.json b/schemas/LauncherProvider.json new file mode 100644 index 0000000..869b7ac --- /dev/null +++ b/schemas/LauncherProvider.json @@ -0,0 +1,63 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.srcos.ai/v2/LauncherProvider.json", + "title": "LauncherProvider", + "description": "A typed description of a workstation launcher or command-bus frontend/provider.", + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "type", + "specVersion", + "name", + "providerKind" + ], + "properties": { + "id": { + "type": "string", + "pattern": "^urn:srcos:launcher-provider:", + "description": "Stable URN identifier. Pattern: urn:srcos:launcher-provider:." + }, + "type": { + "const": "LauncherProvider", + "description": "Discriminator constant — always \"LauncherProvider\"." + }, + "specVersion": { + "type": "string", + "description": "Spec version of this document, e.g. \"2.1.0\"." + }, + "name": { + "type": "string", + "minLength": 1, + "description": "Human-readable provider name." + }, + "providerKind": { + "type": "string", + "enum": ["palette", "desktop-launcher", "search-provider", "command-bus"], + "description": "Primary provider role." + }, + "trigger": { + "type": ["string", "null"], + "description": "Optional shortcut or textual trigger such as space or 'sourceos '." + }, + "binary": { + "type": ["string", "null"], + "description": "Optional frontend binary or command name." + }, + "scopes": { + "type": "object", + "additionalProperties": false, + "properties": { + "apps": { "type": "string" }, + "files": { "type": "string" }, + "web": { "type": "string" } + }, + "description": "Routing policy for launcher scopes." + }, + "invariants": { + "type": "array", + "items": { "type": "string" }, + "description": "Operational invariants this provider must preserve." + } + } +} diff --git a/schemas/PackageManifest.json b/schemas/PackageManifest.json new file mode 100644 index 0000000..bc411ab --- /dev/null +++ b/schemas/PackageManifest.json @@ -0,0 +1,66 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.srcos.ai/v2/PackageManifest.json", + "title": "PackageManifest", + "description": "A layered workstation package manifest describing system, user, and toolbox package sets.", + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "type", + "specVersion", + "name", + "layers" + ], + "properties": { + "id": { + "type": "string", + "pattern": "^urn:srcos:package-manifest:", + "description": "Stable URN identifier. Pattern: urn:srcos:package-manifest:." + }, + "type": { + "const": "PackageManifest", + "description": "Discriminator constant — always \"PackageManifest\"." + }, + "specVersion": { + "type": "string", + "description": "Spec version of this document, e.g. \"2.1.0\"." + }, + "name": { + "type": "string", + "minLength": 1, + "description": "Human-readable manifest name." + }, + "layers": { + "type": "object", + "additionalProperties": false, + "properties": { + "system": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { "type": "string", "minLength": 1 } + }, + "description": "Host/system layer grouped by package backend." + }, + "user": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { "type": "string", "minLength": 1 } + }, + "description": "User-space package layer grouped by package backend." + }, + "toolbox": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { "type": "string", "minLength": 1 } + }, + "description": "Toolbox/container build-space package layer grouped by backend." + } + }, + "description": "Package layers for workstation realization." + } + } +} diff --git a/schemas/README.md b/schemas/README.md index 3dcadd3..daef0a7 100644 --- a/schemas/README.md +++ b/schemas/README.md @@ -4,6 +4,27 @@ This directory contains the JSON Schema (draft 2020-12) files that make up the S --- +## Recent additions — Workstation Contract Family + +The workstation contract family adds the following top-level schemas: + +| File | Type | URN prefix | +|------|------|-----------| +| `LauncherAction.json` | LauncherAction | `urn:srcos:launcher-action:` | +| `LauncherProvider.json` | LauncherProvider | `urn:srcos:launcher-provider:` | +| `PackageManifest.json` | PackageManifest | `urn:srcos:package-manifest:` | +| `DesktopProfile.json` | DesktopProfile | `urn:srcos:desktop-profile:` | +| `WorkstationProfile.json` | WorkstationProfile | `urn:srcos:workstation-profile:` | + +These types support: +- reproducible workstation profile descriptions +- typed launcher / command-bus surfaces +- layered package manifests for system, user, and toolbox lanes +- desktop posture capture for GNOME and adjacent shells +- alignment between Linux realization and the canonical contract layer + +--- + ## Recent additions — Fog Layer The FogVault / FogCompute contract family adds the following top-level schemas: @@ -43,6 +64,7 @@ These types support: | `DataSphere.json` | DataSphere | `urn:srcos:sphere:` | | `Dataset.json` | Dataset | `urn:srcos:dataset:` | | `DeltaSurface.json` | DeltaSurface | `urn:srcos:delta-surface:` | +| `DesktopProfile.json` | DesktopProfile | `urn:srcos:desktop-profile:` | | `EntityField.json` | EntityField | _(sub-object inside SchemaDefinition)_ | | `EventEnvelope.json` | EventEnvelope | `urn:srcos:event:` | | `Exception.json` | Exception | _(sub-object inside Policy)_ | @@ -52,6 +74,8 @@ These types support: | `Field.json` | Field | `urn:srcos:field:` | | `FrustrationSignal.json` | FrustrationSignal | `urn:srcos:frustration:` | | `GlossaryTerm.json` | GlossaryTerm | `urn:srcos:glossary:` | +| `LauncherAction.json` | LauncherAction | `urn:srcos:launcher-action:` | +| `LauncherProvider.json` | LauncherProvider | `urn:srcos:launcher-provider:` | | `Link.json` | Link | _(sub-object, no id)_ | | `MappingEvidence.json` | MappingEvidence | _(sub-object inside MappingSpec)_ | | `MappingSpec.json` | MappingSpec | `urn:srcos:mapping:` | @@ -60,6 +84,7 @@ These types support: | `ObjectSelector.json` | ObjectSelector | _(sub-object inside Policy scope)_ | | `Obligation.json` | Obligation | _(sub-object, no id)_ | | `Offer.json` | Offer | `urn:srcos:offer:` | +| `PackageManifest.json` | PackageManifest | `urn:srcos:package-manifest:` | | `Party.json` | Party | `urn:srcos:party:` | | `PhysicalAsset.json` | PhysicalAsset | `urn:srcos:asset:` | | `Policy.json` | Policy | `urn:srcos:policy:` | @@ -95,6 +120,7 @@ These types support: | `WorkflowSpec.json` | WorkflowSpec | `urn:srcos:workflow:` | | `WorkloadSpec.json` | WorkloadSpec | `urn:srcos:workload:` | | `WorkOrder.json` | WorkOrder | `urn:srcos:workorder:` | +| `WorkstationProfile.json` | WorkstationProfile | `urn:srcos:workstation-profile:` | --- @@ -156,6 +182,16 @@ These types support: | `Agreement` | A data-sharing agreement between one or more parties with terms and effective dates | | `Party` | A named signatory (person, org, or service) with optional authority links | +### Workstation / Desktop + +| Schema | Description | +|--------|-------------| +| `LauncherAction` | A typed launcher or command-bus action surfaced to workstation users/operators | +| `LauncherProvider` | A typed launcher or command-bus provider with routing scopes and invariants | +| `PackageManifest` | A layered workstation package manifest covering system, user, and toolbox layers | +| `DesktopProfile` | A typed desktop-environment posture including extensions, keybindings, and input/gesture lanes | +| `WorkstationProfile` | A top-level workstation profile tying package, desktop, launcher, and validation surfaces together | + ### Execution / Provenance | Schema | Description | diff --git a/schemas/WorkstationProfile.json b/schemas/WorkstationProfile.json new file mode 100644 index 0000000..648908d --- /dev/null +++ b/schemas/WorkstationProfile.json @@ -0,0 +1,67 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.srcos.ai/v2/WorkstationProfile.json", + "title": "WorkstationProfile", + "description": "A typed SourceOS workstation profile tying together package layers, desktop posture, launcher surfaces, and validation entrypoints.", + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "type", + "specVersion", + "name", + "channel" + ], + "properties": { + "id": { + "type": "string", + "pattern": "^urn:srcos:workstation-profile:", + "description": "Stable URN identifier. Pattern: urn:srcos:workstation-profile:." + }, + "type": { + "const": "WorkstationProfile", + "description": "Discriminator constant — always \"WorkstationProfile\"." + }, + "specVersion": { + "type": "string", + "description": "Spec version of this document, e.g. \"2.1.0\"." + }, + "name": { + "type": "string", + "minLength": 1, + "description": "Human-readable workstation profile name." + }, + "channel": { + "type": "string", + "minLength": 1, + "description": "Realization channel such as linux-dev or linux-stable." + }, + "packageManifestRef": { + "type": ["string", "null"], + "description": "Optional reference to the PackageManifest defining layered package sets." + }, + "desktopProfileRef": { + "type": ["string", "null"], + "description": "Optional reference to the DesktopProfile defining desktop posture." + }, + "launcherProviderRef": { + "type": ["string", "null"], + "description": "Optional reference to the primary LauncherProvider." + }, + "launcherActionRefs": { + "type": "array", + "items": { "type": "string" }, + "description": "Optional references to LauncherAction objects surfaced by this workstation profile." + }, + "validation": { + "type": "object", + "additionalProperties": false, + "properties": { + "doctorCommand": { "type": ["string", "null"] }, + "statusCommand": { "type": ["string", "null"] }, + "searchCommand": { "type": ["string", "null"] } + }, + "description": "Operator-facing validation and inspection entrypoints." + } + } +}