Skip to content

bug(llc): Kanban swimlane humanItems() filters on assignee_type === 'human' but backend only ever writes 'user' #13954

Closed

Description

@mrveiss

Discovered while implementing #13937 (AssigneeType enum SSOT).

Evidence

  • Backend AssigneeType (now the canonical SSOT in autobot-backend/llc/models/enums.py) has exactly two members: USER = "user" and AGENT = "agent". Every write site (work_item_service.py, handoff.py) persists "user" for the human branch — never "human".
  • autobot-frontend/src/views/llc/workItemTypes.ts:40 types the field as assignee_type?: 'human' | 'agent' | null.
  • autobot-frontend/src/views/llc/KanbanBoardView.vue:159 — humanItems() swimlane filter: i.assignee_type === 'human'.

Impact

The swimlane split on the Kanban board is a silent no-op for the human lane: it can never match a real row because the backend value is always 'user', never 'human'. agentItems() (line 163, === 'agent') does match correctly, so the board looks like it works (agent items show) while human items are structurally invisible to that filter — the same "lying detector" pattern as #13852's cluster.

Fix

Either:

  1. Change the frontend type/comparison to 'user' | 'agent' (matches the backend SSOT), or
  2. Rename the backend value to 'human' (migration required — rejected: breaks the "additive only, no data migration" invariant tech-debt(llc): assignee_type is an untyped String(16) — no AssigneeType enum in the LLC enum SSOT #13937 just established).

Option 1 is the correct fix — no backend/migration risk.

Scope

Frontend-only (autobot-frontend/src/views/llc/workItemTypes.ts, KanbanBoardView.vue), out of scope for #13937 which is backend-only (enum SSOT).

Activity

  1. mrveiss commented on Aug 11, 2026

    @mrveiss
    OwnerAuthor

    This issue understates the bug — do not start with the string literal.

    Verified while reviewing PR #13955: the 'human' vs 'user' mismatch is the third defect in a chain, not the first. The board renders zero cards in every column regardless, because autobot-backend/llc/api/boards.py:245-248 returns {board, columns} with no top-level items key while KanbanBoardView.vue:226 reads itemsData.items ?? []. _work_item_summary() also omits both assignee_type and column_id.

    Full chain filed above. Whoever picks this up would otherwise change one string, see nothing change, and be confused.

    Also relevant here: workItemTypes.ts:40 types the field 'human' | 'agent' | null — 'user' is absent, so the fix is a type change too.

  2. mrveiss commented on Aug 11, 2026

    @mrveiss
    OwnerAuthor

    Delivered in PR #14043 (via #13993, which supersedes this framing — this was the third defect in a three-defect chain that made the board render zero cards in every column).

    Option 1 as recommended here, no backend change:

    • autobot-frontend/src/views/llc/workItemTypes.ts:46 — assignee_type?: 'user' | 'agent' | null (was 'human' | 'agent' | null, a union that did not contain the value the backend actually sends).
    • autobot-frontend/src/views/llc/KanbanBoardView.vue:159 — humanItems() now filters === 'user'.

    grep -rn "assignee_type" autobot-frontend/src confirms no 'human' literal remains anywhere in the frontend.

    Guarded by a regression test that mutation-proves specifically this defect: reverting only the 'user' → 'human' comparison turns the swimlane test red (2 cards → 1) while the other three tests stay green, so the assertion is specific to this bug rather than incidentally coupled to the shape fix.

    The CoWorkerType {agent,human} vs assignee {user,agent} vocabulary fork remains open as #13970 and is untouched.

  3. mrveiss commented on Aug 11, 2026

    @mrveiss
    OwnerAuthor

    Delivered in PR #14043, squash-merged into Dev_new_gui as 93f64153f.

    Closing manually: Closes #NNN does not fire on Dev_new_gui (only on the default branch), and the
    PR body named this issue.

    Verified on the merged base, not assumed:

    $ git show origin/Dev_new_gui:autobot-frontend/src/views/llc/KanbanBoardView.vue | grep "assignee_type ==="
    162:  return items.value.filter(i => i.column_id === colId && i.assignee_type === 'user')
    166:  return items.value.filter(i => i.column_id === colId && i.assignee_type === 'agent')
    

    The human swimlane now filters on 'user', matching what the backend actually writes at every write
    site. workItemTypes.ts was retyped and its provenance comment corrected — it had claimed
    assignee_type was board-only, when in fact the work-items response emits it and only column_id is
    board-only.

    Scope note recorded on this issue earlier still stands: this string was the third defect in a
    chain, not the first. The board rendered zero cards regardless, because the API returns
    {board, columns} with items nested per column while three frontend views read a nonexistent
    top-level items key. That was #13993, fixed in the same PR, along with a fourth broken caller
    (GanttTimelineView) that the original issue never mentioned.

    Mutation evidence from review: reverting only this 'user' → 'human' literal reddens exactly
    one test (swimlane split uses the backend vocabulary), confirming the assertion is specific rather
    than incidental.

    Related follow-ups spun out of the same work: #14074 (sprint/burndown never render), #14075 (board
    summary typed as full WorkItem, so the detail drawer shows a blank description), #14062 (fixtures
    asserting API shapes the backend never returns), #14064 (load failure renders as a legitimately
    empty board).

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingfrontend

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions