aeat.entrypoints.mcp._faithfulness module

Faithfulness check: agent narration must not invent numeric tax values.

A documented failure mode of financial MCP agents is fabricating a plausible numeric result when uncertain. This PostToolUse check extracts amount-shaped numbers from the agent’s narration and flags any whose digit sequence is absent from the preceding tool-result JSON. It is advisory by default - relaying a warning - and a hard block on the irreversible filing-handoff path, mirroring the no-silent-under-declaration discipline of warning where legitimate cases exist and blocking where the consequence is irreversible. It never computes a value; it only checks that every number the agent states came from a tool result.

class FaithfulnessResult(**data)[source]

Bases: BaseModel

Verdict of one faithfulness check.

faithful is true when every amount-shaped number in the narration is grounded in the tool JSON. blocking records whether this check ran on the irreversible handoff path; flagged_values lists the ungrounded numbers.

Parameters:
faithful: bool
blocking: bool
flagged_values: tuple[str, ...]
property blocks: bool

True when the check should hard-block the action (handoff + unfaithful).

faithfulness_check(*, agent_text, tool_result_json, blocking=False)[source]

Flag amount-shaped numbers in agent_text absent from tool_result_json.

Parameters:
  • agent_text (str) – The agent’s operator-facing narration.

  • tool_result_json (str) – The serialized JSON of the tool results the narration is supposed to be grounded in.

  • blocking (bool) – When true (the export / record-marker handoff path), an unfaithful result blocks; otherwise it is advisory.

Return type:

FaithfulnessResult

Returns:

FaithfulnessResult with the advisory or blocking verdict.

class SessionGroundingWindow(*, max_results=32)[source]

Bases: object

A bounded, in-memory record of the session’s tool-result JSON.

The serving-path integration surface (ADR R6): the model’s free narration lives client-side where the server cannot see it, so the ENFORCEABLE faithfulness boundary is the tool-call arguments — every amount-shaped number an agent sends INTO a call must be grounded in a tool result this same session produced. The window accumulates each call’s result JSON (memory only, never persisted — results carry taxpayer figures and sensitive-financial-data-secure-storage-only forbids writing them outside secure storage) and serves as the grounding corpus for arguments_faithfulness().

Bounded FIFO so a long session cannot grow without limit; the bound is generous because a grounding figure is almost always from the immediately preceding calculate/revision reads.

Parameters:

max_results (int)

record(tool_result_json)[source]

Append one call’s result JSON to the window, evicting the oldest past the bound.

Return type:

None

Parameters:

tool_result_json (str)

corpus()[source]

The concatenated grounding corpus the checks run against.

Return type:

str

arguments_faithfulness(*, arguments_json, window, blocking)[source]

Check a tool call’s ARGUMENTS against the session’s grounding window.

The serving-path enforcement point: advisory on ordinary mutating calls, a hard block at the export / record-marker handoff (an amount the session never produced must not enter the irreversible artefact call). An empty window with amount-shaped arguments on the handoff path blocks — figures from nowhere are exactly the fabrication this gate exists to stop.

Return type:

FaithfulnessResult

Returns:

A FaithfulnessResult.

Parameters:
advisory_line(result)[source]

The warning line the server prepends to a result for an advisory mismatch (client-relayed, localized).

Return type:

str

Parameters:

result (FaithfulnessResult)