Finding
TEPP now fails closed on session-local trigger suppression through direct SET, PostgreSQL set_config, and writable pg_settings, including the bounded Unicode-identifier cases tracked through #587. One PostgreSQL configuration surface remains outside that execution-context authority: persistent login defaults.
PostgreSQL 18 defines these as first-class configuration surfaces:
ALTER ROLE { role | ALL } [ IN DATABASE database ] SET parameter = value stores a role/session default; SET ... FROM CURRENT stores the current session value. The value is applied when a subsequent session logs in.
ALTER DATABASE ... SET parameter = value supplies a database default for subsequent sessions.
ALTER SYSTEM SET parameter = value writes the cluster-wide default to postgresql.auto.conf; it becomes effective after configuration reload/restart as applicable and cannot be rolled back.
session_replication_role=replica disables ordinary/default triggers and rules. A migration that leaves tepp_app_runtime, every role (ALL), the target database, or the cluster with a persistent replica default can therefore make a later TEPP application session bypass append-only/retention trigger enforcement even though the migration's own session ends in ordinary execution mode and role attributes remain NOSUPERUSER/NOBYPASSRLS.
Primary PostgreSQL 18 authority:
Required ordinary-forward RED → repair
Add public validate_migration_catalog() contracts before changing production code.
Unsafe persistent defaults must fail closed:
ALTER ROLE tepp_app_runtime SET session_replication_role = replica;
ALTER ROLE tepp_app_runtime IN DATABASE <db> SET session_replication_role TO replica;
ALTER ROLE ALL SET session_replication_role = replica and the database-scoped ALL equivalent;
ALTER ROLE tepp_app_runtime SET session_replication_role FROM CURRENT because the persisted value cannot be proven ordinary-trigger-safe from syntax alone;
ALTER DATABASE <db> SET session_replication_role = replica;
ALTER SYSTEM SET session_replication_role = replica.
Controls:
- direct
origin and local defaults preserve ordinary trigger execution;
- unrelated parameters remain unrelated;
- role/database mutations inside an explicit transaction that rolls back are non-durable and must not poison final state;
ALTER SYSTEM is not given a rollback control because PostgreSQL forbids it inside transaction blocks;
- strings/comments/dollar bodies containing marker text remain opaque;
- identifier-prefix/lookalike objects do not impersonate the protected role/parameter/database surfaces.
Repair boundary
Do not add another raw-SQL lexer or one-off string-search authority. Consume the existing normalized + committed transaction projection and extend the first-class execution-context/default-state model. Preserve #576–#587 semantics for direct SET/set_config/pg_settings, Unicode fail-closed behavior, role final-state logic, and current rollback projection.
Long-term aggregate should distinguish at least:
- session-current execution mode;
- role-specific and role+database login defaults;
- database/global defaults and precedence;
FROM CURRENT, DEFAULT/RESET, and statement ordering/final state;
- reload/restart activation for system defaults;
- transaction durability;
- protected trigger/rule dependency state.
A conservative interim fail-closed boundary is acceptable only if it is explicit about unsupported final-state transitions; do not silently certify a historical unsafe default merely because a later unrelated statement exists.
Keep this issue open until the surviving post-#538 non-force-restacked exact head has hosted Rust/Live PostgreSQL, current-topology rustdoc 100%, authored line/branch/edge acceptance, security/CodeQL, qualifying independent review, and immutable release evidence. No force push, destructive rebase, self-approval, skip/xfail, coverage-denominator manipulation, or gate weakening.
Finding
TEPP now fails closed on session-local trigger suppression through direct
SET, PostgreSQLset_config, and writablepg_settings, including the bounded Unicode-identifier cases tracked through #587. One PostgreSQL configuration surface remains outside that execution-context authority: persistent login defaults.PostgreSQL 18 defines these as first-class configuration surfaces:
ALTER ROLE { role | ALL } [ IN DATABASE database ] SET parameter = valuestores a role/session default;SET ... FROM CURRENTstores the current session value. The value is applied when a subsequent session logs in.ALTER DATABASE ... SET parameter = valuesupplies a database default for subsequent sessions.ALTER SYSTEM SET parameter = valuewrites the cluster-wide default topostgresql.auto.conf; it becomes effective after configuration reload/restart as applicable and cannot be rolled back.session_replication_role=replicadisables ordinary/default triggers and rules. A migration that leavestepp_app_runtime, every role (ALL), the target database, or the cluster with a persistent replica default can therefore make a later TEPP application session bypass append-only/retention trigger enforcement even though the migration's own session ends in ordinary execution mode and role attributes remainNOSUPERUSER/NOBYPASSRLS.Primary PostgreSQL 18 authority:
Required ordinary-forward RED → repair
Add public
validate_migration_catalog()contracts before changing production code.Unsafe persistent defaults must fail closed:
ALTER ROLE tepp_app_runtime SET session_replication_role = replica;ALTER ROLE tepp_app_runtime IN DATABASE <db> SET session_replication_role TO replica;ALTER ROLE ALL SET session_replication_role = replicaand the database-scopedALLequivalent;ALTER ROLE tepp_app_runtime SET session_replication_role FROM CURRENTbecause the persisted value cannot be proven ordinary-trigger-safe from syntax alone;ALTER DATABASE <db> SET session_replication_role = replica;ALTER SYSTEM SET session_replication_role = replica.Controls:
originandlocaldefaults preserve ordinary trigger execution;ALTER SYSTEMis not given a rollback control because PostgreSQL forbids it inside transaction blocks;Repair boundary
Do not add another raw-SQL lexer or one-off string-search authority. Consume the existing normalized + committed transaction projection and extend the first-class execution-context/default-state model. Preserve #576–#587 semantics for direct SET/set_config/pg_settings, Unicode fail-closed behavior, role final-state logic, and current rollback projection.
Long-term aggregate should distinguish at least:
FROM CURRENT,DEFAULT/RESET, and statement ordering/final state;A conservative interim fail-closed boundary is acceptable only if it is explicit about unsupported final-state transitions; do not silently certify a historical unsafe default merely because a later unrelated statement exists.
Keep this issue open until the surviving post-#538 non-force-restacked exact head has hosted Rust/Live PostgreSQL, current-topology rustdoc 100%, authored line/branch/edge acceptance, security/CodeQL, qualifying independent review, and immutable release evidence. No force push, destructive rebase, self-approval, skip/xfail, coverage-denominator manipulation, or gate weakening.