> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nika.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# nika:hash

> Usage, declared contract and source links for this Nika builtin.

export const Ecosystem = () => <CardGroup cols={3}>
    <Card title="Documentation" icon="book" href="/introduction">
      Guides, reference contracts and working examples.
    </Card>
    <Card title="Nika Lab" icon="diagram-project" href="https://github.com/supernovae-st/nika-lab">
      Internal workspace and graph projections of the spec, documentation and code.
    </Card>
    <Card title="Language spec" icon="file-contract" href="https://github.com/supernovae-st/nika-spec">
      the nine-key envelope, Apache-2.0. The contract these docs explain.
    </Card>
    <Card title="Engine source" icon="gem" href="https://github.com/supernovae-st/nika">
      Rust, AGPL-3.0-or-later. Every commit public.
    </Card>
    <Card title="TypeScript SDK" icon="code" href="/sdk/overview">
      Use one typed lifecycle locally or against authenticated nika serve HTTP.
    </Card>
    <Card title="Editor extension" icon="puzzle-piece" href="https://marketplace.visualstudio.com/items?itemName=supernovae.nika-lang">
      VS Code · Cursor · Windsurf: check-as-you-type, DAG view, trace replay.
    </Card>
    <Card title="Homebrew tap" icon="beer-mug-empty" href="https://github.com/supernovae-st/homebrew-tap">
      `brew install supernovae-st/tap/nika` for the latest tagged CLI release.
    </Card>
    <Card title="SuperNovae" icon="star" href="https://supernovae.studio">
      The Paris studio crafting Nika. 🦋
    </Card>
  </CardGroup>;

[Builtins catalog](/reference/builtins) / `nika:hash`

<CardGroup cols={2}>
  <Card title="Data" icon="layer-group">Tool family from the canonical registry.</Card>
  <Card title="invoke" icon="code" href="/reference/language/words/invoke">Call this builtin through the invoke verb.</Card>
</CardGroup>

## Read this contract

This reference preserves the specification at the revision linked below. Source examples are **fragments**: their surrounding tasks, inputs and permissions are not supplied here. Consult [engine status](/reference/status) and `nika catalog --tools --json` for the installed implementation; a registry declaration is not a runtime qualification.

## Usage and behavior

\> **Reference-engine availability at `6ac427c5e62dc450d1d2393e3eec169e9566f6a3`:**
\> digest calls accept `content`, `algo` and `encoding`. The `op` argument,
\> including explicit `op: hash`, and the `sign`/`verify` forms below are
\> **spec-ahead of this engine pin**. Their normative contract is retained;
\> these examples do not announce implementation availability.

```yaml illustration theme={"system"}
invoke: { tool: "nika:hash", args: { algo: blake3, content: "${{ tasks.X.output }}", encoding: hex } }

# Normative op forms · spec-ahead at the engine pin named above
invoke: { tool: "nika:hash", args: { op: sign,   content: "${{ with.manifest }}", key: "${{ secrets.release_key }}" } }
invoke: { tool: "nika:hash", args: { op: verify, content: "${{ with.manifest }}", public_key: "${{ const.release_pub }}", signature: "${{ with.sig }}" } }
```

Content hashing · default **blake3** (fastest modern cryptographic hash · parallel · secure) · or `sha256`/`sha512`. md5/sha1 NOT supported (cryptographically broken · `NIKA-BUILTIN-HASH-001` `validation_error` on an unsupported algo). `encoding:` `hex` (default) | `base64`. Use cases · cache keys · content addressing · provenance. `content:` accepts a string **or** a structured value (an object/array is hashed as compact JSON — do not pre-pipe `| tojson`).

**Digest arguments (`op` omitted or `op: hash`).** `content` MUST be present and non-null. Strings are hashed verbatim; every other non-null JSON value (object, array, number or boolean) is hashed as compact JSON. An empty string, `0`, `false`, an empty object or array, and null members inside an object or array are valid content. `algo` and `encoding` use their defaults only when absent. When present, each MUST be a string in its listed closed set; null, another JSON type, an empty string or an unsupported value is a validation error (`NIKA-BUILTIN-HASH-001`). Statically known invalid literals MUST be refused before execution. A valid substitution expression whose result is not yet known is checked after resolution; it does not exempt other, independently decidable arguments from validation.

**`op:` · `hash` (default) · `sign` · `verify` (normative · v0.1 surface).**
The engine already signs and verifies Ed25519 — the run seal is one Ed25519
signature over the journal, minted by `nika key init` and checked by the
evidence verifier. **The language could not reach any of it.** A capability
that ships and stays unreachable from the file is not a shipped capability,
so `op:` exposes it through the builtin that already owns the digest.

| Arg          | Ops             | Notes                                                                                         |
| ------------ | --------------- | --------------------------------------------------------------------------------------------- |
| `content`    | all             | required · the bytes under the operation                                                      |
| `algo`       | `hash`          | `blake3` (default) · `sha256` · `sha512`                                                      |
| `encoding`   | `hash` · `sign` | `hex` (default) · `base64` — the output encoding                                              |
| `key`        | `sign`          | required · the Ed25519 private key · **MUST be a `${{ secrets.X }}` reference**               |
| `public_key` | `verify`        | required · the Ed25519 public key (a `const:`/`inputs:` value — a public key is not a secret) |
| `signature`  | `verify`        | required · the signature to check, in `encoding:`                                             |

`sign` returns the signature string; `verify` returns a boolean and never
throws on a bad signature (a *false* verdict is data, not an error — a
workflow branches on it with `when:`). A malformed key, an unknown `op:`, or
a missing per-op required arg is `NIKA-BUILTIN-HASH-001` (`validation_error`).

**The key rides `secrets:` — that is a hard rule, not a convention.** A
private key reached from the ambient environment or an implicit on-disk
keyring would make `nika:hash` read state its declaration does not name,
which is exactly the pure-compute-that-is-not-pure defect the permits
boundary exists to refuse. Declaring the key under `secrets:` keeps it inside
the three-authority family, keeps it masked in logs, and keeps its reach
governed by `egress:` like any other secret.

**What this closes, and what it does NOT (bounded honestly).** It closes
**Ed25519** signing and verification — detached signatures over content the
workflow already holds: release manifests, provenance attestations,
inter-workflow handoffs, checkpoint verification. It does **not** close
RS256/JWT: that is RSA with a different key format, a different padding
scheme and a token envelope, none of which this surface has. A GitHub App
credential exchange is RS256 and stays out of reach — do not read this
section as authenticating anything that mints a JWT. `capability_classification`
for the builtin moves from `pure_internal` to secret-reading under `op: sign`;
the classification row in `canon/builtins.yaml` follows when the engine wires
the op (today the engine's `ARGS` gate declares `content · algo · encoding`
only, so `op:` is spec-ahead-of-engine and this file says so rather than
implying a green that does not exist).

***

## Related concepts

<CardGroup cols={2}>
  <Card title="Arguments" icon="sliders" href="/reference/language/words/args">Pass the values required by the tool contract.</Card>
  <Card title="Permissions" icon="shield" href="/concepts/security">Understand authority before granting effects.</Card>
  <Card title="Errors and recovery" icon="rotate" href="/reference/error-codes">Read diagnostics and choose a recovery policy.</Card>
  <Card title="Workflow templates" icon="file-code" href="/guides/templates">Put the fragment inside a complete workflow.</Card>
</CardGroup>

## Contract provenance

[Read the pinned specification](https://github.com/supernovae-st/nika-spec/blob/f8c5df2127c7867b2e51a2cd5712fa9d8461e73e/stdlib/builtins-v0.1.md#L287) · [Canonical registry](https://github.com/supernovae-st/nika-spec/blob/f8c5df2127c7867b2e51a2cd5712fa9d8461e73e/canon/builtins.yaml).

Tool identity: `nika:hash`. Specification revision: `f8c5df2127c7`.
The Lab language identity is `language:tool:hash`; the registry view is `ecosystem:tool/nika:hash`. They refer to this contract without merging their graph identities.

<Ecosystem />
