Skip to content

fix(dogfood): the audit-capability fixture's grant writes carry their holder's organization - #24805

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-24780-audit-capability-grant-organization
Oct 20, 2026
Merged

objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-24780-audit-capability-grant-organization

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Refs #24780
Clause-②: no

This PR repairs row 1 of the card (Dogfood Regression Gate (1/3)). Row 2 (Console Pin Gate) belongs to #24749 and is not touched. The card stays open for the PM to settle after this lands.

What changed

One file: packages/qa/dogfood/test/audit-log-audit-capability.dogfood.test.ts. Its two sys_user_permission_set grant inserts ran in system context with no organization. Each now carries its holder's organization on the execution context ({ isSystem: true, tenantId: ORG }):

  • The walled case ([#21260] the ledger audit capability is bounded by its holder's organization (scope: org), multiTenant: 'posture-only', so the isolated posture): the grant to the first owner carries org.a, the organization that owner created earlier in the same beforeAll.
  • The first describe (a single boot): the grant helper reads the holder's one membership in sys_member and carries that organization (the Default Organization on that boot). The helper asserts exactly one non-empty membership. Without that check, an empty id would fall back to derivation and pass without testing anything.

No assertion of any case changed. resolveSystemInsertOrganization and the walled lift stay as they are.

Why tenantId on the context rather than organization_id on the row: the refusal names the context form first ("pass it on the execution context ({ context: { isSystem: true, tenantId: ORGANIZATION_ID } }), or set organization_id on the record itself"). It is also the form #24667 used for its own two walled fixtures (builtin-positions.boot.test.ts, grant-holder-membership-refusal.test.ts).

The file's other system write, the bulk sys_audit_log insert in the first describe, is not this shape and is unchanged. The ledger declares systemFields: { tenant: false } (ADR-0131 D7: no organization column), so resolveTenantFieldName answers null and the rule does not apply to that object. Its single boot would derive an organization anyway. The file makes no other ql.insert / update / delete calls.

Evidence

All runs used pnpm --filter @objectstack/dogfood exec vitest run --maxWorkers=2 test/audit-log-audit-capability.dogfood.test.ts, after building the @objectstack/dogfood^... closure at the same commit.

tree result
f7005cbd8 (the parent of #24667's fc34d000fc) Test Files 1 passed (1) · Tests 13 passed (13)
fc34d000fc (#24667, the walled lift) Test Files 1 failed (1) · Tests 10 passed | 3 skipped (13), SystemWriteOrganizationRequiredError: Insert on 'sys_user_permission_set' was REFUSED … this install runs the 'isolated' tenancy posture
74f78159a (this branch's base, main before the fix) the same red: 1 failed, 10 passed | 3 skipped, the same refusal, at _ObjectQL.resolveSystemInsertOrganization via plugin-sharing / plugin-security middleware
187a247d0 (this head: the fix plus main at 46bb5e3e5) Test Files 1 passed (1) · Tests 13 passed (13)

The bisect pair confirms #24667 as the cause. The case's own subject is unchanged: the holder case still reads 2 rows about its own organization's deleted record and 0 about the other's. That reading needs the grant (now stamped org.a) to be honoured for the holder.

The file runs in exactly one vitest project, isolated (it is not in SHARED_SHOWCASE). The gate runs pnpm turbo run test --filter=@objectstack/dogfood with OS_TEST_SHARD=k/3. The boot log shows the file's two boots at posture single and posture isolated. No boot in this file uses group.

Gates

  • Local, on 187a247d0: the 55 commands of node scripts/pm/dispatch-gates.mjs --commands (narrowed to this diff) all exit 0. --ran reconciles them as 55 derived, 55 run, 0 NOT-MEASURED, 0 UNRUN. pnpm lint (eslint . --no-inline-config): exit 0, no findings.
  • pnpm --filter @objectstack/dogfood run typecheck: exit 0. The tsc program lists this file (--listFilesOnly, 1 hit).
  • Dogfood Regression Gate does not run on pull_request or merge_group, so its first CI reading of this change is main's push battery after the merge. The local red-then-green above is the pre-merge reading.

Changeset

skip-changeset: the diff is one test file in @objectstack/dogfood, a private: true package that publishes nothing. No published package's files[] changes.

Acceptance notes

  • The dispatch expected group and single runs of the same lines. Measured: the vitest projects are shared-showcase and isolated, and the file's boots are single (first describe) and isolated (second). There is no group boot here. Both grant lines answer under the boot they run in: 10 passed before the lift and 13 passed after this fix.

Generated by Claude Code

… holder's organization

Both `sys_user_permission_set` grant inserts in
`audit-log-audit-capability.dogfood.test.ts` ran in system context with no
organization. Under the walled posture a system insert on a tenant-scoped
object must carry one (ADR-0131 D9), so the `isolated`-posture case was
refused with SYSTEM_WRITE_ORGANIZATION_REQUIRED before any assertion ran.

Each grant now carries its holder's organization on the execution context,
the first form the refusal prescribes: the organization the walled case
created for its holder, and on the `single` boot the one organization the
holder is a member of. No assertion changes; the engine rule stays.

Claude-Session: https://claude.ai/code/session_01LmjU2x1faLZ39DVTFyVca6
Co-authored-by: Claude <noreply@anthropic.com>
…ssue-24780-audit-capability-grant-organization
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 20, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

Nothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 0 changed package(s)), so this run has no opinion about the docs.

What this run could not see

Coarse fallback — 0 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json a43405d596d4d670dc761e90c9fc20822dc806a9 → packageMentionDocs.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对 · ACCEPT

domain:cli seat 2 (#22648) · os-justin · session session_01LmjU2x1faLZ39DVTFyVca6 · 2026-10-20T07:17Z · head 187a247d0d · claim 6284594294 → report 6285540070. No contract face (Clause-②: no, a test file only), so no review of record is owed.

Check Reading
Shape Draft, base main. First line Refs #24780, which is correct: the card's row 2 is #24749's, and this seat closes the card after this lands. Clause-②: no line-initial. Assignee os-justin = the card's. skip-changeset is applied and correct: one file under packages/qa/dogfood/test/, and the package is private.
Surface 1 file, audit-log-audit-capability.dogfood.test.ts (+19 / −2), inside the claim. Read on origin/main...187a247d0d: only the two sys_user_permission_set grant writes and a fixture helper change. No case assertion moves, nothing is skipped or re-timed, and resolveSystemInsertOrganization is untouched. check-governed-merges.mjs --pr 24805: NOT governed, 21 changed lines.
Mechanism Both grants carry tenantId on the system context. That is the form the refusal names first, and the one PR #24667 used for its own walled fixtures. The walled case grants with org.a, which the case already holds (:416). The single describe reads the holder's one sys_member row, and two setup guards make an empty id fail instead of falling back to derivation. The file's other system write, the bulk sys_audit_log insert, is outside the rule: sys-audit-log.object.ts:31 declares systemFields: { tenant: false }, read at source.
Evidence The bisect pair names the cause: f7005cbd8 (the parent of fc34d000fc) is 13/13 green, and fc34d000fc (#24667) is 1 failed with the card's refusal. The base 74f78159a reproduces the same red, and the head 187a247d0 is 13/13. That matches the card's runs 39369975004 / 39372642212 and main's latest hourly 39378039597, where this is the only failing dogfood file.
Gates Local: 55/55 derived families exit 0, and --ran reports 0 UNRUN; pnpm lint exit 0. Check-runs on this head (38, latest per name), read at this act: 24 success, 8 skipped (the dogfood shards and the Console Pin Gate, which run on main's battery), 6 in_progress (Lint, Type Check · consumer gates, Test Core 1–3). Landing waits on all of them.

Accepted deviations:

  • Zone 2's item 4 was framed wrongly by this seat: the file runs in the one isolated vitest project, which boots single and isolated, and nothing boots group. The single line answered green both before and after.
  • main (46bb5e3e5) was merged into the branch before the PR, and the file and gates were re-run on that head.
  • The dogfood package's full run was not done locally, a declared narrowing. main's battery read 95/96 with only this file red, and the shards do not run on pull_request or merge_group. The first full reading is main's run after the merge.

Out-of-scope dispositions: none.

Landing: this is the lane's main-red fix, so it is the first PR this lane arms. It goes through the merge queue by this seat once every check on this head reads success (or an expected skip). After it merges, this seat closes #24780 for row 1 and points at #24749 for row 2. The main-side proof is the first hourly run carrying the merge commit.


Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 20, 2026 07:23
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 20, 2026 07:23
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 20, 2026
Merged via the queue into main with commit c56115b Oct 20, 2026
46 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-24780-audit-capability-grant-organization branch October 20, 2026 08:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants