Redesign compliance repo and evidence pages

Task 10064 · Done · Coder · created · updated

# C4 — Repo page, evidence pane and gap row Part of epic "Simplify and improve Compliance UI clarity". Redesigns `/compliance/repos/:id` and `/compliance/repos/:id/cells/:key`. No API dependency (uses only existing endpoints; inline `MODE_LABEL[...]` if C1's `modeLabel` has not merged yet). ## Scope (Architecture §3.6, §3.7, §2.3 repo row) Files: `RepoPage.tsx`, `RepoSections.tsx` (drop its per-gap `StateBadge`, ~line 70 — same GapRow rules), `GapRow.tsx`, `CellPage.tsx`, `WaiverList.tsx` (revoke from a row menu), `parts.tsx` (`NotScannableHint` one-line form) under `apps/web/src/pages/compliance/`, their tests, e2e repo/cell cases in `apps/web/e2e/compliance.spec.ts`. **Repo page header:** title = project name, `LevelBadge` beside it. Meta line `Commit abc1234 · Scanned 3 d ago`. Pack name **only when** the viewed pack is not the org's active one. Guard blocks only when the 30-day count > 0. A not-scannable project shows its badge and the fix link in one line, no restating sentence (`Not scannable: no node · Add to a node`). Actions: **Rescan** (editor), plus ⋯ with *Auditor run* (when there is one). The Observed toggle leaves the header. **Tabs (Q4): `Overview · Rules`** (Debt is no longer a tab). - **Overview**, in order: 1. `Gaps (26)` with a section action **Fix all**, shown only when there are fixable gaps and the user `can_fix`; the "Fixing needs…" sentence appears once, only for a reader who cannot fix. 2. `Not scanned (n)` only when n > 0. 3. `Levels by pillar`: the existing grid (`DataTable`). 4. `Facts (15)`: collapsed by default to one line, e.g. `C#, HCL, JavaScript · 12 unconfirmed`; expanded, each fact is one row `predicate: value` with a row ⋯ (*Confirm*, *Correct*). Status shows as `Unconfirmed` once in the header count, not per chip. - **Rules:** a `ui/feed/FeedList` with one `FeedSection` per pillar. Row: title = rule name linking to the **rule page**; slots `L1` · state badge (or `Waived until <date>`) · a visible text link **Evidence** (opens the cell pane); row ⋯ *Revoke* only when the rule carries an active waiver and the reader may edit. n/a rules form one `FeedSection` **per n/a reason** (heading = the reason, said once: `n/a: This repo has no Go code`). Observe-mode rules form a last muted section `Observed`. A filter chip row (URL key `filter`, absent = All) reads `All · Failing · Waived (n) · n/a`. **Waived** renders today's Debt query unchanged: `<WaiverList filters={{ packId }} match={w => w.project_id === project || cells.some(c => c.exception?.id === w.id)} />` (`RepoPage.tsx:~437-440`), `n` = `debt_count`. - **URL:** `/compliance/repos/:projectId[?tab=rules[&filter=failing|waived|na]]`. A retired `?tab=debt` is **rewritten** before `useUrlTab` reads it: the page sees raw `tab=debt` and replaces the URL with `?tab=rules&filter=waived`. - Multi-repo projects: `RepoSections` stays, above Gaps, with no state badge per gap. **GapRow:** line 1 the rule name (→ rule page), the overlay badge (fix in flight), then `L1 · Advise · 15 d` (mode via label, age `15 d` with title "failing since <date>"); line 2 the why, no "Why it matters:" label; line 3 `Found: …`. Actions: **Fix** (the one visible button) plus a row ⋯ with *Evidence* and *Waive* (editor, not lock). No state badge inside the Gaps section; errored rows in "Not scanned" keep `Last result <badge>`. Recorded style-guide exception: gap rows keep three lines (meta, why, Found) — the why is always shown in full (`GapRow.tsx:12-16` contract). **Evidence pane:** title is the **rule name linking to the rule page** (replaces "Rule details"), state badge beside it. Rationale is plain text (no "Why it matters:" label). "Check type" dropped. `Commit` and `Scanned` stay. Dropped/moved (Architecture §6, this child's rows): Fact Confirm/Correct → Facts row ⋯; Waivers/Debt → gap row ⋯ Waive, repo Rules "Waived" filter + row ⋯ Revoke; Fix all → Gaps section action; repo header not-scannable sentence, "Guard blocks: 0 · 0", pack · version in repo meta, "inferred Confirm Correct" per chip, "✗ Fail" badge / "Why it matters:" / per-gap Evidence+Waive buttons, "Every rule" heading and repeated n/a reasons, Debt tab, evidence "Rule details" link and "Check type" row. ## Original request (verbatim, epic Task 10032) > Go over Compliance process with oam-demo project in prod as an example. The Compliance UI seems to be too busy, very confusing, not clear where user actually sets up rules, etc. Clean up and make more straight and intuitive. Remove repetitions and stating obvious facts ## Settled requirements (PRD, verbatim) - **R2: Less on screen (A2).** Each page has at most **3 visible header actions** at ≥1280px. The rest go in one overflow menu or move to the tab that owns them (e.g. Settings). - **R3: No repetition, no obvious facts (A6, A7).** Every item F2–F10 in §4 is resolved: the repeated text is removed or said once, and the obvious label is dropped. The spec names how each one is resolved. Specifically, no rendered Compliance surface: - shows a status badge that only restates the section it sits in (e.g. "Fail" under "Gaps"); - shows a field whose value is the default ("every repo", zero counts, "None") unless it is editable there; - repeats the same sentence on more than one row of a list (a shared state is said once for the group); - shows the same fact twice in one header (badge + sentence, or pack + version in the header *and* the subtitle). - **R4: One name, one destination (A3).** A rule's name opens the same kind of page wherever it appears: the rule page. Evidence for a repo × rule is a separate, explicitly labelled action or link. - **R5: Consistent words (A3).** Mode values use their labels (Observe/Advise/Nudge/Gate/Lock) everywhere. Every label follows `docs/standards/ui-copy-standards.md`. - **R6: Dropped features are explicit (D5).** The architecture spec lists every removed feature with a one-line reason. Anything not listed stays reachable. No feature disappears silently. - **R7: Available on dev (charter).** The redesigned UI is the only Compliance UI: no flag or toggle gates it. It is live on the dev control plane (`dev.jaah.ai`) for an operator whose org has Portfolio Compliance on. Operator decisions: D3 full redesign to the UI style guide; Architect Q1/Q2: **no capability is dropped** — rare actions move into a ⋯ menu or appear only in context; Q4 repo page = gaps first, 2 tabs (Overview · Rules). **Binding design principle:** a page shows at most one always-visible primary action; any other action goes into the page's ⋯ (`ui/OverflowMenu`), a row's ⋯, or appears only while its condition holds. Breadcrumb ends at the parent; the page title names the page; a breadcrumb never repeats the title. Full design docs: the epic's PRD and Architecture artifacts (Tasks 10032 / 10033); §-numbers refer to the Architecture document; its §6 "Dropped / moved" table is binding. States covered: an org with **no scan yet**, **a scan running**, **results present**, **a project not scannable**, a **ready-made** active pack and an **org (forked)** pack. A viewer is either **compliance:view only** or **compliance:edit**, and `guard_enabled` is **on** or **off**. Unless a criterion names a state, it holds in all of them. Desktop = 1440×900; phone = 390×844 (`docs/standards/ui-style-guide.md` § Checking a page). Credentials & reach (Architect §7, verbatim): - AC1–AC17 (dev console UI), guard **on** states — `me/jaah/debug/main/operator-login` (owner/admin in several dev orgs). Environment: dev control plane via its public ALB **`https://app.dev.jaah.ai`** (`docs/architecture.md:185`). Target tenant: **Org B** — **verified**: `credential_get` succeeded. A sign-in to `app.dev.jaah.ai` returned 200. Switching to Org B returned 200, its session reads `compliance_enabled` and `guard_enabled` true, and `GET /api/compliance/setup` returned 200 (10 projects, 3 packs). The internal `dev.jaah.ai` ALB timed out from this node (tailnet-only), so oracles use `app.dev.jaah.ai`. - AC1–AC17, guard **off** states — Same credential. Target tenant: **TimeSaver2** — **verified**: the switch returned 200, `compliance_enabled` true, `guard_enabled` false, and `GET /api/compliance/setup` returned 200 (2 projects, 2 packs) - AC6 (compliance:view-only viewer) — Same credential: the login is `owner` in Org B (admin covers non-admin). The coder adds a view-only member through the console's Users/Groups UI at verify time and signs in as it — **verified** (owner identity probed above; creating the member is a console step, not a missing credential) - AC8 / AC16 data (≥2 not-scannable projects, fresh results) — Same credential, Org B set up through the console (projects with no node, a rescan) — **verified** (Org B reachable with 10 projects; data is arranged at verify) - AC18 (`./dc check quick`, unit + e2e suites) — Nothing beyond the worktree — **verified** (worktree only) Out of scope: - Do NOT touch `/compliance/verify` (`apps/web/src/pages/ComplianceVerifyPage.tsx`), the task manifest (`apps/web/src/components/tasks/ComplianceManifest.tsx`), org compliance signing (`apps/web/src/pages/settings/complianceSigning/`), `apps/web/src/pages/orgs/OrgSettingsTab.tsx`, `apps/web/src/pages/customers/ComplianceDeleteDialog.tsx` or the plan feature (`apps/web/src/pages/products/plan/PlanFields.tsx`). - Do NOT change scan/score semantics: `apps/api/app/routes/compliance.py` matrix/repo/cell computation, levels, the auditor runner, the daily-scan cron behaviour, Guard enforcement in `apps/jaahd/guards/`. - Do NOT change permissions: `compliance:view` / `compliance:edit` and the `RequireCompliance` / plan gating stay as they are. - Do NOT add a second sidebar entry for Compliance, and do NOT add a feature flag for the new UI. - Do NOT remove any capability silently; a removal is allowed only if listed in Architecture §6 (which drops none). - No data migration: stored packs, rules, waivers, facts and scans are untouched. - Do NOT touch the `/compliance` shell, Repos/Rules/Guard/Settings tabs or the rule page (C2, C3, C5). Done means: - AC7 (repo, evidence): ≤3 visible header actions — At 1440×900, on the repo page and the evidence pane, count the visible buttons/links in the page header (excluding the overflow ⋯ and the tabs). There are ≤3 (design target: Rescan + ⋯). - AC9 (repo): No restating badges or default values — On the oam-demo repo page (dev): no "Fail" badge inside the Gaps list, no "Why it matters:" label repeated per gap, no "Guard blocks: 0 … 0" when both are zero, and no not-scannable badge followed by a sentence restating it. - AC10: Facts don't repeat per chip — On oam-demo Overview (dev), the words "Confirm" / "Correct" / "inferred" each appear at most once in the facts area (e.g. one bulk action or per-fact actions on hover/menu); Confirm/Correct stay reachable from each fact's row ⋯. - AC11 (gap, repo Rules list, evidence): Rule names open the rule page everywhere — Click a rule name on: a repo's gap, a repo's per-rule list, the evidence page. Each lands on that rule's page. Evidence opens only from a control labelled for evidence. - AC12: Mode labels — Search the repo page's and evidence pane's rendered text: no lower-case raw mode token (`observe`, `advise`, `nudge`, `gate`, `lock`) stands as a value; the label is used. - AC13 (repos, cells): Old links resolve — Open `/compliance/repos/<id>`, `/compliance/repos/<id>/cells/<key>` and `/compliance/repos/<id>?tab=debt` on dev. Each shows its content (debt → Rules tab with the Waived filter), never a 404 or a blank page. - AC16 (repo page): Readable, not just smaller — At 1440×900 and 390×844 on the repo page: no rule or project name truncated to an ellipsis (names wrap); no horizontal page scroll; table columns don't wrap single words mid-word. The oam-demo repo page above the fold shows the level, the gap count and the first gap with its Fix action. **Tightened:** attach 1440 and 390 screenshots of the repo Overview, repo Rules and evidence pane to the report; a page that passes the counts but reads cramped, mis-aligned or with orphaned controls fails. - No capability lost: Waive, Revoke, Fix, Fix all, Confirm, Correct, Auditor run and Rescan are each reachable for an editor (verify by clicking each on dev). - AC18: `./dc check quick` passes; `RepoPage.test.tsx`, `GapRow.test.tsx`, `CellPage.test.tsx`, `WaiverList.test.tsx` and the repo/cell cases of `apps/web/e2e/compliance.spec.ts` pass, updated to the new structure.

Outcome

Repo page redesigned and merged (#6924, 9c7b0f55): gaps first, Overview · Rules, ⋯ menus, evidence pane titled by its rule. Quick gate, unit tests and compliance e2e green; checked on dev after a successful deploy. Visual check at 1440/390 showed clean, wrapping layouts. Memory: none applied.

Pull request

Artifacts

Activity

  • Draft
  • Ready
  • Runner started
  • Runner ended (done)