Skip to main content
Glama

sysknife_audit_verify

Verify the integrity of the audit log by validating its Ed25519-signed hash chain. Returns status (intact/broken/cannot_verify), rows checked, and the first offending row if tampering is detected.

Instructions

Verify the tamper-evident Ed25519-signed hash chain over the audit log. Returns status (intact/broken/cannot_verify), rows_checked, and, on broken, the first offending row. Read-only and safe to call without prior sysknife_plan.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
actualNoThe hex Ed25519 signature actually stored for the first broken row.
reasonNoHuman-readable explanation. Only set when `status == "cannot_verify"`.
statusYesOne of `"intact"`, `"broken"`, `"cannot_verify"`.
backendYesBackend label: a filesystem path for SQLite, the literal `"postgres"` for Postgres deployments.
expectedNoWhat verification expected for the first broken row (the literal `"valid ed25519 signature"`).
chain_statusYesThe transaction chain's own verdict: `"intact"`, `"broken"` or `"cannot_verify"`. Reported separately because `status` is the worst of three checks, so a broken *approval-event* chain sets `status` to `"broken"` while this stays `"intact"`. Read this one, not `status`, to decide whether the attribution counts below are findings or claims: without it an agent had no way to recover the chain verdict and would discard sound attribution.
rows_checkedYesNumber of audit rows the verifier successfully checked. `0` for `cannot_verify` outcomes that fail before the first row is read.
rows_censusedNoHow many rows were censused for attribution: every row read, whether or not it verified. `null` when the store could not be read at all, along with every count below, so a database nobody could open never reads as one where nothing was found. A readable but empty store reports `0`. When `chain_status` is not `"intact"` this can exceed `rows_checked`, and the difference is the part of the trail that was counted but not proven.
binding_statusYes`"consistent"` or `"missing_event"`: whether every event tip committed by a transaction row is still present in the event chain.
events_checkedYesNumber of approval events (grant / consume / revoke) checked in the second chain.
attributed_rowsNoHow many rows have a signed principal naming an account: a non-empty value under the `uid` or `token` scheme, which this build could read back as something the daemon itself could have written. Only a finding when `chain_status` is `"intact"`. Past a detected break the walk stopped checking, so those rows' principals are claims: some may be authentic, since deleting or reordering a row breaks the link while leaving later signatures valid, and this tool cannot say which.
rows_unattestedNoHow many rows have no principal any signature vouches for: the column is populated on an encoding that does not sign it, or holds a value this build cannot read back as one the daemon could have written, or the row declares an encoding this build does not know. This build writes none of those. The first two are out-of-band writes to investigate; the third means a newer SysKnife wrote the rows and the fix is to verify with a build at least that new.
first_broken_seqNoSequence number of the first row that broke the chain. Only set when `status == "broken"`.
unattributed_rowsNoHow many rows record that the daemon could not name the caller. `chain_status: "intact"` with a non-zero count here means the chain is sound and the attribution is not: report both, never the first alone. Since 0.4.0 this counts only rows whose `chain_version = 3` principal is signed as `none:unattributed`. 0.3.0 matched the column on any encoding, which meant an unsigned column could land here; such rows are now `rows_unattested`.
daemon_socket_caveatNoSet when `SYSKNIFE_SOCKET` names a daemon that may not live on this machine, because verification reads a local store while every other tool travels over that socket. `None` for the local-daemon case.
approval_events_statusYesResult of the approval-event chain walk: `"intact"`, `"broken"`, or `"cannot_verify"`. Reported separately from `status` so a clean authorisation trail can never paper over a tampered approval trail.
rows_naming_no_accountNoHow many rows name no account, for any reason. The complement of `attributed_rows` over `rows_censused`, provided so a reader does not have to add the three reasons and risk missing one.
rows_without_principalNoHow many rows carry no principal the signature covers, normally because they were signed before the column existed. Reported next to `unattributed_rows` because zero attribution failures over a pre-v3 database would otherwise read as full attribution. The two have different remedies: this one cannot be fixed, since backfilling a principal would rewrite the bytes the signature covers.
first_broken_transaction_idNoTransaction ID of the first broken row. Only set when `status == "broken"`.
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does well: it discloses read-only safety, the 'without prior plan' requirement, and the exact return values (status, rows_checked, first offending row). It does not cover potential edge cases like permissions or empty logs, but the core behavior is transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences deliver purpose, safety, return values, and a usage note without any waste. The structure is front-loaded with the action and resource, making it easy to parse quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a parameterless tool with an output schema, the description provides complete context: what it verifies, its read-only nature, and what it returns. The output schema covers the detailed return structure, so the description suffices.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the baseline is 4. There is nothing for the description to add beyond the empty schema, and the description appropriately avoids invented parameter details.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Verify') and a clear resource ('tamper-evident Ed25519-signed hash chain over the audit log'), which unambiguously distinguishes it from sibling tools like sysknife_execute and sysknife_plan. The mechanism and object are named precisely.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says it is 'Read-only and safe to call without prior sysknife_plan', giving direct usage context and a notable distinction from tools that may require a plan. It doesn't explicitly exclude any scenarios, but the verification purpose is clearly scoped.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/lacs-project/sysknife'

If you have feedback or need assistance with the MCP directory API, please join our Discord server