Planned Integrations¶
This page catalogs integrations that are not production-ready: scaffolded SDKs, stub applications, and adapter surfaces named in the original v1 design that are not implemented. For shipped integrations, see the dedicated reference pages (Python SDK, REST API, gRPC API, MCP Tools, CLI, VSCode Tooling, Rule Packs).
Each entry declares a Status of one of:
- Shipped — in-tree, tested, documented, and reachable from a release artifact.
- Partial — in-tree with working code but missing tests, packaging, or CI coverage.
- Planned — named in the original v1 design with no implementation in the source tree.
Go SDK — packages/fathom-go/¶
Status: Partial.
Location: packages/fathom-go/ — a hand-written REST client plus
generated gRPC bindings. Package contents: client.go (181 lines),
client_test.go (818 lines), grpc_test.go (230 lines, build-tagged
integration), tools.go, go.mod, go.sum, Makefile, and
proto/ with fathom.pb.go + fathom_grpc.pb.go. go.mod declares
module github.com/KrakenNet/fathom-go at go 1.25.0.
What works today:
NewClient(baseURL, opts...)constructor atclient.go:39-48, with functional optionsWithBearerToken(client.go:25-27) andWithHTTPClient(client.go:31-33).- Four request/response pairs covering the REST surface:
Evaluate,AssertFact,Query,Retract(client.go:74-144). - Shared transport at
client.go:148-180: JSON marshal/unmarshal,Content-Type: application/json, optionalAuthorization: Bearer <token>header, and error surfacing on any non-2xx status with the server body embedded in the returned error. - Unit tests in
client_test.goexercise the REST surface againsthttptestservers. - Generated gRPC stubs live in
packages/fathom-go/proto/(built fromprotos/fathom.proto);grpc_test.gois a-tags=integrationtest that spawns the Python gRPC server and dials it via those stubs.
What is missing:
- No released module. Consumers must vendor the package from a local clone; nothing is published to a Go proxy. Tracked as issue #41.
The Go suite is wired into CI:
.github/workflows/go-ci.yml runs go vet, go build, and
go test ./... on every pull request, with a second integration job
that spins up the Python gRPC server and runs go test -tags integration
./.... A verify-grpc step also fails the build if the generated
bindings drift from protos/fathom.proto.
How to use today: Clone the monorepo, go get against the local path
(or add a replace directive), and point the client at a running REST
server. For the current public API surface, see the generated reference
at Go SDK.
TypeScript SDK — packages/fathom-ts/¶
Status: Partial.
Location: packages/fathom-ts/ — published identity
@fathom-rules/sdk, versioned in lockstep with the engine (release-please
writes package.json from the same tag, and scripts/check_version_sync.py
fails the build if the two drift). Source lives in
src/client.ts (215 lines), src/errors.ts (77 lines), and
src/index.ts (26 lines). Vitest suites in test/client.test.ts and
test/errors.test.ts.
What works today: A hand-written FathomClient plus a typed error
hierarchy. The package ships with 34
vitest tests passing (15 in test/client.test.ts, 19 in
test/errors.test.ts), and the typedoc reference is generated into
docs/reference/typescript-sdk/ by the docs npm script in
package.json. The suite is wired into CI: .github/workflows/ts-ci.yml
runs typecheck, build and vitest as the required ts-test check on every
pull request.
There is no generated client. src/generated/ used to hold one, and
this page used to describe it as working. It was generated once, in April
2026, from a copy of the spec at the repo root that was frozen at API
version 0.3.0 — two endpoints behind the live one — and nothing in the
package ever imported it. Its generate script emitted zero files against
the pinned @hey-api/openapi-ts, so it could not be refreshed either.
Both the dead tree and the stale root spec are gone; the single spec is
docs/reference/rest/openapi.json, regenerated by
scripts/export_openapi.py and held to the running app by
tests/test_scripts/test_export_openapi.py.
What is missing:
- The client covers 4 of the 11 documented endpoints —
/v1/evaluate,/v1/facts(assert and retract) and/v1/query./v1/compile,/v1/templates,/v1/modules,/v1/rules,/v1/rules/reload,/v1/status,/v1/data/{path}and/healthhave no method onFathomClient. - No published npm release.
repository.urlinpackage.jsonpoints at the monorepo; nodist/is published. Tracked as issue #40.
How to use today: Clone the monorepo, pnpm install in
packages/fathom-ts/, and import from the local workspace path. The
generated API reference lives at
TypeScript SDK.
Visual Rule Editor¶
Status: Planned.
The original v1 design named a browser-based rule editor. A React scaffold
lived at packages/fathom-editor/ and was removed: six component stubs, no
tests, no backend wiring, and a CI job whose only assertion was that the tree
still compiled. It never round-tripped against a live Fathom server, and
Policy Studio (below) had meanwhile shipped
a working browser UI over a real engine. Building the editor out is tracked as
issue #43; the scaffold is in
git history if it is ever the right starting point.
Framework adapters¶
The original v1 design listed four framework adapters. All four are now shipped.
| Adapter | Status | Location |
|---|---|---|
| LangChain callback handler | Shipped | src/fathom/integrations/langchain.py |
| CrewAI before-tool-call hook | Shipped | src/fathom/integrations/crewai.py |
| OpenAI Agents SDK tool guardrail | Shipped | src/fathom/integrations/openai_agents.py |
| Google ADK before-tool callback | Shipped | src/fathom/integrations/google_adk.py |
Each adapter follows the same pattern: intercept tool calls, then evaluate a
tool_request fact against the policy through Engine.evaluate_once, which
asserts the fact, runs, and withdraws it again so one call cannot be decided
on the previous call's working memory.
The guard is allowlist-only: it permits the call when — and only when —
the decision is exactly allow. Every other outcome (deny, escalate,
route, scope, a missing decision, or any value a future release adds)
blocks the call. A denylist of known-bad decisions would fail open on
anything it had not heard of.
How each adapter blocks is dictated by its framework, and only LangChain
blocks by raising. CrewAI, the Agents SDK and ADK all wrap the handler call
in try/except, log whatever it raises, and then run the tool anyway — so
in those three a raised exception is a fail-open, and the block has to be a
return value:
| Adapter | Block signal | Carries the reason? |
|---|---|---|
| LangChain | raises PolicyViolation (needs raise_error = True on the handler, or LangChain swallows it) |
yes |
| CrewAI | hook returns False |
no — CrewAI's own rejection message replaces it |
| OpenAI Agents SDK | guardrail returns ToolGuardrailFunctionOutput.raise_exception(output_info=violation), which the runner turns into ToolInputGuardrailTripwireTriggered |
yes, on output_info |
| Google ADK | callback returns {"error": ...} |
yes |
PolicyViolation is one class, defined in fathom.integrations and
re-exported by every adapter, so one except covers every adapter that
raises.
raise_error = True is necessary but not sufficient on the async LangChain
handler. langchain_core honours it in both its dispatchers, but only for a
handler method that runs there: the sync dispatcher calls the method, sees a
coroutine come back, and defers it to _run_coros, which catches everything,
logs Error in callback coroutine, and never reads raise_error. That is not
an exotic path — StructuredTool.ainvoke falls back to
run_in_executor(config, self.invoke, …) for any tool with no coroutine=,
which is every plain @tool-decorated function. FathomAsyncCallbackHandler
therefore defines on_tool_start as a plain def; both dispatchers run it
inline (the async one via run_in_executor) and both propagate. The engine is
synchronous anyway.
Blocking covers every failure to reach a decision, not only deny. An
exception other than PolicyViolation — a ValidationError from a pack whose
tool-call template is spelled differently, a ScopeError, an
EvaluationLimitError — means no decision was produced, and the CrewAI hook
turns it into the block signal and logs it rather than letting it escape into
CrewAI's except, which would log it and then run the tool.
The CrewAI hook reads the calling agent off the ToolCallHookContext CrewAI
hands it (agent.role, else agent.id), falling back to the agent_id given
to fathom_before_tool_call only when CrewAI supplies no agent. CrewAI's hook
registry is process-global and every registered hook runs on every call, so an
identity frozen at registration labels the whole crew with one name — and one
hook per member is not a workaround, because any hook returning False blocks,
so each member's allowed calls would be blocked by everybody else's hook.
Install via pip install fathom-rules[langchain], fathom-rules[crewai],
fathom-rules[openai-agents], or fathom-rules[google-adk]. The CrewAI and
Agents SDK extras carry floors of crewai>=1.5 and openai-agents>=0.4 —
the releases that introduced crewai.hooks and agents.tool_guardrails
respectively. Earlier releases have no hook to attach to at all.
Policy Studio — packages/fathom-studio/¶
Status: Partial.
Location: packages/fathom-studio/ — package identity fathom-studio at
0.1.0, a uv workspace member of this repo. It depends on fathom-rules
like any other consumer; the engine wheel ships no Studio code.
What works today: A browser UI over a real engine — five views (Reasoning
Bench, Live Wire, Rules, Templates, Audit) served as a zero-build React SPA,
a JSON backend under /studio/api, server-rendered HTMX panels, and the
production REST app mounted in the same process under /api. Nine demo
scenarios ship as package data, held byte-identical to the repo's
examples/0N-* directories by a test. Its pytest suite runs in CI: root
testpaths includes packages/fathom-studio/tests, so the required test
job covers it.
What is missing:
- No published release.
fathom-studiois not on PyPI and no workflow builds or publishes it; run it from a checkout withuv run fathom-studio. - No stability promise. The
/studio/api/*routes are unversioned and explicitly excluded from VERSIONING.md. - In-memory audit only. The Audit view's chain is process-local, capped
at 200 records, and signed with a keypair minted at startup. The durable
equivalent is
fathom.chained_log.ChainedAttestationLog.
How to use today: Running Policy Studio.
Known blockers¶
- Proto ↔
go.modpath alignment — previously flagged asREVIEW.mdM2 (proto declaredgithub.com/KrakenNet/fathom/gen/go/fathom/v1whilego.moddeclaredgithub.com/KrakenNet/fathom-go, which would have brokenprotocoutput). Resolved at HEAD:protos/fathom.proto:12now declaresgo_package = "github.com/KrakenNet/fathom-go/proto;fathomv1", matchingpackages/fathom-go/go.mod:1. Generated bindings now live inpackages/fathom-go/proto/{fathom.pb.go,fathom_grpc.pb.go}. - Every in-tree package is now covered by CI. The Python suite
(
.github/workflows/ci.yml, which also covers the Studio), the Go suite (.github/workflows/go-ci.yml, unit +-tags integration) and the TypeScript suite (.github/workflows/ts-ci.yml, the requiredts-testcheck, closing issue #39) all run on every pull request.
See also¶
- Python SDK — the reference implementation; all shipped adapters (including LangChain) live here.
- REST API — the wire protocol the Go and TypeScript SDKs target.
- gRPC API — the proto surface, which the Go SDK now
implements through the generated bindings in
packages/fathom-go/proto/. - Go SDK — gomarkdoc output for the clients described above.
- TypeScript SDK — typedoc output for
@fathom-rules/sdk.