Skip to content

[UX] Settings selects leak raw JSON ids; goal footer leaks internal enums and conflicting tones #67

Closed

Description

@GeekCmore

Summary

A cluster of wrong-state displays in the settings form and the goal status footer.

Settings selects (UX-12)

  • Option ids are JSON.stringify(value) (packages/mayfly/src/interaction/settings-model.ts:76, :79). When the configured value is not among the options (e.g. a deleted agent preset still set as default, or permission.defaultPreset: custom which the preset list never contains), the collapsed select renders the raw id with literal quotes — "custom" shown as '"custom"' (packages/mayfly/src/core/ui-patterns.ts:352).
  • For multiselects, unknown values vanish from the display entirely (ui-patterns.ts:353) yet still trip "A selected option is unavailable" on save (packages/mayfly/src/core/ui-interaction-form.ts:258) — an error about a selection the user cannot see anywhere.

Goal status (UX-13)

  • The footer interpolates the raw internal enum goal.activation (packages/mayfly/src/transcript/status-goal.ts:21): users see Goal active · 2/10 · armed — armed/disarmed is a process-local continuation flag (@deepseek-ai/dsh-goal lib/types/types.d.ts:58), and the 2/10 fraction has no unit.
  • Tone and visibility rules conflict between footer and todo pane: blocked is warning in the footer (status-goal.ts:39-45) but red ✕ danger in the pane (pane-todo.ts:202-206); paused is warning vs muted ❚❚; a complete goal is hidden by the pane (pane-todo.ts:209) yet renders "Goal complete · N/M · …" in the footer indefinitely (status-goal.ts:19-22 has no complete case).

Acceptance criteria

  • Off-list select values render as readable labels (not JSON-quoted ids); multiselect stale values are visible (e.g. marked unavailable) so the save error is actionable.
  • Goal footer uses human wording for activation/state, a labeled unit for the fraction, and consistent tone/visibility with the todo pane; a completed goal does not linger in the footer.

Audit reference

docs/audits/2026-09-28-ui-ux-audit-data-and-layout.md § UX-12, UX-13 (baseline 27bc188, 2026-09-28)

Activity

  1. self-assigned this
    on Sep 28, 2026
  2. GeekCmore commented on Sep 28, 2026

    @GeekCmore
    CollaboratorAuthor

    In progress (status:in-progress). Covered by the unified display-fidelity plan:

    • UX-12 — interaction/settings-model.ts: make the stored-value → label mapping total by appending off-list stored values as labeled options (select: one; multiselect: each missing value), not disabled, so the raw JSON.stringify id never reaches the renderer and the phantom "A selected option is unavailable" save error disappears. No packages/ui contract change.
    • UX-13 — transcript/status-goal.ts: human wording, round n/m unit, tone/visibility aligned with pane-todo.ts, complete goals hidden; empty blockedReason no longer renders a bare blocked: row.

    Branch fix/display-layout-fidelity, worktree mayfly-display-layout. Evidence docs land with #77.

  3. GeekCmore commented on Sep 28, 2026

    @GeekCmore
    CollaboratorAuthor

    Implementation opened as #81 (branch fix/display-layout-fidelity). pnpm run verify:full is green (typecheck, lint, build, shots, coverage, happy smoke). Manual runtime acceptance is pending before merge.

  4. added 2 commits that reference this issue on Sep 28, 2026
  5. GeekCmore commented on Sep 29, 2026

    @GeekCmore
    CollaboratorAuthor

    Status after verification on current main (14e6ce7):

    • UX-12 (settings selects): fixed by fix(ui): display-fidelity and layout-budget hardening (#67 #68 #73 #74) #81 — off-list scalars project as readable options (optionEntries in interaction/settings-model.ts), non-scalar containers read as unset / "Managed in settings file" instead of a raw JSON id, and the phantom "A selected option is unavailable" save error is gone. settings-model.spec.ts (9 tests) passes. The first acceptance box can be checked.
    • UX-13 (goal footer): still open. Implementation starting on branch fix/goal-footer-ux13:
      • human activation wording — drop the raw armed/disarmed enum; silent when armed, a translated auto-continue off marker when disarmed;
      • labeled unit for the fraction — round {rounds}/{total};
      • tone/visibility aligned with the todo pane badge — active → accent, paused → muted, blocked → danger, and completed goals hidden instead of lingering as success;
      • the pane no longer renders a bare blocked: row when the reason message is empty.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingstatus:in-progressWork has started on this issue

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions