phase: 157_chat_chip_cap
All verification is green. Final report: **Phase 157 — final verification pass (all 3 tasks already complete in `complete/`)** - Verified the implemented work matches the design: `CHIP_CAP = 90` constant + display-only cap in `renderChips` (`slice(0,90).trimEnd() + "…"`), `title`/`aria-label`/click payload byte-unchanged; unit pins (89/90/91 letter & space, full-text invariant, short-string guard, Maybe-try single-path guard); phase-104 E2E updated to the cap contract - Full suite `uv run pytest --cov=app --cov-report=term-missing`: **3578 passed**, app/ coverage **99%** (>90% ✓) - `uv run ruff check .` clean; `uv run pyright`: 0 errors - Dedicated E2E `uv run pytest tests/e2e/test_chat_chip_cap.py -v --no-cov`: **4/4 passed** in isolation (DB up) - Cross-phase regression: phase-104 E2E 6/6, phase 05/80/103 chip suite 8/8 (seed chips <90 chars — cap is a no-op, assertions hold) - Criteria: ≤91-char capped display ✓ (byte-for-byte pin) · click submits FULL 120-char question (user bubble) ✓ · `title` + clipped-case `aria-label` carry full text ✓ (375px viewport) · <90-char byte-identical ✓ (unit + live DOM) · commit: deferred to the harness (per harness protocol, overrides AGENTS.md rule 8 for this pass) - Documentation: README.md reviewed in full — every `.env.example` var documented, all referenced scripts/pages/commands verified against the tree, the phase's chip-cap note is in the Chat section; AGENTS.md verified (commands, test files, layout-rule citations — phase 157 adds no new layout principle) → **verified consistent, no changes needed** - No live-infrastructure changes were required or made - Next pending phase: **158_thinking_timeline**
This commit is contained in:
+13
-2
@@ -1289,6 +1289,14 @@ function submitSuggestion(text) {
|
||||
composer.requestSubmit();
|
||||
}
|
||||
|
||||
/* Phase 157 (owner-locked 2026-10-03, A1): the chip display cap — a
|
||||
* chip's DISPLAYED text never exceeds CHIP_CAP characters (the `…`
|
||||
* brings a capped chip to at most CAP+1). The cap is the PRIMARY
|
||||
* length guard; the phase-104 single-line CSS clip stays the
|
||||
* secondary. Display-only: the title / aria-label / click payload
|
||||
* keep the FULL text (the phase-104 contract, extended). */
|
||||
const CHIP_CAP = 90;
|
||||
|
||||
function renderChips(container, items, { onSelect } = {}) {
|
||||
// Replace only previous chips; keep any other children (e.g. the
|
||||
// visually-hidden group label inside a "maybe-try" row).
|
||||
@@ -1300,10 +1308,13 @@ function renderChips(container, items, { onSelect } = {}) {
|
||||
btn.type = "button";
|
||||
btn.className = "suggestion-chip";
|
||||
btn.setAttribute("role", "listitem");
|
||||
btn.textContent = text;
|
||||
btn.textContent =
|
||||
text.length > CHIP_CAP ? text.slice(0, CHIP_CAP).trimEnd() + "…" : text;
|
||||
// phase 104 (owner 2026-09-12): the single-line chip clips long
|
||||
// questions — `title` is the hover reveal, `aria-label` the
|
||||
// clipped-case accessible name (the source-chip pattern).
|
||||
// clipped-case accessible name (the source-chip pattern);
|
||||
// phase 157 (owner 2026-10-03, A1): the CHIP_CAP display cap is
|
||||
// the PRIMARY guard — the CSS clip is the secondary.
|
||||
btn.title = text;
|
||||
btn.addEventListener("click", () => {
|
||||
submitSuggestion(text);
|
||||
|
||||
Reference in New Issue
Block a user