From 3febe026c1825cd9796a3889a8f2e3db70b2459c Mon Sep 17 00:00:00 2001 From: Michael Sitarzewski Date: Wed, 2 Sep 2026 20:32:18 -0500 Subject: [PATCH] fix(lib): get_field strips a quoted YAML scalar's outer quotes so quoted sources don't double-wrap (#826) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Contributors keep reaching for the same fix when a description contains ": " and breaks YAML frontmatter: double-quote the source scalar (#473 for zk-steward, re-proposed in #548, and again in #810). #778 fixed the same problem one layer down by having the converters emit quoted scalars. The two compose badly: get_field returned a quoted source's quotes as content, so yaml_quote wrapped them again and every generated file for an already-quoted agent shipped as description: '"..."' with a literal quote leaking into the parsed value. zk-steward and ai-data-remediation-engineer are affected on main today. get_field now treats one matching outer pair of double or single quotes as delimiters: it strips them and unescapes (\" -> ", \\ -> \, '' -> '). Quoting a source description is now safe and harmless, so #473/#548/#810's instinct and #778's generator-side fix reconcile. Unquoted sources are unchanged. Verified in a sandbox end-to-end (source -> convert.sh -> parsed YAML): zk-steward and ai-data-remediation-engineer no longer leak a quote and keep their internal apostrophes; developer-tooling-engineer (unquoted, contains ": ") is byte-identical to before; synthetic '...''...' and "...\"...\\" cases unescape correctly. lib.sh is only ever sourced by bash (its shebang); note `repeat()` at the top of the TUI section is a zsh reserved word, so sourcing lib.sh from a zsh shell errors — pre-existing and unrelated. Refs #473 #548 #810 #778 Co-authored-by: Claude Fable 5.1 --- scripts/lib.sh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/scripts/lib.sh b/scripts/lib.sh index 270388a9..e1eeba8a 100755 --- a/scripts/lib.sh +++ b/scripts/lib.sh @@ -21,7 +21,16 @@ get_field() { local field="$1" file="$2" awk -v f="$field" ' /^---$/ { fm++; next } - fm == 1 && $0 ~ "^" f ": " { sub("^" f ": ", ""); print; exit } + fm == 1 && $0 ~ "^" f ": " { + sub("^" f ": ", "") + # A quoted YAML scalar carries its quotes as delimiters, not content. + # Strip one matching outer pair and unescape, so a quoted source value + # never double-wraps when a converter re-quotes it (\047 is a literal + # apostrophe; this program sits inside shell single quotes). + if ($0 ~ /^".*"$/) { $0 = substr($0, 2, length($0) - 2); gsub(/\\"/, "\"", $0); gsub(/\\\\/, "\\", $0) } + else if ($0 ~ /^\047.*\047$/) { $0 = substr($0, 2, length($0) - 2); gsub(/\047\047/, "\047", $0) } + print; exit + } ' "$file" }