Files
ForgeLM/.planning/phases/01-hf-model-discovery/01-03-PLAN.md
T

9.1 KiB

phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
phase plan type wave depends_on files_modified autonomous requirements must_haves
01-draft-state-ownership 03 execute 3
01-02
tauri-app/src/features/runtime/components/RuntimeSettingsDrawer.tsx
tauri-app/src/features/runtime/runtime-settings-form.ts
tauri-app/src/features/runtime/runtime-settings-form.test.ts
tauri-app/src/features/runtime/components/RuntimeSurface.test.tsx
true
CONF-01
CONF-03
CONF-04
truths artifacts key_links
Folder, model, and provider/source choices stay stable until the user saves or discards them.
Older async responses do not overwrite newer field intent.
Invalid draft values remain visible with inline errors and block save instead of being silently removed.
path provides
tauri-app/src/features/runtime/components/RuntimeSettingsDrawer.tsx field-scoped async handlers and inline invalid-state rendering
path provides
tauri-app/src/features/runtime/runtime-settings-form.ts helper logic for preserving selections and determining invalid draft state
path provides
tauri-app/src/features/runtime/components/RuntimeSurface.test.tsx regression coverage for stale async responses and invalid draft preservation
path provides
tauri-app/src/features/runtime/runtime-settings-form.test.ts unit coverage for selection-preservation helpers and invalid-save blocking rules
from to via pattern
tauri-app/src/features/runtime/components/RuntimeSettingsDrawer.tsx tauri-app/src/features/runtime/runtime-settings-form.ts helper calls that preserve current selections and compute invalid draft state chooseModel|createRuntimeConfigPatch
from to via pattern
tauri-app/src/features/runtime/components/RuntimeSettingsDrawer.tsx tauri-app/src/features/runtime/components/RuntimeSurface.test.tsx async picker and rescan regression tests scanRuntimeModels|pickRuntimeModelsDir|searchHuggingFaceModels
Harden the controlled draft flow so field-scoped async work, rescans, and validation failures preserve user intent instead of silently mutating the draft.

Purpose: finish the phase by protecting the highest-risk interactions: folder pickers, model rescans, stale async responses, and save failure recovery. Output: field-scoped async safety, invalid-draft preservation, save blocking, and regression tests for the full draft-safety contract.

<execution_context> @$HOME/.config/opencode/get-shit-done/workflows/execute-plan.md @$HOME/.config/opencode/get-shit-done/templates/summary.md </execution_context>

@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/01-hf-model-discovery/01-CONTEXT.md @.planning/phases/01-hf-model-discovery/01-RESEARCH.md @.planning/phases/01-hf-model-discovery/01-UI-SPEC.md @.planning/phases/01-hf-model-discovery/01-02-SUMMARY.md @tauri-app/src/features/runtime/components/RuntimeSettingsDrawer.tsx @tauri-app/src/features/runtime/runtime-settings-form.ts @tauri-app/src/features/runtime/runtime-settings-form.test.ts @tauri-app/src/features/runtime/components/RuntimeSurface.test.tsx From `tauri-app/src/features/runtime/runtime-settings-form.ts`:
export function chooseModel(current: string, scanned: RuntimeModelFile[], extra: RuntimeModelFile[]): string;

export function createRuntimeConfigPatch(
  snapshotConfig: RuntimeConfig,
  form: RuntimeSettingsFormState,
  maxLayers: number,
): RuntimeConfig;

Locked behavior from 01-CONTEXT.md:

