diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index ae19558a..b09f6646 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -12,7 +12,7 @@ Requirements for milestone v1.6: AI-Ready Literature Asset Foundation. - [x] **CONF-01**: User can configure PaperForge from a single canonical config source (`paperforge.json`) that is interpreted consistently by CLI, workers, setup flow, and plugin. - [x] **CONF-02**: User can upgrade an existing vault and keep working even if legacy top-level config keys are still present; the system reads them compatibly and writes the normalized shape going forward. - [ ] **CONF-03**: User can inspect the effective runtime configuration and see which values are authoritative versus UI cache values. -- [ ] **CONF-04**: User can safely edit plugin settings without creating a second runtime truth that disagrees with Python commands. +- [x] **CONF-04**: User can safely edit plugin settings without creating a second runtime truth that disagrees with Python commands. ### Canonical Asset Index @@ -85,7 +85,7 @@ Which phases cover which requirements. Updated during roadmap creation. | CONF-01 | Phase 22 | Complete | | CONF-02 | Phase 22 | Complete | | CONF-03 | Phase 22 | Pending | -| CONF-04 | Phase 22 | Pending | +| CONF-04 | Phase 22 | Complete | | ASSET-01 | Phase 23 | Pending | | ASSET-02 | Phase 23 | Pending | | ASSET-03 | Phase 23 | Pending | diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index fb8b96f6..14bf1ada 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -49,7 +49,7 @@ v1.6 turns PaperForge's existing sync, OCR, deep-reading, status, plugin, and `f Plans: - [x] 22-01-PLAN.md — Python config layer: schema_version, migration engine, sync hook -- [ ] 22-02-PLAN.md — Plugin config truth: read paperforge.json, remove DEFAULT_SETTINGS path fields +- [x] 22-02-PLAN.md — Plugin config truth: read paperforge.json, remove DEFAULT_SETTINGS path fields - [ ] 22-03-PLAN.md — Setup wizard cleanup: vault_config-only output + doctor migration detection + config source tracing **UI hint**: yes @@ -108,7 +108,7 @@ Plans: | Phase | Plans Complete | Status | Completed | |-------|----------------|--------|-----------| -| 22. Configuration Truth & Compatibility | 1/3 | In Progress| | +| 22. Configuration Truth & Compatibility | 2/3 | In Progress| | | 23. Canonical Asset Index & Safe Rebuilds | 0/TBD | Not started | - | | 24. Derived Lifecycle, Health & Maturity | 0/TBD | Not started | - | | 25. Surface Convergence, Doctor & Repair | 0/TBD | Not started | - | diff --git a/.planning/STATE.md b/.planning/STATE.md index 182a0367..9147006a 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -3,13 +3,13 @@ gsd_state_version: 1.0 milestone: v1.6 milestone_name: AI-Ready Literature Asset Foundation status: Ready to execute -stopped_at: Completed 22-01-PLAN.md -last_updated: "2026-05-03T14:43:30.072Z" +stopped_at: Completed 22-02-PLAN.md +last_updated: "2026-05-03T14:59:30.150Z" progress: total_phases: 5 completed_phases: 0 total_plans: 4 - completed_plans: 1 + completed_plans: 2 --- # Project State @@ -24,7 +24,7 @@ See: .planning/PROJECT.md (updated 2026-05-03) ## Current Position Phase: 22 (configuration-truth-compatibility) — EXECUTING -Plan: 2 of 3 +Plan: 3 of 3 ## Performance Metrics @@ -48,6 +48,7 @@ Plan: 2 of 3 - Trend: Stable | Phase 22-configuration-truth-compatibility P01 | 4 min | 3 tasks | 3 files | +| Phase 22-configuration-truth-compatibility P02 | 6 min | 3 tasks | 1 files | ## Accumulated Context @@ -60,6 +61,7 @@ Recent decisions affecting current work: - `formal-library.json` evolves into the canonical derived asset index rather than introducing a parallel index. - Plugin remains a thin shell over CLI logic and canonical index outputs. - [Phase 22-configuration-truth-compatibility]: schema_version is metadata excluded from load_vault_config() path config output; use get_paperforge_schema_version() instead +- [Phase 22-configuration-truth-compatibility]: Added paddleocr_api_key and zotero_data_dir to DEFAULT_SETTINGS to prevent data loss from saveSettings() key filtering — Plan omitted these keys from DEFAULT_SETTINGS, but saveSettings() now filters persisted keys to only DEFAULT_SETTINGS entries - would have permanently deleted user API keys and Zotero paths ### Pending Todos @@ -72,6 +74,6 @@ None yet. ## Session Continuity -Last session: 2026-05-03T14:43:23.249Z -Stopped at: Completed 22-01-PLAN.md +Last session: 2026-05-03T14:59:30.147Z +Stopped at: Completed 22-02-PLAN.md Resume file: None diff --git a/.planning/phases/22-configuration-truth-compatibility/22-02-SUMMARY.md b/.planning/phases/22-configuration-truth-compatibility/22-02-SUMMARY.md new file mode 100644 index 00000000..5985de7c --- /dev/null +++ b/.planning/phases/22-configuration-truth-compatibility/22-02-SUMMARY.md @@ -0,0 +1,131 @@ +--- +phase: 22-configuration-truth-compatibility +plan: "02" +subsystem: plugin, config +tags: + - main.js + - paperforge.json + - Obsidian + - plugin + - DEFAULT_SETTINGS + - vault_config + +# Dependency graph +requires: + - phase: 22-01 + provides: Python config migration (auto-migrates top-level keys to vault_config block) +provides: + - Plugin reads path configuration from canonical paperforge.json (not from DEFAULT_SETTINGS or data.json) + - Plugin Settings tab displays path values from paperforge.json + - Plugin data.json no longer stores path directory fields + - savePaperforgeJson() writes config changes to paperforge.json vault_config block + - Fresh vaults without paperforge.json do not crash plugin (graceful fallback to Python defaults) +affects: + - 22-03 (settings write-back) + +# Tech tracking +tech-stack: + added: [] + patterns: + - Single source of truth: plugin path config sourced exclusively from paperforge.json + - Thin plugin shell: plugin reads/writes Python-owned config file, no independent path defaults + - Defensive key filtering: saveSettings() only persists keys that exist in DEFAULT_SETTINGS + +key-files: + created: [] + modified: + - paperforge/plugin/main.js - Refactored DEFAULT_SETTINGS, added readPaperforgeJson()/savePaperforgeJson(), updated loadSettings/saveSettings, refactored PaperForgeSettingTab + +key-decisions: + - "Added paddleocr_api_key and zotero_data_dir to DEFAULT_SETTINGS (plan had a bug: the proposed DEFAULT_SETTINGS omitted them, which would cause data loss when saveSettings() filters to only DEFAULT_SETTINGS keys)" + - "Plugin data.json cleaned on first load by calling saveSettings() which now filters to non-path DEFAULT_SETTINGS keys only" + +patterns-established: + - "path-config-from-paperforge: all path directory values (system_dir, resources_dir, literature_dir, control_dir, base_dir) read from paperforge.json at load time, not from plugin data.json" + - "non-path-persistence: saveSettings() filters to DEFAULT_SETTINGS keys only, automatically excluding path fields" + - "paperforge-json-write: savePaperforgeJson() writes to vault_config block, removes stale top-level keys, and preserves all non-path config" + +requirements-completed: + - CONF-01 + - CONF-04 + +# Metrics +duration: 6 min +completed: 2026-05-03 +--- + +# Phase 22 Plan 02: Plugin Reads paperforge.json as Path Config Source of Truth — Summary + +**Refactored Obsidian plugin to read path configuration from `paperforge.json` (vault_config block), eliminating the second runtime truth problem where plugin DEFAULT_SETTINGS had wrong defaults (System/Resources/Notes/Index_Cards/Base instead of Python's 99_System/03_Resources/Literature/LiteratureControl/05_Bases).** + +## Performance + +- **Duration:** 6 min +- **Started:** 2026-05-03T14:51:57Z +- **Completed:** 2026-05-03T14:57:52Z +- **Tasks:** 3 +- **Files modified:** 1 + +## Accomplishments + +- Removed all 5 path directory keys from DEFAULT_SETTINGS (system_dir, resources_dir, literature_dir, control_dir, base_dir), keeping only non-path settings +- Added `readPaperforgeJson()` method reading from paperforge.json vault_config block with Python DEFAULT_CONFIG fallback for fresh vaults +- Refactored `loadSettings()` to overwrite path fields from paperforge.json after merging data.json +- Refactored `saveSettings()` to filter persisted keys to DEFAULT_SETTINGS only (path fields automatically excluded) +- Added `savePaperforgeJson()` method writing path config back to paperforge.json vault_config block, removing stale top-level keys +- Refactored `PaperForgeSettingTab` to display path values from `_pfConfig` (paperforge.json source) instead of plugin.settings +- Added `saveSettings()` cleanup call in `onload()` to purge stale path fields from existing plugin data.json + +## Task Commits + +Each task was committed atomically: + +1. **Task 1: Add readPaperforgeJson() and clean DEFAULT_SETTINGS** - `00ae8e8` (feat) +2. **Task 2: Refactor SettingsTab to read from paperforge.json** - `cda3cff` (feat) +3. **Task 3: Add savePaperforgeJson() and data.json cleanup** - `36de493` (feat) + +## Files Created/Modified + +- `paperforge/plugin/main.js` - Complete refactor of config truth architecture: + - `DEFAULT_SETTINGS` (line 145): Removed 5 path keys, kept 7 non-path keys + - `readPaperforgeJson()` (line 1043): Reads paperforge.json vault_config block with Python default fallback + - `savePaperforgeJson()` (line 1083): Writes path config to paperforge.json vault_config block + - `loadSettings()` (line 1144): Overwrites path fields from readPaperforgeJson() + - `saveSettings()` (line 1155): Filters to DEFAULT_SETTINGS keys only + - `onload()` (line 988): Calls saveSettings() to clean stale data.json path keys + - `PaperForgeSettingTab` (line 443): Added _pfConfig cache, _refreshPfConfig(), Config Summary reads from _pfConfig + +## Deviations from Plan + +### Auto-fixed Issues + +**1. [Rule 1 - Bug] Added paddleocr_api_key and zotero_data_dir to DEFAULT_SETTINGS** +- **Found during:** Task 1 (DEFAULT_SETTINGS replacement) +- **Issue:** The plan's proposed DEFAULT_SETTINGS omitted `paddleocr_api_key` and `zotero_data_dir`. The refactored `saveSettings()` filters persisted keys to only those in `DEFAULT_SETTINGS`, so any key missing from DEFAULT_SETTINGS would be silently dropped on save — causing permanent data loss of user API keys and Zotero data paths. +- **Fix:** Added `paddleocr_api_key: ''` and `zotero_data_dir: ''` to DEFAULT_SETTINGS. These are non-path user settings that must survive the saveSettings() filter. +- **Files modified:** paperforge/plugin/main.js (DEFAULT_SETTINGS block) +- **Verification:** Verification script confirms both keys are present in DEFAULT_SETTINGS and excluded from path-key removal checks +- **Committed in:** `00ae8e8` (Task 1 commit) + +--- + +**Total deviations:** 1 auto-fixed (1 bug) +**Impact on plan:** Critical data-loss bug prevented — without this fix, existing user paddleocr_api_key and zotero_data_dir values would be permanently deleted from plugin data.json on first saveSettings() call after the refactor. + +## Issues Encountered + +None — plan executed cleanly with the one deviation documented above. + +## Next Phase Readiness + +Ready for 22-03 (settings write-back). The plugin now: +- Reads path config exclusively from paperforge.json +- Displays paperforge.json values in Settings tab +- Writes path changes to paperforge.json via savePaperforgeJson() +- Gracefully falls back to Python defaults when file doesn't exist +- Cleans stale path fields from plugin data.json on first load + +--- + +*Phase: 22-configuration-truth-compatibility* +*Completed: 2026-05-03*