fix(skill): write --plan / --competitors-plan to tmpfile, bump 3.2.2 -> 3.2.3

Closes #403.

The SKILL.md templates instructed the model to invoke the engine with
inline single-quoted JSON: `--plan '$JSON'` and `--competitors-plan '{...}'`.
When any resolved field value contained an apostrophe (common in `context`
strings like "McDonald's", "people's choice", or contracted forms like
"don't", "won't"), the inner `'` closed the outer single-quote and broke
shell parsing before the engine was even invoked.

Observed during PR #400 testing: a Codex run hit the trap and self-healed
by re-encoding, wasting one engine invocation and ~30s of latency.

Fix: switch both templates to the heredoc + tmpfile pattern. The engine's
`parse_plan()` and `parse_competitors_plan()` already check
`os.path.isfile(plan_str)` and read from disk — only the SKILL.md prose
needed to change.

The quoted heredoc marker (<<'PLAN_EOF') is load-bearing: it suppresses
shell interpolation so apostrophes, $, backticks, etc. pass through verbatim.
A trap on EXIT cleans up the tmpfile after the engine call returns.

LAW 7's "MUST contain --plan" self-check guidance and Step 1's invocation
example both updated to reference the file form. Comparison-mode invocation
block updated the same way for --competitors-plan.

Version bump 3.2.2 -> 3.2.3 because this is a behavior change users
running comparison-mode queries will notice (no more "shell quoting error,
retrying" sequences on apostrophe-containing context strings).
This commit is contained in:
Trevin Chow
2026-05-15 22:43:02 -07:00
parent e276c30477
commit ff54c07a3b
7 changed files with 46 additions and 16 deletions
Generated
+1 -1
View File
@@ -106,7 +106,7 @@ wheels = [
[[package]]
name = "last30days-skill"
version = "3.2.2"
version = "3.2.3"
source = { virtual = "." }
[package.dev-dependencies]