Skip to content

refactor: make Kata the sole task UI authority - #869

Open
wesm wants to merge 1 commit into
mainfrom
remove-kata-ui
Open

refactor: make Kata the sole task UI authority#869
wesm wants to merge 1 commit into
mainfrom
remove-kata-ui

Conversation

@wesm

@wesm wesm commented Aug 9, 2026

Copy link
Copy Markdown
Member

Why

Forge still carries a copied Kata browser even though Kata now owns its browser product and shared presentation. Maintaining both implementations creates divergent behavior and an ambiguous data boundary.

What changes

  • Remove Forge's /kata route, copied task UI, mutation/recurrence/graph surfaces, generic proxy, snapshots, event relay, and Kata mode flag.
  • Keep Forge-owned links from provider items and workspaces to stable Kata identities, including direct, inherited, and intrinsic provenance.
  • Render one daemon-pinned read-only task inline through Kata's shared @kenn-io/kata-ui component.
  • Preserve safe standalone launch and create-or-open workspace flows, including Docs folder daemon pinning.
  • Keep all cross-product linkage metadata in Forge; Kata receives no Forge-specific reverse-link storage or API.
  • Pin both Go and frontend integration dependencies to reviewed Kata PR Fix sidebar filter collapse at narrow widths #247 commit 7ce11af95d278883012f673b25cf3d62ba78f7ea; no Kata release is assumed or published.

Review note

This branch was flattened to remove transient Superpowers documents and private absolute paths from unpublished history. It currently conflicts with the newer Effect/frontend consolidation now on main; that port should be reviewed as an explicit follow-up rather than hidden inside a mechanical rebase of this product-boundary change.

Verification

  • Full Forge frontend unit suite: 2,923 passed, 1 skipped.
  • Docs/Kata Playwright workflows: 54 passed across Chromium and Firefox.
  • Full Go lane: 6,103 tests executed; the two strict-umask assertions and one PTY timing case passed targeted reruns (the PTY case three times).
  • Commit and push hooks passed, including generated clients, frontend checks, short Go tests, lint, NilAway, and repository guardrails.
  • Kata PR Fix sidebar filter collapse at narrow widths #247: full Go suite, package tests/checks, web checks, pack test, and accessibility suite passed.

@roborev-ci

roborev-ci Bot commented Aug 9, 2026

Copy link
Copy Markdown

roborev: Combined Review (86ca609)

The PR has one high-severity security issue and three medium-severity functional regressions.

High

  • Validate Kata launch-target URLs before browser navigationinternal/server/kata/client.go:153, frontend/src/App.svelte:297

    A remote Kata daemon can return an unvalidated target.URL. Navigating an inherited-origin about:blank popup to a javascript: URL could expose Forge’s loopback API and local data.

    Fix: Server-side, require an absolute http or https URL with a nonempty host and no userinfo. Reject malformed, relative, javascript:, and data: URLs. Repeat the scheme validation at browser navigation sinks as defense in depth.

Medium

  • Preserve reverse-proxy path prefixes in daemon requestsinternal/server/kata/client.go:173

    Narrow daemon requests clear the configured URL path before joining endpoints, incorrectly sending requests to /api/v1/... instead of <prefix>/api/v1/....

    Fix: Preserve base.Path and base.RawPath when joining endpoints, with coverage for a prefixed daemon URL.

  • Reserve the Kata popup before awaiting the launch requestpackages/ui/src/components/kata/KataLinksPanel.svelte:106

    Calling window.open after an awaited request can lose transient user activation, causing browsers to block the popup silently.

    Fix: Open an about:blank popup synchronously, close it on failure, and navigate it after resolving the launch target.

  • Honor the disabled action gate for Kata actionspackages/ui/src/components/kata/KataLinksPanel.svelte:93,115

    Open in Kata and Create/Open workspace remain actionable during workspace transitions or deletion, allowing operations against stale state.

    Fix: Include disabled in both handler guards and button disabled expressions.


