You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
files: an authorization gap in the file-reference lifecycle, within one organization (detail withheld) #25692
Filing gate ①, the "may leak data" exception, on the maintainer's direct word. Found by the os-dev of the folded #25622 + #25572 dispatch (PR #25682), measured in the same seam that PR fixes. 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 and fix it).
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 in the file-reference lifecycle (ADR-0104 D3, packages/services/service-storage), within one organization. PR #25682 closes the anonymous door and the cross-organization half of the same seam; this card is the remaining same-organization half. ADR-0104 promises one file, one owning record and one access rule.
Business reason: any deployment whose private records hold files (contracts, IDs, HR attachments) relies on that one access rule holding for every member of the organization. Not fixing it leaves ADR-0104's stated worst case wrong.
Reader who acts: after triage, the domain:server lane (packages/services/service-storage, the file-reference lifecycle), sized M by the measuring dev; it needs an ADR-0104 D3 amendment, which is the maintainer's.
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.
⛔ Not a claim, ⛔ not a dispatch.
⛔ Nothing about the mechanism goes on this card (#9387).
p1: measured, and inside one organization, on the access rule ADR-0104 promises for every stored file.
Route:domain:server (packages/services/service-storage), M. The dev gets the detail from the filing seat's session (session_01JVTd3PprStGa26aez5omLB), as the maintainer chose 「立卡修复」. The ADR-0104 D3 amendment is Tier H: a separate docs PR that the maintainer merges.
Claim: PM loop round 1 · card thread · 2026-10-26T03:42Z
Session: session_016DTRymn12to8YSGMcTzS7h (the card thread, mode:thread; the seat writes this claim for it: seat session session_01TFnDdepdwyDJeM2kJ4GtMy)
Account: os-elon-musk (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/project-thread-n8sx5h (platform-assigned to the card thread; a thread can push only its assigned branch, a measured platform exception to claude/issue-<n>-<slug>)
Worktree: objectstack-issue-25692
Domain: domain:server
Seat: domain:server#2 (seat post #20966; 由 os-elon-musk 账户的项目负责)
File surface: packages/services/service-storage/src/file-reference-lifecycle.ts (the claim path; read on origin/maincb0a2fcf), its tests, one patch changeset for @objectstack/service-storage. The ADR-0104 D3 amendment, if owed, is a separate Tier H docs PR the maintainer merges; ⛔ not in this PR. Stop on a breach and explain it in the report.
Disclosure: mechanism only, per triage 6386999094 and the lane charter. ⛔ No reproduction steps on this card, the PR, commits, the changeset or test titles; detail travels only to the seat thread. The filing seat's session (session_01JVTd3PprStGa26aez5omLB) is on another account and unreachable from this seat; the thread re-measures from PR #25682 and ADR-0104.
Container & model: M, mode:thread, model: default tier (dispatch-gates --tier on this surface: "no path-derived mandate"), effort: xhigh (p1, security); the narrowing owes a CONTRACT_REVIEW_TIER review before the queue
Clause-②: no
Metadata-protocol: none
Basis for the Clause-② line: a narrowing. A same-organization access the ADR-0104 rule does not grant is refused; nothing that was refused becomes accepted. The PR body and changeset carry Clause-②: no (narrowing) as AGENTS.md's arm spells it. Every negative pin is ablated (the refused behaviour put back, the pin goes red, output reported, restored), per the lane charter.
Responsibility: service-storage's file-reference lifecycle produces the risk | no platform path covers it: PR #25682 closed the anonymous door and the cross-organization half, not the same-organization one | reached by members of one organization on any stored file, per the card's measurement
Thread-read: 6386999094
Premise: holds (the thread has located a same-organization gap in the claim path on current main; it re-measures before any fix)
Writes: PR only through the relay pr_create; comments, labels and bodies only through the relay write tools (post-stamped.mjs, label-write.mjs, fleet-write/dispatch.mjs). ⛔ No GitHub MCP write tool. Report both counts (writes, mcp_calls).
Serial constraints cleared: #25694 (p2, security, same file) is queued after this card and stays unclaimed until it lands. No open PR names file-reference-lifecycle.ts.
Resume-from: none
File surface adds, both in @objectstack/service-storage:
packages/services/service-storage/src/storage-service-plugin.ts: the download door's existing read judgement is extracted into one function that the door and the file-reference lifecycle both call, wired into installFileReferenceHooks. One predicate for one file, ⛔ not a second one in file-reference-lifecycle.ts.
packages/services/service-storage/src/attachment-access-hooks.ts: export the existing callerContext (one keyword and a doc line), so the lifecycle reads the writer's context the same way the attach gates do.
The answer shape follows PR #25682's precedent on the same seam. The PR body names it as the precedent it follows, and the contract-tier review judges it. Disclosure stands: mechanism only on GitHub. Every other line of the claim stands.
os-dev-report
{
"issue": 25692,
"status": "done",
"branch": "claude/project-thread-n8sx5h",
"pr": "#25951",
"session": "session_016DTRymn12to8YSGMcTzS7h",
"premise_still_valid": true,
"summary": "The file-reference claim path (ADR-0104 D3 wave 2 claim and copy-on-claim) now asks the download door's own read verdict, under the write's caller context, before it claims or copies a referenced file. The door's verdict body moved into judgeFileRead, which the door and the claim path both call, so one file has one access rule. A file the caller may not read gets the quiet answer of the #25682 precedent: the id is kept as written, nothing is claimed or copied, and constraint verdicts no longer run ahead of the read check. System and context-less writes are unchanged, and an authorization-store outage fails the write with its declared envelope.",
"tests": "service-storage: file-reference-lifecycle.test.ts with 15 new cases (stand-in verdict) and the new file-reference-read-verdict.integration.test.ts with 11 cases (real ObjectQL, SqlDriver and StorageServicePlugin; the door's 403/200 and the claim path's kept/copied/claimed outcome agree per file): 77/77. Package suite: Test Files 65 passed (65), Tests 1179 passed (1179), typecheck exit 0. Ablations A-F through scripts/ablation-replace.mjs, against src modules imported relatively by both test files. Each leg: anchor 1 -> 0, blob changed, restored blob == HEAD, git diff HEAD empty. A (verdict ignored) 15 red, all allow controls green; B (outage swallowed) 2 red; C (plugin binding admits all) 5 red; D (outage re-raise removed) 1 red; E (own-copy stash ignored) 1 red; F (system write asked) 1 red.",
"gates": "Head 4f3c21e after a full pnpm build (119/119). dispatch-gates --commands derived 102 gates; all 102 exit 0; --ran: 102 derived, 102 run, 0 NOT-MEASURED, 0 UNRUN. pnpm lint (eslint . --no-inline-config) exit 0, recorded outside the derivation. check-commit-card-trailers over origin/main..HEAD: 6 commits pass. CI check-runs on the PR are not cited yet; the thread watches them.",
"dogfood_battery": "4f3c21e5 · VERDICT command-exit 1, held the lock 1280s · Test Files 295 passed, 1 failed, 3 skipped (299) · Tests 2522 passed, 1 failed, 18 skipped (2541) · the failure: packaged-flow-write-door-parity.dogfood.test.ts 'a flow no package ships is still created, updated and removed through the same door' timed out at 5000ms while 102 gates ran on the same 4 cores; re-run alone under the lock: VERDICT command-exit 0, 5/5 passed; the test touches no file field.",
"mcp_calls": "8 — mcp__github__issue_read x7, mcp__github__pull_request_read x1; reads only, no write tool",
"api_writes": "relay dispatches only (POST /repos/objectstack-ai/objectstack/dispatches, run as objectstack-fleet): pr_create -> POST /pulls and POST /issues/25951/assignees; pr_request_reviewers -> POST /pulls/25951/requested_reviewers; comment -> POST /issues/25692/comments (this report). git push is not a REST write.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: Server lane seat · three acceptance-note candidates on the claim path's edges were handed to the seat thread, kept off GitHub under the card's disclosure rule · noted, not filed",
"carrier: Server lane seat · #25694 (same file, queued next) should be re-read against this head before dispatch · noted, not filed"
]
}
Activity
objectstack-fleet commentedon Oct 24, 2026
Triage: first grade —
bug·security·priority:p1·domain:server·area:files·pm:queue· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-24T16:58Z⛔ Not a claim, ⛔ not a dispatch.
⛔ Nothing about the mechanism goes on this card (#9387).
domain:server(packages/services/service-storage), M. The dev gets the detail from the filing seat's session (session_01JVTd3PprStGa26aez5omLB), as the maintainer chose 「立卡修复」. The ADR-0104 D3 amendment is Tier H: a separate docs PR that the maintainer merges.Generated by Claude Code
objectstack-fleet commentedon Oct 26, 2026
Claim: PM loop round 1 · card thread · 2026-10-26T03:42Z
Session:
session_016DTRymn12to8YSGMcTzS7h(the card thread, mode:thread; the seat writes this claim for it: seat sessionsession_01TFnDdepdwyDJeM2kJ4GtMy)Account:
os-elon-musk(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/project-thread-n8sx5h(platform-assigned to the card thread; a thread can push only its assigned branch, a measured platform exception toclaude/issue-<n>-<slug>)Worktree:
objectstack-issue-25692Domain:
domain:serverSeat:
domain:server#2(seat post #20966; 由 os-elon-musk 账户的项目负责)File surface:
packages/services/service-storage/src/file-reference-lifecycle.ts(the claim path; read onorigin/maincb0a2fcf), its tests, onepatchchangeset for@objectstack/service-storage. The ADR-0104 D3 amendment, if owed, is a separate Tier H docs PR the maintainer merges; ⛔ not in this PR. Stop on a breach and explain it in the report.Disclosure: mechanism only, per triage 6386999094 and the lane charter. ⛔ No reproduction steps on this card, the PR, commits, the changeset or test titles; detail travels only to the seat thread. The filing seat's session (
session_01JVTd3PprStGa26aez5omLB) is on another account and unreachable from this seat; the thread re-measures from PR #25682 and ADR-0104.Container & model:
M,mode:thread,model: default tier (dispatch-gates --tier on this surface: "no path-derived mandate"),effort: xhigh(p1, security); the narrowing owes aCONTRACT_REVIEW_TIERreview before the queueClause-②: no
Metadata-protocol: none
Basis for the Clause-② line: a narrowing. A same-organization access the ADR-0104 rule does not grant is refused; nothing that was refused becomes accepted. The PR body and changeset carry
Clause-②: no (narrowing)as AGENTS.md's arm spells it. Every negative pin is ablated (the refused behaviour put back, the pin goes red, output reported, restored), per the lane charter.Responsibility:
service-storage's file-reference lifecycle produces the risk | no platform path covers it: PR #25682 closed the anonymous door and the cross-organization half, not the same-organization one | reached by members of one organization on any stored file, per the card's measurementThread-read: 6386999094
Premise: holds (the thread has located a same-organization gap in the claim path on current
main; it re-measures before any fix)Writes: PR only through the relay
pr_create; comments, labels and bodies only through the relay write tools (post-stamped.mjs,label-write.mjs,fleet-write/dispatch.mjs). ⛔ No GitHub MCP write tool. Report both counts (writes,mcp_calls).Serial constraints cleared: #25694 (p2, security, same file) is queued after this card and stays unclaimed until it lands. No open PR names
file-reference-lifecycle.ts.Resume-from: none
Generated by Claude Code
objectstack-fleet commentedon Oct 26, 2026
Claim amendment (file surface) ·
domain:server#2· seat sessionsession_01TFnDdepdwyDJeM2kJ4GtMy· 2026-10-26T03:45Z · amends claim 6407719048, same session, same branchclaude/project-thread-n8sx5h.File surface adds, both in
@objectstack/service-storage:packages/services/service-storage/src/storage-service-plugin.ts: the download door's existing read judgement is extracted into one function that the door and the file-reference lifecycle both call, wired intoinstallFileReferenceHooks. One predicate for one file, ⛔ not a second one infile-reference-lifecycle.ts.packages/services/service-storage/src/attachment-access-hooks.ts: export the existingcallerContext(one keyword and a doc line), so the lifecycle reads the writer's context the same way the attach gates do.The answer shape follows PR #25682's precedent on the same seam. The PR body names it as the precedent it follows, and the contract-tier review judges it. Disclosure stands: mechanism only on GitHub. Every other line of the claim stands.
Generated by Claude Code
objectstack-fleet commentedon Oct 26, 2026
os-dev-report
{
"issue": 25692,
"status": "done",
"branch": "claude/project-thread-n8sx5h",
"pr": "#25951",
"session": "session_016DTRymn12to8YSGMcTzS7h",
"premise_still_valid": true,
"summary": "The file-reference claim path (ADR-0104 D3 wave 2 claim and copy-on-claim) now asks the download door's own read verdict, under the write's caller context, before it claims or copies a referenced file. The door's verdict body moved into judgeFileRead, which the door and the claim path both call, so one file has one access rule. A file the caller may not read gets the quiet answer of the #25682 precedent: the id is kept as written, nothing is claimed or copied, and constraint verdicts no longer run ahead of the read check. System and context-less writes are unchanged, and an authorization-store outage fails the write with its declared envelope.",
"tests": "service-storage: file-reference-lifecycle.test.ts with 15 new cases (stand-in verdict) and the new file-reference-read-verdict.integration.test.ts with 11 cases (real ObjectQL, SqlDriver and StorageServicePlugin; the door's 403/200 and the claim path's kept/copied/claimed outcome agree per file): 77/77. Package suite: Test Files 65 passed (65), Tests 1179 passed (1179), typecheck exit 0. Ablations A-F through scripts/ablation-replace.mjs, against src modules imported relatively by both test files. Each leg: anchor 1 -> 0, blob changed, restored blob == HEAD, git diff HEAD empty. A (verdict ignored) 15 red, all allow controls green; B (outage swallowed) 2 red; C (plugin binding admits all) 5 red; D (outage re-raise removed) 1 red; E (own-copy stash ignored) 1 red; F (system write asked) 1 red.",
"gates": "Head 4f3c21e after a full pnpm build (119/119). dispatch-gates --commands derived 102 gates; all 102 exit 0; --ran: 102 derived, 102 run, 0 NOT-MEASURED, 0 UNRUN. pnpm lint (eslint . --no-inline-config) exit 0, recorded outside the derivation. check-commit-card-trailers over origin/main..HEAD: 6 commits pass. CI check-runs on the PR are not cited yet; the thread watches them.",
"dogfood_battery": "4f3c21e5 · VERDICT command-exit 1, held the lock 1280s · Test Files 295 passed, 1 failed, 3 skipped (299) · Tests 2522 passed, 1 failed, 18 skipped (2541) · the failure: packaged-flow-write-door-parity.dogfood.test.ts 'a flow no package ships is still created, updated and removed through the same door' timed out at 5000ms while 102 gates ran on the same 4 cores; re-run alone under the lock: VERDICT command-exit 0, 5/5 passed; the test touches no file field.",
"mcp_calls": "8 — mcp__github__issue_read x7, mcp__github__pull_request_read x1; reads only, no write tool",
"api_writes": "relay dispatches only (POST /repos/objectstack-ai/objectstack/dispatches, run as objectstack-fleet): pr_create -> POST /pulls and POST /issues/25951/assignees; pr_request_reviewers -> POST /pulls/25951/requested_reviewers; comment -> POST /issues/25692/comments (this report). git push is not a REST write.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: Server lane seat · three acceptance-note candidates on the claim path's edges were handed to the seat thread, kept off GitHub under the card's disclosure rule · noted, not filed",
"carrier: Server lane seat · #25694 (same file, queued next) should be re-read against this head before dispatch · noted, not filed"
]
}
Generated by Claude Code
objectstack-fleet commentedon Oct 26, 2026
ACCEPT → PR #25951 comment 6408966158 ·
domain:server#2· 2026-10-26T05:30Z · contract review PASS 6408818225Generated by Claude Code