SIGN IN SIGN UP

sessions: replace per-step LLM request bodies with hash-deduped prompt envelopes (#484)

The per-step LLM request log stored the full provider payload on every model-call step — the entire growing conversation re-serialized per step, O(turns squared) bytes — and it dominates database growth on any active deployment; the message arrays it duplicates are already durable exactly once on the session tape. Replace the stored request body with a compact prompt envelope: system/tools/config captured once and deduplicated by content hash, with the message window reconstructed from the tape on read. Observability views reassemble the original request for inspection, so debugging fidelity is unchanged while storage per step drops from the full conversation to a constant-size record.

**Deployment notes**

- Release note: admin LLM forensics for steps recorded by the new version render without request bodies on any pre-upgrade instance or after rollback; scrub/snapshot pipelines must add `llm_prompt_envelopes` to exclusions.
- Schema at boot, all idempotent and instant: `ALTER session_llm_requests ALTER COLUMN request DROP NOT NULL`, `ADD COLUMN IF NOT EXISTS prompt_hash`, `CREATE TABLE IF NOT EXISTS llm_prompt_envelopes`. No table rewrite; pre-migration request bodies are frozen in place and detail reads fall back to them — old rows keep serving.
- Rollback / blue-green hazard: new code writes `request = NULL` + `prompt_hash`. Old code's `rowToLlmRequest` and the admin viewer expect `request NOT NULL` semantics — during a blue-green overlap or after rollback, old instances read NULL-request rows and render blank context for those steps. The ALTER already dropped the constraint, so writes do not fail; this is a read-quality gap, forensics-only, not user-facing.
- No backfill is needed or attempted by design; the change is safe for small databases.
- Follow-up: snapshot/scrub pipelines that exclude `session_llm_requests` must also exclude `llm_prompt_envelopes`.
- Known follow-up: envelope blobs are not garbage-collected when sessions are deleted — slow, mild, unbounded growth.

Screenshots of the admin viewer were omitted from this PR; the viewer change reassembles the same request view as before, with a blank-context fallback for NULL-request rows.

<!-- codesmith:footer -->
---
<a href="https://app.blacksmith.sh/yc-software/codesmith/qm/pr/484"><picture><source media="(prefers-color-scheme: dark)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg"><source media="(prefers-color-scheme: light)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-light-v2.svg"><img alt="View with [code]smith" src="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg"></picture></a> <a href="https://backend.blacksmith.sh/track/enable-autofix?expires=1789249300&installation_model_id=19911&pr_number=484&repository=yc-software%2Fqm&return_to=https%3A%2F%2Fgithub.com%2Fyc-software%2Fqm%2Fpull%2F484&signature=aebf8a03dbd0f39dc9ad75e08991e8266dcb69a4f8cb5ba52d4bb43f862d5c7c"><picture><source media="(prefers-color-scheme: dark)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-light.svg"><img alt="Autofix with [code]smith" src="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg"></picture></a>
<sup>Need help on this PR? Tag <code>@codesmith-bot</code> with what you need. Autofix is disabled.</sup>

<!-- codesmith:autofix:disabled -->
<!-- /codesmith:footer -->
R
Regan Bell committed
73d793b3db0022ecf956a7131978bdcf497179fa
Parent: fc3b9b2
Committed by GitHub <noreply@github.com> on 8/13/2026, 9:52:09 PM