Skip to content

Commit a3ac7fb

Browse files
docs(qa): correct checklist items from QA run 31486 (#31524)
<!-- claude-projects-attribution: {"github_login":"zhuangjianguo"} --> _Requested by **Steedos** · [project thread](https://claude.ai/code/project/chan_018ETKaNwMZCNRYD7D8Q9Ubb?thread=cmsg_018ETKaNwMZCNRYD7D8Q9UbbXQ1XffyfWbgHS4nxAXKADA)_ Fixes #31499 Clause-②: no Metadata-protocol: none ## 维护者速读 - **改了什么**:按 QA 运行 #31486 的实测,改正平台测试清单里 25 个条目的文字(22 处条目纠正、4 处覆盖缺口写进各条目已有的 `knownGaps`、1 处夹具清理说明),每个条目升一个 revision 并加一行引用该运行的 history。 - **为什么改**:这些条目写的步骤或判据已与当前平台不符(工具数、路由、表名、请求体形状、界面入口等),照旧执行会让下一轮 QA 白跑或误判;缺口记在条目上,下一轮不必重新发现。 - **风险与回滚**:风险很低,只改 `docs/qa/platform-checklist/areas/*.json` 的文字,不动代码、测试或钩子,也不新增或拆分条目;回滚即还原这些 JSON。 - **先看**:`identity-auth.json` 的 `email-verification-loop`(改动最大:邮件改读 `sys_identity_email`,并改用 SMTP 收件桩);`records-forms.json` 的 `form-view-gallery`(覆盖层改走定制配对);`platform-core.json` 的 `package-lifecycle-enable-disable`。 - **两分钟验证**:`node scripts/check-platform-checklist.mjs`,预期打印 `check-platform-checklist: OK — 16 areas, 360 items` 并以 0 退出。 - **需要你做的**:无,席位落地。 ## What changes The QA run #31486 (owed:weekly, subject `0647dabb`) met 22 checklist-accuracy findings, 4 coverage gaps and one fixture-hygiene note; the card lists each. This PR applies them to the named items of `docs/qa/platform-checklist/areas/*.json`. Every touched item bumps `revision` by one and gains one `history` row (date 2026-11-08, ref `#31499`) that cites the run and the base it was read at. No item is added, split or retired, and no file outside `areas/*.json` changes. | Card line | Item | Fields | |:--|:--|:--| | 1 | `ai.mcp-http-surface` | acceptance[4] clause + verify: 15 HTTP tools, stdio 10 | | 2 | `studio-authoring.meta-save-preconditions-and-draft-rows` | steps[1]: once the ACTIVE row exists | | 3 | `dashboards.analytics-exposure-gate-and-measure-aggregate` | fixtures.requires[2]: `enable: { apiEnabled: false }` | | 4 | `cli.organization-ownership-ceremony` | steps[1], [3], [4]: apply and comment-reactions take no `--dev` | | 5 | `attachments-storage.field-accept-maxsize-server-enforced` | fixtures.requires[2]: a direct database write | | 6 | `studio-authoring.package-customize-restore-display` | acceptance[3].verify, steps[6]: chip popover, `studio-override-restore` | | 7 | `studio-authoring.api-written-keys-survive-studio-save` | variants[4]: `requiredPermissions` with `studio.access` | | 8 | `studio-authoring.metadata-diagnostics-sweep` | steps[3], [6]: `/studio/PKG/metadata`; steps[8]: `OBJECT.default` | | 9 | `studio-authoring.record-page-roundtrip` | acceptance[3].verify: title the card before publish | | 10 | `studio-authoring.hooks-tab-authoring` | steps[3], [5]: one record name per throwing hook | | 11 | `studio-authoring.actions-tab-presets` | steps[1], [2], [4]: label each preset; "More actions" overflow | | 12 | `studio-authoring.validation-rules-authoring` | acceptance[1].verify: no further PUT while the served verdict stands | | 13 | `identity-auth.email-verification-loop` | requires[2], knownGaps[1], steps[0], [2], acceptance[1], [3]: `sys_identity_email`, SMTP sink | | 14 | `integration-system.email-template-render` | fixtures.knownGaps[1]: email channel suppressed on the log transport | | 15 | `access-security.permission-matrix-edit-loop` | steps[2]: the Setup door redirects into Studio's All metadata area | | 16 | `automation.package-flow-override` | steps[0] `data.runs`, steps[3] folded chip, steps[7] Restore | | 17 | `cli.scaffold-first-run` | fixtures.requires[1] verdaccio rules; steps[4] `npx skills add CHECKOUT --list` | | 18 | `platform-core.package-lifecycle-enable-disable` | steps[5], acceptance[4]: meta read; acceptance[5]: named not-found state | | 19 | `records-forms.form-view-gallery` + `ux-conventions.disabled-control-reason` | requires[0]: the ADR-0146 D11 pair recipe; variants[1]: run before the pair exists | | 20 | `records-forms.bulk-select-all-matching` | steps[7]: deleteMany takes `{"ids": [...]}` | | 21 | `i18n.notification-localized-and-clears` | steps[4]: a member popover may draw the Activity tab | | 22 | `ux-conventions.disabled-control-reason` | variants[5]: the task list's "Reassign…" with no row selected | | gap | `attachments-storage.chunked-upload-integrity` | knownGaps: acceptance[3] needs a second organization (group boot) | | gap | `automation.package-flow-override` | knownGaps: acceptance[2] needs a topology-changing edit or its pin | | gap | `studio-authoring.no-entry-property-matrix` | knownGaps: 9 rows per runner budget; own runner or split, the split owed | | gap | `studio-authoring.package-customize-restore-display`, `studio-authoring.validation-rules-authoring` | knownGaps: acceptance[6] and acceptance[2] unpinned halves | | hygiene | `studio-authoring.picklist-bound-select` | fixtures.requires[0]: make the scratch copy in the run's own linked worktree, where the Bash guard allows `rm -rf` | `platform-core.json` was edited last and `origin/main` merged in before this PR opened, as the claim orders (the #31497/#31498 pair edits two other items in that file). ## Tests No test, code or hook changes. The checklist validator is the gate on this diff: `node scripts/check-platform-checklist.mjs` exits 0. A semantic diff against `origin/main` (both sides parsed as JSON) shows exactly the 25 named items changed, each with `revision` +1 and `history` +1, no area-level key changed, and item sets and order unchanged. ## Acceptance notes - Step-1 spot-check on `origin/main` 4894cfe: the premises of lines 1, 4, 8, 13, 18 and 20 all hold, so no line is dropped. Line 1: `wireBridgeTools` in `packages/mcp/src/mcp-http-tools.ts` registers 15 data and action tools, and the federation pair is scope-gated. Line 4: `migrate/apply.ts` and `migrate/comment-reactions.ts` declare no `dev` flag. Line 8: `AppContent.tsx` sends `/apps/APP/metadata` and `metadata/_diagnostics` to `SetupMetadataRoute`, which redirects to `studioMetadataAreaPath`. Line 13: `IDENTITY_EMAIL_OBJECT` is `sys_identity_email`. Line 18: no `packages/:id/published` route exists. Line 20: `batch-routes.ts` parses `deleteMany` through `DeleteManyDataRequestSchema`. - Line 4 is worded "apply and comment-reactions take no `--dev`", not "only organization-ownership and serve do": `migrate/packageless-overlays.ts` and `migrate/security-catalog-overlays.ts` declare `--dev` too. The seat accepted this wording. - Placement readings: line 8's `OBJECT.default` note sits on steps[8], the planted-row leg it describes, since steps[3] and [6] plant nothing. Line 16's `data.runs` note sits on steps[0], the item's first runs read, because steps[8] (New similar) reads no runs list. Line 19's "variant 2" is read 1-based, as variants[1] (Studio Publish on a read-only package). Line 11 names no index, so steps[1], [2] and [4] carry it. Line 1 also widens acceptance[4].verify's degradation list to the file pair. - Fixture hygiene was measured by feeding the Bash guard's own hook script `rm -rf examples/qa-picklist-showcase` with each cwd: the shared primary checkout answers exit 2 (blocked), a linked worktree exit 0. - The run's close-out also parked `identity-auth.auth-method-matrix` acceptance[0] and `integration-system.email-template-render` acceptance[5] on #31499. The card's coverage-gaps list does not name them, so they are untouched. ## Verification All readings are on objectstack `claude/project-thread-eiodyp`. The edits were read at base `4894cfe1`, and the gates ran at the merged head `c1789f47` (main `9431c45d` plus the two commits). <details><summary>Derived gates</summary> `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` at merged head `c1789f47` derived 16 families for the 13 changed paths (288 changed lines, under the 3000 human-merge threshold). All 16 exit 0: `check-adr-links` (+ `--self-test`), `check-closing-keyword-parity` (+ `--self-test`, on this body), `check-comment-mask-corpus`, `ci/plan-test-core-shards --self-test`, `@objectstack/lint check:doc-formula-expressions`, `check:ci-filter-parity`, `check:cross-package-test-inputs`, `check:doc-authoring`, `check:driver-memory-census`, `check:gitlink-declared`, `check:nul-bytes`, `check:platform-checklist`, `check:refd-timer-probe` and `check:watch-hint-literal`. `check:doc-formula-expressions` first exited 3 (PREREQUISITE NOT MET, nothing measured) in the fresh worktree. After its named prerequisite, `turbo run build --filter=@objectstack/formula --filter=@objectstack/lint` under the verify lock (VERDICT command-exit 0), it exited 0. `dispatch-gates --ran` reconciliation: 16 derived, 16 run, 0 NOT-MEASURED, 0 UNRUN. Not local, per the derivation: CI's `Plan Test Core shards` step and the conditional `Type Check UI` lane, which no path in this diff feeds. </details> Dogfood battery: n/a, no `!` in the title and no (narrowing) arm. --- _Generated by [Claude Code](https://claude.ai/code/session_01QsR2jTF22yU6xKsdoYV5Gp)_ <!-- signed: domain:devx#2 · zhuangjianguo · session_01QsR2jTo666XXx9e1Gm21C6 --> --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 86e3766 commit a3ac7fb

13 files changed

Lines changed: 204 additions & 84 deletions

‎docs/qa/platform-checklist/areas/access-security.json‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2319,7 +2319,7 @@
23192319
"title": "Editing the permission matrix and publishing flips an affected persona's live API access; revoke flips it back; assign/unassign moves access",
23202320
"since": "v16",
23212321
"status": "active",
2322-
"revision": 6,
2322+
"revision": 7,
23232323
"priority": "P1",
23242324
"surface": "mixed",
23252325
"personas": [
@@ -2337,7 +2337,7 @@
23372337
"steps": [
23382338
"boot showcase with the console; admin session; provision member M granted a writable set S that WITHHOLDS a verb on an object (e.g. delete:false on showcase_task); as M create the showcase_task rows the DELETE probes below use — M's OWN rows, never seeded ids: a set silent on writeScope is owner-only (packages/plugins/plugin-security/src/permission-evaluator.ts getEffectiveScope), so a seeded task owned by someone else stays refused after the verb flips ON and confounds the verb with ownership",
23392339
"baseline: as M, DELETE /api/v1/data/showcase_task/<one of M's own ids> — must be refused 403 (the withheld verb)",
2340-
"in the console Permission Matrix editor for S (Setup's metadata-admin door, which mounts the editor with no packageId), flip delete ON for showcase_task and Save. That Save is a plain PUT that lands state:'active' at once, not a draft: only a package-scoped editor (Studio's Access pillar, packageId set) saves with mode 'draft' (ui/packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.tsx, the saveVersioned call; QA run #27441). Capture PUT /api/v1/meta/permission/S, then POST /api/v1/meta/permission/S/publish, which answers 404 code NO_DRAFT after that active save, per acceptance[1]; a run that edits through the package door instead publishes the pending draft and captures a 2xx",
2340+
"in the console Permission Matrix editor for S (Setup's metadata-admin door: /apps/setup/metadata/permission/S redirects to /_console/studio/~all/metadata/permission/S, which mounts the editor with no packageId and saves on an explicit Save), flip delete ON for showcase_task and Save. That Save is a plain PUT that lands state:'active' at once, not a draft: only a package-scoped editor (Studio's Access pillar, packageId set) saves with mode 'draft' (ui/packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.tsx, the saveVersioned call; QA run #27441). Capture PUT /api/v1/meta/permission/S, then POST /api/v1/meta/permission/S/publish, which answers 404 code NO_DRAFT after that active save, per acceptance[1]; a run that edits through the package door instead publishes the pending draft and captures a 2xx",
23412341
"as M: DELETE /api/v1/data/showcase_task/<another of M's own ids> — must now be 2xx (access flipped)",
23422342
"flip delete back OFF in the matrix and Save (active at once, as in steps[2]; publish only a package-door draft); as M: DELETE again — must be refused 403",
23432343
"field-level half: flip an FLS bit (a showcase_project field editable:false→true) in the lower matrix and Save (as in steps[2]); as M PATCH that field — the write flips accordingly",
@@ -2431,6 +2431,12 @@
24312431
"date": "2026-11-01",
24322432
"change": "negative[2] moved to source[6]: it was a scope note naming the items that own the neighbouring surfaces, which no run can decide, so it could only score skipped. Its text is unchanged. Ruling 6545938831 item ① on #28345 (scope notes leave negative[], which keeps only decidable entries; the #27651 precedent). No clause changed. Wave anchor #27377",
24332433
"ref": "#28345"
2434+
},
2435+
{
2436+
"revision": 7,
2437+
"date": "2026-11-08",
2438+
"change": "steps[2]: /apps/setup/metadata/permission/NAME redirects to /_console/studio/~all/metadata/permission/NAME, where the editor uses an explicit Save. Checklist-accuracy finding of QA run #31486 (owed:weekly, at 0647dabb). Read at base 4894cfe1",
2439+
"ref": "#31499"
24342440
}
24352441
]
24362442
},

‎docs/qa/platform-checklist/areas/ai.json‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@
134134
"title": "MCP HTTP transport (/mcp) and the public /mcp/skill endpoint gate exactly as documented: 404 when opted out, 501 when unimplemented, 401 anonymous, 403 scopeless-OAuth, full tool list when keyed",
135135
"since": "v15",
136136
"status": "active",
137-
"revision": 8,
137+
"revision": 9,
138138
"priority": "P1",
139139
"surface": "api",
140140
"fixtures": {
@@ -185,9 +185,9 @@
185185
"evidence": "the 401 response incl. headers"
186186
},
187187
{
188-
"clause": "a keyed MCP client completes initialize + tools/list, and the tool set over /api/v1/mcp (the HTTP door) is the documented principal-bound surface: list_objects, describe_object, query_records, aggregate_records, get_record, create_record, update_record, delete_record, list_actions, run_action, resume_run, validate_expression. The stdio door on the same build serves 9 of these, without the action family (list_actions, run_action, resume_run): the tool set is a function of the bridge (wireBridgeTools, packages/mcp/src/mcp-http-tools.ts), and the stdio data bridge implements no action methods (createStdioDataBridge, packages/mcp/src/stdio-data-bridge.ts), so a stdio count of 9 is not a shortfall against this clause",
188+
"clause": "a keyed MCP client completes initialize + tools/list, and the tool set over /api/v1/mcp (the HTTP door) is the documented principal-bound surface: list_objects, describe_object, query_records, aggregate_records, get_record, create_record, update_record, delete_record, delete_records, list_actions, run_action, resume_run, validate_expression, read_file, create_upload_link: 15 tools. list_remote_tables and import_object are not in it: they register only for a token whose scopes name metadata:write (registerFederationTools, the same file), so a key or a session never lists them. The stdio door on the same build serves 10 of these: every tool but the action family (list_actions, run_action, resume_run) and the file pair (read_file, create_upload_link). The tool set is a function of the bridge (wireBridgeTools, packages/mcp/src/mcp-http-tools.ts), and the stdio data bridge implements no action methods and neither readRecordFile nor createUploadLink (createStdioDataBridge, packages/mcp/src/stdio-data-bridge.ts), so a stdio count of 10 is not a shortfall against this clause",
189189
"oracle": "network",
190-
"verify": "tools/list names against packages/mcp/src/mcp-http-tools.ts registrations (aggregate_records may be absent only when the bridge cannot route it, and resume_run only when the host cannot resume runs — both graceful degradation; record which)",
190+
"verify": "tools/list names against packages/mcp/src/mcp-http-tools.ts registrations (aggregate_records may be absent only when the bridge cannot route it, resume_run only when the host cannot resume runs, and read_file / create_upload_link only when the bridge implements no readRecordFile / createUploadLink — all graceful degradation; record which)",
191191
"evidence": "the session trace + tool-name list"
192192
},
193193
{
@@ -225,7 +225,8 @@
225225
"change": "automated.ref and variants[2] corrected. Checklist-accuracy findings of the 18.2.0 wave 2 (QA run #26468, Tier 1 half A, at 756220c4; wave anchor #25807, slice B). (1) The ref said no named file scores a clause alone, but mcp-skill-method-not-allowed.hono.integration.test.ts asserts acceptance[2] in full (status, Allow: GET, the exact envelope message) over a real Hono socket and the real dispatcher, and a 405 never reaches the faked services; the ref now says it scores that clause. (2) The ref gains packages/cli/test/serve-mcp-capability-collision.e2e.test.ts as corroboration (spawned server, osk_ key, initialize + tools/list, /mcp/skill 200) and says the scopes test's fake bridge has no resumeRun, so it counts 11 tools. (3) variants[2] omitted resume_run, which the same actions:execute scope grants. Re-read at base fd246c22: packages/mcp/src/mcp-http-tools.ts registerActionTools (canResume, 'the same actions:execute scope grants both'), mcp-http-tools.scopes.test.ts ACTION_TOOLS. No clause changed",
226226
"ref": "#25807"
227227
},
228-
{ "revision": 8, "date": "2026-10-31", "change": "acceptance[4] names its transport. Checklist-accuracy finding of QA run #27409 (18.3.0 sweep, wave 3, Tier 1 half A, at c4c515ad; sweep anchor #27377): the HTTP door listed the twelve, while the stdio door on the same build listed 9 with no action family, and the clause did not say which door 'the documented twelve' meant. It now names /api/v1/mcp and says why stdio serves 9. Re-read at base 488b3ed0: packages/mcp/src/mcp-http-tools.ts wireBridgeTools (the action pair registers only when the bridge implements listActions and runAction), packages/mcp/src/stdio-data-bridge.ts createStdioDataBridge (an McpDataBridge, no action methods). The HTTP assertion is unchanged", "ref": "#27409" }
228+
{ "revision": 8, "date": "2026-10-31", "change": "acceptance[4] names its transport. Checklist-accuracy finding of QA run #27409 (18.3.0 sweep, wave 3, Tier 1 half A, at c4c515ad; sweep anchor #27377): the HTTP door listed the twelve, while the stdio door on the same build listed 9 with no action family, and the clause did not say which door 'the documented twelve' meant. It now names /api/v1/mcp and says why stdio serves 9. Re-read at base 488b3ed0: packages/mcp/src/mcp-http-tools.ts wireBridgeTools (the action pair registers only when the bridge implements listActions and runAction), packages/mcp/src/stdio-data-bridge.ts createStdioDataBridge (an McpDataBridge, no action methods). The HTTP assertion is unchanged", "ref": "#27409" },
229+
{ "revision": 9, "date": "2026-11-08", "change": "acceptance[4].clause and .verify name the HTTP tool set as 15: delete_records, read_file and create_upload_link joined the 12 it listed, and the stdio door serves 10 (its former 9 plus delete_records). Checklist-accuracy finding of QA run #31486 (owed:weekly, at 0647dabb): tools/list answered 15 on a keyed session. Read at base 4894cfe1", "ref": "#31499" }
229230
]
230231
},
231232
{

‎docs/qa/platform-checklist/areas/attachments-storage.json‎

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,7 +1030,7 @@
10301030
"title": "A field's declared accept/maxSize is re-enforced SERVER-SIDE on record write — the control the client widget check explicitly is not — with the declared missing-metadata and dotless-extension holes scored as documented boundaries",
10311031
"since": "v17",
10321032
"status": "active",
1033-
"revision": 7,
1033+
"revision": 8,
10341034
"priority": "P1",
10351035
"surface": "api",
10361036
"personas": ["seeded admin (admin@objectos.ai) — the check is a declaration constraint, not an authz gate: it binds every caller identically, so no restricted persona is needed"],
@@ -1039,7 +1039,7 @@
10391039
"requires": [
10401040
"the qamedia_media scratch object with field-level accept/maxSize (see provisioning) — no stock showcase object declares either",
10411041
"the storage service live at the default base — presign/complete is how the probe sys_file rows are minted, and their mime_type/size are the DECLARED values the check reads (packages/services/service-storage/src/storage-routes.ts#registerStorageFamily: its POST /storage/upload/presigned handler persists the pending sys_file row with the declared mimeType and size)",
1042-
"a system-write channel to CLEAR mime_type and size on one committed sys_file row for the missing-metadata clause — the presign door refuses a body without mimeType/size (400 INVALID_REQUEST, storage-routes.ts), so a metadata-less row cannot be minted through the API; without the system write that one clause is blocked(fixture)"
1042+
"a system-write channel to CLEAR mime_type and size on one committed sys_file row for the missing-metadata clause — the presign door refuses a body without mimeType/size (400 INVALID_REQUEST, storage-routes.ts), so a metadata-less row cannot be minted through the API. Since #27399 the data door cannot be that channel either: a PATCH of mime_type / size through /api/v1/data/sys_file answers 200 and changes nothing. Name a direct database write: an UPDATE of the sys_file row in the run's own database (for a file DB, node:sqlite against the OS_DATABASE_URL file). Without the system write that one clause is blocked(fixture)"
10431043
],
10441044
"provisioning": {
10451045
"use": "qa-media-constraints",
@@ -1135,6 +1135,12 @@
11351135
"date": "2026-10-28",
11361136
"change": "steps[1](B), steps[5] and negative[3] corrected. Checklist-accuracy findings of the 18.2.0 wave 2 (QA run #26476, manual api set, at 756220c4; wave anchor #25807, slice B). (1) steps[1](B) said the bytes need not match the declared size; since #24548 upload/complete answers 409 when the backend's bytes differ from the declared size, so B must carry its 2097152 bytes. (2) steps[5] offered PUT, which a record answers 405. (3) negative[3] said an unknown id passes untouched; since #26043 a write with a caller refuses it 400 VALIDATION_FAILED, the same answer as an unreadable file. Re-read at base fd246c22: packages/services/service-storage/src/storage-routes.ts heldBytesRefusal (getInfo size against the declared size), file-reference-lifecycle.ts findReferenceableFile ('refused' for an id the lookup cannot see when a caller is asked). The run's recipe line (media_qa_media, 422 NAMESPACE_PREFIX) is already closed by revision 6 (#26876, qamedia_media). The negative still says the probe measures nothing; only the reason changed",
11371137
"ref": "#25807"
1138+
},
1139+
{
1140+
"revision": 8,
1141+
"date": "2026-11-08",
1142+
"change": "fixtures.requires[2] names a direct database write as the system-write channel: since #27399 a PATCH through the data door answers 200 and changes nothing. Checklist-accuracy finding of QA run #31486 (owed:weekly, at 0647dabb). Read at base 4894cfe1",
1143+
"ref": "#31499"
11381144
}
11391145
]
11401146
},
@@ -1252,7 +1258,7 @@
12521258
"title": "Chunked upload integrity on v18: complete with a missing chunk is 409 with details.missingChunks and the session stays in_progress, a re-sent chunk counts once, parallel chunks all record, and an org switch mid-upload answers 409 on chunk and complete, and on progress only once the session's expiry stamp is due",
12531259
"since": "v18",
12541260
"status": "active",
1255-
"revision": 8,
1261+
"revision": 9,
12561262
"priority": "P2",
12571263
"surface": "api",
12581264
"personas": [
@@ -1264,7 +1270,8 @@
12641270
"a fresh boot of the showcase: `pnpm dev -- --fresh -p PORT --seed-admin` (ephemeral DB; the seeded admin is printed)"
12651271
],
12661272
"knownGaps": [
1267-
"CLOSED for the pin half: packages/plugins/organizations/src/storage-upload-organization-change.wall.test.ts now drives the CHUNKED doors after an organization switch over a booted wall (chunk PUT 409, chunked complete 409, progress 200 on a live session and 409 when its expiry stamp is due), so the door-level 409 of acceptance[3] is pinned at http-in-process and the automated.ref names it. The guard is the doors' shared requireStartingOrganization (packages/services/service-storage/src/storage-routes.ts, asking packages/services/service-storage/src/metadata-store.ts#organizationOutOfWriteReach). acceptance[3]'s live leg, steps[3], needs a second organization the admin can make active. A stock boot holds one: POST /api/v1/auth/organization/create answers 403 ORGANIZATION_CREATION_DISABLED on every boot whose posture enforces no wall (packages/plugins/plugin-auth/src/auth-manager.ts#ORGANIZATION_CREATION_DISABLED_CODE; QA runs #24560 / #24558). On 18.0.0, where 18.x step 4 (#24580) has deleted the walled boot refusal that of the published prereleases only 18.0.0-next.5 carries, a walled boot provisioned per RUNNER.md's environment-facts entry 'A walled boot is a fixture of its own' creates it through that same door (RUNNER.md 'A stock `single` boot holds exactly one organization, and no door mints a second; a walled boot mints them through the auth API'). A run that provisions neither records acceptance[3] blocked(fixture) naming those entries, never fail. Such a run scores the guard from the wall pin alone; a run that stages the second organization with a system write, as QA run #24560 did, scores a fixture of its own making and records that its verdict rests on it"
1273+
"CLOSED for the pin half: packages/plugins/organizations/src/storage-upload-organization-change.wall.test.ts now drives the CHUNKED doors after an organization switch over a booted wall (chunk PUT 409, chunked complete 409, progress 200 on a live session and 409 when its expiry stamp is due), so the door-level 409 of acceptance[3] is pinned at http-in-process and the automated.ref names it. The guard is the doors' shared requireStartingOrganization (packages/services/service-storage/src/storage-routes.ts, asking packages/services/service-storage/src/metadata-store.ts#organizationOutOfWriteReach). acceptance[3]'s live leg, steps[3], needs a second organization the admin can make active. A stock boot holds one: POST /api/v1/auth/organization/create answers 403 ORGANIZATION_CREATION_DISABLED on every boot whose posture enforces no wall (packages/plugins/plugin-auth/src/auth-manager.ts#ORGANIZATION_CREATION_DISABLED_CODE; QA runs #24560 / #24558). On 18.0.0, where 18.x step 4 (#24580) has deleted the walled boot refusal that of the published prereleases only 18.0.0-next.5 carries, a walled boot provisioned per RUNNER.md's environment-facts entry 'A walled boot is a fixture of its own' creates it through that same door (RUNNER.md 'A stock `single` boot holds exactly one organization, and no door mints a second; a walled boot mints them through the auth API'). A run that provisions neither records acceptance[3] blocked(fixture) naming those entries, never fail. Such a run scores the guard from the wall pin alone; a run that stages the second organization with a system write, as QA run #24560 did, scores a fixture of its own making and records that its verdict rests on it",
1274+
"acceptance[3] needs a second organization, and a single stock boot cannot make one: QA run #31486 (owed:weekly, at 0647dabb) met create organization → 403 ORGANIZATION_CREATION_DISABLED and scored it blocked(fixture). The walled group boot (OS_TENANCY_POSTURE=group) that run's C3a slice provisioned would serve it; access-security.no-active-org-session-semantics (blocked, #9334) needs the same boot"
12681275
]
12691276
},
12701277
"steps": [
@@ -1355,6 +1362,12 @@
13551362
"date": "2026-10-28",
13561363
"change": "knownGaps[0], acceptance[0] and automated.ref follow the chunked-door wall pin. Checklist-accuracy finding of the 18.2.0 wave 2 (QA run #26468, Tier 1 half A, at 756220c4; wave anchor #25807, slice B): knownGaps[0] said no file drives a chunked door after an organization switch, but packages/plugins/organizations/src/storage-upload-organization-change.wall.test.ts pins the chunk PUT 409, the chunked-complete 409, progress 200 and the progress-with-due-expiry 409 over a booted wall. The file joins the ref, knownGaps[0] is closed for the pin half (its live-leg fixture text is kept), and acceptance[0]'s 'no chunked-door pin' sentence is replaced. Re-read at base fd246c22 (the wall file's chunk-PUT, chunked-complete and progress cases). No clause's assertion changed",
13571364
"ref": "#25807"
1365+
},
1366+
{
1367+
"revision": 9,
1368+
"date": "2026-11-08",
1369+
"change": "fixtures.knownGaps gains acceptance[3]'s second-organization fixture gap and the group boot that would serve it. Coverage gap of QA run #31486 (owed:weekly, at 0647dabb). Read at base 4894cfe1",
1370+
"ref": "#31499"
13581371
}
13591372
]
13601373
}

0 commit comments

Comments
 (0)