Skip to content

Release Notes

ops-release edited this page Sep 6, 2026 · 32 revisions

v3.10.7 — 2026-09-06

Inbox sweep now treats an archived chat as dealt with. The recency floor was overriding the archive flag for anything touched in the last 7 days, so a swept account still reported handled threads as unanswered and inbox zero could not be reached. The corruption net now arms only on stores that still have open chats.

v3.10.6 — 2026-09-06

Fixed — inbox zero was unreachable by construction

Three defects in the inbox toolchain, all found in one live run, all failing the same way: a value was read from configuration, or from one store, when the truth lived somewhere else.

  • A completed inbox-zero run was diagnosed as flag corruption. With every chat archived, ops-inbox-scan fell back to handled=0 as its working set. Nothing in the toolchain ever writes handled, so that predicate matched 1803 of 1806 archived chats and the entire history came back as unanswered asks — 171 false NEEDS_REPLY across two accounts, moments after the inbox was genuinely empty. The better a sweep did its job, the louder the next scan disagreed. The corruption fallback now fires only when handled is demonstrably in use; genuine corruption still recovers the live thread, and the scan states which verdict it reached and why.
  • A reply sent from one WhatsApp number did not count on the other. One person exists in both stores under different jids, and an outgoing message lands only in the store it was sent from — so the second account still saw an unanswered thread and offered a duplicate reply. The scan now reads every other account's store as read-only evidence and demotes those threads with a stated reconciled reason. Auto-discovered; --peer-store names one explicitly, --no-peer-stores disables it. This matters more now that --all-accounts scans both numbers in a single pass.
  • The bridge port came from a launcher script that need not exist. ops-wa-accounts scanned run-bridge.sh for WA_PORT and fell back to 8080, so two bridges started any other way both reported 8080 while actually listening on 8082 and 8083 — pointing every read, archive and reply at one number. The port is now read from the live listening socket via /proc, the same way the phone number is read from the store, and every account reports port_source so a caller can tell a live value from a guess.

Also: ops-inbox-archive-set --dry-run no longer reports zero planned archives on a multi-account box. It refused to count anything when the bridge port was unresolved, including under a dry run that contacts no bridge at all, so the preview silently disagreed with the real run. The refusal now applies only to a live --apply, where a wrong port is unrecoverable.

