refactor(agents): migrate .agent/ planning tree to .agents/

Standardize on the .agents/ directory (shared with project skills):
phases/, user_stories/, reports/, screenshots/, validate.sh, and
phase-sessions/ + pipeline.log all move to .agents/ (git mv preserves
history; runtime artifacts move alongside).

Updates every reference in AGENTS.md, README.md, .gitignore, app
docstrings, and test story headers. Historical KB content in data/
and the runtime pipeline.log transcript are left untouched.
This commit is contained in:
2026-09-05 10:57:07 -04:00
parent 766702c750
commit dbf2af26c6
1118 changed files with 664 additions and 664 deletions
@@ -0,0 +1,41 @@
# Phase 60 — Sticky Navbar (stays stuck to the top while scrolling)
**Source:** `TODO.md` L3 — "The navbar disappears when you scroll down, should stay stuck to the top of the screen"
**Story:** n/a (TODO-derived — owner roadmap confirmation 2026-08-31, A1–A3)
**Context:** The navbar already HAS the sticky CSS: `.app-header` (`frontend/assets/styles.css` ~L194 — `position: sticky; top: 0; z-index: 20`) and the document viewer's two-row `.doc-header` (~L2201 — also `position: sticky; top: 0`), both direct children of `<body>` on every page. The bug: `html, body { height: 100% }` (~L40) pins the body box to exactly one viewport, and a sticky element's travel range is constrained to its containing block — so after ~1 viewport of scrolling the header un-pins and scrolls away with the body. Verified with headless Chromium during the TODO audit (2026-08-31): with the current rule the header's rect top is −1264px after a 2000px scroll; with `height` dropped from `body` (keeping `min-height: 100dvh`) it is top = 0, and on a short page the footer still lands at the viewport bottom (800/800 at 1280×800). The document must stay the scroll container (phase 52 no-inner-scroller contract, ~L387) — this fix adds no scroller, it only lets the body grow to its content. `.agents/` is untracked (owner commit 281f355) — phase commits stage `frontend/ tests/` only.
## Objective
The navbar — and the document-viewer header — stays stuck to the top of the screen on every page at every scroll position, while the short-page layout (flex stretch, pinned composer, footer) stays exactly as it is today.
## Dependencies
- `59_response_to_docs_push` (todo, preceding — no functional dependency; ordering by number)
## Tasks
1. `01_sticky_header_css.md` — drop `height: 100%` from `body` (keep it on `html`), refresh the stale phase-12 comment, unit CSS pins in `tests/unit/test_sticky_header.py`.
2. `02_e2e_sticky_navbar.md` — `tests/e2e/test_sticky_navbar.py` (rect-top == 0 proofs on Sources + viewer at the bottom of long pages; short-page stretch/composer regressions), regression suites, atomic commit.
## Testing & Quality
- Unit CSS pins (house style, `tests/unit/test_save_chat_ui.py` pattern): `html` keeps `height: 100%`; the `body` rule carries NO `height:` (negative pin) and keeps `min-height: 100dvh`; `.app-header` and `.doc-header` keep `position: sticky; top: 0`.
- E2E (mandatory, A3): `tests/e2e/test_sticky_navbar.py`, run in isolation.
- Coverage: **>90%** on `app/` (validate.sh gate — pure-CSS phase, gate still runs).
## Completion Criteria
- [ ] Sources page (KB long enough to scroll), 1280×800: after `window.scrollTo(0, 999999)` the `.app-header` rect top == 0 (±1px) and the header is visible.
- [ ] Document viewer on a long doc: after full scroll, `.doc-header` rect top == 0 (±1px).
- [ ] Short page (empty chat, 1280×800): body height == 800, `.app-footer` bottom == 800, `.composer` bottom ≈ 800 (±2px) — the phase-52 pin holds.
- [ ] `uv run pytest` green; coverage TOTAL >90%.
- [ ] `uv run pytest tests/e2e/test_sticky_navbar.py -v --no-cov` green in isolation (DB up).
- [ ] Regression E2E suites green in isolation: `test_pinned_composer.py`, `test_document_viewer.py`, `test_responsive_polish.py`, `test_smoke.py`, `test_no_reply_autoscroll.py`, `test_mobile_hamburger_nav.py`.
- [ ] `uv run ruff check . && uv run pyright` clean.
- [ ] One `--no-gpg-sign` commit; phase dir moved to `.agents/phases/complete/` (`.agents/` stays untracked — owner instruction, commit 281f355).
## Locked decisions
- **Owner-locked (2026-08-31, roadmap confirmation, A1–A3):**
1. **A1 (root cause):** the sticky travel range is capped by `body { height: 100% }` (`styles.css` L40) — the body box is pinned to one viewport and sticky elements (`.app-header`, `.doc-header`) can only travel within it.
2. **A2 (fix):** CSS-only — drop `height: 100%` from `body` (keep it on `html`); the body's existing `min-height: 100dvh` keeps driving the short-page stretch. No JS changes, no new scroller (the document stays the scroll container).
3. **A3 (E2E):** long-scroll surfaces = the seeded Sources table + the document viewer, with KB seeding via `import_sources` (the `test_document_viewer.py` pattern — fixtures + generated docs). No real LLM involved.
## Commit
```bash
git add frontend/ tests/ && git commit --no-gpg-sign -m "fix(web): keep the navbar stuck to the top — drop the body height cap on the sticky range"
```