diff --git a/docs/superpowers/specs/2026-04-23-checkpoints-grid-row-design.md b/docs/superpowers/specs/2026-04-23-checkpoints-grid-row-design.md
new file mode 100644
index 00000000..724f97fc
--- /dev/null
+++ b/docs/superpowers/specs/2026-04-23-checkpoints-grid-row-design.md
@@ -0,0 +1,252 @@
+# Checkpoints in the Identity grid + locale time + remove History — design
+
+**Date:** 2026-04-23
+**Scope:** three targeted UX changes on the unified app deployment page, follow-up to `2026-04-23-deployment-page-polish-design.md`.
+**Status:** Draft — pending user review.
+
+## 1. Motivation
+
+The previous polish shipped a collapsible `CheckpointsTable` as a standalone section below the Identity & Artifact block. That made the visual hierarchy noisy — Checkpoints became a third section between Identity and the config tabs, competing for attention. The proper home for "how many past deployments exist and what were they" is *inside* the Identity panel, as one more row in its config grid.
+
+Three changes:
+
+1. Move the checkpoints section into the Identity & Artifact config grid as an in-grid row.
+2. Format the Deployed-column sub-line to the user's locale (replaces the raw ISO string).
+3. Remove the redundant `HistoryDisclosure` from the Deployment tab — the checkpoints table covers the same information and the per-deployment log drill-down now lives in the drawer.
+
+## 2. Design
+
+### 2.1 Checkpoints row in the Identity config grid
+
+**Current structure** (`IdentitySection.tsx`):
+
+```tsx
+
+ Identity & Artifact
+
+ ... label + value cells (Application Name, Slug, Environment, External URL, Current Version, Application JAR) ...
+
+ {children} {/* CheckpointsTable + CheckpointDetailDrawer currently render here */}
+
+```
+
+**New structure:**
+
+```tsx
+
+ Identity & Artifact
+
+ ... existing label + value cells ...
+ {checkpointsSlot} {/* NEW: rendered as direct grid children via React.Fragment */}
+
+ {children} {/* still used — for the portal-rendered CheckpointDetailDrawer */}
+
+```
+
+**Slot contract.** `IdentitySection` gains a new prop:
+
+```ts
+interface IdentitySectionProps {
+ // ... existing props ...
+ checkpointsSlot?: ReactNode;
+ children?: ReactNode;
+}
+```
+
+`checkpointsSlot` is expected to be a React.Fragment whose children are grid-direct cells (spans / divs). React fragments are transparent to CSS grid, so the inner elements become direct children of `configGrid` and flow into grid cells like the existing rows.
+
+**`CheckpointsTable` rewrite.** Instead of wrapping itself in `
`, the component returns a Fragment of grid-ready children:
+
+```tsx
+if (checkpoints.length === 0) {
+ return null;
+}
+
+return (
+ <>
+ Checkpoints
+
+
+
+ {open && (
+
+
...
+ {hidden > 0 && !expanded && (
+
+ )}
+
+ )}
+ >
+);
+```
+
+**Why this layout.**
+- The trigger button sits in the value column (180px label + 1fr value). When closed, the row reads `Checkpoints ▸ Expand (5)`.
+- When opened, a third grid child appears: a div that spans both columns (`grid-column: 1 / -1`) containing the `
` + optional "Show older" button. This gives the 7-column table the full grid width so columns don't crush.
+- The trigger remains in the value cell of the label row above — collapse/expand stays attached to its label.
+
+**CSS changes** (`AppDeploymentPage.module.css`):
+
+*Add:*
+
+```css
+.checkpointsTriggerCell {
+ display: flex;
+ align-items: center;
+}
+
+.checkpointsTrigger {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ background: none;
+ border: none;
+ padding: 0;
+ color: var(--text-primary);
+ cursor: pointer;
+ font: inherit;
+ text-align: left;
+}
+
+.checkpointsTrigger:hover {
+ color: var(--amber);
+}
+
+.checkpointsTableFullRow {
+ grid-column: 1 / -1;
+ margin-top: 4px;
+}
+```
+
+*Remove (no longer referenced):*
+- `.checkpointsSection`
+- `.checkpointsHeader` + `.checkpointsHeader:hover`
+- `.checkpointsCount`
+
+*Keep:* `.checkpointsChevron` (still used by the trigger for the arrow). `.checkpointsTable`, `.jarCell`, `.jarName`, `.jarStrike`, `.archivedHint`, `.isoSubline`, `.muted`, `.strategyPill`, `.outcomePill`, `.outcome-*`, `.chevron`, `.showOlderBtn`, `.checkpointArchived` — all still referenced by the table body.
+
+*Also remove* (cleanup — unrelated dead weight from the retired `Checkpoints.tsx` row-list view, safe to delete because no TSX references remain):
+- `.checkpointsRow`
+- `.disclosureToggle`
+- `.checkpointList`
+- `.checkpointRow`
+- `.checkpointMeta`
+- Standalone `.checkpointArchived { color: var(--warning); font-size: 12px; }` (the table-row variant `.checkpointsTable tr.checkpointArchived { opacity: 0.55; }` stays)
+- `.historyRow` (see §2.3)
+
+### 2.2 Deployed-column locale sub-line
+
+In `CheckpointsTable.tsx`, the Deployed `
` currently renders:
+
+```tsx
+
+ {d.deployedAt && timeAgo(d.deployedAt)}
+
{d.deployedAt}
+
+```
+
+Replace with:
+
+```tsx
+
+ {d.deployedAt && timeAgo(d.deployedAt)}
+
+ {d.deployedAt && new Date(d.deployedAt).toLocaleString()}
+
+
+```
+
+`new Date(iso).toLocaleString()` uses the browser's resolved locale via the Intl API. No locale plumbing, no new util.
+
+Primary "5h ago" display stays unchanged.
+
+### 2.3 Remove the History disclosure from the Deployment tab
+
+`HistoryDisclosure.tsx` renders a collapsible `DataTable` + nested `StartupLogPanel`. It duplicates information now surfaced via `CheckpointsTable` + `CheckpointDetailDrawer` (which has its own LogsPanel).
+
+**Changes:**
+
+- Delete `ui/src/pages/AppsTab/AppDeploymentPage/DeploymentTab/HistoryDisclosure.tsx`.
+- `ui/src/pages/AppsTab/AppDeploymentPage/DeploymentTab/DeploymentTab.tsx` — remove the import and the `` render at the bottom of the tab.
+- `ui/src/pages/AppsTab/AppDeploymentPage/AppDeploymentPage.module.css` — drop the `.historyRow` rule (covered in §2.1's CSS cleanup list).
+
+## 3. Page wiring
+
+`ui/src/pages/AppsTab/AppDeploymentPage/index.tsx` currently passes the table + drawer together as `children` to `IdentitySection`:
+
+```tsx
+
+ {app && (
+ <>
+
+ {selectedDep && }
+ >
+ )}
+
+```
+
+After the change:
+
+```tsx
+ : undefined}
+>
+ {app && selectedDep && }
+
+```
+
+The drawer continues to pass through as `children` because `SideDrawer` uses `createPortal` — it can live at any DOM depth, but conceptually sits outside the Identity grid so it doesn't become a stray grid cell.
+
+## 4. Files touched
+
+| Path | Change |
+|------|--------|
+| `ui/src/pages/AppsTab/AppDeploymentPage/IdentitySection.tsx` | Add `checkpointsSlot?: ReactNode`; render inside `configGrid` after JAR row |
+| `ui/src/pages/AppsTab/AppDeploymentPage/CheckpointsTable.tsx` | Return React.Fragment of grid-ready children; replace header wrapper with `checkpointsTrigger` button; locale sub-line in Deployed cell |
+| `ui/src/pages/AppsTab/AppDeploymentPage/CheckpointsTable.test.tsx` | Update `expand()` helper to target `/expand|collapse/i`; add test asserting locale sub-line differs from raw ISO |
+| `ui/src/pages/AppsTab/AppDeploymentPage/AppDeploymentPage.module.css` | Add `.checkpointsTriggerCell`, `.checkpointsTrigger`, `.checkpointsTableFullRow`; remove obsolete classes listed in §2.1 |
+| `ui/src/pages/AppsTab/AppDeploymentPage/index.tsx` | Split `checkpointsSlot` out of `children`; drawer stays in `children` |
+| `ui/src/pages/AppsTab/AppDeploymentPage/DeploymentTab/DeploymentTab.tsx` | Remove `HistoryDisclosure` import + render |
+| `ui/src/pages/AppsTab/AppDeploymentPage/DeploymentTab/HistoryDisclosure.tsx` | **Delete** |
+
+## 5. Testing
+
+**Unit (vitest + RTL):**
+
+- Update `CheckpointsTable.test.tsx`:
+ - `expand()` helper targets `screen.getByRole('button', { name: /expand|collapse/i })`.
+ - The "defaults to collapsed" test asserts the trigger button exists and reads `Expand (1)`; rows hidden.
+ - The "clicking header expands" test clicks the button (now labeled `Expand`); after click, button label is `Collapse`; rows visible.
+ - One new test: render the table with `deployedAt: '2026-04-23T10:35:00Z'`, expand, grab the `.isoSubline` element, assert its text contains neither the raw ISO `T` nor `Z`, i.e. it was parsed into a localized form. (Avoids asserting the exact string — CI locales vary.)
+
+**Manual smoke:**
+
+- Page loads → `Checkpoints | ▸ Expand (N)` as a grid row under Application JAR. Collapsed by default.
+- Click trigger → text swaps to `▾ Collapse (N)`; table appears below, spanning full grid width.
+- Deployed column sub-line shows a local-format date/time (e.g. `4/23/2026, 12:35:00 PM` in `en-US`).
+- Deployment tab no longer shows `▶ History (N)` below `Startup Logs`.
+- `CheckpointDetailDrawer` still opens on row click (unaffected).
+- Empty state: app with no checkpoints shows no Checkpoints row at all.
+
+## 6. Non-goals
+
+- No changes to `CheckpointDetailDrawer` layout or behavior.
+- No changes to `timeAgo` (other components still use it).
+- No new locale-formatting helpers; `toLocaleString()` inline at the one callsite.
+- Not touching primary Deployed column display (keeps "5h ago").
+- No changes to the `CheckpointsTable` columns themselves.
+
+## 7. Open questions
+
+None — all resolved during brainstorming.