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

# Java SDK Reference

> Local-decision reference for the Java binding to the VisIQ governance core — gateAction / gateRetrieval over the same compiled Rust core the Python and TypeScript SDKs use, via the Panama FFM API.

The Java binding calls the **same compiled Rust core** the Python and TypeScript
SDKs use, in-process via the Foreign Function & Memory API (Panama, finalized in
JDK 22) — no JNI shim. One core, many languages; every decision is local.

<Note>
  **Scope: local-decision layer only** — bundle auto-refresh, HITL and audit
  streaming are the Governor harness (Python/TypeScript only). This binding makes
  one thing fast and local: the policy DECISION. You fetch the rule bundle and
  stream audit yourself.
</Note>

## Install

The jar bundles the platform-matching compiled core (extracted at load time), so
there is no separate native install.

```xml theme={null}
<dependency>
  <groupId>com.visiqlabs</groupId>
  <artifactId>visiq-sdk</artifactId>
  <version>0.1.1</version>
</dependency>
```

Requires **JDK 22+**, run with `--enable-native-access=ALL-UNNAMED` so the FFM
downcall to the core is permitted.

## Acquire a bundle

Every decision is made against a rule bundle you fetch from the control plane and
parse. Fetch it over the [rules API](/rules/action/api-reference):

```bash theme={null}
curl -H "Authorization: Bearer $VISIQ_API_KEY" \
  "$VISIQ_ENDPOINT/rules/bundle?agent_id=support-bot"
```

`VISIQ_ENDPOINT` defaults to `https://api.visiqlabs.com`; set it only for onprem.
Parse the returned JSON into a Jackson `JsonNode` (`bundle`) and pass it in.

## Govern a tool call

`Visiq.gateAction(bundle, toolName, args, agentId)` decides one tool/action call.
Inspect `decision.get("allowed")`; on a `mask` verdict apply
`decision.get("action").get("argRedactionRules")` to the args first.

```java theme={null}
// guide:begin
JsonNode decision = Visiq.gateAction(bundle, "wire_transfer", args, "sdk-agent");
System.out.println("allowed=" + decision.get("allowed").asBoolean());
// guide:end
```

This exact snippet is executed as a proof (`GuideExampleTest`) against a bundle
copied verbatim from the oracle-stamped conformance corpus: the deny fixture
blocks (`allowed=false`), the permit fixture passes (`allowed=true`).

## Govern a retrieval

`Visiq.gateRetrieval(bundle, resourceMetadata, agentId)` decides one retrieval.
Inspect `decision.get("retrieval").get("action")` — drop on `deny`/`escalate`,
redact via `retrieval.get("redactionRules")` — before content reaches the model.

```java theme={null}
JsonNode decision = Visiq.gateRetrieval(bundle, metadata, "sdk-agent");
System.out.println("action=" + decision.get("retrieval").get("action").asText());
```

## Fail mode

A HARNESS-internal failure — the native core can't load, or `visiq_evaluate`
returns NULL/throws — is routed by `VISIQ_FAIL_MODE` (owner G001 rescope): `open`
(**default**) returns a permit-equivalent decision plus a loud stderr report so a
VisIQ packaging bug never disrupts the agent; `closed` throws a fail-closed
exception. A real rule **deny** always blocks regardless of fail mode.

```bash theme={null}
VISIQ_FAIL_MODE=closed   # strict: a core-load/FFI failure denies instead of proceeding
```

## Override the core library

The jar extracts its bundled core to a temp file. Point it at a specific library
with `VISIQ_CORE_LIB` (an absolute path), matching the Go and Ruby bindings.

```bash theme={null}
VISIQ_CORE_LIB=/opt/visiq/libvisiq_core.so
```

## Next steps

<CardGroup cols={2}>
  <Card title="Ruby Reference" icon="book" href="/reference-ruby">
    The published Ruby gem — `gate_action` over the same core.
  </Card>

  <Card title="Python Reference" icon="book" href="/reference-python">
    The full Python harness — Governor, gates, and audit streaming.
  </Card>
</CardGroup>
