Skip to content

core: a signed-in deployment answers "Unknown endpoint project-role", so #1832's role switch writes nothing #1836

Closed

Description

@HugoXK

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 to projectEndpoint.
  • core/src/host/store.js:598-611 — implements it and delegates the policy to changeRole in project-board.js.
  • core/src/host/authz.js:60-77 — the Project rows of TASK_ENDPOINTS list projects, project-create, project-read, project-bind, project-of, project-board and project-memory, project-memory-write, project-delete, project-assistant-owner. project-role is 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.

验收(红先)

  1. Red first on base: a signed-in actor with a session asks rt.authorize(actor, 'project-role', body) → today bot/not-found / Unknown endpoint project-role; after the fix it is not that code.
  2. callAs('project-role', { id, role: 'member' }, token) for a maintainer of that Project → ok, and the next projects read shows role: 'member' (the write actually lands).
  3. A maintainer or plain member targeting another member (memberId) → not-owner, and roles byte-identical to before the call. (An Owner re-roling another member is allowed today by changeRole and must keep working; that policy is Projects 导航与项目角色:点项目直达看板,右键切 Owner/Maintainer/Member #1828's, not this issue's.)
  4. No actor → bot/unauthorized, unchanged.
  5. node --test test/projects-nav.test.js test/project-roles.test.js test/project-board.test.js green without edits; full npm run verify exit 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 copy patches/ds-bot/files/src/host/authz.js (authz.js is a FlyBot-added file stored in files/, so node scripts/ds-bot-patches.mjs check must pass with the two byte-identical — no patch hunk changes).
  • One test file: core/test/project-roles.test.js or a new core/test/project-role-authz.test.js.
  • No client change, no i18n.js, no client.js, no 0008.

查重

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

  1. added a commit that references this issue on Oct 30, 2026
    d0be5d5
  2. Birfy commented on Oct 30, 2026

    @Birfy
    Collaborator

    Written-by: Chief

    状态补记:agent-pr。本单已有开放 PR #1837(dev/4-p245-project-role-authz,tip d0be5d5e,正文 Fixes #1836),此前本单没有任何状态标签。CI、入队与合并由开该 PR 的那条线负责,本线不接手。

    读取时间 2026-10-30T16:35Z,来源 api.github.com。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions