Repository navigation
Commit 87c09eb
qa(checklist): clauses for three round-3 defects outside the ledger, plus two RUNNER rules — a pin scores only the layer it drives, and an off-clause probe budget (#24811)
Fixes #24802
Clause-②: no — the internal QA ledger and its runner protocol; nothing
published
## Summary
Three ledger clauses for the defects round 3 of the 18.0 sweep found
outside the ledger, and two RUNNER rules. Each new clause carries a
`QA-source:` citation, a `revision` bump, a `history` row, and a
`knownGaps` line naming its card. Each stays red until that card's fix
lands.
- **`api-backend.batch-transactional-discovery` rev 6 (#24781).** New
acceptance[5]: an `update` or `delete` op on `POST /api/v1/batch` whose
id is the empty string answers 400 `VALIDATION_FAILED`, the same as a
missing id, and never a 5xx. Adds steps[6] (the empty-id pair plus their
no-id controls) and negative[1]. Source: QA run #24779, observed beside
the clauses.
- **`records-forms.validation-rule-type-matrix` rev 5 (#24782).** New
acceptance[5] (log oracle): an unevaluable `severity: 'warning'` rule
lets the write land, and no log entry naming the rule says the write was
rejected or failed closed. fixtures.requires[2] carries round 3's
recipe: two scratch objects authored through `PUT /api/v1/meta/object`,
each with a script rule `int(record.title) > 1`, one at `warning` and
one at `error`. That closes round 2's fixture gap (QA run #24616:
negative[0] blocked(fixture), "an unevaluable CEL validation cannot be
authored through any door"). negative[0] now names its scratch object.
Adds steps[6] and negative[3].
- **`access-security.no-active-org-session-semantics` rev 6 (#24784).**
New acceptance[7], the walled `group` leg: a member whose membership set
is non-empty and whose session has no active organization never gets a
5xx on a tenant-scoped create, and nothing is stamped with a NULL
`organization_id`. Whether `group` lands that write or refuses it 4xx is
left to #24784. Adds steps[8] (the set-active-null producer) and
knownGaps[3]. `automated.ref` now names the layer its pin drives.
`no-active-organization-write-refusal.test.ts` runs SecurityPlugin's
middleware over a stub terminal that stands in for the engine, so its
`group` CONTROL "lands" at the plugin-security layer only. The pin
therefore cannot score acceptance[7].
- **RUNNER rule 6, new paragraph: a pin scores only the layer it
drives.** Before a pin scores a clause whose oracle is a public door's
answer, the runner names the layer the pin reaches (plugin unit, engine,
or HTTP), read off the pin's harness. A pin that stops above the
oracle's layer scores the clause `partial` and names the missing layer.
#24784 is the worked instance. The paragraph sits beside rule 6, not
inside the walled-boot entry.
- **RUNNER rule 8: keep an off-clause probe budget.** Each run keeps
time after its clauses for probing the selector's doors past them:
boundary values, the opposite severity or posture, and recipients
outside the asserted scope. A probe scores nothing. A finding that
passes the filing gate is extracted with `QA-source: … · observed beside
the clauses`. The run-record body contract gains the probe line: how
long the probes took, what they covered, and what they found.
**Not in this PR: the `records-forms.record-discussion-mentions` clause
for #24785.** Its fix PR #24794 is still an open draft (checked just
before this PR was opened). Under RUNNER rule 2 that clause would
publish the reproduction before the fix ships, so it waits until #24794
merges.
Out of scope, and not touched here: the round-3 re-points and accuracy
findings in #24579 comment 6284472874. These include F3, the `group`
wording of this item's acceptance[0] and [1] and its knownGaps[0] and
[1] producers. They belong to the anchor lane.
## Verification
The clauses were run on a stock showcase at `a43405d596`, this branch's
base and current `origin/main`. The build was `pnpm build
--concurrency=2` (76/76). The boot was `objectstack dev --seed-admin`,
posture `single`, on a fresh DB. Server stopped by process group
afterwards.
| clause | expected now (card open) | measured |
|---|---|---|
| batch acceptance[5], update with id empty string | red | 500
`DATABASE_ERROR` "Internal data error"; no-id control 400
`VALIDATION_FAILED` "Operation 'update' on 'showcase_task' requires an
id" |
| batch acceptance[5], delete with id empty string | red | 500
`INTERNAL_ERROR`; no-id control 400 `VALIDATION_FAILED`. Log: `[REST]
Unhandled error: Error: Update requires an ID or options.multi=true`
(and the Delete twin) |
| validation acceptance[5], warning rule | red | 201, row persisted
(re-read 1 row). The log prints two entries naming
`qa_unevaluable_warn`, and both say "write rejected". The first ends "a
rule that cannot be evaluated fails closed, it is never skipped" after a
multi-line CEL caret excerpt, so the verify text now says to read each
entry to its end |
| validation negative[0], error twin | green | 400 `VALIDATION_FAILED`,
fields[0] `{field: _record, code: rule_violation}`, re-read 0 rows |
| no-active-org acceptance[7], walled group | red | not measured here:
it needs a walled boot (scratch app declaring
`@objectstack/organizations`, owner email, membership policy). Its red
rests on QA run #24783 and the RUNNER rule 7 re-derivation in #24784.
Per the dispatch, written from knownGaps, not hand-tested |
The red and green states match the cards: #24781, #24782 and #24784 are
open.
## Gates
On head `1143504b`:
- `node scripts/check-platform-checklist.mjs` → exit 0. Output:
`check-platform-checklist: OK — 16 areas, 328 items (323 active, 1
planned)`. It reports 0 line citations surviving and 943/953 symbol
anchors resolved, the same counts as on base.
- `node scripts/pm/dispatch-gates.mjs --commands` derived 13 commands,
each run and each exit 0:
- `node scripts/check-ci-filter-parity.mjs` 0
- `node scripts/check-closing-keyword-parity.mjs` 0
- `node scripts/check-closing-keyword-parity.mjs --self-test` 0
- `node scripts/check-comment-mask-corpus.mjs` 0
- `pnpm --filter @objectstack/lint run check:doc-formula-expressions` 0
(ran: the log ends with the checker's own summary)
- `pnpm check:cross-package-test-inputs` 0
- `pnpm check:doc-authoring` 0
- `pnpm check:driver-memory-census` 0
- `pnpm check:gitlink-declared` 0
- `pnpm check:nul-bytes` 0
- `pnpm check:platform-checklist` 0
- `pnpm check:refd-timer-probe` 0
- `pnpm check:watch-hint-literal` 0
- `node scripts/pm/dispatch-gates.mjs --ran` → exit 0: `13 derived
famil(ies) accounted for — 13 run, 0 NOT-MEASURED`.
- `coverage.json` untouched: the checker required no change.
## Acceptance notes
- Steps are referenced 1-based in `verify` text, as the existing
api-backend clauses do ("step-7"). History rows use 0-based array
indices ("steps[6]").
- The batch and validation knownGaps lines record the `580fd4ed`
measurement and this PR's re-measurement at `a43405d596`. Each tells the
runner to re-run the clause and drop the line once its card's fix
merges.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01MRkuLGosywLTY6EMcP6fGK)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent ddb3360 commit 87c09eb
4 files changed
Lines changed: 107 additions & 17 deletions
File tree
- docs/qa/platform-checklist
- areas
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
110 | 110 | | |
111 | 111 | | |
112 | 112 | | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
113 | 130 | | |
114 | 131 | | |
115 | 132 | | |
116 | 133 | | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
117 | 156 | | |
118 | 157 | | |
119 | 158 | | |
| |||
717 | 756 | | |
718 | 757 | | |
719 | 758 | | |
720 | | - | |
| 759 | + | |
| 760 | + | |
721 | 761 | | |
722 | 762 | | |
723 | 763 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2352 | 2352 | | |
2353 | 2353 | | |
2354 | 2354 | | |
2355 | | - | |
| 2355 | + | |
2356 | 2356 | | |
2357 | 2357 | | |
2358 | 2358 | | |
| |||
2371 | 2371 | | |
2372 | 2372 | | |
2373 | 2373 | | |
2374 | | - | |
| 2374 | + | |
| 2375 | + | |
2375 | 2376 | | |
2376 | 2377 | | |
2377 | 2378 | | |
2378 | 2379 | | |
2379 | 2380 | | |
2380 | | - | |
| 2381 | + | |
2381 | 2382 | | |
2382 | 2383 | | |
2383 | 2384 | | |
| |||
2387 | 2388 | | |
2388 | 2389 | | |
2389 | 2390 | | |
2390 | | - | |
| 2391 | + | |
| 2392 | + | |
2391 | 2393 | | |
2392 | 2394 | | |
2393 | 2395 | | |
| |||
2431 | 2433 | | |
2432 | 2434 | | |
2433 | 2435 | | |
| 2436 | + | |
| 2437 | + | |
| 2438 | + | |
| 2439 | + | |
| 2440 | + | |
| 2441 | + | |
2434 | 2442 | | |
2435 | 2443 | | |
2436 | 2444 | | |
| |||
2453 | 2461 | | |
2454 | 2462 | | |
2455 | 2463 | | |
2456 | | - | |
| 2464 | + | |
| 2465 | + | |
2457 | 2466 | | |
2458 | 2467 | | |
2459 | 2468 | | |
| |||
2486 | 2495 | | |
2487 | 2496 | | |
2488 | 2497 | | |
| 2498 | + | |
| 2499 | + | |
| 2500 | + | |
| 2501 | + | |
| 2502 | + | |
| 2503 | + | |
2489 | 2504 | | |
2490 | 2505 | | |
2491 | 2506 | | |
| |||
0 commit comments