Observability

How an ArmorEdu agent's tool calls and policy decisions appear as traces in ArmorIQ observability.

ArmorEdu doesn't ship its own observability bridge. An education agent's telemetry comes entirely from whichever ArmorIQ SDK it's integrated with (the same TypeScript or Python SDK used in Getting Started), so what you see in the dashboard is the shared SDK trace model (OpenTelemetry spans), not an ArmorEdu-specific view.

What a turn records

Session
└── Trace (armoriq.agent.run)
    ├── armoriq.intent.plan
    ├── armoriq.policy.evaluate   (allow / hold / block)
    ├── gen_ai.chat               (model call)
    └── armoriq.tool              (tool execution, with error.type on failure)

Each capture_plan → get_intent_token → invoke cycle from Getting Started adds a plan to the session trace. The policy check against your ArmorEdu policy is recorded as an armoriq.policy.evaluate span: its armoriq.policy.decision attribute shows the decision, and armoriq.policy.enforcement_action shows the enforcement action your policy resolved for that tool. So a call to export_student_records that your course bundle blocks appears as a policy span with a block decision; a call to create_privileged_account that your OIT bundle holds appears as a span reflecting the hold, correlated with the plan that's now waiting in approvals.

Additive and fail-open

Observability is telemetry, not an enforcement dependency. If the SDK's trace export destination is unreachable or a span fails to record, the policy decision your agent already received is unaffected: a blocked share_dataset_external call stays blocked whether or not the trace for it ever ships. See the SDK observability reference for the shared export behavior, and observability overview for the full producer and freshness model.

When traces appear

Spans are sent in batches and the last ones are sent when the session closes, rather than streamed live, and the dashboard itself polls every 30 seconds. A tool call your agent just made (an allowed get_grade_distribution, a held submit_grant_proposal) can therefore complete before its trace is visible. This is normal SDK behavior, not something specific to education agents.

What's not captured

The domain control blocks (ferpaAccessControl, researchDataControl, privilegedAccessControl, and the rest) shape what a policy decides, but they aren't separately recorded as their own span type: the resulting allow / hold / block decision on the policy span is what you see, along with the enforcement action and reason. There's no per-control-block audit trail beyond the policy decision itself in the current observability model.

Tool inputs and outputs can appear on tool-execution spans. By default ArmorIQ stores metadata only, and it stores tool inputs and outputs only if your organization chooses Enhanced or Debug capture and allows content. Redaction is pattern based and cannot catch every student record, grant detail, or account value. See What data is captured. Restrict dashboard access to appropriate organization members and avoid sending anything you would not want retained in telemetry.

Next steps

On this page