Story 2841: canonical clear/reset

Story-2841 closes CC-53 for the conversation memory clear action. Before this change, the clear endpoint reset agents.chat_session.summary, but the next agent invoke assembled durable memory from agents.session_memory.fold_text. That split meant the UI could report a cleared session while the next prompt still received the old fold.

What changed

SurfaceChange
src/app_api/agent_session_service.py clear_session() now resets the canonical session_memory row for the loaded session's (firm, matter/form, user, agent) scope. It nulls fold_text, clears fold metadata, and bumps memory_version through the existing shared helper in the same transaction.
agents.chat_session The endpoint still clears summary and summary_until_turn_index and sets cleared_until_turn_index to the current turn count. This remains the visible in-session compact marker for the dropdown client.
agents.chat_turn No transcript rows are deleted or rewritten. Clear is a memory reset, not transcript erasure.
tests/integration/test_app_agent_sessions.py The existing lifecycle route test now seeds a canonical fold, clears the session over HTTP, verifies the fold is nulled and version-bumped, verifies transcript rows remain, and assembles a memory pack to prove the next invoke observes session_fold = null.

Why this exists

Invoke-time memory reads from agents.session_memory.fold_text. A clear action that only clears chat_session.summary resets a different store than the agent actually consumes. This change makes the clear verb line up with the real prompt input while keeping the transcript available for session history.

Before and after

PathBeforeAfter
Clear session memory Cleared chat_session.summary only. Clears both the visible compact marker and the canonical session_memory.fold_text.
Next agent invoke Could still receive the stale fold from session_memory. Receives a fresh memory pack with session_fold = null and bumped memory_version.
Transcript history Raw turns were retained. Raw turns are still retained; clear is not delete.

Doctrine held

Verification

uv run ruff check src\app_api\agent_session_service.py tests\integration\test_app_agent_sessions.py
# All checks passed!

uv run mypy src\app_api\agent_session_service.py --follow-imports=skip
# Success: no issues found in 1 source file

uv run pytest tests\unit\test_memory_version_bump.py tests\unit\test_memory_pack_assembly.py -q
# 10 passed

uv run pytest tests\integration\test_app_agent_sessions.py -q
# Not run to completion locally: DATABASE_URL / PRAMAAN_ADMIN_DATABASE_URL not set.
# scripts/test-db.sh up also could not start the isolated DB because Docker is not running.
# CI must run the DB-backed integration proof.

The system-boundary proof is committed, but local execution of that DB-backed integration file is CI-only in this environment because the required database URL is absent and Docker is not running.