phase: 113_source_chip_quality
Build and Push Containers / build-and-push-app (push) Successful in 2m2s
Build and Push Containers / build-and-push-db (push) Successful in 15s

All gates green — no defects found; this pass was verification only.

**Phase 113 final verification pass — report**

- Verified (no code changes needed): `select_documents_tiered` cited/related tiering + `select_documents` wrapper, `TurnPlan.related_docs`, `ChatDoneEvent.related` (additive, old payloads parse), `appendRelated` UI row (`.related-doc`, never `.source-chip`), done-frame + restore-path wiring, two settings with validators, `.env.example` entries
- `uv run pytest --cov=app --cov-report=term-missing` → 2422 passed, app/ coverage **99%** (>90% gate)
- `uv run pytest tests/e2e/test_source_chip_quality.py -v --no-cov` (isolated) → 2 passed
- Regression E2E `test_retrieval_quality.py` + `test_honest_deflection.py` + `test_chat_rag.py` + `test_sources_midstream_bug.py` → 17 passed
- `uv run ruff check . && uv run pyright` → clean (0 errors); `bash .agents/validate.sh` → "validation OK"

Completion criteria:
1. Single-doc question → exactly one `.source-chip` (E2E): ✅ passed
2. Weak 2nd doc only in de-emphasized related row, never `.source-chip` (unit + E2E): ✅ passed
3. Deflected turn → zero citation chips, weak hits in related row: ✅ passed
4. Full suite green, coverage >90%, isolated E2E green, lint/types clean: ✅ passed
5. `--no-gpg-sign` commit + phase dir move: left to harness per pass rules (task files already in `complete/`)

No deviations. Next pending phase: `114_embed_question_length`.
This commit is contained in:
2026-09-15 03:11:05 -04:00
parent 1374faf136
commit 97d663d16d
31 changed files with 2370 additions and 52 deletions
+45
View File
@@ -692,6 +692,51 @@ details.thinking .thinking-text ul { margin: 0 0 0.5rem; }
}
.source-chip:hover { background: var(--brand-soft); text-decoration: underline; }
/* Phase 113 (task 02): the related-docs row — the SECONDARY tier of
scored docs (phase 113 task 01's usefulness bar demotes the
sub-floor hits out of the citation surface; on a deflected turn the
weak hits live HERE and the chip row is absent). It must never read
as a citation: smaller mono links, DASHED border (the solid brand
pill is the citation look), transparent fill, muted --ink-soft text
— 8.6:1 on --bg (verified ≥4.5:1, WCAG 2.1 AA), palette variables
only (phase-92 zero-literal: no new hue, the monochrome theme grays
it automatically). The row joins .msg-meta (the .msg-body flex gap
stacks it below the citation row — no extra margin) but the meta
ACTIONS never do: app.js appends it last, after the first-row
claimers. :focus-visible via the global 3px outline rule. The hover
is deliberately flat — NO background swap (the chip's brand-soft
hover is the citation affordance): only the ink-soft → ink step-up
plus the underline. */
.related-docs-label {
font-size: 0.68rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--ink-soft);
}
.related-doc {
display: inline-flex;
align-items: center;
font-family: var(--mono);
font-size: 0.7rem;
color: var(--ink-soft);
background: transparent;
border: 1px dashed var(--line);
border-radius: 999px;
padding: 0.12rem 0.55rem;
text-decoration: none;
max-width: 100%;
/* min-width: 0 so the nowrap pill ellipsizes (same as the chips) */
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.related-doc:hover {
color: var(--ink); /* ink on --bg 16.7:1 — the flat secondary hover */
text-decoration: underline;
}
/* "Maybe try" chips under a deflected bubble (phase 04). Unlike the
onboarding row (which scrolls horizontally on mobile), this group wraps
at every width: the chips are the actionable follow-up, not decoration.