v3.10.4 - 2026-08-29

  • fix(ops-speedup): stop counting the systemctl legend line as a failed unit (#910). On Linux/WSL a healthy box reported failed_units=1 because systemctl --failed --no-pager prints "0 loaded units listed.", which matched grep -c "loaded". That applied a permanent -5 health penalty and surfaced a false failed-startup-units factor in every scan.

v3.10.4 — 2026-08-29

  • fix(ops): memory extractor, proxy auth, and unread-bridge follow-ups (#908)

v3.10.2 — 2026-08-28

Grok skipped the inbox autosync hook because $INPUT in hooks.json is treated as a required env var.

v3.10.1 — 2026-08-28

Fixed multi-source inbox checks, full-resolution social ads and Google Ads v24, WhatsApp account naming, and a broker socket readiness race.

v3.10.0 — 2026-08-28

Changed

  • feat(skills): relations + vip skills, all config in plugin.json (#902)

v3.9.9 — 2026-08-28

ops-marketing-dash --project no longer inherits the default brand's Amplitude, AppsFlyer, RevenueCat, Klaviyo, or Instagram credentials.

v3.9.8 — 2026-08-28

PreToolUse WhatsApp bridge health reads the event from stdin. Do not interpolate $TOOL_INPUT in hook command strings (Grok skips the hook when that env var is unset).

v3.9.7 — 2026-08-28

WhatsApp client bridges resolve from plugin-written $PREFS_PATH / registry; no guessed :8080.

v3.9.5 — 2026-08-26

Fixed

  • Stop an untrusted request path from re-pointing the auto-router (#885).
  • Replace gh run watch in deploy-fix with bounded REST polling (#886).
  • Stop the MCP repair agent mutating cloud infrastructure (#887).

v3.9.2 — 2026-08-24

Fixed

  • /flow now resolves its lifecycle reference on macOS (renamed the skill's internal map file to avoid a case-insensitive filename collision).

v3.9.1 — 2026-08-24

Fixed

  • FLOW now routes the full installed toolchain instead of only part of it, so commands are dispatched to the right tool.
  • Corrected an unquoted heredoc in the registry sync script that could expand shell variables in its output.

v3.9.0 — 2026-08-23

Added

  • ops-ar taste profile injection. When ar.profile exists in preferences, the whole object is injected into every ar-producer spawn so verdicts are calibrated to the owner's own catalog, tempo range and songwriting taste, and REFERENCE & POSITIONING names the closest catalog comparison instead of a generic genre act. Absent profile falls back to the generic default and says so in the card header.
  • ops-ar imprint gate. Imprints defined under ar.imprints get an IMPRINT section on the A&R card, scored against that imprint's own ten-point test, plus one routing line. An imprint is a strict subset of the label, so a failed gate routes the release and never downgrades the main verdict.
  • ops-inbox step 0. Reading a thread's own sent messages is now a blocking pre-check on every connected account before anything is classed NEEDS_REPLY. A scan result is a snapshot rather than current state, and a subagent's NEEDS_REPLY is a claim about the moment it looked.

Changed

  • Imprints are data, not code. The imprint gate reads every imprint's name, lane, sound description and test from preferences rather than assuming one hardcoded imprint, so any number of imprints work.
  • Corrected the CRS-removal entry, which listed scripts/crsproxy-reauth/ as deleted. It was kept, holds the Browser Use OAuth reauthentication helpers, and is covered by tests/test-crsproxy-reauth.sh.

Removed

  • Dead gitleaks allowlist entry for the RFC 6238 TOTP vector. The constant is now assembled from fragments, so the full string appears nowhere in the tree and the exclusion had nothing left to excuse.

Migration

  • ar.future_tropical in preferences.json moves to ar.imprints.<key> with a display_name added. Nothing reads the old key, so an unmigrated profile simply skips the IMPRINT section.

v3.8.1 — 2026-08-23

Fixed

  • The release command now aborts instead of proceeding when it cannot read the currently published version, so a release can no longer be cut from an unknown baseline.

Changed

  • Version bumps are derived from the published version rather than local state, keeping release numbering consistent.
  • Added test coverage for profile-first reauth and for version-bump behaviour during releases.

v3.8.0 — 2026-08-22

Changed

  • Specialist discovery no longer loads every skill's context up front. The ops skill now resolves capabilities from a generated reference index and pulls specialist detail only when a command needs it, cutting startup token cost across all ops-* skills.

Fixed

  • Secret scanning no longer fails CI on the published RFC 6238 TOTP test vector, which is a spec example rather than a real credential.

v3.6.2 — 2026-08-22

  • README, INDEX, and harness-ports docs for Claude / Grok / Hermes.

v3.6.1 — 2026-08-22

Slim ops-inbox SKILL.md (~6k → ~2k) and rewrite remaining skill descriptions with real NL triggers. Hermes plugin.yaml and the installer pin stay in lockstep with plugin.json so Claude, Grok, and Hermes ship the same version. Plugin .mcp.json is empty on purpose (MCP starts on demand). See Harness Ports.

v3.6.0 — 2026-08-22

Skills match plugin-dev practice: ops-rules skill (root CLAUDE.md is a pointer), third-person frontmatter and shared preamble on every skill, oversized SKILL.md files split into references/, SessionStart pointer, plugin validate coverage.

v3.5.0 — 2026-08-22

Native Hermes plugin: slash commands, skill_view("ops:*"), Rule 10 harness fallbacks, installer ~/.hermes/plugins/ops.

v3.4.4 — 2026-08-18

Fix boss agent-dash resolution and macOS pressure evidence check

v3.4.3 — 2026-08-18

Fixed

  • WhatsApp bridge LaunchAgent now runs the supervised run-bridge.sh wrapper instead of the bare binary, so a logged-out bridge can no longer request pairing codes unattended (the behaviour that gets an account banned). KeepAlive gains Crashed, and ThrottleInterval goes 60 -> 300.
  • The bridge LaunchAgent template now sets GODEBUG=netdns=go, which the bridge requires on macOS. With the cgo resolver the whatsmeow websocket dies with "failed to read frame header: EOF" and pairing fails as a misleading "Couldn't link device" on the phone.
  • ops-post-update-migrate refuses to install the bridge LaunchAgent when run-bridge.sh is missing, and defers its per-version sentinel so the skip is retried next session instead of becoming permanent.

v3.4.2 — 2026-08-16

Fixed

  • ops-speedup scored a perfect 100/100 from empty probes on macOS. It published probe results with declare -g, which bash 3.2 does not have, and an existing stderr redirect swallowed the error, so every probe variable stayed unset. The assignments are portable now, and the tests run the JSON contract under /bin/bash as well. (#827)
  • The rm -rf guard blocked nothing on stock macOS. (#826)
  • ops-release: a failed CI query no longer strands the release PR. (#820)

Changed

  • ops-inbox: stage drafts as cards, and never end a run with a question. (#821)

v3.4.1 — 2026-08-16

  • ops-release: a failed tag push no longer aborts the run. The release PR has already merged by then, so a dead git transport left main released but untagged. It now resolves main's commit over the REST API when git fetch fails, creates the tag object and ref over the API when git push fails, and names the ref to create if both fail. API calls retry pinned to the other IP family. (#817)
  • ops-sync-docs / ops-release: the badge regex required a - straight after the digits, so a count carrying a URL-encoded + (skills-33%2B-success) never matched and stayed frozen at 33 while the tree grew to 63. It now matches the suffix and drops it — the count is exact, not a floor. (#817)

v3.4.0 — 2026-08-16

  • ops-mac: the application firewall is opt-in. /ops:mac fix no longer offers or recommends enabling it; the audit reports its state and stops. Turning it on breaks local listeners — dev servers, MCP proxies, VNC, tunnels — and the breakage surfaces long after the run. socketfilterfw runs only when the firewall is asked for by name. (#814)
  • ops-inbox no longer hardcodes 127.0.0.1:8080. On a box running one whatsmeow bridge per phone number the lowest port answers first, which bound the skill to whichever number owned 8080 and sent replies from the wrong account. New bin/ops-wa-accounts discovers every bridge and reads the number actually paired in each store. (#815)
  • ops-inbox / ops-comms: port the Hermes ops lessons — triage is not the deliverable, dedupe merged WhatsApp threads by message ID, transcribe outbound voice notes, and an output quality gate to prove before reporting a pass complete. (#813)

v3.3.1 — 2026-08-15

  • The outbound guard now refuses to send from a Gmail send-as alias whose SMTP relay is broken. Such a send fails silently: Gmail stamps the message SENT and drops the delivery failure into Trash, so the sender believes it arrived and the recipient never gets it. The check runs ahead of every path that would otherwise allow the send, including a held approval and the approved-recipient bypass, because a broken relay bounces the mail whoever it was addressed to.
  • When a service account can impersonate the alias, the block message names the command that works. Sending as the mailbox over the API skips the send-as relay entirely and needs no app password, so a "broken" alias is often already reachable.
  • New refresh_broken_aliases.py builds the alias list from Gmail's own bounce threads, reading the failed alias off the SENT message's From header rather than matching addresses in the bounce body. --clear <address> drops an alias after a repair, and an absent or empty list blocks nothing.
  • New gog-sa-token mints a narrow-scope impersonated token. gog requests its whole scope bundle in one call, so a Workspace that delegated only gmail.send and gmail.readonly refuses the entire request, and a mailbox that can in fact send looks unreachable.
  • New tests/outbound-guard/test-broken-alias.py covers the alias path against a throwaway HOME, and clears the shared approval store afterwards so the other guard suites stay order-independent.

v3.3.0 — 2026-08-15

Added

  • Shared outbound guard that gates every outbound send through one code path, with matching hook entry points for Python and Node callers.
  • Test suite for the guard covering the hook matrix, false positives, and shared-guard behaviour.
  • Approval helper for granting a send, plus a README documenting how the gate works and how to wire it up.

Changed

  • ops-comms and ops-inbox now route sends through the shared guard instead of their own checks.

v3.1.5 — 2026-08-15

Added: bin/ops-fleet-pool-snapshot fetches a sanitized read-only CLIProxyAPI pool snapshot from a remote helper over ssh, and ops-fleet is reworked into a read-only session plus gateway dashboard that uses it. The helper restricts the remote path to a plain safe-character path, rejects a destination or user beginning with a dash so ssh cannot read it as an option, confines the timeout to digits, and validates the remote output as JSON before emitting it. Fixed: ops-inbox now rechecks the live thread tail immediately before every send. Approval is not a license to fire a stale draft, so between the approval and the send call it re-reads the real channel for new inbound arriving after the draft was staged and for replies already sent from another session, the phone, or a different client, and rebuilds or drops the draft instead of double-replying. A scan from earlier in the same run does not count as current state.

v3.1.4 — 2026-08-15

Fixed: apply-patches.py Fix Q no longer appends a duplicate /api/app_state_status route. The idempotency sentinel matched the comment above the handler, which Fix Y later rewrote, so on any Fix-Y tree the check missed and a second http.HandleFunc for the same path was appended. Go panics at startup on a duplicate pattern, so the bridge died on the next go build. The sentinel is now the handler registration itself. Fixed: the plugin no longer assumes the WhatsApp MCP server is named whatsapp. Multi-account installs run one bridge and one server per account (whatsapp-) and have no plain mcp__whatsapp__*, so every hardcoded reference failed with an unknown tool. Adds CLAUDE.md Rule 8 (resolve the name at runtime, pick the account deliberately, never reply from the wrong number, Rule 6 applies to every variant) and points ops-inbox, ops-comms, comms-scanner and scripts/whatsapp/ENDPOINTS.md at it. Also warns that allowed-tools entries are exact strings and that host send-gate hook matchers pinned to the literal mcp__whatsapp__send_message stop firing silently when an account is renamed or added.

v3.1.3 — 2026-08-15

ops-merge no longer scans or merges repos the owner cannot push to. The registry lists every locally cloned project, including upstreams we only read, so the queue filled with unrelated contributors' PRs in repos we do not own. Push access is now checked fail-closed immediately before every create, merge and push, --repo is no longer exempt, the scanner accepts both --repo and a bare slug, and OPS_MERGE_INCLUDE_EXTERNAL takes a single slug instead of acting as a global bypass.

v3.1.2 — 2026-08-10

Runtime-first ops-speedup: CPU/RAM/GPU/PID/DNS/TCP health scoring, safer demotion defaults, and CI harness fixes.

v3.1.1 — 2026-08-03

  • Update the Telegram server's transitive Hono dependency to 4.13.0, fixing GHSA-8j4g-w8fx-2239 (CORS middleware ReDoS).

v3.1.0 — 2026-08-03

  • Added a portable CLIProxyAPI account provider with health, account inventory, and utilization support in ops-accounts.
  • Standardized CLIProxyAPI discovery across CLIPROXYAPI_AUTH_DIR, CLIPROXYAPI_HOME, and XDG_CONFIG_HOME, with explicit environment configuration for optional proxy endpoints.
  • Hardened release automation with required CI and CodeQL checks, bounded GitHub queries, stable-head verification, and exact-SHA squash merges without branch-protection bypass.
  • Updated ip-address from 10.2.0 to 10.4.0 in the plugin and Telegram server dependency trees.
  • Updated Telegram server fast-uri from 3.1.4 to 3.1.5, including the upstream security fix.
  • Preserved existing release notes during first-time and interrupted GitHub wiki synchronization.
  • Fixed gateway execution through symlinked or canonical paths and added a clear 503 response when the optional Grok endpoint is not configured.
  • Removed ShellCheck warnings from the touched account and release commands.
  • Removed deployment-specific browser login, CAPTCHA, reauthentication, and subscription automation from the public plugin.

v3.0.0 — 2026-08-03

Upgraded @hono/node-server to 2.0.12 for security and performance fixes, and aligned the Telegram server minimum runtime to Node.js 20+ (#771).

Clone this wiki locally