Skip to content

files: an authorization-adjacent gap on a file-serving door (detail withheld pending measurement) #25693

Closed

Description

@objectstack-fleet

Filing gate ①, the "may leak data" exception, on the maintainer's direct word (reach is measured first, not before filing). Found by the os-dev of the folded #25622 + #25572 dispatch (PR #25682), from source reading only, not measured. Filed by domain:server seat 2 (seat post #20966) · sunhaolin · session session_01JVTd3PprStGa26aez5omLB. ⛔ Not a claim. Domain, grade and route are triage's.

The maintainer, in this seat's session, choosing among the seat's options for this finding: 「立卡,先实测再修(推荐)」 (file a card; measure first, then fix).

Disclosure: the mechanism and the path are withheld from every public surface under the security-family discipline. The seat holds them and has handed them to the maintainer in the seat's session; the dev who takes this card gets them from the seat.

What can be said: the gap sits on a file-serving door of packages/services/service-storage. It is unmeasured: the first step is a measurement through the public door on a fresh boot, and the result decides whether a fix is owed.

Business reason: every multi-organization deployment keeps one organization's files away from another's; if the measurement confirms the gap, that guarantee does not hold for part of the stored files.

Reader who acts: after triage, the domain:server lane (packages/services/service-storage), measurement first.

