> ## 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.

# Go SDK Reference

> Local-decision reference for the Go binding to the VisIQ governance core — build-from-repo GateAction / GateRetrieval over the same compiled Rust core the Python and TypeScript SDKs use.

The Go binding calls the **same compiled Rust core** the Python and TypeScript
SDKs use, in-process over a C ABI (cgo). One core, many languages — no
re-implementation, no drift.

<Warning>
  **Internal / build-from-repo — Go is NOT published.** Go libraries distribute as
  **source** (a public git repo + `proxy.golang.org`); there is no compiled-binary
  Go *library* artifact. Publishing this binding would expose the engine call graph
  in source, the same reason the Rust SDK stays off crates.io. So the Go binding is
  `package main`, **non-importable**, consumed by building from the monorepo — not
  `go get`. The published, installable bindings are **Python, TypeScript, and
  Ruby** (compiled artifacts); **Java** publishes with the first `main` release —
  build from source until then. Use those if you need a package manager install.
</Warning>

<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>

## Build

Build the C-ABI core (no pyo3) once, then build/run the Go package from the repo:

```bash theme={null}
cd experiments/matrix-v2/visiq-core-rs && cargo build --release --target-dir target-capi
cd ../visiq-sdk-go && CGO_ENABLED=1 go test ./...
```

## Acquire a bundle

Every decision is made against a rule bundle you fetch from the control plane and
hold in memory. 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.
Hold the returned JSON as a string (`bundleJSON`) and pass it to the gate helpers.

## Govern a tool call

`GateAction(bundleJSON, toolName, args, agentID)` decides one tool/action call.
Inspect `decision["allowed"]`; on a `mask` verdict apply
`decision["action"]["argRedactionRules"]` to the args before running the tool.

```go theme={null}
// guide:begin
decision, _ := GateAction(bundleJSON, "wire_transfer", map[string]any{"amount": 999}, "sdk-agent")
// A denied tool: decision["allowed"] is false — do NOT run it.
fmt.Printf("allowed=%v\n", decision["allowed"])
// guide:end
```

This exact snippet is executed as a proof (`guide_example_test.go`,
`ExampleGateAction`) 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

`GateRetrieval(bundleJSON, resourceMetadata, agentID)` decides one retrieval.
Inspect `decision["retrieval"]["action"]` — drop on `deny`/`escalate`, redact via
`decision["retrieval"]["redactionRules"]` — before content reaches the model.

```go theme={null}
decision, _ := GateRetrieval(bundleJSON, map[string]any{"classification": "restricted"}, "sdk-agent")
retrieval := decision["retrieval"].(map[string]any)
fmt.Printf("action=%v\n", retrieval["action"])
```

## Fail mode

A HARNESS-internal failure — the native core can't load, or `visiq_evaluate`
returns NULL — 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` returns a deny-equivalent.
A real rule **deny** always blocks regardless of fail mode.

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

## Override the core library

The binding loads `libvisiq_core` from the build tree. Point it elsewhere with
`VISIQ_CORE_LIB` (an absolute path), matching the Java and Ruby bindings.

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

## Next steps

<CardGroup cols={2}>
  <Card title="Java Reference" icon="book" href="/reference-java">
    The Java binding — `gateAction` over the same core.
  </Card>

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