Skip to content

docs(qa): records-forms provisioning recipes for the walled mention leg, a packaged action specimen and the app-crm import spec - #26929

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

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

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Requested by Warren · project thread
Fixes #26625

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:在 records-forms 检查单里补了三份测试数据配方:双组织 walled 启动下的 @提及跨组织腿、一个经包加载器安装的 action 样本、一套 app-crm 启动加环境变量让导入撤销的控制台 spec 原样能跑。三个条目各实跑一次,结果写进 history。
  • 为什么改:18.2.0 第二波里这三个条目有 clause 因为缺测试环境一直打不了分。维护者原话:「补测试数据配方。立卡」。
  • 风险与回滚:只改一个 JSON 账本文件,没有产品代码、没有发布内容。回滚就是 revert 本 PR。
  • 先看:① records-forms.json 新增的两个区级配方 qaact-placement-specimen 和 qa-crm-import-console;② record-discussion-mentions 的 steps[13] 新写的 walled 序列;③ 三个条目新加的 history 行。
  • 两分钟验证:跑 node scripts/check-platform-checklist.mjs,应该看到 OK,并且 10/10 recipes referenced。
  • 需要你做的:无,席位落地。

What changes

docs/qa/platform-checklist/areas/records-forms.json only.

  • New area recipe qaact-placement-specimen. It installs a package through POST /api/v1/marketplace/install-local (namespace qaact) with three url actions bound to showcase_task: qaact_control and qaact_visible_throws on list_item and record_header, where the second has a visible predicate that throws at evaluation, and qaact_no_locations with no locations key. The package loader's actions are joined into the served object (registry.ts#attachBoundActions). Runtime-authored ones are not, which is why the old probe could not work. action-location-matrix opts in, and its knownGaps[2] now says the recipe closes the gap and which surfaces count as evidence.
  • New area recipe qa-crm-import-console. It boots app-crm (pnpm dev:crm -- --fresh -p PORT) behind the console dev server (DEV_PROXY_TARGET=… pnpm --filter @object-ui/console dev), so ui/e2e/import-console/import-console-undo.spec.ts runs as committed on its own defaults (crm_app / crm_lead, port 5180). The API half replays against crm_lead. import-job-undo-cancel opts in, and its knownGaps[0] is rewritten.
  • The walled two-organization mention leg is folded into record-discussion-mentions. That item already uses qa-feeds-disabled, and fixtures.provisioning.use takes one recipe (the checker accepts no list and refuses an unreferenced recipe), so the seat ruled to write the leg into the item. steps[13] carries the literal sequence, fixtures.requires[2] names the group-posture boot and its three variables, and knownGaps[2] says the leg is driven live. The sequence grants the mention target read on sys_comment through a scratch permission set (namespace qamention), because no showcase permission set grants it.
  • Each item gets one history row citing qa(checklist): records-forms — provisioning recipes for a walled two-organization mention leg, a packaged action specimen, and the app-crm import specs #26625, with a revision bump: action-location-matrix 15 → 16, import-job-undo-cancel 7 → 8, record-discussion-mentions 9 → 11 (after test(dogfood): pin the last records-forms checklist api clauses and name the live legs (slice 4) #26908 and docs(qa): qa-media-constraints and qa-feeds-disabled declare namespaces their object names carry #26907 landed).

Scratch packages declare their own namespaces (qaact, qamention), never qa, qamedia, qafeeds or qagroup.

Tests

Every clause was re-driven once on its recipe, at main 1708115e2f, after a full pnpm exec turbo run build. The ledger edit was written on main 5ce3404a and merged with main 8074feb6 before this PR, then merged with main 8bbdb0b4 after #26907 landed.

record-discussion-mentions acceptance[9], walled leg: PASS

Group-posture boot (OS_TENANCY_POSTURE=group OS_PLATFORM_OWNER_EMAIL=admin@objectos.ai OS_AUTH_MEMBERSHIP_POLICY=invite-only pnpm dev -- --fresh -p PORT).

S4 create-user 200 … "organizationId":"<B>","membershipCreated":true
S4b package 201 · permission set 200 (saved env-wide) · bind 201
S6 M GET sys_comment 200
S7 M reads B account 200
S7 inbox after M {"unread":1,"mentions":[{"actionUrl":"/showcase_account/<B account>", …}]}   (control)
S8 M reads A account 404 RECORD_NOT_FOUND
S9 comment by id 201 | by email 201
S9 inbox after M: unchanged (1 mention, the control) · admin inbox: no collab.mention
WARN [audit] mention notification withheld {"reason":"cannot_read_source","userId":"<M>","commentId":"<by id>"}
WARN [audit] mention notification withheld {"reason":"cannot_read_source","userId":"<M>","commentId":"<by email>"}

