Signed decision evidence for Haystack Agents.
Connect LoopGrid through Haystack's native tracing and Agent hooks. Haystack keeps running agents, confirmation controls and tools; your application owns authority, policy, authenticated reviewer identity and the real downstream outcome; LoopGrid preserves and independently verifies the evidence.
loopgrid-haystack v0.1.0 · validated with haystack-ai 3.3.0 · Python 3.10–3.14 · LoopGrid Core 0.8.1-design-partner.
Confirmation controls; tracing observes. Haystack owns the Agent and tool-control runtime. LoopGrid records evidence at native boundaries without inventing authority, reviewer identity or business outcome.
Install the native Haystack integration.
pip install loopgrid-haystack
Version 0.1.0 is public on PyPI. The package targets haystack-ai 3.3.x, depends on loopgrid 0.8.x, and supports Python 3.10 or newer.
Bind one consequential decision to one Haystack Agent run.
from haystack.components.agents import Agent
from haystack.dataclasses import ChatMessage
from loopgrid_haystack import LoopGridHaystack
loopgrid = LoopGridHaystack(
base_url="http://127.0.0.1:8000",
workspace_id="default",
agent_id="support-agent",
)
loopgrid.enable_tracing()
decision = loopgrid.start_decision(
decision_type="customer_refund",
agent={"id": "support-agent", "version": "1"},
authority={"acting_for": "Example Store", "scope": ["refund:create"], "limit_usd": 100},
model={"provider": "openai", "name": "gpt-5"},
context={"prompt_version": "support-v1"},
proposed_action={"tool": "refund.create", "amount": 25, "currency": "USD"},
policy={"policy_id": "refund-policy", "version": "1", "decision": "auto_allowed"},
)
agent = Agent(
chat_generator=...,
tools=[...],
hooks=loopgrid.agent_hooks(decision["decision_id"]),
)
result = agent.run(messages=[ChatMessage.from_user("Handle this duplicate charge.")])
loopgrid.flush()
loopgrid.assert_healthy()
# Only after the application observes the authoritative downstream result:
loopgrid.record_outcome(
decision["decision_id"],
{"status": "succeeded", "external_reference": "refund_123"},
observer="billing-webhook",
)Decision correlation is explicit and request-scoped. Constructing LoopGridHaystack does not change Haystack tracing automatically; enable_tracing() is an explicit application choice.
Use Haystack tracing for model evidence and Agent hooks for the tool boundary.
start_decision() records explicit agent identity, delegated authority, model/context provenance and the proposed consequential action.
The native Tracer / Span integration maps completion of haystack.agent.step.llm into model_completed evidence.
LoopGrid's Agent before_tool hook records tool_requested only after earlier confirmation/modification hooks have allowed a surviving call through.
The Agent after_tool hook records tool_executed after Haystack-owned execution returns; it does not infer the authoritative business outcome.
record_human_review() records an application-authenticated reviewer and explicit approval/rejection when supplied by the application.
record_outcome() appends the authoritative downstream outcome after the application actually observes it.
Keep Haystack ConfirmationHook native — and record only the call that survives it.
ConfirmationHook / other before_tool control → reject: no tool_requested evidence → modify: surviving arguments continue → approve: surviving call continues application authenticates reviewer → loopgrid.record_human_review(...) → human_approved LoopGrid before_tool → tool_requested → actual Haystack tool executes LoopGrid after_tool → tool_executed application observes downstream result → loopgrid.record_outcome(...) → outcome_observed → evidence_complete → verify valid:true
Pass confirmation/modification hooks through before_tool_prefix. LoopGrid appends its request hook after them, so a rejected call cannot become tool_requested evidence and a modified call is recorded with the final parameters that survive confirmation. Reviewer identity is never inferred merely because a tool executed.
Commit to content without storing it by default.
capture_content=False by default. Model span tags and tool inputs/outputs are represented with SHA-256 commitments rather than raw content unless capture is explicitly enabled.Framework callbacks queue transport work so evidence delivery does not raise into the Haystack Agent execution path. Call flush() and assert_healthy() when delivery must be confirmed. Explicit human-review and outcome writes drain earlier queued evidence first, preserving lifecycle order under slower transport. If another Haystack tracing backend is required, pass a concrete tracer instance explicitly as the delegate; do not feed the process-level tracing facade back into LoopGrid.
Validated through the real Haystack Agent runtime, native confirmation paths and LoopGrid Core.
haystack-ai 3.3.0evidence_completevalid: true with no failuresloopgrid-haystack==0.1.0 clean-installed from PyPI with public import and dependency validationv0.1.0; PyPI Trusted Publishing via GitHub OIDCThe release E2Es use deterministic Haystack test components and sandbox-only refund functions, so no real-money movement is required. Verification establishes the integrity/provenance of captured evidence; it does not prove that the underlying decision was correct, that every upstream statement was true, that capture was complete, or that the system is legally compliant.
Keep Haystack native. Make the evidence portable.
Install the PyPI package, bind native tracing and Agent hooks, and preserve consequential-agent evidence without replacing the Haystack runtime.