F18 tasks: History and Timeline
Dependency order. Each step names the requirements it satisfies, the test that proves them, and a size. Size is one module, several modules, or a schema change. No step lacks a requirement.
1. Keep the editor dialog
Satisfies: F18-REQ-001, F18-REQ-002, F18-REQ-003, F18-REQ-004, F18-REQ-005.
Size: several modules (components/history-dialog.tsx, components/history-store.ts, components/document-chrome.tsx).
Tests:
- F18-AC-001a in
lib/history/dialog.test.ts - F18-AC-002a, F18-AC-002b in
lib/history/dialog.test.ts - F18-AC-003a in
lib/history/dialog.test.ts - F18-AC-004a, F18-AC-004b in
lib/history/dialog.test.ts - F18-AC-005a in
lib/history/dialog.test.ts
While the Ledger screen is not in use, Version history opens the dialog and does not navigate. Rows are current, at most 50 snapshots, then the repository copy. Restore replaces the working copy, writes Before restoring, toasts Version restored, and does not insert a revisions row. A matching row disables Restore this version.
2. Open the history screen on the document
Satisfies: F18-REQ-006, F18-REQ-007.
Size: several modules (lib/history/list.ts, components/history/history-screen.tsx, app/[project]/[...slug]/history/page.tsx).
Tests: F18-AC-006a, F18-AC-007a, F18-AC-007b in lib/history/list.test.ts.
Depends on step 1 for the menu item, which switches target when the Ledger screen is in use. The path for docs/notes.md in guide is /guide/docs/notes/history. The list is every revision, newest first, with no localStorage row. The first selection is the head and its parent.
3. Diff two revisions
Satisfies: F18-REQ-008.
Size: one module (lib/history/diff.ts).
Tests: F18-AC-008a, F18-AC-008b in lib/history/diff.test.ts.
Depends on step 2. The older created_at is the base. Equal times use the smaller revision id. The diff covers the full UTF-8 file, frontmatter in stored key order.
4. Restore by appending a revision
Satisfies: F18-REQ-009, F18-REQ-010, F18-REQ-011, F18-REQ-012, F18-REQ-013.
Size: one module (lib/history/restore.ts).
Tests:
- F18-AC-009a in
lib/history/restore.test.ts - F18-AC-010a, F18-AC-012a in
lib/history/restore.test.ts - F18-AC-011a in
lib/history/restore.test.ts - F18-AC-013a in
lib/history/restore.test.ts
Depends on step 2 and on F19 step 2 (nullable author_user_id while sign-in is absent). Validate against the schemas loaded now. No error appends one revision with message Restore, parent equal to the previous head, and the chosen row unchanged. An error, including field_missing against a schema that changed later, appends nothing. Warnings still append. Identical bytes return no_change.
5. Allow restore by role
Satisfies: F18-REQ-014, F18-REQ-015, F18-REQ-020.
Size: one module (lib/history/restore.ts).
Tests: F18-AC-014a, F18-AC-015a, F18-AC-015b, F18-AC-015c, F18-AC-015d, F18-AC-020a, F18-AC-020b in lib/history/access.test.ts.
Depends on step 4. While sign-in is absent, the person at the keyboard restores and no role is checked. When sign-in exists, Owner and Editor restore. Contributor, Viewer, agent key, and OAuth grant receive permission_denied and append nothing. A public read-only visitor sees the list and cannot restore.
6. Group the space on a timeline
Satisfies: F18-REQ-016, F18-REQ-017, F18-REQ-018, F18-REQ-019.
Size: several modules (lib/history/timeline.ts, components/history/timeline-screen.tsx, app/[project]/timeline/page.tsx).
Tests:
- F18-AC-016a, F18-AC-016b in
lib/history/timeline.test.ts - F18-AC-017a in
lib/history/timeline.test.ts - F18-AC-018a, F18-AC-018b in
lib/history/timeline.test.ts - F18-AC-019a in
lib/history/timeline.test.ts
Depends on step 2. The route is /{project}/timeline. Days use the viewer's time zone. The list includes a human save and a merge, and excludes an open proposal, a draft, and a localStorage snapshot. Type and author filters both apply when set. An agent key shows its label and the agent glyph.
7. Move the list with J and K
Satisfies: F18-REQ-021.
Size: several modules (components/history/history-screen.tsx, components/history/timeline-screen.tsx).
Tests: F18-AC-021a, F18-AC-021b in lib/history/keys.test.ts.
Depends on steps 2 and 6. J selects the next row. K selects the previous row. The binding applies on the history list and on the timeline list.