Without the grant, the same member got GET /api/v1/data/sys_comment 403 PERMISSION_DENIED, and the control mention was withheld cannot_read_thread. That is why the grant is part of the sequence.

action-location-matrix acceptance[3] fail-closed half and acceptance[4] half (a): PASS

Stock showcase boot, console from ui/ at the same commit on port 5180.

install-local 200 {"manifestId":"com.objectstack.qaact.specimen","hotLoaded":true,…}
meta/object/showcase_task actions: qaact_control[list_item,record_header] | qaact_visible_throws[list_item,record_header] visible={"dialect":"cel","source":"qaact_undeclared_root.flag == true"} | qaact_no_locations[NO-KEY] | total 13
[list_item row 0..2] menu testids: … row-action-qaact_control   (no qaact_visible_throws, no qaact_no_locations)
[record_related row 0..1] menu: Edit, Mark Done, Reassign…, Quick View, Log Time, QA Control, Delete
[list_toolbar] / [Task Detail header] / [Task Detail ⋯ overflow]: no qaact label
console.warn: [object-ui] A conditional predicate failed to evaluate (qaact_visible_throws) and was treated as its safe default … Unknown variable: qaact_undeclared_root
teardown: DELETE install-local 200 · showcase_task back to 10 actions · ledger dir empty

Task Detail's header, overflow and quick-actions bar render the action ids the page lists, so QA Control is absent there too. Those reads are not counted as evidence, and the recipe's knownGaps[0] says so.

import-job-undo-cancel: console spec passes unmodified; API half PASS on all four clauses
IMPORT_CONSOLE_LIVE=1 LIVE_API_URL=http://localhost:PORT pnpm exec playwright test --config=playwright.import-console.config.ts --timeout=120000
  ✓ 1 … a small background import made through the console is undoable (35.9s)
  1 passed (37.4s)
(two earlier runs without --timeout failed on the default 30 s test timeout, 31.1 s, both after the import had landed)

a0 create 201 · terminal succeeded total 20 created 20 · results 20 rows
a1 marker counts pre 0 post-import 20 post-undo 0; undo {deleted:20,restored:0,failed:0}; unfiltered total 11 -> 11
a2 4000-row job cancelled at 1400: status cancelled, processed 1400, marker total 1400, rows read back whole (0 torn)
a3 list entry before undo: undoable true, no revertedAt key · after: undoable false, revertedAt set

Acceptance notes

  • Seat-requested fold: RDM automated.ref, ALM steps[6] and acceptance[4].verify, IJU fixtures.requires[2] and steps[0] now name the recipes.
  • The harness twin ui/e2e/import-harness/import-undo.spec.ts has no door. ui/playwright.import-harness.config.ts serves it with packages/plugin-grid/demo/vite.live.config.ts at /live.html, and neither file exists in ui/packages/plugin-grid/demo (only index.html and bulk-actions.html). Its CSV (first_name,last_name,email) also has no column for crm_lead's required name. It stays a self-skip, tracked on retire the zero-consumer surface: nine dead modules (2,211 LOC), plugin-ai, runner's publish flag, test-only reset helpers on public barrels, the providers trio, 122 dead i18n keys, root orphans #25921 (comment 6454554259), the card that already lists that config for retirement.
  • ui/playwright.import-console.config.ts's header still names an OBJECTSTACK_CLIENT_DIST alias and a backend on port 3002. Neither is needed: the workspace console resolves the in-tree client.

