# Requirements Archive: v1.9 Frontmatter Rationalization & Library-Record Deprecation

**Archived:** 2026-05-07
**Status:** SHIPPED

For current requirements, see `.planning/REQUIREMENTS.md`.

---

# Requirements: PaperForge

**Defined:** 2026-05-07
**Core Value:** Researchers always know what papers they have, what state those papers are in, and whether each paper is reliably usable by AI with traceable fulltext, figures, notes, and source links.

## v1.9 Requirements

Requirements for milestone v1.9: Frontmatter Rationalization & Library-Record Deprecation.

### Library-Record Deprecation

- [ ] **LRD-01**: New users (no existing library-records) never see `<control_dir>/library-records/` created — sync skips library-record generation entirely when no legacy records exist.
- [ ] **LRD-02**: Upgrading users get lossless migration: all frontmatter fields from existing library-records that are needed by the formal note workflow (has_pdf, do_ocr, analyze, ocr_status, deep_reading_status, recommend_analyze) are merged into corresponding formal notes.
- [ ] **LRD-03**: After migration, `paperforge sync` no longer creates new library-record files for any papers (neither new nor existing).
- [ ] **LRD-04**: Orphaned-record cleanup logic in `run_index_refresh()` is updated to work with formal notes instead of library-records.
- [ ] **LRD-05**: `paperforge doctor` detects stale library-records directory and recommends user action (manual delete or ignore).

### Base View Fix

- [ ] **BASE-01**: Base views no longer declare `lifecycle`, `maturity_level`, or `next_step` as properties — these are dashboard-owned and never written to .md frontmatter.
- [ ] **BASE-02**: Base views restore `has_pdf`, `do_ocr`, `analyze`, and `ocr_status` as declared properties with correct display names.
- [ ] **BASE-03**: Base view folder filter is updated from `<control_dir>/<domain>` to `<literature_dir>/<domain>` (formal notes directory).
- [ ] **BASE-04**: All 8 workflow views (控制面板, 推荐分析, 待OCR, OCR完成, 待深度阅读, 深度阅读完成, 正式卡片, 全记录) use the same filter/sort logic as the current master-branch Base views.
- [ ] **BASE-05**: Base generation (`base_views.py`) regenerates all .base files on next `paperforge sync` with the corrected properties and folder filters.

### Frontmatter Rationalization

- [ ] **FM-01**: Formal note frontmatter excludes workspace path fields (`paper_root`, `main_note_path`, `fulltext_path`, `deep_reading_path`, `ai_path`) — these are deterministically derivable from `zotero_key + title + domain`.
- [ ] **FM-02**: Formal note frontmatter excludes OCR infrastructure fields (`ocr_job_id`, `ocr_md_path`, `ocr_json_path`) — these are internal pipeline data.
- [ ] **FM-03**: Formal note frontmatter retains workflow flags needed by Base views: `has_pdf`, `do_ocr`, `analyze`, `ocr_status`, `deep_reading_status`.
- [ ] **FM-04**: Formal note frontmatter retains core identity fields: `title`, `year`, `journal`, `first_author` (not full `authors` list), `doi`, `pmid`, `zotero_key`, `domain`, `abstract`, `tags`.
- [ ] **FM-05**: Per-workspace `paper-meta.json` is created in each paper's workspace directory, storing `ocr_job_id`, `ocr_md_path`, `ocr_json_path`, `health` dict, `maturity` breakdown, `paperforge_version`, and a `migrated_from` field (when upgrading from library-records).
- [ ] **FM-06**: `_build_entry()` writes the slimmed frontmatter fields into formal notes; the full internal state (including workspace paths, OCR details, derived state) remains in the canonical index and paper-meta.json.
- [ ] **FM-07**: `library_record_markdown()` is removed or deprecated — no new library-record .md files are generated.

### Plugin Dashboard Sync

- [ ] **PLG-01**: Plugin `_fetchStats()` and all dashboard render methods continue to work after index entry field changes — field references in main.js are verified against the final `_build_entry()` output.
- [ ] **PLG-02**: Plugin Quick Action buttons (Open Fulltext, Jump to Deep Reading, Copy Context) resolve workspace paths correctly after workspace stabilization (WS-01, WS-02).
- [ ] **PLG-03**: Plugin dashboard lifecycle stepper, health matrix, maturity gauge, and bar chart read from canonical index fields without regressions after frontmatter rationalization.
- [ ] **PLG-04**: Version badge displays correct `paperforge_version` from canonical index envelope (`index.paperforge_version`), not from stale cached stats.
- [ ] **PLG-05**: Plugin dashboard lifecycle key alignment verified: all JS code uses `deep_read_done`/`ai_context_ready` matching Python `compute_lifecycle()` output.
- [ ] **PLG-06**: Plugin CSS includes all dashboard component styles (loading skeleton, metric cards, lifecycle stepper, health matrix, maturity gauge, bar chart, per-paper view, collection view, deep-reading mode).

### Workspace Stabilization

- [ ] **WS-01**: On first sync of a new paper, `_build_entry()` creates the workspace directory and writes `main_note_path` directly (no flat-first-then-migrate path).
- [ ] **WS-02**: `fulltext_path` bridge: after OCR completes, the fulltext content at `<system_dir>/PaperForge/ocr/<key>/fulltext.md` is copied or linked to the workspace `fulltext.md` path declared in the canonical index entry.
- [ ] **WS-03**: `discussion.py` reads the workspace `ai_path` from the canonical index entry (via `_build_ai_dir()`) instead of independently reconstructing the path.
- [ ] **WS-04**: `migrate_to_workspace()` handles the fulltext bridging gap during migration: when migrating old flat notes, copies OCR output to workspace `fulltext.md` if available.
- [ ] **WS-05**: `paperforge doctor` validates workspace integrity: checks that workspace dirs exist for indexed papers, that fulltext.md exists in workspace when ocr_status=done, and reports gaps.

## Future Requirements

Deferred to future milestone.

### v1.8 Dashboard Features (paused)

- **DASH-01**: Deep-reading dashboard mode with status bar, Pass 1 summary, and AI Q&A history.
- **DASH-02**: "Jump to Deep Reading" button on per-paper dashboard card.
- **DISC-01**: AI discussion recorder: `/pf-paper` and agent chats produce `discussion.md` + `discussion.json` in workspace `ai/`.
- **BUG-01**: Remove meaningless "ai" row from plugin UI.
- **BUG-02**: Restore version number display in plugin.

## Out of Scope

| Feature | Reason |
|---------|--------|
| Replacing Zotero or Better BibTeX | Project is built around them. |
| Automatically triggering deep-reading agents from workers | Lite architecture intentionally separates worker and agent. |
| Cloud-hosted multi-user service | Local-first, single-user. |
| Full OCR provider abstraction | PaddleOCR is the priority. |
| Plugin auto-update | Deferred to when listed on Obsidian Community Plugins. |
| v1.8 dashboard features | Paused — structural foundation (v1.9) must land first. |

## Traceability

| Requirement | Phase | Status |
|-------------|-------|--------|
| FM-01 | Phase 37 | Pending |
| FM-02 | Phase 37 | Pending |
| FM-03 | Phase 37 | Pending |
| FM-04 | Phase 37 | Pending |
| FM-05 | Phase 37 | Pending |
| FM-06 | Phase 37 | Pending |
| FM-07 | Phase 37 | Pending |
| WS-01 | Phase 38 | Pending |
| WS-02 | Phase 38 | Pending |
| WS-03 | Phase 38 | Pending |
| WS-04 | Phase 38 | Pending |
| WS-05 | Phase 38 | Pending |
| BASE-01 | Phase 39 | Pending |
| BASE-02 | Phase 39 | Pending |
| BASE-03 | Phase 39 | Pending |
| BASE-04 | Phase 39 | Pending |
| BASE-05 | Phase 39 | Pending |
| LRD-01 | Phase 40 | Pending |
| LRD-02 | Phase 40 | Pending |
| LRD-03 | Phase 40 | Pending |
| LRD-04 | Phase 40 | Pending |
| LRD-05 | Phase 40 | Pending |
| PLG-01 | Phase 41 | Pending |
| PLG-02 | Phase 41 | Pending |
| PLG-03 | Phase 41 | Pending |
| PLG-04 | Phase 41 | Pending |
| PLG-05 | Phase 41 | Pending |
| PLG-06 | Phase 41 | Pending |

**Coverage:**
- v1.9 requirements: 28 total
- Mapped to phases: 28 ✓
- Unmapped: 0 ✓

---
*Requirements defined: 2026-05-07*
*Last updated: 2026-05-07 after initial definition*

## Reference Vault Learnings (D:\L\Med\Research_LitControl_Sandbox)

The reference vault contains a manually-maintained working copy of the PaperForge plugin that MUST be treated as the ground truth for dashboard behavior. Key lessons absorbed:

### Working patterns to preserve
- **Mode detection** (`_detectAndSwitch`): `.base` → collection, `.md` with `zotero_key` → per-paper, otherwise → global. Simple, direct, works reliably.
- **Global mode** (`_renderGlobalMode`): metric cards + OCR pipeline section. Calls `_fetchStats` to read canonical index JSON directly (no CLI spawn).
- **Per-paper mode** (`_renderPaperMode`): lifecycle stepper (6 stages), health matrix (4 dimensions), maturity gauge (6 levels), next-step recommendation card with actionable buttons.
- **Collection mode** (`_renderCollectionMode`): domain-level metric cards (Papers/Fulltext Ready/Deep Read), lifecycle bar chart, health overview grid (healthy/unhealthy counts per dimension).
- **Quick Actions** (`_renderActions`): 7 action cards rendered in a grid — Sync Library, Run OCR, Deep-Reading Queue, Doctor, Repair, Copy Context, Copy Collection Context.
- **`_switchMode`**: Clears `_contentEl` before rendering new mode. `_refreshCurrentMode` for index-change updates (invalidates cache, re-renders same mode).
- **Event subscriptions**: `active-leaf-change` (debounced 300ms → `_detectAndSwitch`), `modify` (formal-library.json only → `_invalidateIndex` + `_refreshCurrentMode`).
- **`onClose`**: Full cleanup — unsubscribe events, clear timer, null cached items + stats.
- **CSS classes**: `paperforge-metric-card`, `paperforge-lifecycle-stepper`, `paperforge-health-matrix` (2x2 grid), `paperforge-maturity-gauge` (6 segments), `paperforge-bar-chart` (proportional bars), `paperforge-collection-view`, `paperforge-paper-view`, `paperforge-next-step-card`, `paperforge-paper-actions`.

### Issues fixed in current branch (verify not reverted)
- Lifecycle key alignment: reference uses `deep_read`/`ai_ready`/`imported`; current branch uses `deep_read_done`/`ai_context_ready` (matching Python `compute_lifecycle()` output).
- `_resolveModeForFile` abstraction: current branch extracted mode resolution into a pure function with deep-reading.md detection. Reference does inline detection without deep-reading support.
- Deep-reading mode (`_renderDeepReadingMode`): ONLY in current branch. Reads `deep-reading.md` + `discussion.json` via vault adapter. Must NOT regress during v1.9 work.

### Issues to fix (both files)
- **Version badge**: reads `this._cachedStats?.version` (stale) instead of `index.paperforge_version` from JSON envelope. First load always shows `v—`.

### Reference vault structural notes
- Reference vault main.js: 103KB, 2068 lines (leaner, no deep-reading mode)
- Current branch main.js: 118KB, 2337 lines (added deep-reading + resolveModeForFile)
- Reference CSS: 35.9KB vs current 39.1KB (current adds deep-reading mode styles)
- All dashboard components (lifecycle stepper, health matrix, maturity gauge, bar chart) are IDENTICAL between reference and current branch — no structural divergence
