Needle System Facts: How Temporal Context Controls Agent Validation
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:
from needle import Needle
agent = Needle(
tools=[InvoiceTool],
system="date: 2026-07-21 Tue 14:30"
)
The Python implementation in 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, 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:
_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:
{"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:
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
Needleclass - The
_source_yearsand_licensed_yearsmethods inneedle/__init__.pyextract and combine temporal boundaries from system context and user input (lines 778-791 and 944-998) _temporal_groundingvalidates 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 raisingExtractionValidationError(lines 446-680) - The raw system string propagates to the native engine through
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, 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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →