Upgrading from 4.x? 5.x needs Node 22.14+ or 24+; Node 20 and 23 are unsupported. On Node 20, npm warns and still installs unless engine-strict is set; the database engine will not load. Read the guide.

Changelog

Release history for ShieldCortex. Install the latest: npm install -g shieldcortex

v5.10.5

Latest 2026-10-18

Patch on 5.10.4: five fixes and one docs correction (#819, #821, #823, #824, #828, #830). No CLI command, config key, default, Node floor or Cloud pin changes.

  • Database startup lock ownership during a copy-restore (#819) — the 5.10.4 copy-restore fix (#817) did not cover an ownership check that ran while the copy was still being written. On a filesystem without hard links, a holder that checked ownership at that moment, while its lock record was still empty or only partly written, lost ownership for good. It then skipped shieldcortex maintain write steps as locked and left its own record behind at shutdown. Such a check now reports no ownership for that moment only, and the holder owns the lock again once its exact record is back. A complete record with any other contents, including another process’s record or the holder’s own record with changed contents, still ends ownership as before.
  • OpenClaw plugin minimum version (#821) — the plugin’s peer dependency, its openclaw.plugin.json manifest (and the copy bundled with the skill) and the README said OpenClaw 2026.3.22, while the package’s install compatibility check already required 2026.4.23. They now say 2026.4.23, and the README no longer suggests that OpenClaw versions below that keep working. Supported hosts do not change, because the install check already required 2026.4.23.
  • OpenClaw plugin compatibility docs (#823) — the plugin README now states the ShieldCortex requirement as its declared ^5.0.0 peer range.
  • Approving a quarantined item no longer re-queues it (#824) — when the item was held by a detector that does not depend on source trust (for example the skill-level threat detector), approving it ran the re-scan, which held the content again: the original item was marked rejected and a new pending copy appeared. The re-scan’s refusal is still final, as before, but the item now ends as one rejected entry with the reason (still held on re-scan: ...) and no new pending copy. The MCP quarantine_review approve reply, the dashboard command rail (quarantine approve <id>) and the Quarantine view now say the item was not approved, with the reason, instead of reporting it approved. approve_by_source lists refused items separately, the dashboard single-approve endpoint returns success: false with the reason, and bulk and by-source approvals report how many items were refused.
  • Quarantine approval wording (#828) — when a bulk or by-source approval refuses items, the dashboard notice and the approve_by_source reply now say those items could not be admitted and are rejected, not added to memory. They no longer say a re-scan refused them, because some items are refused without one (for example an item that was originally hard-blocked). The approve confirmation dialogs no longer promise that items will be promoted into memory or that their content will be re-scanned: they say approval is not guaranteed and that an item that cannot be admitted is rejected instead. A bulk approval of only memory-file findings no longer says other items will be tried; if some selected items have left the list since they were selected, the dialog says only that any other selected items that are still pending will be tried. Which items are approved or rejected does not change.
  • Rate-limit refusal reason (#830) — when too many approvals ran within a minute, the refused item’s reason said still held on re-scan: ..., although the rate limit refuses before any scan runs. The reason now says not admitted (memory write rate limit): ... in the MCP quarantine_review approve reply, the dashboard Quarantine view and the dashboard command rail. A refusal from the scan itself still says still held on re-scan: .... The item still ends rejected and is not added to memory, as before.

ShieldCortex 5.10.5 release notes on GitHub

v5.10.4

2026-10-17

Patch on 5.10.3: two fixes (#813, #817). No CLI command, config key, default, Node floor or Cloud pin changes. The stale takeover can still briefly leave the lock path empty; this release does not close that window.

  • Database startup lock ownership after a stale takeover (#813) — when another process’s record replaces a process’s lock record, that process now drops its ownership at its next ownership check, so at most one of them reports owning the lock from then on. shieldcortex maintain checks ownership again before consolidate, embed and vacuum, and once ownership is lost reports that step and every later write step as skipped: locked. While a process’s record is only moved aside (the lock path is empty), it reports no ownership but keeps it, and owns the lock again if the record is linked back. Shutdown checks ownership before releasing and leaves another process’s record in place. The stale takeover can still briefly leave the lock path empty: this fix does not stop another starter from publishing in that moment, and a process that already passed an ownership check is not interrupted mid-step.
  • Database startup lock ownership after a copy-restore (#817) — on a filesystem without hard links, when another process’s stale-lock check moves the holder’s lock record aside and puts it back, the record comes back as a copy. The holder now still reports owning the lock after that, so in that case shieldcortex maintain no longer skips its write steps as locked, and shutdown removes the restored record. Any other contents at the lock path, including another process’s record, still end ownership as before. One timing window remains, tracked in #819 and not fixed in 5.10.4: if the holder checks ownership while its record is still being copied back (the file exists but is still empty or partly written), it can lose ownership for the rest of its life.

ShieldCortex 5.10.4 release notes on GitHub

v5.10.3

2026-10-16

Patch on 5.10.2: five fixes only. Corrections to the 5.10.1 and 5.10.2 release notes (#802) and a CI-only change (#811) ship with it and change no shipped code. No CLI command, config key, default, Node floor or Cloud pin changes.

  • Database startup lock (#763) — the lock record is now published complete in one step, so a starting process can no longer claim the lock through another process’s half-written record, and stale-lock takeover and shutdown remove only the exact lock record they checked. One rare window remains: a stale takeover briefly moves the current lock aside before checking it, and if another starter publishes in that moment two processes can end up holding the lock. That window is tracked in #813 and is not fixed in 5.10.3. On filesystems without hard links ShieldCortex falls back to a weaker, time-based check. shieldcortex maintain no longer closes a database handle that another caller in the same process opened.
  • doctor and ledger verify explain legacy project backfills (#795) — when every reported problem is a matching project-only mismatch, the reports name an older ShieldCortex copy (5.2.1 or earlier) as the likely cause and advise upgrading or removing it before repair, instead of using tamper wording. In ledger verify --json those problems carry an optional cause field. Mixed or other damage keeps the existing warning. The ledger is still inconsistent, and verification does not change the database.
  • More JSON and SARIF outputs keep unsafe terminal characters escaped (#798, #806) — scan --json, doctor --json, guard readiness --json, maintain --json, ledger verify --json, audit --sarif, mcp scan --sarif and --json, memories import-native --json, remember --json and env scan --json (#798), then audit --json, policy-evidence, xray --json / --sarif and xray --watch --json (#806) now write C1 controls, bidi controls, line separators and invisible characters as JSON Unicode escapes, so viewing these outputs in a terminal can no longer act on them. Parsed values are unchanged, and output without those characters is byte-for-byte the same as before.
  • X-Ray no longer replaces a findings file it could not read (#801) — when the findings file is not valid JSON, is not a list, or cannot be read (for example a permission error), a dashboard scan or watch that has findings to save now leaves the file exactly as it is and reports the problem; watch mode prints a warning and keeps watching. A dashboard scan with nothing to save, a watch event with no new finding and the CLI xray scan do not read the findings file and report nothing about it. A list holding an entry that is not a valid finding is also left as it is instead of being rewritten with the new findings merged in. A missing findings file is still created by the first scan that finds something. Behaviour change for dashboard and API callers: with an unreadable findings file, an X-Ray scan that has findings to save (POST /api/xray/scan), marking or deleting a finding (PATCH and DELETE /api/xray/findings/:id) and quarantining a finding (POST /api/xray/findings/:id/quarantine) now answer 503 instead of replacing the file.

ShieldCortex 5.10.3 release notes on GitHub

v5.10.2

2026-10-16

Patch on 5.10.1: four fixes only. No CLI command, config key, default, Node floor or Cloud pin changes.

  • Older copies are refused when they change the project of a chained audit row (#674, part 1) — builds up to 5.2.1 fill in the project on audit rows at every start, chained rows included, which broke ledger verify on mixed-version hosts where a 5.3+ build had chained the same database. A new trigger now refuses any statement that changes the project of a row with a chain position, whichever build issues it; an update to the same value still goes through. An old copy logs the refusal on stderr at each start and carries on starting. Only the refused statement is rolled back: backfill work the old copy finished earlier in that start stays, and its remaining backfill steps, including held-back (quarantine) items, are skipped for that start and left for the next start of a current build. This is compatibility protection, not a tamper boundary: the trigger can be dropped by anyone with SQL access, other columns are unguarded (ledger verify still detects edits to them), and old copies’ unchained inserts and un-checkpointed deletes are not blocked.
  • allowlist scan --json keeps unsafe terminal characters escaped (#786) — C1 controls, bidi controls, line separators and invisible characters are written as JSON Unicode escapes, while parsed paths and denial notes keep their original values.
  • Recovery text and update re-run lines are cleaned before display (#788) — the repair command, the doctor report, the MCP server’s startup-failure message and the unresolved-step re-run lines at the end of shieldcortex update now pass the install directory, error text and agent id through the same display cleaner as the update screen. Terminal control sequences, stray line breaks and invisible or direction-changing characters in those values are removed or shown as ⏎ instead of reaching the terminal. Only these values on these screens are covered; other lines the repair command prints are not yet passed through the cleaner. Ordinary text prints as before, and doctor --json still reports the raw values.
  • Line breaks inside install and log paths (#799, completes #788) — a line break inside an install or log path now shows as ⏎ inside its value, so it no longer appears as a separate doctor “NEXT” command or recovery line, and the MCP startup-failure “Details written to” line is cleaned like the message above it.

ShieldCortex 5.10.2 release notes on GitHub

v5.10.1

2026-10-15

Patch on 5.10.0: fixes, wording, tests and CI only. No CLI command, config key, default, Node floor or Cloud pin changes; update exit codes are unchanged, and only service install, service repair, service status and service --help / -h exit codes change. Action Guard stays off by default in the shared ShieldCortex config.

  • A calmer shieldcortex update screen (#773) — the run ends with one headline and one row per part, and each row that needs you names one command. Action Guard switched off is shown as neutral, not as a warning. Internal detail is kept under update --verbose. Exit codes, what update installs, and what Guard allows or blocks are unchanged.
  • A failed OpenClaw plugin check is always red (#773 follow-up) — when OpenClaw started without the ShieldCortex plugin, the update screen now shows a red OpenClaw row and a red “Update failed” headline, and no longer ticks Guard as on.
  • Scheduled-script review wording (#780) — the update line no longer says new or changed scheduled scripts need a yes before they can run. It says they are not reviewed yet and what trusting one does. Wording only; review, trust and Guard behaviour are unchanged.
  • Host-derived text is cleaned before display (#779, #785) — paths, notes and error text on the update screen, in the allowlist scan and in the allowlist subcommands go through one display cleaner, so escape sequences, control characters and bidi or zero-width characters in those values can no longer redraw or reorder the terminal. Ordinary paths print unchanged.
  • service exit codes (#768) — service install exits non-zero when the service cannot be enabled, and service repair runs the same install step and now exits 1 in the same case, where 5.10.0 exited 0. service status exits non-zero when the service is not installed and, on Linux and macOS, also when it is not enabled or loaded, not running, or cannot be queried; on Windows an installed service still exits 0. service --help and -h now print the usage and exit 0.
  • Dashboard counts and indicators (#692, #693) — Needs you marks a count as last known or as a lower bound (“N+”), and “Nothing needs you” appears only when all three lists confirmed an exact zero. The protection row is labelled Iron Dome and says it does not cover Action Guard, and the sidebar’s data-location line follows the cloud sync setting instead of always saying data stays on this computer.
  • Behaviour change for API callers (#692) — an X-Ray findings file that exists but cannot be read or parsed now makes /api/xray/findings and /api/xray/findings/stats return 503 instead of a zero. /api/review/queue gains pairCoverage and /api/xray/findings/stats gains store; both are additive.
  • setup help (#766) — setup --help and the install banner say that bare shieldcortex setup asks before wiring each host, while setup <host> wires that host directly. Behaviour is unchanged.

ShieldCortex 5.10.1 release notes on GitHub

v5.10.0

2026-10-15

Minor on 5.9.0. A new shieldcortex maintain command runs storage and memory hygiene in one step: it consolidates STM above its cap, backfills missing vectors (skipped while the embedding model is not cached), vacuums when at least 20% of database pages are free, then runs doctor's Memories, Semantic coverage and Disk checks. It exits 1 while a FAIL remains and sends the remaining FAIL checks by check name to the configured Action Guard webhook at most once per 24 hours for the same FAIL set; memory content is never sent. Minor rather than patch because maintain is a new CLI command. No existing CLI command, config key, default, Node floor or Cloud pin changes. Action Guard stays off by default in the shared ShieldCortex config.

  • Plain maintain deletes and evicts — when STM is over its cap, plain maintain (without --dry-run) runs the first phase of shieldcortex consolidate, not its Dream Mode phase: it promotes worthy STM, deletes decayed STM, evicts unpinned memories older than one hour in either tier while that tier exceeds maxShortTermMemories or maxLongTermMemories, and resolves near-identical long-term pairs by deleting or downvoting one (memory text is never merged). It does not archive. Run --dry-run first to preview.
  • --dry-run and --json — --dry-run leaves database contents and config unchanged; --json prints a structured report. An unknown argument exits 2.
  • Lock handling — a database lock held by another live ShieldCortex process, whether seen before opening or at lock acquisition, makes consolidation, embedding and vacuum skip, not fail; doctor still runs.
  • Fixed (#761) — a live startup lock acquired after the initial check now stops database initialization before it can write; maintenance steps skip and doctor still runs.
  • Known limit (#763) — the startup lock itself still has pre-existing race windows. They are tracked in #763 and are not fixed in 5.10.0.
  • Not included yet — audit-log retention and scheduling of maintain.

ShieldCortex 5.10.0 release notes

v5.9.0

2026-10-14

Minor on 5.8.0. Four Action Guard and session-lease changes, only where those features are on: fewer false alarms for data-reading heredocs and read-only global npm queries, with tighter coverage for written argv-list global installs and redirection-attached installs. Action Guard stays off by default in the shared ShieldCortex config. No export, CLI command, config key, default, Node floor or Cloud pin changes.

  • Data-reading heredocs — Action Guard again allows a narrowly defined, whole-command interpreter heredoc whose body only reads data through recognised literal read spellings. Other heredocs keep the existing scan; a sensitive path can still be reported.
  • Written argv-list global installs — a script file that builds a global install as an argument list now joins the approval gate when written, like the string form: when Action Guard is on and enforcing, recognised calls require approval; hosts without an approval prompt, including Hermes, block held calls. The reader is bounded: a global flag beyond 8 KB per call and exec APIs outside its listed sinks are not covered.
  • Read-only global npm queries — the session lease now requires the install verb and global flag in the package manager's own command. Queries such as npm list -g | grep -i x no longer take or get refused by the install lease.
  • Redirection-attached global installs — an install such as npm>/dev/null install -g x keeps install scope. Commands the mapper cannot resolve keep conservative scoping and may include non-installs.

ShieldCortex 5.9.0 release notes

v5.8.0

2026-10-12

Minor on 5.7.0. Prompt recall searches the owner's message instead of the OpenClaw envelope, a new Claude SDK browser and computer toolsets export observes calls by default, and doctor checks for repeated recall candidates. The optional vector plane is off by default. The Node range remains ^22.14.0 || >=24.0.0; no existing export, CLI command, config default, Node floor or Cloud pin changes.

  • Recall uses what you asked — the Claude Code UserPromptSubmit hook strips a complete OpenClaw 2026.9.x envelope before searching. An incomplete envelope or a message without one is queried unchanged.
  • Optional vector recall — "recallVector": true or SHIELDCORTEX_RECALL_VECTOR=1 enables it. It re-ranks and tops up lexical candidates without admitting anything full-text search would not.
  • Recall repetition check — a read-only shieldcortex doctor row warns when recent interactive recalls repeatedly return the same candidate set. It is repetition evidence, not a proven cause.
  • Claude SDK toolsets — the new shieldcortex/toolsets export covers browser use and computer use. Its default mode: 'observe' changes nothing about what runs. Opt-in mode: 'enforce' refuses the deny set and holds approval-required calls. Enforce needs the host's own approver (the inner callback): without one, every held call is refused. With one, a held call reaches that approver as a readable, values-free card, with single-use approvals and a deadline. Approval binds to the host in the SDK's last state report, not the live page; before the first read a typed newline in the browser toolset is still allowed. This export was listed under 5.7.0 by mistake and first ships in 5.8.0.
  • Setup wording — status, doctor, help and the README point to shieldcortex setup and shieldcortex setup claude. This is wording only; install and quickstart still work.
  • Threat-graph realtime projection — an unreadable listed day file now reports an error and holds the cursor. A malformed cursor halts projection with a fixed error. Only broken state changes; recovery is an operator action.
  • Release tooling: ClawHub status — the ClawHub sync step reports a version still in ClawHub's security scans as submitted, which proves neither a failed upload nor public availability. A failed ClawHub read is unknown, not absent, and only a version ClawHub actually serves counts as success.

ShieldCortex 5.8.0 release notes

v5.7.0

2026-10-11

Minor on 5.6.0. Two Cloud privacy fixes for the dashboard's bulk quarantine sync, prompt-time recall scoped by lane with a new PERSONAL sensitivity tier, clearer OpenClaw setup failures, and three Action Guard fixes. Action Guard stays off by default in the shared ShieldCortex config, but what the guard does depends on the host: the Hermes plugin, once enabled, has its own enforcement setting. The release notes set out each host. Node floor unchanged (22.14+ or 24).

  • Bulk quarantine sync goes through the same gate — the dashboard's "sync quarantine to Cloud" button used to send stored quarantine content as-is. It now applies the same controls as the automatic sync (sensitive-level exclusion, project filter, metadata-only mode), then PII redaction and credential redaction, before anything leaves the device or is queued for retry. A stored row is graded at least as strictly as the live pipeline graded it. Rows that pass the filters are still sent, redacted, unless you use metadata-only; redaction covers recognised kinds and is not a guarantee that every personal detail or secret is caught. The response gains an additive skipped count.
  • Automated turns recall less — in the Claude Code UserPromptSubmit hook, turns detected as cron or subagent now recall only error, pattern and decision memories labelled PUBLIC, and liveness/automation turns recall nothing by default. Your own unmarked chat is unchanged. recallLanes can change the categories or opt automation in, but non-interactive lanes stay PUBLIC-only. The stored label decides, so a private note labelled PUBLIC by mistake can still reach those lanes. SessionStart context, MCP tool reads and dashboard previews are not lane-scoped.
  • New PERSONAL tier — sits between INTERNAL and CONFIDENTIAL. Your interactive recall still sees it, and the default excludeSensitive keeps it out of Cloud sync. Existing rows keep their labels until you run shieldcortex memories reclassify --execute; without --execute it is a dry run, and it only ever raises a label. Code that switches exhaustively on SensitivityLevel needs a PERSONAL case.
  • setup openclaw shows every refusal — each native plugin install attempt's refusal is printed, package install first, instead of only the last. A missing OpenClaw config is reported as a config problem. npm installs are no longer told to run npm run build; they are pointed at shieldcortex openclaw install or the realtime package.
  • Readiness evidence survives a release — enforce when ready now keys its readiness evidence on the adapter and policy hash, so a release that keeps the policy hash keeps its evidence. When the hash changes, the prior policy's evidence is carried at a discount (actionGuard.readiness.priorPolicyCarry, default 0.5) and counts only once the new policy has its own fresh window. Malformed pins do not count. Reviewed effectiveness evidence is still pinned to the full adapter and policy version.
  • Memory notes that name a dangerous command are recorded, not held — writing a memory-markdown file with no shebang whose plain prose names a dangerous-tier command is now allowed and recorded instead of asking where the guard was enforcing. Catastrophic forms, guard self-protection and sensitive-path mentions, sensitive or guard-owned file paths, shebang bodies, script-like paths and running the file are handled as before. The guard cannot tell prose from a bare command line, so a note made only of a command is writable too. Partial fix for #629.
  • Claude Code hook reads a relative script from the call's directory — a relative invoked script is resolved against the call's own working directory when it is an absolute path, not the hook process's. The OpenClaw plugin is unchanged: calls with no or a relative working directory, and the original cross-host discrepancy in #634, are still open.

ShieldCortex 5.7.0 release notes

v5.6.0

2026-10-10

Minor on 5.5.0. The Action Guard changes what it asks about, approval cards speak plain English, consolidate now drains short-term memory, and the local dashboard starts its redesign. Action Guard stays off by default; the guard changes below apply only where you have turned it on. Node floor unchanged (22.14+ or 24).

  • Teardown commands ask first — deleting a database or table through a database client, destroying infrastructure with Terraform or OpenTofu, deleting a Kubernetes namespace, volume or node, uninstalling a Helm release, and tearing down cloud groups or accounts used to be allowed and now need your approval. Mentioning them in text, such as a search pattern or a commit message, does not trigger it.
  • Script files follow recognised nested calls — a script file now follows the nested script calls the guard recognises, as the same line written inline already did. Not every way of running a second file is recognised yet. Inline << heredoc scripts are checked exactly as in 5.5.0: a planned change for them was withdrawn before release, so a heredoc program that reads a data file containing prose about dangerous commands can still be denied on that file, as before.
  • Recognised sensitive paths stay unread — a nested file whose path, as spelled, matches the guard's recognised sensitive path spellings (such as SSH key and cloud credential locations) is not read into the guard's scan text. It is asked about on its path and is never auto-allowed. This is a spelling check, not file identity: aliases, symlinks, variables and other spellings of the same path are outside that coverage.
  • "Look at" is just prose — writing source that contains a phrase like "Look at the findings" no longer reads as a scheduler command. Real at and crontab calls still ask. This covers the in-process guard only; the outage fallbacks are unchanged.
  • Plain-English approval cards — a held action's card now says what the action does, why it was held and who asked, without showing the raw command. Targets that look like secrets are withheld whole; a secret in an unrecognised shape is not guaranteed to be caught.
  • shieldcortex consolidate drains short-term memory — it now promotes, expires and evicts memories before Dream Mode and prints what it did. It can remove short-term and long-term memories: long-term ones when that store is over its limit, and one of each identical long-term pair. Only cap eviction skips memories captured in the last hour and pinned ones; expiry and duplicate resolution follow their own rules. Doctor's memory warnings follow your configured limits, so doctor --strict may exit differently on the same store.
  • --help is safe — install --help, setup --help and doctor --help print usage and do nothing else.
  • Dashboard redesign, phase A — five nav items (Home, Needs you, Memory, Protection, Settings), a new Needs you page, plain-word labels, a dark theme by default and larger text. Old page URLs redirect to the tab that replaced them, and Protection and Settings tabs switch normally after a deep link.

What's new in 5.6

v5.5.0

2026-10-08

Minor on 5.4.0. Two fixes for problems in 5.4.0, a new way to see how each runtime is configured, and a doctor warning for stock Iron Dome installs. Action Guard stays off by default. Node floor unchanged (22.14+ or 24).

  • Approving on a Mac works again — in 5.4.0 shieldcortex approve refused every human on macOS, so blocked actions could not be approved there. It now finds your Terminal.app or SSH session and still refuses agent-owned shells. It refuses, rather than guesses, when it cannot read the whole process tree, so on Linux with restricted /proc even a real login shell may be unable to approve.
  • No more scan stalls on long blank runs — a long run of newlines could stall a scan for 30 seconds or more. Detection is unchanged.
  • shieldcortex policy-evidence — one record per runtime (Claude Code hook, OpenClaw plugin, Hermes plugin) saying whether it is installed and loaded, how it is configured and any real block it saw, each with its own evidence. These are local self-reports, not attestation, and they show configuration: with enforce when ready on, a record can say enforce while the guard is still watching. shieldcortex guard readiness shows the live gate.
  • Iron Dome stock-defaults warning — doctor warns when Iron Dome still has the default stop phrase or no PII rules, and doctor --strict now exits 1 on such installs.
  • Fixes — Claude Code session leases last their full time, so a second session on a leased scope is refused while the first is alive; doctor's disk row names the largest consumer; MCP SDK 1.31.0 past a published advisory.
  • Dependency audit — a new sharp advisory (GHSA-wq5f-xc86-pv6w) is waived, not fixed, after a reachability check: ShieldCortex never hands image bytes to sharp. The waiver expiry stays 2026-12-12. Production audit at this release: 0 unwaived, 4 waived.

What's new in 5.5

v5.4.0

2026-10-06

Minor on 5.3.1. Action Guard gains a third posture, enforce when ready, and two new commands. Action Guard stays off by default. Node floor unchanged (22.14+ or 24). Worth knowing before you update: watch-only installs now hold calls that touch the guard itself, and a broken Claude Code hook now fails closed for catastrophic commands.

  • Enforce when ready — a third posture beside off and enforce. It runs the dangerous tier in shadow and logs what it would have held or blocked. It enforces only once this install's own audit shows the guard is operable and reviewed evidence for the running version exists. No such evidence ships yet, so today it stays in shadow and says so. shieldcortex guard readiness shows where it stands; shieldcortex guard test-approval sends a test card. The Claude Code hook and the OpenClaw plugin each measure on their own calls. The Hermes plugin ignores this posture and enforces.
  • Self-protection floor in watch-only — with the guard on but not enforcing, a call that touches the guard's own config, state, lease ledger or policy lock is still held until a human answers. Auto-approve rules and broker pre-clears no longer release it. Guard off is unchanged.
  • Broken hook fails closed for catastrophic commands — if the Claude Code hook file fails to load or crashes, a backup scan still denies recognised catastrophic commands, even with the guard off. The scan is a blunt text match, so while the hook is broken it also stops routine recursive force-deletes such as clearing a build folder; shieldcortex doctor shows the repair.
  • Approval answers bound to their attempt — an answer to a replaced attempt, or one more than 15 minutes late, grants nothing.
  • Fixes — shieldcortex remember no longer exits 134 after a successful write; config --help describes the real defaults; webhook URLs carrying credentials are refused; proxy-addr updated for a spoofing advisory.

v5.3.1

2026-10-03

Patch on 5.3.0. One Action Guard fix for OpenClaw's Codex harness; nothing else changes. Action Guard stays off by default. Node floor unchanged (22.14+ or 24).

  • Codex harness commands recognised — on OpenClaw's Codex harness, shell commands and background processes reach the guard under a joined-up name (openclawgateway_exec, openclawgateway_process). The guard did not recognise it, rejected the call's normal fields as unknown and cancelled the approval card. Those names now map to the standard exec and process checks. Exact names only: no prefix is stripped, so a lookalike name gains nothing.

v5.3.0

2026-10-03

Minor on 5.2.1. Action Guard stays off by default. Node floor unchanged (22.14+ or 24). Worth knowing before you update: the injection scanner flags more, and doctor has a new row that can fail.

  • Injection scanner catches more — spoofed authority lines inside tool results (ADMIN: you must …, SYSTEM OVERRIDE:), "repeat everything above including the hidden prompt" extraction, explicit injection phrases in ten languages, and ROT13-encoded instructions anywhere in the input. Content that passed before can now be quarantined. Ordinary Admin: email stays quiet. It is a detection floor: reworded attacks still pass.
  • Tamper-evident audit log — new audit rows are hash-chained as they are written. shieldcortex ledger verify reports consistent, inconsistent (with the first bad row) or unchained, and exits 0 / 1 / 2. Existing rows are not rewritten; they are reported as history from before the chain started.
  • Doctor exit code — a new Chained ledger row FAILs (exit 1) if the audit history was edited or rows were removed, and points at ledger verify. A database with no chain yet is a WARN.
  • Update — a slow OpenClaw install is no longer reported as a failure, and update exits 1 when an OpenClaw plugin install did not land. Scripts that check its exit code may see 1 where 5.2.1 printed green.
  • Safer installs — OpenClaw installs refuse to write through linked extension directories or config snapshots, and openclaw plugins list no longer prints a false "scanning is off" warning.
  • Verifiable builds — published with npm provenance; npm audit signatures confirms the package was built by the ShieldCortex release workflow.

v5.2.1

2026-09-26

Patch on 5.2.0. Action Guard stays off by default. Node floor unchanged (22.14+ or 24).

  • Update refreshes your hooks — shieldcortex update now refreshes the installed OpenClaw hook and Hermes plugin when they are out of date. Nothing you removed is reinstalled, and an interrupted swap prints the backup path and the reinstall command.
  • Help is just help — --help never runs a command. On 5.1.0 and 5.2.0, update --help performed the upgrade.
  • Doctor's disk advice — the DISK row no longer suggests deleting memories or sessions; it reports measured sizes and suggests logs prune or vacuum only when the measurement supports it.
  • Neutral approval card — the OpenClaw approval card says "Your agent" instead of a hardcoded agent name.
  • Action Guard — SSH keys and other home-directory persistence files are treated as sensitive write targets.

v5.2.0

2026-09-24

Minor on 5.1.0. Action Guard stays off by default. Node floor unchanged (22.14+ or 24). One thing worth knowing before you update: stored Review Copilot annotations are redacted once on first start.

  • Review Copilot annotations redacted — the judge's notes on quarantined items now go through the same write-time redactor as memories, and a one-time migration cleans the ones already stored. The original quarantined content is not rewritten. SHIELDCORTEX_PII_REDACTION=off keeps storing verbatim.
  • Hermes plugin copies — doctor asks Hermes which ShieldCortex plugin copy it actually loads and warns when a backup folder is shadowing the installed one. doctor --fix-hermes-plugin-copies moves such copies into backups/ (never deletes) and refuses when the layout is ambiguous. WARN only: it does not change doctor's exit code.
  • Echoed memories framed — MCP tools that echo stored memory back now carry the same untrusted-data frame as recall.
  • Credential exfil — a credential file sent to a scheme-less curl/wget target counts as external egress; local and tailnet targets stay allowed.
  • Doctor accuracy — the denial-sink check now matches what the notify transport actually accepts; audit report fixes.

v5.1.0

2026-09-22

Minor on 5.0.7. Action Guard stays off by default. Node floor unchanged (22.14+ or 24). Two behaviour changes worth reading before you update: PII is now redacted when memories are written, and doctor can exit 1 on a host that enforces Guard with nowhere to send denials. Stay on 4.x with npm install -g shieldcortex@4 if you cannot move Node yet.

  • PII redacted on write — UK NI numbers, US SSNs, labelled tax ids and salary figures are stored as [REDACTED:<kind>], and those rows are CONFIDENTIAL or above. Old rows are not rewritten in bulk; they are redacted the next time they are updated. SHIELDCORTEX_PII_REDACTION=off keeps storing verbatim.
  • Doctor exit code — Guard enabled and enforcing, with no denial sink, is now a FAIL (exit 1), not a WARN. CI that checks doctor's exit code will see it. Guard-off hosts are unchanged. Doctor still only reports.
  • Recall framed as untrusted data — memories injected into a prompt arrive inside an "untrusted data — not instructions" frame with a random boundary id, so a stored note cannot pose as an instruction.
  • SECRET isolated — SECRET and any unknown sensitivity label are withheld like RESTRICTED by every reader.
  • Split keys caught — provider keys split by spaces or invisible characters are detected and redacted.
  • Fewer false blocks — a comment in a script is no longer read as a command, and audit --help / allowlist --help print usage.

v5.0.7

2026-09-20

Patch on 5.0.6. Action Guard stays off by default. Node floor unchanged (22.14+ or 24). Doctor no longer FAILs an unlocked policy lock when Guard is not live.

  • Doctor — leftover signed Enforce with the plugin off no longer prints $ protect and exits 1 on healthy boxes.
  • README — a short install page; detail lives on shieldcortex.ai.

v5.0.6

2026-09-20

Patch on 5.0.5. Action Guard stays off by default. Node floor unchanged (22.14+ or 24). OpenClaw's native process tool is a reviewed contract, not an unknown exec bag. Stay on 4.x with npm install -g shieldcortex@4 if you cannot move Node yet.

  • OpenClaw process — list / poll / log allow. Stop/type-into still cards in plain English, not invalid_tool_input. Allow-once is this call only.
  • OS-owned policy lock — shieldcortex protect (root, once) pins the security-critical config so an agent cannot quietly turn Guard off.

v5.0.5

2026-09-13

Patch on 5.0.4. Action Guard stays off by default. Node floor unchanged (22.14+ or 24). One host table for setup, update, uninstall, and doctor. Stay on 4.x with npm install -g shieldcortex@4 if you cannot move Node yet.

  • Host table — setup detects Claude Code, OpenClaw, Hermes, Codex, and Cursor/VS Code, then asks before wiring. update refreshes wired hosts and asks about new ones (non-TTY does not wire). uninstall removes Hermes and Copilot too.
  • Doctor honesty — warnings no longer print $ --action-guard-enable or $ --allow-conversation-access. doctor --repair is TTY named jobs; --repair --agent writes a brief and does not spawn an agent.

v5.0.4

2026-09-13

Patch on 5.0.3. Action Guard stays off by default. Node floor unchanged (22.14+ or 24). Local dashboard rebuilt; signed Guard writes now sync the OpenClaw plugin plane. Stay on 4.x with npm install -g shieldcortex@4 if you cannot move Node yet.

  • Dashboard v2 — one shell, honest status pills, real memory graph (Map / Focus / Path).
  • Guard plane sync — signed config --action-guard-* writes the same enabled/enforce onto an existing OpenClaw plugin entry. Missed card: approve --denial <id> --reauth. Guard stays off.

v5.0.3

2026-09-13

Patch on 5.0.2. Action Guard stays off by default. Node floor unchanged (22.14+ or 24). shieldcortex update now passes --agent main on OpenClaw 2026.9 multi-agent hosts. Stay on 4.x with npm install -g shieldcortex@4 if you cannot move Node yet.

  • Skill install — reads OpenClaw 2026.9 agents.entries (not only OpenClaw 1 agents.list) and still prefers main. Jarvis 5.0.2 died with Multiple agents are configured.

v5.0.2

2026-09-13

Patch on 5.0.1. Action Guard stays off by default. Node floor unchanged (22.14+ or 24). Jarvis's leftover signed-Enforce doctor fail is gone. Stay on 4.x with npm install -g shieldcortex@4 if you cannot move Node yet.

  • Doctor NOTIFY — signed Enforce leftover no longer FAILs when the OpenClaw plugin is off. Do not add a webhook from that line.
  • #438 — a crashed session lease whose PID is confirmed dead no longer wedges the scope until TTL.
  • #472 — setup openclaw honours OPENCLAW_HOME.
  • #475–#478 — dashboard quarantine INSERT, import path leak, restart/update confirm.

v5.0.1

2026-09-13

Patch on 5.0.0. Action Guard stays off by default. Node floor unchanged (22.14+ or 24). If the first shieldcortex update from 4.x still looks ugly, run it once more — that second run is the honest 5.0.1 CLI.

  • Update honesty — after npm swaps the package, update re-executes the new CLI so Friday-class leftover 4.x footers cannot scream FAILED.
  • Plugin lag — a lagging OpenClaw plugin warns instead of claiming to be current; unread load evidence is NEEDS ATTENTION, not unprotected.
  • Skill install — retries once without a rejected flag; multi-agent hosts get --agent.
  • Stay on 4.x — npm install -g shieldcortex@4 if you cannot move Node yet.

v5.0.0

2026-09-12

Breaking major. Node 20 is gone. Read the upgrade page before you update. Stay on 4.x with npm install -g shieldcortex@4 if you cannot move Node yet.

  • Node 22.14+ (within 22.x) or Node 24+ — Node 20 unsupported: npm warns by default (refuses only with engine-strict) and the database engine fails to load. Node 23 unsupported.
  • #474 — dashboard API auth no longer skipped by /API/… or unauthenticated HEAD.
  • #466 — honest production audit (waived sharp only) + Node 24 doctor no longer SIGABRTs.
  • Upgrade notes — /docs/upgrading-5.

v4.54.15

2026-09-01

OpenClaw 2 exec storm stop. Action Guard is off by default. Existing signed enabled: true stays on.

  • Default off — absent actionGuard.enabled no longer means on. shieldcortex update prints the notice and config --action-guard-enable.
  • OpenClaw 2026.8.1 exec — live fields such as workdir, timeoutSeconds, host no longer mint unknown-keys cards. host is an exec target, not a URL.
  • #449 — shieldcortex scan exit codes no longer collapse usage/tool failure into a deny.

v4.54.13

2026-08-25

Cloud sync durability. Host engine ships atomic retry claim/lease and a transactional outbox so local memory mutations cannot commit without a durable outbound event.

  • #409 transactional outbox (same SQLite txn as mutation; exact-key ack)
  • #408 atomic claim + lease on the cloud sync retry queue

v4.54.12

2026-08-25

Athena P0/HIGH security + integrity — cloud delete privacy, decay fix, recall correctness, bind auth, closed tool schemas.

  • #405 P0 — cloud memory delete sends content-free tombstones and honours the same privacy gate as upsert.
  • #406 P0 — consolidation no longer compounds temporal decay into base salience.
  • #407 / #410 — FTS ranks by BM25 before LIMIT; ACL filters before top-k so unauthorized rows cannot starve results.
  • #411 — non-loopback API bind requires explicit opt-in + strong token; public session-token mint disabled off-loopback.
  • #412 — closed Action Guard tool-input schemas on exec/git; MCP remember/recall execute-path validation.
  • Operator UX + docs — DNP “held (headless)” copy, Approve once cards, intent-first architecture doctrine on main.

v4.54.11

2026-08-21

Update footer honesty — no more double FAILED essay when the guard is already live.

  • Calm protection footer (#390) — English headline + short proof chips after shieldcortex update; full dump only with --verbose.
  • Canary-live + roster-unread is NEEDS ATTENTION (exit 0), not FAILED. True unprotected still fails closed.
  • Quiet canary — expected probe deny no longer prints a scary Action Guard block line (still audited).

v4.54.10

2026-08-21

Mobile-first terminal UX + guard honesty — phone SSH that humans can actually read.

  • Terminal UX (#388) — decision-first allowlist scan cards (no 40-line source walls); [v]iew pages source; update ends with a VERDICT panel. 40-col first.
  • Content ≠ intent (#386) — quoting an install in a log no longer trips install-package-global; real installs still gate. Deny copy points at human auth, not enforce:false.
  • Model cache heal (#383) — corrupt ONNX weights are detected, quarantined once, and re-downloaded; doctor verifies size/sidecar.
  • Doctor nits (#381/#382) — real nativeContract values only; stop-hook stops prescribing hand-edits of signed config.

v4.54.8

2026-08-19

The operator control plane — allow or deny what headless agents were refused, from your phone or terminal.

  • Retry approval cards (#310, ships dark) — a headless denial leaves a fingerprint, never a grant. Approving mints ONE origin-scoped, time-boxed retry; deny opens a windowed silence and revokes anything unspent. Alerts never carry spendable tokens. Enable: actionGuard.retryCards: true.
  • Live interactive approval cards (#371) — OpenClaw require_approval surfaces a real allow-once/deny card in the originating conversation; cron/heartbeat stays fail-closed.
  • Honest denial alerts (#369) — headless denials say DENIED — nothing is waiting, keep a redaction-safe surface, and carry an outcome header for webhook routing.

v4.54.7

2026-08-19

Patch — doctor honesty: recommendations that actually stick.

  • ClawHub skill lock no longer false-flagged as residue when the skill is installed
  • Conversation-scan warnings lead with the real grant command, then gateway restart
  • Project keys stop regressing after updates — generic cwd basenames refused, auto-heal on update
  • 4.54.6 tag exists but was never published to npm

v4.54.5

2026-08-18

Patch — Memory SOTA train for hosts + scorecard honesty.

  • Memory plane — inject v2 / capture distill (OAuth cheap default + OpenClaw C.2), provenance scope, LongMemEval-S harness with defence-on ingest.
  • Full-S retrieval (host) — emb-on RRF R@5 92% / R@10 92.8% / MRR 0.859 (retrieval-only; not a generation bake-off).
  • Defence honesty — doctor: notify.openclaw ≠ DNP sink; bare conversation-scan unknown no longer taints sessions (#360/#362).
  • threatGraph.trustModifier stays advisory. SDK/PyPI stay 0.3.0.

v4.54.4

2026-08-17

Patch — doctor $ lines are real commands.

  • Doctor restart command (#337) — gateway restart prints openclaw gateway restart, never English restart OpenClaw gateway.
  • $ is only prefixed on a real binary. Config grants stay notes.
  • threatGraph.trustModifier stays advisory. SDK/PyPI stay 0.3.0.

v4.54.3

2026-08-16

Patch — doctor mobile/tmux attention-first report.

  • Doctor report (#335) — failures and warnings first with Why + copy-paste $ commands; passes collapsed; duplicate themes merge with xN.
  • shieldcortex doctor --verbose restores the full pass list. Check logic and exit codes unchanged.
  • threatGraph.trustModifier stays advisory. SDK/PyPI stay 0.3.0.

v4.54.2

2026-08-16

Patch — loud DNP digest for headless Action Guard denials.

  • DNP digest (#331) — first denied_no_prompt_surface in a host window pages; later ones coalesce. Config: actionGuard.notify.dnpDigestWindowMs (default 15m, 0 = legacy).
  • Payload / permission_mode never mute. #310 design stays open (no approval cards).
  • threatGraph.trustModifier stays advisory. SDK/PyPI stay 0.3.0.

v4.54.1

16 August 2026

Patch: board grind + instruction-floor GHSA. trustModifier stays advisory.

  • Instruction-floor morphology tighten (GHSA-hx2c-rqg7-ggpm) — regex floor, not semantic
  • Caller-supplied user: identity no longer stamps provenance (#323)
  • Mac doctor UNKNOWN is a log-channel gap (#317)
  • Overflow risk, lease snapshot, shred-device FP, deny-surface honesty

v4.54.0

16 August 2026

Minor train: attestation Phases 3–5 — remaining pipeline callers, OpenClaw realtime record-only attestation, end-to-end sentinel + doctor Attestation coverage. trustModifier stays advisory — do not flip enforce until FP soak.

  • Phase 3: CLI scan / X-Ray / iron-dome attested; REST/langchain/universal stay NULL (#315)
  • Phase 4: OpenClaw realtime record-only attestation + JSONL wedge fix (#316)
  • Phase 5: e2e sentinel + doctor coverage metric; hook-only stale-process warn (#322)
  • Historic source_attested never backfilled

v4.53.0

15 August 2026

Minor train: threat-graph projector heal on upgraded installs, attestation Phases 1+2 (source_attested write-path + hook allowlist clamp), and allowlist scan / update-time batch review. trustModifier stays advisory — do not flip enforce until FP soak.

  • Threat-graph projector un-stall + doctor stall visibility (#304)
  • Attestation write-path NULL-preserving across MCP/read/delete/hook/tool-response/iron-dome (#308)
  • Hook-plane attestation behind allowlist clamp (#313)
  • shieldcortex allowlist scan + update hook (#311 / #309)

v4.52.3

15 August 2026

Hermes Action Guard — malformed 200 is unavailable, not allow. A 200 JSON body without a valid decision no longer coerces to allow and skips the catastrophic fallback on the bound Hermes plane.

  • +Strict verdict parse — missing / blank / unknown / non-dict responses set available=false so the #59 fallback still runs (PR #301).
  • +Bounded remote reasons — single-line, control-stripped, 400-char cap before hook messages.
  • +CI covers the Python plane — Linux job runs the Hermes plugin unit suite.

Upgrade: shieldcortex update then reinstall Hermes plugin if already installed: shieldcortex hermes install

v4.52.2

15 August 2026

Bound-plane honesty + portable shieldcortex/enforce. Docs stop selling Codex/Cursor MCP as deny hooks. Ships the Action Guard entry point and Hermes install path on npm @latest.

  • +Capability matrix — Claude Code / OpenClaw / Hermes can deny. Codex / Cursor / Copilot / generic MCP = memory only, not bound.
  • +import { evaluateAction } from 'shieldcortex/enforce' — portable guard; host must honour block / require_approval.
  • +shieldcortex hermes install — pre_tool_call plugin packaged on npm (enforce by default; conversation/freeze not bound).

Upgrade: shieldcortex update

v4.52.1

15 August 2026

Patch — Action Guard enable/enforce via signed CLI flags. Hosts on shieldcortex update can toggle Action Guard without hand-editing ~/.shieldcortex/config.json (which invalidated the embedded integrity signature).

  • +Signed Action Guard CLI — shieldcortex config --action-guard-enable|disable|enforce|advisory. Enforce also enables; advisory is warn-mode only. Status shows Off / Enforce / Advisory. Doctor points here instead of hand-edit paths (PR #296).
  • +No default behaviour change — absent keys still mean ON/enforce. Sibling keys (notify, reviewedScripts, broker) preserved on write.

Upgrade: shieldcortex update (or npm i -g shieldcortex@4.52.1)

v4.52.0

15 August 2026

Security residual grind — Action Guard precision, approval-broker field residual, and an instruction-detector floor that stops treating English morphology as a different language. Closes the open security board after v4.51.0: store-read FP deadlock, write-content scan, broker timed-out audit honesty, and Stage 1+2 instruction normalisation + morphology on both detectors.

  • +#89 store-read FP closed — pure shell observation of the approvals/decisions stores no longer deadlocks on enforced hosts. Interpreters, nested exec, function-defs, and glued redirects still gate. Fail-closed.
  • +#93 write-content scan — Edit/Write content is scanned on script and memory targets so write-then-exec cannot launder a payload past path policy. Ordinary docs prose stays allowed.
  • +#143 broker field residual — judge timeout 8s→15s with honest judge_timed_out audit. Timeouts never pre-clear / never auto-approve. Broker remains opt-in.
  • +#204 instruction-detector floor — shared normalisation (ZW/bidi, confusables, punct, classic leet as extra variant) + bounded morphology (active/passive/stop-following) on both detectInstructions and scanForInjection. Regex tier is a pre-filter floor — not multilingual or full-paraphrase coverage. Semantic stays async additive.
  • +Deny forensics + trust honesty — denial rows land before notify (#284); env override cannot claim operator/CLI trust (#273/#283); doctor/install/cred residual stack.

Upgrade: npm i -g shieldcortex@4.52.0 && shieldcortex update · OpenClaw: openclaw plugins update @drakon-systems/shieldcortex-realtime

v4.47.39

11 August 2026

The conversation firewall's honesty pass lands on main. Doctor stops reporting a healthy install over a wiped plugin stanza, and the two checks that could only ever report success get separated by cause.

  • +Doctor no longer reports healthy over a wiped plugin stanza, and the conversation firewall can now genuinely block and notify — still opt-in per host via hooks.allowConversationAccess (#222, #225).
  • +The reviewed-script exemption is per-file, never transitive (#189).
  • +The approval hash follows the command surface, not the tool name (#183).
  • +Operator-configurable memory caps (#238).

v4.47.38

11 August 2026

A full memory store no longer eats the memory you just saved. An outside report paired sixteen days of evidence: once long-term memory hit its cap, 169 of 171 writes below salience 1.0 were deleted milliseconds after remember reported success — and the memories most worth keeping were precisely the ones being dropped (#236).

  • +A one-hour grace window — a row created in the last hour is never an eviction victim, whatever the salience distribution says.
  • +Eviction now ranks by effective salience (recency × access × pin × downvote penalty) instead of a saturated raw value that had gone flat at 1.0 across the whole store.
  • +Pinned rows are never cap-evicted, on both the long-term and short-term eviction paths.

If you ran 4.47.35–4.47.37 with a full store: memories lost this way were deleted, not quarantined, and are not recoverable. Upgrading stops the loss.

v4.47.37

11 August 2026

Stop claiming protection we did not have. Three checks whose trigger condition was destroyed by the very fault they existed to detect, and the first defence on the conversation path that actually does something.

  • +Doctor no longer reports a healthy host with no protection on it — an installer wipe that deleted the plugin registration used to fall through to a green “healthy” verdict; on one box that was roughly an hour with no memory firewall and no Action Guard (#222).
  • +The plugin stops announcing conversation hooks OpenClaw refused to register — llm_input/llm_output require an explicit per-plugin consent grant; without it, the startup line now names only what will actually be live (#225).
  • +Conversation-path escalation, added — a detected injection now taints the session for 15 minutes and tightens the Action Guard one notch. Opt-in only, via hooks.allowConversationAccess: true on a host running OpenClaw ≥2026.5.12; ships dormant until an operator grants it (#233).
  • +The release gate can fail now, and says which failure it is — a stale ClawHub listing used to exit the CI job 0 (#200).

v4.47.36

10 August 2026

A blocked action now tells you it was blocked. When ShieldCortex stops a command on a machine with nobody at the keyboard — a scheduled job, a cron, an unattended agent — the operator used to receive a notification asking them to approve something that had already been refused. Answering it did nothing. Scheduled work could die quietly for hours with nothing to show for it.

  • +Denials and requests are different messages — a denial arrives as BLOCKED: this action did NOT run, naming what was stopped, which session and which directory, plus the command that authorises a retry. No Approve/Deny buttons on a request that is already dead.
  • +Carried on both channels — native OpenClaw approval cards and the webhook channel, which now sends the outcome as a header and a first-class field so a receiver can branch on it without parsing text. Webhooks gain a signing secret so a receiver can reject unsigned posts.
  • +A broken notifier is still a working guard — pinned by test: a receiver that errors, times out, or refuses the connection changes the guard’s decision by nothing.

Still to come on this thread: durable pending approvals and resumption. A denial still ends the job — you now learn that it did, and can authorise the retry.

v4.47.11 – v4.47.35

July – August 2026

Twenty-five releases of field hardening, summarised. Most came from real boxes breaking in ways we could reproduce — and several from outside researchers. Full detail in CHANGELOG.md.

  • +The guard reads the script, not just the command — every rule was previously bypassable by moving the code into a file and running the file. It now judges a delete by its target rather than its verb, and treats an installed CLI’s shim as the tool it is rather than the shell it wraps.
  • +Approvals reach the operator — an AI broker that can only ever move an answer toward caution, one-tap approve/deny on the channel you already use, an approval that stays spendable when the agent re-words its retry, and standing trust for scripts a human has reviewed.
  • +The credential detector caught up with its providers — an external report found it blind to OpenAI’s default key format since 2024, and the audit it triggered found the entropy net beneath it disabled for that whole class. Nine provider formats refreshed, with a standing test battery so a stale format fails the build rather than someone’s inbox.
  • +Install, update, uninstall and doctor stopped lying — hook commands must resolve rather than merely exist, install verifies its own registration and fails loud if a box would be left unprotected, uninstall removes everything install creates, and doctor’s schema check derives from the real schema.

v4.47.10

19 July 2026

The Action Guard now understands the difference between mentioning a dangerous command and running one. A quoted search pattern, a commit message, or a fetched URL that merely contains a dangerous-looking string is no longer mistaken for the real thing — while every command that actually executes is still gated.

  • +Mention-vs-intent span classifier — before deciding, the guard classifies where a dangerous token sits: executed shell code, a quoted data argument, or a URL. Quoted data (to a search/print command with no substitution) and in-URL mentions are recognised as mentions; a novel interpreter or any ambiguity stays treated as executed — fail-closed by design. This replaces a series of one-off false-positive fixes with a single general mechanism.
  • +Whitespace-obfuscation hardening — the shell ${IFS} trick (used to strip the spaces a scanner looks for) is now normalised before scanning, closing an evasion that hid a recursive chmod on root and a fork bomb.

v4.47.9

18 July 2026

The Action Guard fails closed on the dangerous tier when it can’t scan — and stops mis-blocking plain single-file deletes. The last fail-open path is closed across all three runtimes, and a false positive that hard-blocked ordinary deletes is fixed.

  • +Dangerous ops fail closed on a scan failure — if the guard can’t scan (module error, unreachable scanner), a recognised-dangerous operation is now gated instead of silently allowed, on the OpenClaw, Claude Code, and Hermes surfaces. Benign work still passes, but every “could not scan” decision leaves an audit breadcrumb.
  • +No more false catastrophic blocks on plain deletes — a filename containing a token like -verify was being read as a recursive-force flag, hard-blocking an ordinary single-file delete. Fixed; genuine recursive-force deletes still block.

v4.47.8

18 July 2026

Guard observability: doctor learns to check the Action Guard, allow-decisions become auditable, and the Hermes gate stops failing open. The enforcement layer is now visible in its own diagnostics and forensics — you can tell “scanned and allowed” from “never scanned.”

  • +Doctor checks the Action Guard — shieldcortex doctor now runs three live verdict probes through the real guard (catastrophic blocks, dangerous prompts, benign allows) and flags when your config opts a surface down — or when the two config surfaces disagree.
  • +Auditable allows — a recognised allow now leaves an audit entry, so “scanned and allowed” is distinguishable from “never scanned” in forensics. Benign noise stays out of the log; an unwritable audit sink now warns loudly instead of dropping entries silently.
  • +Hermes fails closed — when the scanner is unreachable, the Hermes runtime gate now denies unambiguous catastrophic commands via a dependency-free fallback scan (matching the OpenClaw and Claude Code surfaces), instead of waving everything through.

v4.47.7

18 July 2026

Guard tune: residual evasion shapes closed, wrapper and quote evasions gated, use/mention precision. Two adversarial follow-up passes on the Action Guard land together — every fix shipped failing-first with must-still-fire and must-still-allow siblings.

  • +Residual pipe/heredoc shapes closed — stdin-executing python modules (code/pty/pdb) no longer slip the inline-program exemption; the dot-spelling of the shell source builtin is caught; a heredoc body written to a file that a later statement executes stays scanned. The fail-closed fallback scanners learn the new shape too.
  • +Wrapper and quote evasions gated — env/nohup/nice-wrapped scheduler mutations and quoted global-install flags now gate like their bare forms; read-only listings stay exempt through wrappers.
  • +Use/mention precision — a grep whose search pattern mentions a delete utility no longer gates (anchored to command position), and npm's workspace-local --global-style flag no longer over-gates as a global install.

v4.47.6

15 July 2026

Docs-and-disclosure alignment — the published trust claims now match the shipped package. A cross-surface audit compared every published claim (npm README, ClawHub skill, plugin manifest, docs) against the shipped code; everything that didn't match got fixed. No pipeline or guard behaviour changes.

  • +Honest trust table — the skill's provenance table now discloses the bounded postinstall script and the real 8-dependency list instead of claiming neither existed.
  • +Plugin README matches shipped defaults — enforce-by-default Action Guard with the fail-closed fallback documented, correct compatibility floors (ShieldCortex ≥ 4.18.3, Node ≥ 20), and the actionGuard config keys documented in README + manifest.
  • +/shieldcortex-status shows the Action Guard — enforcement state (enforce/warn/off) and auto-approve count are now visible in the plugin's own status output.

v4.47.5

14 July 2026

Seven confirmed command-guard bypasses closed, and the guard now fails closed when it can't load. An adversarial pass proved seven ways past the Action Guard — every one is closed with a failing-then-passing regression test, and the catastrophic path no longer depends on the guard loading at all.

  • +7 bypasses closed — newline-after-echo scan escape, env-prefixed and tee-staged curl | bash, decode-to-shell chains, registry code-exec via npx/dlx, find -delete, recursive chmod/chown on system dirs, and dd/truncate/scheduler shapes. 69/69 new bypass suite, 314/314 full Iron Dome suite.
  • +Fail-closed catastrophic path — if the compiled guard can't load, a dependency-free fallback scanner still denies the unambiguous catastrophes (rm -rf /, raw-disk writes, fork bombs, curl | bash) instead of allowing everything.
  • +ReDoS hardening — three patterns with quadratic backtracking on pipe-dense input (up to 12s) rebuilt as bounded checks (<300ms).

v4.47.4

14 July 2026

The field-hardening batch: false-positive precision, honest plugin status, MCP self-heal. Five over-blocking classes from the fleet dogfood narrowed — each with a must-BLOCK sibling fixture proving the real attack still blocks — on top of v4.47.3's plugin-loader reconciler.

  • +Mention-vs-intent discipline — quoted commands in documentation, interpreters running their own inline programs, and workspace-local npm install no longer trip blocks; curl | sh and global installs still do. Block reasons are now human-readable codes.
  • +Honest status & self-heal — openclaw status recognises managed npm installs instead of reporting “no files on disk” while enforcement runs; a better-sqlite3 ABI mismatch at MCP startup now repairs itself loudly instead of a bare -32000.
  • +Consent-gated canary — an optional synthetic catastrophic op dispatched through the actually-installed interceptor to actively prove enforcement; an unobservable result reports “not proven”, never a fabricated pass.

v4.47.2

10 July 2026

Credential exfiltration is now a first-class classification. Credential-material access combined with off-host movement hard-blocks in enforce — either half alone stays clean, and loopback/RFC1918/tailnet destinations don't count as exfiltration.

  • +credential_exfil — recognises the dangerous conjunction directly (key/token/vault reads × outbound POST/nc/scp) instead of falling through to generic signals.
  • +Hermes gate enforces by default — the pre_tool_call gate now blocks BLOCK/QUARANTINE verdicts out of the box; SHIELDCORTEX_ENFORCE=0 drops back to advisory. A down scanner still never wedges the agent.
  • +Fleet regression pack — the Athena/Edith dogfood false-positives and keep-blocks are locked in as fixtures so precision can't regress silently.

v4.47.0

4 July 2026

Pricing model change: public tiers are now Free + Enterprise. Every local feature is free — the self-serve Pro and Team tiers are retired, the auto 14-day trial is gone, and cloud signup is open to everyone. Plus: the Action Guard reaches Claude Code.

  • +Everything local is free — custom injection patterns, Iron Dome policies, firewall rules, audit export, the dependency scanner, Cortex, Dream Mode, and unlimited X-Ray (the 5-scans/day limit is gone) no longer require a licence. Cloud/org features (fleet sync, team management, SSO) are Enterprise via sales@drakonsystems.com; grandfathered Pro/Team keys keep working.
  • +Cloud signup open to all — the dashboard's email → magic-link signup connects anyone to the cloud free tier (500 scans/month, 7-day audit retention).
  • +Claude Code PreToolUse guard — every Claude Code tool call runs through the shared Iron Dome action guard: catastrophic ops deny outright, dangerous ops route through Claude Code's native permission dialog, and unattended dangerous calls fail closed.

v4.46.0

2 July 2026

The dangerous tier enforces by default, and the zeroth law makes breaking the host a release-blocker. Previously only catastrophic operations were enforced; recognised-dangerous operations now gate by default with a per-agent autoApprove escape hatch for unattended jobs.

  • +Enforce by default — sudo systemctl, real-path rm -rf, forced git rewrites and friends now require approval; unattended with no approver fails closed; enforce: false opts back down to advisory.
  • +The zeroth law — ShieldCortex must never break the gateway or agent it protects: no implicit gateway restarts (headless installs skip the restart entirely), tests can never touch live services, hooks stay timeout-bounded.
  • +Project-key repair works headless — --execute now counts as consent in non-interactive sessions (it silently no-opped for every agent and cron job), and doctor --fix-project-keys one-shots the unambiguous repairs.

v4.45.0

30 June 2026

ShieldCortex now runs on Hermes too — a native pre-tool-call gate. The defence pipeline that protects OpenClaw agents now ships for the Hermes Python runtime as well, and the doctor learned to recommend tappable approval buttons.

  • +Hermes plugin — a Hermes-native gate that scans every tool call through ShieldCortex via pre_tool_call → REST /api/v1/scan. Advisory-first, fail-open (a down scanner never blocks), and install-isolated to ~/.hermes/plugins/. Coexists cleanly with an OpenClaw ShieldCortex on the same host.
  • +Doctor: approval-buttons hint — shieldcortex doctor recommends enabling Telegram inline approval buttons when they're off — recommend-only, never rewrites your config.

v4.44.0

29 June 2026

Action Guard field discipline — plus a claims-proof suite and the overseer guard. The runtime Action Guard now distinguishes what the agent does from what it merely describes.

  • +Field discipline — the Action Guard scans only the execution surface (shell command, target path, egress URL), never content the agent produces. A status message that merely quotes rm -rf / is data, not an action — it no longer trips a block. 56/56 guard + 61/61 related tests.
  • +Claims-proof suite — every public security claim is now backed by a firing test (12/12, 0 gaps).
  • +Overseer-manipulation guard (P1) — detects attempts to manipulate the human approver at the approval boundary.

v4.43.0

28 June 2026

Two new runtime defence layers: the Action Guard and the Environment Firewall. Beyond protecting what the agent stores, ShieldCortex now guards what it does and what it sees.

  • +Iron Dome Action Guard — gates what the agent does: hard-blocks the unambiguously catastrophic (recursive root deletes, fork bombs, curl | sh, secret exfiltration) regardless of config, routes the rest through approval. Positive-recognition — benign work is never interrupted.
  • +Environment Firewall — protects what the agent sees: auto-catches hidden web/prompt injection in fetched pages and tool output before their content becomes authority.

v4.30.2

3 June 2026

OpenClaw registry installs are now visible to ShieldCortex update and doctor. OpenClaw-managed realtime plugins live in OpenClaw's registry, not the old extension path. v4.30.2 teaches shieldcortex update and shieldcortex doctor to read that source of truth, refresh stale registry installs, and report the installed plugin version instead of silently skipping it.

  • + Registry-aware updates — OpenClaw registry-managed installs are refreshed with openclaw plugins update shieldcortex-realtime; legacy file-copied installs are migrated away from the duplicate-install state.
  • + Plugin version drift is visible — doctor now reports the realtime plugin version and warns when it is behind the ShieldCortex npm package, so stale fleet boxes no longer look healthy by accident.

v4.30.1

2 June 2026

Setup now persists SessionEnd hook removal when that is the only change. Running setup without --with-session-end on a machine where the optional SessionEnd hook was still wired could print that the hook was removed but skip writing the settings file. v4.30.1 counts removals as real changes, writes them to disk, and keeps doctor output aligned with what setup reported.

v4.30.0

2 June 2026

Privacy hardening for the realtime plugin — threat metadata only, never your input text. The optional OpenClaw realtime plugin now forwards only threat metadata (type, scores, timestamps) when it flags something, and only when Cloud sync is explicitly enabled. Flagged-content previews stay in your local audit log and are never transmitted. ShieldCortex ships with a full data-handling disclosure documenting exactly what is read, stored, and — only if you opt in — sent.

  • + Metadata-only threat reporting — the realtime plugin strips input/output text before any network call; only threat metadata leaves the machine, and only with Cloud sync on. Local-first by default, as always.
  • + Data handling, privacy & consent — a new disclosure spells out what each path transmits: audit telemetry (metadata only), team memory sync (opt-in, off by default), quarantine (credentials redacted), realtime threats (metadata only).
  • + Deterministic releases — a cross-worker test-isolation race that intermittently broke CI is fixed at the root, so updates ship reliably without manual intervention.

v4.29.0

2 June 2026

The “salience wall” is gone — memory now ranks by what's actually relevant. Over time, auto-captured memories had piled up at maximum salience, so ranking could no longer tell signal from noise — the same stale items surfaced every turn and boot context filled with low-value fragments. This release re-grounds salience end-to-end, closes the capture paths that inflated it, and adds a one-time self-healing migration that repairs existing stores in place — fully reversible.

  • + Effective-salience ranking — recall and boot context now rank by recency, access, and pinning, not a raw score that 80% of memories shared. Never-recalled memories are no longer silently zeroed out of the ranking.
  • + Self-healing backfill — a one-time migration clamps historic auto-captured rows down off the ceiling on first start, behind an in-DB backup table and a pre-migration file snapshot. Undo any time with shieldcortex memory revert-backfill.
  • + Relevance-gated recall — per-turn recall can drop weakly-matched memories by query-term coverage. Ships in shadow mode (logs what it would drop, changes nothing) until you opt in with SHIELDCORTEX_RECALL_ENFORCE=1.
  • + Cleaner capture — hook and auto-sourced writes can no longer mint maximum-salience rows; the OpenClaw memory hook now shares the same hardened, sentence-bounded extractor as everything else; and near-duplicates are caught across every capture path on write.
  • + No more “frankenmemories” — consolidation stopped concatenating duplicate bodies into ever-growing memories; it now keeps the strongest copy and demotes the rest.

v4.24.3

26 May 2026

Memory-extraction quality — sentence-bounded captures, first-sentence headlines, per-session recall dedupe. The auto-extract chunker was sliding fixed-character windows over assistant turns and labelling them by keyword presence — producing memories that grabbed 150 chars regardless of where the sentence ended, with headlines of the first 50 raw chars. Literal \n JSON-escape sequences leaked through the chain. Adjacent user turns recalled near-identical memories because the recall hook had no dedupe.

  • + Sentence-bounded captures — every extractor pattern now stops at the first . / ! / ? / newline, falling back to the 200-char cap only if no terminator is reached. Applied to all six auto-extractors.
  • + First-sentence headlines — the MEMORY.md index now shows the first complete sentence (up to 80 chars at a word boundary), not the first 50 raw characters. URLs / decimals / version strings no longer fool the boundary detector.
  • + Defensive JSON-escape unescape — strips literal \n / \t / \r sequences that survived a stringify/parse round-trip upstream, before regex matching. Idempotent on already-unescaped input.
  • + Per-session recall dedupe — content hashes of injected memories persisted per session with a 5-item ring and 1-hour TTL. Same memory can't appear in two consecutive turns of the same session. Each recalled snippet now carries a _[mem #N]_ source ref so operators can grep / inspect the backing memory.

v4.24.2

26 May 2026

Hotfix — CLI scans on headless servers were silently dropping cloud sync. Companion bug to v4.24.1. Once the gate was open (Free tier unblocked for audit-ingest), CLI scans on macOS started syncing reliably — the launchd-managed dashboard daemon kept the Node process alive long enough for the fire-and-forget POST to complete. On headless Linux servers (cron jobs, ad-hoc ssh scans, container entry points), shieldcortex scan … ran the pipeline, printed results, and called process.exit() within ~1 second — aborting the in-flight fetch.

  • + Track in-flight cloud-sync promises in a module-level Set inside src/cloud/sync.ts. The fire-and-forget signature is preserved for the 50+ existing callers.
  • + New flushPendingCloudSync(maxWaitMs = 8000) awaits all tracked promises with a timeout. Wired into the scan and scan-skill CLI subcommands immediately before process.exit(). Headless servers now drain cloud sync reliably; long-lived processes don't need to call it.

v4.24.1

26 May 2026

Hotfix — Free-tier audit sync to Cloud was incorrectly gated behind Team tier. The defence pipeline's audit-metadata sync (the feed for the Cloud dashboard's scan counts, threat timeline, and device list) was gated on isFeatureEnabled('cloud_sync') — but cloud_sync is a Team-tier feature. Every Free install with a valid cloud API key was silently dropping audit data. The Cloud dashboard appeared stuck on the No scan data yet empty state for every Free-tier user — contradicting the published Free-tier offer (500 scans/mo + 7-day retention).

  • ~ Split cloud_sync into two narrower features: cloud_audit_sync (Free — audit metadata only, no content) and cloud_sync (Team — full bidirectional sync incl. memories, knowledge graph, and quarantine content).
  • ~ Re-gate the audit-ingest call on cloud_audit_sync. Free-tier installs with a configured cloud API key now actually fire POST /v1/audit/ingest on each scan, as the dashboard has always expected. Quarantine content sync stays on cloud_sync (Team) — correctly.

v4.24.0

25 May 2026

Gentle Pro-tier upsell — doctor footer + dashboard banner. Free users now get a non-pushy “you can upgrade — 1-2-3” nudge in two places: the shieldcortex doctor output (where engaged users already look) and the local dashboard's shield overview. The doctor footer renders at most once per week; the dashboard banner is dismissable for 7 days. Anyone already on Pro / Team / Enterprise — or in an active trial — sees nothing.

  • + Three trigger conditions evaluated in priority order: trial_ended (Pro trial expired within the last 30 days), usage (monthly defence_audit count ≥ 80% of the Free 500/mo cap), and engagement (oldest memory ≥ 14 days AND total memories ≥ 100).
  • + Throttle + mute — 7-day cooldown via ~/.shieldcortex/upsell-state.json; mute via npx shieldcortex config --upsell-mute.
  • + Dashboard banner mirrors the existing CloudUpsellCard state-machine pattern. Dismissable via X or Maybe later for 7 days. No telemetry, no remote calls — local-only.

v4.23.0

25 May 2026

Prompt-aware recall — FTS rank is now primary, salience the tiebreaker. Pre–v4.23.0 the UserPromptSubmit recall hook filtered candidates by FTS5 keyword match (ORDER BY fts.rank) but then did a final sort by raw salience — discarding the relevance signal entirely. High-salience-but-off-topic memories bubbled to the top of the per-prompt 🧠 Recalled from memory: preamble. This release picks the simplest of three candidate approaches: FTS-primary ordering with salience as the tiebreaker — no new dependencies, smallest blast radius.

  • ~ prompt-recall-hook.mjs ranking — replaced raw-salience final sort with an FTS-rank-primary / salience-tiebreaker comparator. FTS5 BM25 ranks are negative numbers; lower (more negative) = more relevant. The category-boost fallback is preserved.
  • i session-start-hook.mjs ranking stays salience-DESC — no query at session start, so FTS rank isn't applicable; the preamble's job is “what's important right now”, not “what matches your current question”.

v4.22.1

25 May 2026

Quiet the defence canary — drop the stderr noise that v4.22.0 introduced on cold doctor runs. Field signal showed v4.22.0's canary fires correctly (15–17ms, pattern matched) but leaked a [Events] Failed to persist event: Error: Database not initialized stack trace to stderr ahead of the check output. The doctor's other DB-touching checks lazy-init via getDatabase() and work fine, but the events DB needs explicit init that hadn't happened yet when the canary fired. Canary still worked; the output was polluted.

  • ~ checkDefenceCanary() calls detectInstructions() directly instead of routing through the full runDefencePipeline(). Same signal — the firewall layer catches the marker or it doesn't — without the DB dependency, the audit-log write, or the event persist. As a bonus the canary now runs in ~1ms instead of 15–17ms, and stops accumulating cli:doctor:canary rows in defence_audit.

v4.22.0

24 May 2026

Defence canary + recall quick wins. Field-driven release closing two field critiques: “the defence layer is unprovable from inside the session” and “recall surfaces too much half-formed shrapnel with mid-word cuts.”

  • + Defence canary doctor check — shieldcortex doctor now runs a synthetic-injection probe (__SHIELDCORTEX_CANARY_PROBE_v1__) through the defence pipeline and asserts the firewall blocked it. Output: ✅ Defence canary: caught (10ms, pattern: defence_canary). Moves the defence layer from “unprovable” to “self-attested” — every doctor invocation is a positive heartbeat for the security claim.
  • + Word-boundary-aware truncation — new truncatePreservingWords(text, maxChars, lookback=20) backs off to the last whitespace/punctuation boundary within 20 chars of the limit and appends …. Replaces hard slice(0, N) + '...' at SessionStart (200-char limit) and UserPromptSubmit recall (150-char limit).
  • ~ Auto-extract salience cap — calculateSalience() now supports { autoExtractMode: true }, capping the return at 0.6 instead of 1.0. Safety-in-depth: the downstream cap was already in place; making the function itself cap is the structural fix.

v4.21.2

24 May 2026

Doctor catches up to the v4.21.1 packaging contract — the OpenClaw plugin pkg check now reports INFO on the post–v4.21.1 “no discovery vectors” state. v4.21.0's doctor logic was tightly coupled to the v4.18.3-era invariant that the bare shieldcortex always shipped a root openclaw.plugin.json. v4.21.1 deliberately removed it — at which point the doctor's invariant ran backwards: healthy installs got reported as WARN because the manifest the doctor expected to find was no longer there. This release replaces the manifest-required INFO branch with a visibility-first model.

  • ~ Visibility-first INFO — the bare is INFO when it has zero OpenClaw discovery vectors (post–v4.21.1 architecture). It is WARN when either vector is present (openclaw.extensions field OR root manifest), with the WARN message naming the specific vector so operators can diagnose.
  • ~ WARN fix-message now points at the real fix: cd ~/.openclaw/npm && npm install shieldcortex@latest.

v4.21.1

24 May 2026

Kill the OpenClaw duplicate plugin id detected warning at its real source — drop the root openclaw.plugin.json shim that v4.20.0 left in the tarball as a one-release defensive measure. v4.20.0 removed openclaw.extensions from the main package, intending to make the bare shieldcortex invisible to OpenClaw's discovery. Fleet evidence showed the warning persisted — OpenClaw's bundledDiscovery: "compat" scans node_modules/*/openclaw.plugin.json independently of package.json#openclaw.extensions. The defensive root manifest was still being picked up. With this release the bare ships neither discovery vector — fully invisible to OpenClaw.

  • ~ Root openclaw.plugin.json removed from the published tarball: dropped from package.json's files allow-list, removed from the repo working tree, build script no longer copies the plugin manifest to the package root.
  • i openclaw.hooks kept in package.json — still load-bearing for the documented openclaw hooks install flow. The dedicated @drakon-systems/shieldcortex-realtime plugin remains the only discoverable target.

v4.21.0

24 May 2026

Stop the doctor crying wolf about peer-range version skew on healthy fleet boxes. Since v4.18.3 the bare shieldcortex sitting at ~/.openclaw/npm/node_modules/shieldcortex has been the expected steady state — OpenClaw's managed-peer-deps installer drops it there to satisfy @drakon-systems/shieldcortex-realtime's peerDependencies.shieldcortex. v4.19.1 taught the doctor to report INFO instead of WARN, but only when the bare version exactly equalled the realtime version. In practice OpenClaw never refreshes the bare copy when realtime upgrades — every fleet box where realtime moved forward still got WARN even though the install was healthy.

  • ~ Doctor uses semver.satisfies() against realtime's declared peer range instead of strict equality. When the bare satisfies peerDependencies.shieldcortex AND the root manifest exists → INFO.
  • ~ Realtime peer range widened — @drakon-systems/shieldcortex-realtime's peerDependencies.shieldcortex changes from ^4.20.0 to >=4.18.3 <5.0.0. v4.18.3 is the architectural floor.
  • ~ Out-of-range fix message refined — doctor now suggests openclaw plugins update @drakon-systems/shieldcortex-realtime rather than rm (which doesn't stick — peer-resolution restores the same version from cache).
  • + semver is now a declared direct dependency (^7.7.0). Was previously transitively loadable; making it explicit removes the fragility of relying on indirect resolution.

v4.20.0

22 May 2026

Drop openclaw.extensions from the main package — kill the OpenClaw duplicate plugin id detected warning at its source. OpenClaw's npm discovery is gated on openclaw.extensions. Pre–v4.20.0 both the main shieldcortex package and the dedicated @drakon-systems/shieldcortex-realtime plugin declared one, so OpenClaw scanned both copies (the bare main package gets pulled in as the realtime plugin's peer-dep), registered both under pluginId: shieldcortex-realtime, deduped, and emitted the warning on every openclaw update. Functionally fine (the right dist/index.js always won) but cosmetic noise on every fleet box. The bare shieldcortex is now invisible to discovery; the dedicated realtime plugin remains the only registration target.

  • + Kept openclaw.hooks on the main package — still load-bearing for the documented openclaw hooks install flow.
  • + Packaging test inverted to pin the new contract; doctor check unchanged (still handles mixed-version fleets where pre-4.20.0 bare copies linger).

v4.19.1

22 May 2026

Doctor: OpenClaw plugin pkg check goes WARN→INFO for the expected post–v4.18.3 peer-dep state. Since v4.18.3 the bare shieldcortex landing at ~/.openclaw/npm/node_modules/shieldcortex has been the expected steady state of a healthy install. The doctor's WARN here was conservative noise. Now reports INFO when bare version matches the installed realtime plugin AND the root manifest exists; WARN/FAIL retained for actual surprises (version mismatch, missing peer sibling, missing root manifest).

v4.19.0

21 May 2026

Living Constellation — the knowledge graph as a living map. The dashboard graph view at /memory/graph now has a pinned anchor node, a breathing animation, memory-activity pulses, and particles drifting along the hottest edges as new memories form. The 527-line ConstellationGraph.tsx monolith was refactored into a slim wirer composing seven focused modules. Pulse triggers wire through /ws/events with a polling fallback against /api/memories?mode=recent.

  • + Pinnable anchor + click-to-orbit: the most-connected entity is pinned at canvas centre on load; click any node to smoothly transfer the anchor. Drag any node to pin it in place (drag-to-pin). Shift-click to release a user pin. Double-click empty canvas to reset.
  • + Three-layer pulse system: always-on breathing modulated by salience; spikes on memory.created; warm glow on memory.accessed. Energy budget bounds directional-particle render to the top-N edges by recent activity.
  • + Settings → Graph Motion intensity selector (Subtle / Moderate / Strong) persisted per-browser; prefers-reduced-motion: reduce short-circuits breathing + particles + tweens for accessibility. memory_created / memory_accessed events now carry entity_ids so the client can light up the right node without an extra round-trip.

v4.18.5

18 May 2026

Modern Node support — no more cryptic native crash on Node 23/24/25/26. engines.node was unbounded (>=18) while better-sqlite3 ^11's prebuilts stopped at older Node ABIs — users on a newer Node without a compiler hit a bare libc++abi … Napi::Error crash-loop with zero guidance. Node-LTS users were unaffected; this closes the gap.

  • + Bumped better-sqlite3 ^11 → ^12 (prebuilts for Node 20/22/23/24/25/26); engines.node >=20 (Node 18 EOL). Added a guarded native loader + postinstall smoke-check that emit one actionable message instead of the opaque abort.

v4.18.4

17 May 2026

Cap the cloud sync retry queue. The 7-day TTL purge (purgeOldEntries) only runs while the brain worker is alive; MCP-only installs have no worker, so a long offline stretch could grow sync_queue on disk without bound. Now hard-capped at 5,000 rows, enforced on every enqueue and on the worker purge path. Eviction priority: already-synced → terminally-failed → oldest-pending. Once-per-hour warning when trimming kicks in. Fire-and-forget contract preserved.

v4.18.3

17 May 2026

OpenClaw gateway crash fix — bare shieldcortex ships root openclaw.plugin.json so config validation passes. After openclaw update pulled shieldcortex@4.18.2, OpenClaw config validation failed with "plugin manifest not found" because the package carried openclaw.extensions but didn't ship a root manifest. The tarball now ships openclaw.plugin.json at the package root, byte-identical to the canonical plugin manifest, and the declared openclaw.extensions[0] is resolvable from the published files.

v4.18.2

16 May 2026

shieldcortex doctor detects misplaced bare shieldcortex in the OpenClaw plugin tree. Background: on 2026-05-15 a fleet OpenClaw gateway restart-looped because a stale bare shieldcortex package had landed in ~/.openclaw/npm/node_modules/ — where only the dedicated @drakon-systems/shieldcortex-realtime plugin belongs. Diagnosis required SSHing into the box by hand. Doctor now reports FAIL on the stale state (declared extension entry missing — the crash-loop class), WARN when the bare package is present with its entry intact, and PASS on healthy installs.

v4.18.1

14 May 2026

Audit-pass patch — memory-safe JSONL imports, path-traversal hardening, replay UX polish. Two things move the needle for users with substantial transcript archives: JSONL imports now stream the file in 64 KB chunks via readSync + StringDecoder (UTF-8 safe across chunk boundaries) and flush parsed rows in 2,000-row transactional batches — peak memory is now bounded regardless of archive size; and POST /api/sessions/import-jsonl validates paths against $HOME + os.tmpdir() with path.normalize blocking .. traversal.

  • + Replay UX polish: SessionList surfaces API errors instead of a perpetual "Loading…"; EventDetail renders a skeleton while switching sessions.

v4.18.0

14 May 2026

Session Replay UI — scrub every prompt, tool call, and response. A scrubbable timeline of every captured session lives at /memory/replay: session list on the left, kind-coloured tick timeline with a draggable playhead in the centre, focused-event detail on the right. Play, pause, scrub, 0.5×–4× speed, full keyboard control. Renders cleanly in both terminal and glass themes via the existing dual-render primitives.

  • + Dashboard route /memory/replay with three-column responsive layout. Sessions sortable by recency or event count. Selected session lives in ?session=… so refresh + share-by-URL work.
  • + Transport + keyboard: space toggle, ←/→ step, shift+arrows jump to ends, [/] cycle speed. Shortcuts skip when typing in inputs.
  • + Glob-aware import endpoint: POST /api/sessions/import-jsonl accepts file paths, glob patterns, or empty body (defaults to ~/.claude/projects/**/*.jsonl). The dashboard's Import JSONL button uses the zero-arg form for one-click backfill.

v4.17.0

10 May 2026

Session Capture Backend — turn-by-turn event store, JSONL importer, HTTP API. ShieldCortex now records every prompt, response, tool call, tool result, and hook fire into a dedicated session_events table with enough fidelity to scrub/replay a session end-to-end. Two ingestion paths in lockstep: live capture (hook scripts) and batch import (shieldcortex import-jsonl). A content_hash + UNIQUE index makes re-imports idempotent.

  • + session_events schema with CHECK kind IN (prompt|response|tool_call|tool_result|tool_error|hook_fire), project + ts indexes, and an audit-id foreign key so events outlive their audit rows.
  • + JSONL importer maps Anthropic SDK content blocks to event kinds. Thinking blocks are skipped (not user-replayable). SHA-256 content_hash + INSERT OR IGNORE drops collisions silently.
  • + Live hook capture wired into prompt-recall, session-end, and pre-compact hooks. Opt-out via captureEvents=false.
  • + Four new HTTP routes: list, detail, paginated events, import.

v4.16.0

10 May 2026

Defence pipeline + chunker hardening on the auto-capture write path. Three coupled defects closed: session-end / pre-compact / stop hooks routed memories through the firewall pipeline (defence_audit rows now created on every capture); 9 built-in firewall rules seeded on first run; and the chunker rejects six classes of malformed candidates (imperative tool-call segments, email-body fragments, bare imperatives, etc.) before they reach the dedupe stage. Auto-extract salience capped at 0.6.

v4.15.0

10 May 2026

Hybrid retrieval with Reciprocal Rank Fusion + LongMemEval benchmark harness. ShieldCortex's recall pipeline now fuses FTS5 keyword, vector cosine, and graph-walk retrievers via Cormack et al. (2009) RRF (k=60). The harness reproduces locally via npm run bench against a 5-question toy fixture today; numbers against the full LongMemEval-S corpus are on the roadmap and not yet published. Legacy weighted-sum scoring stays available as a one-release safety belt (SHIELDCORTEX_RANKER=legacy).

  • + Reproducible benchmark: npm run bench produces benchmark/longmemeval/SCORECARD.md with R@5, R@10, MRR, and per-question diff between RRF and legacy engines. CI uploads the scorecard as a release artifact on every tagged push.
  • + Multiplicative post-fusion boosts (recency, category, link, tag, activation, contradiction penalty) modulate the rank-fused score without drowning the underlying retrieval signal — what additive weighted-sum couldn't avoid.

v4.14.4

6 May 2026

Doctor disk check excluded local-AI model cache from the 100 MB safety limit. The 100 MB limit predates the local Review Copilot AI Explainer feature. Once a user opts into local AI, ShieldCortex caches ~750 MB of Qwen2.5-0.5B-Instruct ONNX weights under ~/.shieldcortex/models/. Doctor walked the entire tree, so users with the model cached saw a permanent Disk: at limit! plus a fix command (Run consolidation or delete old memories) that would never recover the bytes — memories prune only operates on rows in memories.db, never on model files.

  • ~ models/ excluded from the 100 MB limit. Disk check now splits the directory into a data bucket (DB, state, audit, logs, telemetry, quarantine — everything except models/) and a models bucket. The 100 MB limit applies only to data. The models total is still reported as a parenthetical (e.g. 2.0 MB / 100 MB limit + 750.0 MB models).
  • ~ Fix message updated to point at the actual recovery commands (shieldcortex memories prune --execute / memories dedupe --execute) instead of the vague Run consolidation.
  • + 6 new tests in doctor-disk-models-exclusion.test.ts covering small data + small models, the bug case (small data + 200 MB models), 99 MB data fail with DB-trimming fix, 85 MB warn, no models/ subtree, and missing scDir.

v4.14.3

6 May 2026

Two unrelated regressions surfaced after v4.14.2: shieldcortex update couldn't reconcile the OpenClaw plugin on 2026.5.5+, and doctor still hardcoded the pre-v4.14.0 sampling cadence in one cosmetic message.

  • ~ shieldcortex update passes --force to openclaw plugins install. OpenClaw 2026.5.5 added a guard that refuses install when the plugin is already present, telling the caller to use update or --force. Reconcile is by definition an overwrite — the user wants the latest plugin, not the existing one. --force also handles fresh installs (no-op when nothing to replace). Reconcile detection extended to include the ~/.openclaw/npm/node_modules/... path so the step actually runs on 2026.5.x installs.
  • ~ Doctor's stop-hook fallback default lowered 10 → 5 to match the canonical default in scripts/lib/auto-memory-config.mjs. Users without an autoMemory.stopHookSamplingTurns override now see the correct value in the Auto-memory: Stop hook row.

v4.14.2

6 May 2026

Fix — shieldcortex install ignored timeout drift on existing hook entries. Doctor correctly flagged a too-low UserPromptSubmit=2s (canonical 5s) timeout (the v4.14.0 #43 check working as intended) and pointed users at Re-run shieldcortex install to restore canonical timeouts. But running install logged = Hook: UserPromptSubmit (already configured) and exited without updating the timeout — re-running doctor showed the same warning. setupHooks() only added missing hooks; existing shieldcortex entries were treated as immutable.

  • ~ setupHooks reconciles timeouts on existing entries. After the npx-migration pass, reconcileHookTimeouts() walks every hook event in ~/.claude/settings.json and, for any entry whose command references shieldcortex AND whose timeout is below the canonical value, bumps it to canonical. Higher-than-canonical user overrides are preserved. Non-shieldcortex entries are never touched. Doctor warn → install → no-warn now actually works. Idempotent on re-run.
  • + 4 tests in hook-timeout-reconcile.test.ts pin the contract: 2 → 5 bump, idempotency, non-shieldcortex isolation, above-canonical preservation.

v4.14.1

6 May 2026

Fix — OpenClaw plugin install fails on OpenClaw 2026.5.5+. Field-filed within minutes of v4.14.0 going live: every fleet host running shieldcortex update saw the npm package install successfully but the OpenClaw plugin reinstall step bail with HOOK.md missing in /tmp/openclaw-hook-…/extract/package/llm_input. OpenClaw 2026.5.5 introduced a new install-time hook-pack validator that, for every entry declared in openclaw.hooks, requires a directory of that name at the package root containing HOOK.md plus a handler.ts/handler.js or index.ts/index.js.

  • + Per-hook stub directories for llm_input, llm_output, before_tool_call, session_end. Each contains HOOK.md with YAML frontmatter and a minimal handler.js stub. validateHookDir only checks file existence at install time; runtime hook handlers are still registered via register(api) in dist/index.js, so behaviour is unchanged.
  • ~ Plugin files: array extended to ship the four new directories. Plugin peerDependency bumped to shieldcortex: ^4.14.1.

v4.14.0

Major 6 May 2026

Auto-memory hardening — coordinated fix for issues #42, #43, #44, #45. Field-filed by Jarvis after observing 7 days of effectively empty memory on a stock install: 5 STM rows, 0 LTM, 0 episodic. Investigation surfaced four faults in the auto-memory pipeline, all real, all stacking — silent-amnesia from a project-key mismatch (#42), recall drops from a too-tight hook timeout (#43), 90% sampling loss from a too-sparse modulo gate (#44), and STM→LTM promotion never running because the brain worker never autostarted under the default MCP-only install shape (#45). Each issue's fix on its own would still have left the others producing the same symptom.

  • ~ #42 — silent amnesia from project-key mismatch. All hook writers (stop, session-end, pre-compact) now derive project keys via the shared deriveProjectKey() helper instead of local extractProjectFromPath() copies. New TS port mirrors the .mjs helper so the MCP-server side matches the hook side. Both SHIELDCORTEX_PROJECT_KEY and the legacy CLAUDE_MEMORY_PROJECT are honoured.
  • + #42 data recovery — shieldcortex memories repair-project-keys. New CLI subcommand: dry-run by default, --map basename=canonical, --scan-paths <dirs>, --include-stm, auto-backup before write, JSON log of every rewrite, idempotent on re-run.
  • ~ #43 — UserPromptSubmit hook timeout 2 s → 5 s. Cold-spawn floor on the recall hook is ~1.5 s; the previous 2 s ceiling SIGKILLed the hook silently under IO pressure. 5 s leaves ~3 s headroom on a busy host.
  • ~ #44 — stop-hook 1-in-10 sampling left LTM under-fed. Default stopHookSamplingTurns lowered 10 → 5. New stopHookSalienceBypass (default true) skips the modulo gate when the recent transcript window contains a fenced code block or hits ≥2 keyword categories. High-signal turns get captured at any cadence; low-signal turns still throttle.
  • ~ #45 — STM→LTM promotion never ran on hooks-only installs. Brain worker now autostarts in MCP-server mode under a new lightweight 'mcp' profile (15 min cadence, no medium tick, no cloud sync). Pre-4.14, the worker was only instantiated by --mode dashboard / --mode api / --mode worker — typical hooks-only installs never reached it, and consolidate() never fired. Each light tick persists pid + profile + lastLightTick state to ~/.shieldcortex/state/worker.json. SHIELDCORTEX_DISABLE_WORKER=1 escape hatch.
  • + Four new shieldcortex doctor checks: auto-memory sampling, brain-worker freshness, project-key consistency, hook timeouts.
  • + 18 new tests + 936 existing pass across hooks-project-key-alignment, brain-worker-mcp-profile, and repair-project-keys.

v4.13.2

5 May 2026

Fix — doctor stale-lock check produced false positives for long-running daemons. Field-filed against a local install. shieldcortex doctor reported ⚠️ Lock: stale lock file found: memories.db.lock and instructed deletion, despite the recorded PID (shieldcortex dashboard, started 36+ hours earlier under launchd) being alive and actively holding the lock. Following the suggested fix would have broken the dashboard's coordination with the database. Symptom traced to checkLockFile flagging any lock with mtime > 1h as stale — a heuristic that's wrong for daemons launched at boot.

  • ~ PID liveness, not mtime age, decides staleness. checkLockFile now parses the lock file's JSON payload, reads the recorded PID, and runs process.kill(pid, 0). ESRCH ⇒ stale, EPERM ⇒ active, success ⇒ active. Matches the semantics already in acquireStartupLock. The 1-hour mtime fallback is replaced by a 24-hour fallback used only when the lock file is unparseable or missing a PID field.
  • + 5 new tests in doctor-lock-check.test.ts covering live-PID-with-old-mtime (the bug), an ESRCH PID, unparseable-and-old, unparseable-and-recent, and the empty-directory pass case.

v4.13.1

5 May 2026

Fix #41 — auto-memory hooks: triple-gating produced silent-amnesia. Field-filed by Jarvis within 24 hours of v4.13.0 going live. v4.13.0 shipped opt-in Stop and SessionEnd hooks gated in three independent places — install flag, runtime gate, and sampling counter. The install flag and runtime gate had no link, so passing --with-stop-hook wired the hook but left the runtime gate at default-false. The hook fired on every turn and immediately process.exit(0)'d with no log line. Looked indistinguishable from "the model forgot."

  • ~ Single source of truth: install flag IS the runtime gate. setupHooks with stopHook / sessionEnd options now writes autoMemory.enableStop: true / enableSessionEnd: true to ~/.shieldcortex/config.json alongside the settings.json wiring. Re-running setup without the flag disables both layers symmetrically.
  • ~ Loud bail, once per session. Stop hook now prints [shieldcortex stop-hook] disabled — set autoMemory.enableStop=true … to stderr the first time it bails in a session and plants a sentinel under ~/.shieldcortex/logs/stop-hook-disabled-sessions/ so subsequent fires stay quiet.
  • + Doctor surfaces resolved gate state. New checkAutoMemoryHooks reports Auto-memory: Stop hook and Auto-memory: SessionEnd hook. Wired+gate-on → pass, wired+gate-off → warn with the silent-amnesia hint, gate-on+not-wired → warn (inverse mismatch), neither → info opt-in (not installed).
  • ~ OpenClaw plugin sub-package republished as @drakon-systems/shieldcortex-realtime@4.13.1, fixing a long-standing publish-shape bug that OpenClaw 2026.5.4's stricter validator finally caught (files: array missed dist/; openclaw.hooks key was missing).

v4.13.0

4 May 2026

Auto-memory pipeline capture-rate fix + per-hook telemetry. Field diagnosis found memories.db empty after weeks despite hooks installed. Root causes: PreCompact rarely fires; when it does, only the last 50 transcript lines were scanned; a slash-command filter silently dropped /skill turns. Fixed end-to-end, plus a sampled Stop hook and the diagnostics to make "fires but extracts nothing" visible.

  • ~ Transcript reader rewrite — three duplicated slice(-50) readers replaced with a single shared helper that tail-reads up to 1 MiB (configurable) and applies a smart slash-command filter: drop only single-line slash invocations under 200 chars, keep multi-line and long slash messages with prose. On an 85 MB local transcript: 38 messages from the last 1 MiB vs ~5 under the old slice.
  • ~ Stop hook is now a sampling extractor — old behaviour blocked Claude with exit 2 to nudge a remember call (cost an extra turn each time). New behaviour counts assistant turns from the transcript tail and runs full extraction every Nth turn (default 10). Always exits 0. Opt-in via --with-stop-hook.
  • + SessionEnd hook (opt-in) — --with-session-end install flag wires SessionEnd as a final extraction backstop for sessions that never compact. Gated by config AND a process.env-based OpenClaw-context guard so it can't regress the v4.10 OpenClaw-crash class.
  • + Per-hook telemetry — new hook_invocations table records every firing (hook name, time, duration, memories extracted, transcript bytes scanned). shieldcortex status now shows a Hook activity (last 7 days) section so "fires but extracts nothing" stops being indistinguishable from "never fires".
  • + New autoMemory.* config namespace in ~/.shieldcortex/config.json — maxTranscriptBytes, stopHookSamplingTurns, enableSessionEnd, enableStop, and more. Defaults preserve current behaviour for every existing user.
  • + 14 new transcript-reader tests + 1 deep-clean test fix — full suite 904/904 passing across 78 suites. Includes a related fix for the deep-clean test that was inconsistent with the c16ccc1 native-install detection (Mac homebrew false-positive fix).

v4.12.11

27 April 2026

The suspected fleet-wide context-killer + install churn. Two surgical fixes in the install/uninstall paths. One is the suspected root cause of weeks of cross-fleet Claude Code context loss; the other stops shieldcortex update from rewriting OpenClaw's config every time it runs.

  • ~ Context-killer fix — pre-v4.12.11 uninstall left mcpServers.memory in ~/.claude.json pointing at a now-missing binary. Every Claude Code session loaded the orphan, tried to spawn the binary, failed, and the spawn-fail cascaded into context loss across the fleet. New removeMcpEntry() with ownership check (only deletes SC-owned entries — won't clobber the official upstream MCP server which uses the same generic key), wired into both uninstallSetup() and uninstallAll() paths.
  • ~ openclaw.json install idempotency — trustLocalPlugin() used to bump a fresh installedAt timestamp on every call regardless of state, churning the gateway's config-watcher on every npm install -g. New pluginInstallNeedsWrite() pure helper makes the install + uninstall a no-op when state already matches. Loop test on a real Mac confirms 6 back-to-back installs produce zero writes.
  • i Two related claims investigated and disproven — SC ships no SKILL.md path it doesn't actually ship (the references found are SC's own skill-scanner module that scans third-party skills); memory extraction code is correct end-to-end since v4.12.5 (the "still returning 0" report was anecdotal — FLEET-STATUS doesn't even contain a memory-count metric).
  • + 17 new tests across uninstall-mcp-cleanup.test.ts and openclaw-install-idempotency.test.ts. Credit to Edith (peer agent) for finding the mcpServers orphan.

v4.12.10

25 April 2026

Background service crash-loops with exit 209/STDOUT after the logs dir is removed. Caught on Jarvis and Tars after this session's residue cleanup wiped ~/.shieldcortex/. The systemd unit hardcoded StandardOutput=append: to a path inside that dir. systemd opens that file before any ExecStart*, so once the directory disappeared, the service entered a permanent restart loop (300+ attempts on Jarvis). ExecStartPre=mkdir would not have helped — file open precedes ExecStartPre too.

  • ~ Logs now go to journald — StandardOutput=journal with SyslogIdentifier=shieldcortex-${mode}. Inspect with journalctl --user -u shieldcortex-dashboard.service. No filesystem dependency — rm -rf of any user dir cannot break it.
  • + Stale-unit detector — shieldcortex service status now recognises pre-v4.12.10 broken units and prints the missing log dir as the reason. Migrate with shieldcortex service repair --headless.
  • i Why journald and not LogsDirectory= — that directive needs systemd ≥ 250 for user units, and Ubuntu 22.04 ships systemd 249. Journald works on every supported version and survives any cleanup of user dirs.

v4.12.9

25 April 2026

v4.12.8 didn't actually silence the audit — comments count. v4.12.8 extracted cloud sync to its own module so no plugin file paired the two APIs. But the new module included a doc comment that named both APIs alongside the actual call. OpenClaw's audit fired immediately on the next install. The audit is purely textual — it does not strip comments before scanning.

  • ~ Doc comment trimmed in cloud-sync.ts to one line that does not name the file-read API.
  • ~ Test now mirrors OpenClaw's real scan — raw text, no comment stripping. v4.12.8's test stripped comments because that's what a thoughtful linter would do; OpenClaw doesn't, so the regression shipped. Don't infer a spec — mirror the implementation.
  • + Future regressions caught locally — if anyone re-introduces an explanatory comment that names both APIs in the same plugin file, the test now fails before publish, not after the fleet hits a fresh install.

v4.12.8

25 April 2026

OpenClaw 2026.4.24 plugin-audit warning silenced. The new install-time security scanner flagged shieldcortex-realtime with [potential-exfiltration] because readFileSync and fetch() appeared in the same source file. False positive — the two operations never share data — but the heuristic is textual.

  • ~ Cloud sync extracted to its own module (plugins/openclaw/cloud-sync.ts) with zero fs imports. Mirrors the pattern already used for intercept-ingest.ts. Behaviour-equivalent: same threat object, same endpoint, same 5s timeout.
  • + Static-analysis test guard — asserts no plugin source file pairs readFileSync/readFile with fetch(. Stops the warning ever silently coming back if the two operations are re-merged.
  • i Two related findings are not SC bugs — plugins.installs_unpinned_npm_specs (OpenClaw installer records @latest unless given an exact pin) and plugins.installs_version_drift (clears with openclaw plugins update --all). Both are upstream.

v4.12.7

25 April 2026

Mac homebrew false-positive fix — root cause of the v4.12.3–v4.12.6 Mac regression. Doctor kept flagging legitimate plugin config entries as orphans on every Mac install. Linux fleet hosts never hit it.

  • ~ Wrong installPath recorded — the native-package install code (Mac homebrew) wrote installPath = .../plugins/openclaw (the package root) instead of .../plugins/openclaw/dist (where the manifest actually lives). Doctor checked the wrong path, didn't find the manifest, and false-flagged the install.
  • ~ Defensive fallback for old installs — detectInstallState() now also checks installPath/dist/openclaw.plugin.json so existing Mac hosts with the bad path written stop false-flagging on next doctor run, before they even need to re-install.
  • + 4 new tests — repro of Friday's scenario, plus source-level guards that the writer always uses the correct convention.

v4.12.6

25 April 2026

Install now restarts the OpenClaw gateway — symmetric with uninstall --deep. Without this, an npm-package upgrade left the running gateway with the old plugin in memory until something else triggered a restart. Caught Edith mid-fleet-rollout: package on 4.12.5, plugin still loading 4.12.2, status reporting 0 memories / never.

  • ~ Auto-restart by default — shieldcortex openclaw install now calls the same gateway-restart helper that uninstall --deep uses (systemctl on Linux, launchctl on macOS). Skipped when both --no-hooks and --no-plugins are passed.
  • + New --no-gateway-restart flag for scripted multi-step installs that want to defer the restart.
  • ~ Platform-specific manual fallback — if the auto-restart fails, the installer prints the exact systemctl / launchctl command for the host.
  • + 8 new tests lock in the wiring (option declared, CLI flag parsed and passed through, default-true gating, "only restart when something installed" guard, no duplicated implementation).

v4.12.5

25 April 2026

Auto-extract write path fix — v4.12.4 unblocked the read side of auto-extract; v4.12.5 closes the write side. Both pre-compact and session-end hooks built INSERT statements that omitted the uuid column. The schema declares uuid TEXT NOT NULL UNIQUE with no default, so every insert silently errored with NOT NULL constraint failed: memories.uuid and zero memories landed.

  • ~ UUID generated on every insert — new shared scripts/lib/save-memory.mjs util generates crypto.randomUUID() and binds it to the INSERT.
  • ~ Single write path for both hooks — pre-compact and session-end now delegate to the same util, so they can no longer drift apart and produce "one hook works, the other silently fails" bugs.
  • + 5 new tests against a fresh SQLite DB built from the real schema — covers the bug repro, UUID uniqueness over bulk inserts, null project, and tag JSON encoding.

v4.12.4

25 April 2026

Silent zero-memory fix — every fleet host running ShieldCortex from inside a dotfile-prefixed working directory (e.g. ~/.openclaw/workspace) was producing 0 auto-extracted memories on every pre-compact event. Doctor was green, hooks were "configured", but the actual capture was zero.

  • ~ Encoder mismatch — pre-compact's auto-extract path encoded the cwd into a Claude Code project-folder slug by replacing only / with -. Claude Code itself replaces both / and ., so the lookup never matched the folder Claude Code wrote and the transcript was never opened.
  • ~ Now matches Claude Code exactly — new scripts/lib/claude-project-dir.mjs util replaces /, \, ., and : with - and prefixes a leading separator. Other hooks (session-end, prompt-recall, session-start, stop) were audited and confirmed safe — they receive transcript_path directly from the hook payload.
  • + 6 new tests covering the original repro plus dot-inside-component and Windows path scenarios.

v4.12.3

25 April 2026

Doctor recognises Mac homebrew installs — v4.12.2 only checked ~/.openclaw/extensions/ for the plugin. On macOS via homebrew the plugin actually lives in the npm-global tree at /opt/homebrew/lib/node_modules/shieldcortex/... (OpenClaw's "native-package" discovery mode). Doctor saw "no plugin" and flagged the legitimate config entries as orphans.

  • ~ installPath-aware detection — detectInstallState() now reads .plugins.installs[shieldcortex-realtime].installPath from openclaw.json first (the path the installer actually used), with user-space and home-relative npm-global fallbacks for older installs that pre-date the field.
  • + 2 new tests covering the homebrew repro and the missing-installPath fallback path.

v4.12.2

24 April 2026

Doctor DB-init guidance fix — v4.12.1 doctor's "Database: not found" suggested-fix told you to run shieldcortex quickstart, but quickstart only configures hooks/MCP — it doesn't touch the database. On TARS during fleet rollout the user looped on quickstart → doctor → quickstart. v4.12.2 points at the right command.

  • ~ New suggested fix — shieldcortex scan "init" creates the database explicitly. Works on every install shape (Claude+OpenClaw, OpenClaw-only, headless).
  • ~ Lazy-init alternative noted — on Claude+OpenClaw hosts the message also mentions starting a Claude Code session, which lazy-inits the DB via the MCP server on first memory call.
  • + 3 new tests lock the corrected guidance in: no quickstart reference inside checkDatabase(), explicit scan "init" reference present, MCP lazy-init mention preserved.

v4.12.1

24 April 2026

Doctor fix — v4.12.0's OpenClaw residue check flagged legitimate install state as "residue". A freshly-installed host showed 6–7 false-positive warnings and pointed users at uninstall --deep to "purge" a healthy install. v4.12.1 teaches doctor to tell the difference.

  • ~ Orphan-only detection — new scanForOrphans() applies presence-aware filtering. Plugin config entries are only flagged if the extension dir is gone. Hook config entries are only flagged if no cortex-memory hook dir exists. Current install paths are never orphaned; legacy paths and ClawHub skill-locks always are.
  • ~ Tailored "clean" message — doctor now reports "clean (plugin + hook installed, config aligned)" when the install is healthy, instead of a generic "clean" line that left operators unsure whether the check actually ran.
  • ~ uninstall --deep unchanged — still purges everything unconditionally, since its job is total removal for cleanup scenarios.
  • + 7 new tests covering the Case repro, missing-plugin-dir, missing-hook-dir, legacy-always-flagged, ClawHub-always-flagged, canonical-dirs-never-flagged, and a migration guard.

v4.12.0

24 April 2026

ShieldCortex ↔ OpenClaw compatibility pass. Closes the "partial uninstall" gap that left orphan config entries after every version bump, and unlocks OpenClaw 2026.4.23's host-package linking for peer-declared plugins.

  • + shieldcortex uninstall --deep — scans 15 known residue locations across ~/.openclaw/openclaw.json, .clawhub/lock.json, and stale hook/extension dirs. Surgically removes ShieldCortex references while preserving sibling keys, then best-effort restarts the gateway. --no-gateway-restart opts out.
  • + shieldcortex doctor gains OpenClaw residue check — reports dirty-location count and points at uninstall --deep as the fix. Skipped cleanly on non-OpenClaw hosts.
  • + Plugin declares openclaw as optional peer dep — unlocks OpenClaw 2026.4.23's host-package linking (#70462). Plugin manifest hints at engines.openclaw >=2026.4.23 recommended.
  • + Hash-stability guard — 4 static-analysis tests lock in the invariant that the CLAUDE.md INSTRUCTIONS block contains no runtime-dependent content (no Date.now, randomUUID, env reads). Protects against the same silent session-wipe class of bug v4.11.1 closed for MCP config.
  • ~ 19 new tests — 8 deep-clean, 7 plugin-manifest, 4 hook-hash-stability.

v4.11.1

22 April 2026

Fleet-critical fix — MCP registration no longer uses npx -y. The installer now resolves and pins the installed shieldcortex binary path, falling back to npx -y only when no global install exists. Closes a silent session-wipe loop.

  • ~ Why it mattered — npx -y resolves dynamically every invocation. Any shift in what it resolves to (cache misses, fresh publishes, version drift) flipped the MCP config hash, triggering cli session reset reason=mcp and wiping context mid-conversation. Observed on TARS firing ~every 30 minutes before the fix.
  • ~ Stale registrations auto-upgrade — re-running shieldcortex setup on v4.11.0-or-earlier installs rewrites the MCP config to the stable binary path.

v4.11.0

22 April 2026

Memory-injection side is now opt-in. Default behaviour flipped so Recall / CLAUDE.md / session hooks only inject when explicitly enabled — resolves the cases where auto-injection was bloating context windows on resumed sessions.

v4.10.1

20 April 2026

Upgrade-path fix — shieldcortex update now always reconciles the OpenClaw plugin and skill, even when the main npm package is already on the latest version.

  • ~ Short-circuit removed — the early-return when main was current was skipping plugin + skill reconciliation, so v4.9 → v4.10 upgraders stayed stuck on the old plugin. Plugin now always gets rm -rf + fresh install, skill always gets force-reinstall.
  • ~ If you're on v4.9.x, run shieldcortex update once and all three components — main, plugin, skill — land on 4.10.1 in one shot.

v4.10.0

20 April 2026

Environment Firewall (Phase 1) — new third defence layer protecting what the agent sees. Memory firewall covers what the agent stores, Iron Dome covers what it does, Environment Firewall covers what it trusts from the world around it.

  • + New CLI shieldcortex env scan <url> — fetches a URL, scores provenance, extracts visible vs hidden content, runs injection patterns against each surface, returns a taint label (trusted / untrusted / suspicious / hostile). Exit codes 0/1/2 so it drops into CI.
  • + Hidden-instruction detection — display:none, visibility:hidden, zero font-size, off-screen positioning, same-colour text, ARIA-hidden, HTML comments, inline scripts, Unicode bidi overrides, zero-width characters, meta refreshes. Injection patterns found in hidden content mark the page HOSTILE regardless of domain.
  • + Provenance scoring — TLS, redirect chain, domain allowlist, suspicious TLDs, Punycode homograph flags, raw-IP hosts, embedded credentials.
  • + Library export — import { scanUrl } from 'shieldcortex/environment'.

v4.9.1

16 April 2026

Cloud audit log alignment — closed silent data loss between npm and SaaS audit ingest.

  • ~ blocked_patterns now persisted — npm package sends the matched pattern list on every audit event; SaaS schema and DB columns store it for review.
  • ~ fragmentation_score now persisted — cross-memory assembly score travels through /v1/audit/ingest instead of being silently dropped.

v4.9.0

16 April 2026

Defence pipeline hardening — wired skill scanner threat patterns into write-time pipeline.

  • + Skill threat patterns at write-time — the firewall now blocks the seven skill scanner categories on every memory write, not just on demand: tool_injection, scope_escalation, data_exfiltration, persistence, supply_chain, agent_manipulation, and stealth_instruction.
  • + Decoded content re-scan expanded — base64/hex payloads are now re-checked against credential detection and the seven skill threat patterns, not just the legacy injection set.
  • + Path traversal protection — /api/skills/scan rejects ../ escapes before touching the filesystem.

v4.7

8–11 April 2026

Proactive Recall, self-update CLI, OpenClaw plugin hardening, and database resilience improvements.

  • + Proactive Recall — relevant memories auto-injected into every conversation before the model responds. FTS5 + category boost in under 100ms. Works with Claude Code and OpenClaw.
  • + shieldcortex update — new CLI command to check for and install the latest version.
  • + Clickable dashboard — stat cards, hygiene numbers, and quality items navigate to the relevant view on click. Review focus wiring auto-scrolls to the right section.
  • + Cloud sync actions — Clear Failed button in the warning banner. Honest messaging for dead-letter failures instead of "healthy with failed history".
  • ~ Database resilience — auto-reconnect when the live DB file is replaced during recovery. Stale backup cleanup on startup. Precision fix for threshold comparisons.
  • ~ OpenClaw plugin hardened — removed child_process dependency for scanner compatibility. Auto-migrate stale hook registrations. Plugin reinstall handles existing directories automatically.
  • ~ Quality API aligned — duplicate counts now match between stat cards and review queue. SKILL.md rewritten for ClawHub scanner transparency.

v4.6

6–7 April 2026

Constellation Graph, Review Queue redesign, X-Ray accuracy, cloud sync diagnostics, and 13 bug fixes.

  • + Constellation Knowledge Graph — cluster-based view with coloured nebula halos, bloom-on-click drill-down, and cross-cluster ghost links.
  • + Review Queue redesign — card-based flow with Keep/Suppress/Archive actions, slide animations, and progress bar.
  • + X-Ray accuracy — eliminated 98% of false positives with path exclusions, header-only polyglot checks, and code-aware obfuscation detection.
  • + Cloud sync diagnostics — clear failed items, manual refresh, save feedback, replication status cards.
  • ~ Auth token race conditions, WebSocket reconnect, graph search limits, button defaults, keyboard accessibility, and 8 more fixes.

v4.5.0

3 April 2026

Finding lifecycle, X-Ray findings dashboard, dashboard redesign with dark theme, and watch mode improvements.

  • + Finding Lifecycle — X-Ray findings now have persistent status (new, reviewed, ignored, resolved, quarantined) with review, ignore, resolve, quarantine, and delete actions.
  • + Findings Tab — new tab in X-Ray with status filters, stats summary, and action buttons on every finding.
  • + Dashboard Redesign — OpenClaw-inspired dark theme with coral/cyan accents, glassmorphic cards, simplified navigation from 18 routes to 5 tabbed sections.
  • + Real-time Alerts — watch detections broadcast via WebSocket with toast notifications in the dashboard.

v4.4.0

2 April 2026

X-Ray Pro — automated defence features for CI/CD, file monitoring, npm installs, and agent memory.

  • + CI/CD Gate — --ci --threshold=HIGH exits with code 1 when risk meets or exceeds threshold. Drop into any pipeline.
  • + File Watch — --watch continuously monitors a directory for changes, debounces, and scans incrementally. Only new findings printed.
  • + Pre-install Hook — shieldcortex xray-preinstall runs as an npm lifecycle script. Blocks installs with HIGH+ risk findings.
  • + Memory Guard — X-Ray scans content before it enters agent memory via the OpenClaw plugin. Prompt injection, hidden directives, and obfuscated payloads are blocked automatically.

v4.3.0

2 April 2026

X-Ray — a new product module for inspecting packages, files, and plugins for hidden risk.

  • + X-Ray Scanner — shieldcortex xray <target> scans local files, directories, and npm packages for eval/exec, shell execution, AI directives, prompt injection, steganography, obfuscation, unicode tricks, network beacons, persistence hooks, and dependency risk.
  • + Trust Score — 0–100 score with SAFE / LOW / MEDIUM / HIGH / CRITICAL risk levels.
  • + Deep npm scan — --deep flag pulls registry metadata for full package analysis (Pro).
  • + Output formats — --json and --markdown for scripting and reports.

v4.2.x

March 2026

Stability, Docker safety, and dependency scanner improvements.

  • + Docker Install Safety — detects Docker/container environments and skips shell config modifications that break images.
  • + Dependency Scanner fixes — resolved missing runtime.mjs, improved HOOK_FILES array.
  • + OpenClaw plugin v4.2.1 — tool call interceptor with deny cache and audit logging.

v4.0.0

March 2026

Major release — Dream Mode, Hybrid Recall, and memory intelligence overhaul.

  • + Dream Mode — offline memory consolidation with deduplication and compression.
  • + LLM-Powered Hybrid Recall — semantic + keyword search with AI reranking.
  • + Memory Types & Scopes — structured memory with typed entries and project scoping.
  • + Staleness Scoring — automatic decay and cleanup of outdated memories.
  • + Positive Feedback Capture — learn from what works, not just what threatens.

For older releases, see the GitHub releases page.