I begin with context, not interruption.
Every fifteen minutes, the deterministic Nyx Assistant Plane refreshes bounded collectors and reduces current context into source health, freshness, opaque opportunity IDs and timing horizons. It can recognize a preparation need, explain the consequence of a failed capability, and close the loop when it recovers. This plane belongs to the wider installation, not to the Nexus plugin hooks.
Nyx ranks at most one opportunity per run, sends no more than four messages per day, and keeps non-urgent items silent from 22:00–07:00 Amsterdam time. Freshness, privacy, relevance, lifecycle state and existing specialist-watchdog scopes are checked first. When nothing material changed, the correct output is nothing at all.
18:30:31 situation.reduce ....... local metadata only
18:30:31 opportunities.rank ..... max 1
18:30:32 attention.budget ....... 4/day · quiet hours
18:30:32 material_change ........ false
18:30:32 output .................. 0 bytes
Private context stays close to home.
Outside the plugin, calendar details are fetched into a local RAM-backed cache. Public news and route results are cached there too. They can disappear on restart because they are rebuildable. Sessions, configuration, memories and tamper-evident receipts remain persistent because they are not disposable.
Recurring query patterns may be learned only as aggregate categories. The raw questions are not retained for that purpose. Sensitive calendar content is used locally to establish relevance—not copied into public status artifacts or sent to a model just to decide whether an alert matters.
calendar.refresh ........ every 2h + pre-briefing
news.refresh ............ hourly
persistent .............. sessions · state · receipts
learning.mode ............ aggregate · proposal-only
raw_query_retention ...... disabled
Useful intelligence is not measured by how often it speaks.
It is measured by whether it noticed the right change, understood the real context, and spoke early enough for you to do something about it.
That is why Nexus is silent by default, source-grounded, confidence-aware, freshness-aware and explicit when evidence is missing.
Nexus adds context. Hermes keeps authority.
When a message reaches an authenticated agent turn, Nexus deterministically labels privacy signals, risk and a suggested capability family. It also adds the selected identity's role and style. These labels become advisory context for the model; they are not a routing decision or an authorization result.
The /identity command takes a deliberately careful path. Before authentication, pre_gateway_dispatch may rewrite it into an inert marker but cannot change state. The selection is committed only later, in pre_llm_call, after the turn has reached Hermes. Post-generation review is handled by the separate shadow-first nyx-critique plugin; it measures precision silently before it may annotate, and never gates a streamed answer.
pre_gateway_dispatch ....... identity rewrite only
pre_llm_call ............... signals + identity context
review plugin .............. nyx-critique (shadow-first)
security.authority ......... Hermes host policy
I can wear many faces without splitting authority.
The catalog contains 19 named identities, of which 15 are selectable. In automatic mode, deterministic intent rules choose an identity independently for each turn: Home for host-authorized Home Assistant context, Analyst for supplied metrics or data sources, Steward for supplied financial information, and equivalent bounded routes for the other selectable identities. Nyx is the fallback.
An identity is a presentation layer added to one model turn—not a permanent hidden process or a privileged agent. It cannot grant tools, change models or providers, weaken approvals, override user instructions or authorize an action.
/identity name into an inert marker before authentication./identity auto.Capability is not permission.
Proactive intelligence may observe, rank and notify. It may not silently purchase, book, deploy, alter security policy or take control of the physical world. External communications, destructive changes, private adapters and improvement proposals remain human-gated.
Every proactive decision can leave a minimal, allowlisted receipt linked by hash. The receipt proves continuity without copying the private event into an audit trail. These approval and receipt controls belong to the surrounding Hermes installation; the ordinary Nexus plugin cannot authorize or block a tool action.
governance.maximum ........ notify
external_action ............ approval required
receipt.payload ............ allowlisted metadata only
ledger.continuity .......... verified
At quiet hours, I examine patterns—not your private life.
Outside the plugin, failures and outcomes can be reduced into metadata-only signals. Canaries test whether invariants still hold. A monthly advanced-model review receives a sanitized improvement packet, not raw conversations. It may propose a change. It cannot apply one.
Preference observations follow the same rule: they become pending proposals. Stable choices can be remembered when appropriate, but safety policy cannot weaken itself because convenience appeared to improve.
Change the voice, not the authority.
Automatic mode chooses an identity from each request and falls back to Nyx when no bounded intent matches. Send /identity hex to pin Hex for the current conversation. Send /identity auto to remove the pin and resume automatic per-turn selection.
Nexus registers no privileged command handler and no middleware. It uses the stock plugin hook API only. Installation health can be checked with Hermes Plugin Doctor; the standalone contract tests verify registration, deferred identity selection and advisory review behavior.
/identity hex .......... select Hex here
/identity auto ......... restore per-turn selection
plugin hooks ........... 2 registered · 0 tools
Privacy signals are labels, not a firewall.
Nexus scans the current user message with deterministic patterns for credentials, private keys, email, phone, IBAN, address, health and financial signals. It separately detects a small set of elevated-risk requests and suggests a capability family such as coding, research or automation.
The resulting labels and identity context are appended to the turn sent to the active model. Nexus itself does not choose that model, prevent cloud exposure or disable fallback. Those protections—when configured—belong to Hermes and its active host policy.
For high-risk matches, the plugin temporarily keeps the current message in process so the output hook can review the answer. The review is post-generation and may occur after streaming; if the local reviewer fails, Nexus returns control to normal host behavior rather than blocking the answer.
provider selection ..... Hermes host
review timing .......... post-generation
review failure ......... fail-open to host behavior
I can break the boot. So I learned to repair it.
On 1 September an overlay plugin imported the host's gateway module from inside its own register(). Hermes loads plugins on a background thread while its main thread is still importing that very module: two locks, taken in opposite orders. The gateway froze on every start, the startup watchdog killed it every five minutes, and the status command kept reporting a healthy PID for sixteen hours. Nobody was lying. Liveness is simply not readiness.
The repair is a deterministic cron job, not a plugin and not a patch to Hermes. It reads the watchdog's own thread dump, names the plugin whose register() the stock loader was executing—only from a path-anchored stock frame, only when every fire agrees—and either rolls back its own last promotion or renames that plugin's manifest so the next boot skips it. Ambiguous evidence earns one alert and no action. A healthy gateway is never touched.
The same job promotes staged overlay bytes: sha256-pinned per file, contract suite green under an isolation guard, hashes re-checked after the tests ran, previous bytes backed up, then a graceful restart requested through the host's own signal only when it is idle and within a daily budget. The new generation must attest every gated plugin by process id, start ticks and module hash before a single ✓ is sent.
root cause ............... ABBA import-lock deadlock in register()
fix ...................... never import gateway.run; patch defining module
promote → restart → verify 15:56 → 16:01 UTC, automatic
guardian contract ......... 45/45 · three adversarial reviews, all findings fixed
control file .............. fails SAFE to observe-only
register() wedges only. Stock-code faults and module-body imports are reported, never auto-fixed; the guardian cannot restart a gateway it does not consider idle.The honest plugin ledger.
A capable system should know the difference between code that exists, a control that is enforcing, and an idea that still lacks an approved source.
nexus receipt ........... 2.3.3 · module sha256 matches disk
automatic identity tests 4/4 passed
overlay contracts ....... safe-auto-tts 14/14 · guardian 45/45
startup watchdog ........ 0 fires since 14:54 UTC
status source ........... machine-derived nyx-status.json · 65 contracts
pre_llm_call.