diff --git a/app/api/welcome.py b/app/api/welcome.py index ee30583..b09c1c0 100644 --- a/app/api/welcome.py +++ b/app/api/welcome.py @@ -86,9 +86,11 @@ async def admin_put_template( user: dict = Depends(require_admin), conn: duckdb.DuckDBPyConnection = Depends(_get_db), ): - # Validate with autoescape=True (matches runtime environment) and - # StrictUndefined so unknown placeholders are caught at save time. - env = Environment(undefined=StrictUndefined, autoescape=True) + # Validate with autoescape=False to match every runtime render path + # (/setup page, preview endpoint, render_agent_prompt_banner). The + # outer template applies escaping where needed via `| e`. StrictUndefined + # is kept so unknown placeholders are caught at save time. + env = Environment(undefined=StrictUndefined, autoescape=False) try: template = env.from_string(payload.content) # Render against a stub context so undefined placeholders or runtime diff --git a/docs/agent-setup-prompt.md b/docs/agent-setup-prompt.md index 96e7f17..6f1680b 100644 --- a/docs/agent-setup-prompt.md +++ b/docs/agent-setup-prompt.md @@ -34,11 +34,16 @@ row id=1). The `DELETE` endpoint NULLs `content`; the audit trail ## Template language -[Jinja2](https://jinja.palletsprojects.com/) with `autoescape=True` and -`StrictUndefined`. Autoescape is on because the output is rendered into HTML. -Any typo in a placeholder name raises an error at PUT validation time rather -than silently emitting an empty string — the editor reports the error -immediately so the admin can fix it before saving. +[Jinja2](https://jinja.palletsprojects.com/) with `autoescape=False` and +`StrictUndefined`. Autoescape is off because the rendered output is composed +into the surrounding `/setup` template which applies HTML escaping where +needed via `| e`; doubling the escape would corrupt characters like `&` or `<` +inside code blocks. All four render sites (PUT validation, preview endpoint, +`/setup` page render, `render_agent_prompt_banner`) share the same setting, +so the editor's preview matches what analysts see live. Any typo in a +placeholder name raises an error at PUT validation time rather than silently +emitting an empty string — the editor reports the error immediately so the +admin can fix it before saving. ## Available placeholders