# Needle System Facts: How Temporal Context Controls Agent Validation

> Needle uses temporal facts like dates and years to validate agent outputs and data. Discover how this system controls agent behavior and ensures time context accuracy.

- Repository: [Cactus Compute, Inc./needle](https://github.com/cactus-compute/needle)
- Tags: deep-dive
- Published: 2026-09-10

---

**Needle recognizes temporal system facts (dates and years) from an optional system string and uses them to validate that tool outputs and extracted data conform to the provided time context, with strict mode raising errors for temporal contradictions.**

Needle, an open-source structured extraction framework from cactus-compute, accepts an optional system string during agent initialization to establish operational facts. These system facts enable temporal grounding capabilities that prevent language models from returning dates contradicting the supplied context. Understanding how Needle parses and enforces these constraints is essential for building reliable extraction pipelines that maintain consistency with known temporal realities.

## What System Facts Does Needle Recognize?

Currently, Needle exclusively recognizes **temporal system facts**—specifically years and dates extracted from the system string. When creating a Needle agent, you provide these facts via the `system` parameter:

```python
from needle import Needle

agent = Needle(
    tools=[InvoiceTool],
    system="date: 2026-07-21 Tue 14:30"
)

```

The Python implementation in [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py) parses this string (lines 778-791) using pattern matching to identify year-like values. While the raw system string is also forwarded unchanged to the native C library via `lib.needle_init` in [`needle/_worker.py`](https://github.com/cactus-compute/needle/blob/main/needle/_worker.py), the Python layer specifically extracts temporal data to enforce validation rules.

## How System Facts Influence Agent Behavior

System facts drive a multi-stage validation pipeline that governs tool outputs and extraction results.

### Extracting and Licensing Temporal Data

The foundation of temporal control rests on two internal methods in [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py):

- **`_source_years`** (lines 778-791): Scans arbitrary text (including the system string) for year patterns using regular expressions
- **`_licensed_years`** (lines 944-998): Merges years found in user input with those extracted from the system context, creating an authoritative set of valid temporal boundaries

This licensed year set establishes the temporal boundaries within which all model outputs must operate.

### Temporal Grounding Against Tool Schemas

When processing tool outputs, Needle applies **`_temporal_grounding`** to validate date fields. This method (lines 332-346) traverses tool schemas using **`_walk_grounding`**, inspecting fields marked with JSON Schema formats `"date"` or `"date-time"`.

If a returned date falls outside the licensed years extracted from system facts, Needle marks the corresponding path as a grounding failure. This prevents the agent from accepting anachronistic or temporally inconsistent values.

### Validation Enforcement and Response Annotation

After the native engine generates a response, **`_annotate_ungrounded`** (lines 446-666) reviews the extraction results. For any values violating temporal constraints, it injects a validation entry:

```python
{"validation": {"ungrounded": ["Invoice.date"]}}

```

In **strict mode** (the default for `agent.extract()`), **`_validate_extraction`** (lines 668-680) raises an **`ExtractionValidationError`** when grounding failures exist. Non-strict mode allows the operation to complete while preserving failure metadata in the response.

## Practical Implementation of System Facts

The following example demonstrates how system facts trigger validation errors when extraction contradicts the established temporal context:

```python
from needle import Needle, ExtractionValidationError

# Initialize agent with 2026 system context

agent = Needle(
    tools=[Invoice],
    system="date: 2026-07-21 Tue 14:30"
)

# Strict extraction fails on temporal contradiction

try:
    result = agent.extract(
        text="Invoice issued on 2025-12-01.",
        schema=Invoice,
        strict=True  # Raises on ungrounded values

    )
except ExtractionValidationError as e:
    print("Temporal validation failed:", e)

# Non-strict mode captures violations without raising

response = agent.run(
    query="When was the invoice issued?",
    strict=False
)
print(response.get("validation"))

# Output: {'ungrounded': ['Invoice.date']}

```

## Summary

- Needle recognizes **temporal system facts** (years and dates) parsed from the optional system initialization string used when constructing the `Needle` class
- The **`_source_years`** and **`_licensed_years`** methods in [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py) extract and combine temporal boundaries from system context and user input (lines 778-791 and 944-998)
- **`_temporal_grounding`** validates tool outputs against licensed years, checking fields with `"date"` or `"date-time"` formats (lines 332-346)
- Violations appear in **`response["validation"]["ungrounded"]`** via **`_annotate_ungrounded`**, with strict mode raising **`ExtractionValidationError`** (lines 446-680)
- The raw system string propagates to the native engine through [`needle/_worker.py`](https://github.com/cactus-compute/needle/blob/main/needle/_worker.py) (`lib.needle_init`), though the Python layer currently only enforces temporal constraints

## Frequently Asked Questions

### What types of system facts does Needle support besides dates?

Currently, Needle's Python implementation only parses and enforces **temporal facts** (years and dates) from the system string. While the underlying native library receives the complete system context via `lib.needle_init` in [`needle/_worker.py`](https://github.com/cactus-compute/needle/blob/main/needle/_worker.py), the Python validation layer exclusively handles date-related grounding.

### How does Needle handle dates that conflict with system facts?

When `strict=True` (the default for `extract()`), Needle raises an **`ExtractionValidationError`** through `_validate_extraction` (lines 668-680). In non-strict mode, the operation succeeds but marks conflicting fields in `response["validation"]["ungrounded"]` via the `_annotate_ungrounded` method (lines 446-666).

### Can system facts from user input override the initialization context?

No single source overrides another; instead, the **`_licensed_years`** method (lines 944-998) merges years discovered in user input with those extracted from the system string, creating a combined set of licensed years. This allows temporal context to accumulate across the conversation while maintaining validation boundaries.

### Which JSON Schema formats trigger temporal grounding?

Needle applies temporal validation to schema properties declaring **`"date"`** or **`"date-time"`** formats. The `_temporal_grounding` method specifically checks these format declarations when walking tool schemas to determine which values require year validation against system facts.