From 22b60d10905dc91869d46e91b20db2dbcdfea6ce Mon Sep 17 00:00:00 2001 From: thekevinbot <248217931+thekevinbot@users.noreply.github.com> Date: Mon, 28 Sep 2026 09:54:36 -0400 Subject: [PATCH 1/4] test(rust): serialize native paths into TOML and command fixtures A Windows path embedded raw in a TOML basic string is an invalid escape, and raw in a command template shlex strips its backslashes. Serialize with toml and shlex instead. Open files writable before set_modified, which Windows refuses on a read-only handle. --- packages/rust/tests/extensions.rs | 4 ++-- .../rust/tests/persist_parsed_path_table.rs | 24 ++++++++++++------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/packages/rust/tests/extensions.rs b/packages/rust/tests/extensions.rs index 79573a135..1dcc95d8d 100644 --- a/packages/rust/tests/extensions.rs +++ b/packages/rust/tests/extensions.rs @@ -113,7 +113,7 @@ fn loads_real_extension_and_calls_registered_function() { format!( r#" [[dirsql.extension]] -path = "{}" +path = {} entrypoint = "sqlite3_extension_init" [[table]] @@ -122,7 +122,7 @@ ddl = "CREATE TABLE files (path TEXT)" glob = "*.txt" on-file = "cat {{path}}" "#, - ext.display(), + toml::Value::String(ext.display().to_string()), ), ) .unwrap(); diff --git a/packages/rust/tests/persist_parsed_path_table.rs b/packages/rust/tests/persist_parsed_path_table.rs index 3c50dadfa..800429525 100644 --- a/packages/rust/tests/persist_parsed_path_table.rs +++ b/packages/rust/tests/persist_parsed_path_table.rs @@ -73,8 +73,8 @@ impl Fixture { fs::write(&script, format!("printf x >> \"$2\"\n{body}\n")).unwrap(); format!( "sh {} {{path}} {}", - script.display(), - self.counter.display() + shell_word(&script), + shell_word(&self.counter) ) } @@ -120,6 +120,12 @@ impl Fixture { } } +fn shell_word(path: &Path) -> String { + shlex::try_quote(&path.to_string_lossy()) + .unwrap() + .into_owned() +} + fn payload(i: usize, tag: &str) -> String { format!( "[{{\"id\":{i},\"tag\":\"{tag}\",\"body\":\"{}\"}}]", @@ -127,11 +133,16 @@ fn payload(i: usize, tag: &str) -> String { ) } +/// Windows refuses `set_modified` on a handle opened read-only. +fn writable(path: &Path) -> fs::File { + fs::OpenOptions::new().write(true).open(path).unwrap() +} + /// Push a file's mtime clear of the racy window so the stat tuple alone /// decides whether it changed. fn touch_into_the_future(path: &Path) { let future = SystemTime::now() + Duration::from_secs(5); - fs::File::open(path).unwrap().set_modified(future).unwrap(); + writable(path).set_modified(future).unwrap(); } /// Pin a file's mtime far enough ahead that every cache written during the @@ -140,7 +151,7 @@ fn touch_into_the_future(path: &Path) { /// changed and the reuse decision falls through to the content hash. fn pin_inside_the_racy_window(path: &Path) -> SystemTime { let pinned = SystemTime::now() + Duration::from_secs(3600); - fs::File::open(path).unwrap().set_modified(pinned).unwrap(); + writable(path).set_modified(pinned).unwrap(); pinned } @@ -319,10 +330,7 @@ fn content_that_leaves_the_stat_tuple_untouched_is_caught_by_the_hash() { // `payload` is the same length for either tag, so rewriting in place leaves // size, inode and device alone; restoring the mtime leaves the rest. fs::write(&edited, payload(3, "v2")).unwrap(); - fs::File::open(&edited) - .unwrap() - .set_modified(pinned) - .unwrap(); + writable(&edited).set_modified(pinned).unwrap(); let after = fs::metadata(&edited).unwrap(); assert_eq!( From 0edefc8b9a43da8e88771c0e6ed1c62045a675eb Mon Sep 17 00:00:00 2001 From: thekevinbot <248217931+thekevinbot@users.noreply.github.com> Date: Mon, 28 Sep 2026 09:54:44 -0400 Subject: [PATCH 2/4] test(rust): make on-file fixtures separator-agnostic Hook fixtures derived basename and root-relative path by splitting on '/', so on Windows the whole backslash path landed unescaped in the JSON payload. Normalize separators in the hook before splitting, keep {path} out of JSON in the run_on_file test, compute the watch helper's relative path with '/' against either root form, and give run_parser a cwd that exists on every OS. skip-changelog: test-only change inside #[cfg(test)] modules --- packages/rust/src/lib.rs | 22 ++++++++----------- packages/rust/src/parsed_vtab.rs | 9 +++++--- packages/rust/tests/cli_e2e.rs | 8 +++---- packages/rust/tests/cli_integration.rs | 2 +- packages/rust/tests/config_root_derivation.rs | 4 ++-- packages/rust/tests/declared_table_name.rs | 2 +- packages/rust/tests/from_config.rs | 14 ++++++------ packages/rust/tests/repeatable_config.rs | 2 +- packages/rust/tests/sdk.rs | 2 +- packages/rust/tests/watch_scan_correctness.rs | 12 ++++++---- 10 files changed, 40 insertions(+), 37 deletions(-) diff --git a/packages/rust/src/lib.rs b/packages/rust/src/lib.rs index 2bd2645b9..097cf961a 100644 --- a/packages/rust/src/lib.rs +++ b/packages/rust/src/lib.rs @@ -4346,15 +4346,13 @@ mod internal_tests { } /// `{abspath}` is not in the substitution table: it is left literal like any - /// unknown `{…}`, so `printf` receives the string `{abspath}` verbatim. The - /// template references `{path}` so that arg is the real path (and no path is - /// appended), isolating the `{abspath}` behavior in the `q` column. + /// unknown `{…}`, so `printf` receives the string `{abspath}` verbatim. #[test] fn run_on_file_does_not_substitute_abspath() { let dir = TempDir::new().unwrap(); let abs = dir.path().join("f.txt"); let rows = run_on_file( - r#"printf '[{"p":"%s","q":"%s"}]' {path} {abspath}"#, + r#"printf '[{"q":"%s"}]' {abspath}"#, &abs.to_string_lossy(), dir.path(), dir.path(), @@ -4365,25 +4363,23 @@ mod internal_tests { } /// `{path}` interpolates the matched file's **absolute** path (not a - /// root-relative one). The command echoes its `{path}` argument back as a - /// row value, and we assert it is byte-for-byte the absolute path even when - /// the file sits directly under `root` (the case the old `strip_prefix` - /// would have shortened to a bare relative path). + /// root-relative one), byte-for-byte, even when the file sits directly + /// under `root`. The command writes its argument to a side file rather than + /// into the JSON payload, where a Windows path's `\` would need escaping. #[test] fn run_on_file_passes_absolute_path_for_path_placeholder() { let dir = TempDir::new().unwrap(); let abs = dir.path().join("f.txt"); - let rows = run_on_file( - r#"sh -c "printf '[{\"p\":\"%s\"}]' \"$1\"" sh {path}"#, + run_on_file( + r#"sh -c 'printf %s "$1" > seen; echo "[]"' sh {path}"#, &abs.to_string_lossy(), dir.path(), dir.path(), ) .expect("a well-formed payload parses"); - assert_eq!(rows.len(), 1); assert_eq!( - rows[0]["p"], - Value::Text(abs.to_string_lossy().into_owned()) + std::fs::read_to_string(dir.path().join("seen")).unwrap(), + abs.to_string_lossy() ); } diff --git a/packages/rust/src/parsed_vtab.rs b/packages/rust/src/parsed_vtab.rs index 97b3029c2..6de118226 100644 --- a/packages/rust/src/parsed_vtab.rs +++ b/packages/rust/src/parsed_vtab.rs @@ -660,9 +660,12 @@ mod tests { #[test] fn run_parser_substitutes_the_absolute_path_and_the_root() { - let payload = - run_parser("echo {path} {root}", Path::new("/tmp"), Path::new("a.json")).unwrap(); - assert_eq!(payload, "/tmp/a.json /tmp"); + let root = std::env::temp_dir(); + let payload = run_parser("echo {path} {root}", &root, Path::new("a.json")).unwrap(); + assert_eq!( + payload, + format!("{} {}", root.join("a.json").display(), root.display()) + ); } #[test] diff --git a/packages/rust/tests/cli_e2e.rs b/packages/rust/tests/cli_e2e.rs index 5833a9ef9..cb43262dd 100644 --- a/packages/rust/tests/cli_e2e.rs +++ b/packages/rust/tests/cli_e2e.rs @@ -47,7 +47,7 @@ fn blog_fixture() -> TempDir { name = "posts" ddl = "CREATE TABLE posts (basename TEXT, size INTEGER)" glob = "posts/*/*.json" -on-file = '''sh -c 'base=${1##*/}; size=$(wc -c < "$1" | tr -d " "); printf "[{\"basename\":\"%s\",\"size\":%s}]" "$base" "$size"' sh {path}''' +on-file = '''sh -c 'p=$(printf %s "$1" | tr "\\\\" /); base=${p##*/}; size=$(wc -c < "$1" | tr -d " "); printf "[{\"basename\":\"%s\",\"size\":%s}]" "$base" "$size"' sh {path}''' "#, ) .unwrap(); @@ -69,7 +69,7 @@ fn quoted_blog_fixture() -> TempDir { name = "posts" ddl = 'CREATE TABLE "posts" (basename TEXT)' glob = "posts/*/*.json" -on-file = '''sh -c 'printf "[{\"basename\":\"%s\"}]" "${1##*/}"' sh {path}''' +on-file = '''sh -c 'p=$(printf %s "$1" | tr "\\\\" /); printf "[{\"basename\":\"%s\"}]" "${p##*/}"' sh {path}''' "#, ) .unwrap(); @@ -973,13 +973,13 @@ fn query_subcommand_fans_out_file_to_overlapping_tables() { name = "ta" ddl = "CREATE TABLE ta (path TEXT)" glob = "data/*/metadata.json" -on-file = '''sh -c 'rel=${1#"$2"/}; printf "[{\"path\":\"%s\"}]" "$rel"' sh {path} {root}''' +on-file = '''sh -c 'p=$(printf %s "$1" | tr "\\\\" /); r=$(printf %s "$2" | tr "\\\\" /); rel=${p#"$r"/}; printf "[{\"path\":\"%s\"}]" "$rel"' sh {path} {root}''' [[table]] name = "tb" ddl = "CREATE TABLE tb (path TEXT)" glob = "data/**/metadata.json" -on-file = '''sh -c 'rel=${1#"$2"/}; printf "[{\"path\":\"%s\"}]" "$rel"' sh {path} {root}''' +on-file = '''sh -c 'p=$(printf %s "$1" | tr "\\\\" /); r=$(printf %s "$2" | tr "\\\\" /); rel=${p#"$r"/}; printf "[{\"path\":\"%s\"}]" "$rel"' sh {path} {root}''' "#, ) .unwrap(); diff --git a/packages/rust/tests/cli_integration.rs b/packages/rust/tests/cli_integration.rs index 172ab4f93..c360b3f9a 100644 --- a/packages/rust/tests/cli_integration.rs +++ b/packages/rust/tests/cli_integration.rs @@ -43,7 +43,7 @@ fn blog_fixture() -> (TempDir, DirSQL) { name = "posts" ddl = "CREATE TABLE posts (basename TEXT, size INTEGER)" glob = "posts/*/*.json" -on-file = '''sh -c 'base=${1##*/}; size=$(wc -c < "$1" | tr -d " "); printf "[{\"basename\":\"%s\",\"size\":%s}]" "$base" "$size"' sh {path}''' +on-file = '''sh -c 'p=$(printf %s "$1" | tr "\\\\" /); base=${p##*/}; size=$(wc -c < "$1" | tr -d " "); printf "[{\"basename\":\"%s\",\"size\":%s}]" "$base" "$size"' sh {path}''' "#, ) .unwrap(); diff --git a/packages/rust/tests/config_root_derivation.rs b/packages/rust/tests/config_root_derivation.rs index e902aa670..144b3101a 100644 --- a/packages/rust/tests/config_root_derivation.rs +++ b/packages/rust/tests/config_root_derivation.rs @@ -60,7 +60,7 @@ fn config_without_root_indexes_process_cwd_not_config_parent() { name = "files" ddl = "CREATE TABLE files (path TEXT)" glob = "*.txt" -on-file = '''sh -c 'rel=${1#"$2"/}; printf "[{\"path\":\"%s\"}]" "$rel"' sh {path} {root}''' +on-file = '''sh -c 'p=$(printf %s "$1" | tr "\\\\" /); r=$(printf %s "$2" | tr "\\\\" /); rel=${p#"$r"/}; printf "[{\"path\":\"%s\"}]" "$rel"' sh {path} {root}''' "#, ) .unwrap(); @@ -90,7 +90,7 @@ fn explicit_root_wins_over_cwd() { name = "files" ddl = "CREATE TABLE files (path TEXT)" glob = "*.txt" -on-file = '''sh -c 'rel=${1#"$2"/}; printf "[{\"path\":\"%s\"}]" "$rel"' sh {path} {root}''' +on-file = '''sh -c 'p=$(printf %s "$1" | tr "\\\\" /); r=$(printf %s "$2" | tr "\\\\" /); rel=${p#"$r"/}; printf "[{\"path\":\"%s\"}]" "$rel"' sh {path} {root}''' "#, ) .unwrap(); diff --git a/packages/rust/tests/declared_table_name.rs b/packages/rust/tests/declared_table_name.rs index a502c22fb..cabd79e1e 100644 --- a/packages/rust/tests/declared_table_name.rs +++ b/packages/rust/tests/declared_table_name.rs @@ -10,7 +10,7 @@ use std::fs; use tempfile::TempDir; /// An `on-file` hook emitting the file's root-relative `path`. -const HOOK: &str = r#"on-file = '''sh -c 'rel=${1#"$2"/}; printf "[{\"path\":\"%s\"}]" "$rel"' sh {path} {root}'''"#; +const HOOK: &str = r#"on-file = '''sh -c 'p=$(printf %s "$1" | tr "\\\\" /); r=$(printf %s "$2" | tr "\\\\" /); rel=${p#"$r"/}; printf "[{\"path\":\"%s\"}]" "$rel"' sh {path} {root}'''"#; /// A tempdir with one matched file and a `.dirsql.toml` holding `config`. fn fixture(config: &str) -> TempDir { diff --git a/packages/rust/tests/from_config.rs b/packages/rust/tests/from_config.rs index 56568902e..3c6645062 100644 --- a/packages/rust/tests/from_config.rs +++ b/packages/rust/tests/from_config.rs @@ -18,7 +18,7 @@ fn from_config_produces_one_row_per_matched_file() { name = "files" ddl = "CREATE TABLE files (path TEXT, basename TEXT)" glob = "data/*.csv" -on-file = '''sh -c 'rel=${1#"$2"/}; base=${1##*/}; printf "[{\"path\":\"%s\",\"basename\":\"%s\"}]" "$rel" "$base"' sh {path} {root}''' +on-file = '''sh -c 'p=$(printf %s "$1" | tr "\\\\" /); r=$(printf %s "$2" | tr "\\\\" /); rel=${p#"$r"/}; base=${p##*/}; printf "[{\"path\":\"%s\",\"basename\":\"%s\"}]" "$rel" "$base"' sh {path} {root}''' "#, ) .unwrap(); @@ -57,7 +57,7 @@ ignore = ["ignored/**"] name = "files" ddl = "CREATE TABLE files (path TEXT)" glob = "**/*.csv" -on-file = '''sh -c 'rel=${1#"$2"/}; printf "[{\"path\":\"%s\"}]" "$rel"' sh {path} {root}''' +on-file = '''sh -c 'p=$(printf %s "$1" | tr "\\\\" /); r=$(printf %s "$2" | tr "\\\\" /); rel=${p#"$r"/}; printf "[{\"path\":\"%s\"}]" "$rel"' sh {path} {root}''' "#, ) .unwrap(); @@ -143,7 +143,7 @@ fn from_config_capture_placeholder_without_column_still_matches() { name = "comments" ddl = "CREATE TABLE comments (path TEXT, basename TEXT)" glob = "_comments/{thread_id}/*.txt" -on-file = '''sh -c 'rel=${1#"$2"/}; base=${1##*/}; printf "[{\"path\":\"%s\",\"basename\":\"%s\"}]" "$rel" "$base"' sh {path} {root}''' +on-file = '''sh -c 'p=$(printf %s "$1" | tr "\\\\" /); r=$(printf %s "$2" | tr "\\\\" /); rel=${p#"$r"/}; base=${p##*/}; printf "[{\"path\":\"%s\",\"basename\":\"%s\"}]" "$rel" "$base"' sh {path} {root}''' "#, ) .unwrap(); @@ -196,7 +196,7 @@ fn from_config_exposes_stat_virtuals() { name = "files" ddl = "CREATE TABLE files (path TEXT, basename TEXT, dir TEXT, ext TEXT, size INTEGER, mtime INTEGER)" glob = "docs/*.md" -on-file = '''sh -c 'rel=${1#"$2"/}; base=${1##*/}; case "$rel" in */*) dir=${rel%/*};; *) dir="";; esac; ext=${base##*.}; [ "$ext" = "$base" ] && ext=""; size=$(wc -c < "$1" | tr -d " "); mtime=$(stat -c %Y "$1"); printf "[{\"path\":\"%s\",\"basename\":\"%s\",\"dir\":\"%s\",\"ext\":\"%s\",\"size\":%s,\"mtime\":%s}]" "$rel" "$base" "$dir" "$ext" "$size" "$mtime"' sh {path} {root}''' +on-file = '''sh -c 'p=$(printf %s "$1" | tr "\\\\" /); r=$(printf %s "$2" | tr "\\\\" /); rel=${p#"$r"/}; base=${p##*/}; case "$rel" in */*) dir=${rel%/*};; *) dir="";; esac; ext=${base##*.}; [ "$ext" = "$base" ] && ext=""; size=$(wc -c < "$1" | tr -d " "); mtime=$(stat -c %Y "$1"); printf "[{\"path\":\"%s\",\"basename\":\"%s\",\"dir\":\"%s\",\"ext\":\"%s\",\"size\":%s,\"mtime\":%s}]" "$rel" "$base" "$dir" "$ext" "$size" "$mtime"' sh {path} {root}''' "#, ) .unwrap(); @@ -243,7 +243,7 @@ fn from_config_undeclared_stat_columns_are_silently_dropped() { name = "minimal" ddl = "CREATE TABLE minimal (path TEXT)" glob = "*.txt" -on-file = '''sh -c 'rel=${1#"$2"/}; base=${1##*/}; printf "[{\"path\":\"%s\",\"basename\":\"%s\"}]" "$rel" "$base"' sh {path} {root}''' +on-file = '''sh -c 'p=$(printf %s "$1" | tr "\\\\" /); r=$(printf %s "$2" | tr "\\\\" /); rel=${p#"$r"/}; base=${p##*/}; printf "[{\"path\":\"%s\",\"basename\":\"%s\"}]" "$rel" "$base"' sh {path} {root}''' "#, ) .unwrap(); @@ -377,7 +377,7 @@ name = "files" ddl = "CREATE TABLE files (path TEXT)" glob = "*.csv" strict = true -on-file = '''sh -c 'rel=${1#"$2"/}; printf "[{\"path\":\"%s\"}]" "$rel"' sh {path} {root}''' +on-file = '''sh -c 'p=$(printf %s "$1" | tr "\\\\" /); r=$(printf %s "$2" | tr "\\\\" /); rel=${p#"$r"/}; printf "[{\"path\":\"%s\"}]" "$rel"' sh {path} {root}''' "#, ) .unwrap(); @@ -403,7 +403,7 @@ async fn async_from_config_works() { name = "files" ddl = "CREATE TABLE files (path TEXT, basename TEXT)" glob = "*.csv" -on-file = '''sh -c 'rel=${1#"$2"/}; base=${1##*/}; printf "[{\"path\":\"%s\",\"basename\":\"%s\"}]" "$rel" "$base"' sh {path} {root}''' +on-file = '''sh -c 'p=$(printf %s "$1" | tr "\\\\" /); r=$(printf %s "$2" | tr "\\\\" /); rel=${p#"$r"/}; base=${p##*/}; printf "[{\"path\":\"%s\",\"basename\":\"%s\"}]" "$rel" "$base"' sh {path} {root}''' "#, ) .unwrap(); diff --git a/packages/rust/tests/repeatable_config.rs b/packages/rust/tests/repeatable_config.rs index 918fec649..77698e4ad 100644 --- a/packages/rust/tests/repeatable_config.rs +++ b/packages/rust/tests/repeatable_config.rs @@ -25,7 +25,7 @@ fn table_config(name: &str) -> String { name = "{name}" ddl = "CREATE TABLE {name} (basename TEXT)" glob = "*.json" -on-file = '''sh -c 'printf "[{{\"basename\":\"%s\"}}]" "${{1##*/}}"' sh {{path}}''' +on-file = '''sh -c 'p=$(printf %s "$1" | tr "\\\\" /); printf "[{{\"basename\":\"%s\"}}]" "${{p##*/}}"' sh {{path}}''' "# ) } diff --git a/packages/rust/tests/sdk.rs b/packages/rust/tests/sdk.rs index 6ec829ff7..ac6594d37 100644 --- a/packages/rust/tests/sdk.rs +++ b/packages/rust/tests/sdk.rs @@ -653,7 +653,7 @@ fn builder_explicit_root_wins_over_config_directory() { name = "items" ddl = "CREATE TABLE items (basename TEXT)" glob = "*.json" -on-file = '''sh -c 'printf "[{\"basename\":\"%s\"}]" "${1##*/}"' sh {path}''' +on-file = '''sh -c 'p=$(printf %s "$1" | tr "\\\\" /); printf "[{\"basename\":\"%s\"}]" "${p##*/}"' sh {path}''' "#, ) .unwrap(); diff --git a/packages/rust/tests/watch_scan_correctness.rs b/packages/rust/tests/watch_scan_correctness.rs index 60faaee31..c7e158e6a 100644 --- a/packages/rust/tests/watch_scan_correctness.rs +++ b/packages/rust/tests/watch_scan_correctness.rs @@ -13,7 +13,8 @@ use std::time::{Duration, Instant}; /// A table matching *every* path (like the default `files` table's `**/*`), /// so a newly created subdirectory is a matcher candidate on the watch path. fn files_table(root: &std::path::Path) -> Table { - let root = fs::canonicalize(root).unwrap_or_else(|_| root.to_path_buf()); + let canonical = fs::canonicalize(root).unwrap_or_else(|_| root.to_path_buf()); + let root = root.to_path_buf(); Table::new( "files", "CREATE TABLE files (name TEXT, path TEXT)", @@ -22,10 +23,13 @@ fn files_table(root: &std::path::Path) -> Table { let content = fs::read_to_string(path).unwrap_or_default(); let abs = std::path::Path::new(path); let rel = abs - .strip_prefix(&root) + .strip_prefix(&canonical) + .or_else(|_| abs.strip_prefix(&root)) .unwrap_or(abs) - .to_string_lossy() - .into_owned(); + .iter() + .map(|part| part.to_string_lossy()) + .collect::>() + .join("/"); vec![HashMap::from([ ("name".to_string(), Value::Text(content.trim().to_string())), ("path".to_string(), Value::Text(rel)), From 4972013b7c67d244d8536443829c145ef58fed3b Mon Sep 17 00:00:00 2001 From: thekevinbot <248217931+thekevinbot@users.noreply.github.com> Date: Mon, 28 Sep 2026 09:57:14 -0400 Subject: [PATCH 3/4] e2e attestation for claude/1186-win-test-harness --- .../e2e-attestations/claude-1186-win-test-harness.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 packages/python/e2e-attestations/claude-1186-win-test-harness.json diff --git a/packages/python/e2e-attestations/claude-1186-win-test-harness.json b/packages/python/e2e-attestations/claude-1186-win-test-harness.json new file mode 100644 index 000000000..a88005f71 --- /dev/null +++ b/packages/python/e2e-attestations/claude-1186-win-test-harness.json @@ -0,0 +1,7 @@ +{ + "command": "just test-e2e", + "ran_at": 1790603833, + "exit_code": 0, + "commit": "6b84d84d60179482a842b0db205ee257f8e03c11", + "branch": "claude/1186-win-test-harness" +} From ba7a360e40682ece0d4724bd85b2760db46b8ba5 Mon Sep 17 00:00:00 2001 From: thekevinbot <248217931+thekevinbot@users.noreply.github.com> Date: Mon, 28 Sep 2026 09:59:38 -0400 Subject: [PATCH 4/4] e2e attestation for claude/1186-win-test-harness --- .../ts/e2e-attestations/claude-1186-win-test-harness.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 packages/ts/e2e-attestations/claude-1186-win-test-harness.json diff --git a/packages/ts/e2e-attestations/claude-1186-win-test-harness.json b/packages/ts/e2e-attestations/claude-1186-win-test-harness.json new file mode 100644 index 000000000..2e691adc3 --- /dev/null +++ b/packages/ts/e2e-attestations/claude-1186-win-test-harness.json @@ -0,0 +1,7 @@ +{ + "command": "pnpm test:e2e", + "ran_at": 1790603978, + "exit_code": 0, + "commit": "3aa71ff81e229fd7f5da6536659b45fc7c54e559", + "branch": "claude/1186-win-test-harness" +}