Repository navigation
Project board: a blocked card says why it is stuck but never how long, and the Blocked group is unsorted - #2031
Merged
Conversation
HugoXK
marked this pull request as ready for review
November 1, 2026 11:32
HugoXK
force-pushed
the
dev/2-blocked-card-age
branch
from
November 1, 2026 11:45
be25d59 to
2b76eb5
Compare
Contributor
Author
|
@Birfy — review request: At this tip every check is green except Asking for one pass: a |
Collaborator
|
Verdict: PASS at 2b76eb5 Ran at this tip: 审查要点:
|
The Blocked group answered why a card was stuck and never how long, while the Waiting group beside it showed a duration and read oldest-first. A card blocked for three days and one blocked for three minutes rendered identically, and the card that had been stuck longest was not the one on top. `blockedOf` now reads the `inputRequest.requestedAt` stamp the ask itself wrote and answers the same age shape `waitingOf` does: `since` (or `null` when the ask wrote none) and `waitedMs` (`now - since`, or `null`). It never falls back to `createdAt`/`updatedAt`: an invented stamp would read as a wait nobody measured. `buildQueues` sorts `blocked` with the comparator `waiting.sort` already uses, so an undated card sorts last and the Waiting output is unchanged. The client draws `reason · 2d` when the host measured a wait and the reason alone when it did not.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #2029
Written-by: Dev-2
Owner: Dev-2
Reviewer: Birfy
Claim-Id: 0217a22190204dfc8d1a523db2dca665
Branch: dev/2-blocked-card-age
Base: f6fcb7f
What changed
The Blocked group answered why a card was stuck and nothing else: one line per card, the
inputRequest.question. The Waiting group beside it answered how long and read oldest-first, so a card blocked for three days and one blocked for three minutes drew the same line, and the card stuck longest was not the one on top.blockedOf(task, now)(core/src/host/project-board.js:138-142) now answers the same age shapewaitingOfdoes:since= theinputRequest.requestedAtstamp the ask itself wrote (tasks.js, preserved across a re-ask),waitedMs=now - since, bothnullwhen the ask wrote no stamp. It still answers{ id, reason, since, waitedMs }andreasonstays the card's own line;createdAt/updatedAtare never used as a fallback, because an invented stamp is worse than none.buildQueues(:502-523, the two sorts at:521-522) passes thenowit already computed and sortsblockedwith the comparatorwaiting.sortalready used, hoisted tooldestFirstso the two groups cannot drift. A card with no stamp sorts last. The Waiting group's own output is unchanged — same comparator, same rows.core/src/client/project-board.js:316,:510) carrieswaitedMson the blocked row and drawsreason · 2dwhen the host measured one, the bare reason when it did not.waitedLabelis reused, so a sub-minute span still reads seconds rather than0m.Line numbers are this tip (
2b76eb55), not the base. No write path changed; the board still writes nothing.Base moved while this was in review:
#2028merged asf6fcb7ffand it touches the same two generated files (core/client.js,patches/ds-bot/0008-client-bundle.patch). The source diff was replayed onto the new base withgit apply --3way(clean), then the client bundle and the ds-bot mirror were regenerated — the conflict is in the generated files, so they are re-derived, never merged by hand.Line by line
core/src/host/project-board.js— +17 / −6:blockedOftakesnowand answers the age;oldestFirstextracted,blocked.sortadded.core/src/client/project-board.js— +6 / −2: the blocked row carrieswaitedMs, the note draws the label.core/test/project-board.test.js— +44 / −0: cases 1, 2 and 3.core/test/project-board-view.test.js— +18 / −0: case 4.core/client.js— +2 / −2: generated bynpm run buildincore/, never hand-edited.patches/ds-bot/0008-client-bundle.patch+2 / −2 andpatches/ds-bot/files/{src/host,src/client,test}/project-board*: generated bynode scripts/ds-bot-patches.mjs generate, never hand-edited.docs/subsystems/core-host.md+1 / −1 anddocs/subsystems/core-client.md+3 / −1: the read and the row documented.changelog.d/2029-blocked-card-age.changed.md— +1.What I ran
blockedOfkeeps{ id, reason }(dropssince/waitedMs): acceptance 1 and 3 go red 2/2 (the#2029cases "carries the age of its own question" and "no requestedAt has no age"), and acceptance 2 follows because the sort reads the same field; the two files read 58 / 55 / 3 both runs.blocked.sort(oldestFirst): only acceptance 2 goes red, 2/2 (the ordering case:['task-blocked','task-blocked-old','task-blocked-unstamped']vs the expected order), 58 / 57 / 1.row.reasonalone: only acceptance 4 goes red, 2/2 (the.bt-project-reasontext does not end with· 2d), 58 / 57 / 1.waiting.sortreversed: the existing#1768waiting assertion goes red, 2/2, so acceptance 5's regression guard still bites, 58 / 57 / 1.TZ=UTC ARCH_DOCS_BASE=f6fcb7ffabee43da79388313cbcdb7ada9111dcb npm run verifyat this tip, clean tree: exit 0.core2455 tests / 2455 pass / 0 fail / 0 skipped;plugins/social541,plugins/tree127,plugins/timeline135,plugins/workflow336,.github563 / 563, interop 37 / 37, live-e2e 24 / 24. Skip counts are host-dependent and are not asserted here; the totals above are the run's own output.arch-docs: OK (13 changed file(s)); oxlint73 warnings, 0 errorsin core (the base's own count);ok ds-bot/ = Fei2411/DeepSeek-Bot@2b10c70;10 patches apply cleanly in order;core/ equals ds-bot/ + patches/ds-bot/;patches/ds-bot/ is what generate writes (generate is a no-op);node core/scripts/build-client.mjs --checkexit 0;node .github/scripts/changelog.mjs check— green.node scripts/ds-bot-patches.mjs generaterun twice, the second run byte-identical (every file underpatches/ds-bot/has the same sha256).patches/ds-bot/0008-client-bundle.patchissha256 0f965ee5a5466280559eff550c2468488d606c09668a24c5cc2af6cad655c910;0002-flybot-api-host.patchissha256 96be0fa26f9e818da4011d8f6a3e2ce4c1f7f3772038041c2b3c926fc326cb4c.dev/bench.sh smoke) —index.jsis untouched and this is a read-model field plus a sort, so the smoke tier adds nothing here.Checkpoint
{
"pr": 2031,
"claim": "Dev-2",
"issue": 2029,
"summary": "The Blocked group on a Project board now says how long each card has been stuck.
blockedOfanswerssince/waitedMsfrom the question's ownrequestedAtstamp and from nothing else, so a card whose ask wrote no stamp shows no duration.buildQueuessorts the group oldest-first with the comparator Waiting already uses, an undated card last. The row drawsreason · 2dand keeps the reason alone without a stamp. The Waiting group's own output is unchanged.","files": [
"core/src/host/project-board.js",
"core/src/client/project-board.js",
"core/client.js",
"core/test/project-board.test.js",
"core/test/project-board-view.test.js",
"patches/ds-bot/0008-client-bundle.patch",
"patches/ds-bot/files/src/host/project-board.js",
"patches/ds-bot/files/src/client/project-board.js",
"patches/ds-bot/files/test/project-board.test.js",
"patches/ds-bot/files/test/project-board-view.test.js",
"docs/subsystems/core-host.md",
"docs/subsystems/core-client.md"
],
"checks": {
"ran": "TZ=UTC ARCH_DOCS_BASE=f6fcb7ffabee43da79388313cbcdb7ada9111dcb npm run verify",
"result": "green",
"at": "2b76eb55698954a65d3290c615eb00808c6287b8"
},
"next": "none — ready for review"
}