ReferenceAdapter Protocol v1

Adapter Protocol Reference

This page documents the complete FORG adapter signal contract — the wire format adapters use to POST structured behavioral signals to the FORG Rule Engine. All first-party adapters (Claude Code, Cursor, VS Code, Windsurf, JetBrains, OpenCode, Neovim) implement this protocol. Community adapters must pass the conformance suite before receiving the Verified badge.

Transport

All signals are delivered as HTTP POST requests to the FORG engine endpoint. The engine is never reached directly by internal sub-domain — all public-facing traffic routes through forg.pro/engine/v1/*.

  • Method: POST
  • Endpoint: https://forg.pro/engine/v1/signals
  • Content-Type: application/json
  • Protocol version header: X-Forg-Adapter-Protocol: v1
  • Signature header: X-Forg-Signature: sha256=<hex-digest>
  • Timeout: Adapters must set a request timeout of ≤ 3 000 ms and fail open — FORG unavailability must never block the user's AI tool.

Example request

POST https://forg.pro/engine/v1/signals
Content-Type: application/json
Authorization: Bearer <token-from-forg-activate>
X-Forg-Adapter-Protocol: v1
X-Forg-Signature: sha256=<hmac-sha256-hex-digest>

{
  "type": "session-start",
  "ts": "2025-05-29T10:00:00.000Z",
  "session_id": "sess_4f9a2e1b8c3d",
  "adapter_id": "claude-code-forg",
  "goal_declared": "Refactor authentication module to use PKCE"
}

Signal types

Every signal payload must include a type field (one of the 10 values below) and a ts field (ISO 8601 UTC timestamp). Additional fields depend on the signal type.

session-start

Emitted when a new AI coding session begins.

FieldTypeDescription
session_idstringUnique session identifier assigned by the adapter.
goal_declaredstring?Optional natural-language description of the session goal.
adapter_idstringStable identifier for the adapter emitting signals, e.g. claude-code-forg.

session-end

Emitted when the session terminates cleanly.

FieldTypeDescription
session_idstringSession identifier from session-start.
duration_msnumberTotal wall-clock duration of the session in milliseconds.
tasks_completednumberNumber of tool calls or task units completed during the session.

session-pause

Emitted when a session is interrupted but not ended.

FieldTypeDescription
session_idstringSession identifier.
pause_reason"idle" | "explicit" | "window_blur"Why the session was paused.
context_snapshot_idstringOpaque ID of the context snapshot taken at pause time for later resumption.

goal-drift

Emitted when the engine detects the session trajectory diverging from the declared goal.

FieldTypeDescription
session_idstringSession identifier.
drift_scorenumberFloat 0–1 indicating drift severity (1 = complete divergence).
original_goalstringThe goal declared at session-start.
current_trajectorystringEngine-inferred description of the current task direction.

context-switch

Emitted when the user's active context moves from one tool category to another.

FieldTypeDescription
session_idstringSession identifier.
from_toolstringTool or context being left, e.g. editor.
to_toolstringTool or context being entered, e.g. browser.

tool-switch

Emitted when the user switches between specific AI tools within the same session.

FieldTypeDescription
session_idstringSession identifier.
toolstringThe AI tool now active, e.g. cursor.
previous_toolstringThe AI tool previously active.

token-milestone

Emitted when cumulative token usage crosses a configured threshold.

FieldTypeDescription
session_idstringSession identifier.
tokens_usednumberTotal tokens consumed in this session at the time of the milestone.
milestonenumberThe threshold value that was crossed, e.g. 10000.

refocus-ack

Emitted when the user acknowledges a FORG refocus intervention.

FieldTypeDescription
session_idstringSession identifier.
intervention_idstringID of the intervention being acknowledged, from the engine response.
ack_delay_msnumberMilliseconds between intervention delivery and user acknowledgment.

completion-verified

Emitted when the adapter or user confirms a goal has been achieved.

FieldTypeDescription
session_idstringSession identifier.
goal_idstringIdentifier of the goal being verified.
confidencenumberFloat 0–1 indicating confidence in completion, as reported by the adapter.

adapter-heartbeat

Periodic liveness signal. Adapters should emit this every 30 s while a session is active.

FieldTypeDescription
adapter_idstringStable adapter identifier.
latency_msnumberRound-trip latency to the FORG agent measured by the adapter.

Engine response shape

The engine returns a JSON object on every 200 OK. Non-200 responses indicate a transport or authentication error — adapters should log and fail open.

Fields

FieldTypeDescription
action"noop" | "intervention" | "log"What the adapter should do. "noop" = continue normally. "intervention" = surface a message to the user. "log" = signal was accepted and logged only.
session_idstringEcho of the session_id from the request, or a newly assigned ID if omitted in the request.
loggedbooleanWhether the signal was persisted to the behavioral log.
intervention_idstring?Present when action is "intervention". Adapters must send this back in a refocus-ack signal when the user dismisses the notification.
messagestring?Human-readable message to surface when action is "intervention".
severity"info" | "warning" | "critical"?Severity level of the intervention. Adapters should style notifications accordingly.

Noop response (normal)

HTTP/1.1 200 OK
Content-Type: application/json

{
  "action": "noop",
  "session_id": "sess_4f9a2e1b8c3d",
  "logged": true
}

Intervention response

{
  "action": "intervention",
  "session_id": "sess_4f9a2e1b8c3d",
  "intervention_id": "int_7b3c1a9f",
  "message": "Token budget 80% consumed — consider wrapping up this session.",
  "severity": "warning",
  "logged": true
}

Authentication

Adapters authenticate using a bearer token issued during forg activate. The token is stored in the OS-native keychain (macOS Security.framework, Linux libsecret, Windows DPAPI) and never written to disk in plain text. Retrieve it at runtime with:

forg token --print

Every request must carry two authentication artifacts:

  1. Bearer token in the Authorization header: Authorization: Bearer <token>
  2. HMAC-SHA256 signature in the X-Forg-Signature header. The signature is computed over the raw request body using the first 32 bytes of the bearer token as the HMAC key.
import crypto from "crypto";

// The bearer token from `forg activate` (stored in OS keychain).
// Retrieve with: forg token --print
const BEARER_TOKEN = process.env.FORG_TOKEN!;

// HMAC key = first 32 bytes of the bearer token, UTF-8 encoded
const HMAC_KEY = Buffer.from(BEARER_TOKEN.slice(0, 32), "utf8");

function signPayload(body: string): string {
  return crypto.createHmac("sha256", HMAC_KEY).update(body, "utf8").digest("hex");
}

const body = JSON.stringify({ type: "adapter-heartbeat", adapter_id: "my-tool", latency_ms: 4 });

const response = await fetch("https://forg.pro/engine/v1/signals", {
  method: "POST",
  headers: {
    "Content-Type":            "application/json",
    "Authorization":           `Bearer ${BEARER_TOKEN}`,
    "X-Forg-Adapter-Protocol": "v1",
    "X-Forg-Signature":        `sha256=${signPayload(body)}`,
  },
  body,
});

Requests that fail signature verification receive a 401 Unauthorized response. The engine logs the attempt for anomaly detection.

Versioning

The protocol version is declared in the X-Forg-Adapter-Protocol header. The current stable version is v1.

X-Forg-Adapter-Protocol: v1

Breaking changes (new required fields, removed signal types, changed response shape) will increment the version to v2. Minor, additive changes (new optional fields, new signal types) are made within the current version. Adapters that omit the header are assumed to be v1 during the current cycle; future versions may require the header.

  • The engine will accept v1 signals for a minimum of 12 months after anyv2 announcement.
  • Version deprecation notices are posted to the FORG changelog and emailed to registered adapter authors.

Conformance test suite

The conformance suite verifies that an adapter correctly implements the v1 protocol: signal shape validation, HMAC signing, fail-open behavior, and session lifecycle ordering. Community adapters must pass all conformance checks to receive the Verified badge in the FORG adapter registry.

# Install the conformance runner
npm install -g @forg-pro/adapter-conformance

# Run against your adapter's emit endpoint
forg-conformance --adapter-id my-tool-forg --endpoint http://localhost:6247

Full test suite source: github.com/forgpro/adapter-protocol/conformance

© 2026 UpgradIQ, Inc.Edit this page on GitHub