From bbaad073dda7175b830705c49fcc4ffcdc67c7da Mon Sep 17 00:00:00 2001 From: Jelle Spreeuwenberg Date: Sun, 6 Sep 2026 14:57:30 +0200 Subject: [PATCH] fix: restore workflow ownership and pilot gates --- docs/plans/workflow-system.md | 87 ++++++++++++++---- docs/workflow-discovery.md | 28 ++++-- modules/capabilities/desktop-defaults.nix | 105 ++++++++++++---------- 3 files changed, 151 insertions(+), 69 deletions(-) diff --git a/docs/plans/workflow-system.md b/docs/plans/workflow-system.md index caf23b9..a2de2e1 100644 --- a/docs/plans/workflow-system.md +++ b/docs/plans/workflow-system.md @@ -2,9 +2,9 @@ Source: [`../workflow-discovery.md`](../workflow-discovery.md) -The declarative workflow implementation is complete. This file is the living -handoff for operational constraints and external gates; implementation history -is available in Git. +The declarative workflow core is complete; pilots remain. This file is the +living handoff for operational constraints and external gates; implementation +history is available in Git. ## Activation boundary @@ -29,28 +29,37 @@ restarted Kitty and closed the user's terminal session. ## Current checkpoint -- State: declarative implementation and autonomous verification complete. +- State: declarative core complete; corrective activation and pilots remain. - Branch: `chore/workflow-system`. -- Validation: `nix flake check --no-build --quiet` plus no-link Zenith and Orion - system builds passed on 2026-09-06 after Orion became the sole transcription - owner. The expected dirty-tree and unknown `modules` warnings were emitted. +- Validation: `nix flake check --no-build --quiet`, all three no-link system + builds, generated Zenith and Polaris Niri validation, and all six companion + flake evaluations passed on 2026-09-06. The updated data-science shell exposes + Python 3.14.7 and its full project check passes. The expected dirty-tree and + unknown `modules` warnings were emitted. - Live state: Walker project and terminal actions, daily notes, stable web apps, Evolution D-Bus activation, the Zenith VPN, invocation-scoped GitHub and Context7 credentials, Pinta, and Orion transcription passed their completed pilots. -## External or deferred gates +## Active pilot gates These gates do not block work on each other. -- During a docked Zenith session, capture the external display's stable identity - and test the two-output `Super+A` exchange. The current recorded session exposed - only `eDP-1`. -- Resume Evolution only when the user chooses to configure the personal, - old-personal, university, work, and Radicale accounts. Keep Thunderbird and - Outlook until the daily-use gate passes. -- On Android, complete the DAVx5/Radicale and Tasks.org pilots, including default - accounts, recurrence, reminders, and Microsoft To Do within documented limits. +- Add `RabbitMQ — TEST` for `https://test.rabbitmq.yookr.org` and + `RabbitMQ — LIVE` for `https://rabbitmq.yookr.org` to a Vivaldi `Operations` + bookmark folder. Vivaldi remains the bookmark owner. +- Supply approved test RabbitMQ management credentials at runtime, then verify + the Nix-provided client without installing it permanently: + + ```console + RABBITMQADMIN_BASE_URI=https://test.rabbitmq.yookr.org nix run --quiet nixpkgs#rabbitmqadmin-ng -- show overview + RABBITMQADMIN_BASE_URI=https://test.rabbitmq.yookr.org nix run --quiet nixpkgs#rabbitmqadmin-ng -- queues list + ``` + + Export `RABBITMQADMIN_USERNAME` and `RABBITMQADMIN_PASSWORD` from the approved + credential source first; do not place their values in documentation or shell + history. Keep publishing, getting, and purge visibly interactive in the + management UI. - Supply one real Yookr S3 task, a least-privileged remote, and explicit permission for any upload. `rclone` is installed; no remote or wrapper is preconfigured. - Deploy a GET image exposing `/full-api-docs/openapi.json`, then rerun @@ -64,6 +73,36 @@ These gates do not block work on each other. - Wait for a real Monday ticket before adding anything beyond native GitHub, Herdr, Git, and worktree workflows. +The Herdr pilot passes only when short, long, and approval-blocked sessions have +accurate attention state; detach and reattach preserve output; one Claude or Pi +fallback works; and each completed event produces exactly one notification. +Create two independently writing, non-overlapping task worktrees under +`~/dev/work/.worktrees//`, explicitly authorize each +`.envrc`, and confirm paths are predictable, dirty removal is refused, and the +branches remain for review. If a component fails, fall back independently to +native agent sessions and Codex TUI notifications or native +`git worktree add/list/remove`; do not add a wrapper or Worktrunk yet. + +## Deferred pilots + +- During a docked Zenith session, capture the external display's stable identity + and test the two-output `Super+A` exchange. The current recorded session exposed + only `eDP-1`. +- Resume Evolution only when the user chooses to configure the personal, + old-personal, university, work, and Radicale accounts. Keep Thunderbird and + Outlook until the daily-use gate passes. +- On Android, complete the DAVx5/Radicale and Tasks.org pilots, including default + accounts, recurrence, reminders, and Microsoft To Do within documented limits. +- Do not replicate the workstation workflow on Polaris until the user resumes + the procedure below. + +The Niri pilot is two-output-only. It passes when the active workspaces exchange +physical outputs, both arrivals are active, original names are preserved, and +focus returns to the original physical output. Any temporary names must be +collision-free and restored on success or failure; missing output or workspace +state must leave the session unchanged. Keep the helper only after repeated +reliable swaps with an acceptable visible transition. + ## Deferred Polaris replication Do not access or test Polaris unless the user resumes this deferred replication. @@ -81,6 +120,11 @@ Zenith's result remains representative meanwhile. 7. Create mode-0600 `~/.config/context7/api-key` without a trailing newline, restart Codex after activation, and run one Context7 lookup. +Replication passes only when the VPN has the expected route and DNS behavior, +reaches a test service, reconnects after disconnect and suspend, and survives a +reboot without autoconnecting. The two credential files must remain mode 0600; +the fresh-shell GitHub read and restarted-Codex Context7 lookup must both work. + ## Durable implementation decisions - Active work repositories live under `~/dev/work`, archives under `.archive`, @@ -88,6 +132,12 @@ Zenith's result remains representative meanwhile. - Participating repositories expose non-mutating direnv shells, minimal flake checks, native commands through `just`, concise `AGENTS.md`, and machine-local credential inputs. +- `yookr-data-science/conf/local/credentials.yml` is an approved narrow + application-owned exception to the external credential-file default: Kedro's + named credential dataset resolves it from the native ignored `conf/local` + hierarchy. Keep it untracked and mode 0600. +- `yookr-data-science` follows ordinary `nixos-unstable`, like the other + companion repositories; it needs no `devenv-nixpkgs` compatibility input. - `yookr-workbench` starts with cross-system work only; isolation and additional tools wait for observed needs. - Walker's native Elephant menu scans repository roots and calls one Nix-owned @@ -111,5 +161,6 @@ Zenith's result remains representative meanwhile. ## Next step -Continue an external pilot only when its real input arrives. Otherwise no workflow -implementation action remains. +Activate the verified corrective generation on Zenith, confirm Vivaldi cannot +replace the managed launchers, then collect all inputs for the active pilots +before running them in the order RabbitMQ, OpenAPI/API, workbench, S3, and Herdr. diff --git a/docs/workflow-discovery.md b/docs/workflow-discovery.md index 909dc76..c7731ec 100644 --- a/docs/workflow-discovery.md +++ b/docs/workflow-discovery.md @@ -1,7 +1,7 @@ # Workflow system blueprint -Status: implemented. Current external gates and operational handoff live in -[`plans/workflow-system.md`](plans/workflow-system.md). +Status: declarative core implemented; pilots remain. Current gates and the +operational handoff live in [`plans/workflow-system.md`](plans/workflow-system.md). This document is the durable design for the workstation and surrounding Yookr workflow. Implementation history belongs in Git. @@ -111,6 +111,8 @@ copied application state. the repository root, starts Neovim, and leaves a shell after Neovim exits. - Vivaldi remains the bookmark and web-app authority. Home Manager owns stable launchers for Actual, WhatsApp, and Outlook without duplicating browser state. + Its `Operations` folder owns visibly labeled test/live RabbitMQ bookmarks; + terminal inspection uses the Nix-provided `rabbitmqadmin-ng` on demand. - Niri keeps dynamic general-purpose workspaces and a compact navigation and movement vocabulary. The two-output active-workspace exchange remains a bounded pilot. @@ -141,15 +143,18 @@ synchronization. The accepted `yookr-vpn.ovpn` is a narrow exception for Zenith and Polaris: keep it user-restricted and import it into NetworkManager without printing or committing its contents. +`yookr-data-science/conf/local/credentials.yml` is a separate application-owned +exception: Kedro resolves its named credential dataset through the conventional +ignored `conf/local` hierarchy. Keep the file untracked and mode 0600; do not +generalize the exception to other repositories. + Only the user activates a NixOS or Home Manager generation. Agents may evaluate and build configurations, then provide an activation command. ## Remaining pilots -- Capture Zenith's external display identity during a docked session and test the - two-output `Super+A` exchange. -- Resume Evolution and Android PIM only when the user chooses to run those daily - use pilots. +- Verify the labeled RabbitMQ test/live bookmarks and a read-only test overview + plus queue listing through an invocation-scoped `rabbitmqadmin-ng` run. - Add workbench database connections and a Marimo report only for a real cross-system investigation. - Configure an S3 remote only for a real task with least-privileged credentials @@ -157,9 +162,20 @@ and build configurations, then provide an activation command. - Rerun the Yookr OpenAPI refresh after the deployed image exposes `/full-api-docs/openapi.json`; run authenticated API checks only with current user credentials. +- Run the complete Herdr notification, fallback-agent, and safe worktree pilot + with a real Monday ticket. - Keep Bruno, DBeaver, and existing PIM clients until their independent gates are resolved. +## Deferred pilots + +- Capture Zenith's external display identity during a docked session and test the + two-output `Super+A` exchange, including name and focus restoration on failure. +- Resume Evolution and Android PIM only when the user chooses to run those daily + use pilots. +- Replicate the proven workstation workflow on Polaris only when the user resumes + its machine-local VPN and credential procedure. + ## Deferred work - Define the team release process and OpenAPI publication policy before encoding diff --git a/modules/capabilities/desktop-defaults.nix b/modules/capabilities/desktop-defaults.nix index ac68edf..a36f027 100644 --- a/modules/capabilities/desktop-defaults.nix +++ b/modules/capabilities/desktop-defaults.nix @@ -34,6 +34,56 @@ actualId = "ahoihnifhakgijcmjlhbcgehigihinlo"; outlookId = "eoficlgicibekocmfdomjbfnjmehnhcd"; whatsappId = "hnpfjngllnobngcgfapefoaidbinmjnm"; + actualDesktop = pkgs.makeDesktopItem { + name = "vivaldi-${actualId}-Default"; + desktopName = "Actual"; + exec = appCommand actualId; + icon = "vivaldi-${actualId}-Default"; + extraConfig.StartupWMClass = "crx_${actualId}"; + actions = { + Accounts = { + name = "Accounts"; + exec = "${appCommand actualId} --app-launch-url-for-shortcuts-menu-item=${config.facts.services.actual.origin}/accounts"; + }; + "Add-Transaction" = { + name = "Add Transaction"; + exec = "${appCommand actualId} --app-launch-url-for-shortcuts-menu-item=${config.facts.services.actual.origin}/transactions/new"; + }; + Reports = { + name = "Reports"; + exec = "${appCommand actualId} --app-launch-url-for-shortcuts-menu-item=${config.facts.services.actual.origin}/reports"; + }; + }; + }; + whatsappDesktop = pkgs.makeDesktopItem { + name = "vivaldi-${whatsappId}-Default"; + desktopName = "WhatsApp Web"; + exec = appCommand whatsappId; + icon = "vivaldi-${whatsappId}-Default"; + extraConfig.StartupWMClass = "crx_${whatsappId}"; + }; + outlookDesktop = pkgs.makeDesktopItem { + name = "vivaldi-${outlookId}-Default"; + desktopName = "Outlook"; + exec = "${appCommand outlookId} %U"; + icon = "vivaldi-${outlookId}-Default"; + mimeTypes = [ "x-scheme-handler/mailto" ]; + extraConfig.StartupWMClass = "crx_${outlookId}"; + actions = { + Calendar = { + name = "Open calendar"; + exec = "${appCommand outlookId} --app-launch-url-for-shortcuts-menu-item=https://outlook.cloud.microsoft/calendar"; + }; + Compose = { + name = "New message"; + exec = "${appCommand outlookId} --app-launch-url-for-shortcuts-menu-item=https://outlook.cloud.microsoft/mail/deeplink/compose"; + }; + Event = { + name = "New event"; + exec = "${appCommand outlookId} --app-launch-url-for-shortcuts-menu-item=https://outlook.cloud.microsoft/calendar/deeplink/compose"; + }; + }; + }; in { desktop.commands.browser = [ command ]; @@ -42,53 +92,18 @@ sessionVariables.BROWSER = command; }; xdg = { - desktopEntries = { - "vivaldi-${actualId}-Default" = { - name = "Actual"; - exec = appCommand actualId; - icon = "vivaldi-${actualId}-Default"; - settings.StartupWMClass = "crx_${actualId}"; - actions = { - Accounts = { - name = "Accounts"; - exec = "${appCommand actualId} --app-launch-url-for-shortcuts-menu-item=${config.facts.services.actual.origin}/accounts"; - }; - "Add-Transaction" = { - name = "Add Transaction"; - exec = "${appCommand actualId} --app-launch-url-for-shortcuts-menu-item=${config.facts.services.actual.origin}/transactions/new"; - }; - Reports = { - name = "Reports"; - exec = "${appCommand actualId} --app-launch-url-for-shortcuts-menu-item=${config.facts.services.actual.origin}/reports"; - }; - }; + dataFile = { + "applications/vivaldi-${actualId}-Default.desktop" = { + force = true; + source = "${actualDesktop}/share/applications/vivaldi-${actualId}-Default.desktop"; }; - "vivaldi-${whatsappId}-Default" = { - name = "WhatsApp Web"; - exec = appCommand whatsappId; - icon = "vivaldi-${whatsappId}-Default"; - settings.StartupWMClass = "crx_${whatsappId}"; + "applications/vivaldi-${whatsappId}-Default.desktop" = { + force = true; + source = "${whatsappDesktop}/share/applications/vivaldi-${whatsappId}-Default.desktop"; }; - "vivaldi-${outlookId}-Default" = { - name = "Outlook"; - exec = "${appCommand outlookId} %U"; - icon = "vivaldi-${outlookId}-Default"; - mimeType = [ "x-scheme-handler/mailto" ]; - settings.StartupWMClass = "crx_${outlookId}"; - actions = { - Calendar = { - name = "Open calendar"; - exec = "${appCommand outlookId} --app-launch-url-for-shortcuts-menu-item=https://outlook.cloud.microsoft/calendar"; - }; - Compose = { - name = "New message"; - exec = "${appCommand outlookId} --app-launch-url-for-shortcuts-menu-item=https://outlook.cloud.microsoft/mail/deeplink/compose"; - }; - Event = { - name = "New event"; - exec = "${appCommand outlookId} --app-launch-url-for-shortcuts-menu-item=https://outlook.cloud.microsoft/calendar/deeplink/compose"; - }; - }; + "applications/vivaldi-${outlookId}-Default.desktop" = { + force = true; + source = "${outlookDesktop}/share/applications/vivaldi-${outlookId}-Default.desktop"; }; }; mimeApps.defaultApplicationPackages = [ pkgs.vivaldi ];