Skip to content

test(dogfood): pin access-security checklist clauses at the api oracle's layer, slice 1 - #26797

Merged
objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/project-thread-czmdl5
Oct 27, 2026
Merged

objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/project-thread-czmdl5

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Warren · project thread

Refs #26571 (slice 1 of about 4, items: access-security.rls-both-sides, access-security.write-path-guards, access-security.crud-permission-matrix, access-security.owd-sharing-matrix, access-security.fls-mask-and-strip)

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:给 access-security 区前 5 个清单条目补上 dogfood 断言(进程内 HTTP,正是这些条款的 oracle 层),共钉住 19 条此前只靠现场手跑的条款;5 个条目的 automated.ref 改写成逐条款对应、revision 加一、history 记本卡。
  • 为什么改:18.2.0 Tier 1 记录 QA run · release-18.2.0-w2-tier1-a (73/73) · 756220c4 · 2026-10-27 · 13 PASS / 60 PARTIAL / 0 FAIL / 0 BLOCKED / 0 NOT-RUN #26468 里这 5 条全是 PARTIAL——旧断言只看状态码、不复读行,或只覆盖部分对象/人设;每次发版都要重新手跑。钉住后成为可重复跑的常备证明。
  • 风险与回滚:只加测试和改清单文字,不动任何产品代码;新增断言全部按现行行为写成并跑绿。dogfood 仍在原有位置运行,没有新 CI 通道。回滚即 revert 本 PR。
  • 先看:① showcase-crud-persona-matrix.dogfood.test.ts 新增的 delegate × sys_* 16 格用例(含 sys_user 的 405);② showcase-readonly-when-parent.dogfood.test.ts 的 updateMany 逐行用例;③ access-security.json 里 crud-permission-matrix 的新 automated.ref。
  • 两分钟验证:cd packages/qa/dogfood && pnpm exec vitest run test/showcase-crud-persona-matrix.dogfood.test.ts(需先按 dogfood 惯例 build 依赖闭包),预期 Tests 49 passed。
  • 需要你做的:无,席位落地。

What changes

Pins at the layer each clause's oracle names (api: the in-process HTTP stack of @objectstack/verify), in packages/qa/dogfood/** only. No product code changes. Every new assertion was written against today's behaviour and is green.

item clauses newly pinned where
rls-both-sides acceptance[2], acceptance[3], negative[0] showcase-private-owd: the admin re-reads the foreign note after the refused PATCH (whole record equal), and the admin's filtered list carries every note the file created
write-path-guards acceptance[0], [4], [5], [6], negative[0] showcase-static-readonly: INSERT strip advertised in body droppedFields and the X-ObjectStack-Dropped-Fields header. owner-anchor-and-bulk-writes: member REST createMany stamps the caller on all three rows; the admin's forge-insert and disown pass. showcase-readonly-when-parent: the paid line's product is held; a mixed updateMany reports results[i].droppedFields (readonly_when) on the locked row only, and the open row lands; updateMany with continueOnError: true fails the row below min: 0 alone (VALIDATION_FAILED, unchanged) and applies both neighbours, with the default stop shape (tail NOT_ATTEMPTED) pinned beside it
crud-permission-matrix acceptance[0], [1], [3], [6], negative[0] showcase-crud-persona-matrix: the auditor's viewAllRecords over a foreign inquiry, invoice and line (by id and filtered list) against a contributor who holds read without the bit; the first denied cell of every set re-run as the admin answers 2xx; and the 16 showcase_field_ops_delegate × sys_* cells driven by a member holding exactly that set, with sys_user create and delete scored 405 OBJECT_API_METHOD_NOT_ALLOWED for the delegate and the admin
owd-sharing-matrix acceptance[0], [1], [4], [5] showcase-private-owd / showcase-public-read-owd: non-2xx by-id read, PATCH at least 400, admin re-read unchanged. New showcase-invoice-line-contributor-pair (shared-showcase project): two stock showcase_contributor members C1/C2 and a stock showcase_auditor; C2's filtered list excludes C1's line while C1's identical list carries it, C2's by-id read and PATCH are refused with the row unchanged, C1 reads and edits it, the auditor lists and reads it
fls-mask-and-strip acceptance[0], [2] showcase-permission-zoo: the contributor's name edit re-reads changed; the admin's budget write on a seeded project lands and re-reads changed (raised, then put back)

