v0.6.0 - 2026-07-06
One-command capture and an intent-conformance layer. agentprov launch -- <agent>
wraps any agent in a full provenance run with a single command, and the model-
intent layer moves from "which command did the model run" to contract-vs-effect:
what each action DECLARED it would do versus what the runtime ACTUALLY did, with
boundary violations, refusal bypasses, and honest coverage gaps as first-class
verdicts. The agent's real prompt and reasoning are harvested from the session
transcript with zero instrumentation.
Added
agentprov launch -- <agent>(internal/launch). One command does the
whole run: create a run scope, serve the live dashboard, inject a per-run
Claude Code hooks overlay via--settings(the user's~/.claudeis never
modified), start the kernel sensor when the host can (else degrade honestly),
exec the agent in a dedicated cgroup, then seal + sign the evidence graph and
print a one-line verdict. Evidence level is printed up front on two honest
axes — application side (hooks / transcript vs record-only) and system side
(kernel telemetry vs none). A hiddeninternalcommand group begins the
git-style porcelain/plumbing split.agentprov doctor -- <agent>launch preflight. The same readiness checks
launch prints can now run without starting the agent: agent binary, Claude
hook-injection compatibility, dashboard port availability, cgroup v2 scope
support, and kernel sensor capability. Warnings are explicit degradation
reasons rather than hidden failures;--jsongives install scripts a stable
machine-readable report.- Intent-Runtime Diff conformance engine (
internal/intent,
agentprov intent diff). Reconciles each captured IntentContract (a tool
call, peer message, or refusal, each declaring the effects it should and must
not produce) against the RuntimeEffects attributed to its scope. Verdicts:
declared_vs_effect_mismatch(a boundary violation, e.g. an install that read
a foreign secret),refused_but_runtime_happened,decided_and_executed, and
the honesty stateintent_coverage_gap(an effect it could not tie to captured
intent is a gap, never a fabricated finding). Effects are classified through
the existing policy engine (a foreign-secret read vs the agent's own creds),
and the finding is conditional on each action's declared contract — a network
connect is drift for a read-only tool but permitted for bash. Results feed a
newintent_conformancedimension in the unified signal model and flip the
launch verdict;peer_message_intent_mismatchmarks a violation whose intent
came from another agent's message. - Transcript harvest (
internal/provenance.HarvestTranscript). The Claude
Code session transcript (the JSONL a hook's stdin points at) is ingested into
the samellm_callgraph model TLS capture feeds — the model's real prompt,
reasoning, and tool decisions — with zero instrumentation and on any platform.
Renders through the existing agent-intent flow with no lens change. - Conformance ("Intent · declared vs actual") graph lens. Renders each
contract's scope → the diff verdict → the observed effects, colored by status,
alongside the delegation (主从) and peer (对等) agent structure.
Changed
- Agent-intent DAG collapses the caused fan-out. A model response that
causes hundreds of syscalls now aggregates into a single "caused N syscalls"
summary node above a threshold, so the prompt→decision→action spine stays
legible (individual syscalls remain in the process / security lenses). - Demos re-captured with
launch. The snake supply-chain and multi-agent
team bundles are freshly captured through the one-command flow; both now carry
the transcript (cognitive) axis and surface a real conformance mismatch — the
poisoned install's secret-read + metadata-egress is flagged as aninstall
operation exceeding its declared contract, attributed to the acting sub-agent.
LLM-intent provenance: the sensor now captures the agent's actual LLM traffic
as full TLS plaintext, reassembles and parses it, and materializes it into the
signed graph — so the DAG can answer "which model call caused this syscall,
and did the command that ran match what the model decided?" The agent-intent
lens is rebuilt as a causal DAG over real evidence nodes, and a new llm-judge
demo has an external LLM render an audited verdict over the full trajectory.
Added
- Full TLS body capture (
internal/sensor). The SSL_write/SSL_read uprobes
now emit the complete plaintext as ordered chunks keyed by TLS connection and
direction (previously hash + bounded metadata only). - TLS reassembly + LLM semantics (
internal/tlsintent). Userspace
accumulates the sensor's chunks into COMPLETE HTTP/1.1 messages
(Content-Length, chunked, and SSE streaming bodies; HTTP/2 is detected via
the client preface and passed through raw, never mis-parsed) and parses
minimal LLM semantics tolerant across Anthropic Messages / OpenAI Chat
Completions shapes: model, message count, system-prompt presence, tools
offered, tool calls + the shell commands the model decided to run, stop
reason. Platform-neutral (no eBPF deps), unit-tested off-Linux. - LLM calls in the signed graph (
graph materialize-llm,
internal/provenance.MaterializeLLMCalls). Each captured body is
objectified as a content-addressedllm_message; each request/response pair
becomes a first-classllm_callnode withllm_request/llm_response/
llm_bodyedges. Idempotent; covered bygraph verifyand
scripts/accept_llm_intent_causality.sh. llm_causedscoped to the decided command. The causality edge from an
llm_callto a syscall is drawn only when the executed command matches a
tool_commandfrom the model's response — not to everything that happened
after the call — so "the model told it to" stays narrow and defensible. The
legacy ingest-timellm_intent_causededge is no longer rendered
(superseded by the materializedllm_caused).- Agent-intent lens is now a causal DAG. The stage-card renderer is
dropped; the view is a DAG over real evidence nodes —llm_call→ decided
command → process → runtime events → risk — with blocked/refused intents
shown as first-class nodes, grouped by the agent that proposed them.
Run Overview tool-call / LLM-intent entries drill down into it. - Dashboard: LLM lifecycle spine + readability.
summaryshows only the
LLM lifecycle route when a captured model call exists (the send-msg step
tracks orchestrator delegation); readable execve labels; content previews on
tool_call/event nodes; sticky expand; node labels clipped inside their boxes. - llm-judge demo (
demo/llm-judge/judge.py, Stage 3). A single-file,
stdlib-only Python judge reads a captured run's FULL trajectory through the
generic contract surfaces (EvalContext, ai tools, graph lenses — no event-type
filter, chunked map-reduce past the context budget, coverage recorded),
has any Anthropic/OpenAI-protocol LLM produce a structured verdict
(agentprovenance.llm_judge/v1), and imports it back as graph-referenced
signals. The judge itself runs underrecordand its own LLM
requests/responses becomellm_callnodes in the judge's provenance run —
the judge is itself audited. Degrades to a keyless offline fixture. - Real LLM intent in the demo bundles (
demo/shared/llm-intent-curl.sh).
Both capture harnesses fire one real model/tool-intent request via
curl/OpenSSL (secrets stay in headers, never in the script or body), so the
recaptured, re-signed Stage 1/2 bundles now carry the model call that
decided the poisoned install —llm_call→llm_caused→ the exact syscall.
Changed
- README narrative: evidence layers, not integration modes. The
"White-box mode / Zero-SDK mode" split is gone: one entry point
(record -- <cmd>), kernel/runtime facts as the foundation, application
context (hooks bridge / MCP context-write,ai_asserted≤0.5) as an
automatically stacking enrichment layer. "SDK/framework integration"
phrasing removed throughout;docs/product.mdaligned. - README slimmed into docs/ references. Full command references moved to
docs/security-commands.md,docs/graph-commands.md, and
docs/compliance.md; the Python custom-rules content merged into the
External Evaluator Protocol section (one topic, told once). - Falco receiver demoted to a compatibility path. The README section moved
todocs/falco-receiver.md; the native eBPF sensor is the featured
kernel-evidence source, and third-party receivers (Falco/Tetragon) are
maintained for compatibility, not extended.
Fixed
graph explainno longer crashes on large scopes. Telemetry batches are
matched against event ids in Go instead of one SQLLIKEclause per event,
which overflowed SQLite's expression-depth limit (~1000 events) and crashed
--attempt/--tool-call/--process/--file.- Deterministic DAG rendering. Every
created_atordering feeding the
causality DAG gained an id tiebreaker, lens summary builders iterate in
(created_at, node id)order, and/api/graphnode output is sorted — BFS
order,page_hash, evidence_refs, and the 32-item lens truncations are now
byte-stable across renders and survive re-materialize (verified 3× on both
demo bundles). - Hooks bridge: sub-agent identity. Sub-agents spawned via the Agent tool
now resolve their name from the tool'snamefield instead of falling back
to a generic id. - perf: graph edges indexed by
(run_id, created_at, id); lens metadata cached.