Agent-First PSQL v0.3.1: Output Policy Protected SQL Rows

by Agent-First Kit Contributors

The v0.3.1 update separated SQL payloads from output-layer redaction and preserved row structure across JSON, YAML, plain, and MCP responses.

A PostgreSQL row is user data. The output layer should not reinterpret it.

Agent-First PSQL v0.3.1 focused on a subtle but important boundary: afpsql’s event envelope follows Agent-First Data rules, but SQL result rows are payloads from the database. They need to be reported accurately.

The problem: generic redaction can be wrong for SQL rows

Agent-First Data redacts _secret fields by default. That is correct for tool metadata such as DSNs, passwords, and trace fields.

But a SQL query might intentionally read a column named api_key_secret because the user asked to audit it. If afpsql blindly redacts result rows, the agent does not get the database answer.

The change: result events use trace-only redaction

v0.3.1 applied an explicit output policy: Result and ResultRows events keep SQL payload keys and values intact while still allowing trace metadata to be redacted.

The connector stops treating database rows as its own config. It reports what PostgreSQL returned.

The format change: YAML and plain stopped reshaping rows

Human-readable output formats can be useful for debugging, but they should not corrupt SQL row structure. v0.3.1 protects the rows field in YAML and plain output by serializing it as an opaque JSON string.

That means the event envelope can be readable without causing the row payload to be key-stripped, unit-formatted, or otherwise transformed.

The integration change: MCP got the same per-event policy

At the time, afpsql still had an MCP mode. v0.3.1 applied per-event redaction policy before assembling MCP responses too, keeping CLI, pipe, and MCP behavior consistent.

Where this fits: separate envelope semantics from payload semantics

This release clarified a core connector rule. afpsql owns the event envelope: code, trace, error_code, limits, and session metadata. PostgreSQL owns the rows.

Agents need both, but they should not be mixed.