Skip to content

attachments: a member who uploaded an attachment cannot withdraw it (delete own attachment) after the member grant of #32754 #33010

Description

@objectstack-fleet

domain:server#4 · os-sales · session_01L6bhgWRcTEB3toGxnWvuvX

Out of scope of #32754 by its ruling (6837170004, letter B): the storage service's member grant hands out read and create on the attachment object only. A member who attached the wrong file to a record they can edit cannot remove it; only an administrator can. Filed by the seat as the ruling asked. p2, queued, not dispatched.

Filing gate: ② a ruling routing. class: a · type: Feature gap · Suggested-grade: p2 · lane: domain:server.

Do

  • Decide (needs-user-decision if it moves the permission boundary) whether the uploader may delete their own attachment, under which record access (edit on the parent, or own row only), and through which grant (the storage service's own contribution or the app's member set).
  • Then implement and pin: the uploader removes their own attachment; another member cannot; an administrator still can; one ablation per pin.

Reader who acts: packages/services/service-storage/src/attachment-member-grant.ts and the attachment write rule beside it (after PR #32932 lands).


Generated by Claude Code

Activity

  1. added
    pm:queueReady for the PM dispatch loop
    domain:serverDomain lane — seat card indexed by label:pm:seat
    on Nov 13, 2026
  2. objectstack-fleet commented on Nov 13, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · hotlong · session_01Q4EjjMnyLqJdzuktEmRPXH

    Path: none

    Triage: first-touch audit (pre-labeled card) · p2 confirmed · 2026-11-13T07:56Z

    ⛔ Not a claim; the claim (if any) is unchanged.


    Generated by Claude Code

  3. objectstack-fleet commented on Nov 14, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#5 · os-elon-musk · session_016WV4czXwx6JtQPvacrzzUw

    Ruled · maintainer · 2026-11-14T15:05Z

    Maintainer, verbatim (project thread, 2026-11-14, answering the seat's recommendation list): 「以上都同意」.

    Ruling: a member may delete an attachment they uploaded themselves (own uploads only; no wider delete bit on the member grant). Area A3 builds it; the ADR-0090 D5 text that says the member grant has no delete bit gets a matching sentence in the same PR or a docs PR beside it.


    Generated by Claude Code

  4. objectstack-fleet commented on Nov 14, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#5 · os-elon-musk · session_016WV4d1D3AzXvEhBbz79Pmi

    Claim: area-lease pilot #33059 · area A3 · 2026-11-14T16:20Z
    Session: session_016WV4d1D3AzXvEhBbz79Pmi (area thread A3, os-dev executor)
    Account: os-elon-musk
    Branch: claude/area-A3-33010
    Ruling: comment 6879388034 (a member may delete an attachment they uploaded themselves; own uploads only).
    File surface: packages/services/service-storage/src/attachment-member-grant.ts, the attachment write/delete rule beside it, their tests, root .changeset/.

  5. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 14, 2026
  6. objectstack-fleet commented on Nov 14, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#5 · os-elon-musk · session_016WV4d1D3AzXvEhBbz79Pmi

    Dev report · PR #33322 · head e5aa3112bdbf29d0cef2c5d8c28b8d6ad6758bd7

    Per ruling 6879388034: a member removes an attachment they uploaded, and only their own. The member grant storage_attachment_member is unchanged (read + create only); the removal is a new own-row door, DELETE /api/v1/attachments/:id (core's registerOwnRowDeleteRoute, owner column sys_attachment.uploaded_by). The row is read as the caller, so every attachment read rule still applies; only the uploader is admitted; the row is removed under a system context recorded against the caller, so the file is released.

    • Premise: on origin/main 6a28a271 with the plugin file at base, all 5 integration pins red (no route DELETE /api/v1/attachments/:id).
    • Pins (dogfood, real stack): uploader removes own → 200, row gone; CONTROL the data door still refuses the uploader 403 and explain reports delete refused; another member who can edit the record → 403 on both doors, row stays; administrator → 403 on the door, deletes through the data door. Storage-level: unreadable row → 404 like an unknown id; anonymous → 401; route mounted once.
    • Ablation (mount call removed): storage pins Tests 5 failed | 3 passed (8); dogfood Tests 4 failed | 21 passed (25) (uploader 404 ENDPOINT_NOT_FOUND vs 200); restored, git diff HEAD empty, 8/8 and 25/25 again.
    • Suites: service-storage Tests 1641 passed | 1 skipped; dependents (runtime 10675, organizations, verify, client, mcp, http-conformance, service-mailbox, service-print, plugin-dev, hono, cloud-connection, downstream-contract, cli unit tier) all exit 0; dogfood attachment/storage set 118 passed | 1 skipped.
    • Gates: 123 of 126 derived families run (3 not measured, missing prerequisites unrelated to this diff); check:route-envelope passes with the new module declared. CI on this head: 59 success, 9 skipped, none failed.
    • Declarations: Clause-②: yes (widening), Metadata-protocol: none, patch.
    • Not in this PR: the Console attachments panel still shows delete only to a delete-grant holder (UI half); the cloud host door mountStorageRoutes does not carry the removal door; no SDK method yet (the ledger's one gap row). The ADR-0090 D5 matching sentence comes as a separate docs PR.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

domain:serverDomain lane — seat card indexed by label:pm:seatlease:A3pm:dispatchedDispatched to a dev agent by /pm-dispatchpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions