hooksbridge

package
v0.7.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 9, 2026 License: Apache-2.0 Imports: 16 Imported by: 0

Documentation

Overview

Package hooksbridge translates a Claude Code (or compatible) harness hook log into AgentProvenance's graph: agent nodes, delegation spawn edges, peer (peer) message edges carrying the message body as objectified evidence, and a tool_call per agent tool invocation bound to the acting agent_id. Each proposed tool call is pre-flighted through the trusted policy engine so an obviously unsafe proposal (e.g. an SSRF to the metadata IP, or a credential read) lands as a status=denied "refused" node -- the app-side half of the blame chain the kernel sensor later confirms.

Trust boundary: everything the bridge writes is APP-ASSERTED context derived from the harness's own hooks (binding_source=hooks). It records no system events and forges no signatures; the deny verdict on a refused node is computed by the trusted engine, not by the model. The kernel sensor remains the ground truth that a syscall actually happened; the bridge only says which agent intended it.

Index

Constants

View Source
const (
	EdgeAgentSpawn    = "agent_spawn"     // delegation: parent/main -> sub-agent (delegation)
	EdgeAgentMessage  = "agent_message"   // peer: sender -> body-object -> recipient (peer influence)
	EdgeAgentToolCall = "agent_tool_call" // agent -> the tool_call it invoked
	EdgeAgentSyscall  = "agent_syscall"   // tool_call -> the kernel event it caused (command-match join)
)

Edge types the bridge emits (all app-asserted orchestration structure).

Variables

This section is empty.

Functions

func AdaptHarness added in v0.7.1

func AdaptHarness(harness string, r io.Reader) (io.Reader, error)

AdaptHarness wraps a harness-specific session transcript in a reader of the normalized hook-JSONL events Ingest consumes, so a non-Claude-Code harness is captured by translating its OWN session record — no per-harness bespoke bridge. harness "" / "claude" is a passthrough (the events are already normalized).

func AdaptKimiSession added in v0.7.1

func AdaptKimiSession(sessionDir string) (io.Reader, error)

AdaptKimiSession walks a Kimi session directory (…/session_<id>/) and its per-agent wire.jsonl files into one normalized hook stream. The main agent's `Agent` tool call is the delegation dispatch (Kimi reuses Claude Code's tool name), and each agents/<sub>/ becomes a SubagentStart + its own tool calls — so the existing bridge draws the same delegation graph as Claude Code.

func CorrelateSyscalls

func CorrelateSyscalls(db *sql.DB, runID string) (int, error)

CorrelateSyscalls attributes kernel syscall events to the acting sub-agent. In-process agents share ONE cgroup, so the sensor cannot split them; the join is COMMAND-MATCH -- the sensor's execve command against an agent tool_call's command -- then propagation to the high-risk events (secret_path, metadata_ip, ...) that ran in the SAME pid. This turns "some process in the run read the secret" into "bob's install tool_call read the secret", completing the blame chain agent -> tool_call -> syscall. Returns the number of links written.

Types

type Options

type Options struct {
	RunID string
	// Engine pre-flights each proposed tool call. Zero value -> DefaultEngine.
	Engine security.Engine
	// Objects stores message bodies as content-addressed evidence objects.
	Objects provenance.ObjectStore
	// Base is the fallback clock: events without a stamped `ts` are ordered
	// monotonically from Base (hook stdin carries no timestamp). Zero -> a fixed
	// epoch so synthetic runs are deterministic.
	Base time.Time
}

Options configures an ingest.

type Summary

type Summary struct {
	Agents       int `json:"agents"`
	ToolCalls    int `json:"tool_calls"`
	Refused      int `json:"refused"`
	SpawnEdges   int `json:"spawn_edges"`
	MessageEdges int `json:"message_edges"`
	Lines        int `json:"lines"`
}

Summary reports what an ingest wrote.

func Ingest

func Ingest(db *sql.DB, r io.Reader, opts Options) (Summary, error)

Ingest reads a hook JSONL stream and writes the orchestration graph for RunID. Prior bridge-written rows for the run are cleared first so re-ingest is clean; it never touches record/sensor rows (only rows with agent_id / agent_* edges).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL