4 Commits
Author SHA1 Message Date
Bohan Jiang ff60b2f25a MUL-7379 fix: restore per-status sort order and the delegated handoff signal (#8435)
Fixes three regressions left by MUL-7240's collapse from seven stored issue
lifecycle categories to four. All three share one shape — a comparison of an
Effective() result against one of the five NON-TERMINAL built-in keys, which
stopped matching custom statuses once nonterminal custom keys were left raw.
Terminal projection survived, which is why no done/cancelled check regressed.

Principle applied: behavior logic aggregates on category, display logic resolves
on status.

1. Status sort collapsed from seven ranks to four (server and client, affects
   every workspace). Backlog tied with Todo and In Progress/In Review/Blocked
   all tied, leaving the created_at tiebreak to order a list the user sorted by
   status. Both sides now rank on the concrete key in catalog board order,
   reusing issueTableStatusOrder so sorting and grouping share one source of
   truth. statusOrderExpression itself is unchanged — its other caller ranks
   the four category buckets of a status_category grouping, which is correct.

2. Delegated subscribers stopped being told about handoffs. Their allowlist was
   {in_review, done, cancelled, blocked}; a workspace's "Awaiting Response" or
   "Code Review" used to match via its category and no longer did, so the human
   whose agent filed the issue was never told it was waiting on them. Both
   hand-kept allowlists (which had already drifted) are replaced by one
   predicate: done/closed, or started excluding the fixed in_progress key.
   Delivery fails open, stale task_failed dismissal fails closed.

3. Autopilot webhook crash-compensation stopped repairing the lost create_issue
   task for any workspace with a custom status, leaving the run in
   issue_created with no task while the delivery recorded success.

Also corrects four comments that still justified their behavior with the
retired "a custom status resolves to the canonical status it inherits"
mechanism — the exact failure mode MUL-7364's postmortem named.

Tests: the existing sort regression test used one issue per category, so four
buckets and seven produced identical output; the new one puts several built-ins
in one category, wedges a custom Started status between two of them by position,
and orders insertion so created_at DESC is the reverse of the expected result.
Verified to fail on the pre-fix expression.
2026-09-15 13:30:37 +08:00
7dafc0cd62 MUL-7240: Unify issue lifecycle into four stored categories (#8261)
* feat: simplify issue status categories

Co-authored-by: multica-agent <[email protected]>

* feat: adopt four stored issue lifecycle categories

Co-authored-by: multica-agent <[email protected]>

* fix: preserve visible work when upgrading saved category preferences

Co-authored-by: multica-agent <[email protected]>

* docs: align lifecycle comments with stored and wire contracts

Co-authored-by: multica-agent <[email protected]>

* test: align mobile grouping expectations with four categories

Co-authored-by: multica-agent <[email protected]>

* fix(issues): group user views by concrete status keys

Co-authored-by: multica-agent <[email protected]>

* fix(settings): simplify status editor copy and category selector

Co-authored-by: multica-agent <[email protected]>

* feat(statuses): allow ordering built-ins and unify row actions

Co-authored-by: multica-agent <[email protected]>

* feat(statuses): configure custom status icons independently of category

Co-authored-by: multica-agent <[email protected]>

* fix(statuses): dismiss built-in status notice

Co-authored-by: multica-agent <[email protected]>

* fix(issue-status): require moving issues before archive and polish controls

Co-authored-by: multica-agent <[email protected]>

* fix(ci): renumber issue status migrations after main updates

Co-authored-by: multica-agent <[email protected]>

* fix(statuses): isolate archive inspection and align catalog behavior

Co-authored-by: multica-agent <[email protected]>

* fix(statuses): respect injectable catalog for table grouping

Co-authored-by: multica-agent <[email protected]>

* refactor(statuses): simplify built-in skill and runtime guidance

Co-authored-by: multica-agent <[email protected]>

---------

Co-authored-by: Lambda <[email protected]>
Co-authored-by: multica-agent <[email protected]>
2026-09-14 12:57:24 +08:00
5d5fe64672 MUL-6343: Add semantic issue activity timestamps (#7193)
* feat: add semantic issue activity timestamps

Co-authored-by: multica-agent <[email protected]>

* fix(migrations): register issue activity index cleanup

Co-authored-by: multica-agent <[email protected]>

* fix(issues): address last activity review

Co-authored-by: multica-agent <[email protected]>

* fix(issues): close last activity review gaps

Co-authored-by: multica-agent <[email protected]>

* fix(issues): harden activity rollout safeguards

Co-authored-by: multica-agent <[email protected]>

---------

Co-authored-by: Sol-Boy <[email protected]>
Co-authored-by: multica-agent <[email protected]>
2026-08-19 16:08:40 +08:00
002ea0d879 MUL-4797: add configurable issue table view (#5454)
* feat(issues): add configurable table view

Co-authored-by: multica-agent <[email protected]>

* test(issues): cover table columns in page fixture

Co-authored-by: multica-agent <[email protected]>

* fix(issues): make table column picker interactive

Co-authored-by: multica-agent <[email protected]>

* fix(issues): repair quick create and virtualize table rows

Co-authored-by: multica-agent <[email protected]>

* fix(issues): keep pinned table cells opaque

Co-authored-by: multica-agent <[email protected]>

* fix(issues): anchor full-width table rows

Co-authored-by: multica-agent <[email protected]>

* fix(issues): consolidate table controls

Co-authored-by: multica-agent <[email protected]>

* fix(issues): harden table pagination and export

Co-authored-by: multica-agent <[email protected]>

* feat(issues): add table quick search

Co-authored-by: multica-agent <[email protected]>

* fix(issues): make table window filters, selection, and export authoritative

Round-2 review fixes for the issues table (MUL-4797):

- Send the agents-working filter as a server ids facet so matches on
  unfetched pages surface and total/pagination/export agree; a present-
  but-empty id list yields an empty window instead of an unfiltered one.
- Reset surface selection when the membership window changes and act on
  selection ∩ visible rows in the batch toolbar, so batch actions,
  Export selected, and the count all share one authoritative set.
- Materialize the full flat window while table grouping is active, and
  suspend hierarchy nesting / parent-based grouping until the window is
  complete so structure cannot reshuffle as pages arrive; suppress
  header facet-count badges while the table window is partial.
- Resolve actor directories and the property catalog at export time and
  fail the export instead of writing Unknown* actors or dropping
  configured property columns on cold/errored lookups.
- Append a unique id tie-break to the list/grouped ORDER BY and mirror
  it in compareIssuesForSort so offset pages are stable across
  same-timestamp ties.

Co-authored-by: multica-agent <[email protected]>

* fix(issues): bound table structure window and align chip/transport/selection

Round-3 review fixes for the issues table (MUL-4797):

- Cap whole-window materialization at TABLE_STRUCTURE_MAX_WINDOW (1000):
  below it the remaining pages load automatically — hierarchy applies
  without scrolling to the last page — and above it grouping/hierarchy
  suspend with an explicit toolbar notice instead of triggering an
  unbounded workspace download from a persisted view option.
- Give the agents-working chip the authoritative in-window running set
  (the ids-facet window query, shared key with the filter-on state) so
  its badge can no longer say 0 while the filter would find matches on
  unfetched pages; falls back to loaded-row scoping elsewhere.
- Route ids-facet windows through a new POST /api/issues/query twin —
  hundreds of running-issue UUIDs overflow the ~8 KB GET request-line
  budget of common proxies. The body carries the same key/value pairs;
  the handler rebuilds the query string and delegates to ListIssues.
- Reset surface selection during render (key-change pattern) instead of
  a post-commit effect, so no frame ever pairs new membership with the
  old selection.

Co-authored-by: multica-agent <[email protected]>

* fix(issues): harden table auto-pagination against errors and stale totals

Round-4 review fixes for the issues table (MUL-4797):

- Stop the structure materialization loop (and the scroll sentinel) when
  the window query is in error state — a persistently failing page left
  hasNextPage true and isFetchingNextPage false after every attempt, so
  the ungated effect refired forever. Resuming is an explicit toolbar
  Retry. The advancement decision now lives in a pure, tested
  shouldAutoLoadNextStructurePage helper.
- Make the structure ceiling a hard stop: the ceiling check reads the
  LATEST page's total (pagination already advances on it, so a stale
  small page-1 total could re-open unbounded materialization), and the
  loop additionally halts on loaded count >= ceiling regardless of any
  reported total.
- Drive the working (ids-facet) window to completion — it is inherently
  bounded by the running set — and treat it as the chip's authoritative
  scope only when complete, so >100 running issues no longer under-count
  as a single page.

Co-authored-by: multica-agent <[email protected]>

* fix(issues): make working-window pagination capped and unknown-aware

Round-5 (final) review fixes for the issues table (MUL-4797):

- The working (ids-facet) window now advances through the same
  shouldAutoLoadNextWindowPage gates as the structure loop — it shares
  the main table's cache key while the agents-working filter is on, so
  an uncapped chip-driven loop re-opened the very ceiling the table just
  enforced. An over-ceiling window stops after page one.
- A cold-load failure of the flat window is an ERROR state, not an empty
  workspace: isEmpty only claims empty on a successful zero-result
  fetch, and the surface renders a dedicated failed-to-load state with a
  reachable Retry (the in-table Retry never mounted without data).
- The chip scope is now tri-state honest: a COMPLETE window (or an empty
  running set) yields a precise count, keepPreviousData carries the
  last-known-complete set across re-keys, and everything else — cold
  resolving, failed, over the ceiling — presents as an explicit unknown
  ('Agents working: —') instead of a number derived from whichever
  incomplete window happened to be loaded.

Co-authored-by: multica-agent <[email protected]>

* fix(issues): single pagination owner and placeholder-honest chip scope

Round-6 review fixes for the issues table (MUL-4797):

- Exclude placeholder data from the working-window completeness gate:
  on a re-key (running set or facet change) keepPreviousData leaves the
  OLD key's rows visible, and pairing them with the new task snapshot
  published a precise-looking number for a scope nobody fetched. The
  scope now reads unknown until the new key resolves.
- Make the shared table query single-owner while the agents-working
  filter is on: the chip's background loop no longer answers the same
  render snapshot as TableView's structure loop, and every auto caller
  (structure loop, working loop, scroll sentinel, retry) now uses
  fetchNextPage({cancelRefetch: false}) so a concurrent responder
  no-ops instead of cancel/restarting a fetch whose HTTP request is not
  abortable — which had been duplicating every offset.

Co-authored-by: multica-agent <[email protected]>

---------

Co-authored-by: Lambda <[email protected]>
Co-authored-by: multica-agent <[email protected]>
2026-07-17 19:21:27 +08:00