Reviewers: 2 done | Synthesis: codex, 15s | Total: 18m49s

@roborev-ci

roborev-ci Bot commented Aug 9, 2026

Copy link
Copy Markdown

roborev: Combined Review (98615de)

Verdict: One high-severity security issue and two medium-severity correctness issues require fixes.

High

  • Daemon-controlled launch URLs enable same-origin script execution
    Location: internal/server/kata/client.go:153, packages/ui/src/components/kata/KataLinksPanel.svelte:113, frontend/src/App.svelte:242
    A remote Kata daemon can return a javascript: launch URL that Forge forwards unchanged. Navigating the same-origin about:blank popup to it allows the script to access Forge APIs and user data. Validate server-side that launch targets are absolute http or https URLs with a nonempty host and no userinfo; reject invalid schemes as upstream errors. Keep a matching frontend allowlist as defense in depth.

Medium

  • Configured reverse-proxy path prefixes are discarded
    Location: internal/server/kata/client.go:173
    Clearing base.Path and base.RawPath causes a daemon configured at https://host/kata to receive requests at /api/v1/... instead of /kata/api/v1/.... Preserve the configured base path when joining API endpoints and add an HTTP-level test for a daemon URL with a path prefix.

  • Stale workspace creation can trigger duplicate requests and incorrect navigation
    Location: packages/ui/src/components/kata/KataLinksPanel.svelte:122
    Workspace creation state is component-local, and completion navigates unconditionally. A remount or subject change during the request can issue a duplicate request or navigate to the previous task’s workspace. Track pending creation in shared, identity-keyed state and guard navigation using the current subject or request generation while still publishing the completed workspace globally.


Reviewers: 2 done | Synthesis: codex, 19s | Total: 14m54s

@roborev-ci

roborev-ci Bot commented Aug 9, 2026

Copy link
Copy Markdown

roborev: Combined Review (ef2f14b)

The changes are generally sound, but two medium-severity issues should be addressed around inactive loading and workspace diagnostics.

Medium

  • Inactive panels eagerly fetch Kata link detailsfrontend/src/lib/components/kata/KataLinksPanel.svelte:275
    The subject effect calls loadLinks() even when active is false. Because inactive issue and pull-request panes remain mounted, selecting an item hydrates every Kata link and fetches full task details before the Kata tab is opened. Defer the initial association/detail load until the panel becomes active, while ensuring each subject loads only once upon activation.

  • Workspace resolution failures lack actionable diagnosticsinternal/server/kata/effective_links.go:251
    Resolution errors are discarded, while unmapped or ambiguous results expose only available: false. The UI therefore removes the workspace action without explaining whether configuration is missing, ambiguous, or temporarily failing. Preserve resolver status/source or a per-link diagnostic in the response, mark genuine resolver failures as partial, and display the explanation beside the selected task.


Reviewers: 2 done | Synthesis: codex, 10s | Total: 20m49s

@roborev-ci

roborev-ci Bot commented Aug 10, 2026

Copy link
Copy Markdown

roborev: Combined Review (36b2907)

The PR has two medium-severity regressions affecting Kata workspace access and closed-task navigation.

Medium

  • Local workspace actions disappear when Kata hydration fails
    Location: internal/server/kata/effective_links.go:207, frontend/src/lib/components/kata/KataLinksPanel.svelte:209
    Failed daemon or reference hydration skips local workspace resolution, while the UI requires selected.workspace.available even when effectiveWorkspace identifies an existing local workspace. A daemon outage, deleted task, or stale association can therefore hide the Open workspace action for a workspace that still exists.
    Fix: Resolve and attach local workspaces independently of live Kata hydration. Permit opening an existing effectiveWorkspace, and require live availability only when creating a workspace.

  • Closed Docs task references no longer resolve
    Location: frontend/src/App.svelte:407
    Human-readable Docs references now use the open-task autocomplete endpoint, which omits closed tasks. Links to completed tasks that previously resolved with status: "all" therefore fail unless they use UID-form references.
    Fix: Use a separate exact-reference resolver that includes closed tasks for navigation while keeping autocomplete open-only, and add coverage for opening a closed qualified reference.


