Exclusion Reasons

Overview

Every item considered by the pipeline receives either an inclusion reason or an exclusion reason. These reasons form the explainability core of the diagnostics system — they answer “why was this item included or excluded?” Reasons are attached to items in the SelectionReport, where each IncludedItem carries an InclusionReason and each ExcludedItem carries an ExclusionReason.

ExclusionReason

ExclusionReason describes why the pipeline did not select an item for the context window. Each variant is data-carrying: it includes associated fields that provide context for the exclusion decision. This is a deliberate design choice — data-carrying variants enable callers to programmatically inspect exclusion details without parsing message strings.

Rejected alternative: fieldless enum variants — simpler wire format, but forces callers to reconstruct context from other diagnostic data, which is fragile and error-prone.

VariantDescriptionFieldsEmitted byStatus
BudgetExceededItem did not fit within the token budgetitem_tokens: integer, available_tokens: integerSlice stage, Place stage (Truncate)Active
ScoredTooLowItem scored below the selection thresholdscore: float64, threshold: float64Reserved
DeduplicatedByte-exact content duplicate removeddeduplicated_against: string (content identifier)Deduplicate stageActive
QuotaCapExceededKind exceeded its quota capkind: string, cap: integer, actual: integerReserved
QuotaRequireDisplacedDisplaced to satisfy another kind’s quota requirementdisplaced_by_kind: stringReserved
NegativeTokensItem has a negative token counttokens: integerClassify stageActive
PinnedOverrideDisplaced by a pinned item during truncation overflow handlingdisplaced_by: string (content identifier)Place stage (Truncate)Active
FilteredExcluded by a user-defined filter predicatefilter_name: stringReserved

Reserved variants are defined but not emitted by any built-in pipeline stage. They are reserved for future specification versions and custom stage implementations. Implementations must include these variants in their type definitions to ensure forward compatibility.

Rationale: defining reserved variants now ensures that implementations allocate space in their type system for future extensions, avoiding breaking changes when these variants become active.

JSON example — BudgetExceeded:

{
  "reason": "BudgetExceeded",
  "item_tokens": 2048,
  "available_tokens": 512
}

JSON example — Deduplicated:

{
  "reason": "Deduplicated",
  "deduplicated_against": "tool_output_abc123"
}

JSON example — NegativeTokens:

{
  "reason": "NegativeTokens",
  "tokens": -1
}

Reserved variant examples:

JSON example — ScoredTooLow:

{
  "reason": "ScoredTooLow",
  "score": 0.12,
  "threshold": 0.25
}

JSON example — QuotaCapExceeded:

{
  "reason": "QuotaCapExceeded",
  "kind": "ToolOutput",
  "cap": 3,
  "actual": 4
}

JSON example — QuotaRequireDisplaced:

{
  "reason": "QuotaRequireDisplaced",
  "displaced_by_kind": "SystemPrompt"
}

JSON example — Filtered:

{
  "reason": "Filtered",
  "filter_name": "max_age_filter"
}

Wire format: the reason field is a string discriminator. Variant-specific fields appear as sibling fields alongside reason. Fields that belong to other variants are omitted — absent fields are never represented as nulls. Both ExclusionReason and InclusionReason use this same envelope format: { "reason": "<VariantName>", ...fields }. For InclusionReason, which carries no fields, the envelope contains only the reason discriminator.

InclusionReason

InclusionReason describes why the pipeline selected an item for the context window. Inclusion reasons are not data-carrying — they carry no additional fields beyond the variant name. The score itself (carried on IncludedItem) provides the quantitative detail.

Rationale: inclusion reasons are simple status indicators. Data-carrying variants would add complexity without diagnostic value.

VariantDescriptionEmitted by
ScoredIncluded based on computed score within budgetPlace stage
PinnedBypassed scoring and slicing due to pinned statusPlace stage
ZeroTokenIncluded at no budget cost (zero-token item)Place stage

JSON example:

{
  "reason": "Scored"
}

Conformance Notes

  • Implementations MUST define all 8 ExclusionReason variants, including reserved variants, to ensure forward compatibility.
  • Implementations MUST handle unknown ExclusionReason variants gracefully when deserializing diagnostic data from other implementations or future specification versions.
  • The reason field in the JSON wire format MUST be the string name of the variant (e.g., "BudgetExceeded", not an integer code).
  • Data-carrying fields MUST be present when the variant is emitted. For example, BudgetExceeded MUST include both item_tokens and available_tokens.
  • Reserved variants MUST NOT be emitted by built-in pipeline stages. Custom stage implementations may emit reserved variants.