diff --git a/README.md b/README.md
index 62200bfb..393daa37 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,27 @@
# TeaQL Java
+## Sensitive log data
+
+Runtime diagnostic logs redact payload values by default, before delivery to
+file, console, buffers, or custom logging sinks. Selecting a diagnostic sink
+alone does not authorize plaintext. For controlled troubleshooting only:
+
+```bash
+export TEAQL_ALLOW_SENSITIVE_PLAINTEXT_LOGS=I_UNDERSTAND_SENSITIVE_DATA_MAY_BE_WRITTEN_TO_DISK
+```
+
+Only this exact value enables plaintext permission; empty values, `true`, and
+whitespace variants do not. Enabling it emits a warning. Credential-classified
+fields remain redacted. The flag does not force every sink to expose values.
+SQL without reliable field/literal provenance may be suppressed and marked
+`NOT REPLAYABLE`. Execution parameters and persisted business data are unchanged.
+
+Do not put sensitive data in free-text comments or purpose declarations.
+TeaQL cannot govern arbitrary application prints or independent driver loggers;
+configure those separately. This setting does not erase older plaintext files.
+Restrict access and retention when using plaintext diagnostics, then unset the
+variable and restart processes when troubleshooting is complete.
+
[](https://www.bestpractices.dev/projects/13612)
TeaQL Java is the Java runtime for TeaQL domain applications. It provides a
diff --git a/examples/business-id-runtime/pom.xml b/examples/business-id-runtime/pom.xml
index f9ed9fc5..04e086f5 100644
--- a/examples/business-id-runtime/pom.xml
+++ b/examples/business-id-runtime/pom.xml
@@ -6,7 +6,7 @@
io.teaql
teaql-java-parent
- 1.550-RELEASE
+ 1.551-RELEASE
../../pom.xml
teaql-business-id-example
diff --git a/examples/conformance/lib/pom.xml b/examples/conformance/lib/pom.xml
index 50d78872..2d6dd0df 100644
--- a/examples/conformance/lib/pom.xml
+++ b/examples/conformance/lib/pom.xml
@@ -12,7 +12,7 @@
21
4.1.1
- 1.550-RELEASE
+ 1.551-RELEASE
UTF-8
true
diff --git a/examples/conformance/pom.xml b/examples/conformance/pom.xml
index e22b76f1..3670af08 100644
--- a/examples/conformance/pom.xml
+++ b/examples/conformance/pom.xml
@@ -16,7 +16,7 @@
1.0.0
UTF-8
true
- 1.550-RELEASE
+ 1.551-RELEASE
diff --git a/examples/order-management/java-app-console/pom.xml b/examples/order-management/java-app-console/pom.xml
index 29d443ed..0145cb16 100644
--- a/examples/order-management/java-app-console/pom.xml
+++ b/examples/order-management/java-app-console/pom.xml
@@ -11,7 +11,7 @@
21
UTF-8
- 1.550-RELEASE
+ 1.551-RELEASE
diff --git a/examples/order-management/java-lib-core/lib/pom.xml b/examples/order-management/java-lib-core/lib/pom.xml
index 99f4b6bb..414c9304 100644
--- a/examples/order-management/java-lib-core/lib/pom.xml
+++ b/examples/order-management/java-lib-core/lib/pom.xml
@@ -12,7 +12,7 @@
21
4.1.1
- 1.550-RELEASE
+ 1.551-RELEASE
UTF-8
true
diff --git a/examples/round-trip-reference-runtime/pom.xml b/examples/round-trip-reference-runtime/pom.xml
index a46f4920..98e556b8 100644
--- a/examples/round-trip-reference-runtime/pom.xml
+++ b/examples/round-trip-reference-runtime/pom.xml
@@ -6,7 +6,7 @@
io.teaql
teaql-java-parent
- 1.550-RELEASE
+ 1.551-RELEASE
../../pom.xml
teaql-round-trip-reference-example
diff --git a/examples/school-management/lib/pom.xml b/examples/school-management/lib/pom.xml
index 9a310346..96c3a4a2 100644
--- a/examples/school-management/lib/pom.xml
+++ b/examples/school-management/lib/pom.xml
@@ -12,7 +12,7 @@
21
4.1.1
- 1.550-RELEASE
+ 1.551-RELEASE
UTF-8
true
diff --git a/examples/school-management/pom.xml b/examples/school-management/pom.xml
index 3766edc6..bd325b4b 100644
--- a/examples/school-management/pom.xml
+++ b/examples/school-management/pom.xml
@@ -16,7 +16,7 @@
0.0.1-SNAPSHOT
UTF-8
true
- 1.550-RELEASE
+ 1.551-RELEASE
diff --git a/examples/security-foundations/pom.xml b/examples/security-foundations/pom.xml
index 14a72b17..da1cfae2 100644
--- a/examples/security-foundations/pom.xml
+++ b/examples/security-foundations/pom.xml
@@ -6,7 +6,7 @@
io.teaql
teaql-java-parent
- 1.550-RELEASE
+ 1.551-RELEASE
../../pom.xml
teaql-security-foundations-example
diff --git a/pom.xml b/pom.xml
index cc74ff52..44059240 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
io.teaql
teaql-java-parent
- 1.550-RELEASE
+ 1.551-RELEASE
pom
teaql-java-parent
diff --git a/releases/1.551-RELEASE.md b/releases/1.551-RELEASE.md
new file mode 100644
index 00000000..b4e5923c
--- /dev/null
+++ b/releases/1.551-RELEASE.md
@@ -0,0 +1,34 @@
+# 1.551-RELEASE: default log privacy
+
+Tracking: https://github.com/teaql/teaql-java/issues/184
+Cross-runtime contract: https://github.com/teaql/teaql-conformance/issues/58
+
+## Behavior and migration
+
+Runtime-controlled SQL and audit logging now redact sensitive payloads before
+normal, custom, buffered and file destinations. Execution values are unchanged.
+Selecting a diagnostic sink alone no longer authorizes plaintext output.
+
+For intentional plaintext debugging only, set this exact acknowledgement:
+
+```sh
+export TEAQL_ALLOW_SENSITIVE_PLAINTEXT_LOGS=I_UNDERSTAND_SENSITIVE_DATA_MAY_BE_WRITTEN_TO_DISK
+```
+
+Invalid, empty or truthy shortcut values do not enable it. Enabling it emits a
+value-free warning. Credential-classified fields remain hidden. The switch grants
+permission; it does not force every sink to reveal values. Restart after changing
+the environment. Previously written files are not erased.
+
+Without reliable parameter/field provenance, SQL logs use conservative redaction;
+SQL may be labeled non-replayable. Operations, timing and safe intent remain.
+Do not put unrelated secrets in comments/purpose, or print raw business events.
+Arbitrary application and third-party driver logs are outside this boundary.
+
+## Verification
+
+Local runtime tests and `bash scripts/verify-examples.sh` passed before release
+preparation. Retained real SQLite CRUD/failure canaries assert unchanged persisted
+values and absence of sensitive markers in runtime log destinations. Exact/invalid
+environment gates and credential behavior have separate regression fixtures.
+Published-package verification is a separate gate, not implied by local results.
diff --git a/teaql-android/pom.xml b/teaql-android/pom.xml
index 3e5e2578..64c09eb5 100644
--- a/teaql-android/pom.xml
+++ b/teaql-android/pom.xml
@@ -7,7 +7,7 @@
io.teaql
teaql-java-parent
- 1.550-RELEASE
+ 1.551-RELEASE
teaql-android
diff --git a/teaql-business-id-jdbc/pom.xml b/teaql-business-id-jdbc/pom.xml
index 9d6dcc8e..b9f07d84 100644
--- a/teaql-business-id-jdbc/pom.xml
+++ b/teaql-business-id-jdbc/pom.xml
@@ -7,7 +7,7 @@
io.teaql
teaql-java-parent
- 1.550-RELEASE
+ 1.551-RELEASE
../pom.xml
diff --git a/teaql-cloud/pom.xml b/teaql-cloud/pom.xml
index c5c18ba0..a73fa662 100644
--- a/teaql-cloud/pom.xml
+++ b/teaql-cloud/pom.xml
@@ -6,7 +6,7 @@
io.teaql
teaql-java-parent
- 1.550-RELEASE
+ 1.551-RELEASE
teaql-cloud
teaql-cloud
diff --git a/teaql-context-runtime-tools/pom.xml b/teaql-context-runtime-tools/pom.xml
index 5d7e4ead..1d7992f2 100644
--- a/teaql-context-runtime-tools/pom.xml
+++ b/teaql-context-runtime-tools/pom.xml
@@ -6,7 +6,7 @@
io.teaql
teaql-java-parent
- 1.550-RELEASE
+ 1.551-RELEASE
teaql-context-runtime-tools
diff --git a/teaql-core/pom.xml b/teaql-core/pom.xml
index 11f21672..0fb136fe 100644
--- a/teaql-core/pom.xml
+++ b/teaql-core/pom.xml
@@ -7,7 +7,7 @@
io.teaql
teaql-java-parent
- 1.550-RELEASE
+ 1.551-RELEASE
../pom.xml
diff --git a/teaql-data-service-sql/pom.xml b/teaql-data-service-sql/pom.xml
index e8e4cd62..be5e6073 100644
--- a/teaql-data-service-sql/pom.xml
+++ b/teaql-data-service-sql/pom.xml
@@ -6,7 +6,7 @@
io.teaql
teaql-java-parent
- 1.550-RELEASE
+ 1.551-RELEASE
../pom.xml
diff --git a/teaql-db2/pom.xml b/teaql-db2/pom.xml
index 3fb7385f..4a797539 100644
--- a/teaql-db2/pom.xml
+++ b/teaql-db2/pom.xml
@@ -6,7 +6,7 @@
io.teaql
teaql-java-parent
- 1.550-RELEASE
+ 1.551-RELEASE
teaql-db2
teaql-db2
diff --git a/teaql-dm8/pom.xml b/teaql-dm8/pom.xml
index 5c1280c8..9d895b47 100644
--- a/teaql-dm8/pom.xml
+++ b/teaql-dm8/pom.xml
@@ -6,7 +6,7 @@
io.teaql
teaql-java-parent
- 1.550-RELEASE
+ 1.551-RELEASE
teaql-dm8
teaql-dm8
diff --git a/teaql-duckdb/pom.xml b/teaql-duckdb/pom.xml
index 275f3f36..3c111ac3 100644
--- a/teaql-duckdb/pom.xml
+++ b/teaql-duckdb/pom.xml
@@ -6,7 +6,7 @@
io.teaql
teaql-java-parent
- 1.550-RELEASE
+ 1.551-RELEASE
teaql-duckdb
teaql-duckdb
diff --git a/teaql-dynamic-fields-api/pom.xml b/teaql-dynamic-fields-api/pom.xml
index c3cd66a7..7632ce30 100644
--- a/teaql-dynamic-fields-api/pom.xml
+++ b/teaql-dynamic-fields-api/pom.xml
@@ -7,7 +7,7 @@
io.teaql
teaql-java-parent
- 1.550-RELEASE
+ 1.551-RELEASE
../pom.xml
diff --git a/teaql-dynamic-fields-jdbc/pom.xml b/teaql-dynamic-fields-jdbc/pom.xml
index 5c031aa9..879237e4 100644
--- a/teaql-dynamic-fields-jdbc/pom.xml
+++ b/teaql-dynamic-fields-jdbc/pom.xml
@@ -7,7 +7,7 @@
io.teaql
teaql-java-parent
- 1.550-RELEASE
+ 1.551-RELEASE
../pom.xml
diff --git a/teaql-hana/pom.xml b/teaql-hana/pom.xml
index 43485311..93fb5bd7 100644
--- a/teaql-hana/pom.xml
+++ b/teaql-hana/pom.xml
@@ -6,7 +6,7 @@
io.teaql
teaql-java-parent
- 1.550-RELEASE
+ 1.551-RELEASE
teaql-hana
teaql-hana
diff --git a/teaql-jackson/pom.xml b/teaql-jackson/pom.xml
index c4abdec9..1a826a5d 100644
--- a/teaql-jackson/pom.xml
+++ b/teaql-jackson/pom.xml
@@ -6,7 +6,7 @@
io.teaql
teaql-java-parent
- 1.550-RELEASE
+ 1.551-RELEASE
teaql-jackson
diff --git a/teaql-mssql/pom.xml b/teaql-mssql/pom.xml
index c8d41f6c..f0db014f 100644
--- a/teaql-mssql/pom.xml
+++ b/teaql-mssql/pom.xml
@@ -6,7 +6,7 @@
io.teaql
teaql-java-parent
- 1.550-RELEASE
+ 1.551-RELEASE
teaql-mssql
teaql-mssql
diff --git a/teaql-mysql/pom.xml b/teaql-mysql/pom.xml
index 01cb2be2..8dcd11ed 100644
--- a/teaql-mysql/pom.xml
+++ b/teaql-mysql/pom.xml
@@ -7,7 +7,7 @@
io.teaql
teaql-java-parent
- 1.550-RELEASE
+ 1.551-RELEASE
teaql-mysql
diff --git a/teaql-opentelemetry/pom.xml b/teaql-opentelemetry/pom.xml
index 25905c44..b364a210 100644
--- a/teaql-opentelemetry/pom.xml
+++ b/teaql-opentelemetry/pom.xml
@@ -6,7 +6,7 @@
io.teaql
teaql-java-parent
- 1.550-RELEASE
+ 1.551-RELEASE
teaql-opentelemetry
diff --git a/teaql-oracle/pom.xml b/teaql-oracle/pom.xml
index 03a6eb6d..79ba329e 100644
--- a/teaql-oracle/pom.xml
+++ b/teaql-oracle/pom.xml
@@ -6,7 +6,7 @@
io.teaql
teaql-java-parent
- 1.550-RELEASE
+ 1.551-RELEASE
teaql-oracle
teaql-oracle
diff --git a/teaql-postgres/pom.xml b/teaql-postgres/pom.xml
index f9959b3f..c0e0d915 100644
--- a/teaql-postgres/pom.xml
+++ b/teaql-postgres/pom.xml
@@ -6,7 +6,7 @@
io.teaql
teaql-java-parent
- 1.550-RELEASE
+ 1.551-RELEASE
teaql-postgres
teaql-postgres
diff --git a/teaql-provider-jdbc/pom.xml b/teaql-provider-jdbc/pom.xml
index b3929d9d..c767a936 100644
--- a/teaql-provider-jdbc/pom.xml
+++ b/teaql-provider-jdbc/pom.xml
@@ -6,7 +6,7 @@
io.teaql
teaql-java-parent
- 1.550-RELEASE
+ 1.551-RELEASE
../pom.xml
diff --git a/teaql-provider-spring-jdbc/pom.xml b/teaql-provider-spring-jdbc/pom.xml
index faaa3022..2fc85547 100644
--- a/teaql-provider-spring-jdbc/pom.xml
+++ b/teaql-provider-spring-jdbc/pom.xml
@@ -6,7 +6,7 @@
io.teaql
teaql-java-parent
- 1.550-RELEASE
+ 1.551-RELEASE
../pom.xml
diff --git a/teaql-query-json/pom.xml b/teaql-query-json/pom.xml
index 8d59ee0b..b2abd1a9 100644
--- a/teaql-query-json/pom.xml
+++ b/teaql-query-json/pom.xml
@@ -6,7 +6,7 @@
io.teaql
teaql-java-parent
- 1.550-RELEASE
+ 1.551-RELEASE
teaql-query-json
diff --git a/teaql-redis/pom.xml b/teaql-redis/pom.xml
index e61e466f..00bab25e 100644
--- a/teaql-redis/pom.xml
+++ b/teaql-redis/pom.xml
@@ -7,7 +7,7 @@
io.teaql
teaql-java-parent
- 1.550-RELEASE
+ 1.551-RELEASE
../pom.xml
diff --git a/teaql-runtime-log/pom.xml b/teaql-runtime-log/pom.xml
index 9a8ea988..4443c0f3 100644
--- a/teaql-runtime-log/pom.xml
+++ b/teaql-runtime-log/pom.xml
@@ -6,7 +6,7 @@
io.teaql
teaql-java-parent
- 1.550-RELEASE
+ 1.551-RELEASE
teaql-runtime-log
diff --git a/teaql-runtime-log/src/main/java/io/teaql/runtime/log/HumanReaderFormatter.java b/teaql-runtime-log/src/main/java/io/teaql/runtime/log/HumanReaderFormatter.java
index 921f774f..f780143b 100644
--- a/teaql-runtime-log/src/main/java/io/teaql/runtime/log/HumanReaderFormatter.java
+++ b/teaql-runtime-log/src/main/java/io/teaql/runtime/log/HumanReaderFormatter.java
@@ -23,6 +23,7 @@ private String formatTraceChain(List traceChain) {
@Override
public String formatExecutionLog(io.teaql.core.ExecutionMetadata metadata) {
+ metadata = io.teaql.runtime.LogPrivacy.sql(metadata, io.teaql.runtime.LogPrivacy.plaintextEnabled());
String ts = LocalDateTime.now().format(TS_FORMATTER);
String traceStr = formatTraceChain(metadata.getTraceChain());
String traceDisplay = traceStr.isEmpty() ? "" : " - [" + traceStr + "]";
diff --git a/teaql-runtime-log/src/main/java/io/teaql/runtime/log/JsonReaderFormatter.java b/teaql-runtime-log/src/main/java/io/teaql/runtime/log/JsonReaderFormatter.java
index 15cf5b38..e437b081 100644
--- a/teaql-runtime-log/src/main/java/io/teaql/runtime/log/JsonReaderFormatter.java
+++ b/teaql-runtime-log/src/main/java/io/teaql/runtime/log/JsonReaderFormatter.java
@@ -23,6 +23,7 @@ private String escapeJson(String text) {
@Override
public String formatExecutionLog(io.teaql.core.ExecutionMetadata metadata) {
+ metadata = io.teaql.runtime.LogPrivacy.sql(metadata, io.teaql.runtime.LogPrivacy.plaintextEnabled());
String execution = String.format("{\"type\":\"EXEC_LOG\",\"tracePath\":%s,\"backend\":\"%s\",\"operation\":\"%s\",\"comment\":\"%s\",\"purpose\":\"%s\",\"auditReason\":\"%s\",\"elapsedUs\":%d,\"resultCount\":%s,\"affectedRows\":%s,\"summary\":\"%s\",\"parameterizedSQL\":\"%s\"",
formatTraceChain(metadata.getTraceChain()),
escapeJson(metadata.getBackend()),
diff --git a/teaql-runtime-log/src/main/java/io/teaql/runtime/log/LogManager.java b/teaql-runtime-log/src/main/java/io/teaql/runtime/log/LogManager.java
index f1de4559..173e6ea6 100644
--- a/teaql-runtime-log/src/main/java/io/teaql/runtime/log/LogManager.java
+++ b/teaql-runtime-log/src/main/java/io/teaql/runtime/log/LogManager.java
@@ -128,7 +128,7 @@ private void initFileChannel() {
this.currentSize.set(this.currentChannel.size());
calculateNextMidnight();
} catch (Exception e) {
- System.err.println("TeaQL LogManager Failed to initialize file channel: " + e.getMessage());
+ System.err.println("TeaQL LogManager Failed to initialize file channel: " + e.getClass().getSimpleName());
}
}
}
@@ -142,7 +142,7 @@ private void processQueue() {
Thread.currentThread().interrupt();
break;
} catch (Exception e) {
- System.err.println("TeaQL LogManager Exception in worker thread: " + e.getMessage());
+ System.err.println("TeaQL LogManager Exception in worker thread: " + e.getClass().getSimpleName());
}
}
}
@@ -170,7 +170,7 @@ private void writeHeaderIfNeeded() {
currentSize.addAndGet(bytes.length);
}
} catch (Exception e) {
- System.err.println("TeaQL LogManager Failed to write header: " + e.getMessage());
+ System.err.println("TeaQL LogManager Failed to write header: " + e.getClass().getSimpleName());
} finally {
headerWritten = true;
}
@@ -217,7 +217,7 @@ private void syncWrite(String content, CustomLogSink customSink) {
currentChannel.write(ByteBuffer.wrap(bytes));
currentSize.addAndGet(bytes.length);
} catch (Exception e) {
- System.err.println("TeaQL LogManager Failed to write to log file: " + e.getMessage());
+ System.err.println("TeaQL LogManager Failed to write to log file: " + e.getClass().getSimpleName());
}
}
}
@@ -244,7 +244,7 @@ private void rotateLogFile() {
}
} catch (Exception e) {
- System.err.println("TeaQL LogManager Failed to rotate log file: " + e.getMessage());
+ System.err.println("TeaQL LogManager Failed to rotate log file: " + e.getClass().getSimpleName());
}
}
@@ -263,7 +263,7 @@ private void compressAsync(File source) {
gos.finish();
source.delete();
} catch (Exception e) {
- System.err.println("TeaQL LogManager Failed to compress log file: " + e.getMessage());
+ System.err.println("TeaQL LogManager Failed to compress log file: " + e.getClass().getSimpleName());
}
});
}
@@ -294,6 +294,7 @@ public void writeExecutionLog(io.teaql.core.UserContext context, io.teaql.core.E
if (!LogConfig.getInstance().shouldLogSql(metadata.getParameterizedQuery())) {
return;
}
+ metadata = io.teaql.runtime.LogPrivacy.sql(metadata, io.teaql.runtime.LogPrivacy.plaintextEnabled());
String content = LogFormatterFactory.getFormatter().formatExecutionLog(metadata);
CustomLogSink customSink = resolveCustomSink(context);
asyncWrite(content, customSink);
@@ -313,6 +314,19 @@ public void writeAuditLog(io.teaql.core.UserContext context, List tra
if (!LogConfig.getInstance().shouldLogAudit(event.getEntityType())) {
return;
}
+ boolean allow = io.teaql.runtime.LogPrivacy.plaintextEnabled();
+ java.util.List