Verification

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. (JSON ledger only; no lint-covered file touched)
  • 4. One issue, one branch off an up-to-date main, one pull request.
  • 5. A change that publishes carries a changeset, and both declaration lines are filled in here and in the changeset. (publishes nothing: skip-changeset)
  • 6. packages/spec touched: its generated artifacts are regenerated and committed. (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, except the maintainer brief and the quoted ruling.

Generated by Claude Code

…eg, a packaged action specimen and the app-crm import spec

Two area recipes in records-forms.json: qaact-placement-specimen
installs, through the package loader, a control action, an action
whose visible predicate throws at evaluation and an action with no
locations key, all bound to showcase_task, for action-location-matrix
acceptance[3]'s fail-closed half and acceptance[4] half (a);
qa-crm-import-console boots app-crm behind the console dev server so
import-console-undo.spec.ts runs unmodified. record-discussion-mentions
already uses qa-feeds-disabled, so its walled two-organization leg is
written into steps[13] and fixtures.requires[2]. Each clause was
re-driven once and recorded in the item history.

Claude-Session: https://claude.ai/code/session_01JQwxbXyxFGYMNdVd5maF1e
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
…discussion-mentions and fold the seat-requested stale texts

main's #26907 landed record-discussion-mentions revision 10, so this
branch's row becomes revision 11 after it. At the seat's request the
same commit retires the text the recipes made stale:
record-discussion-mentions automated.ref no longer says the walled leg
waits on this card; action-location-matrix steps[6] and
acceptance[4].verify name the qaact-placement-specimen recipe and the
surfaces that count; import-job-undo-cancel fixtures.requires[2] and
steps[0] name the qa-crm-import-console route, keeping the showcase
scratch-copy route as the alternative. The three history rows say so.

Claude-Session: https://claude.ai/code/session_01JQwxbXyxFGYMNdVd5maF1e
Co-Authored-By: Claude <noreply@anthropic.com>
…he import-harness gap at its retirement card

action-location-matrix knownGaps[2] no longer says steps[6] and
acceptance[4].verify lack the specimen (the fold rewrote both). The
import-harness twin's missing harness is tracked on the existing
retirement card #25921, in the qa-crm-import-console recipe's
knownGaps[0] and in import-job-undo-cancel knownGaps[0].

Claude-Session: https://claude.ai/code/session_01JQwxbXyxFGYMNdVd5maF1e
Co-Authored-By: Claude <noreply@anthropic.com>
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

维护者速读

席位核对

ACCEPT · domain:devx#1 · session_01JQwxbaFpnMwgpCgneKe2qS · head df4bfb046b · 2026-10-27T22:31Z

  1. Shape: 1 file, +159/−13: docs/qa/platform-checklist/areas/records-forms.json. Not governed (check-governed-merges --pr 26929). File surface as in claim 6453462776; Fixes #26625.
  2. Read by the seat: the whole diff at 5e0d57f0 and the 3-line follow-up at df4bfb046b. qaact-placement-specimen installs three url actions on showcase_task through POST /api/v1/marketplace/install-local (namespace qaact): a control, one whose visible throws at evaluation, and one with no locations key, with a mandatory teardown DELETE because the ledger is written into the project tree. Its knownGaps say which surfaces count as evidence (the list row menu and the Related-tab row menus, where the control renders). qa-crm-import-console boots app-crm behind the console dev server so import-console-undo.spec.ts runs as committed, with --timeout=120000 as a run flag rather than a spec edit. The walled mention leg is folded into record-discussion-mentions steps[13], because fixtures.provisioning.use takes one recipe and that item already uses qa-feeds-disabled. Its sys_comment read grant uses scratch namespace qamention. Revisions: ALM 15→16, IJU 7→8, RDM 10→11 (after test(dogfood): pin the last records-forms checklist api clauses and name the live legs (slice 4) #26908 and docs(qa): qa-media-constraints and qa-feeds-disabled declare namespaces their object names carry #26907), each with one history row citing qa(checklist): records-forms — provisioning recipes for a walled two-organization mention leg, a packaged action specimen, and the app-crm import specs #26625.
  3. Gates: head check-runs on df4bfb046b: 27 success, 16 skipped, 0 failing; check-expected-skips --pr 26929: OK; mergeable clean. The thread re-ran dispatch-gates: 16 derived, 16 run, all exit 0, 0 NOT-MEASURED. check-platform-checklist OK, 10/10 recipes referenced. Report 6454513202.
  4. Accepted deviations: the walled leg lives on the item, not in an area recipe (the one-recipe shape, ruled by the seat at claim). At the seat's request, the stale text on the three items (RDM automated.ref, ALM steps[6] and acceptance[4].verify, IJU fixtures.requires[2] and steps[0]) is folded in, outside the claim's first surface. The PR body was amended by the seat on the final head.
  5. Out of scope: the import-harness twin has no door (its vite.live.config.ts and live.html are absent). That is tracked on retire the zero-consumer surface: nine dead modules (2,211 LOC), plugin-ai, runner's publish flag, test-only reset helpers on public barrels, the providers trio, 122 dead i18n keys, root orphans #25921 (comment 6454554259), which already lists the config for retirement. The import-console config header's stale alias note is left as is. 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): records-forms — provisioning recipes for a walled two-organization mention leg, a packaged action specimen, and the app-crm import specs #26625 closes and leaves pm:dispatched.

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

Projects

None yet

2 participants