Skip to content

test(dogfood): pin the last access-security checklist clauses at the oracle's layer, slice 4 - #26941

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

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

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Warren · project thread

Fixes #26571 (slice 4 of 4, items: access-security.parent-and-organization-write-guards, access-security.deployment-tables-platform-only, access-security.share-link-combined-gates)

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:access-security 区最后 3 个清单条目补上 dogfood 断言(进程内 HTTP,即这些条款 oracle 指定的层),新增 3 个隔离用例文件,共钉住 8 条此前只在引擎层或单元层的条款。3 个条目的 automated.ref 逐条款改写,其中 deployment-tables-platform-only 和 share-link-combined-gates 的 automated.kind 改为 dogfood;每个条目 revision 加一、history 记本卡。本片之后 qa(checklist): access-security — pin the Tier 1 clauses the 18.2.0 sweep scored partial at the layer their oracle names (18 items) #26571 无剩余条目。
  • 为什么改: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 把这 3 条判为 PARTIAL:组织字段清空拒绝、表头存在性对等、部署级表的两类人员、分享链接组合关卡,都没有走 HTTP 的断言。
  • 风险与回滚:只加测试和改清单文字,不动产品代码,不加 CI 通道。回滚即 revert 本 PR。
  • 先看:① parent-and-organization-write-guards.dogfood.test.ts(posture-only 隔离启动下清空 organization_id 被 403,以及不可读与不存在表头返回相同 400);② share-link-combined-gates.dogfood.test.ts(匿名各变体字节级相同的拒绝体,/resolve 与 /messages 配对);③ Acceptance notes 里关于 controlled_by_parent 明细返回 403 而非 400 的说明。
  • 两分钟验证:cd packages/qa/dogfood && pnpm exec vitest run test/parent-and-organization-write-guards.dogfood.test.ts(需先按 dogfood 惯例 build 依赖闭包),预期 Tests 6 passed。
  • 需要你做的:无,席位落地。

What changes

