Sessions & path-aware policy
Most governance tools evaluate each call in isolation. TapPass also evaluates the path: the ordered history of what this agent has already done in this session. The same action can be allowed at minute one and blocked at minute ten, because of what came before it.
What a session accumulates
Section titled “What a session accumulates”Every governed call, including blocked attempts, is appended to the session’s path after the decision. The tracker keeps, per session:
- the ordered event list (behavior type, resource, timestamp), and
- aggregates:
count_by_type,unique_resources,total_events, first/last timestamps.
A session is identified by session_id; when the caller doesn’t supply one, the server pins one per (org, agent).
What policy sees
Section titled “What policy sees”Three projections land in the policy input:
{ "state": { "session": { "event_count": 17, "unique_resources": 4 }, "path": { "tools": ["read_file", "query_db", "read_file"], "last": { "type": "TOOL_CALL", "resource": "read_file" } } }, "path": { // opt-in: full projection "session_id": "ses_…", "events": [ /* capped at a fixed window */ ], "aggregates": { /* counts, uniques, timestamps */ } }}state.session, always available.state.path.tools, the ordered prior tool trajectory; read by sequence and rate rules.state.path.last, the immediate predecessor event (type + resource), regardless of type. Freshness rules key on it: “the gate must be the step directly before this one,” not “a gate exists somewhere in history.”path, the full event projection, available when opt-in path projection is enabled for your org. Rules that read it (e.g. therate_limit_tool_per_sessiontemplate) require it.
If the path store is unavailable, state.session becomes {"unavailable": true} and path facts are absent, policy can treat “history unknown” as a reason to refuse, keeping the system fail-closed.
What path-aware rules look like
Section titled “What path-aware rules look like”Concrete rules you can express today with built-in kinds:
| Intent | Rule kind | Reads |
|---|---|---|
| No more than N calls to tool T per minute | PerToolRateLimit |
state.tool_rate |
| Cap session spend at $X | MaxSpend |
state.spend |
| Cap tokens per day | MaxTokensPerDay |
state.tokens_used_today |
| Forbid tool B after tool A ran | BlockToolSequence |
state.path.tools |
| Max calls per session overall | SessionRateLimit |
state.session |
| Flag anomalous tool args vs learned baseline | ToolArgOutlier |
findings.tool_baseline |
BlockToolSequence is the taint primitive: “once read_secrets appears in the trajectory, block http_post for the rest of the session.” Taint is permanent within the session because the trajectory only grows.
Why it matters
Section titled “Why it matters”Single-call rules can’t express the attacks and failures that actually hurt agents:
- Data-leak chains, read a secret file, then exfiltrate. Neither call is bad alone.
- Runaway loops, the 40th identical
query_dbcall in a session. - Scope creep, an agent that touches one customer record is fine; one that touches thirty in a session needs approval.
Path-aware policy is what turns an audit trail into a control plane.
Next steps
Section titled “Next steps”- Rule reference, the trajectory and usage rule kinds
- The audit trail, how sessions are recorded and queried