Skip to content

security(metadata): tighten the draft publish gate and package identity for org view overlays (follow-up to #21864) #21934

Description

@objectstack-fleet

Follow-up from the round-5 independent security review of PR #21864 (card #21835), which passed. These are the low and informational items it recorded. Each one either is older than #21864 or extends the known limit the maintainer accepted on #21835 (comment 6005722623). None of them blocks #21864. Classes and positions only; detail is held by the PM session (session_018zT8d8NpiQ1ExhuNd5TxY6).

  1. Package identity of a served org overlay (LOW). Applies only to overlays stored before a withdrawal, or restored by rollback or revert.
    • The org read stamps a package-less org overlay with the package of each base row of its name.
    • So the doors cannot tell an inherited package from the row's own. Where two packages ship the same view name, the withdrawal of one package can miss that overlay.
    • Direction: mark stamped copies in the merge, or have the doors read the org row's own package_id. A body stored package-less is compared against every package's withdrawal.
    • Positions: packages/metadata-core/src/anonymous-form-intake.ts (package comparison) and packages/metadata-protocol/src/protocol.ts (the list merge's package stamp).
  2. Publish gate and promotion are separate reads (LOW, older than fix(rest,metadata-protocol): a public form's intake withdrawal at any metadata layer holds; layering can only narrow intake #21864).
    • The gate's reads of the draft and the promotion's own read are not pinned to each other.
    • A draft saved in between can be promoted without being judged.
    • Direction: pass the judged draft's hash into promoteDraft and refuse with a conflict when the row's hash differs.
  3. Lock lookup uses the request's package, not the resolved one (INFO, older than fix(rest,metadata-protocol): a public form's intake withdrawal at any metadata layer holds; layering can only narrow intake #21864).
    • In the publish path, lockWriteRefusal takes request.packageId rather than the package key the gate resolved.
    • Direction: thread the resolved key into the lock lookup. Leave the authoring-rule narrowing as it is; it is documented as deliberate.

Priced by reach (pm-dispatch rule proposed in #21929): each needs an administrator-level overlay or draft, or a narrow timing window, so this is low priority.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 6, 2026

    @objectstack-fleet
    ContributorAuthor

    Path: ② the capabilities an end user meets in the app — public forms and metadata publishing | 缺项 | P2

    Triage: first grade — bug · security · priority:p3 · domain:engine · area:access · pm:blocked (finding removed). Low follow-ups from #21864's passing review, serial behind it

    Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-06T01:52Z. ⛔ Not a claim, ⛔ not a dispatch.

    Triage: lands in packages/metadata-protocol/src/protocol.ts (the list merge's package stamp and the publish path) and packages/metadata-core/src/anonymous-form-intake.ts ⇒ domain:engine; rationale: these are the metadata core and protocol, the same files PR #21864 changes.

    Blocked-by: #21835


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 6, 2026

    @objectstack-fleet
    ContributorAuthor

    Addendum from the contract review of PR #21864 at 7882eef683 (record 6008961867, PASS). This item is in scope for this card, with classes and positions only.

    1. The write door's row anchor across packages (LOW, unchanged since before fix(rest,metadata-protocol): a public form's intake withdrawal at any metadata layer holds; layering can only narrow intake #21864's round 5).
      • Where: envWideRawViewRows in packages/metadata-protocol/src/protocol.ts.
      • When no env-wide row is stored, it falls back to lookupArtifactItem(type, name) without a package key. If several packages ship the same view name, the save check then judges only the first match in registry order. Separately, a stored row from any package hides every artifact of that name.
      • Direction: resolve the anchor per package, using the saved row's own package and falling back to the package-less definition. Fall back to the artifact per package, not per name. Pin the case where the withdrawing package is not first in registry order.
      • Wording: the fix(rest,metadata-protocol): a public form's intake withdrawal at any metadata layer holds; layering can only narrow intake #21864 changeset and docs say the shared judgement "never under-closes". When this item lands, narrow that sentence to match.

    Generated by Claude Code

  3. objectstack-fleet commented on Oct 6, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: unlocked — pm:blocked → pm:queue. #21835 closed completed through PR #21864

    Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-06T04:57Z. ⛔ Not a claim, ⛔ not a dispatch.


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 6, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 41 · 2026-10-06T05:31Z
    Session: session_017ErfyP2Rx7XWHJA27QjyUi
    Account: os-project-manager (the seat's linked user, as GET /user answers it; always the card's assignee)
    Branch: claude/issue-21934-org-overlay-publish-gate
    Worktree: objectstack-issue-21934
    Domain: domain:engine
    Seat: domain:engine#1
    Provenance (thread read through the unlock 6009643967, including the first grade 6007709051 and the addendum 6008978556):

  5. objectstack-fleet commented on Oct 6, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 21934,
    "status": "done",
    "branch": "claude/issue-21934-org-overlay-publish-gate",
    "pr": "#21962",
    "session": "session_017ErfyP2Rx7XWHJA27QjyUi (mode:subagent, the PM's session id; identity is the branch)",
    "premise_still_valid": true,
    "summary": "Five commits on PR 21962 (head 7c30229), one pin per item, all in @objectstack/metadata-protocol plus a docblock in metadata-core and the narrowed docs sentence. Item 1: H1 holds for the stamp (no reader compares packages), but the item's outcome was reachable on main through the list merge's view branch, which upserted every name by name once any view row was stored, so the env-wide layer the form doors judge against held one package's item of a two-package view name; fixed at that producer (only names a stored container's expansion writes are upserted); the residual for two packages' env-wide copies of one view container is stated in the docs and raised as an open question. Item 2: promoteDraft takes an optional expectedDraftHash and refuses a different or unexpected draft row with a ConflictError before writing; the publish passes the judged hash and answers 409 METADATA_CONFLICT. Item 3: the publish resolves its draft key before the lock check and threads it into lockWriteRefusal (authoring-rule narrowing untouched), and a follow-up commit keeps an unreadable store answered as 503 at the moved read. Item 4: envWideRawViewRows anchors per package (own env-wide row, else package-less row, else that package's artifact); 'never under-closes' narrowed in the docblock and the docs page.",
    "tests": "Final head 7c30229 (origin/main 76fec88 merged at 5297072): metadata-protocol typecheck green and full vitest 218 files passed / 3 skipped, 27984 tests passed / 19 skipped; the edited test file is in the tsc program (--listFiles count 1). At 5297072: metadata-core 18 files / 411 tests passed, typecheck green (both programs, unchanged since); objectql full 378 files / 7507 tests passed against metadata-protocol dist built at 5297072 (the later commit only changes an outage path). Pins in packages/metadata-protocol/src/protocol.org-scoped-write-refused.test.ts: 63 tests in the file green. Reverse verification through scripts/ablation-replace.mjs in wrap mode (anchor hit 1 time, blob changed on disk; source imported relatively, so no dist leg), each from a committed head, each item's code set back to its base shape: from 1e271aa (protocol.ts blob ba2e49c522eb, identical at 5297072): item 1 5 red / 2 green (the two write-door re-saves it does not touch), item 2 2 red / 1 green (control), item 3 1 red / 1 green (control), item 4 3 red / 2 green (controls); from 7c30229 the follow-up's classification removed: its pin 1 red. Every restore proved by the tool: blob == HEAD (ba2e49c522eb, then 961652c249e0) and git diff HEAD empty. Predicted counts matched before running.",
    "mcp_calls": "0",
    "api_writes": "3 REST writes, each through the fleet-write relay (POST /repos/objectstack-ai/objectstack/dispatches, executed as objectstack-fleet[bot]): pr_create POST /repos/objectstack-ai/objectstack/pulls (run 37425351849, read-back identical 10417 bytes, PR 21962); label-write assign POST /repos//issues/21962/assignees os-project-manager (run 37425431078, read-back matches); os-dev-report comment POST /repos//issues/21934/comments (this comment). Plus git push of the branch, 7 pushes: empty probe, item 1, one --force-with-lease after amending item 1 to add its changeset, item 3, item 4, the main merge, the item 3 follow-up.",
    "open_questions": [
    {
    "question": "Item 1 residual: where two packages each store an env-wide copy of the same view container, the env-wide view list still holds one package's expansion of each name those containers expand, so the anonymous form doors can miss the other package's withdrawal of that form (the org-scoped save check judges both, after item 4). Keep each package's expansion apart?",
    "options": [
    "A: key the list's expansion upsert per package (a package-bound container row writes only its own package's slot, a package-less one stands in for all), and teach the by-name read (resolveRowlessExpandedView) the same rule so the two doors agree",
    "B: keep it as the documented known limit (as this PR states it) and file it as its own card"
    ],
    "recommendation": "B now, A as its own card: the expansion upsert is shared with the by-name read and several earlier rulings on container expansion, so changing it is a design change outside this card's four items; the reach is narrow (two packages each saving an env-wide copy of one container) and the save check already refuses the overlay."
    }
    ],
    "out_of_scope_findings": [
    "class: a · reach: measured through the protocol's real getMetaItems reads and the doors' own anonymousFormIntakeWithdrawnIn verdict (the composition registerFormEndpoints runs), not through an HTTP call: two packages ship container 'task'; org overlay stored package-less; pkg_b saves the form withdrawn env-wide, then pkg_a saves it open env-wide; the env-wide list holds only pkg_a's expansion of task.intake_form and the doors' verdict serves the overlay (scratch probe at 1e271aa) · evidence: protocol.ts list merge view branch, expansion upsert by name · same defect class as item 1 (its residual), stated in the docs page and PR Acceptance notes · dedupe words: view container expansion upsert by name across packages, env-wide list one expansion per name, public form withdrawal missed two packages container, expandStoredViewContainers byName",
    "carrier: none (承接者:无) · noted, not filed: the publish path's draft-key read (protocol.ts promoteDraftForPublish, engine.findOne on sys_metadata, state draft) carries no explicit system opt-in context, unlike the store reads the system-opt-in sweep converted; check-system-context-census is green on it, so it is read-only inference. Item 3 moved it unchanged (now inside a store-failure classification). Not in the PR's Acceptance notes because the body is written once; the seat may add it."
    ],
    "gates": "Final union at 7c30229, derivation identical to the one at 5297072 (dispatch-gates --commands, no paths, 93 commands; artifact-roster block unchanged, 53). 93 derived: all exit 0, reconciled with --ran (each line 'command :: exit N'): '93 derived famil(ies) accounted for — 93 run, 0 NOT-MEASURED (a DERIVED zero — all 93 recorded an exit code and none of them is 3)'. Artifact-roster block (53) all exit 0, the PR-context ones run against PR 21962 (closing-target-claim: 'PR #21962 closes #21934, and each carries a Claim: whose Branch: line names claude/issue-21934-org-overlay-publish-gate'); check:select-shard-packages first exited 1 only because this runner exported NODE_USE_ENV_PROXY and node's experimental-proxy warning entered its fixture output, then exit 0 rerun without it. Four symbol-anchor sweeps (check:adr-symbol-anchors, check:scripts-symbol-anchors, check:spec-docblock-symbol-anchors, check:adr-anchors) exit 0. Earlier union at 5297072 (the one the PR body quotes): 92 of 93 green, check:dual-build-cjs-loads NOT MEASURED (exit 3, missing dist), green at 7c30229 after the closure builds. CI on 7c30229 at one reading: 33 of 34 check runs completed, none failed (Lint & Repo Gates, TypeScript Type Check, Dogfood Regression Gate, Build Core, Temporal Conformance, Governed Surface Queue Guard, Check Changeset among them), Test Core (1/6) in_progress.",
    "line_budget": "n/a",
    "deviations": [
    "Item 1 changes code although the order expected a pin only: H1's stamp half holds, but the measured miss was reachable on main through the list merge's by-name upsert, so the fix landed at that producer (protocol.ts view branch of the list read). Neither card direction applied because nothing compares packages. Reported as falsified in items[0].",
    "No changeset for @objectstack/metadata-core although it is touched: the edit is a docblock only (os-dev fast track: comments do not publish); its public declaration is byte-identical with comments stripped. The narrowing is stated in the metadata-protocol changeset .changeset/21934-save-check-anchor-per-package.md.",
    "Four changesets (one per item) instead of one, so each item stays droppable: 21934-view-list-one-item-per-package (patch), 21934-publish-promotes-judged-draft (minor, carries Clause-②: yes (widening)), 21934-publish-lock-resolved-package (patch), 21934-save-check-anchor-per-package (patch).",
    "Item 1's commit was amended after its first push to add its changeset, and pushed with --force-with-lease=claude/issue-21934-org-overlay-publish-gate:1fb7bd527b (all five AGENTS.md conditions held: claude/issue-* name, created by this worktree, only this session pushed, no PR existed).",
    "Reverse verification ran at 1e271aa, before the main merge; protocol.ts is blob-identical at 5297072, and the merge brought no change to metadata-protocol, metadata-core or spec.",
    "Commit trailers use the AGENTS.md model-free pair and the PR footer uses the AGENTS.md session-URL form, not the harness attribution reminder's model-named trailer and footer.",
    "Item 3 has two commits (114ed63 and the follow-up 7c30229): moving the draft-key read above the lock check changed an unreadable store's answer from the lock read's 503 to the driver's error, so the follow-up classifies that read the way the lock read does, with its own pin. Dropping item 3 drops both.",
    "The PR body (written once, not patched) quotes the union and suites at 5297072 and records check:dual-build-cjs-loads as NOT MEASURED and the three PR-context roster gates as NOT WIRED; at the final head 7c30229 all 93 derived and all 53 roster gates are green and the suite counts are the ones in this report. The body does not mention the item 3 follow-up commit; the seat may update the Tests section and item 3."
    ],
    "files_changed": [
    ".changeset/21934-publish-lock-resolved-package.md",
    ".changeset/21934-publish-promotes-judged-draft.md",
    ".changeset/21934-save-check-anchor-per-package.md",
    ".changeset/21934-view-list-one-item-per-package.md",
    "content/docs/ui/public-data-collection.mdx",
    "packages/metadata-core/src/anonymous-form-intake.ts",
    "packages/metadata-protocol/src/protocol.org-scoped-write-refused.test.ts",
    "packages/metadata-protocol/src/protocol.ts",
    "packages/metadata-protocol/src/sys-metadata-repository.ts"
    ],
    "clause_2": {
    "line": "Clause-②: yes (widening)",
    "measured": "Built entry declarations, base a3bd157 vs head 5297072, diffed with comments stripped.",
    "metadata_protocol": "dist/index.d.ts SysMetadataRepository.promoteDraft(ref: MetaRef, opts: {...}) at base line 9838 / head line 9833 gains 'expectedDraftHash?: string | null;' (head line 9883): an optional input field, a widening. Return type unchanged. No other non-comment difference (one comment-placement change inside an inlined type).",
    "metadata_core": "dist/index.d.ts 'declare function anonymousFormIntakeWithdrawnIn(layer, view, candidate): boolean' byte-identical (base line 21311, head line 21316); docblock only.",
    "consequence": "item 2's changeset is minor; a contract review is owed (the seat runs it); the claim's provisional 'Clause-②: no' should read 'Clause-②: yes (widening)'."
    },
    "items": [
    {
    "item": 1,
    "measured": "H1 partly falsified. Confirmed: anonymousFormIntakeWithdrawnIn (metadata-core/src/anonymous-form-intake.ts:329) compares no package, and findPublicFormView (rest/src/rest-server.ts:10735) reads no _packageId, so the stamp (protocol.ts:2166, :9077 at base) alone causes no miss. Falsified: 'stays closed at both doors' did not hold on main. The view branch of the list read (protocol.ts:9063-9083 at base) rebuilt the item list through a by-name map whenever any view row was stored, keeping one package's item of a two-package view name; measured through the protocol's real getMetaItems and the doors' verdict, a package-less org overlay stored before the withdrawal stayed served when the withdrawing package was first in registry order and closed when it was second. The org-scoped save check refused the re-save in both orders.",
    "changed": "yes",
    "commit": "21f75eb892",
    "pin": "protocol.org-scoped-write-refused.test.ts 'a package-less organization overlay, two packages shipping its view name' (7 tests): one served copy per package, each stamped; for the first and the second package in registry order, the env-wide list holds the withdrawal, the doors serve no copy, a re-save is refused."
    },
    {
    "item": 2,
    "measured": "H2 confirmed: promoteDraftForPublish judges the draft read by repo.get (protocol.ts:21623 at base) and SysMetadataRepository.promoteDraft reads the draft row again with engine.findOne (sys-metadata-repository.ts:969 at base); a draft saved between them, or appearing where the gate found none, was promoted unjudged. The promotion can be handed the judged body without a new public option only by repurposing the deriveActiveBody derivation hook as a guard (body comparison, not the stored hash); not taken, the card's direction names the hash.",
    "changed": "yes",
    "commit": "d1365db627",
    "pin": "'a publish promotes only the draft its gate judged' (3 tests): a draft saved after the gate read, and one saved where the gate judged none, are not promoted and 409 METADATA_CONFLICT answers; control promotes and drains."
    },
    {
    "item": 3,
    "measured": "H3 confirmed: the publish path's lockWriteRefusal (protocol.ts:21583 at base) took request.packageId while the gate resolves draftKey (stated binding, else the draft row's own package_id) after it. The lock verdict is the strictest across every row and shipping package in scope, so the key decides whose lock prose (lockReason) the refusal carries, not whether it refuses.",
    "changed": "yes",
    "commit": "114ed6393c, follow-up 7c30229",
    "pin": "'a publish consults the lock of the package key it resolved' (2 tests): no stated package, draft bound to pkg_b, both packages' rows locked: refusal carries pkg_b's lockReason; control with a stated package carries that package's. Follow-up pin 'a publish that states no package, over a store that cannot be read': answers 503 SERVICE_UNAVAILABLE and promotes nothing."
    },
    {
    "item": 4,
    "measured": "H4 confirmed: envWideRawViewRows (protocol.ts:16092 at base) returned every stored env-wide row of the name when any existed and otherwise lookupArtifactItem(type, name) with no package (first in registry order). With the withdrawing package second in order, a renaming org save was accepted; with another package's env-wide row stored, the withdrawing package's artifact was not judged.",
    "changed": "yes",
    "commit": "1e271aaae1",
    "pin": "'the save check anchors each package's row on that package's env-wide definition' (5 tests): withdrawing package not first in registry order, package-less and package-bound renaming org saves refused; another package's env-wide row anchors that package only; controls: kept-withdrawn save saves, a package-less env-wide row stands in for every package. Wording narrowed in the docblock and content/docs/ui/public-data-collection.mdx; the released #21864 changeset untouched."
    }
    ]
    }


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 6, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 21934,
    "round": "patch round 1 (contract review FAIL 6011725183 on head 7c30229: the endpoint exception's wording)",
    "status": "done",
    "branch": "claude/issue-21934-org-overlay-publish-gate",
    "pr": "#21962",
    "session": "session_017ErfyP2Rx7XWHJA27QjyUi (mode:subagent, the PM's session id; identity is the branch)",
    "premise_still_valid": true,
    "summary": "Wording only; the code of all four items stands. New commit 3eea8f0 restates the endpoints' exception in the three places the record names (content/docs/ui/public-data-collection.mdx 'Known limit: packages and names'; .changeset/21934-save-check-anchor-per-package.md; the anonymousFormIntakeWithdrawnIn docblock) with the record's meaning: where a package's environment-wide copy of a view container is saved, the endpoints read that copy's expansion alone for each form it expands, and can miss another package's withdrawal of that form, whether saved or shipped. Kept: a withdrawal of a view name still closes that name in every package, so it may over-close; the organization-scoped save check judges every package's environment-wide definition of the name. #21967 is named as the card carrying the per-package expansion design. The PR body was patched once: the Acceptance note's residual now has the same reach, the Tests section is refreshed to the final head, and item 3's paragraph names its follow-up 7c30229; the first two lines remain 'Fixes #21934' and 'Clause-②: yes (widening)'.",
    "tests": "Final head 3eea8f0 (3 files: the docs page, one changeset, the metadata-core docblock; git diff --stat 7c30229..HEAD). metadata-core at 3eea8f0: typecheck green (tsc --noEmit and -p tsconfig.test.json), 18 files / 411 tests passed. metadata-protocol src byte-identical to 7c30229, where typecheck and the full suite (218 files passed / 3 skipped, 27984 tests passed / 19 skipped) ran. Rebuilt declarations at 3eea8f0: metadata-core identical to base a3bd157 with comments stripped, metadata-protocol identical to the 5297072 build with comments stripped, so Clause-② is unchanged. No code changed, so no reverse verification is owed this round.",
    "mcp_calls": "0",
    "api_writes": "2 REST writes this round, each through the fleet-write relay (POST /repos/objectstack-ai/objectstack/dispatches, executed as objectstack-fleet[bot]): issue_patch PATCH /repos//issues/21962 (the PR body; run 37434770483, read-back identical 12433 bytes, one footer); os-dev-report comment POST /repos//issues/21934/comments (this comment). Plus one git push (3eea8f0, fast-forward; no amend, no force).",
    "open_questions": [],
    "out_of_scope_findings": [],
    "gates": "At 3eea8f0, dispatch-gates --commands with no paths: the same 93 commands as at 5297072 and 7c30229. 92 exit 0, among them pnpm check:doc-authoring, pnpm check:docs-audit-scope, node scripts/docs-audit/check-affected-docs.mjs, node scripts/docs-audit/check-drift-comment.mjs, pnpm --filter @objectstack/spec run check:docs, pnpm check:nul-bytes, node scripts/check-empty-changeset.mjs --base origin/main, node scripts/check-adr-0087-registration.mjs --base origin/main ('4 non-breaking changeset(s) seen'), pnpm check:changeset-gate-self-tests. Check Changeset's local equivalent: node scripts/check-changeset-no-major.mjs --base origin/main --event (a pull_request payload carrying the patched body): exit 0, 'This diff introduces no major bump' and 'LEVEL AXIS: this PR declares clause-② yes (widening), and it grades a package whose packages//src/ it moves at minor or above'. 1 NOT MEASURED: pnpm check:dual-build-cjs-loads exit 3, PREREQUISITE NOT MET (32 workspace packages without dist in the recreated worktree; it was green at 7c30229, whose code this head keeps). Reconciled with --ran ('command :: exit N' lines): '93 derived famil(ies) accounted for — 92 run, 1 NOT-MEASURED (1 DERIVED from a recorded exit 3)'. Artifact-roster block (53) all exit 0, PR-context gates against PR 21962 (check-partof-closing-keyword also on the patched body); four symbol-anchor sweeps exit 0. CI on 3eea8f0 at one reading: 33 success, 4 skipped, 5 in_progress, none failed.",
    "line_budget": "n/a",
    "deviations": [
    "Stated a remedy beside the corrected exception in the docs page and the changeset: to close such a form at the endpoints, withdraw it in every saved environment-wide copy of that container as well. It follows from the code (the layer holds the saved copies' expansions for those names) and replaces the old remedy sentence, which named two packages' copies.",
    "Not merged with origin/main this round (the order asked for one commit only): dispatch-gates warns the tree is at least 5 commits behind origin/main, with scripts/engine-double-contract.pinned.json changed across that range; check:engine-double-contract is green here, and CI judges the merge ref.",
    "check:dual-build-cjs-loads is NOT MEASURED at 3eea8f0 because the worktree was recreated and 32 packages were not rebuilt; the round changes no code."
    ],
    "files_changed": [
    ".changeset/21934-save-check-anchor-per-package.md",
    "content/docs/ui/public-data-collection.mdx",
    "packages/metadata-core/src/anonymous-form-intake.ts"
    ],
    "clause_2": {
    "line": "Clause-②: yes (widening)",
    "measured": "Unchanged at 3eea8f0: the round's commit edits a docblock, a docs page and a changeset; rebuilt declarations are identical with comments stripped (metadata-core to base a3bd157, metadata-protocol to 5297072). The widening remains SysMetadataRepository.promoteDraft's optional expectedDraftHash."
    },
    "items": [
    {
    "item": 1,
    "measured": "unchanged this round",
    "changed": "no (wording of its residual corrected in the docs page, the changeset and the docblock)",
    "commit": "21f75eb892; wording 3eea8f0",
    "pin": "unchanged"
    },
    {
    "item": 2,
    "measured": "unchanged this round",
    "changed": "no",
    "commit": "d1365db627",
    "pin": "unchanged"
    },
    {
    "item": 3,
    "measured": "unchanged this round",
    "changed": "no (PR body now names follow-up 7c30229)",
    "commit": "114ed6393c, follow-up 7c30229",
    "pin": "unchanged"
    },
    {
    "item": 4,
    "measured": "unchanged this round",
    "changed": "no (its wording deliverable corrected)",
    "commit": "1e271aaae1; wording 3eea8f0",
    "pin": "unchanged"
    }
    ]
    }


    Generated by Claude Code

  7. objectstack-fleet commented on Oct 6, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR #21962 → c9761cd2fb on main. It merged through the merge queue at 2026-10-06T09:01Z; it entered the queue at 2026-10-06T08:25Z. Verified at 2026-10-06T09:01Z. domain:engine#1 · session_017ErfyP2Rx7XWHJA27QjyUi.


    Generated by Claude Code

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

Metadata

Metadata

Labels

area:accessPermissions that actually hold — RLS/FLS, sharing model, write-path guardsbugSomething isn't workingdomain:enginepriority:p3security

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions