Security: Prompt injection guardrails for imported text (#434)
* fix(security): address PR review — strengthen red-team tests and log boundary escapes - sanitize_text now logs and truncates when boundary markers are escaped - test_injection_is_truncated asserts for ALL inputs (not just long ones) - test_injection_is_logged asserts ALL suspicious inputs trigger warnings - Add test_rejects_type_based_bypass_list for non-string coercion - Update guardrails docs to match actual test corpus Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(security): add boundary escaping to all reskill render paths Close fence-escape vulnerability in reskill.py where render_wisdom, render_skills, render_recent_analyses, and render_snapshot_context injected untrusted file content without escaping boundary markers. Also add escaping in track_quality.build_quality_report() and load_scorecard.render_scorecard_section(). Add 6 targeted red-team tests verifying boundary markers cannot leak through any reskill template variable path. Closes #352 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(security): escape boundary markers in render path headers and fix vacuous test - Escape relative_path in Skill Source, Analysis Source, and Snapshot Context headers to prevent boundary marker injection via filenames - Escape week in Snapshot Context headers for same reason - Fix scorecard boundary test: use correct card schema (top-level validated/correct/by_type) so test is no longer vacuous - Add assertion that render_scorecard_section returns non-empty output - Fix red-team corpus count in docs: 17 → 18 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(security): escape parentheses in markdown link URLs to prevent syntax injection URLs containing parentheses (e.g., Wikipedia links) could break markdown link syntax [text](url), potentially allowing content to escape the link context. Add _escape_markdown_url() helper that percent-encodes ( and ) characters before embedding URLs in markdown links. Applies to all three markdown link construction sites in render_press_context.py. Includes tests validating the escaping behavior. Closes part of #352 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(security): escape remaining unescaped markdown URLs in render_press_context Apply _escape_markdown_url() to the two remaining markdown link constructions that interpolated external URLs without parenthesis escaping (correlation citation and AI-prompt divergence list). Remove redundant local re-import of _escape_markdown_url in test. Resolves Copilot review threads on PR #434. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>