Skip to main content
Glama

verify_receipt

Read-only

Verify a CodeRifts signed chain-receipt you ALREADY HOLD: cryptographic authenticity (signature + key id), body binding, and — when lifecycle indices are available — whether it is currently valid authorization (not expired, superseded, or revoked) for a stated operation/target.

Use this when:

  • You already obtained a chain_receipt / receipt token from a prior preflight (or CI artifact) and are about to act (merge/deploy) under that receipt.

  • A contract-gate or policy requires offline/online proof that the receipt is authentic for this change before proceeding.

  • You must distinguish "signature ok" from "currently authorized" (stale or superseded receipts must not be treated as live approval).

Do not use when:

  • You do not have a receipt yet — call coderifts.preflight_change_set first.

  • You need a NEW decision for a changed base→head set — preflight again; verify_receipt does not re-diff specs.

  • The receipt you hold binds a different operation or target than the one you are about to perform — call coderifts.preflight_change_set with context.operation set to that operation (a merge receipt does not authorize a deploy); verify_receipt cannot re-scope or re-issue a decision.

  • You only need human-readable history of an old decision_id without a receipt token — use coderifts.get_decision_details.

  • The change set itself is unknown or incomplete — fix the change set and preflight; do not "verify" a placeholder.

Inputs: receipt token (required); target_id = decision_result.artifact_digest — required for an authorization verdict; omitted → target_not_stated. Optional intended context (operation, environment, fingerprint, audience, repository/branch/pull_request, base/head) and the body_hash-bound decision_result envelope. 30s clock-skew leeway on expiry. A 0s grace for declared destructive production operations is defined in the policy but is unreachable today: the intended-context schema has no destructive field, so nothing can declare one and the 30s leeway always applies. Returns { valid, status, currently_authorized (bool|null), reason, payload, authz_* }. Branch on currently_authorized; null = not evaluated.

When a decision envelope is also in hand (e.g. from a prior preflight), its control_envelope.next_agent_step (if present) is structured remediation guidance the agent MAY follow after a non-CONTINUE decision — still branch on execution_action; next_agent_step is suggestion, not permission.

Input Schema

NameRequiredDescriptionDefault
baseNoIntended base commit/ref SHA the receipt must match (signed-wins vs envelope.base)
headNoIntended head commit/ref SHA the receipt must match (signed-wins vs envelope.head)
tokenYesThe chain receipt token (base64url(body).base64url(signature))
branchNoIntended branch the receipt must bind (place binding; optional)
audienceNoIntended audience — must match the receipt
operationNoIntended operation the receipt must authorize (conventional: merge|deploy|tool_call|publish). Triggers authorization evaluation when non-empty; supply decision_result for full scope binding.
target_idNoREQUIRED to authorize under a held receipt. Set it to decision_result.artifact_digest — the digest of the artifact the receipt was issued for, which you already hold in the decision_result you are passing. The server does NOT derive it for you: it carries YOUR intended apply-site, and taking it from the envelope would compare that document against itself. Omit it and the answer is currently_authorized false with authz_reason target_not_stated and authz_status VERIFIED_TARGET_NOT_STATED — a missing input, distinct from target_mismatch, which means the receipt covers a different target.
repositoryNoIntended repository the receipt must bind (place binding; optional)
environmentNoIntended environment (e.g. production) — must match the receipt
fingerprintNoIntended change fingerprint — must equal the receipt fp
pull_requestNoIntended pull-request id the receipt must bind (place binding; optional)
decision_resultNoThe body_hash-bound decision envelope (carries operation/target/decision). Required for a meaningful AUTHORIZATION evaluation of scope; without it, intended context alone fails closed on authorization (currently_authorized false) while signature status remains independent. Full schema: https://coderifts.com/schemas/decision-result.v1.consumer.json.

Output Schema

