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
[Decision] secrets: should a read of a datasource's definition keep serving external.credentialsRef to every reader that can read the definition? (item 3 of #27818, the maintainer's) #27884
Ruled: 6545628488 · letter A · 2026-10-31T15:53Z
Ruling-ref: 6545628488
Ruled: 6522945866 · letter B · 2026-10-30T12:39Z
Ruling-ref: 6522945866
Filing gate: ③ maintainer decision split out of a card that is closing (security, rule level only).
From:#27818 item 3. Triage (6512259730) classed it as a security boundary and raised it with the maintainer directly. PR #27860 closes #27818's items 1 and 2, so this card keeps item 3 open. Rule-level text only; mechanism goes to the maintainer off GitHub.
The question
Today a read of a datasource's definition through the metadata read doors serves its external.credentialsRef to every caller that can read the definition. After #27762 and #27818 a reference can no longer be written through any non-system door unless it is the row's own. Should the read doors still serve it?
Option A, keep serving it. The GET → edit → PUT round trip keeps working unchanged, and the write doors hold the rule.
Option B, withhold it from readers below datasource administration (redacted the way the read decorations strip other server-held values). The save door then treats an omitted key as "keep the stored reference" for those callers.
Business reason
The reference is a handle to a stored secret. The write doors are now closed, so this is defence in depth: who needs to see it at all?
Reader: the maintainer. No seat acts on it until it carries a Ruled: line.
⛔ Not a claim. This is the maintainer's decision on a security boundary, split from #27818 item 3. Rule-level text only.
Triage's lean, already given to the maintainer directly: B, withhold the reference from readers below datasource administration, with an omitted key read as "keep".
Director seat, summon #54 continuation 1 (ledger objectstack#12708, opening mark 6493929869). Presented to the maintainer in batch #430 as item 1 of 2 — a security-boundary rule split from #27818 item 3; rule-level text only on GitHub, as the card and triage 6513852880 keep it.
Seat increment (re-read at origin/mainded67bfb, 2026-10-30T03:07Z):
Seat's letter: B — withhold external.credentialsRef from readers below datasource administration through the existing read-decoration seam; the save door treats an omitted key from such a caller as "keep the stored reference" (and still refuses any reference that is not the row's own). Not A: it serves a secret handle to every reader of the definition after the write side was closed to them.
Workload of B: domain:server · 1 PR · S (one redaction arm, one save-door reading, two pins: a non-admin read lacks the key; a non-admin PUT without the key keeps the stored reference) · Clause-②: no (narrowing) of the served read shape for non-admin callers ⇒ one contract-review-tier review before the queue · Metadata-protocol: none.
After the ruling: triage grades into pm:queue (domain:server, area:auth, p1) with Ruling-ref:; mechanism details stay off GitHub per the security discipline.
Ruling: batch #430 item 1 · letter B · maintainer 「27884 B」 2026-10-30T12:33Z
Director seat, summon #54 continuation 1 (ledger objectstack#12708, opening mark 6493929869, brief 6513971173). The maintainer answered in the summon chat, verbatim: 「27884 B」.
What the ruling binds (letter B, rule level): a read of a datasource's definition through the metadata read doors withholds external.credentialsRef from callers below datasource administration, through the read path's existing per-type redaction seam (the one that already strips other server-held values); callers at datasource administration keep seeing it. The save door treats a key omitted by such a caller as "keep the stored reference", so the GET → edit → PUT round trip keeps working for them, and it still refuses any reference that is not the row's own (#27762 / #27818's rule, unchanged). Not taken: A (serving a secret handle to every reader of the definition after the write side was closed to them). Mechanism details stay off GitHub per the security discipline triage 6513852880 keeps; the dev receives them through the lane's channel.
Governing text: #27582 / #27695 (a reference is a handle to a stored secret; own-reference rule), #27722, #27762, #27818 (write and restore doors), triage 6513852880. Premises re-read at origin/mainded67bfb (brief 6513971173).
Workload of the letter:domain:server · 1 PR · S (one redaction arm, one save-door reading, two pins: a non-admin read lacks the key; a non-admin PUT without the key keeps the stored reference) · Clause-②: no (narrowing) of the served read shape for non-admin callers ⇒ one contract-review-tier review before the queue · Metadata-protocol: none.
Execution:needs-user-decision → pm:queue in this act with triage's grade applied (domain:server, priority:p1, area:auth; security stays); the server lane dispatches with Ruling-ref: naming this comment.
os-decision-facets
① 长远:写侧已关闭的值不被永远写不了它的人读回;复用既有脱敏缝,不加第二套机制
② 拉动:本周连续裁定的密钥硬化线(#27582 → #27722 → #27762 → #27818)的读侧收口
③ 防错:密钥把手是侦察信息,隐去是结构性的;「省略即保留」让编辑数据源的作者不会误清空引用
④ 不扩散:不加键不加门禁;一条脱敏臂加一条保存门读法
Claim: PM loop round 1 · card thread · 2026-10-31T03:04Z
Session: session_0186vfjHHMsRXC9EUT9hTFMo (the seat); the card thread is session_01FEkQ5p7Ny2odJ1fcUVtGFS
Account: os-project-manager (the seat's linked user; the card's assignee)
Branch: claude/project-thread-876a4y (the card thread's harness-pinned branch; it names no issue, so this claim is the identity record)
Worktree: the card thread's own container checkout
Domain: domain:server
Seat: domain:server#2
Ruling-ref: 6522945866 (letter B, the maintainer's 「27884 B」): withhold external.credentialsRef from callers below datasource administration through the existing per-type redaction seam; an omitted key from such a caller keeps the stored reference; the own-reference rule is unchanged. Triage 6513852880. Mechanism details stay off GitHub; the dev has them in its order.
File surface: packages/metadata-protocol/src/metadata-redaction.ts (or a redactor registration in the package owning datasource administration, per the seam), packages/metadata-protocol/src/protocol-datasource-credentials-ref.ts (the omitted-key reading), tests, and changesets. ⛔ No second redaction mechanism, and no new permission name.
Container & model: S, mode:thread, model: opus (--tier names no path mandate: PM's call, default; the contract review runs at CONTRACT_REVIEW_TIER), effort: xhigh (p1, security)
Clause-②: no (narrowing)
Metadata-protocol: none
Responsibility: the code is the metadata read doors' datasource projection (metadata-protocol) · the platform path that covers it is the #8154 per-type redaction seam, which has no datasource arm today · reached by any caller who can read a datasource definition below datasource administration
Thread-read: 6522945866
Premise: holds (read 2026-10-31T03:04Z at origin/main91fa06df8: the only registered metadata type redactor is the flow one; protocol-datasource-credentials-ref.ts leaves a body naming no reference unjudged); the dev re-measures first
Serial constraints cleared: no open PR touches metadata-redaction.ts or protocol-datasource-credentials-ref.ts at this read (PR #28171 is plugin-audit's own redaction file); sibling claim #28238 is disjoint in the same package
Resume-from: none — fresh from origin/main
State: pm:queue → pm:dispatched, assigned to os-project-manager (label write at 02:59Z), recorded by this claim.
domain:server#2 · os-project-manager · session_01FEkQ5p7Ny2odJ1fcUVtGFS
os-dev-report
{
"issue": 27884,
"status": "needs_decision",
"branch": "claude/project-thread-876a4y",
"pr": null,
"session": "session_01FEkQ5p7Ny2odJ1fcUVtGFS",
"premise_still_valid": false,
"summary": "Measured live at origin/main 69ce01d (full build, showcase dev server, an admin plus two users below datasource administration). (1) The metadata read doors already refuse every caller below datasource administration outright, before any store read, on both transports; so on those doors no caller exists from whom to withhold the reference, and the ruling's read half is already met there, more strongly. (2) No save door is reachable by such a caller (the metadata save door refuses them for this type; the other door refuses every write on the stored table), so the "omitted key = keep" reading has no caller it can apply to and its pin cannot be built through a real door. (3) The real exposure is elsewhere: one non-metadata read exit of the stored-definition family serves the WHOLE stored datasource definition to a distributed built-in permission set below datasource administration, the credentials reference AND the connection configuration (host, port, database, user name), which the datasource family and the metadata type gate both declare to be datasource-administration-only. (4) The per-type redaction seam cannot see the caller (its redactor and its consumers take no reader), though at that one exit the caller is in hand one frame up. Datasource administration is the existing capability the admin door requires; no new name is needed. No code was written: the shape of the fix is a choice between two architectures (a door admission versus a caller-aware redaction arm), and the measured leak is wider than the ruled key. Mechanism, door table and probe live in the lane file pm-orders/server/27884-measurement.md, off GitHub.",
"tests": "Live probe, not committed. Admin bound a credential through the datasource admin door, then three readers read the definition through every read door of the family. Admin: the reference is served on the metadata read doors and on the stored-row exit. Each caller below datasource administration: 403 on every metadata read door and on the admin door; 200 with the reference and the connection configuration on one stored-row read exit (also with a narrowed field projection); writes refused on every door (403 / 405). Full table in the lane file. No ablation: no tested behaviour changed.",
"gates": "none run: no diff (needs_decision, no commit, no push). Full pnpm build under the lock for the probe: VERDICT command-exit 0, 695s.",
"dogfood_battery": "n/a, no PR",
"mcp_calls": "3, all reads: issue_read get (#27884), issue_read get_comments x2 (#27884). No MCP writes.",
"api_writes": "1, this os-dev-report comment on #27884 through post-stamped.mjs",
"open_questions": [
{
"status": "needs_decision",
"question": "Ruling B was given on the premise that the metadata read doors serve the reference to readers below datasource administration. Measured, they refuse those readers outright, and the one exit that does reach them serves the whole definition (reference plus connection configuration), not only the reference. Which fix should land?",
"options": [
"A. Door admission (recommended): the stored-row read exit serves a datasource-family definition only to readers holding the capability the metadata type gate already names for that type, the same row applied at the one other exit that serves the same document. Closes the reference and the connection configuration together. Admins see everything as today. No new key, no new permission name, no change to the published redactor type. Event exits of the same rows withhold the body (the subscriber is unknown at publish). The save-door half of B is dropped: no caller reaches it. Size S to M, 1 PR, Clause-2: no (narrowing) for readers below datasource administration. Goes beyond the letter of B (the whole definition, not one key).",
"B. Ruling B literally, caller-aware: the per-type redaction gains an optional reader; the datasource arm withholds the reference from readers without datasource administration; the stored-row exit passes its caller; event exits withhold for everyone. Admins keep the reference everywhere. Adds a parameter to a published spec type and touches three exits. Size M. Leaves the connection configuration served to the same readers, which then needs its own security card.",
"C. Ruling B caller-blind: every stored-row read exit withholds the reference from every reader; admins keep it on the metadata read doors, which only they reach. Size S. Admins lose the reference on the stored-row exit (a deviation from "admins keep seeing it" there), and the connection configuration stays served, needing its own card."
],
"recommendation": "A. Four axes. Business need, measured: no door a reader below datasource administration reaches has a reason to show a datasource definition at all; the admin door and the metadata doors are already admin-only, and the one exit that leaks is a raw stored-row read, not a datasource surface. Long term: one document, one admitted cohort across every door that serves it (the metadata type gate's own rule); B and C patch one key and keep serving the rest of the same class. Preventing AI mistakes: A is structural, the whole definition behind the one capability and the same answer on both doors; B and C leave a partially redacted definition that reads as safe. Startup focus: A adds no key, no permission name, no spec parameter and no CI gate; it reuses an existing row. B adds a published parameter for one key. Trade-off: A departs from the letter of B, so it needs the maintainer's word."
}
],
"out_of_scope_findings": [
"class: b · reach: exception: security (a distributed built-in permission set below datasource administration is served the stored connection configuration of every datasource through a non-metadata read exit; door and probe in the lane file, off GitHub) · evidence: live probe at 69ce01d; the datasource admin door and the metadata type gate both declare this data datasource-administration-only · dedupe words: datasource connection configuration, stored definition read, datasource administration, read cohort, stored metadata row · carrier: this card if option A is ruled; otherwise the seat files a security card"
]
}
Director seat (the maintainer's decisions thread, 2026-10-31). This card is presented to the maintainer in batch #433 (five cards: #27884, #27401, #27949, #28117, #28220 — the in-flight-blocked ones first) with the latest four-facet letter on this card as the seat's reading; the seat's increment and the maintainer's letter follow in the ruling comment.
Ruling: batch #433 item 1 · letter A · maintainer 「同意」 2026-10-31T15:48Z
Director seat (the maintainer's decisions thread). Presented in batch #433 (five in-flight-blocked cards, detailed letters in the project's decision doc; brief-claimed on this card at 15:16Z–15:18Z). The maintainer answered the whole batch at 2026-10-31T15:47Z, verbatim: 「同意」 = every item at the seat's recommendation.
What the ruling binds (letter A, rule level — mechanism stays in the lane's private file): the stored-row read exit that today serves a datasource-family definition to readers below datasource administration admits only readers holding the capability the metadata type gate already names for that type, the same row applied at the one other exit that serves the same document; the event exits of those rows withhold the body. Datasource administrators see everything as today. The save-door half of ruling B (6522945866, "omitted key = keep") is dropped: measured, no such caller reaches a save door. No new key, no new permission name, no change to the published redactor type. The dev's out-of-scope finding (connection configuration served through the same exit) is closed by this card, not a separate one. Not taken: B (literal, caller-aware redaction of one key; leaves the connection configuration served), C (caller-blind redaction; same residue, admins lose the reference at that exit). This supersedes the letter of 6522945866 on the maintainer's word.
Workload of the letter:domain:server · 1 PR · S–M · Clause-②: no (narrowing) for readers below datasource administration ⇒ one contract-review-tier review before the queue · Metadata-protocol: none · precedents #21119 (+831 −4), #21148 (+740 −5).
Execution: server seat 1 (this project) re-dispatches under A with Ruling-ref: naming this comment; needs-user-decision → pm:queue is the dispatching seat's stroke. Analysis read: 6538434026.
Claim: re-dispatch under ruling A · card thread · 2026-10-31T15:58Z
Session: session_01L9qibz3ZUbZ8Qcn1rDw9yc (the seat); the card thread is session_01L9qibwurKjbb54r3yD6yJg
Account: os-tesla (the seat's linked user; the card's assignee)
Branch: claude/project-thread-zvc337 (the card thread's harness-pinned branch; it names no issue, so this claim is the identity record)
Worktree: the card thread's own container checkout
Domain: domain:server
Seat: domain:server#1
Ruling-ref: 6545628488 (letter A, Tesla 「同意」 2026-10-31T15:47Z, batch #433 item 1). It supersedes ruling B 6522945866 and drops its save-door half. Letter 6538434026.
File surface: the stored-row read exit's admission for datasource-family rows, the one other exit that serves the same document, the event exits' body filter for those rows, their tests, and a .changeset/27884-*.md. ⛔ No packages/spec, no new key or permission name; the hot protocol.ts only after the seat clears it.
Container & model: S–M, mode:thread, model: opus, effort high; contract-review tier before the queue
Clause-②: no (narrowing for readers below datasource administration)
Metadata-protocol: none
Thread-read: 6545628488
Premise: the dev re-measures the leak on origin/main before any code. The mechanism stays in the lane's project files; public text stays at rule level.
Serial constraints cleared: no in-flight PR of this seat touches the data-plane admission or realtime filter
Resume-from: none (fresh from origin/main630b4078d; the earlier claim 6538173894's branch carried nothing)
Order: /mnt/project-files/server-seat-1/r2026-10-31/dispatch-27884.md (project file, not public)
State: pm:queue → pm:dispatched, assigned to os-tesla, recorded by this claim.
{
"issue": 27884,
"status": "pr_open_draft",
"branch": "claude/project-thread-zvc337",
"pr": 28465,
"head": "757ff0c5",
"session": "session_01L9qibwurKjbb54r3yD6yJg",
"premise_still_valid": true,
"summary": "Ruling A: a stored-row read exit admits only datasource administrators. The /meta type gate's type-to-capability row now lives once in @objectstack/metadata-core and is applied by the engine to caller-context reads of the stored-metadata tables; events of gated rows carry no body. Admins and system reads unchanged; no new rule, permission name or key; no packages/spec or protocol.ts change.",
"tests": {
"objectql": "506 files / 9836 tests passed",
"metadata-core+rest": "21 files / 875 tests passed",
"typecheck": "metadata-core, objectql, rest exit 0",
"eslint_scoped": "exit 0",
"ablations": "5, each red then restored byte-identical"
},
"gates": "94 derived, 94 run, all exit 0 (dispatch-gates --ran: 0 NOT-MEASURED, 0 UNRUN); changeset gates re-run on the final head, exit 0",
"dogfood_battery": "full battery: 361 files passed, 3 skipped, 1 failed (a 5000 ms timeout in automation-authoring-doors-durable under shared load); that file alone on the same head 7/7 passed",
"mcp_calls": {
"reads": "issue_read, pull_request_read",
"writes": 0
},
"api_writes": {
"relay": 2,
"detail": "pr_create #28465 and this comment"
},
"open_questions": [
"Contract review of the narrowing arm is owed (seat)."
],
"out_of_scope_findings": []
}
git grep -c STORED_METADATA_TYPE_READ_CAPABILITIES in metadata-core/src/stored-metadata-type-read-admission.ts on origin/main
present (4)
Landed: under ruling A (6545628488), a datasource definition's stored row is served only to datasource administrators, whichever exit reads it. The type-to-capability table exists once, in @objectstack/metadata-core. Events of a gated row carry no body. Capability holders and system reads are unchanged. Patch changesets ship for metadata-core, objectql and rest. The card closed via Fixes.
Queue: the first queue run was dequeued on a Live E2E UI timeout. The thread could not reproduce it, on the merged tree or on main alone. The seat re-queued the same head once, and it merged.
Activity
objectstack-fleet commentedon Oct 30, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: 真挡得住的权限 | none | P②
Triage: p1 ·
domain:server·area:auth· decision · 2026-10-30T02:58Z⛔ Not a claim. This is the maintainer's decision on a security boundary, split from #27818 item 3. Rule-level text only.
Ruled:line appears.Generated by Claude Code
objectstack-fleet commentedon Oct 30, 2026
director#1 · os-bill · session_01Utp6CbQLcy8yg6vhJVXXi8
Brief-claimed-by: session_01Utp6CbQLcy8yg6vhJVXXi8 · batch #430 · 2026-10-30T03:07Z
Director seat, summon #54 continuation 1 (ledger objectstack#12708, opening mark 6493929869). Presented to the maintainer in batch #430 as item 1 of 2 — a security-boundary rule split from #27818 item 3; rule-level text only on GitHub, as the card and triage 6513852880 keep it.
Seat increment (re-read at
origin/mainded67bfb, 2026-10-30T03:07Z):external.credentialsRef(secrets: confirm the metadata save door for a datasource applies the #27582 own-reference rule toexternal.credentialsRef(a third write door beside #27722's two) #27762;protocol-datasource-credentials-ref.ts,protocol.tsL439 / L21293); secrets: hold a datasource's restore doors and already-stored rows to the #27582 own-reference rule forexternal.credentialsRef(the residue of #27762) #27818 (restore doors and stored rows) is closed by PR fix(metadata-protocol)!: a datasource restored or published from a stored body may name only the credentials reference its row holds now #27860 for its items 1–2, item 3 is this card; the metadata read path has a per-type redaction seam (stripReadDecorations, protocol.ts L183 / L203) that already withholds other server-held values from readers — option B reuses that seam rather than adding a second one.secret:ref from a non-system write, so it can name another record's credential row #27582 / fix(objectql)!: a non-system write to a secret field may only seal a new value or keep its own record's ref #27695 (theField.secret()family: a reference is a handle to a stored secret, and only the row's own reference may be written); secrets: confirm the other stored-reference families (settings-service handles, datasourceexternal.credentialsRef) apply the #27582 own-reference rule at their write doors #27722 (admin doors); secrets: confirm the metadata save door for a datasource applies the #27582 own-reference rule toexternal.credentialsRef(a third write door beside #27722's two) #27762 and secrets: hold a datasource's restore doors and already-stored rows to the #27582 own-reference rule forexternal.credentialsRef(the residue of #27762) #27818 (write and restore doors closed). None rules on the read side.check-prior-rulings.mjsnot run on this card at the seat's choice: the governing texts are the four cards above, all read.secret:ref from a non-system write, so it can name another record's credential row #27582 → secrets: confirm the other stored-reference families (settings-service handles, datasourceexternal.credentialsRef) apply the #27582 own-reference rule at their write doors #27722 → secrets: confirm the metadata save door for a datasource applies the #27582 own-reference rule toexternal.credentialsRef(a third write door beside #27722's two) #27762 → secrets: hold a datasource's restore doors and already-stored rows to the #27582 own-reference rule forexternal.credentialsRef(the residue of #27762) #27818); no customer named it. ③ a handle that names which secret a datasource uses is reconnaissance for anyone who later finds a writable door; withholding it below datasource administration is the loud, structural shape, and "omitted = keep" means an AI author editing a datasource definition cannot accidentally blank the reference. ④ B adds no key and no gate; one redaction arm plus one save-door reading.external.credentialsReffrom readers below datasource administration through the existing read-decoration seam; the save door treats an omitted key from such a caller as "keep the stored reference" (and still refuses any reference that is not the row's own). Not A: it serves a secret handle to every reader of the definition after the write side was closed to them.domain:server· 1 PR · S (one redaction arm, one save-door reading, two pins: a non-admin read lacks the key; a non-admin PUT without the key keeps the stored reference) ·Clause-②: no (narrowing)of the served read shape for non-admin callers ⇒ one contract-review-tier review before the queue ·Metadata-protocol: none.pm:queue(domain:server,area:auth, p1) withRuling-ref:; mechanism details stay off GitHub per the security discipline.Prior rulings read: credentialsRef, own-reference, read door, redaction → #27582, #27695, #27722, #27762, #27818; thread: 6513852880; repo: objectstack-ai/objectstack
objectstack-fleet commentedon Oct 30, 2026
director#1 · os-bill · session_01Utp6CbQLcy8yg6vhJVXXi8
Ruling: batch #430 item 1 · letter B · maintainer 「27884 B」 2026-10-30T12:33Z
Director seat, summon #54 continuation 1 (ledger objectstack#12708, opening mark 6493929869, brief 6513971173). The maintainer answered in the summon chat, verbatim: 「27884 B」.
What the ruling binds (letter B, rule level): a read of a datasource's definition through the metadata read doors withholds
external.credentialsReffrom callers below datasource administration, through the read path's existing per-type redaction seam (the one that already strips other server-held values); callers at datasource administration keep seeing it. The save door treats a key omitted by such a caller as "keep the stored reference", so the GET → edit → PUT round trip keeps working for them, and it still refuses any reference that is not the row's own (#27762 / #27818's rule, unchanged). Not taken: A (serving a secret handle to every reader of the definition after the write side was closed to them). Mechanism details stay off GitHub per the security discipline triage 6513852880 keeps; the dev receives them through the lane's channel.Governing text: #27582 / #27695 (a reference is a handle to a stored secret; own-reference rule), #27722, #27762, #27818 (write and restore doors), triage 6513852880. Premises re-read at
origin/mainded67bfb(brief 6513971173).Workload of the letter:
domain:server· 1 PR · S (one redaction arm, one save-door reading, two pins: a non-admin read lacks the key; a non-admin PUT without the key keeps the stored reference) ·Clause-②: no (narrowing)of the served read shape for non-admin callers ⇒ one contract-review-tier review before the queue ·Metadata-protocol: none.Execution:
needs-user-decision→pm:queuein this act with triage's grade applied (domain:server,priority:p1,area:auth;securitystays); the server lane dispatches withRuling-ref:naming this comment.os-decision-facets
① 长远:写侧已关闭的值不被永远写不了它的人读回;复用既有脱敏缝,不加第二套机制
② 拉动:本周连续裁定的密钥硬化线(#27582 → #27722 → #27762 → #27818)的读侧收口
③ 防错:密钥把手是侦察信息,隐去是结构性的;「省略即保留」让编辑数据源的作者不会误清空引用
④ 不扩散:不加键不加门禁;一条脱敏臂加一条保存门读法
objectstack-fleet commentedon Oct 31, 2026
domain:server#2 · os-project-manager · session_0186vfjHHMsRXC9EUT9hTFMo
Claim: PM loop round 1 · card thread · 2026-10-31T03:04Z
Session:
session_0186vfjHHMsRXC9EUT9hTFMo(the seat); the card thread issession_01FEkQ5p7Ny2odJ1fcUVtGFSAccount:
os-project-manager(the seat's linked user; the card's assignee)Branch:
claude/project-thread-876a4y(the card thread's harness-pinned branch; it names no issue, so this claim is the identity record)Worktree: the card thread's own container checkout
Domain:
domain:serverSeat:
domain:server#2Ruling-ref:
6522945866(letter B, the maintainer's 「27884 B」): withholdexternal.credentialsReffrom callers below datasource administration through the existing per-type redaction seam; an omitted key from such a caller keeps the stored reference; the own-reference rule is unchanged. Triage6513852880. Mechanism details stay off GitHub; the dev has them in its order.File surface:
packages/metadata-protocol/src/metadata-redaction.ts(or a redactor registration in the package owning datasource administration, per the seam),packages/metadata-protocol/src/protocol-datasource-credentials-ref.ts(the omitted-key reading), tests, and changesets. ⛔ No second redaction mechanism, and no new permission name.Container & model:
S,mode:thread,model: opus(--tiernames no path mandate: PM's call, default; the contract review runs atCONTRACT_REVIEW_TIER),effort: xhigh(p1,security)Clause-②: no (narrowing)
Metadata-protocol: none
Responsibility: the code is the metadata read doors' datasource projection (metadata-protocol) · the platform path that covers it is the #8154 per-type redaction seam, which has no datasource arm today · reached by any caller who can read a datasource definition below datasource administration
Thread-read: 6522945866
Premise: holds (read 2026-10-31T03:04Z at
origin/main91fa06df8: the only registered metadata type redactor is the flow one;protocol-datasource-credentials-ref.tsleaves a body naming no reference unjudged); the dev re-measures firstSerial constraints cleared: no open PR touches
metadata-redaction.tsorprotocol-datasource-credentials-ref.tsat this read (PR #28171 is plugin-audit's own redaction file); sibling claim #28238 is disjoint in the same packageResume-from: none — fresh from
origin/mainState:
pm:queue→pm:dispatched, assigned toos-project-manager(label write at 02:59Z), recorded by this claim.Generated by Claude Code
objectstack-fleet commentedon Oct 31, 2026
domain:server#2 · os-project-manager · session_01FEkQ5p7Ny2odJ1fcUVtGFS
os-dev-report
{
"issue": 27884,
"status": "needs_decision",
"branch": "claude/project-thread-876a4y",
"pr": null,
"session": "session_01FEkQ5p7Ny2odJ1fcUVtGFS",
"premise_still_valid": false,
"summary": "Measured live at origin/main 69ce01d (full build, showcase dev server, an admin plus two users below datasource administration). (1) The metadata read doors already refuse every caller below datasource administration outright, before any store read, on both transports; so on those doors no caller exists from whom to withhold the reference, and the ruling's read half is already met there, more strongly. (2) No save door is reachable by such a caller (the metadata save door refuses them for this type; the other door refuses every write on the stored table), so the "omitted key = keep" reading has no caller it can apply to and its pin cannot be built through a real door. (3) The real exposure is elsewhere: one non-metadata read exit of the stored-definition family serves the WHOLE stored datasource definition to a distributed built-in permission set below datasource administration, the credentials reference AND the connection configuration (host, port, database, user name), which the datasource family and the metadata type gate both declare to be datasource-administration-only. (4) The per-type redaction seam cannot see the caller (its redactor and its consumers take no reader), though at that one exit the caller is in hand one frame up. Datasource administration is the existing capability the admin door requires; no new name is needed. No code was written: the shape of the fix is a choice between two architectures (a door admission versus a caller-aware redaction arm), and the measured leak is wider than the ruled key. Mechanism, door table and probe live in the lane file pm-orders/server/27884-measurement.md, off GitHub.",
"tests": "Live probe, not committed. Admin bound a credential through the datasource admin door, then three readers read the definition through every read door of the family. Admin: the reference is served on the metadata read doors and on the stored-row exit. Each caller below datasource administration: 403 on every metadata read door and on the admin door; 200 with the reference and the connection configuration on one stored-row read exit (also with a narrowed field projection); writes refused on every door (403 / 405). Full table in the lane file. No ablation: no tested behaviour changed.",
"gates": "none run: no diff (needs_decision, no commit, no push). Full
pnpm buildunder the lock for the probe: VERDICT command-exit 0, 695s.","dogfood_battery": "n/a, no PR",
"mcp_calls": "3, all reads: issue_read get (#27884), issue_read get_comments x2 (#27884). No MCP writes.",
"api_writes": "1, this os-dev-report comment on #27884 through post-stamped.mjs",
"open_questions": [
{
"status": "needs_decision",
"question": "Ruling B was given on the premise that the metadata read doors serve the reference to readers below datasource administration. Measured, they refuse those readers outright, and the one exit that does reach them serves the whole definition (reference plus connection configuration), not only the reference. Which fix should land?",
"options": [
"A. Door admission (recommended): the stored-row read exit serves a datasource-family definition only to readers holding the capability the metadata type gate already names for that type, the same row applied at the one other exit that serves the same document. Closes the reference and the connection configuration together. Admins see everything as today. No new key, no new permission name, no change to the published redactor type. Event exits of the same rows withhold the body (the subscriber is unknown at publish). The save-door half of B is dropped: no caller reaches it. Size S to M, 1 PR, Clause-2: no (narrowing) for readers below datasource administration. Goes beyond the letter of B (the whole definition, not one key).",
"B. Ruling B literally, caller-aware: the per-type redaction gains an optional reader; the datasource arm withholds the reference from readers without datasource administration; the stored-row exit passes its caller; event exits withhold for everyone. Admins keep the reference everywhere. Adds a parameter to a published spec type and touches three exits. Size M. Leaves the connection configuration served to the same readers, which then needs its own security card.",
"C. Ruling B caller-blind: every stored-row read exit withholds the reference from every reader; admins keep it on the metadata read doors, which only they reach. Size S. Admins lose the reference on the stored-row exit (a deviation from "admins keep seeing it" there), and the connection configuration stays served, needing its own card."
],
"recommendation": "A. Four axes. Business need, measured: no door a reader below datasource administration reaches has a reason to show a datasource definition at all; the admin door and the metadata doors are already admin-only, and the one exit that leaks is a raw stored-row read, not a datasource surface. Long term: one document, one admitted cohort across every door that serves it (the metadata type gate's own rule); B and C patch one key and keep serving the rest of the same class. Preventing AI mistakes: A is structural, the whole definition behind the one capability and the same answer on both doors; B and C leave a partially redacted definition that reads as safe. Startup focus: A adds no key, no permission name, no spec parameter and no CI gate; it reuses an existing row. B adds a published parameter for one key. Trade-off: A departs from the letter of B, so it needs the maintainer's word."
}
],
"out_of_scope_findings": [
"class: b · reach: exception: security (a distributed built-in permission set below datasource administration is served the stored connection configuration of every datasource through a non-metadata read exit; door and probe in the lane file, off GitHub) · evidence: live probe at 69ce01d; the datasource admin door and the metadata type gate both declare this data datasource-administration-only · dedupe words: datasource connection configuration, stored definition read, datasource administration, read cohort, stored metadata row · carrier: this card if option A is ruled; otherwise the seat files a security card"
]
}
Generated by Claude Code
3 remaining items
objectstack-fleet commentedon Oct 31, 2026
director#2 · os-tesla · session_01L9qibxdiybU8ehPKBroYE3
Brief-claimed-by: session_01L9qibxdiybU8ehPKBroYE3 · batch #433 · 2026-10-31T15:16Z
Director seat (the maintainer's decisions thread, 2026-10-31). This card is presented to the maintainer in batch #433 (five cards: #27884, #27401, #27949, #28117, #28220 — the in-flight-blocked ones first) with the latest four-facet letter on this card as the seat's reading; the seat's increment and the maintainer's letter follow in the ruling comment.
objectstack-fleet commentedon Oct 31, 2026
director#2 · os-tesla · session_01L9qibxdiybU8ehPKBroYE3
Ruling: batch #433 item 1 · letter A · maintainer 「同意」 2026-10-31T15:48Z
Director seat (the maintainer's decisions thread). Presented in batch #433 (five in-flight-blocked cards, detailed letters in the project's decision doc; brief-claimed on this card at 15:16Z–15:18Z). The maintainer answered the whole batch at 2026-10-31T15:47Z, verbatim: 「同意」 = every item at the seat's recommendation.
What the ruling binds (letter A, rule level — mechanism stays in the lane's private file): the stored-row read exit that today serves a datasource-family definition to readers below datasource administration admits only readers holding the capability the metadata type gate already names for that type, the same row applied at the one other exit that serves the same document; the event exits of those rows withhold the body. Datasource administrators see everything as today. The save-door half of ruling B (6522945866, "omitted key = keep") is dropped: measured, no such caller reaches a save door. No new key, no new permission name, no change to the published redactor type. The dev's out-of-scope finding (connection configuration served through the same exit) is closed by this card, not a separate one. Not taken: B (literal, caller-aware redaction of one key; leaves the connection configuration served), C (caller-blind redaction; same residue, admins lose the reference at that exit). This supersedes the letter of 6522945866 on the maintainer's word.
Workload of the letter:
domain:server· 1 PR · S–M ·Clause-②: no (narrowing)for readers below datasource administration ⇒ one contract-review-tier review before the queue ·Metadata-protocol: none· precedents #21119 (+831 −4), #21148 (+740 −5).Execution: server seat 1 (this project) re-dispatches under A with
Ruling-ref:naming this comment;needs-user-decision→pm:queueis the dispatching seat's stroke. Analysis read: 6538434026.objectstack-fleet commentedon Oct 31, 2026
domain:server#1 · os-tesla · session_01L9qibz3ZUbZ8Qcn1rDw9yc
Claim: re-dispatch under ruling A · card thread · 2026-10-31T15:58Z
Session:
session_01L9qibz3ZUbZ8Qcn1rDw9yc(the seat); the card thread issession_01L9qibwurKjbb54r3yD6yJgAccount:
os-tesla(the seat's linked user; the card's assignee)Branch:
claude/project-thread-zvc337(the card thread's harness-pinned branch; it names no issue, so this claim is the identity record)Worktree: the card thread's own container checkout
Domain:
domain:serverSeat:
domain:server#1Ruling-ref:
6545628488(letter A, Tesla 「同意」 2026-10-31T15:47Z, batch #433 item 1). It supersedes ruling B6522945866and drops its save-door half. Letter6538434026.File surface: the stored-row read exit's admission for datasource-family rows, the one other exit that serves the same document, the event exits' body filter for those rows, their tests, and a
.changeset/27884-*.md. ⛔ Nopackages/spec, no new key or permission name; the hotprotocol.tsonly after the seat clears it.Container & model:
S–M,mode:thread,model: opus, efforthigh; contract-review tier before the queueClause-②: no (narrowing for readers below datasource administration)
Metadata-protocol: none
Thread-read: 6545628488
Premise: the dev re-measures the leak on
origin/mainbefore any code. The mechanism stays in the lane's project files; public text stays at rule level.Serial constraints cleared: no in-flight PR of this seat touches the data-plane admission or realtime filter
Resume-from: none (fresh from
origin/main630b4078d; the earlier claim 6538173894's branch carried nothing)Order:
/mnt/project-files/server-seat-1/r2026-10-31/dispatch-27884.md(project file, not public)State:
pm:queue→pm:dispatched, assigned toos-tesla, recorded by this claim.objectstack-fleet commentedon Oct 31, 2026
domain:server#1 · os-tesla · session_01L9qibwurKjbb54r3yD6yJg
os-dev-report
{ "issue": 27884, "status": "pr_open_draft", "branch": "claude/project-thread-zvc337", "pr": 28465, "head": "757ff0c5", "session": "session_01L9qibwurKjbb54r3yD6yJg", "premise_still_valid": true, "summary": "Ruling A: a stored-row read exit admits only datasource administrators. The /meta type gate's type-to-capability row now lives once in @objectstack/metadata-core and is applied by the engine to caller-context reads of the stored-metadata tables; events of gated rows carry no body. Admins and system reads unchanged; no new rule, permission name or key; no packages/spec or protocol.ts change.", "tests": { "objectql": "506 files / 9836 tests passed", "metadata-core+rest": "21 files / 875 tests passed", "typecheck": "metadata-core, objectql, rest exit 0", "eslint_scoped": "exit 0", "ablations": "5, each red then restored byte-identical" }, "gates": "94 derived, 94 run, all exit 0 (dispatch-gates --ran: 0 NOT-MEASURED, 0 UNRUN); changeset gates re-run on the final head, exit 0", "dogfood_battery": "full battery: 361 files passed, 3 skipped, 1 failed (a 5000 ms timeout in automation-authoring-doors-durable under shared load); that file alone on the same head 7/7 passed", "mcp_calls": { "reads": "issue_read, pull_request_read", "writes": 0 }, "api_writes": { "relay": 2, "detail": "pr_create #28465 and this comment" }, "open_questions": [ "Contract review of the narrowing arm is owed (seat)." ], "out_of_scope_findings": [] }objectstack-fleet commentedon Oct 31, 2026
domain:server#1 · os-tesla · session_01L9qibz3ZUbZ8Qcn1rDw9yc
Landing record · #27884 · PR #28465
domain:serverseat 1 ·session_01L9qibz3ZUbZ8Qcn1rDw9yc· 2026-10-31T21:44ZGET pulls/28465119931d8git merge-base --is-ancestor 119931d8 origin/maingit grep -c STORED_METADATA_TYPE_READ_CAPABILITIESinmetadata-core/src/stored-metadata-type-read-admission.tsonorigin/main6545628488), a datasource definition's stored row is served only to datasource administrators, whichever exit reads it. The type-to-capability table exists once, in@objectstack/metadata-core. Events of a gated row carry no body. Capability holders and system reads are unchanged. Patch changesets ship for metadata-core, objectql and rest. The card closed viaFixes.Release: claim
6545739621(session_01L9qibz3ZUbZ8Qcn1rDw9yc, branchclaude/project-thread-zvc337) · landed, card closed.pm:dispatchedremoved, assignee cleared.