Skip to content

Releases

NockGuard v0.12.0

Choose a tag to compare

@nock-fleet nock-fleet released this 04 Nov 20:07
176f2fc

Changed

  • The Live Wall's empty view shows installed commands (nockguard wall --demo
    and nockguard proxy --upstream <command> --agent <name>) instead of a
    source-checkout go run, names the watched trail, and fills in the
    --agent the Wall was started with. The proxy command is always paired
    with nockguard wall --agent <name>, because a zero-config proxy writes the
    agent's own trail rather than the shared one. A filter that hides every row
    now shows "No rows match these filters" until a row matches or the filters
    clear.
  • When its Guard trail file does not exist yet, the Live Wall prints a startup
    warning naming the path, /context reports trailExists: false, and the
    empty view reads "No trail file at yet" instead of looking like a
    healthy feed with no decisions.

Fixed

  • A decision that reaches the Live Wall before /context loads no longer
    stops the page from filling in its export scope and other context fields.

Documentation

  • Add examples/github-mcp-claude-code/: a copyable Claude Code setup that
    runs the GitHub MCP server under NockGuard and denies create_repository,
    fork_repository and delete_repository, with a policy test and a signed
    trail checked by nockguard verify.

NockGuard v0.11.1

Choose a tag to compare

@miraanocktech miraanocktech released this 30 Oct 15:36
35e47ab

v0.11.1 makes the Live Wall easier to search. The text filter now matches the decision reason as well as the agent and tool, so typing a rule name, a spend cap or a NockLock event type finds every row where it fired. Upgrade by downloading the release archive or running brew upgrade nockguard.

Changed

  • The Live Wall text filter matches the decision reason as well as the agent and tool. /pulse?q= and /export?q= (CSV and JSON) use the same match.
  • The PROOF export's text filter still matches agent and tool only. Matching the reason there needs a new export schema version so older verifiers fail closed on it.

Building from source still requires Go 1.27.3 or later.

NockGuard v0.11.0

Choose a tag to compare

@miraanocktech miraanocktech released this 21 Oct 19:02
9a82b20

v0.11.0 is a security release. NockGuard now requires Go 1.27.3 or later to
build: GO-2026-6809 in crypto/x509 was reachable through the Wall server in
the published v0.10.1 binaries, which were built with an affected Go release.
Upgrade by downloading the v0.11.0 release archive or running
brew upgrade nockguard. This release also adds opt-in desktop notifications
to the Live Wall and skips the CI test suite on docs-only PRs.

Security

  • Requires Go 1.27.3 or later to build. GO-2026-6809 in crypto/x509,
    reached through the Wall server's http.Server.Serve, affects Go before
    1.26.10 and Go 1.27.0 to 1.27.2. go.mod now requires Go 1.27.3, so any
    older toolchain, including the patched 1.26.10, either downloads Go 1.27.3
    automatically or refuses to build.

Added

  • The Live Wall has an opt-in NOTIFY toggle for desktop notifications. While
    the tab is hidden, a new block or critical row raises one notification with
    the agent, tool name (cut at the first : or space, at most 64 characters)
    and decision, at most one per 10 seconds with the rest collapsed into
    "+N more"; an audit-chain break notifies once, and again if it returns after
    an intact check. Replayed
    history (the /events stream now marks the end of its replay with a
    replayed event) and demo rows do not notify. The choice is remembered in
    the browser.

Changed

  • CI skips the test suite on PRs that change only Markdown or docs/; it
    still runs the tests that read repo Markdown, and build-test and
    macos-test still report. Contributor docs now ask for focused tests plus
    lint before pushing, with the full suite run once in CI. A rename or copy
    skips the suite only when both its old and new paths are docs.

v0.10.1

Choose a tag to compare

@kkwills13 kkwills13 released this 17 Oct 23:17
1203e75

v0.10.1 rejects malformed CLI arguments before setup and removes redundant
approval audit bookkeeping. Approval gates and historical trail verification
are unchanged.

Upgrade notes

  • proxy, mcp-http, mcp-listen, egress-proxy, and init now reject
    unknown flags, missing flag values, and unexpected positional arguments.
    Correct invocations that previously relied on ignored arguments before upgrading.
  • Approved native ask and fail_mode: ask calls no longer add the synthetic
    state-write audit row. approval-granted remains; scripts that count rows
    will see one fewer row per approved call. Existing signed state-write rows
    still verify and display unchanged.

Changed

  • Use standard Go flag parsing for proxy, mcp-http, mcp-listen,
    egress-proxy, and init; reject malformed flags before startup or file writes.
  • Reuse one named-agent/default policy lookup and remove unused internal helpers.
  • Stop emitting redundant synthetic state-write rows on approved calls;
    approval gates and verification of historical signed trails are unchanged.
  • Consolidate contributor guidance in AGENTS.md, check its file references
    in CI, and require a whole-batch cleanup pass before release preparation.

NockGuard v0.10.0

Choose a tag to compare

@nock-fleet nock-fleet released this 17 Oct 13:06
347d85f

v0.10.0 extends the opt-in paired stdio audit (audit.action_pairing: true). Signed action rows now record a digest of each tool definition the server advertised. Operators can pin reviewed definitions with tool_pins and --upstream-id; a pinned tool whose definition is missing, unhashable or changed is hidden from tools/list and its calls are blocked. Each paired proxy run writes signed open, heartbeat and close rows, and verify --completeness reports a per-run assessment next to the integrity verdict. Paired audit now needs a signing key. This release also fixes concurrent Telegram approval routing, the bracketed IPv6 loopback Host on mcp-listen, oversized method and tool names, and a malformed approval_actor latching the required audit writer.

Upgrade notes

  • audit.action_pairing: true now needs a signed audit writer (an Ed25519 or HMAC signing key). Without one, nockguard proxy exits with audit.action_pairing requires a signed audit writer for run lifecycle. v0.9.0 ran pairing unsigned. Policies without action_pairing are not affected.
  • Paired trails now contain run rows (open, a heartbeat every 30 seconds, close) and, on call rows, tool_pin_status with tool_hash_version and tool_definition_hash when a definition was observed. Scripts that count rows or match on record_type will see them. These rows use the v2 format v0.9.0 already validates, so a v0.9.0 verify still checks their integrity; --completeness needs v0.10.0.
  • With pairing on, when the upstream exits or the proxy gets SIGINT, SIGTERM, SIGHUP or SIGQUIT, the proxy stops accepting input, waits a bounded time for accepted calls, records outcome_unknown for calls still in flight and then writes the run close row. With pairing off, shutdown is unchanged.
  • tool_pins and strict_tool_pins are new agent policy keys. A policy that uses them does not load on v0.9.0, so roll back with a policy that omits them.
  • --upstream-id is required only when the agent's policy sets tool_pins or strict_tool_pins. The ID must be 1 to 128 bytes with no whitespace or control characters, and when pins are listed it must name an upstream under tool_pins; the same rule applies to tool_pins keys when the policy loads. A pin policy also needs audit.action_pairing: true (the policy fails to load without it) and a signing key. --audit-best-effort is refused with pins, and mcp-listen, mcp-http and mcp-gateway refuse to start with a pin policy.
  • verify --completeness keeps the integrity exit status: BROKEN, INCOMPLETE or UNASSESSABLE do not change the exit code. Read completeness[].verdict from --json. The completeness array and the text COMPLETENESS: lines appear only when the integrity verdict is PROTECTED; on any other verdict, or a key or read error, there is no completeness output, so check verdict first. It checks a single trail and cannot be combined with --all.
  • MCP requests whose method or tool name is longer than 256 bytes are now refused with JSON-RPC -32600 and recorded as method-deny.

Added

  • Tool-definition digests for opt-in paired stdio audit. Each tool in a complete client tools/list listing gets a SHA-256 digest of its RFC 8785 canonical JSON (jcs-rfc8785-v1), kept in a session tool catalog. Signed v2 call rows record the observed hash and a tool_pin_status (unpinned, unobserved or unhashable). The digest identifies the definition the server advertised, not how the server behaves. Only a complete single-page listing attaches a hash to later calls; calls after a paginated listing or after notifications/tools/list_changed stay unobserved. No raw definition or schema is written to the trail. If the catalog cannot be built, tools/list still returns the normal filtered listing.
  • Operator tool pins for the stdio proxy. tool_pins maps a stable upstream ID, passed with --upstream-id, and an exact tool name to a reviewed jcs-rfc8785-v1 SHA-256 digest. A pinned tool whose definition is missing, unhashable or changed is hidden from tools/list and blocked on tools/call, even without strict mode. strict_tool_pins: true also blocks allowed tools that have no pin. Signed rows record the expected tool_pin_hash next to the observed hash, with matched, mismatch, unobserved, unhashable or unpinned status. Re-listing and call approval never change a pin; only a policy edit does. After notifications/tools/list_changed, re-list from the first page or reconnect. Pinned tools behind a paginated listing stay blocked. With pins, a tools/list request that cannot be matched to a live listing (such as an unknown continuation cursor) or whose upstream page is invalid or cannot join the catalog build is refused with JSON-RPC -32603 and recorded as method-deny with reason tool_catalog_refresh_required.
  • Signed run lifecycle rows for opt-in paired stdio audit. Each run has a fresh random run nonce and writes a durable open row before reading input, a heartbeat every 30 seconds and, after a bounded shutdown drain, a close row that commits to the run's preceding row count and signature. A write or sync failure prevents a clean close.
  • verify --completeness adds a per-run assessment to a single trail's integrity verdict. LIMITED is the best result: the signed, checkpointed observation stream recorded for that run is internally complete. It does not prove that every attempted call was recorded or that a remote side effect completed. A recent open run is IN_PROGRESS; an open run with no heartbeat for 90 seconds, or an action with no terminal observation, is INCOMPLETE; future-dated heartbeats and mixed legacy and v2 trails are UNASSESSABLE; legacy-only trails are UNVERIFIED; invalid run structure is BROKEN. Completeness is reported only when integrity verification passes (PROTECTED); with any other integrity result (TAMPERED, NO_ROWS, UNANCHORED) or a key or read error, there is no completeness output. Completeness is separate from integrity and does not change the exit code.

Changed

  • The proxy waits at most one second for the audit writer to close on exit. If a write is still in progress, it says so and points to verify --completeness.

Fixed

  • Route Telegram approval callbacks to the matching held request when calls wait concurrently.
  • mcp-listen accepts the bracketed IPv6 loopback Host [::1] without a port.
  • Reject MCP method and tool names exceeding 256 bytes before forwarding, with bounded audit diagnostics that preserve trail verification.
  • A required audit write rejected for a malformed approval_actor no longer latches the writer or creates the .audit-failing marker; nothing is written, and later calls proceed. Real storage failures still latch.

NockGuard v0.9.0

Choose a tag to compare

@miraanocktech miraanocktech released this 16 Oct 19:39
ec53bc2

v0.9.0 tightens Telegram approvals: only listed users in the configured chat can decide held calls, callbacks use random nonces, rejected taps get a reply without stalling, and polling respects the hold deadline. The MCP listener validates loopback Host headers, rejects any Origin header and requires application/json on POST requests; remote egress proxy binds now need explicit opt-in. Non-tool MCP methods get distinct audit decisions and optional denials, the HTTP bridge forwards canonical messages, the upstream child no longer inherits the audit-forwarder key, and policy proposals verify their audit input.

Install on macOS: brew install nocktechnologies/tap/nockguard (installs nockguard and nockguard-wall). Existing users: brew upgrade nocktechnologies/tap/nockguard. Linux and macOS archives with SHA256SUMS are attached below.

Upgrade notes

  • egress-proxy now refuses a non-loopback listen address unless --allow-remote is passed. Existing remote binds must add this flag to start; remote binds print a warning.
  • Telegram approval now needs NOCKGUARD_APPROVER_IDS, a comma-separated list of numeric Telegram user IDs. NOCKGUARD_APPROVAL_CHAT_ID must be a numeric chat ID; a @channel name no longer works. If either is missing or invalid, the Telegram approver does not start and every ask and require_approval call is denied. A v0.8.0 setup with only the bot token and chat ID must add the approver IDs.
  • mcp-listen returns 415 for a POST unless it sends one Content-Type header with media type application/json (parameters such as charset are allowed), and the local listener returns 403 for any request with an Origin header, including null. Methods other than POST get 405. Native MCP clients omit Origin; browser-based or custom clients may need changes. The same Content-Type rule applies to requests that mcp-gateway forwards.
  • policy propose now verifies the audit trail before it proposes anything. It needs the agent's Ed25519 public key (the same environment variable or key file verify --agent uses) and a non-empty trail that is fully covered by its signed checkpoint. Unsigned, HMAC-signed or partly checkpointed trails, which v0.8.0 read as they were, now fail with an error.
  • Audit trails now contain method-allow and method-deny rows for non-tool MCP methods. Scripts that count audit rows or match on decision values will see these new values.

Changed

  • Clarify that verify --session session IDs come from the launching process's environment and are not authenticated.
  • egress-proxy requires a loopback listen address unless --allow-remote is passed; remote binds print a warning.

Fixed

  • Telegram approval polling respects the hold deadline and preserves in-time approvals when callback replies are slow.
  • Telegram approvals require listed user IDs and the configured chat, and use random callback nonces.
  • policy propose verifies its audit input and lists tool names containing glob characters as comments instead of rules.
  • mcp-listen validates loopback Host headers, rejects any Origin header and requires application/json POST requests before forwarding.
  • Non-tool MCP methods now record distinct method-allow / method-deny audit decisions, excluded from tool proposals and tool decision counts. Method rows are written immediately; denied requests return JSON-RPC -32601. The optional per-agent deny_methods list refuses exact method names before forwarding; other methods continue to pass through by default.
  • The HTTP MCP bridge forwards canonical messages so forwarded tool calls and their audit records agree, and returns an invalid-request error for rejected requests with an ID instead of leaving clients waiting.
  • Stdio MCP rejection messages use "ambiguous message key" for conflicting method or params aliases.
  • The upstream MCP child no longer inherits the configured audit-forwarder API key.
  • The policy-lint W005 check now warns when Telegram approval lacks a valid NOCKGUARD_APPROVER_IDS list or a numeric chat ID, matching what the approver needs to start.

NockGuard v0.8.0

Choose a tag to compare

@miraanocktech miraanocktech released this 15 Oct 19:32
a022531

v0.8.0 fixes policy patterns that use ? or character classes, which loaded without error but matched only as literal text. The Wall now checks the Host of every request and serves only on loopback unless you opt in. Local approvals record the approver's UID in the signed trail, and an opt-in audit mode pairs each tool call with its observed outcome.

Install on macOS: brew install nocktechnologies/tap/nockguard (installs nockguard and nockguard-wall). Existing users: brew upgrade nocktechnologies/tap/nockguard. Linux and macOS archives with SHA256SUMS are attached below.

