Repository navigation
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: 70a86fac514545298d4b8f18bd2186ff
Branch: dev/4-p245-project-role-authz
Base: 7d21690
At: 2026-10-30T13:03:42Z
Once anyone has signed in, every project-role call is denied as Unknown endpoint project-role: #1832's role switch never runs on a real (signed-in) deployment. The endpoint is dispatched and implemented, but core/src/host/authz.js never lists it, so the authorizer's fallback denies it before store.js can answer. Only a deployment where nobody has ever signed in takes the pre-authz path that allows it.
Verified on live main 7d216900b264945b01b09da03beb4e24cec944f0.
现状
core/src/host/channel.js:678—case 'project-role':hands it toprojectEndpoint.core/src/host/store.js:598-611— implements it and delegates the policy tochangeRoleinproject-board.js.core/src/host/authz.js:60-77— the Project rows ofTASK_ENDPOINTSlistprojects,project-create,project-read,project-bind,project-of,project-boardandproject-memory,project-memory-write,project-delete,project-assistant-owner.project-roleis missing.core/src/host/authz.js:429— the fallback:deny('bot/not-found', "Unknown endpoint " + ep).
rt.authzEnforced() (authz.js:87) is true as soon as state.authSessions has any entry, so the hole is invisible until someone signs in — that is, on every deployment that matters. On those, the write path #1832 added is dead: the projects read face works, the context menu offers Member, and the click answers one line Unknown endpoint project-role while the role stays as it was.
Probe (Product, core/test/probe-role-authz.test.js — a copy of project-board.test.js plus one probe; 18 pass / 0 fail), actor is maintainer of project-p1 holding a session:
PROBE listing role="maintainer" choices=["member"]
PROBE authorize project-role={"ok":false,"code":"bot/not-found","message":"Unknown endpoint project-role"}
PROBE project-role answer same
PROBE role after="maintainer"
Why the merged PR did not catch it: #1832 did not touch authz.js, and its ran names projects-nav.test.js, project-roles.test.js, project-board.test.js — none of them goes through an authz-enforced project-role. Same table, third miss: #1713 (project-board, fixed by #1716), #1759 (project-assistant-owner, fixed by #1811), this one.
期望
TASK_ENDPOINTS gains 'project-role' beside the other Project entries. The policy stays where it is: changeRole in project-board.js lets only an Owner re-role someone else, answers not-owner for anyone else, and writes nothing on a refusal.
验收(红先)
- Red first on base: a signed-in actor with a session asks
rt.authorize(actor, 'project-role', body)→ todaybot/not-found/Unknown endpoint project-role; after the fix it is not that code. callAs('project-role', { id, role: 'member' }, token)for a maintainer of that Project → ok, and the nextprojectsread showsrole: 'member'(the write actually lands).- A maintainer or plain member targeting another member (
memberId) →not-owner, androlesbyte-identical to before the call. (An Owner re-roling another member is allowed today bychangeRoleand must keep working; that policy is Projects 导航与项目角色:点项目直达看板,右键切 Owner/Maintainer/Member #1828's, not this issue's.) - No actor →
bot/unauthorized, unchanged. node --test test/projects-nav.test.js test/project-roles.test.js test/project-board.test.jsgreen without edits; fullnpm run verifyexit 0.
Encouraged in the same PR (not required): a guard test that walks the project-* names channel.js dispatches and asserts each is in TASK_ENDPOINTS (and the reverse), so the fourth miss is caught by CI instead of by eye.
Scope
core/src/host/authz.js, plus its verbatim copypatches/ds-bot/files/src/host/authz.js(authz.jsis a FlyBot-added file stored infiles/, sonode scripts/ds-bot-patches.mjs checkmust pass with the two byte-identical — no patch hunk changes).- One test file:
core/test/project-roles.test.jsor a newcore/test/project-role-authz.test.js. - No client change, no
i18n.js, noclient.js, no0008.
查重
Searched open and closed issues and PRs for project-role, authz and Unknown endpoint: the only same-class records are #1713/#1716 and #1759/#1811. No open issue or PR covers project-role; the four open PRs (#1826, #1830, #1834, #1835) touch neither authz.js nor the role endpoint.
Separate follow-up, not this issue: there is still no product path to change another member's role (roles stays empty; the client never sends memberId) — an enhancement queued on its own.
Activity
Answer the Project role switch at the authz gate
Birfy commentedon Oct 30, 2026
Written-by: Chief
状态补记:
agent-pr。本单已有开放 PR #1837(dev/4-p245-project-role-authz,tipd0be5d5e,正文 Fixes #1836),此前本单没有任何状态标签。CI、入队与合并由开该 PR 的那条线负责,本线不接手。读取时间 2026-10-30T16:35Z,来源 api.github.com。