Skip to content

test(dogfood): pin five records-forms checklist items at the REST door (slice 1) - #26788

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

objectstack-fleet[bot] merged 6 commits into
mainfrom
claude/project-thread-jcuzjj

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Warren · project thread

Refs #26573 (slice 1 of about 5 items: predicate-relationship-traversal, write-answer-advisories-rollback-and-tree-delete, comment-reactions-and-edit-stamps, encrypted-field-behavior, write-time-option-and-element-shape-judgement)

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:records-forms 区 5 个清单项的 api 条款原先只有引擎层/进程内的钉测,现在新增 5 个 dogfood 测试文件,在真实启动的栈上经 REST 门断言这些条款,并把 5 项的 automated.ref 改为指向新钉测(revision 各加 1,history 引本卡)。
  • 为什么改:18.2.0 Tier 1 扫描把这些条款判为 PARTIAL(钉测低于条款 oracle 的层);按维护者「同意」的分卡,每次发版都要补跑活腿,钉在 oracle 层之后就是常驻可复跑的证据。
  • 风险与回滚:只加测试和清单文字,不动产品代码、不加 CI 车道;新文件跑在现有 dogfood 腿里(isolated 项目)。回滚即 revert 本 PR。
  • 先看:packages/qa/dogfood/test/encrypted-field-behavior.dogfood.test.ts(无加密提供者的 fail-closed 腿是启动后把引擎的 provider 置空,看这个建模是否可接受);packages/qa/dogfood/test/comment-reactions-and-edit-stamps.dogfood.test.ts(实测码 405 / 403);docs/qa/platform-checklist/areas/records-forms.json 的 5 处 automated 与 history。
  • 两分钟验证:pnpm --filter @objectstack/dogfood exec vitest run --maxWorkers=2 test/predicate-relationship-traversal.dogfood.test.ts test/write-answer-warnings-rest.dogfood.test.ts test/comment-reactions-and-edit-stamps.dogfood.test.ts test/encrypted-field-behavior.dogfood.test.ts test/write-time-option-and-element-shape.dogfood.test.ts(先建依赖闭包),预期 5 个文件 22 个用例全绿;node scripts/check-platform-checklist.mjs 预期 OK。
  • 需要你做的:无,席位落地。

What changes

Five new dogfood files, each booting a real stack through @objectstack/verify and driving the REST doors (/data/:object, /data/:object/query, /data/:object/import), so these api clauses are pinned at the layer their oracle names:

Item (rev → new) Clauses now pinned over REST Pin
predicate-relationship-traversal (4 → 5) acceptance[0]–[3], negative[0]–[2] predicate-relationship-traversal.dogfood.test.ts — the showcase invoice rule as shipped, plus the scratch pair fixtures.knownGaps describes for a member with no parent grant
write-answer-advisories-rollback-and-tree-delete (2 → 3) acceptance[1]; acceptance[2] and negative[0] write-answer-warnings-rest.dogfood.test.ts (new) reads the PATCH body's warnings[]; the existing hook-after-abort-rollback.dogfood.test.ts already refused the aborting create over REST and read the store back, and is now named
comment-reactions-and-edit-stamps (3 → 4) acceptance[1]–[3] comment-reactions-and-edit-stamps.dogfood.test.ts — org-bound comments fixture + plugin-audit, the member armed (assertArmed) as org_member
encrypted-field-behavior (5 → 6) acceptance[2]–[4], negative[1]–[3] encrypted-field-behavior.dogfood.test.ts — showcase field zoo for the echoed mask and the aggregate refusal; a scratch object on an engine left with no crypto provider for fail-closed
write-time-option-and-element-shape-judgement (1 → 2) acceptance[1]–[4] write-time-option-and-element-shape.dogfood.test.ts — scratch app: faulting option gate, kept-option import, matched-row dry run, multi-lookup element shape

Each item's automated.ref names the new pin and what it scores; the existing engine/unit pins stay named as acceptance[0]'s pins and as evidence of their own layer (RUNNER rule 6). One history row per item, citing #26573. No clause text, fixture, step or knownGaps line was edited (the claim's file surface).

