diff --git a/docs/sourceos-shell-integration.md b/docs/sourceos-shell-integration.md index b0be40a..9f365a9 100644 --- a/docs/sourceos-shell-integration.md +++ b/docs/sourceos-shell-integration.md @@ -11,6 +11,7 @@ This repository, `source-os`, carries the Linux realization surfaces required to - Nix/NixOS modules - profile wiring - machine-level integration hooks +- derive-service runtime integration such as `docd` ## What does not belong here diff --git a/docs/sourceos-shell-launcher-bridge.md b/docs/sourceos-shell-launcher-bridge.md new file mode 100644 index 0000000..87287df --- /dev/null +++ b/docs/sourceos-shell-launcher-bridge.md @@ -0,0 +1,28 @@ +# sourceos-shell launcher bridge note + +During the early shell rollout, launcher integration is tracked as temporary bridge work. + +## Routing rule + +Queries are routed by scope: + +- `apps` -> launcher or desktop-entry provider +- `files` -> Linux-native file search only +- `web` -> browser or web agent + +## Required invariant + +For `files` queries, Albert must not perform a second file-search pass in parallel with the Linux-native provider. + +## Realization scaffolds + +The Linux realization currently carries placeholder search-provider material at: + +- `linux/desktop/sourceos-search-provider.conf` +- `/etc/sourceos-shell/search-provider.json` (realized by the shell Nix module scaffold) + +These capture the intended rollout mode and the provider choice for the Linux-native file search lane. + +## Lifecycle + +This bridge exists only until the shell's own command/search surface fully absorbs the routing behavior. diff --git a/docs/sourceos-shell-service-graph.md b/docs/sourceos-shell-service-graph.md new file mode 100644 index 0000000..e7df946 --- /dev/null +++ b/docs/sourceos-shell-service-graph.md @@ -0,0 +1,30 @@ +# sourceos-shell service graph note + +The Linux realization layer currently models the `sourceos-shell` runtime as a four-service graph: + +- `sourceos-shell` +- `sourceos-router` +- `sourceos-pdf-secure` +- `sourceos-docd` + +These services are grouped by the `sourceos-shell.target` scaffold. + +## Intent + +This target is a Linux realization placeholder that captures the expected runtime grouping before the actual product/runtime repo exists. + +## Validation scaffold + +The current Linux realization adds a dedicated contract-style check at: + +- `tests/sourceos-shell-service-graph-contract.nix` + +This check verifies that: + +- `sourceos-shell.target` exists +- the four runtime scaffold services are grouped beneath that target +- the Nix module expresses the target and `partOf` relationships consistently + +## Follow-on + +Once `SourceOS-Linux/sourceos-shell` exists, the placeholder ExecStart values should be replaced with real package/service paths and the current scaffold checks should be upgraded into actual runtime/service-graph checks. diff --git a/flake.nix b/flake.nix index 507321e..3a9c42d 100644 --- a/flake.nix +++ b/flake.nix @@ -65,6 +65,9 @@ else pkgs.runCommand "stable-x86_64-smoke-skip" {} '' mkdir -p $out ''; + + sourceos-shell-module-contract = import ./tests/sourceos-shell-module-contract.nix { inherit pkgs; }; + sourceos-shell-service-graph-contract = import ./tests/sourceos-shell-service-graph-contract.nix { inherit pkgs; }; }); sourceos = { diff --git a/linux/desktop/sourceos-search-provider.conf b/linux/desktop/sourceos-search-provider.conf new file mode 100644 index 0000000..dc610ce --- /dev/null +++ b/linux/desktop/sourceos-search-provider.conf @@ -0,0 +1,11 @@ +# SourceOS shell search-provider scaffold +# This file records the intended launcher/search routing policy during early shell rollout. + +mode=launcher-bridge +linux-file-provider=tracker3 +invariant=no_redundant_file_search + +# scopes +apps=launcher +files=linux-native-only +web=browser-agent diff --git a/linux/systemd/sourceos-docd.service b/linux/systemd/sourceos-docd.service new file mode 100644 index 0000000..b34e30c --- /dev/null +++ b/linux/systemd/sourceos-docd.service @@ -0,0 +1,13 @@ +[Unit] +Description=SourceOS docd derive service +After=network-online.target +Wants=network-online.target + +[Service] +Type=simple +ExecStart=/opt/sourceos-shell/bin/sourceos-docd +Restart=on-failure +RestartSec=2s + +[Install] +WantedBy=multi-user.target diff --git a/linux/systemd/sourceos-shell.target b/linux/systemd/sourceos-shell.target new file mode 100644 index 0000000..d3a2937 --- /dev/null +++ b/linux/systemd/sourceos-shell.target @@ -0,0 +1,4 @@ +[Unit] +Description=SourceOS shell service graph +Wants=sourceos-shell.service sourceos-router.service sourceos-pdf-secure.service sourceos-docd.service +After=network-online.target diff --git a/modules/nixos/sourceos-shell/default.nix b/modules/nixos/sourceos-shell/default.nix index 7ae9e9a..72dfa3d 100644 --- a/modules/nixos/sourceos-shell/default.nix +++ b/modules/nixos/sourceos-shell/default.nix @@ -35,6 +35,20 @@ in default = 7073; description = "Local port for the sourceos-shell derive/docd service."; }; + + searchProvider = { + mode = lib.mkOption { + type = lib.types.enum [ "linux-native" "launcher-bridge" "shell-native" ]; + default = "launcher-bridge"; + description = "Search routing mode during shell rollout."; + }; + + linuxFileProvider = lib.mkOption { + type = lib.types.enum [ "tracker3" "fd" "locate" ]; + default = "tracker3"; + description = "Linux-native file search provider used when scope=files."; + }; + }; }; config = lib.mkIf cfg.enable { @@ -45,11 +59,32 @@ in routerPort=${toString cfg.routerPort} pdfSecurePort=${toString cfg.pdfSecurePort} docdPort=${toString cfg.docdPort} + searchProvider.mode=${cfg.searchProvider.mode} + searchProvider.linuxFileProvider=${cfg.searchProvider.linuxFileProvider} ''; + environment.etc."sourceos-shell/search-provider.json".text = builtins.toJSON { + mode = cfg.searchProvider.mode; + linuxFileProvider = cfg.searchProvider.linuxFileProvider; + invariant = "no_redundant_file_search"; + scopes = { + apps = "launcher"; + files = "linux-native-only"; + web = "browser-agent"; + }; + }; + + systemd.targets.sourceos-shell = { + description = "SourceOS shell service graph"; + wants = [ "sourceos-shell.service" "sourceos-router.service" "sourceos-pdf-secure.service" "sourceos-docd.service" ]; + after = [ "network-online.target" ]; + wantedBy = [ "multi-user.target" ]; + }; + systemd.services.sourceos-shell = { description = "SourceOS shell runtime scaffold"; wantedBy = [ "multi-user.target" ]; + partOf = [ "sourceos-shell.target" ]; serviceConfig = { Type = "simple"; ExecStart = "${pkgs.coreutils}/bin/echo sourceos-shell runtime placeholder root=${cfg.packageRoot} port=${toString cfg.shellPort}"; @@ -59,6 +94,7 @@ in systemd.services.sourceos-router = { description = "SourceOS shell router scaffold"; wantedBy = [ "multi-user.target" ]; + partOf = [ "sourceos-shell.target" ]; serviceConfig = { Type = "simple"; ExecStart = "${pkgs.coreutils}/bin/echo sourceos-router placeholder port=${toString cfg.routerPort}"; @@ -68,10 +104,21 @@ in systemd.services.sourceos-pdf-secure = { description = "SourceOS shell pdf-secure scaffold"; wantedBy = [ "multi-user.target" ]; + partOf = [ "sourceos-shell.target" ]; serviceConfig = { Type = "simple"; ExecStart = "${pkgs.coreutils}/bin/echo sourceos-pdf-secure placeholder port=${toString cfg.pdfSecurePort}"; }; }; + + systemd.services.sourceos-docd = { + description = "SourceOS shell docd scaffold"; + wantedBy = [ "multi-user.target" ]; + partOf = [ "sourceos-shell.target" ]; + serviceConfig = { + Type = "simple"; + ExecStart = "${pkgs.coreutils}/bin/echo sourceos-docd placeholder port=${toString cfg.docdPort}"; + }; + }; }; } diff --git a/profiles/linux-dev/default.nix b/profiles/linux-dev/default.nix index f2ef598..678d171 100644 --- a/profiles/linux-dev/default.nix +++ b/profiles/linux-dev/default.nix @@ -2,6 +2,7 @@ { imports = [ ../../modules/build/default.nix + ../../profiles/linux-dev/sourceos-shell.nix ]; sourceos.build = { diff --git a/tests/sourceos-shell-module-contract.nix b/tests/sourceos-shell-module-contract.nix new file mode 100644 index 0000000..dc8b6c6 --- /dev/null +++ b/tests/sourceos-shell-module-contract.nix @@ -0,0 +1,24 @@ +{ pkgs ? import {} }: +pkgs.runCommand "sourceos-shell-module-contract" { + nativeBuildInputs = [ pkgs.gnugrep ]; +} '' + test -f ${../modules/nixos/sourceos-shell/default.nix} + test -f ${../profiles/linux-dev/sourceos-shell.nix} + test -f ${../linux/desktop/sourceos-shell.desktop} + test -f ${../linux/desktop/sourceos-search-provider.conf} + test -f ${../linux/systemd/sourceos-shell.service} + test -f ${../linux/systemd/sourceos-router.service} + test -f ${../linux/systemd/sourceos-pdf-secure.service} + test -f ${../linux/systemd/sourceos-docd.service} + test -f ${../linux/systemd/sourceos-shell.target} + grep -q '../../modules/nixos/sourceos-shell/default.nix' ${../profiles/linux-dev/sourceos-shell.nix} + grep -q 'sourceos.shell' ${../modules/nixos/sourceos-shell/default.nix} + grep -q 'sourceos-docd' ${../modules/nixos/sourceos-shell/default.nix} + grep -q 'searchProvider' ${../modules/nixos/sourceos-shell/default.nix} + grep -q 'systemd.targets.sourceos-shell' ${../modules/nixos/sourceos-shell/default.nix} + grep -q 'partOf = \[ "sourceos-shell.target" \]' ${../modules/nixos/sourceos-shell/default.nix} + grep -q 'no_redundant_file_search' ${../linux/desktop/sourceos-search-provider.conf} + grep -q 'sourceos-shell.service sourceos-router.service sourceos-pdf-secure.service sourceos-docd.service' ${../linux/systemd/sourceos-shell.target} + mkdir -p $out + echo validated > $out/result.txt +'' diff --git a/tests/sourceos-shell-service-graph-contract.nix b/tests/sourceos-shell-service-graph-contract.nix new file mode 100644 index 0000000..adac31a --- /dev/null +++ b/tests/sourceos-shell-service-graph-contract.nix @@ -0,0 +1,12 @@ +{ pkgs ? import {} }: +pkgs.runCommand "sourceos-shell-service-graph-contract" { + nativeBuildInputs = [ pkgs.gnugrep ]; +} '' + test -f ${../linux/systemd/sourceos-shell.target} + grep -q 'sourceos-shell.service sourceos-router.service sourceos-pdf-secure.service sourceos-docd.service' ${../linux/systemd/sourceos-shell.target} + grep -q 'systemd.targets.sourceos-shell' ${../modules/nixos/sourceos-shell/default.nix} + grep -q 'partOf = \[ "sourceos-shell.target" \]' ${../modules/nixos/sourceos-shell/default.nix} + grep -q 'sourceos-shell.target' ${../docs/sourceos-shell-service-graph.md} + mkdir -p $out + echo validated > $out/result.txt +''