Repository navigation
fix(project-assistant): read the Project's own board for the 09:00 digest (#1846) - #1877
Conversation
|
@Birfy review request for this tip: What changed, in one line: the 09:00 digest now reads the Project's own board through an opt-in internal read ( Evidence at this head:
Owner: FlyBot Lead Request: a Verdict on this tip, or a waiver if you would rather not spend a review round on it. The tip is frozen while this is open — no rebase, no new push, no further comments. |
The digest called `rt.projectBoard(id)` with no actor. Once anyone has signed
in, `authzEnforced()` is on and the board's per-reader `taskVisible` rule
filters every card out, so every digest said "no change since the previous
digest" — and that sentence was stored as the next run's `since`, hiding every
finished card for good.
`projectBoard` now takes an explicit `{ internal: true }` option that skips the
one `visible` decision, and only the digest passes it (`project.id, null,
{ internal: true }`). The channel builds its options from the time zone alone,
so an `internal` field in a request body never reaches the flag, and a call
without it keeps today's behaviour (0 rows without an actor).
|
Verdict: PASS at 581bb2d Ran at this tip: Review points:
Not run here: the full |
Written-by: Dev-4
Owner: Dev-4
Reviewer: Birfy
Fixes #1846
What was wrong
The 09:00 digest read the board with no actor:
rt.projectBoard?.(project.id)(project-assistant.js:478). On any install where somebody has signed in —authzEnforced()isObject.keys(state.authSessions).length > 0— the board paints a row only whenrt.taskVisible(task, actor)allows it, and withactorundefined every branch of that predicate is false. Sorowswas[],buildDigestfilled none of its four sections, and every day answeredProject Assistant (P1) — …: no change since the previous digest.Worse, that sentence was stored throughsetProjectDigestas the next run'ssince, so every card finished before the first empty digest could never appear in "Merged since" or "Closed" again.Red first
Base
1c44a786cd460472afa8727f6a18ba895a59969b(live main at push time), clean checkout, source untouched, onlycore/test/project-digest-authz.test.jsplaced in the tree,node --import ./test/harness-resolve.mjs --test test/project-digest-authz.test.js:The seed differs from
project-assistant.test.jsby one line —authSessions: { 's-3': … }— which is exactly what turns the reader's rule on; no board stub anywhere, the board path is the real one.What changed
core/src/host/project-board.js:projectBoard(id, actor, options)honoursoptions.internal === trueby skipping the singlevisibledecision in the row loop (if (!internal && !visible(task, actor)) continue). The flag is read from that argument and nowhere else.core/src/host/project-assistant.js: the digest is the one caller that passes it —rt.projectBoard?.(project.id, null, { internal: true }).core/test/project-digest-authz.test.js: the four acceptance cases, with anauthSessionsentry and no stub on the board path.patches/ds-bot/files/src/host/project-board.js,…/project-assistant.js,…/test/project-digest-authz.test.js: the mirrors, produced bynode scripts/ds-bot-patches.mjs generate. Both host files are FlyBot-added, so they live whole infiles/and no.patchin the series changed (.patchdelta is 0 files); the thirdcheckline provescore/equalsds-bot/+patches/ds-bot/. The local git 2.34 adds hunk-header function names to0001/0008when regenerating, which is cosmetic-only; that output was not committed, both stay byte-identical to1c44a786.docs/subsystems/core-host.md: one sentence in theproject-assistant.jsrow — the digest reads the Project's own board, and the channel's options come from the zone alone so a request body cannot ask for the internal read.changelog.d/1846-digest-empty.fixed.md.The guard: opt-in, never a default
A flag that a request could set would be a hole, so the test pins all four shapes:
rt.projectBoard(id)with no actor and no options still answersrows: []; theproject-boardendpoint called by a signed-in non-owner, withinternal: truein the request body, still answerstasks: [](the store builds its options fromtimeZonealone); the owner of the card's Bot still sees their own row; andrt.projectBoard(id, null, { internal: true })sees the whole Project. No synthesised all-powerful actor, no channel-path widening.Scope note
internalskips one decision in one loop, so for that callmine— and thewaiting/inflight/blockedcounts derived from it — are the Project's too, not one reader's. The digest only consumesrows. This is the internal read's own boundary, stated rather than left implicit.Acceptance (the four items on the issue)
In progress, waiting on:\n- task-… — Chief, and no "no change" sentence.projectMemoryFor(id, owner).digest.textnames the same card, and it is the delivered text — the next run'ssinceis no longer empty.Alpha cardforowner-1,Beta cardforowner-2) and never the other owner's.Files
352 insertions, 7 deletions, 8 files.
Gates
arch-docs: OK (8 changed file(s))withARCH_DOCS_BASE=1c44a786, andnpm run verifyexit 0 at this head: core 2257/2257, plugins social 541/541, tree 127/127, timeline 135/135, workflow 336/336,.github/scripts561/561, interop 37/37, live-e2e 24/24. The new file is 4/4;project-assistant.test.js,project-board*.test.js,project-metrics.test.js,project-roles.test.jsandauthz.test.jsstay green without edits (82/82 when run together).Where to read it
Checkout
/home/xuke/.dsh/bot/workspace/w1846, branchdev/4-p234-digest-authz, head581bb2d59c5aa17feeca7ffcf5800f760b04bc87, tree435ef81e909b72d96f6b946c046b534bb651cbd7, base1c44a786cd460472afa8727f6a18ba895a59969b.git diff 1c44a786is the whole change: two host lines of logic, one test file, the mirrors, one doc sentence and the fragment.