Ledger: each of the five items gets a rewritten automated.ref that maps clauses to cases, revision +1, and a history row citing #26571. The owd-sharing-matrix ref also names two existing showcase-crud-persona-matrix cases that already pinned its acceptance[2] (modifyAllRecords) and acceptance[3] (showcase_contributor / showcase_member_default × showcase_project edit cells), which revision 5 recorded as unpinned.

vitest.config.ts: the new file joins SHARED_SHOWCASE. It meets that list's three eligibility rules: plain showcase boot, only sys_user_permission_set rows for its own sign-ups, and every list filtered to its own row.

Clauses left as they are, each with its reason in the item's automated.ref:

  • rls-both-sides acceptance[5], negative[1], negative[2]: procedural (a reading of the verify report, run-record rules), and the D11 spot-check needs the private write-up.
  • crud-permission-matrix acceptance[5]: blocked(fixture) per knownGaps[2] (the guest anchor intake is not observable on a member persona).
  • owd-sharing-matrix acceptance[6]: procedural (run-record completeness).
  • fls-mask-and-strip acceptance[3] and the UI half of acceptance[4]: dom / browser oracle. The dogfood suite drives no browser and the ruling adds no CI lane, so they stay a run's browser leg.

Tests

Head fd634911, the eight touched files, under os-verify-lock: Test Files 8 passed (8), Tests 103 passed (103) (VERDICT command-exit 0). pnpm --filter @objectstack/dogfood typecheck: exit 0. The full dogfood battery is CI's (no ! in the title, no narrowing arm).

Acceptance notes

  • crud-permission-matrix acceptance[6].verify and steps[6] still describe the 16 delegate cells as hand-driven, and the same file's header comment said "6 delegate rows" (now corrected to 4 in the test header). The two item-text fields sit outside this slice's claimed edit surface (automated.ref, revision, history); the history row says so.
  • Measured on head fd634911: the delegate's 16 cells answer exactly the matrix, unioned with nothing — sys_business_unit, sys_business_unit_member and sys_user read 200, every withheld verb 403 PERMISSION_DENIED, sys_user create and delete 405, sys_user_position create 201 and read/edit/delete 200 on the delegate's own in-subtree row.

Verification

Local gate subset on head fd634911 (origin/main merged, including #26337): node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derives 55 families; all 55 ran and exited 0, and --ran reconciles 55 derived famil(ies) accounted for — 55 run, 0 NOT-MEASURED. Repository-wide scans (pnpm lint, the full dogfood battery) are CI's.

node scripts/check-platform-checklist.mjs: check-platform-checklist: OK — 16 areas, 329 items (324 active, 1 planned).

Changeset: none. @objectstack/dogfood is private and docs/qa/** ships in no package, so this PR carries skip-changeset.

Template note: .github/PULL_REQUEST_TEMPLATE.md's Why is folded into 维护者速读 and What changes; its Human Minimum items hold as follows: 1 n/a (no spec), 2 yes, 3 no formatter ran, pnpm lint left to CI, 4 yes, 5 n/a (publishes nothing), 6 n/a, 7 yes, 8 yes.


Generated by Claude Code

…s layer (#26571)

Items: rls-both-sides, write-path-guards, crud-permission-matrix,
owd-sharing-matrix, fls-mask-and-strip. Each item's automated.ref names
the new cases, revision bumped, history row cites the card.

Claude-Session: https://claude.ai/code/session_01JQwxbWKBLcQCG7FBS17aMA
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 27, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

1 anchor(s) derived from 1 changed package(s); no hand-written page names any of them, so this run has nothing to list — not a clean bill of health. This check sees only pages that NAME a derived anchor: one that documents this change in prose, or enumerates it in an authoring dialect, names none and stays invisible to it on every run.

What this run could not see

Coarse fallback — 2 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 665059b6056c4caf54e631d678203d8c9dc4aba3 → packageMentionDocs.

Which tree this was computed on

This run read content/docs from 227eab16f199ea47de6f7682c7b41bda399d9f02 — the merge of head fd634911182e3356a394d7859d8ce95b72e44e81 into base 665059b6056c4caf54e631d678203d8c9dc4aba3, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 227eab16f199ea47de6f7682c7b41bda399d9f02 && git checkout 227eab16f199ea47de6f7682c7b41bda399d9f02
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 665059b6056c4caf54e631d678203d8c9dc4aba3 fd634911182e3356a394d7859d8ce95b72e44e81 && git checkout -B drift-repro 665059b6056c4caf54e631d678203d8c9dc4aba3 && git merge --no-ff fd634911182e3356a394d7859d8ce95b72e44e81

node scripts/docs-audit/affected-docs.mjs --json 665059b6056c4caf54e631d678203d8c9dc4aba3

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

维护者速读

  • 改了什么:access-security 区前 5 条清单项(RLS 两侧、写路径守卫、CRUD 权限矩阵、OWD 共享矩阵、FLS 掩码与剥离)里 19 个「部分覆盖」条款,现在都在接口层有了钉测。新增 1 个共用 showcase 的测试文件,另扩了 7 个现有 dogfood 测试;线程本地 103/103 全绿。5 条清单项各自的 automated.ref、修订号和历史行都已更新。
  • 为什么改:这些安全条款以前只在更低一层被断言,或只靠手工现场测试,每次发版扫描都只能记成「部分」。
  • 风险与回滚:只加测试和清单文字,不改产品代码;回滚 = revert 本 PR。Dogfood Regression Gate 不在 PR 和合并队列上跑,这批钉测要到 main 的下一次全量跑才首次在 CI 上执行。
  • 先看:showcase-invoice-line-contributor-pair.dogfood.test.ts(两个贡献者互相看不到、改不了对方的明细行,审计员能看全),以及 showcase-crud-persona-matrix.dogfood.test.ts 新加的 16 格 delegate × sys_* 用例。
  • 两分钟验证:node scripts/check-platform-checklist.mjs,退出 0。
  • 需要你做的:无,席位落地。余下 13 条由后续批次派发。
  • 席位意见:每个越权用例都用管理员重读确认数据没变,也都配了「有权的一侧能做」的对照,所以不会靠一个一律拒绝的门变绿。

席位核对

ACCEPT · domain:devx#1 · session_01JQwxbaFpnMwgpCgneKe2qS · head fd63491118 · 2026-10-27T16:26Z

  1. Shape: 10 files, +554/−26: docs/qa/platform-checklist/areas/access-security.json, eight packages/qa/dogfood/test/*.dogfood.test.ts (one new) and one line in packages/qa/dogfood/vitest.config.ts, which registers the new file in SHARED_SHOWCASE so it boots on the shared showcase. Not governed (check-governed-merges --pr 26797, 580 lines ≤ 3000). File surface as in claim 6445125819; Refs #26571. Slice 1 is the first five items in card order.
  2. Read by the seat: the new contributor-pair file and the added cases in the extended files. Every refused cross-owner read or write is checked by an admin re-read showing the row unchanged, and each carries an entitled-side control. The isSystem contexts appear only in setup and in re-reads, never in the call under test. The crud matrix's delegate rows are now a dedicated case, with its header comment reworded to match.
  3. Gates: head check-runs on fd63491118: 36 success, 16 skipped, 0 failing; check-expected-skips --pr 26797: OK, all 16 in main's roster. Thread's local run: 103/103 tests, dogfood typecheck exit 0, dispatch-gates 55/55 exit 0, check-platform-checklist OK. Report 6447169639.
  4. Accepted deviations: the dogfood battery does not run on pull_request or merge_group, so these pins first run in CI on main's next full battery; a red there is main-red and this seat stanches it. owd-sharing-matrix's ref now also cites existing crud-matrix cases that already pin its a2/a3, correcting revision 5's "no pin". Clauses that stay unpinned keep their reasons in the refs: procedural clauses, crud a5 blocked(fixture), and fls a3 plus the UI half of a4, which are browser clauses with no new lane.
  5. Out of scope: crud-permission-matrix acceptance[6] verify and steps[6] still describe the 16 delegate cells as hand-driven. That is item text outside this slice's claim surface, and the next #26571 slice carries it (noted in the history row). Skills-docs: not owed.
  6. Landing: not governed, CI green on this head, mergeable clean ⇒ the seat readies it and arms auto-merge through the relay. The card stays pm:dispatched for the next slice.

Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 27, 2026 16:29
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 27, 2026
Merged via the queue into main with commit c8583f8 Oct 27, 2026
53 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-czmdl5 branch October 27, 2026 16:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/l 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