Provider-private pa1 prompt builder for Anthropic Messages requests.
pa1 mirrors the px3 prompt contract in doctrine, not bytes. Layer 0 is a byte-stable system text block selected by mode, Layer 1 is the deterministic Skills index when present, and volatile late context is inserted as the leading text content block of the latest user message because Anthropic has no developer role on the target model.
cache_control planning is fixed for pa1:
- B1 is placed on the last system block.
- B2 is placed on the content block at
prev_turn_boundary, using a 1-based count over message content blocks after any late-context insertion. If that block is not cacheable, B2 walks backward to the nearest cacheable block at a lower position and is omitted when none exists. - B3 is placed only when more than 15 content blocks exist between the prior message breakpoint position, or B1 when B2 is absent, and the latest user message. When triggered, B3 targets the last content block before the latest user message, then walks backward to the nearest cacheable block at or before that target and is omitted when none exists or when it collides with B2.
Verified Anthropic prompt-caching documentation on 2026-07-08 says thinking, redacted_thinking, and empty text blocks cannot be marked directly with cache_control; pa1 treats those blocks as non-cacheable.
pa1 never emits more than three breakpoints. The fourth Anthropic breakpoint is reserved by ADR 0037 and adding a planned use for it requires a pa1 to pa2 prompt contract bump. Any future layout or fence-token change is also a pa1 to pa2 bump.
Summary
Functions
Build Anthropic-native system and messages with the pa1 cache plan.
The pa1 prompt contract label, mirrored into neutral cache metadata (ADR 0037 D7).
Types
@type input() :: %{ mode: :build | :plan, skills_index: String.t() | nil, messages: [map()], late_context: String.t() | nil, prev_turn_boundary: non_neg_integer() | nil }