phase: 108_history_wire_check
Build and Push Containers / build-and-push-app (push) Successful in 16s
Build and Push Containers / build-and-push-db (push) Successful in 12s

Final verification pass complete — everything independently re-verified green. Report:

**Phase 108 — History wire check (final verification pass; verdict: NO BUG, tests-only per D13)**

- Verified all 3 tasks complete in `.agents/phases/complete/108_history_wire_check/`; re-ran every pin and gate myself
- Layer 1 (unit): 2 owner-shape pins in `tests/unit/test_history.py` (2-turn keep-whole + A4 thinking mapping) — pass
- Layer 2 (integration): `test_endpoint_two_turn_history_reaches_the_llm` — captured LLM request = `[system, user Q1, assistant R1, user Q2]`, `history_msgs=2` — pass
- Layer 3 (E2E): `tests/e2e/test_history_wire_check.py` — owner's verbatim 3-message scenario, echo byte-exact (T2: `2 prior messages`+R1 tail; T3: `4 prior messages`+R2 tail) — pass
- `VERDICT.md` present in phase dir: layer outcomes + "no bug — model behavior/user error" + pin names

**Gates (exact results)**
- `uv run pytest --cov=app --cov-report=term-missing` → 2305 passed, TOTAL **99%** (>90%)
- `uv run pytest tests/e2e/test_history_wire_check.py -v --no-cov` → 2 passed (isolation, DB up)
- `uv run pytest tests/e2e/test_llm_history.py -v --no-cov` (phase-74 regression) → 3 passed
- `uv run ruff check .` → clean; `uv run pyright` → 0 errors

**Completion criteria:** all six met — no defects found; diff scoped to `tests/**`, `VERDICT.md`, `.agents/phases/**`, `.agents/reports/**` (no `app/`/`frontend/` changes, consistent with no-bug verdict). Per executor rules, no git commit made — left for the harness.

**Next pending phase:** `109_turn_progress_loader`
This commit is contained in:
2026-09-13 23:57:54 -04:00
parent 6bcee831ec
commit fbbd98d734
20 changed files with 833 additions and 0 deletions
+57
View File
@@ -96,6 +96,63 @@ def test_result_is_chronological_oldest_to_newest() -> None:
assert "reasoning_content" not in got[3]
# ---------- owner shape (phase 108, TODO L4: the 2-turn follow-up) ----------
def test_short_two_turn_history_kept_whole_and_chronological() -> None:
"""Phase 108 layer 1 (TODO L4 — the owner's exact shape): one user
question + one brain answer is orders of magnitude under the DEFAULT
budgets (40 turns / 24 000 chars — no overrides, the file's plain
``_settings()``) and must survive the trimmer WHOLE: both turns kept,
chronological (Q1 then R1), roles mapped, no trim, no reordering. A
server-side missing-first-turn on the owner's follow-up would have to
be dropped here."""
history = [
_turn("user", "What is my name?"),
_turn("brain", "Your name is Reese."),
]
assert history_to_messages(history, _settings()) == [
{"role": "user", "content": "What is my name?"},
{"role": "assistant", "content": "Your name is Reese."},
]
def test_two_turn_history_thinking_mapping() -> None:
"""Phase 108 layer 1 (TODO L4), the A4 gate on the owner's shape: a
non-empty prior ``thinking`` travels as ``reasoning_content`` on the
assistant message; with ``thinking`` absent or empty the key is
ABSENT (not an empty string) — the message equals the plain brain
turn."""
got = history_to_messages(
[
_turn("user", "What is my name?"),
_turn("brain", "Your name is Reese.", thinking="The owner asked for their name."),
],
_settings(),
)
assert got == [
{"role": "user", "content": "What is my name?"},
{
"role": "assistant",
"content": "Your name is Reese.",
"reasoning_content": "The owner asked for their name.",
},
]
for thinking in (None, ""): # absent and empty — both omit the key
got = history_to_messages(
[
_turn("user", "What is my name?"),
_turn("brain", "Your name is Reese.", thinking=thinking),
],
_settings(),
)
assert got == [
{"role": "user", "content": "What is my name?"},
{"role": "assistant", "content": "Your name is Reese."},
]
assert "reasoning_content" not in got[1]
# ---------- turn-count budget ----------