From b96388872f9cd4d60fd7f2bb8620c2997307a4c6 Mon Sep 17 00:00:00 2001 From: thekevinbot <248217931+thekevinbot@users.noreply.github.com> Date: Mon, 5 Oct 2026 20:15:46 -0400 Subject: [PATCH 1/9] test: unbalanced braces and brackets in a glob are literal --- packages/rust/tests/unbalanced_glob_e2e.rs | 110 +++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 packages/rust/tests/unbalanced_glob_e2e.rs diff --git a/packages/rust/tests/unbalanced_glob_e2e.rs b/packages/rust/tests/unbalanced_glob_e2e.rs new file mode 100644 index 000000000..e28b1e638 --- /dev/null +++ b/packages/rust/tests/unbalanced_glob_e2e.rs @@ -0,0 +1,110 @@ +//! A `{`, `}` or `[` with no partner is a literal character, as in bash, on +//! both the path-table and the `[[table]] glob` surfaces. Real binary, real +//! files, nothing mocked. + +#![cfg(all(feature = "cli", unix))] + +use std::fs; +use std::process::Output; + +use assert_cmd::prelude::*; +use serde_json::Value; +use tempfile::TempDir; + +const NAMES: [&str; 5] = ["{a.json", "a}.json", "[a.json", "a[b.json", "a.json"]; + +fn fixture(glob: &str) -> TempDir { + let root = TempDir::new().unwrap(); + for name in NAMES { + fs::write(root.path().join(name), r#"[{"id": "row"}]"#).unwrap(); + } + fs::write( + root.path().join(".dirsql.toml"), + format!( + "[[table]]\nname = \"t\"\nddl = \"CREATE TABLE t (id TEXT)\"\nglob = \"{glob}\"\non-file = \"cat\"\n" + ), + ) + .unwrap(); + root +} + +fn query(root: &TempDir, sql: &str) -> Output { + std::process::Command::cargo_bin("dirsql") + .unwrap() + .arg("query") + .arg(sql) + .arg("--config") + .arg(root.path().join(".dirsql.toml")) + .current_dir(root.path()) + .output() + .unwrap() +} + +fn count(root: &TempDir, sql: &str) -> usize { + let out = query(root, sql); + assert!( + out.status.success(), + "stderr: {}", + String::from_utf8_lossy(&out.stderr) + ); + serde_json::from_slice::>(&out.stdout) + .unwrap() + .len() +} + +fn table_matches(glob: &str) -> usize { + count(&fixture(glob), "SELECT id FROM t") +} + +fn path_matches(pattern: &str) -> Vec { + let root = fixture("a.json"); + let out = query(&root, &format!("SELECT path FROM './{pattern}'")); + assert!( + out.status.success(), + "stderr: {}", + String::from_utf8_lossy(&out.stderr) + ); + serde_json::from_slice::>(&out.stdout) + .unwrap() + .iter() + .map(|r| r["path"].as_str().unwrap().to_string()) + .collect() +} + +#[test] +fn a_table_glob_with_an_unclosed_brace_is_literal() { + assert_eq!(table_matches("{a.json"), 1); +} + +#[test] +fn a_table_glob_with_an_unopened_brace_is_literal() { + assert_eq!(table_matches("a}.json"), 1); +} + +#[test] +fn a_table_glob_with_an_unclosed_bracket_is_literal() { + assert_eq!(table_matches("[a.json"), 1); + assert_eq!(table_matches("a[b.json"), 1); +} + +#[test] +fn a_table_glob_with_a_balanced_alternation_still_alternates() { + assert_eq!(table_matches("{a,b}.json"), 1); +} + +#[test] +fn a_path_table_with_an_unclosed_bracket_is_literal() { + assert_eq!(path_matches("[a.json"), vec!["[a.json"]); + assert_eq!(path_matches("a[b.json"), vec!["a[b.json"]); +} + +#[test] +fn a_path_table_with_an_unclosed_bracket_before_a_brace_group_is_literal() { + assert!(path_matches("[{q}.json").is_empty()); +} + +#[test] +fn a_path_table_with_unbalanced_braces_is_literal() { + assert_eq!(path_matches("{a.json"), vec!["{a.json"]); + assert_eq!(path_matches("a}.json"), vec!["a}.json"]); +} From df0774263bbc25a5602a4295764a4434f3b07598 Mon Sep 17 00:00:00 2001 From: thekevinbot <248217931+thekevinbot@users.noreply.github.com> Date: Mon, 5 Oct 2026 20:19:09 -0400 Subject: [PATCH 2/9] Treat an unbalanced brace or bracket in a glob as a literal character --- docs/reference/path-tables.md | 4 +- .../2026-10-05-unbalanced-brackets-literal.md | 1 + .../2026-10-05-unbalanced-brackets-literal.md | 29 ++++++ .../2026-10-05-unbalanced-brackets-literal.md | 1 + .../2026-10-05-unbalanced-brackets-literal.md | 29 ++++++ packages/rust/src/brace.rs | 14 +-- packages/rust/src/lib.rs | 1 + packages/rust/src/matcher.rs | 7 +- packages/rust/src/parsed_vtab.rs | 2 +- packages/rust/src/scanner.rs | 2 +- packages/rust/src/unbalanced.rs | 89 +++++++++++++++++++ packages/rust/src/vtab.rs | 2 +- packages/rust/src/vtab_scaffold.rs | 2 +- packages/rust/tests/sdk.rs | 2 +- .../2026-10-05-unbalanced-brackets-literal.md | 1 + .../2026-10-05-unbalanced-brackets-literal.md | 29 ++++++ 16 files changed, 200 insertions(+), 15 deletions(-) create mode 100644 packages/python/changelog.d/2026-10-05-unbalanced-brackets-literal.md create mode 100644 packages/python/migrations.d/2026-10-05-unbalanced-brackets-literal.md create mode 100644 packages/rust/changelog.d/2026-10-05-unbalanced-brackets-literal.md create mode 100644 packages/rust/migrations.d/2026-10-05-unbalanced-brackets-literal.md create mode 100644 packages/rust/src/unbalanced.rs create mode 100644 packages/ts/changelog.d/2026-10-05-unbalanced-brackets-literal.md create mode 100644 packages/ts/migrations.d/2026-10-05-unbalanced-brackets-literal.md diff --git a/docs/reference/path-tables.md b/docs/reference/path-tables.md index 52b830ef5..0b316f8cc 100644 --- a/docs/reference/path-tables.md +++ b/docs/reference/path-tables.md @@ -59,7 +59,9 @@ alternation: `'./docs/{a,b}.md'` is `docs/a.md` and `docs/b.md`, and groups nest. A group holding a `..` range counts: `'./log/{1..3}.txt'`, `'./{a..c}.md'`, `'./{01..10}.md'` (zero-padded) and `'./{1..10..2}.md'` (every second value). Any other brace is literal text, so `'./br/{q}.md'` -names the file `br/{q}.md`, and `\{` is always a literal brace. +names the file `br/{q}.md`, and `\{` is always a literal brace. A `{`, `}` +or `[` with no partner is literal too, in a path-table and in a config +`[[table]] glob`. The scan starts at the last directory named outright before the first glob component, and descends only as deep as the pattern can match -- diff --git a/packages/python/changelog.d/2026-10-05-unbalanced-brackets-literal.md b/packages/python/changelog.d/2026-10-05-unbalanced-brackets-literal.md new file mode 100644 index 000000000..0d11f4c86 --- /dev/null +++ b/packages/python/changelog.d/2026-10-05-unbalanced-brackets-literal.md @@ -0,0 +1 @@ +**Fixed** An unmatched `{`, `}` or `[` in a path-table or a config `[[table]] glob` is a literal character, as in bash, instead of a glob compile error. diff --git a/packages/python/migrations.d/2026-10-05-unbalanced-brackets-literal.md b/packages/python/migrations.d/2026-10-05-unbalanced-brackets-literal.md new file mode 100644 index 000000000..4e88403e1 --- /dev/null +++ b/packages/python/migrations.d/2026-10-05-unbalanced-brackets-literal.md @@ -0,0 +1,29 @@ +### Core: unbalanced braces and brackets in a glob are literal + +#### Summary + +A `{`, `}` or `[` with no partner in a glob is now a literal character, as in +bash, on path-tables and on config `[[table]] glob`. It used to fail with a +glob compile error. Nothing that compiled before changes meaning. + +#### Required changes + +_None._ + +#### Deprecations removed + +_None._ + +#### Behavior changes without code changes + +- `'./{a.md'`, `'./a}.md'`, `'./[a.md'` and `'./a[b.md'` match files named + exactly that instead of failing to compile. + +#### Verification + +```bash +cd "$(mktemp -d)" +touch '[a.md' +dirsql query "SELECT path FROM './[a.md'" +# expected: [{"path":"[a.md"}] +``` diff --git a/packages/rust/changelog.d/2026-10-05-unbalanced-brackets-literal.md b/packages/rust/changelog.d/2026-10-05-unbalanced-brackets-literal.md new file mode 100644 index 000000000..0d11f4c86 --- /dev/null +++ b/packages/rust/changelog.d/2026-10-05-unbalanced-brackets-literal.md @@ -0,0 +1 @@ +**Fixed** An unmatched `{`, `}` or `[` in a path-table or a config `[[table]] glob` is a literal character, as in bash, instead of a glob compile error. diff --git a/packages/rust/migrations.d/2026-10-05-unbalanced-brackets-literal.md b/packages/rust/migrations.d/2026-10-05-unbalanced-brackets-literal.md new file mode 100644 index 000000000..4e88403e1 --- /dev/null +++ b/packages/rust/migrations.d/2026-10-05-unbalanced-brackets-literal.md @@ -0,0 +1,29 @@ +### Core: unbalanced braces and brackets in a glob are literal + +#### Summary + +A `{`, `}` or `[` with no partner in a glob is now a literal character, as in +bash, on path-tables and on config `[[table]] glob`. It used to fail with a +glob compile error. Nothing that compiled before changes meaning. + +#### Required changes + +_None._ + +#### Deprecations removed + +_None._ + +#### Behavior changes without code changes + +- `'./{a.md'`, `'./a}.md'`, `'./[a.md'` and `'./a[b.md'` match files named + exactly that instead of failing to compile. + +#### Verification + +```bash +cd "$(mktemp -d)" +touch '[a.md' +dirsql query "SELECT path FROM './[a.md'" +# expected: [{"path":"[a.md"}] +``` diff --git a/packages/rust/src/brace.rs b/packages/rust/src/brace.rs index b96fe195f..282318eac 100644 --- a/packages/rust/src/brace.rs +++ b/packages/rust/src/brace.rs @@ -198,7 +198,7 @@ fn steps(lo: i64, hi: i64, step: i64) -> Option> { /// Escape the braces bash left as literal text, so globset matches them /// rather than reading an alternation. A complete `[...]` class is copied as -/// written; an unclosed one ends escaping so globset reports the error. +/// written; an unclosed `[` is a literal character. fn escape_braces(word: &str) -> String { let chars: Vec = word.chars().collect(); let mut out = String::with_capacity(word.len()); @@ -223,8 +223,8 @@ fn escape_braces(word: &str) -> String { resume = end + 1; } None => { - out.extend(&chars[i..]); - return out; + out.push_str("[[]"); + resume = i + 1; } }, ('{', _) => out.push_str("[{]"), @@ -237,7 +237,7 @@ fn escape_braces(word: &str) -> String { /// Index of the `]` closing the class globset opens at `open`, where a `]` /// first in the class (after any `!` / `^`) is a member, not the close. -fn class_end(chars: &[char], open: usize) -> Option { +pub(crate) fn class_end(chars: &[char], open: usize) -> Option { let mut i = open + 1; if matches!(chars.get(i), Some('!' | '^')) { i += 1; @@ -411,9 +411,9 @@ mod tests { } #[test] - fn an_unclosed_class_ends_escaping() { - assert_eq!(escape_braces("x[{q}"), "x[{q}"); - assert_eq!(escape_braces("x[]{"), "x[]{"); + fn an_unclosed_bracket_is_literal() { + assert_eq!(escape_braces("x[{q}"), "x[[][{]q[}]"); + assert_eq!(escape_braces("x[]{"), "x[[]][{]"); } #[test] diff --git a/packages/rust/src/lib.rs b/packages/rust/src/lib.rs index c787bde08..51a1c9ecd 100644 --- a/packages/rust/src/lib.rs +++ b/packages/rust/src/lib.rs @@ -43,6 +43,7 @@ pub mod row_event_flat; pub mod scanner; #[doc(hidden)] pub mod sql_literal; +mod unbalanced; #[doc(hidden)] pub mod vtab; mod vtab_scaffold; diff --git a/packages/rust/src/matcher.rs b/packages/rust/src/matcher.rs index fa72d42c3..ea5821e68 100644 --- a/packages/rust/src/matcher.rs +++ b/packages/rust/src/matcher.rs @@ -1,4 +1,5 @@ use crate::posix_class::expand_posix_classes; +use crate::unbalanced::escape_unbalanced; use globset::GlobBuilder; use regex::{Regex, RegexBuilder}; use std::path::Path; @@ -161,7 +162,9 @@ impl TableMatcher { let mut entries = Vec::new(); for (pattern, table_name) in mappings { entries.push(PatternEntry { - pattern: Pattern::new(&glob_with_placeholders_as_star(pattern))?, + pattern: Pattern::new(&escape_unbalanced(&glob_with_placeholders_as_star( + pattern, + )))?, table_name: table_name.to_string(), }); } @@ -320,7 +323,7 @@ mod tests { #[test] fn invalid_glob_returns_error() { - let result = TableMatcher::new(&[("[invalid", "t")], &[]); + let result = TableMatcher::new(&[("[z-a]", "t")], &[]); assert!(result.is_err()); } diff --git a/packages/rust/src/parsed_vtab.rs b/packages/rust/src/parsed_vtab.rs index e07a4c64b..706b8e271 100644 --- a/packages/rust/src/parsed_vtab.rs +++ b/packages/rust/src/parsed_vtab.rs @@ -291,7 +291,7 @@ mod tests { #[test] fn parse_module_args_rejects_an_invalid_glob() { - let args = args_with(&[b"'/tmp'", b"'['", b"'cat'", b"'gitignore'", b"'/tmp'"]); + let args = args_with(&[b"'/tmp'", b"'[z-a]'", b"'cat'", b"'gitignore'", b"'/tmp'"]); assert!(parse_module_args(&args).is_err()); } diff --git a/packages/rust/src/scanner.rs b/packages/rust/src/scanner.rs index ac8849359..4c9376901 100644 --- a/packages/rust/src/scanner.rs +++ b/packages/rust/src/scanner.rs @@ -641,7 +641,7 @@ mod tests { #[test] fn compile_glob_rejects_an_invalid_pattern() { - assert!(compile_glob("[").is_err()); + assert!(compile_glob("[z-a]").is_err()); } #[test] diff --git a/packages/rust/src/unbalanced.rs b/packages/rust/src/unbalanced.rs new file mode 100644 index 000000000..90ad0895a --- /dev/null +++ b/packages/rust/src/unbalanced.rs @@ -0,0 +1,89 @@ +//! Bash reads a `{`, `}` or `[` with no partner as a literal character; +//! globset refuses it. Spell each such character as a one-member class. + +use crate::brace::class_end; + +/// `glob` with every unmatched `{`, `}` and `[` escaped for globset. A +/// complete `[...]` class and a balanced `{...}` group are left as written. +pub(crate) fn escape_unbalanced(glob: &str) -> String { + let chars: Vec = glob.chars().collect(); + let mut literal = vec![false; chars.len()]; + let mut open = Vec::new(); + let mut i = 0; + while i < chars.len() { + match chars[i] { + '\\' => i += 1, + '[' => match class_end(&chars, i) { + Some(end) => i = end, + None => literal[i] = true, + }, + '{' => open.push(i), + '}' => { + if open.pop().is_none() { + literal[i] = true; + } + } + _ => {} + } + i += 1; + } + for unclosed in open { + literal[unclosed] = true; + } + let mut out = String::with_capacity(glob.len()); + for (c, lit) in chars.iter().zip(literal) { + if lit { + out.extend(['[', *c, ']']); + } else { + out.push(*c); + } + } + out +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn an_unclosed_brace_is_escaped() { + assert_eq!(escape_unbalanced("{a.md"), "[{]a.md"); + assert_eq!(escape_unbalanced("{a,b.md"), "[{]a,b.md"); + } + + #[test] + fn an_unopened_brace_is_escaped() { + assert_eq!(escape_unbalanced("a}.md"), "a[}].md"); + assert_eq!(escape_unbalanced("{a,b}}.md"), "{a,b}[}].md"); + } + + #[test] + fn an_unclosed_bracket_is_escaped() { + assert_eq!(escape_unbalanced("[a.md"), "[[]a.md"); + assert_eq!(escape_unbalanced("a[]b"), "a[[]]b"); + assert_eq!(escape_unbalanced("[!a"), "[[]!a"); + } + + #[test] + fn a_stray_closing_bracket_is_left_alone() { + assert_eq!(escape_unbalanced("a].md"), "a].md"); + } + + #[test] + fn balanced_groups_and_classes_are_untouched() { + for glob in ["{a,b}.md", "[ab].md", "[{]x[}]", "{a,{b,c}}", "[]a].md"] { + assert_eq!(escape_unbalanced(glob), glob); + } + } + + #[test] + fn braces_inside_a_class_do_not_count() { + assert_eq!(escape_unbalanced("[{]a}"), "[{]a[}]"); + } + + #[test] + fn an_escaped_character_does_not_count() { + assert_eq!(escape_unbalanced(r"\{a"), r"\{a"); + assert_eq!(escape_unbalanced(r"\[a"), r"\[a"); + } +} diff --git a/packages/rust/src/vtab.rs b/packages/rust/src/vtab.rs index 7cdd34429..5dae38e4e 100644 --- a/packages/rust/src/vtab.rs +++ b/packages/rust/src/vtab.rs @@ -562,7 +562,7 @@ mod tests { #[test] fn parse_module_args_rejects_an_invalid_glob() { - let args = args_with(&[b"'/tmp'", b"'['", b"''", b"'gitignore'"]); + let args = args_with(&[b"'/tmp'", b"'[z-a]'", b"''", b"'gitignore'"]); assert!(parse_module_args(&args).is_err()); } diff --git a/packages/rust/src/vtab_scaffold.rs b/packages/rust/src/vtab_scaffold.rs index 7ae701a64..c2f0d3116 100644 --- a/packages/rust/src/vtab_scaffold.rs +++ b/packages/rust/src/vtab_scaffold.rs @@ -669,7 +669,7 @@ mod tests { #[test] fn compile_glob_rejects_an_invalid_pattern() { - let err = compile_glob("[").unwrap_err(); + let err = compile_glob("[z-a]").unwrap_err(); assert!( matches!(err, Error::ModuleError(_)), "invalid globs surface as module errors, got {err:?}" diff --git a/packages/rust/tests/sdk.rs b/packages/rust/tests/sdk.rs index a6375703c..dee29682b 100644 --- a/packages/rust/tests/sdk.rs +++ b/packages/rust/tests/sdk.rs @@ -831,7 +831,7 @@ fn declared_name_absent_from_the_catalog_errors() { #[test] fn invalid_glob_errors() { let root = TempDir::new().unwrap(); - let table = Table::new("t", "CREATE TABLE t (x TEXT)", "a[b", |_| vec![]); + let table = Table::new("t", "CREATE TABLE t (x TEXT)", "a[z-a]", |_| vec![]); let result = DirSQL::new(root.path(), vec![table]); assert!(matches!(result, Err(dirsql::DirSqlError::Matcher { .. }))); } diff --git a/packages/ts/changelog.d/2026-10-05-unbalanced-brackets-literal.md b/packages/ts/changelog.d/2026-10-05-unbalanced-brackets-literal.md new file mode 100644 index 000000000..0d11f4c86 --- /dev/null +++ b/packages/ts/changelog.d/2026-10-05-unbalanced-brackets-literal.md @@ -0,0 +1 @@ +**Fixed** An unmatched `{`, `}` or `[` in a path-table or a config `[[table]] glob` is a literal character, as in bash, instead of a glob compile error. diff --git a/packages/ts/migrations.d/2026-10-05-unbalanced-brackets-literal.md b/packages/ts/migrations.d/2026-10-05-unbalanced-brackets-literal.md new file mode 100644 index 000000000..4e88403e1 --- /dev/null +++ b/packages/ts/migrations.d/2026-10-05-unbalanced-brackets-literal.md @@ -0,0 +1,29 @@ +### Core: unbalanced braces and brackets in a glob are literal + +#### Summary + +A `{`, `}` or `[` with no partner in a glob is now a literal character, as in +bash, on path-tables and on config `[[table]] glob`. It used to fail with a +glob compile error. Nothing that compiled before changes meaning. + +#### Required changes + +_None._ + +#### Deprecations removed + +_None._ + +#### Behavior changes without code changes + +- `'./{a.md'`, `'./a}.md'`, `'./[a.md'` and `'./a[b.md'` match files named + exactly that instead of failing to compile. + +#### Verification + +```bash +cd "$(mktemp -d)" +touch '[a.md' +dirsql query "SELECT path FROM './[a.md'" +# expected: [{"path":"[a.md"}] +``` From ed99769118bf0dd064fcca93a778bdb0c02b37b1 Mon Sep 17 00:00:00 2001 From: thekevinbot <248217931+thekevinbot@users.noreply.github.com> Date: Mon, 5 Oct 2026 20:38:30 -0400 Subject: [PATCH 3/9] Collapse the unmatched closing brace arm --- packages/rust/src/unbalanced.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/rust/src/unbalanced.rs b/packages/rust/src/unbalanced.rs index 90ad0895a..c71fe83e9 100644 --- a/packages/rust/src/unbalanced.rs +++ b/packages/rust/src/unbalanced.rs @@ -18,11 +18,7 @@ pub(crate) fn escape_unbalanced(glob: &str) -> String { None => literal[i] = true, }, '{' => open.push(i), - '}' => { - if open.pop().is_none() { - literal[i] = true; - } - } + '}' if open.pop().is_none() => literal[i] = true, _ => {} } i += 1; From d525bf0d9bdd1fc27f9dd12b101cc3b2217b3933 Mon Sep 17 00:00:00 2001 From: thekevinbot <248217931+thekevinbot@users.noreply.github.com> Date: Mon, 5 Oct 2026 21:03:02 -0400 Subject: [PATCH 4/9] e2e attestation for claude/1268-unbalanced-brackets --- .../e2e-attestations/claude-1268-unbalanced-brackets.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 packages/ts/e2e-attestations/claude-1268-unbalanced-brackets.json diff --git a/packages/ts/e2e-attestations/claude-1268-unbalanced-brackets.json b/packages/ts/e2e-attestations/claude-1268-unbalanced-brackets.json new file mode 100644 index 000000000..df952acf8 --- /dev/null +++ b/packages/ts/e2e-attestations/claude-1268-unbalanced-brackets.json @@ -0,0 +1,7 @@ +{ + "command": "pnpm test:e2e", + "ran_at": 1791248582, + "exit_code": 0, + "commit": "845cd6d4853e01cb8a9c8e75c25719d0b104d816", + "branch": "claude/1268-unbalanced-brackets" +} From 6a15a72f4ed1e2a4083c15b665ed65d5451b6593 Mon Sep 17 00:00:00 2001 From: thekevinbot <248217931+thekevinbot@users.noreply.github.com> Date: Mon, 5 Oct 2026 21:17:14 -0400 Subject: [PATCH 5/9] Leave the resume index alone at an unclosed bracket --- packages/rust/src/brace.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/rust/src/brace.rs b/packages/rust/src/brace.rs index 282318eac..b31f10b4a 100644 --- a/packages/rust/src/brace.rs +++ b/packages/rust/src/brace.rs @@ -222,10 +222,7 @@ fn escape_braces(word: &str) -> String { out.extend(&chars[i..=end]); resume = end + 1; } - None => { - out.push_str("[[]"); - resume = i + 1; - } + None => out.push_str("[[]"), }, ('{', _) => out.push_str("[{]"), ('}', _) => out.push_str("[}]"), From cece7cc086e5a529c16df9a8c206c4a3a3c4620b Mon Sep 17 00:00:00 2001 From: thekevinbot <248217931+thekevinbot@users.noreply.github.com> Date: Tue, 6 Oct 2026 11:47:06 -0400 Subject: [PATCH 6/9] e2e attestation for claude/1268-unbalanced-brackets --- .../e2e-attestations/claude-1268-unbalanced-brackets.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 packages/python/e2e-attestations/claude-1268-unbalanced-brackets.json diff --git a/packages/python/e2e-attestations/claude-1268-unbalanced-brackets.json b/packages/python/e2e-attestations/claude-1268-unbalanced-brackets.json new file mode 100644 index 000000000..c9fe05f66 --- /dev/null +++ b/packages/python/e2e-attestations/claude-1268-unbalanced-brackets.json @@ -0,0 +1,7 @@ +{ + "command": "uv run python -m pytest tests/e2e/glob_speed_depth_bound_test.py tests/e2e/glob_speed_recursive_test.py tests/e2e/query_contract_test.py tests/e2e/fanout_test.py tests/e2e/capture_collision_test.py -x -q", + "ran_at": 1791301626, + "exit_code": 0, + "commit": "536bce1bbf2ea97a35b59815b8997d5b0428dd59", + "branch": "claude/1268-unbalanced-brackets" +} From ef16ec32a348a32f88897bbfdeb4b931c0ee6f3c Mon Sep 17 00:00:00 2001 From: thekevinbot <248217931+thekevinbot@users.noreply.github.com> Date: Tue, 6 Oct 2026 15:27:58 -0400 Subject: [PATCH 7/9] e2e attestation for claude/1268-unbalanced-brackets --- .../e2e-attestations/claude-1268-unbalanced-brackets.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/python/e2e-attestations/claude-1268-unbalanced-brackets.json b/packages/python/e2e-attestations/claude-1268-unbalanced-brackets.json index c9fe05f66..945885763 100644 --- a/packages/python/e2e-attestations/claude-1268-unbalanced-brackets.json +++ b/packages/python/e2e-attestations/claude-1268-unbalanced-brackets.json @@ -1,7 +1,7 @@ { - "command": "uv run python -m pytest tests/e2e/glob_speed_depth_bound_test.py tests/e2e/glob_speed_recursive_test.py tests/e2e/query_contract_test.py tests/e2e/fanout_test.py tests/e2e/capture_collision_test.py -x -q", - "ran_at": 1791301626, + "command": "uv run python -m pytest tests/e2e/glob_speed_depth_bound_test.py tests/e2e/glob_speed_recursive_test.py tests/e2e/glob_speed_one_level_test.py tests/e2e/glob_speed_matchers_test.py tests/e2e/glob_speed_dotfiles_test.py tests/e2e/query_contract_test.py tests/e2e/fanout_test.py tests/e2e/capture_collision_test.py -x -q", + "ran_at": 1791314878, "exit_code": 0, - "commit": "536bce1bbf2ea97a35b59815b8997d5b0428dd59", + "commit": "a410b6780b4c65c7a027ddd863bb35b912531026", "branch": "claude/1268-unbalanced-brackets" } From 1b7fe8a7f8e4cd8a870c76fc6e26cd087c431dc3 Mon Sep 17 00:00:00 2001 From: thekevinbot <248217931+thekevinbot@users.noreply.github.com> Date: Tue, 6 Oct 2026 18:31:11 -0400 Subject: [PATCH 8/9] e2e attestation for claude/1268-unbalanced-brackets --- .../e2e-attestations/claude-1268-unbalanced-brackets.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/python/e2e-attestations/claude-1268-unbalanced-brackets.json b/packages/python/e2e-attestations/claude-1268-unbalanced-brackets.json index 945885763..df9b02e31 100644 --- a/packages/python/e2e-attestations/claude-1268-unbalanced-brackets.json +++ b/packages/python/e2e-attestations/claude-1268-unbalanced-brackets.json @@ -1,7 +1,7 @@ { "command": "uv run python -m pytest tests/e2e/glob_speed_depth_bound_test.py tests/e2e/glob_speed_recursive_test.py tests/e2e/glob_speed_one_level_test.py tests/e2e/glob_speed_matchers_test.py tests/e2e/glob_speed_dotfiles_test.py tests/e2e/query_contract_test.py tests/e2e/fanout_test.py tests/e2e/capture_collision_test.py -x -q", - "ran_at": 1791314878, + "ran_at": 1791325871, "exit_code": 0, - "commit": "a410b6780b4c65c7a027ddd863bb35b912531026", + "commit": "45535f123cfc3ea9cf9460c228196e2630d377db", "branch": "claude/1268-unbalanced-brackets" } From ae9dc60256c7b8cb16bbf88170c72138a5f70e9c Mon Sep 17 00:00:00 2001 From: thekevinbot <248217931+thekevinbot@users.noreply.github.com> Date: Tue, 6 Oct 2026 18:33:10 -0400 Subject: [PATCH 9/9] e2e attestation for claude/1268-unbalanced-brackets --- .../ts/e2e-attestations/claude-1268-unbalanced-brackets.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/ts/e2e-attestations/claude-1268-unbalanced-brackets.json b/packages/ts/e2e-attestations/claude-1268-unbalanced-brackets.json index df952acf8..20d328d85 100644 --- a/packages/ts/e2e-attestations/claude-1268-unbalanced-brackets.json +++ b/packages/ts/e2e-attestations/claude-1268-unbalanced-brackets.json @@ -1,7 +1,7 @@ { "command": "pnpm test:e2e", - "ran_at": 1791248582, + "ran_at": 1791325990, "exit_code": 0, - "commit": "845cd6d4853e01cb8a9c8e75c25719d0b104d816", + "commit": "1b7fe8a7f8e4cd8a870c76fc6e26cd087c431dc3", "branch": "claude/1268-unbalanced-brackets" }