Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
fa8a3fb
feat(03-01): prove typed IPC error contract on evidence_binder_mutate
entelecheia Aug 23, 2026
915187e
docs(03-01): complete typed IPC error contract tracer plan
entelecheia Aug 23, 2026
e603f69
feat(03-02): migrate today domain commands to typed IpcError
entelecheia Aug 23, 2026
eff3526
feat(03-02): migrate save_document to typed IpcError
entelecheia Aug 23, 2026
4eb2716
docs(03-02): complete today-domain and save_document IpcError plan
entelecheia Aug 23, 2026
e3dfb4d
docs(03-02): complete today-domain and save_document IpcError plan
entelecheia Aug 23, 2026
98f655b
fix(03-02): use TODAY_CONFLICT constant in web_actions.rs retry branch
entelecheia Aug 23, 2026
1088532
docs(03-02): record the ERR-02 literal-vs-constant fix in the summary
entelecheia Aug 23, 2026
c10c7e4
docs(03-02): record the ERR-02 fix in the plan summary
entelecheia Aug 23, 2026
81a4bb0
feat(03-03): normalize today funnel and retire todayErrorCode (D-08)
entelecheia Aug 23, 2026
6805b26
feat(03-03): normalize save_document funnel and type the reportInsert…
entelecheia Aug 23, 2026
51afe3f
docs(03-03): complete frontend IPC error branch-site migration plan
entelecheia Aug 23, 2026
add9249
docs(03-04): prove ERR-02/03/04 with rename drills, count guard, and …
entelecheia Aug 23, 2026
eb154f1
fix(03-04): close ERR-02 cross-language gap with a Rust/TS agreement …
entelecheia Aug 23, 2026
c8791ff
docs(03-04): record the ERR-02 cross-language gap and its fix in the …
entelecheia Aug 23, 2026
eb0e3f1
docs(03-verify): verify Phase 3 typed IPC error contract, flag open W…
entelecheia Aug 23, 2026
a2db46f
docs(03): record the Codex review findings as ERR-05 and ERR-06
entelecheia Aug 23, 2026
a80acb2
fix(evidence-binder): accept camelCase mutation fields and unblock th…
entelecheia Aug 23, 2026
7a3e804
docs(03-verify): close the real-app gap, Phase 3 verification passes
entelecheia Aug 23, 2026
3f32db3
docs(03): close Phase 3 - roadmap checkbox, state, and carried lessons
entelecheia Aug 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 17 additions & 8 deletions .planning/REQUIREMENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ milestone with no end-user-visible surface.

### Typed IPC Errors

