diff --git a/MIGRATION_ACCEPTANCE_CRITERIA.md b/MIGRATION_ACCEPTANCE_CRITERIA.md new file mode 100644 index 0000000..1c8491e --- /dev/null +++ b/MIGRATION_ACCEPTANCE_CRITERIA.md @@ -0,0 +1,165 @@ +# C# Backend Parity Acceptance Criteria (Python Twin) + +## Goal +Create a C# backend that is behaviorally equivalent to the current Python backend for core journaling workflows, with zero data-loss regressions and compatible vault handling. + +## Parity Rule +Behavior parity is required. Internal implementation can differ. + +## Source of Truth (Current Python) +- `journal/core/storage.py` +- `journal/core/encryption.py` +- `journal/core/parser.py` +- `journal/core/models.py` +- `journal/core/database.py` +- `journal/cli/main.py` +- `journal/ai/analysis.py` +- `journal/ai/chat.py` +- `journal/core/speech.py` + +## Definition of Done (Release Gate) +1. All `P0` criteria below are marked `Pass`. +2. Existing Python-created vault files load successfully in C# backend. +3. Side-by-side output comparison on shared fixture corpus shows no functional mismatch for `P0` flows. +4. No plaintext journal data remains after graceful shutdown flow. + +## Shared Fixture Corpus (Required) +1. `fixtures/vaults/` +- Multiple months (`YYYY-MM.vault`) generated by Python app. +- Includes at least one wrong-password test case. +2. `fixtures/entries/` +- Daily, deep, recovery, fragment-heavy entries. +- Includes multiline fragments, tags, checkboxes, unusual spacing. +3. `fixtures/search/` +- Queries for text, section, tag, type, checked, unchecked, date ranges. +4. `fixtures/ai/` +- Stubbed LLM/embedding responses for deterministic comparison. + +## Acceptance Matrix +Use status values: `Not Started`, `In Progress`, `Blocked`, `Pass`, `Fail`. + +| ID | Priority | Feature | Acceptance Criteria | Status | Owner | Evidence | +| ------- | -------- | --------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | ----------- | ----- | -------- | +| DOM-001 | P0 | Fragment model parity | Fragment has `type`, `description`, `time`, `tags`; rejects empty `type`/`description`; trims values. | Pass | Stan44/Codex | `Journal.Core/Models/Fragment.cs`, `Journal.Core/Services/FragmentService.cs`, smoke test `CreateAsync trims fields` + `UpdateAsync rejects whitespace type` | +| DOM-002 | P0 | Journal entry domain parity | Entry model supports `date`, `raw_content`, `sections`, `fragments` equivalent to Python semantics. | Not Started | | | +| PAR-001 | P0 | Date extraction parity | Parser reads `**Date:**` or `Date:`; falls back to filename stem when missing. | Not Started | | | +| PAR-002 | P0 | Section parsing parity | Recognizes canonical section titles and captures section content lines. | Not Started | | | +| PAR-003 | P0 | Checkbox parsing parity | Parses markdown checkboxes (`- [ ]`, `- [x]`) and preserves checked state by checkbox text. | Not Started | | | +| PAR-004 | P0 | Fragment parsing parity | Parses `!TYPE @time #tags` plus multiline description blocks with same boundary behavior as Python regex parser. | Not Started | | | +| MRG-001 | P0 | Merge behavior parity | Saving existing entry merges non-empty section updates and appends only non-duplicate fragments by description. | Not Started | | | +| MRG-002 | P0 | Markdown reconstruction parity | Entry serialization writes canonical section order and fragment block formatting equivalent to Python `to_markdown()`. | Not Started | | | +| VLT-001 | P0 | Vault crypto format compatibility | Uses AES-256-GCM with payload layout compatible with Python (`salt + nonce + tag + ciphertext`). | Not Started | | | +| VLT-002 | P0 | KDF compatibility | Uses PBKDF2-HMAC-SHA256 with matching salt/key sizes and iteration count for Python vault compatibility. | Not Started | | | +| VLT-003 | P0 | Monthly vault naming parity | Vault filename format exactly `YYYY-MM.vault`. | Not Started | | | +| VLT-004 | P0 | Load workflow parity | `load all vaults` clears decrypted workspace first, then decrypts/extracts monthly vaults. | Not Started | | | +| VLT-005 | P0 | Wrong password behavior | Wrong password returns explicit failure and does not corrupt existing vault files. | Not Started | | | +| VLT-006 | P1 | Legacy vault handling | Legacy `_init_vault.vault` handling behavior is preserved or intentionally migrated with backward-compat note. | Not Started | | | +| VLT-007 | P0 | Current-month optimized save | Supports current-month save path equivalent to Python optimization. | Not Started | | | +| VLT-008 | P0 | Full rebuild save | Supports full monthly regroup/rebuild save flow from decrypted `.md` files. | Not Started | | | +| DAT-001 | P0 | Decrypted data cleanup | Graceful shutdown removes decrypted workspace artifacts. | Not Started | | | +| DB-001 | P1 | SQLCipher compatibility | Database key derivation and SQLCipher connection behavior are compatible with Python expectations. | Not Started | | | +| DB-002 | P1 | Schema parity | `entries`, `sections`, `fragments`, `tags`, `fragment_tags` schema exists with compatible constraints. | Not Started | | | +| SCH-001 | P0 | Search parity (content) | Search supports text query over full entry content. | Not Started | | | +| SCH-002 | P0 | Search parity (filters) | Search supports date range, section filter, tag filter, fragment type filter, checked/unchecked filters. | Not Started | | | +| CLI-001 | P0 | Vault CLI parity | CLI supports vault load/save with password prompt semantics matching Python UX. | Not Started | | | +| CLI-002 | P0 | Search CLI parity | CLI options match existing Python capabilities sufficiently for drop-in replacement. | Not Started | | | +| API-001 | P0 | Sidecar protocol stability | Stdin/stdout contract is line-delimited JSON with `{ok,data}` or `{ok:false,error}` and strict action routing. | In Progress | Stan44/Codex | `Journal.Core/Entry.cs`, smoke tests for unknown action / missing payload / missing id handling | +| API-002 | P1 | HTTP API parity | API exposes endpoints equivalent to supported sidecar actions; no template-only endpoints in parity mode. | Not Started | | | +| AI-001 | P1 | LLM summarize parity | Entry/all-entry summarize workflow callable with equivalent behavior and timeout controls. | Not Started | | | +| AI-002 | P2 | Embedding parity | Embedding endpoint integration available with equivalent request/response contract. | Not Started | | | +| AI-003 | P1 | Cloud chat parity | Cloud chat request/response flow available and configurable. | Not Started | | | +| SPC-001 | P2 | Speech parity | Engine-selectable speech flow (whisper/google/sphinx-like modes) retained or intentionally delegated. | Not Started | | | +| CFG-001 | P0 | Config parity | Equivalent configuration keys exist for paths, vault format, AI endpoints, and speech settings. | Not Started | | | +| OBS-001 | P1 | Logging/error parity | Failures return actionable messages without leaking secrets or plaintext journal data. | In Progress | Stan44/Codex | Error envelope behavior implemented in sidecar; structured logging policy pending | + +## Mandatory Gate Tests (P0) +1. `Vault Compatibility` +- Given existing Python vault fixtures, C# load succeeds with correct password. +- Wrong password consistently fails without partial corruption. +2. `Parser + Merge` +- Given fixture entries, C# parser output matches Python parser output for sections/fragments/checkboxes. +- Saving edited entry preserves merge semantics. +3. `Search` +- For shared corpus, C# and Python return the same entry set for all P0 search filters. +4. `Transport` +- Sidecar commands for core actions produce stable JSON success/error envelopes. +5. `Cleanup` +- After graceful shutdown sequence, decrypted workspace is empty. + +## Migration Phases (Recommended) +1. `Phase 1: Fragment Vertical Slice` +- Complete `DOM-001`, `API-001`, persistence beyond in-memory. +2. `Phase 2: Entry/Parser/Merge Twin` +- Complete `DOM-002`, `PAR-*`, `MRG-*`. +3. `Phase 3: Vault/Crypto Twin` +- Complete `VLT-*`, `DAT-001`. +4. `Phase 4: Search + CLI Twin` +- Complete `SCH-*`, `CLI-*`, `CFG-001`. +5. `Phase 5: AI/Speech` +- Complete `AI-*`, `SPC-001`. +6. `Phase 6: Frontend Cutover` +- Tauri frontend switches to C# backend only after all P0 criteria pass. + +## Rules for Change Requests +1. Any intentional divergence from Python behavior requires: +- Written rationale. +- New acceptance criterion replacing old one. +- Migration note describing user-visible impact. +2. No removal of a `P0` criterion without both maintainers approving in writing. + +## Status Snapshot (2026-02-22, Phase 1.2 Progress) +This section is a proposed status/evidence snapshot based on current code in: +- Python source: `Project_Journal/` +- C# migration: `Project_Journal/journal-master/journal/` + +It does not change release gates or acceptance definitions. + +### Phase Summary +| Phase | Current State | Evidence | +| ----- | ------------- | -------- | +| Phase 1: Fragment Vertical Slice | In Progress (near-complete) | Fragment model/service/sidecar + persisted repository + smoke tests: `journal-master/journal/Journal.Core/Models/Fragment.cs`, `journal-master/journal/Journal.Core/Entry.cs`, `journal-master/journal/Journal.Core/Repositories/FileFragmentRepository.cs`, `journal-master/journal/Journal.SmokeTests/Program.cs` | +| Phase 2: Entry/Parser/Merge Twin | Not Started | No C# entry/parser/merge domain yet. | +| Phase 3: Vault/Crypto Twin | Not Started | No C# vault/crypto compatibility module yet. | +| Phase 4: Search + CLI Twin | Not Started | C# search remains fragment-scoped only (not full entry parity). | +| Phase 5: AI/Speech | Not Started | No C# AI/speech parity services yet. | +| Phase 6: Frontend Cutover | Not Started | P0 parity not yet achieved. | + +### Proposed Acceptance Status Updates +| ID | Proposed Status | Evidence | Notes | +| ------- | --------------- | -------- | ----- | +| DOM-001 | Pass | `journal-master/journal/Journal.Core/Models/Fragment.cs`, `journal-master/journal/Journal.Core/Services/FragmentService.cs`, `journal-master/journal/Journal.SmokeTests/Program.cs` | Fields/validation/trim behavior implemented and smoke-tested. | +| DOM-002 | Not Started | `journal-master/journal/Journal.Core/Entry.cs` | No C# `JournalEntry` parity domain yet. | +| PAR-001 | Not Started | `journal-master/journal/Journal.Core/Entry.cs` | No C# parser/date extraction path yet. | +| PAR-002 | Not Started | `journal-master/journal/Journal.Core/Entry.cs` | No section parser in C#. | +| PAR-003 | Not Started | `journal-master/journal/Journal.Core/Entry.cs` | No checkbox parser in C#. | +| PAR-004 | Not Started | `journal-master/journal/Journal.Core/Entry.cs` | No fragment markdown parser in C#. | +| MRG-001 | Not Started | `journal-master/journal/Journal.Core/Entry.cs` | No entry merge behavior in C#. | +| MRG-002 | Not Started | `journal-master/journal/Journal.Core/Entry.cs` | No markdown reconstruction pipeline in C#. | +| VLT-001 | Not Started | `journal-master/journal/Journal.Core/Entry.cs` | No vault encryption/decryption compatibility module yet. | +| VLT-002 | Not Started | `journal-master/journal/Journal.Core/Entry.cs` | No PBKDF2 compatibility implementation yet. | +| VLT-003 | Not Started | `journal-master/journal/Journal.Core/Entry.cs` | No monthly vault naming/save implementation yet. | +| VLT-004 | Not Started | `journal-master/journal/Journal.Core/Entry.cs` | No load-all-vaults workflow in C#. | +| VLT-005 | Not Started | `journal-master/journal/Journal.Core/Entry.cs` | Wrong-password behavior not implemented in C# vault flow. | +| VLT-006 | Not Started | `journal-master/journal/Journal.Core/Entry.cs` | Legacy vault handling not implemented/documented in C#. | +| VLT-007 | Not Started | `journal-master/journal/Journal.Core/Entry.cs` | Current-month optimized save path not implemented in C#. | +| VLT-008 | Not Started | `journal-master/journal/Journal.Core/Entry.cs` | Full rebuild save flow not implemented in C#. | +| DAT-001 | Not Started | `journal-master/journal/Journal.Core/Entry.cs` | Decrypted workspace cleanup flow not implemented in C#. | +| DB-001 | Not Started | `journal-master/journal/Journal.Core/Entry.cs` | No SQLCipher keying/connection behavior in C#. | +| DB-002 | Not Started | `journal-master/journal/Journal.Core/Entry.cs` | No `entries/sections/fragments/tags/fragment_tags` schema in C#. | +| SCH-001 | Not Started | `journal-master/journal/Journal.Core/Repositories/FileFragmentRepository.cs` | C# search is fragment-centric, not full-entry content search. | +| SCH-002 | Not Started | `journal-master/journal/Journal.Core/Repositories/FileFragmentRepository.cs` | Date/section/checkbox filters not implemented for full entry search. | +| CLI-001 | Not Started | `journal-master/journal/Journal.Sidecar/App.cs` | Sidecar exists; vault CLI parity not implemented. | +| CLI-002 | Not Started | `journal-master/journal/Journal.Sidecar/App.cs` | Search CLI parity not implemented. | +| API-001 | In Progress | `journal-master/journal/Journal.Core/Entry.cs`, `journal-master/journal/Journal.SmokeTests/Program.cs` | JSON envelope routing implemented and tested; fixture-driven P0 gate tests still pending. | +| API-002 | Not Started | `journal-master/journal/Journal.Api/Program.cs` | HTTP API still template endpoint, no journal parity endpoints. | +| AI-001 | Not Started | `journal-master/journal/Journal.Core/Entry.cs` | No summarize workflow/service in C#. | +| AI-002 | Not Started | `journal-master/journal/Journal.Core/Entry.cs` | No embeddings integration in C#. | +| AI-003 | Not Started | `journal-master/journal/Journal.Core/Entry.cs` | No cloud chat flow in C#. | +| SPC-001 | Not Started | `journal-master/journal/Journal.Core/Entry.cs` | No speech module/service in C#. | +| CFG-001 | Not Started | `journal-master/journal/Journal.Core/ServiceCollectionExtensions.cs` | C# config surface is partial and not parity-complete. | +| OBS-001 | In Progress | `journal-master/journal/Journal.Core/Entry.cs` | Actionable error envelope exists; structured logging/secret-scrub policy pending. | + +### Snapshot Risks/Blockers +1. Required fixture corpus (`fixtures/vaults`, `fixtures/entries`, `fixtures/search`, `fixtures/ai`) is still missing. +2. P0 gate test harness for side-by-side Python vs C# parity is not yet implemented. +3. Phase 1 remaining item is final API-001 hardening + fixture-backed transport stability evidence.