Left out of this slice: record-discussion-mentions a9 (needs the #26625 walled two-organization recipe) and the browser/dom-oracle items, which need Playwright or live-boot specs.

Why

The 18.2.0 release-candidate Tier 1 run scored these clauses PARTIAL: every pin was green, but each asserted the clause below its oracle's layer (in-process protocol calls, ObjectQL directly, or an ObjectKernel with no HTTP adapter). A pin at the oracle's layer turns a release-sweep live leg into a standing, re-runnable proof. The triage ruling allows ~5-item slices and no new CI lane; the new files fall under the dogfood package's existing isolated vitest project and run where the dogfood legs run today.

Tests

Measured answers the pins now hold (all first read live, then pinned exactly):

  • reaction PATCH → 405 OBJECT_API_METHOD_NOT_ALLOWED (the object's apiMethods offers no update); foreign reaction DELETE → 403 PERMISSION_DENIED with the member holding the object delete bit, so the refusal is the own-record floor; own DELETE is the 2xx control.
  • the warning-rule PATCH → 200 with warnings: [{ rule: project_health_progression, severity: warning, field: health, code: invalid_transition, message }]; one-step change and the create answer carry no warnings key.
  • faulting option → 400 VALIDATION_FAILED, tier / rule_violation, constraint.rule: visibleWhen, constraint.reason: unevaluable.
  • multi-lookup elements {id}, false, 42 → 400 refs / invalid_type, constraint.detail starting at index 1:.
  • credential group-by / MIN / MAX over POST /data/showcase_field_zoo/query → 400 INVALID_FIELD; a group-by on name is the 200 control.
  • fail-closed secret POST → 500 INTERNAL_ERROR and no row stored; a password write on the same engine → 201, masked on read.
Runs
  • Dependency closure: pnpm exec turbo run build --filter='@objectstack/dogfood^...' --concurrency=2 under os-verify-lock.sh → Tasks: 67 successful, 67 total, VERDICT command-exit 0.
  • First run (pre-merge head): pnpm --filter @objectstack/dogfood exec vitest run --maxWorkers=2 over the five files → Test Files 5 passed (5), Tests 22 passed (22).
  • After merging origin/main (head 8919aecc, which brought a driver-sql refactor): pnpm --filter @objectstack/driver-sql build, then the five files plus hook-after-abort-rollback.dogfood.test.ts → Test Files 6 passed (6), Tests 28 passed (28), VERDICT command-exit 0.
  • pnpm --filter @objectstack/dogfood typecheck (tsc --noEmit) → VERDICT command-exit 0.
  • Final head 5db5a474 (after merging origin/main with feat!: ownership queues and assignment rules (ADR-0142 phase 2) #26337): the dependency closure rebuilt (Tasks: 67 successful, 67 total), then the five files plus hook-after-abort-rollback.dogfood.test.ts → Test Files 6 passed (6), Tests 28 passed (28), then pnpm --filter @objectstack/dogfood typecheck, one locked command, VERDICT command-exit 0.

No ablation was run: this diff adds tests and changes no behaviour they pin (os-dev: ablation only where the diff changes a pinned behaviour). Each refusal assertion has a same-door admitted control beside it, so none passes on a door that refuses everything.

Acceptance notes

  • encrypted-field-behavior acceptance[3]: bootStack always wires a crypto provider, so the fail-closed leg unsets it once after bootstrap (engine.setCryptoProvider(undefined)), before any request. That is the engine state of a boot that never wired one; no stock composition boots that way, so on a live stock boot the clause stays blocked(fixture). fixtures.knownGaps[1] still says the path has "NO live leg"; it is still true of a live boot, and its rewording is left to an item-text pass since this slice's surface is automated.ref / revision / history only. The refusal arrives as the sanitised 500 INTERNAL_ERROR, because the engine throws a plain Error: noted, not filed, since an unwired provider is a host composition fault, not an author error.
  • predicate-relationship-traversal acceptance[3]: now scored live on the scratch substitute the item's fixtures.knownGaps already prescribes, rather than only from the engine pin.
  • write-answer-advisories… acceptance[2] / negative[0] were already pinned over REST by hook-after-abort-rollback.dogfood.test.ts (it reads the store back through the engine rather than a list count); revision 2 did not name it.

Verification

  • node scripts/check-platform-checklist.mjs → exit 0, OK — 16 areas, 329 items (324 active, 1 planned).
  • node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack → 55 commands on head 8919aecc, each run and reconciled with --ran: 55 derived famil(ies) accounted for — 54 run, 1 NOT-MEASURED. The NOT-MEASURED one is pnpm check:dual-build-cjs-loads (exit 3, PREREQUISITE NOT MET: it reads every package's dist/ and this worktree built only the dogfood closure); CI runs it. check-plugin-teardown-shape --self-test first exited 3 on the shallow clone and is exit 0 after git fetch --unshallow.
  • After merging origin/main again (it brought feat!: ownership queues and assignment rules (ADR-0142 phase 2) #26337, which touches coverage.json and packages/qa/dogfood/test): check-platform-checklist exit 0 on the new head; the five files are re-run there (see Runs).
  • CI families are read from this PR's check-runs, not re-run locally.

Human Minimum

  • 1. Schemas start as Zod; packages/spec holds no runtime logic. (not touched)
  • 2. Every name I added uses the casing for its kind.
  • 3. No formatter ran; pnpm lint passes. (CI-owned run)
  • 4. One issue, one branch off an up-to-date main, one pull request.
  • 5. A change that publishes carries a changeset — nothing publishes here (@objectstack/dogfood is private; docs/qa/** ships in no package), so skip-changeset; both declaration lines are filled in above.
  • 6. packages/spec not touched.
  • 7. No hand edits to content/docs/references/, packages/*/CHANGELOG.md or content/docs/releases/.
  • 8. Title, body and comments are in English (the maintainer brief above is Chinese by the repo's communication rule).

Generated by Claude Code

@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 0f3d068cf1299470995840795bc5687ec42d95f1 → packageMentionDocs.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

维护者速读

  • 改了什么:records-forms 区第一批 5 条清单项(谓词跨关系遍历、写入回执的提示/回滚/树删除、评论表情与编辑戳、加密字段行为、写入时选项与元素形状判定),18.2.0 评为「部分覆盖」的接口条款现在都有了走 REST 的钉测。新增 5 个独立的 dogfood 测试文件,线程本地 28/28 全绿;每条清单项的 automated.ref、修订号和历史行都已更新。
  • 为什么改:这些条款原先只在更低一层被断言,每次发版扫描都只能记「部分」或手工补跑。
  • 风险与回滚:只加测试和清单文字,不改产品代码;回滚 = revert 本 PR。Dogfood Regression Gate 不在 PR 和合并队列上跑,这批钉测要到 main 的下一次全量跑才首次在 CI 上执行。
  • 先看:encrypted-field-behavior.dogfood.test.ts 的「无加密提供者 → 拒写」一段,它在启动后撤掉引擎的加密提供者;以及 areas/records-forms.json 里这 5 条的历史行。
  • 两分钟验证:node scripts/check-platform-checklist.mjs,退出 0。
  • 需要你做的:无,席位落地。余下 16 条由后续批次派发,其中 record-discussion-mentions a9 要等 qa(checklist): records-forms — provisioning recipes for a walled two-organization mention leg, a packaged action specimen, and the app-crm import specs #26625 的配方。
  • 席位意见:每个拒绝用例都同时断言「什么都没存」,也配了对照用例;撤掉加密提供者是测试内部的做法,在文件头、automated.ref 和 PR 正文都已申明。

席位核对

ACCEPT · domain:devx#1 · session_01JQwxbaFpnMwgpCgneKe2qS · head 5db5a47448 · 2026-10-27T16:06Z

  1. Shape: 6 files, +880/−11: five new packages/qa/dogfood/test/*.dogfood.test.ts and docs/qa/platform-checklist/areas/records-forms.json. Not governed (check-governed-merges --pr 26788, 891 lines ≤ 3000). File surface as in claim 6445199361; Refs #26573 (slice 1 of 21).
  2. Read by the seat: each new file is one describe per item with acceptance/negative-numbered cases. Refusals assert the code and that nothing was stored, and each refusal block carries a control. Two cases bear on test validity. The fail-closed leg runs on its own boot and unsets the provider once before any request, so it cannot leak into the provider-wired describe. The member who cannot read the parent has a control asserting that the read really is denied. The JSON edits touch only automated.ref, revision and history, each history row citing qa(checklist): records-forms — pin the Tier 1 clauses the 18.2.0 sweep scored partial at the layer their oracle names (21 items) #26573.
  3. Gates: head check-runs on 5db5a47448: 35 success, 16 skipped, 0 failing; check-expected-skips --pr 26788: OK, all 16 in main's roster. Thread's local run: 28/28 tests, check-platform-checklist exit 0, --ran 55 accounted, 54 run, 1 NOT MEASURED (dual-build-cjs-loads, needs a full build). Report 6446486436.
  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. engine.setCryptoProvider(undefined) after boot is the only way to reach the fail-closed arm, because bootStack always wires a provider. Item text outside the claim surface is left for an item-text pass: encrypted-field-behavior knownGaps[1], and predicate-relationship-traversal acceptance[3] verify.
  5. Out of scope: noted, not filed: with no crypto provider the engine's refusal is a plain Error, so REST answers the sanitised 500 INTERNAL_ERROR. That is a host composition fault no stock boot reaches. 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

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