Dedupe: the titles of every objectstack-ai/objectstack issue updated since 2026-10-10, open and closed (1,229 read), matched on claim|copy-on|file id|download|unowned|orphan|sys_file|file reference|guest.*file|anonymous.*file|storage.*(auth|scope)|file.*organi. 21 title hits, none of them this gap (the nearest are #25572 and #25650, ruling C’s two halves, and #23306, a closed storage verb). New.


Generated by Claude Code

Activity

  1. added
    area:filesFiles — upload, download, signed URLs, access derived from the parent record
    bugSomething isn't working
    domain:serverDomain lane — seat card indexed by label:pm:seat
    priority:p1High: required for production / M2
    on Oct 24, 2026
  2. objectstack-fleet commented on Oct 24, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade — bug · security · priority:p1 · domain:server · area:files · pm:queue · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-24T16:59Z

    ⛔ Not a claim, ⛔ not a dispatch.
    ⛔ Nothing about the mechanism goes on this card (#9387).

    • p1, for the measurement: if it is confirmed, files cross organizations. The first step is the measurement the maintainer chose (「立卡,先实测再修」), through the public door on a fresh boot. The result is posted here without a reproduction. If it does not reproduce, the card closes.
    • The detail comes from the filing seat's session (session_01JVTd3PprStGa26aez5omLB).

    Generated by Claude Code

  3. objectstack-fleet commented on Oct 24, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1
    Session: session_01JVTd3PprStGa26aez5omLB
    Account: sunhaolin (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-25693-file-door-measure
    Worktree: objectstack-issue-25693
    Domain: domain:server
    Seat: domain:server#2
    File surface: packages/services/service-storage/src/** (the file-serving door named on this card), its tests, one changeset if a fix is owed. ⛔ Not file-reference-lifecycle.ts (PR #25682 is open there) (stop on breach; explain in the report)
    Container & model: M, security, mode:subagent, model: TIER_DEFAULT (dispatch-gates --tier: "no path-derived mandate … the tier stays the PM's per-card judgment call"), effort: xhigh
    Clause-②: no
    Metadata-protocol: none
    Responsibility: withheld (security family); the seat holds it and hands it to the dev off GitHub
    Thread-read: 6387006016
    Serial constraints cleared: no open PR touches the file-serving door's module (every open PR's file list read this fire). PR #25682 (#25622, area:files) is open on file-reference-lifecycle.ts; this card stays out of that file.
    Premise: the maintainer's word in this seat's session, 「立卡,先实测再修」: measure first through the public door on a fresh boot; a result goes on this card without a reproduction; no reproduction ⇒ the card closes.


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 24, 2026

    @objectstack-fleet
    ContributorAuthor

    measured: reproduces · head b77bb37eb2


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 24, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 25693,
      "status": "done",
      "branch": "claude/issue-25693-file-door-measure",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/25704",
      "session": "session_01JVTd3PprStGa26aez5omLB — a subagent run, so the parent's harness-stamped id; claim 6387155589 names it and this branch",
      "premise_still_valid": true,
      "summary": "Measured first, as the maintainer's word asked; the one-line result is comment 6387385669. Fixed: an unclaimed file is served only within its organization, as every other organization-scoped row is read. The organization wall's verdict for the posture in force and the driver's tenant term decide; the service-storage package writes no organization comparison of its own. The refusal is the door's existing 403 FILE_DOWNLOAD_DENIED, and no error code is added. Re-measured after the fix: the rule holds. The measurement detail is routed to the seat off GitHub.",
      "tests": "Head 34c018bbad, under the shared lock. service-storage vitest: Test Files 63 passed (63), Tests 1147 passed (1147). New unclaimed-file-organization-scope.test.ts: 15 passed (isolated, group and single postures; public_read and attached controls). typecheck: exit 0, and the test layer includes both test files (--listFiles). Ablation leg 1 (organization scoping removed): 10 red, 54 green, restored with blob b34c59e7fdcb equal to HEAD. Leg 2 (the wall's deny exit removed): exactly 2 red, 13 green, restored with blob 1b929b2e9d08 equal to HEAD. Both legs went through scripts/ablation-replace.mjs; there is no dist/ in either path.",
      "gates": "Local: all 74 commands from `dispatch-gates --commands --repo objectstack-ai/objectstack` exit 0. check:type-check-debt's first run was NOT MEASURED (exit 3, lock held by this run's own dogfood) and its rerun under the lock exited 0. check:dts-closure, check:dual-build-cjs-loads and check:lean-entry-closure were rerun after the service-storage rebuild, each exit 0. `--ran` with coded lines: 74 derived, 74 run, 0 NOT-MEASURED, 0 UNRUN (a derived zero). eslint --no-inline-config over packages/services/service-storage/src: exit 0. CI at 34c018bbad, read once: Build Core, Test Core 1-6, Type Check x4, Lint x8, Check Changeset, Governed Surface Queue Guard and Dogfood Regression Gate in_progress; Check PR Size, Check Documentation Links and the four claim/single-writer/part-of guards success; 7 skipped.",
      "dogfood_battery": "34c018bbad · os-verify-lock VERDICT command-exit 0 · Test Files 295 passed | 3 skipped (298) · Tests 2520 passed | 18 skipped (2538) · no failures",
      "mcp_calls": "0",
      "api_writes": "4 relay strokes (fleet-write; each is one POST /repos/objectstack-ai/objectstack/dispatches): POST /issues/25693/comments (the measured line); POST /pulls + POST /issues/25704/assignees (pr_create, draft, assignee sunhaolin); POST /issues/25693/comments (this report)",
      "line_budget": "n/a — no line-ratcheted or governed file touched",
      "files_changed": [".changeset/25693-unclaimed-file-organization-scope.md", "packages/services/service-storage/src/storage-routes.ts", "packages/services/service-storage/src/storage-service-plugin.ts", "packages/services/service-storage/src/storage-routes.test.ts", "packages/services/service-storage/src/unclaimed-file-organization-scope.test.ts"],
      "deviations": "Routed to the seat off GitHub.",
      "open_questions": ["Routed to the seat off GitHub (uploader-only vs organization scope for an unclaimed upload)."],
      "out_of_scope_findings": ["carrier: the seat (domain:server seat 2), off GitHub · noted, not filed."]
    }

    Generated by Claude Code

  6. objectstack-fleet commented on Oct 25, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR #25704 → 3b8ea15c2 · domain:server seat 2 · sunhaolin · session_01JVTd3PprStGa26aez5omLB · 2026-10-25T03:55Z

    reading result
    PR #25704 object merged: true, merge commit 3b8ea15c21caad40686ccb811e2b0b4bd4fef9ca, merged 2026-10-25T03:53:56Z through the merge queue
    origin/main 3b8ea15c2 is origin/main's tip, single parent
    queue branch no gh-readonly-queue/main/* head for PR 25704 remains
    • State: closed completed by Fixes #25693 on merge. pm:dispatched stripped in this act.
    • Delivered: the rule this card asked for holds: an unclaimed file is served only within its organization. Declared Clause-②: no (narrowing), patch, BREAKING; the CONTRACT_REVIEW_TIER review was the director seat's (record 6388650590, PASS).
    • Open question carried to the maintainer off GitHub: organization-scoped plus uploader (as shipped) versus uploader only until claimed.
    • Dev: a local subagent; no cloud session to archive.

    Generated by Claude Code

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

Metadata

Metadata

Assignees

Labels

area:filesFiles — upload, download, signed URLs, access derived from the parent recordbugSomething isn't workingdomain:serverDomain lane — seat card indexed by label:pm:seatpriority:p1High: required for production / M2security

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions