Troubleshooting
Diagnose an ArmorEdu agent that isn't matched by policy, a tool that's unexpectedly blocked, a missing hold, or missing telemetry.
Most ArmorEdu issues trace back to one of four things: the policy's targetId doesn't match the calling agent, a tool name doesn't match what the agent actually sends, a hold isn't where you're looking for it, or the SDK telemetry hasn't shipped yet. Work through the relevant section below before assuming the policy engine itself is wrong.
Agent not matched by policy
Symptom: every tool call the agent makes is allowed (or falls through to a fail-closed block), regardless of what the bundle's allowedTools and toolEnforcement say, as if the policy isn't being evaluated at all.
A policy with targetType: agent only applies to the exact targetId named in its metadata. Check, in order:
- The bundle still has its demo
targetId. All three starter bundles ship with a placeholder UUID for the demo agent they were written against. If you imported a bundle without editingmetadata.targetId, it is not targeting your agent. See Policy Studio. - The agent is registered. The agent must exist in your organization's agent registry before a policy can target it. Register it under Agents in the dashboard, or during SDK bootstrap. See Getting Started.
- The SDK's
agent_idresolves to the same ID. The agent ID your SDK client is configured with must resolve to the same agent the policy'stargetIdnames. A free-form name that doesn't match the registered agent record won't scope the policy correctly. - The policy is
active, notdraftorinactive. Adraftpolicy is saved but not evaluated against live traffic; onlyactive(and, for dry-run comparison,shadow) policies affect real decisions. See Policy Studio. - No higher-priority policy is intercepting first. If more than one policy targets the same agent, they're evaluated in priority order: a higher-priority policy's matching rule wins before your ArmorEdu bundle is reached.
A tool is unexpectedly blocked (or unexpectedly allowed)
Symptom: a tool call resolves to a different enforcement action than the bundle's YAML seems to specify.
Enforcement resolves specific-to-general, and this order matters:
toolEnforcement[toolName] → rule's own enforcementAction → policy.defaultEnforcementAction → block (fail-closed)Check, in order:
- Is the tool name an exact match?
toolEnforcementkeys andallowedToolsentries must match the tool name the agent actually calls, character for character. A typo, a different casing, or a renamed tool silently falls through to the default action instead of the override you expected: it will not raise an error telling you the key didn't match anything. - Is the tool even in
allowedTools? A tool absent fromallowedToolsdoesn't get atoolEnforcementoverride at all; it resolves through the rule's action or the policy default, which isallow_login all three starter bundles. - Is
defaultEnforcementActionwhat you expect? All three bundles ship withdefaultEnforcementAction: allow_log. If you changed it toblockwhile testing, every tool not explicitly set toalloworallow_logintoolEnforcementwill now block. - Is another policy on the same agent taking priority? Two active policies targeting the same agent are resolved in priority order; a higher-priority policy's rule can override what your ArmorEdu bundle specifies for the same tool.
A hold isn't appearing in approvals
Symptom: you triggered an action a bundle should hold (publish_final_grades, submit_grant_proposal above the configured amount, create_privileged_account), but nothing shows up for an approver to act on.
- Confirm the tool actually resolved to
hold. Work through the tool-enforcement checks above first: if the call resolved toallow_loginstead ofhold, it completed immediately and there is nothing to approve. - Check the threshold, for amount-based holds.
grantControl.holdAboveAmountonly holds proposals above the configured amount (100000in the research bundle's default). A proposal at or under the threshold is allowed, not held. - Check the plans queue, not the dashboard's summary view. A held call becomes a plan in the
heldstate in Plans, and the aggregate dashboard metrics can lag behind an individual plan's current status. - Check plan status computation. Plan status is computed at read time; a plan you expect to see as
heldcan already showapproved,rejected, orexpireddepending on what happened to its delegation. See Dashboard.
Telemetry isn't showing up
Symptom: the agent's tool calls and policy decisions ran correctly, but no trace appears in observability.
ArmorEdu has no dedicated telemetry bridge: this is ordinary SDK observability, so the general SDK checks apply:
- Is an API key configured, and is observability enabled? The SDK session must have a valid API key and must not have
enabled: falseset on its observability configuration. - Has the trace actually ended? In-flight (not-yet-ended) traces are retained in memory and are not shipped as completed batches. Call
flushObservability()/flush_observability(), or make sure your integration properly ends the plan trace, rather than leaving it open indefinitely. - Wait for the flush and poll interval. SDK shippers flush on a 5-second interval by default, and the dashboard itself polls every 30 seconds, so a completed tool call can be correct before its trace is visible.
- Confirm the dashboard and API key point at the same organization. Telemetry is scoped to the organization tied to the API key; an org mismatch produces an empty view even though the agent's operations succeeded.
See Observability for what a normal trace looks like, and the SDK observability troubleshooting reference for the full diagnostic path, safe debugging practices, and what not to log.