Each clause is pinned at the layer its oracle names: api is the in-process HTTP stack of @objectstack/verify. All changes are in packages/qa/dogfood/** plus the area ledger, with no product code changes. Every new assertion was written against today's behaviour and is green. All three files boot their own showcase (isolated), since each writes records, mints links or creates an organization.

item clauses newly pinned where
parent-and-organization-write-guards acceptance[1], [2], negative[0] New parent-and-organization-write-guards. acceptance[1]: a multiTenant: 'posture-only' boot (the tenancy service reports isolated, the wall active and not degraded, asserted). An organization owner who is not the platform administrator PATCHes their own showcase_private_note with organization_id: null and gets 403 PERMISSION_DENIED; the row keeps its organization, and the same caller's PATCH that leaves the column alone is admitted. Inserts sending organization_id null and '' are stamped with the caller's active organization. acceptance[2] / negative[0]: a member holding a scratch set that writes showcase_task and whose row policy selects no showcase_project POSTs a task naming a seeded project it cannot read (asserted) and one naming a project id that exists nowhere. Both answer 400 with reference_not_found, and the bodies are equal field by field once the named id is normalised. Nothing lands, and the admin's identical POST lands. The same parity is measured on the controlled_by_parent invoice line, as described in the Acceptance notes
deployment-tables-platform-only acceptance[1], [2] New deployment-tables-platform-only. A Default Organization member's sys_member role is promoted to admin. A guard asserts it resolves an organization_admin set, holds no manage_platform_settings, and is not the platform administrator. On each of the seven tables (sys_job, sys_job_queue, sys_job_run, sys_migration, sys_migration_journal, sys_flow_dispatch, sys_presence), GET /api/v1/data/TABLE is 403 PERMISSION_DENIED for the org admin and 200 for the platform administrator. The platform administrator's URL-encoded organization_id filter is 400 INVALID_FIELD on each
share-link-combined-gates acceptance[1], [2], [3], negative[0] New share-link-combined-gates. The admin mints two links through POST /api/v1/share-links on the seeded published client brief. Link A (signed_in + password), resolved anonymously with no password, a wrong one and the right one (UTF-8 header form), answers 401 SIGN_IN_REQUIRED with three byte-identical bodies. Link B (email + password) answers 404 INVALID_OR_EXPIRED to five non-entitled variants, byte-identical with an unknown token's body; the allowlisted email with the right password resolves 200. The same eight calls are paired with /messages: 404 NOT_FOUND wherever /resolve refused, and 400 UNSUPPORTED on the one call it passed

Ledger:

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

  • Every item's acceptance[0] is the pin run itself (test oracle).
  • parent-and-organization-write-guards acceptance[3] was already pinned over HTTP by cbp-parent-attachment-comment-gates and cbp-explain-master-write.

No clause is left as a live leg.

Tests

On head bc2b4dce (origin/main merged), with the closure rebuilt, the three new files ran under os-verify-lock: Test Files 3 passed (3), Tests 25 passed (25) (VERDICT command-exit 0). That is 15 in deployment-tables-platform-only, 4 in share-link-combined-gates and 6 in parent-and-organization-write-guards. pnpm --filter @objectstack/dogfood typecheck: exit 0. The final merge of main, right before this PR, brought crud-permission-matrix's ledger row (#26923, no overlap with these three items), app-shell fixes, docs, and two runtime/metadata-protocol refusals that none of these doors read. The full dogfood battery is CI's.

Acceptance notes

  • parent-and-organization-write-guards acceptance[2]: on the controlled_by_parent line (showcase_invoice_line), a stock contributor naming another contributor's invoice and one naming a missing invoice both get the ADR-0055 §3 master-edit gate's 403 PERMISSION_DENIED. That gate runs before the reference check. The two bodies are byte-identical, so negative[0] holds there, and the file pins that. The 400 reference_not_found comparison is pinned on showcase_task, a plain master_detail detail of showcase_project. That matches engine-unreadable-master-detail-header.test.ts, whose controls keep a controlled_by_parent detail unchanged. If the item's clause is meant to require 400 on the controlled_by_parent fixture too, that is a clause question for the seat, not a pin gap.
  • parent-and-organization-write-guards acceptance[2]: every showcase member reads projects through the stock baseline. So the scratch set narrows showcase_project with a row policy that selects nothing, and a guard asserts the member's by-id read is refused.
  • The item's knownGaps about provisioning a walled os serve boot are unchanged. They describe the live run's fixture. The pin uses the in-process posture-only walled boot that no-active-organization-write-refusal and wall-catalog-refusal already use.

Verification

Local gate subset on head bc2b4dce (origin/main merged): 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 section is folded into 维护者速读 and What changes. Its Human Minimum items: 1 n/a (no spec); 2 yes; 3 no formatter ran, and pnpm lint is left to CI; 4 yes; 5 n/a (publishes nothing); 6 n/a; 7 yes; 8 yes.


Generated by Claude Code

claude added 13 commits October 27, 2026 14:55
…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>
…layer, slice 2

Slice 2 covers anonymous-deny-surfaces, public-form-withdrawal-layers,
activation-write-operator-gate, platform-owner-email-anchor and
record-view-read-audit: two pins extended, three new isolated pins,
and each item's automated.ref, revision and history updated. No
product code changes.

Claude-Session: https://claude.ai/code/session_01JQwxbWKBLcQCG7FBS17aMA
Co-authored-by: Claude <noreply@anthropic.com>
…layer, slice 3

Slice 3 covers anonymous-floor-v18-doors,
meta-authoring-trail-and-audience-gates,
security-catalog-activation-and-clone-doors,
security-catalog-one-holder-and-boot-report and
grant-table-write-contract: four pins extended, four new isolated
pins, each item's automated.ref, revision and history updated, and
automated.kind set to dogfood where the ref now leads with a dogfood
pin. No product code changes.

Claude-Session: https://claude.ai/code/session_01JQwxbWKBLcQCG7FBS17aMA
Co-authored-by: Claude <noreply@anthropic.com>
…oracle's layer, slice 4

Three new isolated showcase pins drive the clauses the 18.2.0 sweep scored
PARTIAL over in-process HTTP:

- parent-and-organization-write-guards: the walled organization-emptying
  PATCH (403 PERMISSION_DENIED, empty-org inserts stamped) on a posture-only
  boot, and unreadable/nonexistent master parity on a plain master_detail
  detail and on the controlled_by_parent invoice line;
- deployment-tables-platform-only: org admin 403 and platform admin 200 on
  the seven deployment-level tables, and 400 INVALID_FIELD on an
  organization_id filter;
- share-link-combined-gates: anonymous byte-identical refusals across the
  password and email variants, and the resolve/messages pairing.

The ledger items get the new refs, revisions and history rows, with kind
moved to dogfood where the ref now leads with the dogfood pin.

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

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 7a2818c57a21c96a1634e1598cb82066bc320a65 → packageMentionDocs.

…s pin header

Comment-only: the file pins 400 reference_not_found on showcase_task with the
admin control, and the master-edit gate's identical 403 on the
controlled_by_parent invoice line with the invoice owner's control.

Claude-Session: https://claude.ai/code/session_01JQwxbWKBLcQCG7FBS17aMA
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

维护者速读

席位核对

ACCEPT · domain:devx#1 · session_01JQwxbaFpnMwgpCgneKe2qS · head fe7797eadd · 2026-10-27T22:48Z

  1. Shape: 4 files: docs/qa/platform-checklist/areas/access-security.json, and the new files parent-and-organization-write-guards, deployment-tables-platform-only and share-link-combined-gates (.dogfood.test.ts). Not governed (check-governed-merges --pr 26941, 483 changed lines ≤ 3000). File surface as in claim 6445125819; Fixes #26571 (slice 4, the last).
  2. Read by the seat: the whole diff, plus the comment-only follow-up fe7797ea.
    • Write guards. The walled describe boots multiTenant: 'posture-only'. It asserts that the tenancy service reports isolated, active and not degraded, and that the caller is not the platform administrator. The organization_id: null PATCH gets 403 with the organization kept; the control PATCH is admitted. Inserts sending null and '' are stamped with the active organization.
    • Header parity. On showcase_task, the parity uses a scratch task-writer set whose row policy selects no project; the guard asserts that the project is unreadable. Both bodies are 400 reference_not_found, equal once the id is normalised, and nothing lands; the admin control does land. On the controlled_by_parent invoice line, the ADR-0055 §3 gate answers first, with one 403 body for both; the C1 control lands.
    • Deployment tables. The org admin is promoted through sys_member.role. The guard asserts that it holds organization_admin, lacks manage_platform_settings and is not the platform administrator. Across all seven tables it gets 403, the platform admin gets 200, and the organization_id filter gets 400 INVALID_FIELD.
    • Share links. Two links are minted through the real door. For link A, the three password variants answer byte-identical 401. For link B, five variants and an unknown token answer byte-identical 404, and the allowlisted 200 is the control. The eight resolve/messages pairs follow the gate, and the open pairing is exercised exactly once.
    • Ledger. The ledger refs describe exactly these legs. automated.kind changes to dogfood on the two items that now lead with a dogfood pin. Each file boots its own stack, and no SHARED_SHOWCASE file is touched.
  3. Gates: head check-runs on fe7797eadd: 34 success, 12 skipped, 0 failing; check-expected-skips --pr 26941: OK; mergeable clean. Thread's local run: 25/25 tests, dispatch-gates 55/55, check-platform-checklist OK. Report 6455122595.
  4. Accepted deviations: for controlled_by_parent details, acceptance[2]'s 400 is pinned on a plain master_detail detail, because there the master-edit gate's 403 answers first by design. negative[0]'s no-existence-oracle holds on both. The dogfood battery does not run on pull_request or merge_group, so these pins first run on main's next full battery. A red there is main-red, and this seat stanches it.
  5. Out of scope: none. 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. At merge qa(checklist): access-security — pin the Tier 1 clauses the 18.2.0 sweep scored partial at the layer their oracle names (18 items) #26571 closes and leaves pm:dispatched.

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 27, 2026 22:48
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 27, 2026 22:48
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 27, 2026
Merged via the queue into main with commit 912076f Oct 27, 2026
47 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-czmdl5 branch October 27, 2026 23:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/m 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.

qa(checklist): access-security — pin the Tier 1 clauses the 18.2.0 sweep scored partial at the layer their oracle names (18 items)

2 participants