From 705c30c059e741ac8edf3c938c06d066c99ad8a2 Mon Sep 17 00:00:00 2001 From: administrator Date: Thu, 1 Oct 2026 22:51:17 +0000 Subject: [PATCH 1/2] Install Herdr's omp state integration on every apply Without herdr-omp-agent-state.ts Herdr shows every omp agent as idle. herdr.yml now runs `herdr integration install omp` with the managed herdr (agents profile), reporting changed only when the file's checksum changed; verify.yml asserts `herdr integration status` reports `omp: current`. Docs drop the manual host-move step. --- ansible/group_vars/all.yml | 2 ++ ansible/tasks/herdr.yml | 39 ++++++++++++++++++++++++++++++++++++++ ansible/tasks/verify.yml | 22 ++++++++++++++++++++- docs/agent-host-move.md | 2 +- docs/herdr.md | 4 ++++ 5 files changed, 67 insertions(+), 2 deletions(-) diff --git a/ansible/group_vars/all.yml b/ansible/group_vars/all.yml index af78c93..c3b5449 100644 --- a/ansible/group_vars/all.yml +++ b/ansible/group_vars/all.yml @@ -203,6 +203,8 @@ factory_omp_sidebar_extension: "{{ factory_cfg.home }}/.omp/agent/extensions/cod factory_omp_status_icons_extension: "{{ factory_cfg.home }}/.omp/agent/extensions/aa-mode-icons.ts" # Blocks pkill/killall/kill-by-pgrep in every omp session (docs/omp.md). factory_omp_no_pattern_kill_extension: "{{ factory_cfg.home }}/.omp/agent/extensions/fm-no-pattern-kill.ts" +# Herdr's own omp state extension; `herdr integration install omp` writes it (docs/herdr.md). +factory_herdr_omp_integration: "{{ factory_cfg.home }}/.omp/agent/extensions/herdr-omp-agent-state.ts" # omp as the no-mistakes pi agent, and the omp overlay only daemon-spawned omp # loads (docs/omp.md#no-mistakes-pipeline-agent). factory_omp_as_pi_dir: "{{ factory_cfg.home }}/.no-mistakes/omp-as-pi" diff --git a/ansible/tasks/herdr.yml b/ansible/tasks/herdr.yml index 3d44847..7f74eb1 100644 --- a/ansible/tasks/herdr.yml +++ b/ansible/tasks/herdr.yml @@ -180,3 +180,42 @@ become_user: "{{ factory_cfg.user }}" environment: "{{ factory_user_systemd_env }}" when: factory_manage_services | bool + +# Herdr's own omp extension reports each omp pane's state (working, blocked, +# idle) to the sidebar; without it every omp agent shows as idle. herdr refuses +# to install it until the omp extensions directory exists. Every apply runs the +# install so a herdr upgrade refreshes it; the checksum comparison reports a +# change only when herdr rewrote the file. +- name: Install Herdr's omp state integration + when: + - factory_cfg.profiles.agents | bool + - not ansible_check_mode + block: + - name: Ensure the omp extensions directory + ansible.builtin.file: + path: "{{ factory_herdr_omp_integration | dirname }}" + state: directory + owner: "{{ factory_cfg.user }}" + group: "{{ factory_group }}" + mode: "0755" + become: true + + - name: Checksum the Herdr omp integration before install + ansible.builtin.stat: + path: "{{ factory_herdr_omp_integration }}" + become: true + register: factory_herdr_omp_before + + - name: Run herdr integration install omp + ansible.builtin.command: + argv: ["{{ factory_herdr_bin }}", integration, install, omp] + changed_when: false + + - name: Checksum the Herdr omp integration after install + ansible.builtin.stat: + path: "{{ factory_herdr_omp_integration }}" + become: true + register: factory_herdr_omp_after + changed_when: >- + factory_herdr_omp_after.stat.checksum | default('') + != factory_herdr_omp_before.stat.checksum | default('') diff --git a/ansible/tasks/verify.yml b/ansible/tasks/verify.yml index 504908a..0f7eb41 100644 --- a/ansible/tasks/verify.yml +++ b/ansible/tasks/verify.yml @@ -5,7 +5,7 @@ # changed_when: false, so verification can never make a second apply report a # change. Individual task files already assert their own outputs; this file # checks the wiring that crosses them - the Herdr and omp releases this run -# resolved, the static enablement symlinks, the managed shell environment, the pruner runtime, the +# resolved, Herdr's omp integration, the static enablement symlinks, the managed shell environment, the pruner runtime, the # Firstmate revision this run resolved and the loopback-only desktop listeners. # # A check-mode run cannot observe files it did not create, so verification @@ -225,6 +225,26 @@ check_mode: false when: factory_cfg.profiles.agents | bool + # Without Herdr's omp integration every omp pane shows as idle in the sidebar. + - name: Read the Herdr integration status + ansible.builtin.command: + argv: ["{{ factory_herdr_bin }}", integration, status] + register: factory_verify_herdr_integrations + changed_when: false + check_mode: false + when: factory_cfg.profiles.agents | bool + + - name: Assert Herdr's omp integration is current + ansible.builtin.assert: + that: + - "factory_verify_herdr_integrations.stdout is search('(?m)^omp: current')" + fail_msg: >- + `herdr integration status` does not report `omp: current`, so Herdr + shows every omp agent as idle: + {{ factory_verify_herdr_integrations.stdout_lines | select('match', 'omp:') | join(' ') }} + quiet: true + when: factory_cfg.profiles.agents | bool + # --- managed shell environment ----------------------------------------- - name: Read the account profile diff --git a/docs/agent-host-move.md b/docs/agent-host-move.md index 58e84c1..7ce5be2 100644 --- a/docs/agent-host-move.md +++ b/docs/agent-host-move.md @@ -41,7 +41,7 @@ Services that hold state other hosts share, such as a model relay, a monitoring | systemd user units | Apply writes its own. After apply, list what the new host lacks: `comm -23 <(ssh 'ls ~/.config/systemd/user' \| sort) <(ls ~/.config/systemd/user \| sort)`. Move only agent-side units from that list. Never move units for services that stay on the old host, and never copy a unit or drop-in that holds an inline credential ([Never export](security.md#never-export)). | | User crontab | Crontab entries and the scripts they run often name a home's path. After every sync of a home's `data/` to a host where its path differs, run `sed -i 's###g'` on those scripts there. [Cutover](#cutover) comments the entries out on the old host at step 1, adds them with the new path on the new host at step 6, and deletes them on the old host at step 8. | | Hand-installed tools in `~/.local/bin` | After apply, list what the new host lacks: `comm -23 <(ssh 'ls ~/.local/bin' \| sort) <(ls ~/.local/bin \| sort)`. Reinstall each agent-side tool from its source and skip backups. | -| omp rules, extensions and custom models (`~/.omp/agent/rules/`, `extensions/`, `models.yml`) | `rsync -a` them from the old host when they hold no credentials. Then run `herdr integration install omp`, which rewrites Herdr's own extension for the new host's herdr. | +| omp rules, extensions and custom models (`~/.omp/agent/rules/`, `extensions/`, `models.yml`) | `rsync -a --exclude herdr-omp-agent-state.ts` them from the old host when they hold no credentials. Apply already installed Herdr's own omp extension for the new host's herdr ([Pane state](herdr.md#pane-state)). | | omp keys and MCP credentials (`~/.omp/agent/*.key`, `mcp.json`) and each home's `state/secrets/` | Never copy them ([Never export](security.md#never-export)). Recreate each on the new host by hand, mode `600`, entering the keys yourself. | ```bash diff --git a/docs/herdr.md b/docs/herdr.md index 5b674c9..88c6254 100644 --- a/docs/herdr.md +++ b/docs/herdr.md @@ -123,6 +123,10 @@ herdr agent get The result carries `terminal_title` and `tokens.who`, `tokens.pr`, and so on. +### Pane state + +Herdr learns whether an omp agent is working, blocked or idle from its own omp extension, `~/.omp/agent/extensions/herdr-omp-agent-state.ts`. With the `agents` profile on, every `./factory apply` runs `herdr integration install omp` with the herdr it installed, so a herdr upgrade refreshes the extension; apply reports a change only when herdr rewrote the file, and verification fails unless `herdr integration status` reports `omp: current`. Without the extension Herdr shows every omp agent as idle. Apply installs no integration for other agents. + ## Override the layouts or turn parts off Set these keys under `factory.herdr` in `.local/host.yml`, then run `./factory apply`: From f5bd61379cffea76ea76bd2af273c6e7c65ce228 Mon Sep 17 00:00:00 2001 From: administrator Date: Thu, 1 Oct 2026 22:56:03 +0000 Subject: [PATCH 2/2] no-mistakes(review): Document herdr --remote viewer version requirement --- docs/herdr.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/herdr.md b/docs/herdr.md index 88c6254..22fa5a0 100644 --- a/docs/herdr.md +++ b/docs/herdr.md @@ -214,6 +214,8 @@ ssh cat .local/bin/herdr-sidebar-to-client.py | python3 - It copies the host's `sidebar_width`, `sidebar_max_width`, `[ui.sidebar.agents]`, `[ui.sidebar.spaces]` and `[theme.custom] sidebar_bg` into `~/.config/herdr/config.toml` on the viewing machine, or into the path given as a second argument, and leaves every other setting there as is. It writes a timestamped `.bak-sidebar-` copy of that file first. Run it again after the host's layout changes. +Pane state (the sidebar dots) is reported on the host by the omp integration `./factory apply` installs, so the host needs nothing more. A machine that views the host with `herdr --remote` should run the same Herdr release as the host: the host runs the latest, so on the viewing machine run `herdr update`, then compare `herdr --version` with the host's. + ## Known limits - Agents without the extension, including non-omp agents, show only their dot on line 1: nothing reports their `who` token.