Show who owns a story — render the assignees Facility already mirrors
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 71
- Forks
- 64
- Avg merge
- 15h 38m
- Merged PRs (30d)
- 66
Description
The problem
Every story on the board is unowned as far as the interface is concerned. Nowhere in apps/web is assignees read — not on the row, not on the story header, not on the pipeline board.
The data has been there all along, and #70 just made it meaningful:
gh_issues.assigneesis mirrored on every webhook and every sync (packages/db/src/schema.ts:234,services/api/src/github/issues-sync.ts:281);- it is assembled into the story (
services/api/src/pipeline.ts:178); - it is serialised on both responses the web already fetches —
PipelineStorySchema.assignees(services/api/src/routes/v1/github.ts:189) andStoryDetailSchema.assignees(:228); - and since #70, triggering an agent assigns the triggering user on the issue and on the PR the run later opens (
services/api/src/routes/v1/github.ts:944,services/api/src/sandbox/orchestrator.ts:891).
So Facility writes ownership to GitHub, mirrors it back, ships it over the wire — and drops it at the last inch. On a board where several people dispatch agents against the same repository, "who is on this?" is unanswerable without opening GitHub.
What I propose
Render the assignee on the story row and in the story header, in the existing grammar: @login, mono, --dim, beside the labels and the timestamp in IssueRow (apps/web/components/issues/issue-row.tsx:84-92). Several assignees: the first plus +N. Unassigned: render nothing, not a placeholder — the rows are dense and unassigned is the common case in Backlog.
Two things that make it more than decoration, worth the same slice:
- Avatars.
users.avatar_urlexists for Facility users, but a GitHub assignee need not be one;https://github.com/{login}.png?size=40needs no new column and no new sync. Where a deployment must not let the browser reach github.com, the initial-letter fallback the topbar already uses is the answer. - A "mine" filter on the Stories board, next to the stage chips, matching against
me.principal.githubLogin(added by #70,services/api/src/routes/v1/shared.ts:123). That is what turns a rendered field into a working view.
What I considered instead
- Showing the last run's
triggeredByas the owner. That is who dispatched the most recent agent — often, but not always, who owns the story — and it is empty for anything nobody has dispatched yet. The GitHub assignee is the answer the rest of the world already agrees on. - A Facility-native owner field. A second source of truth for something GitHub models, with no writer, no sync path and no reconciliation story.
The change is apps/web-only: the data is already on the wire, and apps/web/test/pipeline-story.test.ts is where the row's rendering rules are pinned.
Related: #70, #18. Findings are against 5712bf8.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with apps/web/components/issues/issue-row.tsx:84-92 and apps/web/test/pipeline-story.test.ts, then trace the story header and Stories board stage-chip components. Confirm the existing assignees data is rendered with the specified unassigned and multiple-assignee rules, avatar fallback behavior, and mine filter, with tests covering the rendering rules.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend
- Issue type
- Feature
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100