NameRequiredDescriptionDefault
validYestrue iff status is VERIFIED_CURRENT or RETIRED_KEY_VALID_AT_ISSUE
reasonNo
statusYes
payloadNo
authz_noteNoPresent when no intended context supplied: status reflects signature+expiry only
authz_stateNoLifecycle state from isCurrentlyAuthorized when authorization is evaluated (optional; omitted when currently_authorized is null)
authz_reasonNoWhen currently_authorized=false: the deny reason (operation_mismatch, decision_not_allow, superseded, expired, target_mismatch, environment_mismatch, …)
authz_statusNoAuthorization-level status (VERIFIED_WRONG_ENVIRONMENT / VERIFIED_SUPERSEDED / VERIFIED_SCOPE_MISMATCH / …)
caller_valueNoCaller claim that differed from the signed envelope
signed_valueNoSigned envelope slot when signed-wins fail-closed (source_binding_mismatch)
authz_reasonsNoEvery violation found; the first is authz_reason. [] when authorized. Fix all of them before re-verifying.
binding_levelNoplace_and_content | content_only — forensic, not a second verdict
correlation_idNoRoute-owned trace id, set by the route itself rather than by correlation middleware; always a non-empty string on 200
currently_authorizedYesWhether the receipt currently authorizes the intended operation/target/fp (§106). null means authorization could not be evaluated (e.g. no intended context) — not unauthorized and not authorized.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedOutput schema / properties / status / enum
      Previous value: -[
      -  "VERIFIED_CURRENT",
      -  "VERIFIED_EXPIRED",
      -  "VERIFIED_WRONG_AUDIENCE",
      -  "VERIFIED_WRONG_ENVIRONMENT",
      -  "VERIFIED_SUPERSEDED",
      -  "VERIFIED_SCOPE_MISMATCH",
      -  "VERIFIED_UNBOUND_OPERATION",
      -  "VERIFIED_UNBOUND_TARGET",
      -  "VERIFIED_UNBOUND_REPOSITORY",
      -  "VERIFIED_UNBOUND_BRANCH",
      -  "VERIFIED_UNBOUND_PULL_REQUEST",
      -  "VERIFIED_TARGET_NOT_STATED",
      -  "UNKNOWN_KEY",
      -  "UNKNOWN_KEY_STATUS",
      -  "RETIRED_KEY_VALID_AT_ISSUE",
      -  "KEY_RETIRED_AFTER_SIGNING",
      -  "REVOKED_KEY",
      -  "REVOKED_KEY_UNDECIDABLE",
      -  "KEY_REVOKED",
      -  "REVOCATION_UNDECIDABLE",
      -  "AUTHORIZATION_UNDECIDABLE",
      -  "INVALID_SIGNATURE",
      -  "MALFORMED",
      -  "UNSUPPORTED_VERSION",
      -  "REGISTRY_UNREACHABLE"
      -]New value: +[
      +  "VERIFIED_CURRENT",
      +  "VERIFIED_EXPIRED",
      +  "VERIFIED_WRONG_AUDIENCE",
      +  "VERIFIED_WRONG_ENVIRONMENT",
      +  "VERIFIED_SUPERSEDED",
      +  "VERIFIED_SCOPE_MISMATCH",
      +  "VERIFIED_UNBOUND_OPERATION",
      +  "VERIFIED_UNBOUND_TARGET",
      +  "VERIFIED_UNBOUND_REPOSITORY",
      +  "VERIFIED_UNBOUND_BRANCH",
      +  "VERIFIED_UNBOUND_PULL_REQUEST",
      +  "VERIFIED_TARGET_NOT_STATED",
      +  "UNKNOWN_KEY",
      +  "UNKNOWN_KEY_STATUS",
      +  "RETIRED_KEY_VALID_AT_ISSUE",
      +  "RETIRED_KEY_UNANCHORED",
      +  "KEY_RETIRED_AFTER_SIGNING",
      +  "REVOKED_KEY",
      +  "REVOKED_KEY_UNDECIDABLE",
      +  "KEY_REVOKED",
      +  "REVOCATION_UNDECIDABLE",
      +  "AUTHORIZATION_UNDECIDABLE",
      +  "INVALID_SIGNATURE",
      +  "MALFORMED",
      +  "UNSUPPORTED_VERSION",
      +  "REGISTRY_UNREACHABLE"
      +]
  2. Changed1 schema field changed
    • addedOutput schema / properties / authz_reasons
      Added value: +{
      +  "description": "Every violation found; the first is authz_reason. [] when authorized. Fix all of them before re-verifying.",
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
  3. Changed3 schema fields changed
    • changedInput schema / description
      Previous value: -"Two evaluation modes (schema-documented; no mode discriminator field). SIGNATURE: supply token only — signature + expiry; currently_authorized is null. AUTHORIZATION: also supply intended context (operation, environment, fingerprint, target_id, audience, repository/branch/pull_request, and/or base/head) AND the body_hash-bound decision_result envelope so currently_authorized / authz_status / authz_reason can be evaluated. Token alone is always accepted; omitting the envelope when context fields are present yields a signature verdict plus fail-closed authorization (currently_authorized false), not a schema reject."New value: +"Two evaluation modes (schema-documented; no mode discriminator field). SIGNATURE: supply token only — signature + expiry; currently_authorized is null. AUTHORIZATION: also supply intended context (operation, environment, fingerprint, target_id set to decision_result.artifact_digest, audience, repository/branch/pull_request, and/or base/head) AND the body_hash-bound decision_result envelope so currently_authorized / authz_status / authz_reason can be evaluated. Token alone is always accepted; omitting the envelope when context fields are present yields a signature verdict plus fail-closed authorization (currently_authorized false), not a schema reject."
    • changedInput schema / properties / target_id / description
      Previous value: -"Intended apply-site target the receipt must bind"New value: +"REQUIRED to authorize under a held receipt. Set it to decision_result.artifact_digest — the digest of the artifact the receipt was issued for, which you already hold in the decision_result you are passing. The server does NOT derive it for you: it carries YOUR intended apply-site, and taking it from the envelope would compare that document against itself. Omit it and the answer is currently_authorized false with authz_reason target_not_stated and authz_status VERIFIED_TARGET_NOT_STATED — a missing input, distinct from target_mismatch, which means the receipt covers a different target."
    • changedOutput schema / properties / status / enum
      Previous value: -[
      -  "VERIFIED_CURRENT",
      -  "VERIFIED_EXPIRED",
      -  "VERIFIED_WRONG_AUDIENCE",
      -  "VERIFIED_WRONG_ENVIRONMENT",
      -  "VERIFIED_SUPERSEDED",
      -  "VERIFIED_SCOPE_MISMATCH",
      -  "VERIFIED_UNBOUND_OPERATION",
      -  "VERIFIED_UNBOUND_TARGET",
      -  "VERIFIED_UNBOUND_REPOSITORY",
      -  "VERIFIED_UNBOUND_BRANCH",
      -  "VERIFIED_UNBOUND_PULL_REQUEST",
      -  "UNKNOWN_KEY",
      -  "UNKNOWN_KEY_STATUS",
      -  "RETIRED_KEY_VALID_AT_ISSUE",
      -  "KEY_RETIRED_AFTER_SIGNING",
      -  "REVOKED_KEY",
      -  "REVOKED_KEY_UNDECIDABLE",
      -  "KEY_REVOKED",
      -  "REVOCATION_UNDECIDABLE",
      -  "AUTHORIZATION_UNDECIDABLE",
      -  "INVALID_SIGNATURE",
      -  "MALFORMED",
      -  "UNSUPPORTED_VERSION",
      -  "REGISTRY_UNREACHABLE"
      -]New value: +[
      +  "VERIFIED_CURRENT",
      +  "VERIFIED_EXPIRED",
      +  "VERIFIED_WRONG_AUDIENCE",
      +  "VERIFIED_WRONG_ENVIRONMENT",
      +  "VERIFIED_SUPERSEDED",
      +  "VERIFIED_SCOPE_MISMATCH",
      +  "VERIFIED_UNBOUND_OPERATION",
      +  "VERIFIED_UNBOUND_TARGET",
      +  "VERIFIED_UNBOUND_REPOSITORY",
      +  "VERIFIED_UNBOUND_BRANCH",
      +  "VERIFIED_UNBOUND_PULL_REQUEST",
      +  "VERIFIED_TARGET_NOT_STATED",
      +  "UNKNOWN_KEY",
      +  "UNKNOWN_KEY_STATUS",
      +  "RETIRED_KEY_VALID_AT_ISSUE",
      +  "KEY_RETIRED_AFTER_SIGNING",
      +  "REVOKED_KEY",
      +  "REVOKED_KEY_UNDECIDABLE",
      +  "KEY_REVOKED",
      +  "REVOCATION_UNDECIDABLE",
      +  "AUTHORIZATION_UNDECIDABLE",
      +  "INVALID_SIGNATURE",
      +  "MALFORMED",
      +  "UNSUPPORTED_VERSION",
      +  "REGISTRY_UNREACHABLE"
      +]
  4. Changed1 schema field changed
    • changedInput schema / properties / decision_result / properties / blast_radius / description
      Previous value: -"ID27 additive COUNTS (not a score). Not permission."New value: +"Additive COUNTS (not a score). Not permission."
  5. Changed1 schema field changed
    • changedOutput schema / properties / correlation_id / description
      Previous value: -"Route-owned trace id (ID828); always a non-empty string on 200"New value: +"Route-owned trace id, set by the route itself rather than by correlation middleware; always a non-empty string on 200"
  6. Changed2 schema fields changed
    • changedInput schema / properties / decision_result / properties / authority / description
      Previous value: -"ID963 additive. { audience, tenant_scope: bound|unbound, binding_proven_at? }. Informational — not permission, not a verify-receipt gate, not an ACL."New value: +"Additive. { audience, tenant_scope: bound|unbound, binding_proven_at? }. Informational — not permission, not a verify-receipt gate, not an ACL."
    • changedInput schema / properties / decision_result / properties / derivation / description
      Previous value: -"ID637 6b additive. Present only when derivation:\"server\" produced this envelope. { source, platform?, base_sha, head_sha }. Covered by body_hash; not fingerprint."New value: +"Additive. Present only when derivation:\"server\" produced this envelope. { source, platform?, base_sha, head_sha }. Covered by body_hash; not fingerprint."
  7. Changed1 schema field changed
    • changedOutput schema / properties / status / enum
      Previous value: -[
      -  "VERIFIED_CURRENT",
      -  "VERIFIED_EXPIRED",
      -  "VERIFIED_WRONG_AUDIENCE",
      -  "VERIFIED_WRONG_ENVIRONMENT",
      -  "VERIFIED_SUPERSEDED",
      -  "VERIFIED_SCOPE_MISMATCH",
      -  "UNKNOWN_KEY",
      -  "RETIRED_KEY_VALID_AT_ISSUE",
      -  "INVALID_SIGNATURE",
      -  "MALFORMED",
      -  "UNSUPPORTED_VERSION",
      -  "REGISTRY_UNREACHABLE"
      -]New value: +[
      +  "VERIFIED_CURRENT",
      +  "VERIFIED_EXPIRED",
      +  "VERIFIED_WRONG_AUDIENCE",
      +  "VERIFIED_WRONG_ENVIRONMENT",
      +  "VERIFIED_SUPERSEDED",
      +  "VERIFIED_SCOPE_MISMATCH",
      +  "VERIFIED_UNBOUND_OPERATION",
      +  "VERIFIED_UNBOUND_TARGET",
      +  "VERIFIED_UNBOUND_REPOSITORY",
      +  "VERIFIED_UNBOUND_BRANCH",
      +  "VERIFIED_UNBOUND_PULL_REQUEST",
      +  "UNKNOWN_KEY",
      +  "UNKNOWN_KEY_STATUS",
      +  "RETIRED_KEY_VALID_AT_ISSUE",
      +  "KEY_RETIRED_AFTER_SIGNING",
      +  "REVOKED_KEY",
      +  "REVOKED_KEY_UNDECIDABLE",
      +  "KEY_REVOKED",
      +  "REVOCATION_UNDECIDABLE",
      +  "AUTHORIZATION_UNDECIDABLE",
      +  "INVALID_SIGNATURE",
      +  "MALFORMED",
      +  "UNSUPPORTED_VERSION",
      +  "REGISTRY_UNREACHABLE"
      +]
  8. Changed1 schema field changed
    • changedInput schema / properties / decision_result / properties / derivation / description
      Previous value: -"ID637 6b additive. Present only when derivation:\"server\" produced this envelope. { source: github_compare, base_sha, head_sha }. Covered by body_hash; not fingerprint."New value: +"ID637 6b additive. Present only when derivation:\"server\" produced this envelope. { source, platform?, base_sha, head_sha }. Covered by body_hash; not fingerprint."
  9. Changed1 schema field changed
    • addedInput schema / properties / decision_result / properties / derivation
      Added value: +{
      +  "description": "ID637 6b additive. Present only when derivation:\"server\" produced this envelope. { source: github_compare, base_sha, head_sha }. Covered by body_hash; not fingerprint.",
      +  "type": [
      +    "object",
      +    "null"
      +  ]
      +}
  10. Changed2 schema fields changed
    • addedInput schema / properties / decision_result / properties / audience
      Added value: +{
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedInput schema / properties / decision_result / properties / authority
      Added value: +{
      +  "description": "ID963 additive. { audience, tenant_scope: bound|unbound, binding_proven_at? }. Informational — not permission, not a verify-receipt gate, not an ACL.",
      +  "type": [
      +    "object",
      +    "null"
      +  ]
      +}
  11. Changed1 schema field changed
    • addedInput schema / properties / decision_result / properties / blast_radius
      Added value: +{
      +  "description": "ID27 additive COUNTS (not a score). Not permission.",
      +  "properties": {
      +    "consumers_declared": {
      +      "minimum": 0,
      +      "type": "integer"
      +    },
      +    "consumers_observed": {
      +      "minimum": 0,
      +      "type": "integer"
      +    },
      +    "endpoints": {
      +      "minimum": 0,
      +      "type": "integer"
      +    },
      +    "fields": {
      +      "minimum": 0,
      +      "type": "integer"
      +    },
      +    "graph_source": {
      +      "type": "string"
      +    },
      +    "params": {
      +      "minimum": 0,
      +      "type": "integer"
      +    }
      +  },
      +  "type": "object"
      +}
  12. Changed4 schema fields changed
    • changedInput schema / description
      Previous value: -"Two evaluation modes (schema-documented; no mode discriminator field). SIGNATURE: supply token only — signature + expiry; currently_authorized is null. AUTHORIZATION: also supply intended context (operation, environment, fingerprint, target_id, audience, and/or base/head) AND the body_hash-bound decision_result envelope so currently_authorized / authz_status / authz_reason can be evaluated. Token alone is always accepted; omitting the envelope when context fields are present yields a signature verdict plus fail-closed authorization (currently_authorized false), not a schema reject."New value: +"Two evaluation modes (schema-documented; no mode discriminator field). SIGNATURE: supply token only — signature + expiry; currently_authorized is null. AUTHORIZATION: also supply intended context (operation, environment, fingerprint, target_id, audience, repository/branch/pull_request, and/or base/head) AND the body_hash-bound decision_result envelope so currently_authorized / authz_status / authz_reason can be evaluated. Token alone is always accepted; omitting the envelope when context fields are present yields a signature verdict plus fail-closed authorization (currently_authorized false), not a schema reject."
    • addedInput schema / properties / branch
      Added value: +{
      +  "description": "Intended branch the receipt must bind (place binding; optional)",
      +  "type": "string"
      +}
    • addedInput schema / properties / pull_request
      Added value: +{
      +  "description": "Intended pull-request id the receipt must bind (place binding; optional)",
      +  "oneOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "number"
      +    }
      +  ]
      +}
    • addedInput schema / properties / repository
      Added value: +{
      +  "description": "Intended repository the receipt must bind (place binding; optional)",
      +  "type": "string"
      +}
  13. Changed2 schema fields changed
    • changedInput schema / properties / decision_result / description
      Previous value: -"The body_hash-bound decision envelope (carries operation/target/decision). Required for a meaningful AUTHORIZATION evaluation of scope; without it, intended context alone fails closed on authorization (currently_authorized false) while signature status remains independent."New value: +"The body_hash-bound decision envelope (carries operation/target/decision). Required for a meaningful AUTHORIZATION evaluation of scope; without it, intended context alone fails closed on authorization (currently_authorized false) while signature status remains independent. Full schema: https://coderifts.com/schemas/decision-result.v1.consumer.json."
    • addedInput schema / properties / decision_result / properties
      Added value: +{
      +  "base": {
      +    "type": [
      +      "string",
      +      "null"
      +    ]
      +  },
      +  "decision": {
      +    "enum": [
      +      "ALLOW",
      +      "WARN",
      +      "REQUIRE_APPROVAL",
      +      "BLOCK"
      +    ],
      +    "type": "string"
      +  },
      +  "decision_body_hash": {
      +    "type": [
      +      "string",
      +      "null"
      +    ]
      +  },
      +  "decision_id": {
      +    "type": "string"
      +  },
      +  "environment": {
      +    "type": [
      +      "string",
      +      "null"
      +    ]
      +  },
      +  "execution_action": {
      +    "enum": [
      +      "CONTINUE",
      +      "CONTINUE_WITH_MONITORING",
      +      "REQUEST_APPROVAL",
      +      "STOP"
      +    ],
      +    "type": "string"
      +  },
      +  "expires_at": {
      +    "type": "string"
      +  },
      +  "fingerprint": {
      +    "type": "string"
      +  },
      +  "head": {
      +    "type": [
      +      "string",
      +      "null"
      +    ]
      +  },
      +  "input_fingerprint": {
      +    "type": "string"
      +  },
      +  "operation": {
      +    "type": [
      +      "string",
      +      "null"
      +    ]
      +  },
      +  "receipt": {
      +    "type": "object"
      +  },
      +  "repository": {
      +    "type": [
      +      "string",
      +      "null"
      +    ]
      +  },
      +  "safe_for_agent": {
      +    "type": "boolean"
      +  },
      +  "spec_version": {
      +    "pattern": "^decision-result\\.v1(\\.[0-9]+)?$",
      +    "type": "string"
      +  }
      +}
  14. Changed3 schema fields changed
    • changedInput schema / description
      Previous value: -"Two evaluation modes (schema-documented; no mode discriminator field). SIGNATURE: supply token only — signature + expiry; currently_authorized is null. AUTHORIZATION: also supply intended context (operation, environment, fingerprint, target_id, and/or audience) AND the body_hash-bound decision_result envelope so currently_authorized / authz_status / authz_reason can be evaluated. Token alone is always accepted; omitting the envelope when context fields are present yields a signature verdict plus fail-closed authorization (currently_authorized false), not a schema reject."New value: +"Two evaluation modes (schema-documented; no mode discriminator field). SIGNATURE: supply token only — signature + expiry; currently_authorized is null. AUTHORIZATION: also supply intended context (operation, environment, fingerprint, target_id, audience, and/or base/head) AND the body_hash-bound decision_result envelope so currently_authorized / authz_status / authz_reason can be evaluated. Token alone is always accepted; omitting the envelope when context fields are present yields a signature verdict plus fail-closed authorization (currently_authorized false), not a schema reject."
    • addedInput schema / properties / base
      Added value: +{
      +  "description": "Intended base commit/ref SHA the receipt must match (signed-wins vs envelope.base)",
      +  "type": "string"
      +}
    • addedInput schema / properties / head
      Added value: +{
      +  "description": "Intended head commit/ref SHA the receipt must match (signed-wins vs envelope.head)",
      +  "type": "string"
      +}
  15. Changed4 schema fields changed
    • addedOutput schema / properties / binding_level
      Added value: +{
      +  "description": "place_and_content | content_only — forensic, not a second verdict",
      +  "type": "string"
      +}
    • addedOutput schema / properties / caller_value
      Added value: +{
      +  "description": "Caller claim that differed from the signed envelope",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / correlation_id
      Added value: +{
      +  "description": "Route-owned trace id (ID828); always a non-empty string on 200",
      +  "type": "string"
      +}
    • addedOutput schema / properties / signed_value
      Added value: +{
      +  "description": "Signed envelope slot when signed-wins fail-closed (source_binding_mismatch)",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
  16. First observed

TDQS

A4.8/5.0
Behavior5/5

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

Annotations only declare readOnlyHint and openWorldHint, so the description carries the behavioral burden and does so: it discloses 30s clock-skew leeway on expiry, explains the declared-0s-grace path is currently unreachable, and states that omitting the envelope yields a signature verdict plus fail-closed authorization rather than a schema reject. It also disambiguates `target_not_stated` from `target_mismatch`, which is exactly the kind of outcome semantics annotations cannot express.

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

Conciseness4/5

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

Well front-loaded: purpose first, then when/not-when blocks, then inputs and return shape, then the remediation caveat. However, it is long, and the paragraph explaining that a policy-defined 0s grace for destructive production operations is unreachable today reads as internal implementation trivia that an invoking agent rarely needs.

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 12-parameter tool with a nested decision envelope, the description supplies the mode selection logic, the fail-closed condition, the return keys to branch on, and the meaning of a null verdict. With an output schema present it correctly stops short of documenting full return structure while still naming the decision-relevant fields.

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?

Schema coverage is 100%, so baseline is 3, and the description does add meaning beyond it: the two evaluation modes (SIGNATURE vs AUTHORIZATION), the fact that `operation` triggers authorization evaluation, and why the server refuses to derive `target_id` from the envelope. Some of this (notably the `target_id` = `artifact_digest` instruction and the target_not_stated outcome) is already spelled out nearly verbatim in the schema, so it is partly repetition rather than pure value-add.

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?

Opens with a specific verb and resource ('Verify a CodeRifts signed chain-receipt you ALREADY HOLD') and enumerates exactly what is checked: signature + key id, body binding, and current authorization validity. It also explicitly separates itself from siblings by naming `preflight_change_set` and `get_decision_details` as the tools for adjacent jobs.

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

Usage Guidelines5/5

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

Provides both a 'Use this when' block (three concrete triggers: acting under a held receipt, policy-required proof, distinguishing 'signature ok' from 'currently authorized') and a 'Do not use when' block with five exclusions, each naming the alternative tool to call instead. It also tells the agent to branch on `currently_authorized` and that null means not evaluated.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.