Reviewers: 2 done | Synthesis: codex, 10s | Total: 19m14s

@roborev-ci

roborev-ci Bot commented Aug 10, 2026

Copy link
Copy Markdown

roborev: Combined Review (57df179)

Four medium-severity issues remain: timeout fallback context, completed bare references, association retry recovery, and disabled workspace actions.

Medium

  • internal/server/kata/effective_links.go:172 — After a daemon request reaches its five-second deadline, the canceled context is reused for the SQLite workspace lookup. The fallback can therefore omit an existing workspace and remove the user’s “Open Workspace” path precisely when the daemon is unavailable. Limit the timeout context to remote daemon calls, use the parent request context for local resolution, and test an actual timeout.

  • frontend/src/App.svelte:403 — Bare Kata references use the search endpoint, but internal/server/kata/read_routes.go:92 restricts results to open tasks. Completed historical references such as #budget consequently stop resolving. Resolve exact bare references across all statuses only when the short ID is unique, and add end-to-end coverage for a completed reference.

  • frontend/src/lib/stores/kata-links.svelte.ts:320 — A failed initial association load cannot automatically retry because #lastAssociationRefreshAt remains null, causing #refreshAssociationsWhenStale to return immediately. Treat the absence of a successful refresh timestamp as stale while retaining the in-flight guard, and test recovery after focus or pane activation.

  • frontend/src/lib/components/kata/KataLinksPanel.svelte:226 — The workspace action handler and button ignore the component’s disabled prop, allowing workspace creation or navigation during deletion or route transitions. Add disabled to both the handler guard and the button’s disabled expression.


Reviewers: 2 done | Synthesis: codex, 11s | Total: 38m37s

Forge carried a copied Kata browser after Kata became its own product, creating parallel implementations and an ambiguous ownership boundary. Keep only the cross-product workflows Forge owns: stable provider/workspace associations, daemon-pinned read-only detail through Kata’s shared component, safe standalone launch, and Kata-backed workspace creation.

Task presentation and mutation remain in Kata, while linkage metadata exists only in Forge. The integration stays pinned to the reviewed Kata PR commit until the maintainer separately approves a Kata release; the old route, proxy, snapshots, event relay, mode flag, and copied frontend are removed without compatibility shims.

Review fixes included:

- Defer inactive Kata reads and explain workspace mapping failures.
- Keep existing workspaces and completed task links reachable when Kata reads fail.
- Preserve workspace actions across daemon timeouts, failed first reads, and disabled transitions.

Generated with Codex
Co-authored-by: Codex <noreply@openai.com>
@roborev-ci

roborev-ci Bot commented Aug 10, 2026

Copy link
Copy Markdown

roborev: Combined Review (39f8d0c)

Review found two medium-severity correctness and concurrency issues that should be addressed before merge.

Medium

  • frontend/src/lib/components/terminal/NewWorkspaceDialog.svelte:409 — Kata workspace creation bypasses the shared kata-workspace-create state. Reopening the dialog or creating from a linked-task panel concurrently can submit duplicate requests and race or repeat queued launch intents.

    • Fix: Wrap the workflow with beginKataWorkspaceCreate, recordKataWorkspaceCreated, and endKataWorkspaceCreate; add full-stack coverage for concurrent entry points.
  • internal/server/kata/client.go:142 — Bare-reference uniqueness is determined from at most 200 substring-search results. A second exact short_id match beyond that truncated set can be missed, causing Forge to resolve and open the wrong task.

    • Fix: Use an exact resolver with completeness guarantees, paginate through all matches, or fail closed whenever results may be truncated.

Reviewers: 2 done | Synthesis: codex, 15s | Total: 21m47s

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant