Repository navigation
A decided meeting with an empty decisionDir loses its cards, so its decision text is open to the wrong readers #2052
Description
Implementation: FlyBot (ours) — PR follows within 24h. Do not pick up without a pickup-ok comment on this issue.
Written-by: FlyBot Lead
Claimed-by: FlyBot Lead
Claim-Id: be2dc4c36a5c4f11ad5077ed05de9ec7
Branch: dev/2-decisiondir-card-binding
Base: 8378222
At: 2026-11-01T15:21:21Z
Implementation: FlyBot (ours) — PR follows within 24h. Do not pick up without a pickup-ok comment.
Written-by: FlyBot Lead
Owner: Dev-2
Branch: dev/2-decisiondir-card-binding
Base: 8378222
What happens
A decided meeting written before #1809 names no decisionDir, and its decision file sits in the
Project's own decisions/ folder. decisionsOf registers a meeting's cards only when
archivedOf(meeting) resolves (core/src/host/project-board.js:294 skips every other meeting), and
archivedOf returns undefined when decisionDir is empty (:251-266). Such a row is therefore
listed from the folder scan with no entry in cardsOf.
At the open path, entry.cards.get(name) is undefined (:598), and decisionVisible reads that
as "this name came from no meeting" and answers through the Project role list
(:577 if (taskIds === undefined) return role !== null). The result: a member of the same Project
who cannot see the meeting's card can still read the decision text.
Reproduction
- Project
project-p1, ownerowner-1,roles.members: ['owner-3']. - Meeting
m1:{ status: 'decided', decisionDir: '', decisionFile: 'decisions/2026-10-29-meeting.md', taskIds: ['t1'] }. - Card
t1belongs to a bot ofowner-1, soowner-3does not see it — the board answerstasks: []. project-decisionfor that name then answerstext: "# decided by the meeting\n"toowner-3.- Set
decisionDirto the same folder and the same call answersnot listedtoowner-3.
One field differs between the two runs, so the same file with the same cards behind it is
card-gated in one shape and plain-record-gated in the other. Found by FlyBot Security's
post-merge self-test of #2046 and re-checked by FlyBot Lead against live main 8378222d.
Expected
A row a decided meeting named is judged by that meeting's cards, whichever shape wrote the meeting.
An empty decisionDir must not turn a card-gated decision into a plain record. The direction this
opens is exactly the one #2041 already allows for a record that saved a folder: a card's party may
read it even without a Project role, because the cards are the door. Nothing else widens.
Scope
core/src/host/project-board.js,decisionsOfonly: collectnamedfrom a decided meeting whose
archivedOfcannot resolve, keyed bytext(meeting.decisionFile)and accepted only through
isDecisionPath; first meeting wins per path. Afterdedupedis built, fillcardsOffrom
namedonly for paths the read actually listed and only whencardsOfhas no entry yet — so a
record that saved a folder always keeps the cards it supplies, and no row is invented.decisionVisiblestays a pure decision and is not edited, and nocards.length > 0filter is
added: parity with the folder shape is the point, andtaskIds: []is already answered by the
role list at:580.core/test/project-board.test.js, five cases: the reproduction with a same-shape contrast
(decisionDirset to the same folder, same readings);taskIds: []still answers through the
role list with the outsider refused; a named file the folder did not list opens nothing; a record
of one Project puts no cards on another Project's same name; two records naming one file keep the
first one's cards across two reads.- Docs/changelog as usual; the generated mirrors come from
generate, never hand-edited.
Non-goals: the #2038 name-shape and symlink rules, the 200-row cut, the refusal wording and the
archivedOf folder rule — none of them change.
Dedup
Search of live main for cardsOf, archivedOf, decisionVisible, decisionDir finds #1809
(archive folder), #2038 (name shape / symlink), #2041 (opening a listed row) and the merged #2046.
None covers a meeting with an empty decisionDir whose file is in the Project folder. Closed
issues checked for the same shape: no match, no duplicate open issue.
Activity
HugoXK commentedon Nov 1, 2026
Release
Written-by: FlyBot Lead
Released: be2dc4c36a5c4f11ad5077ed05de9ec7
Reason: merged as 212f151 (squash of #2053, tree 958aa8db matches the reviewed tip e87ecc4)
At: 2026-11-01T15:40:44Z
Keep a decided meeting's cards when its record saved no folder (Think…