- [ ] **ERR-01**: A frontend caller can read a stable machine-readable `code` from any error it needs to branch on, alongside the human-readable message
- [ ] **ERR-02**: Renaming an error code fails the build on both the Rust and TypeScript side instead of silently breaking a recovery path
- [ ] **ERR-03**: Every existing `message.includes("<code>")` matcher branches on the typed code instead - starting with `evidence_binder_revision_conflict` at `src/components/evidence/EvidenceBinderPane.tsx:174`
- [ ] **ERR-04**: Display-only errors are untouched - the `Result<T, String>` signature count stays within a few of the measured baseline of 1,138 (CONCERNS.md's 1,118 is stale; re-measure before Phase 3 executes)
- [x] **ERR-01**: A frontend caller can read a stable machine-readable `code` from any error it needs to branch on, alongside the human-readable message
- [x] **ERR-02**: Renaming an error code fails the build on both the Rust and TypeScript side instead of silently breaking a recovery path
- [x] **ERR-03**: Every existing `message.includes("<code>")` matcher branches on the typed code instead - starting with `evidence_binder_revision_conflict` at `src/components/evidence/EvidenceBinderPane.tsx:174`
- [x] **ERR-04**: Display-only errors are untouched - the `Result<T, String>` signature count stays within a few of the measured baseline of 1,138 (CONCERNS.md's 1,118 is stale; re-measure before Phase 3 executes)

> **Note for Phase 3 planning, from Phase 1's verification (2026-08-22).** None of the
> seven `make verify` gates can catch a serde mismatch at the Rust-TypeScript IPC
Expand Down Expand Up @@ -94,6 +94,15 @@ not compete with the structural work. Not in the current roadmap.

- **DEP-01**: Each exact version pin in the graph stack and `trash = "=4.1.1"` carries a one-line comment recording why

### Typed IPC Contract Hardening

Raised by the Codex adversarial review of PR #279 (2026-08-23), verified against
the tree. Neither is a live defect in Phase 3's output; both are durability gaps
in the contract Phase 3 established, deliberately not widened into that PR.

- **ERR-05**: The contract constrains which codes Rust can emit, not just which it declares. `IpcError` is a `pub struct` with a `pub code: String`, so any module can mint an arbitrary code, and the cross-language guard in `src/lib/types.test.ts` inventories `pub const` declarations only - it never inspects construction sites. An unregistered code passes the Rust pin, `tsc -b`, and the regex guard, then `normalizeIpcError` downgrades it to a plain `Error` and no recovery branch runs. The shape that closes this is a closed Rust enum serialized as a tagged union with an explicit legacy/display-only variant, private construction, and a TS union generated from that enum rather than regex-parsed from Rust source
- **ERR-06**: Every command capable of emitting a reserved conflict code returns `IpcError`, independent of whether a caller branches on it today. `today_apply_plan_result` (`today_ai.rs`) and `task_calendar_set_sync` (`today_calendar.rs`) both reach `today_mutate` and flatten its typed error back to `String` via `.map_err(|e| e.to_string())`, so a conflict on those paths arrives at the frontend as a plain string and `isTodayConflict` returns false. No caller branches on them today, so nothing regressed - but the boundary was drawn by current frontend usage and validated by a global signature count, which gives a future author no compile-time signal that the advertised recovery is unavailable. Needs an `IpcResult<T>` alias or command-level declaration plus a test that inventories code-producing commands

### Deferred Product Work

- **HUB-01**: Hub graph-metadata sync - the only explicit deferral in the ingested doc set (`docs/graph.md`), held until a Hub consumer exists
Expand Down Expand Up @@ -127,10 +136,10 @@ not compete with the structural work. Not in the current roadmap.
| SCAN-03 | Phase 2 | Complete |
| SCAN-04 | Phase 2 | Complete |
| SCAN-05 | Phase 2 | Complete |
| ERR-01 | Phase 3 | Pending |
| ERR-02 | Phase 3 | Pending |
| ERR-03 | Phase 3 | Pending |
| ERR-04 | Phase 3 | Pending |
| ERR-01 | Phase 3 | Complete |
| ERR-02 | Phase 3 | Complete |
| ERR-03 | Phase 3 | Complete |
| ERR-04 | Phase 3 | Complete |
| SHELL-01 | Phase 4 | Pending |
| SHELL-02 | Phase 4 | Pending |
| SHELL-03 | Phase 4 | Pending |
Expand Down
14 changes: 7 additions & 7 deletions .planning/ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Decimal phases appear between their surrounding integers in numeric order.

- [x] **Phase 1: Trustworthy Verify Signal** - Make `make verify` and CI tell the truth about a behavior-preserving change (completed 2026-08-23)
- [x] **Phase 2: Shared Scanner and Path Invariants** - Collapse five prune lists and ~20 containment checks into one of each (completed 2026-08-23)
- [ ] **Phase 3: Typed IPC Error Contract** - Give the errors the frontend branches on a machine-readable code
- [x] **Phase 3: Typed IPC Error Contract** - Give the errors the frontend branches on a machine-readable code (completed 2026-08-24)
- [ ] **Phase 4: Editor Surface State Extraction** - Move `OutlinePane` and `EditorPane` off their prop bundles onto module stores
- [ ] **Phase 5: Shell Decomposition Completion** - Move the remaining panes and mode routing out of `MainApp`

Expand Down Expand Up @@ -119,21 +119,21 @@ Notes for planning:
3. No `message.includes("<error_code>")` matcher remains in `src/` for a code that moved to the contract
4. The `Result<T, String>` count in `src-tauri/src/` is essentially unchanged from the measured baseline of 1,138 (CONCERNS.md's 1,118 is stale) - display-only errors were not touched

**Plans**: 0/4 plans executed
**Plans**: 4/4 plans complete

Plans:
**Wave 1**

- [ ] 03-01-PLAN.md - Tracer: IpcError struct + TS mirror + normalizer, proven end-to-end on evidence_binder_revision_conflict; real-app smoke checkpoint ratifying the 7-command scope (ERR-01, ERR-02)
- [x] 03-01-PLAN.md - Tracer: IpcError struct + TS mirror + normalizer, proven end-to-end on evidence_binder_revision_conflict; real-app smoke checkpoint ratifying the 7-command scope (ERR-01, ERR-02)

**Wave 2** *(blocked on Wave 1 completion)*

- [ ] 03-02-PLAN.md - Migrate the today and document Rust domains to IpcError; map_err adapter for today_ai; record the ERR-04 count (ERR-01, ERR-04)
- [ ] 03-03-PLAN.md - Normalize the today/save funnels, migrate all five branch sites to err.code, retire todayErrorCode, align e2e fixtures (ERR-01, ERR-03)
- [x] 03-02-PLAN.md - Migrate the today and document Rust domains to IpcError; map_err adapter for today_ai; record the ERR-04 count (ERR-01, ERR-04)
- [x] 03-03-PLAN.md - Normalize the today/save funnels, migrate all five branch sites to err.code, retire todayErrorCode, align e2e fixtures (ERR-01, ERR-03)

**Wave 3** *(blocked on Wave 2 completion)*

- [ ] 03-04-PLAN.md - ERR-02 rename drill (red-then-revert both sides), ERR-04 count guard, ERR-03 residual grep, full make verify (ERR-02, ERR-03, ERR-04)
- [x] 03-04-PLAN.md - ERR-02 rename drill (red-then-revert both sides), ERR-04 count guard, ERR-03 residual grep, full make verify (ERR-02, ERR-03, ERR-04)

Notes for planning:

Expand Down Expand Up @@ -195,7 +195,7 @@ Phases execute in numeric order: 1 -> 2 -> 3 -> 4 -> 5
|-------|----------------|--------|-----------|
| 1. Trustworthy Verify Signal | 7/7 | Complete | 2026-08-23 |
| 2. Shared Scanner and Path Invariants | 3/3 | Complete | 2026-08-23 |
| 3. Typed IPC Error Contract | 0/4 | Not started | - |
| 3. Typed IPC Error Contract | 4/4 | Complete | 2026-08-24 |
| 4. Editor Surface State Extraction | 0/TBD | Not started | - |
| 5. Shell Decomposition Completion | 0/TBD | Not started | - |

Expand Down
55 changes: 37 additions & 18 deletions .planning/STATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@
gsd_state_version: 1.0
milestone: v1.0
milestone_name: milestone
current_phase: 3
current_phase_name: Typed IPC Error Contract
status: executing
stopped_at: Phase 3 context gathered
last_updated: "2026-08-22T23:53:08.966Z"
last_activity: 2026-08-23
last_activity_desc: Phase 1 complete, transitioned to Phase 2
current_phase: 03
current_phase_name: typed-ipc-error-contract
status: phase_complete
stopped_at: Phase 03 complete and verified (passed); PR #279 open; Phase 4 not started
last_updated: "2026-08-24T04:45:00.000Z"
last_activity: 2026-08-24
last_activity_desc: Phase 03 complete - verification passed after the real-app WKWebView smoke closed the last evidence gap
progress:
total_phases: 3
completed_phases: 2
completed_phases: 3
total_plans: 14
completed_plans: 10
completed_plans: 14
---

# Project State
Expand All @@ -23,16 +23,16 @@ progress:
See: .planning/PROJECT.md (updated 2026-08-23)

**Core value:** The filesystem stays the source of truth - everything Maru shows is derived from real files the user owns, and nothing is lost if Maru is uninstalled.
**Current focus:** Phase 02 — Shared Scanner and Path Invariants
**Current focus:** Phase 03 complete; Phase 4 (Editor Surface State Extraction) is next

## Current Position

Phase: 3 — Typed IPC Error Contract
Plan: Not started
Status: Ready to execute
Last activity: 2026-08-23 — Phase 2 complete, transitioned to Phase 3
Phase: 03 (Typed IPC Error Contract) - COMPLETE, verified passed
Plan: 4 of 4 complete
Status: Verified passed on branch gsd/phase-3-typed-ipc-error-contract (PR #279)
Last activity: 2026-08-24 - real-app WKWebView smoke closed the last evidence gap and found two live defects

Progress: [██████████] 100%
Progress: [████████████░░░░░░░░] 60% (3/5 phases)

## Performance Metrics

Expand Down Expand Up @@ -69,6 +69,9 @@ Progress: [██████████] 100%
| Phase 02 P01 | 9min | 3 tasks | 6 files |
| Phase 02 P02 | 5min | 3 tasks | 4 files |
| Phase 02 P03 | 7min | 2 tasks | 3 files |
| Phase 03 P02 | ~50min | 2 tasks | 6 files |
| Phase 03 P03 | 15min | 2 tasks | 9 files |
| Phase 03 P04 | ~35min | 2 tasks | 0 files |

## Accumulated Context

Expand Down Expand Up @@ -107,6 +110,17 @@ Recent decisions affecting current work:
- [Phase ?]: [Phase 2]: 02-03 guard shape - maru_home()/install_root_base() restructured to a single exit wrapped in require_absolute, so a future early-return cannot bypass the check without restructuring the exit
- [Phase ?]: [Phase 2]: 02-03 env_root()/skills_root() get no separate guard - they derive from maru_home() and are covered transitively; duplicating the check would re-fragment the invariant
- [Phase ?]: [Phase 2]: 02-03 require_absolute's temporary allow(dead_code) removed in the same commit the first consumer landed - closes WINDOWS.md ledger entry 1
- [Phase 3]: 03-01 ratified the 7-command branch-on scope over CONTEXT's "four commands" wording - same four codes, seven commands; graph_link_apply stays display-only and OUT
- [Phase 3]: 03-01 ERR-04 pre-migration baseline measured at B = 1138 before any edit, matching the planning-time figure; 03-02 records against B-10 and 03-04 asserts within [B-20, B]
- [Phase 3]: 03-01 leaves `cargo clippy -- -D warnings` transiently red on three not-yet-consumed code constants rather than adding a suppression attribute - the phase prohibition holds and 03-02 clears it
- [Phase 3]: 03-01's human-verify checkpoint was approved without per-step smoke observations being reported back, so no real-app evidence exists for the migrated path yet
- [Phase ?]: [Phase 3]: 03-02 found web_actions.rs (not in the plan's file list) calls today_mutate and task_transition directly; its call sites and one internal conflict-code branch needed the same map_err adapter / code-based check as the plan's own adapter sites, added as Rule 3 fallout
- [Phase ?]: [Phase 3]: 03-02 also fixed document.rs's update_frontmatter_field (uncalled out in PATTERNS.md), which calls assert_expected_revision directly and needed the same map_err adapter as today_apply_plan_result
- [Phase ?]: [Phase 3]: 03-02 measured the post-migration ERR-04 count at 1128, exactly B-10 against 03-01's baseline B=1138, confirming no signature outside the 10-item migration set changed
- [Phase ?]: [Phase 3]: 03-02 migrated eleven prefix-string test assertions, not the six PATTERNS.md/PLAN.md enumerated by line number, since every unwrap_err() on a migrated command now yields IpcError regardless of which error path fired
- [Phase ?]: All three today_conflict fixture throw sites migrated to raw wire shape (not just the two the plan named by line), keeping the one-normalization-point invariant intact
- [Phase ?]: ERR-01 and ERR-03 marked complete after verifying all four contract codes have a frontend reader and the residual substring-matcher grep is zero; ERR-02 left open for 03-04's formal two-sided rename drill
- [Phase ?]: ERR-02 drill extended to three sub-drills (Rust value pin, Rust name/build, TS union/tsc) so the web_actions.rs:860 branch site is proven build-protected, not just the pin test

### Scope Exceptions

Expand All @@ -120,15 +134,19 @@ Recent decisions affecting current work:
untracked (`01-06-SUMMARY.md`, `01-07-SUMMARY.md`, `02-02-SUMMARY.md`); those two
clippy findings and the formatting diffs are fixed in the same commit that adopts
it, so the composite gate runs against the same tree CI sees.

- The bridge's error strings (`cli_missing:`, `hwp_timeout:`, `hwp_failed:`,
`hwp_parse_failed:`, `hwped_bad_request:`) stay `Result<T, String>` and are
**exempt from the Phase 3 typed contract**. `src/lib/hwped.ts` contains no error
branching at all, so they are display-only - exactly the class ERR-04 protects
from migration.

- Still owed, deliberately deferred until the hwp-editor implementation track
reports complete: the Phase 2.1 planning artifacts, the HWPE-01..03 requirement
registration, and the Semantica Phases 6-9 roadmap entries drawn from
`docs/semantica-adoption-plan.md`.
- [Phase 3]: The real-app WKWebView smoke found two live defects nothing else could see - EvidenceBinderMutation lacked serde rename_all_fields so every camelCase mutation was rejected at the bridge, and evidence discovery blocked the UI thread for over 40s on a 64k-file workspace. Treat "no native gate" as a real coverage hole in later phases, not a formality
- [Phase 3]: Codex adversarial review produced ERR-05 and ERR-06 (v2 requirements) - the contract pins declarations but not emission sites, and commands able to emit reserved codes still flatten to String

### Pending Todos

Expand All @@ -149,9 +167,10 @@ None yet.
| Reliability | REL-01 SIGHUP-immortal terminal session | v2 | 2026-08-22 |
| Testing | TEST-01..04 (native Tauri E2E runner, coverage, remaining component tests, app_menu smoke) | v2 | 2026-08-22 |
| Product | HUB-01 Hub graph-metadata sync - the doc set's only explicit deferral | v2 | 2026-08-22 |
| Typed IPC | ERR-05 closed-enum contract (emission sites unconstrained; guard checks declarations only), ERR-06 typed return for every conflict-emitting command (today_apply_plan_result, task_calendar_set_sync flatten to String) | v2 | 2026-08-23 |

## Session Continuity

Last session: 2026-08-22T22:29:59.605Z
Stopped at: Phase 3 context gathered
Resume file: .planning/phases/03-typed-ipc-error-contract/03-CONTEXT.md
Last session: 2026-08-24T04:45:00.000Z
Stopped at: Phase 03 complete and verified; PR #279 open, Phase 4 not started
Resume file: .planning/phases/03-typed-ipc-error-contract/03-VERIFICATION.md
Loading