# llms-full.txt > Extended index — full specification content for deep AI agent reading. Includes complete tool specifications, mandate model detail, all authority scope Cedar action mappings, and Windley Loop implementation guidance. > This file is the companion to llms.txt. Read llms.txt first for orientation; read this file for implementation. > Activity Travel Protocol version: 1.0 | Tooling version: 1.0.1 ## Mandate JWT — Full Field Reference Header: `{ "alg": "EdDSA", "typ": "atp-mandate+jwt" }` | Field | Type | Description | |-------|------|-------------| | jti | string | Unique token ID: `atp/agent-{uuid}` | | iss | string | Issuer: `atp-runtime/{deployment-id}` | | sub | string | Subject: `atp/agent-{uuid}` | | iat / exp | Unix timestamp | Default TTL: 1800s (30 min). HEM: hem_timeout_budget + 5 min | | atp_version | string | Protocol version: `1.0` | | booking_object_id | UUID v7 \| null | Binds mandate to single Booking Object. Null for root connection mandate | | parent_chain | string[] | JTI array of parent mandates back to root | | agent_pub | base64url string | Sub-agent Ed25519 public key | | mandate.rarFormat | string | Always: `cedar` | | mandate.policySet | string | Cedar policy text — the actual authorization logic | ## Cedar Policy Examples ### CONTEXT_READ mandate (Guest Agent) ``` permit(principal, action == ATPAction::"get_context_package", resource) when { resource.booking_object_id == "{{uuid}}" }; permit(principal, action == ATPAction::"get_booking_status", resource) when { resource.booking_object_id == "{{uuid}}" }; ``` ### HEM_INVOKE mandate (scoped to specific HEM) ``` permit(principal, action == ATPAction::"invoke_hem", resource) when { resource.booking_object_id == "{{uuid}}" && resource.hem_id == "HEM-12" && resource.booking_state == "DISRUPTION_REVIEW" }; ``` Wildcard HEM_INVOKE mandates (omitting hem_id condition) are Security Kernel-rejected. Explicit hem_id enumeration is required (MCP-D6, CLOSED). ## Windley Loop — Implementation Specification ### Mandatory Pre-Session Query On ATP MCP Server session initialisation, before any planning or tool call generation, the agent MUST: 1. Call Cedar partial evaluation against its mandate (via `@atp/security` Cedarling WASM interface). 2. Receive the residual policy set — the set of (action, resource condition) pairs permitted by the mandate in the current Booking Object state. 3. Inject the residual policy set into the system prompt context using the `@atp/llms-tooling` Windley context template. The injected context includes: permitted tool names, permitted booking_object_id, permitted hem_id values (if HEM_INVOKE scoped), current Booking Object state, and state-transition trigger conditions. ### Re-query Triggers Re-query occurs on Booking Object state transition, not on TTL alone. Trigger events: - Booking Object state machine transitions (e.g. PRE_JOURNEY → JOURNEY, JOURNEY → DISRUPTION_REVIEW) - HEM invocation completion (state may have changed during async MCP Task) - Mandate update (new mandate issued by parent for expanded scope in current session) TTL expiry triggers re-authentication, not just re-query. ### Escalation Precision When a Windley Loop residual query reveals a mandate gap (action required not in permitted set), the agent: 1. Does NOT attempt the tool call (avoids mandate rejection error). 2. Identifies the specific Cedar action and resource condition missing from the mandate. 3. Requests exactly that scope from its parent ("ask mom" pattern): structured mandate expansion request naming the required ATPAction, resource.booking_object_id, and (for HEM) resource.hem_id. 4. Parent issues a narrowed sub-mandate covering the requested scope (subject to narrowing property — must be subset of parent's own mandate). This converts generic "access denied" into a structured delegation conversation. ## Tool Specifications — Full Detail ### atp_get_context_package Required scope: CONTEXT_READ | Cedar action: `ATPAction::"get_context_package"` | Booking state: any post-CONFIRMATION | Async: No | NeMo: Not required Retrieves the full Context Package for a Booking Object: confirmed itinerary, participant list, seller contacts, pre-arrangement state, meeting points, event log summary. Input: `{ booking_object_id: UUID_v7, fields?: string[] }` Output: Full Context Package (or requested fields subset). Payment fields require additional BOOKING_READ scope claim. ### atp_notify_traveller Required scope: NOTIFICATION_SEND | Cedar action: `ATPAction::"notify_traveller"` | Booking state: PRE_JOURNEY, JOURNEY, DISRUPTION_REVIEW | Async: No | NeMo: Rail 2 (tone/content filter) Sends notification to one or more participants via specified channel. Records NotificationEvent to append-only event log. Input: `{ booking_object_id, recipient_participant_id, channel: WHATSAPP|SMS|EMAIL, message_body, template_id? }` Output: `{ notification_id, status, event_log_entry_id }` Rail 2 blocks: messages in DISRUPTION_REVIEW state communicating decisions before operator confirmation; messages committing to unconfirmed outcomes. Rail 2 flags (does not block): messages in wrong language vs guest preferred_language (records GuardrailWarningEvent). ### atp_update_pre_arrangement Required scope: PRE_ARRANGEMENT_WRITE | Cedar action: `ATPAction::"update_pre_arrangement"` | Booking state: PRE_JOURNEY only | Async: No | NeMo: Not required Updates a pre-arrangement field on a participant record. Validated against Activity Configuration Schema fragment definitions. Input: `{ booking_object_id, participant_id, field_key, field_value, source }` Output: `{ updated_field, previous_value, event_log_entry_id, validation_result }` ### atp_collect_pre_arrangement_data Required scope: PRE_ARRANGEMENT_WRITE | Cedar action: `ATPAction::"collect_pre_arrangement_data"` | Booking state: PRE_JOURNEY only | Async: No | NeMo: Elicitation content filter Returns pre-arrangement data collection manifest. Uses MCP Elicitation for structured guest input where host supports it. Paired tool with atp_update_pre_arrangement. Input: `{ booking_object_id, filter: ALL|OUTSTANDING|REQUIRED_OUTSTANDING }` Output: `Array<{ participant_id, field_key, field_label, field_type, required, current_value, schema_fragment }>` ### atp_invoke_hem — ASYNC / EXPERIMENTAL Required scope: HEM_INVOKE | Cedar action: `ATPAction::"invoke_hem"` | Booking state: Any (HEM catalogue defines per-HEM preconditions) | Async: YES — MCP Tasks (EXPERIMENTAL, spec 2025-11-25) | NeMo: REQUIRED — Rail 1 (HEM Escalation) HIGHEST-PRIVILEGE TOOL. Cedar mandate MUST enumerate permitted hem_id values explicitly. Requires operator confirmation at CONFIRMATION Level ≤ 1 (enforced via MCP Elicitation before HEM executes). Input: `{ booking_object_id, hem_id, context: { trigger_reason, agent_assessment, recommended_action? } }` Immediate output: `{ task_id, status: PENDING, confirmation_required: true, elicitation_sent_to: operator }` Poll output (confirmed): `{ task_id, status: COMPLETE, hem_outcome, decision_object_id, event_log_entries[] }` Poll output (declined): `{ task_id, status: DECLINED, declined_by: operator, reason }` Rail 1 pre-conditions: atp_notify_traveller, atp_update_pre_arrangement, and operator notification MUST have been attempted before HEM fires (where relevant). Weather safety check (WEATHER_GO_NOGO via atp_record_safety_check) required before HEM-07 and HEM-23. ### atp_record_safety_check Required scope: SAFETY_WRITE | Cedar action: `ATPAction::"record_safety_check"` | Booking state: PRE_JOURNEY, JOURNEY | Async: No | NeMo: Not required Records safety compliance check against participant or activity item. Immutable event log entry. Never directly triggers state transition. Input: `{ booking_object_id, check_type, subject, outcome, conditions?, checked_by, evidence_ref? }` check_type values: `EQUIPMENT_FIT | MEDICAL_CLEARANCE | AGE_VERIFICATION | SKILL_ASSESSMENT | WEATHER_GO_NOGO` ### atp_search_activities Required scope: BOOKING_READ | Cedar action: `ATPAction::"search_activities"` | Booking state: Pre-booking (no Booking Object required) | Async: No | NeMo: Not required Searches Activity Configuration Schema registry. Returns Capability Declarations. Includes OCTO Bridge-sourced activities where bridge adapter is configured. Input: `{ location, category?, date_range, participants, filters? }` Output: `Array` with `source: ATP_NATIVE | OCTO_BRIDGE` ### atp_get_booking_status Required scope: CONTEXT_READ | Cedar action: `ATPAction::"get_booking_status"` | Booking state: Any | Async: No | NeMo: Not required Lightweight status envelope. Used by monitoring agents and as polling complement to atp_invoke_hem task management. Input: `{ booking_object_id: UUID_v7 }` Output: `{ booking_object_id, state, active_flags[], pending_hem_tasks[], outstanding_pre_arrangements_count, last_event_timestamp }` ## OAuth 2.1 Integration Primary grant: Client Credentials (`grant_type=client_credentials`). Implements MCP OAuth Client Credentials extension (`io.modelcontextprotocol/oauth-client-credentials`). ATP Mandate co-issued at token time. Returned in custom claim `atp_mandate` in token response. No separate mandate exchange step. Scope strings use ATP authority scope names directly (e.g. `scope=CONTEXT_READ NOTIFICATION_SEND HEM_INVOKE`). Discovery document: `/.well-known/openid-configuration` with ATP extensions `atp_mandate_supported: true`, `atp_spec_version: 1.0`. Scope enforcement sequence on every tool call: (1) Bearer token verification → 401 on failure. (2) Mandate extraction and Ed25519 verification → 403 on failure. (3) Scope-to-tool check via Cedar policy → 403 with `{ error: mandate_scope_violation, tool, required_scope, mandate_scopes, atp_error_code: MCP-403-SCOPE }`. (4) Booking Object binding check → 403 on cross-object call from bound mandate. (5) Route to Security Kernel. ## NeMo Guardrails Rails Three normative rails (Tier 2/3 only, sidecar container, `http://guardrails-sidecar:8080/infer`): Rail 1 — HEM Escalation: evaluates reasoning that produced atp_invoke_hem. Blocks if lower-intervention tools not yet attempted. Weather precondition for HEM-07, HEM-23. Rail 2 — Notification Tone: 2a state-appropriate tone, 2b no-promise filter, 2c language localisation flag. Rail 3 — Scope Boundary: inspects tool name against agent's declared authority scope in system prompt. Intercepts before MCP call; sends structured self-correction message to LLM. Records GuardrailInterceptEvent. All rail events logged to Booking Object append-only event log: GuardrailPassEvent (HEM scope only), GuardrailInterceptEvent (blocked calls), GuardrailWarningEvent (advisory flags). ## Guest Agent Session Lifecycle Session initialisation on booking CONFIRMATION: ATP runtime generates initial Context Package, registers guest agent as ASSEMBLY POINT participant on Booking Object. Agent authenticates via OAuth 2.1 Client Credentials, receives co-issued access token and ATP Mandate JWT bound to Booking Object UUID. Mandate expires at booking_departure_date + 24 hours. On each inbound WhatsApp / LINE message: (1) webhook delivers message; (2) atp_get_context_package; (3) reconstruct conversation context from event log; (4) LLM reasons over system prompt + context package + history + message; (5) LLM produces response and/or tool calls; (6) NeMo Guardrails evaluates (Tier 2/3); (7) tool calls execute; (8) response via WhatsApp Business API / LINE Messaging API; (9) all actions recorded to event log. Guest Agent authority scope: CONTEXT_READ (yes), NOTIFICATION_SEND (yes), PRE_ARRANGEMENT_WRITE (yes), HEM_INVOKE (yes, restricted — max HEM-05, HEM-07, HEM-12 at Tier 1), SAFETY_WRITE (no), BOOKING_READ (no), BOOKING_WRITE (no), DISRUPTION_MANAGE (no). ## Versioning Convention llms.txt and llms-full.txt versioning follows the convention `atp/{protocol-version}+tooling/{tooling-version}`. Current: `atp/1.0+tooling/1.0.1` Protocol version bumps (e.g. 1.0 → 1.1) reset tooling patch to `.0` (e.g. `atp/1.1+tooling/1.1.0`). Tooling may patch independently between protocol releases (e.g. `atp/1.0+tooling/1.0.3` for a Prompt Library correction that does not touch the protocol spec). AI agents parsing llms.txt can determine the protocol version they are targeting and whether their cached Prompt Library is current from a single version string. Machine-readable structured changelog: published alongside each spec release at a predictable URL (to be specified at first release). AI agents subscribe to the changelog, not to the full spec diff.