phase: 106_document_dates
Everything is verified green. Final report: **Phase 106 — Document dates (final verification pass; all 10 tasks already complete)** - Verified all phase artifacts: alembic `0020` (dev DB at `0020`), `doc_dates.py`, git `file_commit_dates`, importer `doc_dates_by_root`/`dates_updated`, both entry-point wirings, date APIs + tree `created_at`/`updated_at`, LLM surfaces (prompt block, `read` line 2, appended `ls` field), `apply_recency_boost` in `retrieve()`, UI columns/badge, admin editor, mock-LLM regex — all present and correct; no defects found, no fixes needed. - `uv run pytest --cov=app --cov-report=term-missing` → **2299 passed, TOTAL 99%** (>90% ✓) - `uv run pytest tests/e2e/test_document_dates.py -v --no-cov` → **6/6 passed** in isolation (DB up) - 12 regression E2E suites (retrieval_quality, whole_document_context, agent_document_tools, ls_tree_drilldown, read_truncation_cap, kb_tree, kb_tree_nav, document_viewer, edit_summaries, import_documents, sync_button, hidden_folders_toggle, smoke) → **all green in isolation** - `uv run ruff check .` → clean; `uv run pyright` → **0 errors, 0 warnings** **Completion criteria:** 1) non-null `created_at` + 0020 upgrade/downgrade on dev DB ✓ (real-Alembic integration tests) 2) sync refresh/older/manual-persists/content-reset/no sources_meta bump ✓ 3) zip/tar mtime + future→today ✓ 4) LLM date surfaces + cross-check ✓ 5) UI Created/Updated/badge positions ✓ 6) admin editor set+revert round-trip ✓ 7) old-correct-beats-new-similar (defaults & boost-off) + near-tie + `BOR_RECENCY_BOOST=0` byte-identical ✓ 8) full gate ✓ 9) commit/phase-move — left to harness per instructions. - **Notable:** recency default tuned 0.001 → **0.0007** (task 07 step 5 explicitly permits; measured margins recorded in `test_recency_boost.py` docstring). - **Next pending phase:** none — `todo/` holds only this phase.
This commit is contained in:
+153
-10
@@ -1937,7 +1937,9 @@ details.thinking .thinking-text ul { margin: 0 0 0.5rem; }
|
||||
directory's STORED description — the surface-panel language of the
|
||||
phase-93 page heads), and #folders-table (the ONE folders/sources
|
||||
table — the .docs-table language; .kb-folders-table only re-styles
|
||||
the 2nd/3rd column cells). Phase-08 tokens only — NO new hue
|
||||
the 2nd/4th column cells — phase 106 (task 08, D8) moved
|
||||
Description from 3rd to 4th, the Updated column taking 3rd). Phase-08
|
||||
tokens only — NO new hue
|
||||
(the phase-92 monochrome invariant): brand-ink on surface 9.0:1,
|
||||
ink 13.8:1, ink-soft 5.1:1 (every pair AA). :focus-visible via the
|
||||
global 3px outline rule; row targets keep the .docs-table cell
|
||||
@@ -1981,7 +1983,12 @@ details.thinking .thinking-text ul { margin: 0 0 0.5rem; }
|
||||
.kb-level p { margin: 0; color: var(--ink-soft); } /* 5.1:1 on --surface */
|
||||
.kb-folders-table { min-width: 480px; }
|
||||
.kb-folders-table td:nth-child(2) { font-family: var(--font); font-size: inherit; max-width: none; }
|
||||
.kb-folders-table td:nth-child(3) {
|
||||
/* Phase 106 (task 08, D8): the Updated column sits at 3rd (BETWEEN
|
||||
Documents and Description) — it takes the .docs-table cell defaults
|
||||
(nowrap text, the table ink: var(--ink) on the wrap's --surface —
|
||||
13.8:1, the pair recorded at :root). NO new CSS: the one-line clamp
|
||||
below follows the Description cell, which moved to 4th. */
|
||||
.kb-folders-table td:nth-child(4) {
|
||||
white-space: nowrap; /* phase 99 (D1): one line — the clamp's budget is the column width */
|
||||
min-width: 18rem;
|
||||
max-width: 44rem;
|
||||
@@ -3637,10 +3644,11 @@ details.thinking .thinking-text ul { margin: 0 0 0.5rem; }
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
/* Meta row: source badge · format badge · mono path · indexed · chunks.
|
||||
Phase 12/34: it may clip, but it must NEVER wrap — the meta stays on
|
||||
one line in the titlebar row (the row is content-sized, so a wrap
|
||||
would grow it). */
|
||||
/* Meta row: source badge · format badge · mono path · created ·
|
||||
indexed · chunks (phase 106 (task 08, D8) added created BEFORE
|
||||
indexed). Phase 12/34: it may clip, but it must NEVER wrap — the
|
||||
meta stays on one line in the titlebar row (the row is content-
|
||||
sized, so a wrap would grow it). */
|
||||
.doc-meta {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
@@ -3682,6 +3690,13 @@ details.thinking .thinking-text ul { margin: 0 0 0.5rem; }
|
||||
min-width: 6rem;
|
||||
}
|
||||
.doc-chunks { font-family: var(--mono); }
|
||||
/* Phase 106 (task 08, D8): the Created badge — the SAME family as the
|
||||
Indexed one (no own look: the meta row's text, var(--ink-soft) on
|
||||
the titlebar's --surface — 5.1:1, the pair recorded at :root; the
|
||||
modal's .doc-modal-meta row records the same pair). The explicit
|
||||
declaration pins the inherited value: a themed --ink-soft moves the
|
||||
badge with the row (byte-identical rendering). */
|
||||
.doc-created { color: var(--ink-soft); /* 5.1:1 on --surface */ }
|
||||
|
||||
.doc-shell {
|
||||
display: flex;
|
||||
@@ -3856,6 +3871,133 @@ details.thinking .thinking-text ul { margin: 0 0 0.5rem; }
|
||||
}
|
||||
.doc-summary-status:empty { margin-top: 0; }
|
||||
|
||||
/* Date edit affordance (phase 106, task 09 — D7, admin-only): the
|
||||
"Edit date" text button after the Created badge (the
|
||||
.doc-summary-edit family — one pill style for both inline
|
||||
editors) and the editor box that swaps in for the button IN the
|
||||
.doc-meta row: the native type=date input, Save / Cancel, the
|
||||
muted underlined "Revert to sync" clear affordance (the phase-57
|
||||
"clear = explicit" contrast), a role=status live line, and a
|
||||
role=alert error line (the .git-source-error err pair). The meta
|
||||
row may clip (nowrap) on the page, so the box wraps ITS children
|
||||
internally (the modal's .doc-modal-meta already wraps). The
|
||||
global 3px :focus-visible outline rule applies — no per-control
|
||||
rule (the phase-105 checkbox idiom). :disabled = opacity +
|
||||
cursor: wait (the .git-source-remove:disabled idiom — one PATCH
|
||||
at a time). Contrast (verified, house style): button / Cancel /
|
||||
revert / status ride the row's ink-soft on --surface (5.1:1, AA);
|
||||
the input is ink on --bg (16.7:1, AA); Save is the solid brand
|
||||
pill (--bg on --brand = 5.2:1, AA); the error line is the err
|
||||
pair (9.1:1 on --err-bg, AA). Anonymous / token holders never see
|
||||
any of it — the wiring is admin-gated (docAdminReady in
|
||||
document.js), so the public badge row stays byte-for-byte the
|
||||
task-08 shape. */
|
||||
.doc-date-edit {
|
||||
flex: 0 0 auto;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
min-height: 24px;
|
||||
padding: 0.15rem 0.7rem;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 999px;
|
||||
background: transparent;
|
||||
color: var(--ink-soft); /* 5.1:1 on --surface (AA) */
|
||||
font: inherit;
|
||||
font-weight: 600;
|
||||
font-size: 0.78rem;
|
||||
letter-spacing: 0.02em;
|
||||
cursor: pointer;
|
||||
}
|
||||
.doc-date-edit:hover { background: var(--brand-soft); color: var(--brand-ink); border-color: var(--brand); }
|
||||
.doc-date-edit[hidden] { display: none; } /* the hidden attr must beat the display above */
|
||||
.doc-date-editor {
|
||||
display: inline-flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 0.35rem;
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
}
|
||||
.doc-date-input {
|
||||
padding: 0.15rem 0.4rem;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: var(--radius-sm);
|
||||
background: var(--bg);
|
||||
color: var(--ink); /* 16.7:1 on --bg (AA) */
|
||||
font: inherit;
|
||||
font-size: 0.78rem;
|
||||
font-family: var(--mono);
|
||||
}
|
||||
.doc-date-save {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
min-height: 24px;
|
||||
padding: 0.15rem 0.7rem;
|
||||
border: 0;
|
||||
border-radius: 999px;
|
||||
background: var(--brand);
|
||||
color: var(--bg); /* --bg on --brand = 5.2:1 (AA) */
|
||||
font: inherit;
|
||||
font-weight: 600;
|
||||
font-size: 0.78rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
.doc-date-save:hover { background: var(--brand-hover); } /* the house hover lightening */
|
||||
.doc-date-cancel {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
min-height: 24px;
|
||||
padding: 0.15rem 0.7rem;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 999px;
|
||||
background: transparent;
|
||||
color: var(--ink-soft); /* 5.1:1 on --surface (AA) */
|
||||
font: inherit;
|
||||
font-weight: 600;
|
||||
font-size: 0.78rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
.doc-date-cancel:hover { background: var(--err-bg); color: var(--err-ink); border-color: var(--err-line); }
|
||||
.doc-date-revert {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
min-height: 24px;
|
||||
padding: 0.15rem 0.2rem;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
color: var(--ink-soft); /* 5.1:1 on --surface (AA) — the muted marker */
|
||||
font: inherit;
|
||||
font-size: 0.78rem;
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
.doc-date-revert:hover { color: var(--ink); } /* 14.5:1 on --surface (AA) */
|
||||
.doc-date-save:disabled,
|
||||
.doc-date-cancel:disabled,
|
||||
.doc-date-revert:disabled,
|
||||
.doc-date-input:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: wait; /* one PATCH at a time (the .git-source-remove:disabled idiom) */
|
||||
}
|
||||
.doc-date-status {
|
||||
font-size: 0.78rem;
|
||||
color: var(--ink-soft); /* 5.1:1 on --surface (AA) */
|
||||
}
|
||||
.doc-date-error {
|
||||
flex-basis: 100%; /* drops onto its own row under the controls */
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
overflow-wrap: anywhere; /* a long server detail never overflows the box */
|
||||
font-size: 0.78rem;
|
||||
font-weight: 600;
|
||||
background: var(--err-bg);
|
||||
color: var(--err-ink); /* 9.1:1 on --err-bg (AA — the .git-source-error pair) */
|
||||
border: 1px solid var(--err-line);
|
||||
border-radius: var(--radius-sm);
|
||||
padding: 0.1rem 0.5rem;
|
||||
}
|
||||
.doc-date-status:empty, .doc-date-error:empty { display: none; } /* an empty live line takes no space */
|
||||
|
||||
/* Raw (non-markdown) formats: full-width mono pre, horizontal scroll. */
|
||||
.doc-raw {
|
||||
width: 100%;
|
||||
@@ -4039,10 +4181,11 @@ details.thinking .thinking-text ul { margin: 0 0 0.5rem; }
|
||||
.doc-modal-close svg { width: 18px; height: 18px; display: block; }
|
||||
|
||||
/* Meta row: the SAME badge classes as the viewer's .doc-meta (source
|
||||
badge · format badge · mono path · indexed · chunks — no duplicate
|
||||
badge styling here); unlike the fixed-height header bar it may WRAP,
|
||||
so nothing clips. aria-live="polite" on the element announces the
|
||||
load → meta swap (phase-10 a11y contract, modal variant). */
|
||||
badge · format badge · mono path · created · indexed · chunks — no
|
||||
duplicate badge styling here); unlike the fixed-height header bar it
|
||||
may WRAP, so nothing clips. aria-live="polite" on the element
|
||||
announces the load → meta swap (phase-10 a11y contract, modal
|
||||
variant). */
|
||||
.doc-modal-meta {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
|
||||
Reference in New Issue
Block a user