mirror of
https://github.com/elicpeter/nyx.git
synced 2026-06-15 20:05:13 +02:00
[pitboss/grind] deferred session-0020 (20260516T052512Z-20f8)
This commit is contained in:
parent
04b3d88eb4
commit
aa209148b0
8 changed files with 649 additions and 13 deletions
|
|
@ -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>"));
|
||||
|
|
|
|||
|
|
@ -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>"));
|
||||
|
|
|
|||
|
|
@ -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>"));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue