Release notes
HOL Guard v3.58.0a2
PreviewHOL Guard v3.58.0a2, released October 26, 2026, is a preview release with 3 additions, 2 improvements, 13 fixes and 3 other changes across 20 merged pull requests. Highlights: Derive and publish the policy verifier key natively; Check configured MCP servers in workspace assessments.
3 added · 2 improved · 13 fixed · 3 other
Key facts
- Version
- v3.58.0a2
- Channel
- Preview
- Published
- Previous release
- alpha/v3.58.0a1
- Merged pull requests
- 20
Documented changes
21 typed entries
Verified contributors
1 verified contributor · 21 credits
Attribution coverage
attribution complete; history inventory partial.
Install
Scope
Guard v3.58.0a2 is a preview release published 2026-10-26. Upstream documents: Guard 3.58.0a2 is an opt-in prerelease cut from 1229abf. Stable installations remain on the stable channel. 21 commits • 21 merged pull requests • 1 contributor since Guard 3.58.0a1. Its comparison base is alpha/v3.57.0a5. It includes 21 verified contribution deliveries with public evidence links.
Changes
Added
3- runtimeDerive and publish the policy verifier key natively (#6011) Evidence for this change
- guardCheck configured MCP servers in workspace assessments (#5993) Evidence for this change
- Python reuses Guard's harness adapters to find configured MCP servers and sends every one with the worktree roots (as named and with links followed). The runtime keeps only servers whose configuration file sits under a…
- Only each server's launch command, arguments and URL go to the runtime over stdin. Environment, headers and other settings stay behind. The new
mcp-config-assess --stdinruntime command reads no files and starts… - The rules live in
guard_command::mcp_config_risk, on top of a sharedguard_command::launch_screenthat later hook checks reuse. A launch reaches a POSIX shell script (sh,bash,zsh,dash,ksh,fishand…
- workspaceCheck agent skills in background workspace assessments (#5990) Evidence for this change
- The native workspace snapshot takes a
skillsflag. With it, the runtime runs the sharedskill_content_riskrules over the bytes it already hashed for eachSKILL.mdunder.claude/skills,.agents/skills… - Each finding carries the rule id, category, severity, confidence, the rule's fixed title, reason and false-positive hint, and the skill's root-relative path. The rule's technical detail can quote skill text, so the…
- A skill the scan could not read in full leaves the detector
incomplete: one over the hook-time skill size bound, one that is not UTF-8, one the snapshot itself skipped, any snapshot limit that may have hidden a…
- The native workspace snapshot takes a
Improved
2- runtimeDrop the unused extension-control snapshot slot (#5998) Evidence for this change
- hookDelete the rest of the CLI hook pipeline and the helpers only it called (#5991) Evidence for this change
Fixed
13- extensionsStop a failed policy save from blocking every later save (#6015) Evidence for this change
- nativeRead logged launches, rooted find -exec and looped inline programs as review (#6007) Evidence for this change
- Logged background launch.
node server.js > /tmp/x.log 2>&1 & ...carried the redirect reason, not the background reason, so the launch had no segments and its script read as a file nobody opened. A launch whose… find -execunder a quoted home root.find "$HOME/Downloads/x" -type f -exec basename {} \;was refused for containing$. A$is now accepted only when it opens a double-quoted parameter followed by/, so…- Inline program in a loop.
for f in ...; do [ -f "$f" ] && node -e '...' "$f"; doneread thenode -elaunch as an interpreter running an unread file. Each launch in a list or loop is now read on its own (split…
- Logged background launch.
- commandRead a package directory flag the same way for every verb (#6003) Evidence for this change
- connectKeep polling for device approval when one request goes unanswered (#6005) Evidence for this change
- A poll that times out, or fails with a refused or reset connection (directly or wrapped in
URLError), doubles the polling interval up to 60 seconds and polls again. - Once the device code deadline passes, it stops with a message that says Guard Cloud did not answer and how to request a new code.
- Other
URLErrorcauses, such as certificate failures, and managed-network policy blocks (ManagedNetworkError) still fail immediately.
- A poll that times out, or fails with a refused or reset connection (directly or wrapped in
- releaseShip a Linux ARM64 native wheel on the GitHub release (#6009) Evidence for this change
- Build: a
manylinux_2_17_aarch64wheel around the staticaarch64-unknown-linux-muslruntime, compiled on theubuntu-24.04-armrunner by the existing single-wheel workflow. The full-task Gauntlet runtime… - Release only: the platform joins
GITHUB_ONLY_PLATFORM_TAGS, so PyPI staging leaves it out. The pure wheel'snative-wheels.jsonlists its digest along with every other platform wheel. - Update path:
hol-guard updateon a pure-wheel Linux ARM64 install downloads that wheel from thevrelease and checks it against the embedded digest manifest, the same check Windows ARM64 gets. Doctor…
- Build: a
- packageBlock bundle-flagged Copilot and exec-flow packages before review (#6004) Evidence for this change
- Copilot sends its command in
toolArgs. The daemon's package check only readtool_input.command, so it never evaluated the command.
- Copilot sends its command in
- updatePoint native Windows ARM64 Python at x64 Python (#6006) Evidence for this change
hol-guard updateon awin-arm64interpreter (sysconfig.get_platform()) that fails while building cryptography or rfc3161-client now stops with statusblockedand reason…- The message gives the reinstall command for the active installer (
pipx install --force --python " " hol-guard, theuv tool installequivalent, or that interpreter's pip) and the check that the… - Guard lists installed x64 interpreters from
py -0p, skipping-arm64and-32tags, and asks each one for its own platform before labeling it x64. If none is found, the message points at the 64-bit python.org…
- commandWalk a project's own skills tree without review (#5994) Evidence for this change
- claudeStore a tool-call permission notice with its credentials masked (#6001) Evidence for this change
hook_authority_state_op/flows.rs:claude_record_noticemaskscommandandraw_command_textontool_callnotices withredacted_command_tokens::redact_textbefore signing. The notice and pending rows are one…- The direct hook lane (
hook_direct_review_notice.rs) and the daemon's fallback writer (_record_claude_permission_notice) both store through this op, so there is one masking point and no Python change. - Other artifact types are stored as sent. A
tool_action_requestcommand feeds the saved policy's exact-match context (hook_decision_native_permission_persist.rs), and masking it would change that hash.
- commandRefuse a contained run that hands the shell a directory search path (#5996) Evidence for this change
- storeMask credentials in queued tool-call commands (#6000) Evidence for this change
ApprovalRequest::decodemasks credentials in atool_callrow'slaunch_targetandraw_command_textwithguard_command::redacted_command_tokens::redact_text, the redaction the generic queue builder already…- Both queue writers decode through this function: the resident hook writer (
add_native_review_approval_request) and the generaladd_approval_requestpath that the daemon uses. One change covers both. native_bash_requestandtool_action_requestrows are left alone, because their scope and exact-match checks re-parse the stored command.
- guardSay when a workspace has no dependency files to check (#5989) Evidence for this change
normalizeAssessmentexposesdependencyFilesFound, false whendetectors.supply_chainisno_inputs.- The empty findings copy for such a workspace becomes "No dependency files were found, so there were no dependencies to check.", followed by the secret result when the secret detector ran.
- Workspaces with dependency files keep the existing copy.
- guardReport dependency files below audit discovery as unchecked (#5986) Evidence for this change
- The Rust snapshot walk flags any manifest or lockfile deeper than the audit's discovery depth and marks the snapshot partial with the
undiscovered_dependency_inputreason. The discovery depth is now shared from… - The dashboard coverage panel explains the new reason in plain language.
- Fix verification treats the new reason like the existing unsupported-lockfile reason: the snapshot is still readable, so verification does not fail on it.
- The Rust snapshot walk flags any manifest or lockfile deeper than the audit's discovery depth and marks the snapshot partial with the
Other changes
3- Guard 3.58.0a2 is an opt-in prerelease cut from
1229abf. Stable installations remain on the stable channel. 21 commits • 21 merged pull requests • 1 contributor since Guard 3.58.0a1. Evidence for this change - plugin-releaseRun plugin releases with Guard 3.58.0a1 (#5997) Evidence for this change
- plugin-releasePin Guard 3.58.0a1 so release summaries can carry the Blue line (#5995) Evidence for this change
- Merged pull request #5989: fix(guard): say when a workspace has no dependency files to check (#5989)
- Merged pull request #5994: fix(command): walk a project's own skills tree without review (#5994)
- Merged pull request #6006: fix(update): point native Windows ARM64 Python at x64 Python (#6006)
- Merged pull request #6011: feat(runtime): derive and publish the policy verifier key natively (#6011)
- Merged pull request #5993: feat(guard): check configured MCP servers in workspace assessments (#5993)
- Merged pull request #5986: fix(guard): report dependency files below audit discovery as unchecked (#5986)
- Merged pull request #6007: fix(native): read logged launches, rooted find -exec and looped inline programs as review (#6007)
- Merged pull request #5991: refactor(hook): delete the rest of the CLI hook pipeline and the helpers only it called (#5991)
- Merged pull request #6003: fix(command): read a package directory flag the same way for every verb (#6003)
- Merged pull request #6000: fix(store): mask credentials in queued tool-call commands (#6000)
- Merged pull request #5996: fix(command): refuse a contained run that hands the shell a directory search path (#5996)
- Merged pull request #6010: fix(package): block bundle-flagged packages launched with npx and bunx (#6010)
- Merged pull request #6004: fix(package): block bundle-flagged Copilot and exec-flow packages before review (#6004)
- Merged pull request #5998: refactor(runtime): drop the unused extension-control snapshot slot (#5998)
- Merged pull request #5990: feat(workspace): check agent skills in background workspace assessments (#5990)
- Merged pull request #6001: fix(claude): store a tool-call permission notice with its credentials masked (#6001)
- Merged pull request #5997: chore(plugin-release): run plugin releases with Guard 3.58.0a1 (#5997)
- Merged pull request #6015: fix(extensions): stop a failed policy save from blocking every later save (#6015)
- Merged pull request #6005: fix(connect): keep polling for device approval when one request goes unanswered (#6005)
- Merged pull request #5995: chore(plugin-release): pin Guard 3.58.0a1 so release summaries can carry the Blue line (#5995)
- Merged pull request #6009: fix(release): ship a Linux ARM64 native wheel on the GitHub release (#6009)
Upgrade and compatibility
None documented.
Compare with the previous release
Predecessor on the same channel: alpha/v3.58.0a1
Verified contributors
Credits derive from public pull-request authorship, verified commit authorship, or verified co-authorship — never from thanks text or release metadata. Each distinct contributor is listed once; the evidence ledger paginates every published credit record.