VARUX AXIS Deterministic PostgreSQL Write-Path Control
v0.6 · Pilot Readiness
AXIS Documentation / Core Concepts / SQL Classification

SQL Classification

VerifiedContract v1.0 · ACTIVE – LockedEffective 2026-08-07

The classifier is governed by the AXIS Security Classification Contract v1.0 — an engineering binding contract between the Classifier and the Policy Evaluator. Any deviation is a Critical Security Defect (Authorization Bypass) and must be treated as such.

Contract rules. "Any deviation from this contract is a Critical Security Defect and must be treated as an active Authorization Bypass." The contract is "not valid until proven by automated tests in CI" — human review alone is insufficient.

Classification principles

QueryType: the primary classification

Primary classification values: QueryType::Read, QueryType::Write, QueryType::Unknown.

TypeDefinitionExamples
ReadDoes not modify any persistent or session state; only returns dataSELECT (without INTO, volatile functions, or data-modifying CTEs); SHOW, EXPLAIN, DESCRIBE; COPY TO STDOUT; SELECT with IMMUTABLE/STABLE functions only; LISTEN/NOTIFY (minimal state change — audit separately)
WriteCreates, alters, deletes or moves persistent data, schema, sequences or large objects — including anything that would change the result of a subsequent SELECT on the same tableSee mandatory patterns below
UnknownSemantic effect cannot be determined from the ASTTreated as Write or Block — never as Read

Mandatory Write patterns

StatementClassification
INSERT / UPDATE / DELETEWrite (DML)
SELECT INTOWrite (DDL + DML)
CREATE TABLE AS (CTAS)Write (DDL + DML)
MERGEWrite (DML)
TRUNCATEWrite (DDL)
DROP / ALTERWrite (DDL)
REFRESH MATERIALIZED VIEWWrite (DML)
COPY FROMWrite (DML)
COPY TO PROGRAMCritical – always BLOCK
CALL (procedure) / DO (anonymous block)Write (DML) unless proved read-only
nextval() / setval()Sequence mutation (Write)
lo_import / lo_exportLarge object mutation (Write)
ALTER SYSTEMCritical – always BLOCK
Data-modifying CTE (WITH d AS (DELETE ...) SELECT * FROM d)Write (DML — the write happens before the outer read)
Nested / chained CTE writesWrite (DML)

Unknown / ambiguous handling

Mandatory risk signals (fallback layer)

Risk signals are a defense-in-depth fallback, not the primary control. They override a permissive read default only when the classifier is wrong:

SignalDetected whenOverride behavior
select_intoSELECT INTO presentIf QueryType == Read (classifier error) → Block or RequireApproval
cte_writeData-modifying CTE presentSame override
sequence_writenextval()/setval() presentSame override
volatile_functionVOLATILE function call presentSame override
copy_programCOPY TO PROGRAM presentAlways Block

Other risk signals used by policy evaluation: prod_write, ddl_operation, bulk_operation, delete_without_where, unknown_target, unknown_scope, cross_schema.

Evaluator behavior

Read QueryType.

Read RiskSignals.

Primary path: if QueryType == Write, apply defaults.write rules directly.

Fallback path: if QueryType == Read and a critical risk signal exists, log CLASSIFIER_OVERRIDE_TRIGGERED and apply the override rule.

Never rely on the override as the primary protection.

CI-enforced testing

Classification-related errors

Fail-closed code PARSE_REJECTED_UNTRUSTED_INPUT covers unsupported SQL, invalid UTF-8, raw NUL bytes and unparseable extended-protocol bind values. Related structured errors: empty_sql, multi_statement_rejected, unsupported_sql_shape, parser_error, parser_unsupported_syntax, unsafe_read_shape. See the Error Codes reference.

Related: Request Lifecycle · Policy Engine · Native PG Wire Protocol (SQL feature matrix for the wire path)