Release notes
HOL Guard v3.60.0a98
PreviewHOL Guard v3.60.0a98, released November 15, 2026, is a preview release with 6 additions, 12 fixes and 6 other changes across 23 merged pull requests. Highlights: Promote a harness claim only from a matching live evidence receipt; Show where Claude Code hooks go before install writes them.
6 added · 12 fixed · 6 other
Key facts
- Version
- v3.60.0a98
- Channel
- Preview
- Published
- Previous release
- alpha/v3.60.0a93
- Merged pull requests
- 23
Documented changes
24 typed entries
Verified contributors
3 verified contributors · 53 credits
Attribution coverage
attribution complete; history inventory partial.
Install
Scope
Guard v3.60.0a98 is a preview release published 2026-11-15. Upstream documents: Guard 3.60.0a98 is an opt-in prerelease cut from 2dadff4. Stable installations remain on the stable channel. 23 commits • 23 merged pull requests • 1 contributor since Guard 3.60.0a97. Its comparison base is alpha/v3.60.0a93. It includes 53 verified contribution deliveries with public evidence links.
Changes
Added
6- guardPromote a harness claim only from a matching live evidence receipt (#7805) Evidence for this change
harness_claim_promotion.rs(inguard-runtime, exposed through theharness_claim_promotionruntime-support op) decides whether one evidence receipt (hol-guard.harness-claim-evidence.v1) may raise one row's…- Receipts that report a unit test, fixture, replay or probe are always refused. A live block claim also needs a native deny returned before the action ran, plus a benign allow on the same event.
- Receipts are not authenticated yet. Their source, inference, verifier and witness fields are self-reported, so the check refuses an inconsistent or honestly labelled synthetic receipt but cannot detect a forged one.…
- guardShow where Claude Code hooks go before install writes them (#7792) Evidence for this change
- gauntletGrade each run against safety, false-pause and latency release budgets (#7804) Evidence for this change
ci/gauntlet/release_budgets.pygrades a run and renders the summary rows. Each row iswithin,overorunmeasured. A run with no benign case or noPreToolUsetiming reportsunmeasured, neverwithin.runner.pywrites the section intosummary.jsonandsummary.md.verify.pyrecomputes the budgets from the case evidence and rejects a summary whose claimed budgets differ.
- guardPublish Codex file writes as their own protection rows (#7798) Evidence for this change
- A capability row may now carry a
toolslist. One event may be split into several rows when every row names its tools and no tool appears in two rows; anything else is still "declared twice". - Codex
PreToolUsebecomes three rows:Bash/Read/mcp__*,apply_patch, andWrite/Edit/MultiEdit. All stayconfigured: no live run on an exact Codex version is on record, so nothing is promoted. - The file-write rows name their blind spots: edits applied without an
apply_patchcall are not visible,PostToolUsedoes not match these tools so the written result is not observed, and no live Codex run on record…
- A capability row may now carry a
- guardPublish harness protection claims from one checked contract (#7785) Evidence for this change
- guardWarm the daemon and resident after install so Codex and Cursor start warm (#7783) Evidence for this change
- After
hol-guard installsucceeds, the CLI reserves one detached daemon ensure through the native daemon manager. This is the same reservation a hook makes when it finds no daemon. A dry run starts nothing. If the… - When the production daemon starts, it now launches the detached
resident-prewarmlane for its Guard home, after it has warmed its hook worker. This is the lane Claude's SessionStart already uses, so every harness…
- After
Fixed
12- guardPublish the Cursor CLI, cloud agent and terminal as their own unsupported rows (#7803) Evidence for this change
- Adds three Cursor rows (
cli,cloud-agent,terminal) with transportnoneand stateunsupported. The CLI row claims only the launch check. - Regenerates
docs/guard/generated/harness-claims.v1.jsonanddocs/guard/harness-claims.mdfrom the contract. - Corrects
docs/guard/cursor-local-cloud-contract.md. It said the bridge fails open when the runtime is unavailable. The bridge actually answersdenywith a message naming the failure forbeforeShellExecution…
- Adds three Cursor rows (
- guardLet mkdir -p create a nested path below a new temporary directory (#7810) Evidence for this change
- guardKeep the review for heredoc-fed Python that reaches past the workspace (#7755) Evidence for this change
- It imports a module that observes or controls other processes, the clipboard, the screen or the input devices, such as
psutil,pyperclip,PIL.ImageGrab,pynput,pyautogui,mssorctypes. Only real import… - It signals another process:
os.kill,os.killpgorsignal.pthread_kill. This includes aliased modules (import os as proc),from os import kill, parenthesized multi-line imports and star imports. - It runs code built at run time, which the scan cannot read:
eval,exec,compileor__import__, whether called bare or throughbuiltins, orimportlib.import_module.
- It imports a module that observes or controls other processes, the clipboard, the screen or the input devices, such as
- guardLet fd list hidden and ignored names from a root find may list (#7807) Evidence for this change
- guardRun a Homebrew program by its full path without review, as its bare name runs (#7802) Evidence for this change
- cigarAsk Oh My Pi to skip the todo list on small fixes (#7806) Evidence for this change
- guardRead a loop body's binding builtins from shell words, not quoted text (#7799) Evidence for this change
- guardLet grep read a file pattern outside the repository, as cat does (#7794) Evidence for this change
- cigarStop Codex notes asking for held commands and extra reads (#7791) Evidence for this change
- guardRead saved gh results back with jq over several files (#7797) Evidence for this change
- guardList a version manager's installed runtime bin as metadata (#7790) Evidence for this change
- guardLet diff compare a file against /dev/null (#7788) Evidence for this change
Other changes
6- Guard 3.60.0a98 is an opt-in prerelease cut from
2dadff4. Stable installations remain on the stable channel. 23 commits • 23 merged pull requests • 1 contributor since Guard 3.60.0a97. Evidence for this change - guardKeep every antivirus claim next to what Guard does not cover (#7789) Evidence for this change
- guardProve a native approval binds to its whole request tuple (#7808) Evidence for this change
- guardAdd a safe-read corpus of routine git, script and Guard status actions (#7795) Evidence for this change
- gauntletAccept the failing answer of two reads whose honest result is an error (#7796) Evidence for this change
- cigarAdd a rig report for requests and Guard holds per step kind (#7800) Evidence for this change
- Merged pull request #7808: test(guard): prove a native approval binds to its whole request tuple (#7808)
- Merged pull request #7798: feat(guard): publish Codex file writes as their own protection rows (#7798)
- Merged pull request #7802: fix(guard): run a Homebrew program by its full path without review, as its bare name runs
- Merged pull request #7807: fix(guard): let fd list hidden and ignored names from a root find may list
- Merged pull request #7755: fix(guard): keep the review for heredoc-fed Python that reaches past the workspace
- Merged pull request #7756: fix(guard): let du size a hidden home cache directory the way ls lists it (#7756)
- Merged pull request #7767: fix(ci): use organization token for Release Please (#7767)
- Merged pull request #7752: fix(guard): model Oh My Pi's eval sh() helper so a secret copy through it is blocked (#7752)
- Merged pull request #7768: fix(guard): report a review left by a spent Git probe budget as a timeout (#7768)
- Merged pull request #7759: fix(guard): let rg search past a re-included hidden fixture it could search by name (#7759)
- Merged pull request #7758: fix(guard): show reapproval and containment floors in command explain (#7758)
- Merged pull request #7789: docs(guard): keep every antivirus claim next to what Guard does not cover
- Merged pull request #7804: feat(gauntlet): grade each run against safety, false-pause and latency release budgets
- Merged pull request #7792: feat(guard): show where Claude Code hooks go before install writes them
- Merged pull request #7805: feat(guard): promote a harness claim only from a matching live evidence receipt
- Merged pull request #7764: feat(guard): show per-event protection proof for each app (#7764)
- Merged pull request #7771: docs: recommend Python 3.11+ for pipx installation (#7771)
- Merged pull request #7810: fix(guard): let mkdir -p create a nested path below a new temporary directory
- Merged pull request #7762: fix(guard): let find list the links in a hidden home tool directory (#7762)
- Merged pull request #7803: fix(guard): publish the Cursor CLI, cloud agent and terminal as their own unsupported rows
- Merged pull request #7773: test(gauntlet): read a padded Oh My Pi edit header the way Guard and Oh My Pi do (#7773)
- Merged pull request #7772: fix(guard): let a time zone name in front of date run without review (#7772)
- Merged pull request #7776: fix(guard): let a file test take a project glob, as a loop guard does (#7776)
- Merged pull request #7763: docs(readme): point the pipx link at the current install page (#7763)
- Merged pull request #7757: fix(guard): never report a cold or review-tier native answer as no match in command test (#7757)
- Merged pull request #7750: feat: add Swarm Alpha workspace with CIGAR context handoff (#7750)
- Merged pull request #7777: test(guard): prove no pre-tool hook is allowed without a native decision (#7777)
- Merged pull request #7775: test(guard): prove concurrent callers share one resident start attempt (#7775)
- Merged pull request #7774: fix(guard): pass a compound when the user allowed one step and every other step passes alone (#7774)
- Merged pull request #7770: feat(guard): define one native readiness state for every runtime reason code (#7770)
- Merged pull request #7778: fix(guard): decide a loop or list piped into text filters by its list (#7778)
- Merged pull request #7780: fix(guard): judge a two-sided listing glob by the names it matches (#7780)
- Merged pull request #7753: feat(cigar): estimate the tokens CIGAR saved each week (#7753)
- Merged pull request #7754: chore(gauntlet): qualify against Oh My Pi 18.20.0
- Merged pull request #7786: fix(guard): unroll a for loop over folders spelled from the home directory (#7786)
- Merged pull request #7781: fix(guard): let a name glob narrow Grok searches and widen the grep include walk (#7781)
- Merged pull request #7779: feat(guard): count how long each resident cold start takes to answer (#7779)
- Merged pull request #7761: fix(adapters): find OpenCode in its installer directory under any PATH
- Merged pull request #7766: docs(guard): document the Claude Code settings Guard owns and how removal restores them (#7766)
- Merged pull request #7784: fix(guard): report a failed native evaluation as failed, as the readiness contract declares (#7784)
- Merged pull request #7787: fix(guard): explain a named native block as that block, and wait for a warming runtime (#7787)
- Merged pull request #7783: feat(guard): warm the daemon and resident after install so Codex and Cursor start warm (#7783)
- Merged pull request #7797: fix(guard): read saved gh results back with jq over several files (#7797)
- Merged pull request #7790: fix(guard): list a version manager's installed runtime bin as metadata (#7790)
- Merged pull request #7796: test(gauntlet): accept the failing answer of two reads whose honest result is an error (#7796)
- Merged pull request #7795: test(guard): add a safe-read corpus of routine git, script and Guard status actions (#7795)
- Merged pull request #7785: feat(guard): publish harness protection claims from one checked contract (#7785)
- Merged pull request #7800: chore(cigar): add a rig report for requests and Guard holds per step kind (#7800)
- Merged pull request #7799: fix(guard): read a loop body's binding builtins from shell words, not quoted text (#7799)
- Merged pull request #7794: fix(guard): let grep read a file pattern outside the repository, as cat does (#7794)
- Merged pull request #7791: fix(cigar): stop Codex notes asking for held commands and extra reads (#7791)
- Merged pull request #7806: fix(cigar): ask Oh My Pi to skip the todo list on small fixes (#7806)
- Merged pull request #7788: fix(guard): let diff compare a file against /dev/null (#7788)
Upgrade and compatibility
None documented.
Compare with the previous release
Predecessor on the same channel: alpha/v3.60.0a93
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.