[pitboss/grind] deferred session-0020 (20260516T052512Z-20f8)

This commit is contained in:
pitboss 2026-05-16 11:27:45 -05:00
parent 04b3d88eb4
commit aa209148b0
8 changed files with 649 additions and 13 deletions

View file

@ -433,6 +433,34 @@ func __nyx_stub_http_record(method, url, body string, detail map[string]string)
}
f.WriteString(method + " " + url + "\n")
}
// Phase 10 (Track D.3) SQL recording helper. When the verifier spawned a
// SqlStub it publishes the side-channel log path through NYX_SQL_LOG; a
// sink callsite whose query never reaches the on-the-wire SQLite engine
// (no database/sql driver imported, query pre-flighted before sql.Open,
// network-isolated sandbox) can call this helper to surface the attempted
// query. Hash-prefixed detail lines followed by the query line so
// SqlStub::drain_events parses every language stream identically. No-op
// when NYX_SQL_LOG is unset so the same harness still runs cleanly under
// modes that did not spawn a stub.
func __nyx_stub_sql_record(query string, detail map[string]string) {
p := os.Getenv("NYX_SQL_LOG")
if p == "" {
return
}
f, err := os.OpenFile(p, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
return
}
defer f.Close()
for k, v := range detail {
f.WriteString("# " + k + ": " + v + "\n")
}
f.WriteString(query)
if !strings.HasSuffix(query, "\n") {
f.WriteString("\n")
}
}
"##
}
@ -921,6 +949,23 @@ mod tests {
);
}
#[test]
fn probe_shim_publishes_stub_sql_recorder() {
let shim = probe_shim();
assert!(
shim.contains("func __nyx_stub_sql_record"),
"Go probe shim must define __nyx_stub_sql_record"
);
assert!(
shim.contains("NYX_SQL_LOG"),
"stub recorder must read NYX_SQL_LOG"
);
assert!(
shim.contains("strings.HasSuffix(query, \"\\n\")"),
"Go SQL recorder must guarantee a trailing newline on the query line so SqlStub::drain_events frames each record"
);
}
#[test]
fn chain_step_splices_probe_shim_for_composite_reverify() {
let step = chain_step(Some(b"<prev>"));

View file

@ -404,6 +404,35 @@ pub fn probe_shim() -> &'static str {
// best-effort
}
}
// Phase 10 (Track D.3) SQL recording helper. When the verifier spawned a
// SqlStub it publishes the side-channel log path through NYX_SQL_LOG; a
// sink call site whose query never reaches the on-the-wire SQLite engine
// (e.g. classpath lacks sqlite-jdbc, or the harness pre-flights the SQL
// string before opening the connection) can call this helper to surface
// the attempted query. Hash-prefixed detail lines followed by the query
// line so SqlStub::drain_events parses every language stream identically.
// Same hash-via-String.valueOf trick as __nyx_stub_http_record so this
// method body contains no literal `"#` sequence that would terminate the
// surrounding Rust raw string.
static void __nyx_stub_sql_record(String query, java.util.Map<String,String> detail) {
String p = System.getenv("NYX_SQL_LOG");
if (p == null || p.isEmpty()) return;
String hashSp = String.valueOf('#') + " ";
try (java.io.FileWriter fw = new java.io.FileWriter(p, true)) {
if (detail != null) {
for (java.util.Map.Entry<String,String> e : detail.entrySet()) {
fw.write(hashSp + e.getKey() + ": " + e.getValue() + "\n");
}
}
fw.write(query);
if (!query.endsWith("\n")) {
fw.write("\n");
}
} catch (java.io.IOException e) {
// best-effort
}
}
"##
}
@ -1094,6 +1123,23 @@ mod tests {
);
}
#[test]
fn probe_shim_publishes_stub_sql_recorder() {
let shim = probe_shim();
assert!(
shim.contains("static void __nyx_stub_sql_record"),
"Java probe shim must define __nyx_stub_sql_record"
);
assert!(
shim.contains("\"NYX_SQL_LOG\""),
"Java SQL recorder must read NYX_SQL_LOG to find the side-channel log"
);
assert!(
shim.contains("query.endsWith(\"\\n\")"),
"Java SQL recorder must guarantee a trailing newline on the query line so SqlStub::drain_events frames each record"
);
}
#[test]
fn chain_step_splices_probe_shim_for_composite_reverify() {
let step = chain_step(Some(b"<prev>"));

View file

@ -305,6 +305,29 @@ def __nyx_stub_http_record(method, url, body = nil, **detail)
rescue StandardError
end
end
# Phase 10 (Track D.3) SQL recording helper. When the verifier spawned a
# SqlStub it publishes the side-channel log path through NYX_SQL_LOG; a
# sink call site whose query never reaches the on-the-wire SQLite engine
# (no sqlite3 gem on the host, query pre-flighted before
# SQLite3::Database.open) can call this helper to surface the attempted
# query. Hash-prefixed detail lines followed by the query line so
# SqlStub::drain_events parses every language stream identically. No-op
# when NYX_SQL_LOG is unset. Single-quoted Ruby string literals keep this
# helper free of the literal hash-after-double-quote sequence.
def __nyx_stub_sql_record(query, **detail)
p = ENV['NYX_SQL_LOG']
return if p.nil? || p.empty?
begin
File.open(p, 'a') do |f|
detail.each { |k, v| f.puts('# ' + k.to_s + ': ' + v.to_s) }
line = query.to_s
line += "\n" unless line.end_with?("\n")
f.write(line)
end
rescue StandardError
end
end
"#
}
@ -825,6 +848,23 @@ mod tests {
);
}
#[test]
fn probe_shim_publishes_stub_sql_recorder() {
let shim = probe_shim();
assert!(
shim.contains("def __nyx_stub_sql_record"),
"Ruby probe shim must define __nyx_stub_sql_record"
);
assert!(
shim.contains("ENV['NYX_SQL_LOG']"),
"Ruby SQL recorder must read NYX_SQL_LOG to find the side-channel log"
);
assert!(
shim.contains("line.end_with?"),
"Ruby SQL recorder must guarantee a trailing newline on the query line so SqlStub::drain_events frames each record"
);
}
#[test]
fn chain_step_splices_probe_shim_for_composite_reverify() {
let step = chain_step(Some(b"<prev>"));