Upgrade notes

  • Policy rules that contain ? or [ now act as glob patterns in deny, ask, require_approval, allow, shadow and inject rules. Before this release they loaded as globs but matched as literal text. In a pattern that contains *, ? or [, a backslash escapes the next character. Review any rule that uses these characters for a literal tool name.
  • The Wall refuses a non-loopback --addr unless you pass --allow-remote. Remote clients also need --allow-host.

Security

  • Policy patterns with ? and character classes now match as globs. A deny rule such as exec? loaded without error but did not deny exec1. Validation, evaluation and inject conflict checks now share one glob test. * and ? do not match /.
  • The Wall validates the Host header on every route, with one optional extra host from --allow-host. Event and export routes also check the browser Origin and Sec-Fetch-Site headers. A remote bind needs --allow-remote and prints a warning. A named port is rejected at startup.

Added

  • Local approvals record a signed approval_actor (local:uid:<n>) taken from the kernel peer-UID check. It identifies the UID of the approving process, not a person. Ordinary tool-call rows and non-local approvals do not carry it. Local decision JSON with unknown identity fields is rejected before the held call is consumed.
  • Opt-in action pairing for stdio (audit.action_pairing: true). The decision, the dispatch and the observed result of each tools/call share one action ID. A matching response is recorded as response_observed; a timeout, cancellation, disconnect or shutdown is recorded as outcome_unknown. No request IDs, arguments or response bodies are written. Pairing needs required audit writes and cannot be combined with --audit-best-effort. Older binaries cannot verify trails that contain these rows, so use a dedicated audit path. See docs/how-it-works/audit.md.

Fixed

  • Evidence packs parse audit entries and verify their chain and checkpoint from the same snapshot, so contents and verdict agree while the file is being replaced.

Changed

  • The Wall decision filter lists every decision the audit log writes. It adds tiles for approvals granted, dispatched and would-deny (observe), with matching /pulse counts and an "other" bucket for unknown values. --demo shows each tile.
  • The public repository no longer carries internal launchers, tool names, local paths or host examples. The quickstart demo uses a self-contained local MCP stub.

Documentation

  • The README quickstart uses a physical fixture path, absolute executable paths and an explicit client PATH.
  • The CLI reference and --help match current behavior, including --audit-best-effort, the optional egress policy and when --agent may be omitted.
  • Warden policy suggestions cite a primary source for each proposed rule, or say that none was found.
  • New design note for the additive action and lifecycle audit contract.

NockGuard v0.7.1

Choose a tag to compare

@miraanocktech miraanocktech released this 14 Oct 04:50
4e6baf7

NockGuard v0.7.1 fixes a gateway race on the first request after initialize, keeps idle timing accurate after a slow initialize, and makes release binaries report a clean source tree.

Install on macOS: brew install nocktechnologies/tap/nockguard (installs nockguard and nockguard-wall). Existing users: brew upgrade nocktechnologies/tap/nockguard. Linux and macOS archives with SHA256SUMS are attached below.

Fixed

  • mcp-gateway releases an SSE initialize session before it delivers the matching result, so an immediate follow-up no longer gets a spurious 429 gateway busy.
  • mcp-gateway does the same for a validated JSON initialize session.
  • mcp-gateway refreshes the session idle timeout after a JSON or SSE initialize result finishes writing, without overwriting the state of a follow-up already in progress. A slow initialize write no longer uses up part of the idle timeout.
  • Release builds ignore the local dist/ directory, so release binaries no longer report a modified source tree (+dirty, vcs.modified=true).
  • The vuln-scan helper (.claude/commands/vuln-scan.md and the Warden template copy) shows the verify --all command again and rates a [SKIP] line (invalid agent name) as HIGH.

Documentation

  • Session handlers behind the hosted gateway must honor request cancellation. A handler that ignores it is outside the gateway's guarantee. A new test runs the production listener with required auditing, blocks another session's signed write, and shows the initialize result still arrives within two seconds.
  • The README shows the Live Wall over a real signed trail, CONTRIBUTING lists the checks CI runs (gofmt, go test -race, the Wall browser test and the quickstart acceptance), and the approvals page links to the README policy rules section.

NockGuard v0.7.0: Ask tools stay visible, Wall counts records, stricter verify

Choose a tag to compare

@miraanocktech miraanocktech released this 14 Oct 01:21
8a7f241

NockGuard v0.7.0 changes what the proxy shows for ask tools, makes the Wall count audit records instead of calls, and tightens how verification reports a trail. It also fixes two proxy bugs and builds with a patched Go.

Upgrade notes: verify exit codes changed. nockguard verify --agent and verify --all now exit 1 for an empty trail (NO_ROWS) or a trail that runs past its signed checkpoint (UNANCHORED). v0.6.0 exited 0 for both. If a script treats a non-zero verify as a failure, it may now fail where it passed on v0.6.0. That is intended: v0.6.0 could report a trail as intact when the signed checkpoint did not cover all of it. The Wall's numbers will also be lower and labeled differently, as described below.

Install on macOS: brew upgrade nocktechnologies/tap/nockguard (installs nockguard and nockguard-wall). Linux and macOS archives with SHA256SUMS are attached below.

Changed

  • tools/list now keeps tools with an Ask verdict visible. Their calls are still held for local or Telegram approval. Denied tools stay hidden. An approved call records its final allow audit row before it is dispatched.
  • The Wall counts audit records, not calls, and says so: the header reads "records in view" and "threat records". Hidden tools from tools/list now show as a separate "tools hidden" count. They no longer count as rejected records, threats or part of the rejected share, so one rejected call no longer reads as 13 threats caught.
  • The Wall no longer scrolls sideways on narrow screens (390 px). Filters and tiles wrap, feed rows stack, and the evidence scope notes sit behind an "Evidence details" toggle on narrow screens. They stay open on wide ones.

Fixed

  • verify and verify --all report an empty signed trail as NO_ROWS and a trail that runs past its signed checkpoint as UNANCHORED. Only a non-empty, fully checkpointed trail reports PROTECTED. Evidence packs follow the same rule, so the CLI, the Wall and the packs agree.
  • verify --agent now checks the --audit file you pass. Before, it quietly checked the agent's default trail.
  • nockguard proxy now exits promptly when the upstream dies. It starts a one-second shutdown deadline, even if the client holds stdin open or stops reading stdout. It sends JSON-RPC -32603 errors for in-flight requests when the client can receive them, stops the upstream process group, and exits nonzero.
  • Fixed a race in the stdio proxy between a request and its response. The proxy now registers the response correlation before writing a request upstream, and clears its pending state if the write fails.
  • Output the upstream wrote before it exited is still delivered while the client reads. Shutdown waits for the client to go idle for one second, up to a ten-second cap.
  • Release archives and CI build with Go 1.26.9, and source and release binaries are checked with govulncheck.

Documentation

  • Wall installation guidance is corrected, and source line references are replaced with file links.
  • Homebrew and Linux archive installation are documented, including the Live Wall. Linux install now verifies the archive against SHA256SUMS first.
  • The /policy-lint, /vuln-scan and /threat-model helper commands, the Warden CLAUDE.md and README, and the model-API egress template now match the engine: unknown keys fail the load, mode defaults to deny, the full agent key list, per-agent audit trails and keygen --agent, egress-proxy --enforce, and the SSRF guard.
  • The helper template checks now report their own failures. A failed check exits instead of reading as a pass, and severity comes from real exit codes. The /vuln-scan helper also reads the verify verdict line before it labels an exit 1, so an empty trail or one past its checkpoint is no longer reported as a missing key.

NockGuard v0.6.0: fail-closed audit, local approver, Wall in the release

Choose a tag to compare

@miraanocktech miraanocktech released this 13 Oct 03:05
4945590

NockGuard v0.6.0 refuses tool calls when it cannot write its signed audit record, adds a local approver for held calls, and ships the Wall in the release archives with NockLock events in the same stream.

Upgrade notes: this release has breaking changes. Read the Breaking section before upgrading. Anything that counts audit rows should expect the new dispatch row. nockguard init writes a new starter policy, and existing policy files are not touched.

Install on macOS: brew upgrade nocktechnologies/tap/nockguard (installs nockguard and nockguard-wall). Linux and macOS archives with SHA256SUMS are attached below.

Breaking

  • Local nockguard proxy and mcp-listen (and mcp-http) now refuse tool calls when a required audit write fails, whenever auditing is enabled. The failure latches: every later call is refused until the trail is fixed and reopened with a verified signing key. Pass --audit-best-effort to get the old forwarding back; startup prints a warning. status, doctor and the Wall show audit failing: calls refused while a failure is outstanding.
  • nockguard proxy and mcp-listen now write a dispatch audit row before they forward an allowed tools/call request, when auditing is on and --audit-best-effort is not set. Each such call has one more row than in 0.5.0. Denied calls, other methods and mcp-http write no dispatch row, and mcp-gateway already wrote one. Anything that counts rows or matches decisions should expect dispatch.
  • nockguard init writes a different starter policy. The agent is coder (was my-agent), it allows read_file and read_text_file and denies write_file, default stays mode: deny, and audit.enabled: true is on (it was commented out). The old ask rules and wildcard allows are gone. Run keygen --agent coder before the first proxy run so the audit trail is signed. Existing policy files are not touched, and init still refuses to overwrite one without --force.
  • The Wall now reads the agent's public key with the same resolver as nockguard verify --agent: the NOCKGUARD_AGENT_<NAME>_ED25519_PUB variable first, then ~/.nockguard/keys/<name>.pub. A Wall that relied on a key being absent will now verify against the file. /verify reports PROTECTED only for a non-empty trail that its signed checkpoint fully covers; empty, unconfigured, unavailable and unanchored trails are shown as such.

Added

  • Local approver for ask verdicts, with no network: set NOCKGUARD_APPROVER=local and decide held calls with nockguard approvals list|approve|deny (prune removes dead sockets left by crashed proxies). Held calls wait on a 0600 unix socket in a 0700 approvals directory, one <pid>-<random>.sock per proxy, removed on exit, and are audited as approval-granted / approval-denied with the approver local:<uid>. The listing shows id, agent, tool, reason and age, never arguments. The approver does not start, and ask fails closed, if the directory or socket permissions, ownership or type are wrong. A same-uid agent can still approve its own calls; see the README trust boundary.
  • Live Wall shows NockLock and NockGuard in one stream. nockguard-wall --lock-db <events.db> reads a NockLock log read-only (file, network and secret fence events, blocked and passed), labeled LOCK / GUARD and colored by outcome, decision only. --lock-pub-env names the NockLock public key (default NOCKLOCK_AUDIT_ED25519_PUB). --demo cannot be combined with --lock-db.
  • Per-session signed-proof badge on the Wall (GET /sessions): the same verdict as nockguard verify --session (PROTECTED / TAMPERED / UNSIGNED / UNVERIFIABLE / NO_ROWS / UNANCHORED) with both key fingerprints. A missing key is UNVERIFIABLE, never green. A Lock log over 100,000 events is UNVERIFIABLE, too large. An unreadable Lock row shows as UNPARSEABLE and makes its session UNVERIFIABLE; the rest of the batch still shows.
  • nockguard wall subcommand. It starts nockguard-wall from beside the CLI or from PATH and forwards flags and signals. nockguard-wall now ships in the Linux and macOS release archives, and a standalone nockguard-wall install keeps working.
  • nockguard status --agent <name> and doctor report a required audit write failure; status accepts --audit <path> for custom trail paths.
  • A Linux CI check runs the README quickstart end to end (init, keygen, proxy, verify) against a local MCP stub, with a successful read, a blocked write and signed allow and deny rows.

Changed

  • /export CSV and JSON gain a trailing source column / field (GUARD or LOCK). With --lock-db, each source keeps its own 500-row cap, and the X-NockGuard-Lock-Verification response header is ok, unsigned (no Guard key, so nothing is verified) or unavailable (no Lock snapshot, so no Lock rows). The PROOF export remains NockGuard rows only.
  • The README quickstart uses the coder agent and a concrete demo path, matching nockguard init.
  • Documentation claims now match shipped behavior, and a repository map and the 1.0 contract are added under docs/.

Fixed

  • macOS: the local approver socket path now fits the 104 byte sun_path limit. When ~/.nockguard/approvals would be too long, it falls back to a private per-user directory under /tmp.
  • macOS 26.5: two nockguard processes starting at once on a fresh machine no longer fail with "opening key lock ... no such file or directory".

Known limits

  • With stdio, a response that arrives ahead of an earlier pending call can be released before its deferred decision row is written. The dispatch row is durable first. If that later write fails, the latch refuses every later call and status reports the failure.
  • The failure marker is per trail, not per process or per agent. Every proxy writing the same trail sees it.
  • An unsigned trail has no verified reopen, so nothing clears its failure marker short of choosing --audit-best-effort. Sign the trail to get the repair path.