- D-07: picker updates only the launched field
- D-08: rescans preserve current draft selection unless invalid
- D-10: stale responses for the same field are ignored
- D-11: invalid drafted values remain visible, inline, and block save
Task 1: Make async picker and rescan handlers field-scoped and stale-safe tauri-app/src/features/runtime/components/RuntimeSettingsDrawer.tsx, tauri-app/src/features/runtime/runtime-settings-form.ts, tauri-app/src/features/runtime/runtime-settings-form.test.ts - tauri-app/src/features/runtime/components/RuntimeSettingsDrawer.tsx - tauri-app/src/features/runtime/runtime-settings-form.ts - tauri-app/src/features/runtime/runtime-settings-form.test.ts - .planning/phases/01-hf-model-discovery/01-CONTEXT.md - Test 1: folder/file pickers update only their target draft fields and do not rehydrate unrelated inputs (D-07). - Test 2: model rescans preserve the current draft selection when it is still valid and only mark it invalid when it disappears (D-08, D-11). - Test 3: only the latest request for a field can update draft-facing UI; older responses are ignored (D-10). Refactor async handlers in `RuntimeSettingsDrawer.tsx` so each operation has field-scoped state and a latest-request guard. Concretely: `handlePickDir`, `handlePickFiles`, `handleRescan`, and any async validation/search path must update only the field(s) they own rather than resetting the full draft. Add explicit request sequencing per field or operation key so older responses are ignored when a newer request for that same field has started. Update `runtime-settings-form.ts` helpers so rescans preserve the current drafted model path when it still exists, and return an invalid-draft signal when the drafted path no longer exists instead of auto-falling back to another model silently. Add helper-level tests in `runtime-settings-form.test.ts` for preserved selection, invalid-selection detection, and non-silent fallback rules. - `tauri-app/src/features/runtime/components/RuntimeSettingsDrawer.tsx` contains explicit stale-request protection for field-level async handlers. - `tauri-app/src/features/runtime/runtime-settings-form.ts` exposes helper logic that distinguishes valid preservation from invalid drafted selections. - `tauri-app/src/features/runtime/runtime-settings-form.test.ts` covers preserved selection and invalid-selection outcomes. npm test -- runtime-settings-form Async field helpers can no longer silently rewrite unrelated fields or let older responses override the latest user intent. Task 2: Preserve invalid drafts visibly and block save until resolved tauri-app/src/features/runtime/components/RuntimeSettingsDrawer.tsx, tauri-app/src/features/runtime/components/RuntimeSurface.test.tsx - tauri-app/src/features/runtime/components/RuntimeSettingsDrawer.tsx - tauri-app/src/features/runtime/components/RuntimeSurface.test.tsx - .planning/phases/01-hf-model-discovery/01-UI-SPEC.md - .planning/phases/01-hf-model-discovery/01-CONTEXT.md - Test 1: an invalid model or folder draft remains visible with inline error text and destructive styling instead of being cleared (CONF-04, D-11). - Test 2: `Save changes` is disabled while invalid draft metadata exists. - Test 3: a failed save keeps the current draft values in place and surfaces the failure message instead of resetting the form (CONF-04). In `RuntimeSettingsDrawer.tsx`, render inline invalid-state messaging for drafted values that fail validation or disappear during rescan. Preserve the user's typed or selected value in the control, add the destructive invalid styling from the Phase 1 color contract, and disable `Save changes` whenever invalid draft metadata exists. Keep save failures drawer-visible without resetting the draft or clearing helper state. Extend `RuntimeSurface.test.tsx` to assert concrete UI outcomes: invalid drafted values stay in the control, inline error copy is rendered near the affected field, `Save changes` is disabled until corrected, and a rejected save preserves the user's current draft state. - `tauri-app/src/features/runtime/components/RuntimeSettingsDrawer.tsx` renders inline invalid/error UI near affected fields and disables `Save changes` when invalid draft state exists. - `tauri-app/src/features/runtime/components/RuntimeSurface.test.tsx` asserts that invalid draft values remain visible and save failures preserve the draft. npm test -- RuntimeSurface Phase 1 ends with durable draft safety: invalid values are visible, saves are blocked until fixed, stale async work is ignored, and user intent survives failures. - `npm test -- runtime-settings-form` - `npm test -- RuntimeSurface` - `npm run build`

<success_criteria>

  • Async field updates never overwrite unrelated draft fields.
  • Invalid model/folder drafts remain visible, explain the problem inline, and block save until fixed.
  • Save failures and rescans preserve user intent rather than silently replacing or clearing values. </success_criteria>
After completion, create `.planning/phases/01-hf-model-discovery/01-03-SUMMARY.md`