## Implementation Plan ### 1. Harden the system prompt in `devplacepy/services/correction.py` (line ~105) Replace the current conflicting instruction with an explicit directive that separates response-format from content-preservation: **Current:** ```python f"Preserve the original author's markdown styles.\nDo not add or remove any code fences.\n{instruction}" ``` **Replace with:** ```python ( "Preserve the original author's markdown styles. " "Do not modify any content inside fenced code blocks (triple backticks). " "Leave the language identifier and every character inside code fences exactly as written. " "Return your entire response as plain text with no wrapping code fences around it.\n" f"{instruction}" ) ``` ### 2. Harden the system prompt in `devplacepy/services/ai_modifier.py` (line ~34) This file currently has no preservation instruction at all. Add the same logic: **Current:** ```python f"Your output should be:\nOriginal (quoted) content or {role}'s instructions for content.\nBased on the given context, {role}'s instructions and the original content, return final text only. Make sure to not open any code fences.\n{instruction}" ``` **Replace with:** ```python ( "Your output should be:\n" "Original (quoted) content or {role}'s instructions for content.\n" "Based on the given context, {role}'s instructions and the original content, return final text only. " "Do not modify any content inside fenced code blocks (triple backticks). " "Leave the language identifier and every character inside code fences exactly as written. " "Make sure to not open any code fences.\n" f"{instruction}" ) ``` ### 3. Add a test for the correction pipeline with code blocks Create a new fixture and test in `tests/api/profile/aicorrection.py` that: - Creates a user with correction enabled and default prompt. - Creates a post containing a fenced code block (e.g., `\`\`\`python\nprint('hello')\n\`\`\``). - Calls the correction endpoint or triggers correction via the save flow. - Verifies that the saved content still contains the exact fenced code block and language identifier. Add a second test that uses a broad user-defined prompt (e.g., `"Fix all grammar"`) to confirm the prompt fix is effective. ### 4. Add a similar test for the modifier pipeline in `tests/api/profile/aimodifier.py` Follow the same pattern: enable modifier, create content with a code block, apply modifier with some change instruction, verify code block preserved. ### 5. Update documentation (optional but follow the findings) The docs at `templates/docs/ai-correction.html` and `templates/profile.html` already claim code blocks are untouched. No change needed there (they are accurate after the prompt fix). But if any other doc mentions the ambiguous “no code fences” phrasing, update it to match the new logic. --- ## Definition of Done - [ ] Both `services/correction.py` and `services/ai_modifier.py` are updated with the new system prompts as described above. - [ ] New test added to `tests/api/profile/aicorrection.py` that verifies fenced code blocks survive the correction pipeline (both with default prompt and a broad custom prompt). - [ ] New test added to `tests/api/profile/aimodifier.py` that verifies fenced code blocks survive the modifier pipeline. - [ ] All existing tests still pass: `pip install -e '.[dev]' -q && make test-unit` exits with code 0. - [ ] Lint passes: `pip install -q ruff && ruff check .` exits with code 0. - [ ] Manual smoke test (optional but recommended): create a post with a fenced code block via the UI (correction enabled), then fetch the raw post content from DB and confirm the code block is unchanged.