Skip to content

docs(qa): map the qa capability to a real checklist item, not a waiver (#7347) - #7786

Merged
huangyiirene merged 1 commit into
mainfrom
claude/issue-7347-coverage-qa-row
Aug 11, 2026
Merged

docs(qa): map the qa capability to a real checklist item, not a waiver (#7347)#7786
huangyiirene merged 1 commit into
mainfrom
claude/issue-7347-coverage-qa-row

Conversation

@huangyiirene

Copy link
Copy Markdown
Collaborator

Fixes #7347

Premise, re-verified first

On a clean origin/main @ 7a8476f, before touching anything:

$ node scripts/check-platform-checklist.mjs
check-platform-checklist: 1 problem(s)

  ✗ coverage.json · qa: UNCLASSIFIED — the platform has this capability (liveness ledger exists)
    but the checklist neither tests nor waives it. Add items or a waiver with a reason.

premise_still_valid: true — the red reproduces on a pristine tree, unchanged since the card was filed.

After this PR:

$ node scripts/check-platform-checklist.mjs
check-platform-checklist: OK — 15 areas, 182 items (182 active); coverage: 28 kinds mapped, 2 waived.

The direction, per the 2026-08-11T14:08Z triage ruling

A waiver was not taken. os test is a shipped, documented CLI command, so a waiver would have had to argue the capability is out of the checklist's scope — which is exactly what the card said looks wrong. No fork to report: the authored-item route worked.

What landed

docs/qa/platform-checklist/areas/cli.json — new item cli.qa-suite-execution (surface: cli, P1, since: v17).

Area choice, per README's sharding logic: the qa domain's user-facing surface is the shipped os test command, and cli.json is the area that already owns per-command CLI contracts (dev, build, migrate, verify, scaffold, flag/command error UX). cli.flag-command-error-ux already lists test among its variants for error UX only; this item owns the command's own load/execute/verdict contract. The area title was extended to name test. No new area file — a one-command area would have been thinner than the shard it belongs in.

Eight acceptance clauses, each measured on a booted showcase app before it was written (not derived from reading the source):

clause measured
green path → exit 0, per-scenario ✅ + summary SUCCESS: All 2 scenarios passed., $? = 0
capture + {{var}} thread state between steps read-back step addressed the created record; confirmed independently over the API
a false assertion fails the run Assertion failed: data.status expected degraded, got ok, $? = 1
#7256 — unevaluable contains FAILS cannot be evaluated by 'contains' … got undefined + the is_null hint
#6247 — load-time TestSuiteSchema refusal named the file, ✗ scenarios.0.steps: …, the expected shape; the two sibling suites still ran; counted as a failed suite
teardown runs after a failed step the record created before the failure was gone; verdict stayed ❌
all 8 TestActionTypeSchema members get their own verdict full sweep run, see below
#7363 glob discipline bare os test found the suite on the default glob; qa/**/*.test.json returned in ~3s

enumSource pins TestActionTypeSchema at 8 members, so a ninth action type makes the variants matrix stale at the next check instead of drifting silently.

No automated entry — deliberately. The three existing unit pins (qa-suite-schema-load.test.ts, resolve-glob-lazy-walk.test.ts, runner.test.ts) cover the load boundary, the glob resolver and one operator; none proves a suite reaches a real server. They are cited in source so a run knows what is already covered, and a negative clause says executing them is not a run of this item.

examples/app-showcase/qa/platform-smoke.test.json — the repo's first real Quality Protocol suite. Two scenarios: the unauthenticated health probe (so a failing run can tell "wrong --url" from "broken assertions"), and a create → capture id → read-back-by-{{id}} → list roundtrip against showcase_category (public_read_write, one required field). It sits where the command's default qa/*.test.json glob finds it with no argument, and its teardown deletes the record it made — verified by listing the object before and after, and by running it twice.

$ cd examples/app-showcase && os test --url http://localhost:38771 --token <token>
Found 1 test suites.

📄 Running suite: platform-smoke.test.json
  ✅ Scenario: health-liveness (63ms)
  ✅ Scenario: category-create-read-roundtrip (458ms)

SUCCESS: All 2 scenarios passed.     # $? = 0

The deliberately broken suites (misspelled steps, false assertion, contains over a missing path) are staged per run in a scratch dir, never committed, so the repo's own suite stays green.

docs/qa/platform-checklist/coverage.json — the qa row, mapped to that item, inserted alphabetically.

Out-of-scope findings — recorded, not fixed

Both are carried as negative clauses on the item so a run records them rather than rediscovering them, and neither is patched here.

  1. Five of the eight action types cannot reach a stock server. HttpTestAdapter builds ${baseUrl}/api/data/:object; the server serves {basePath}/data/:object with basePath /api/v1. Measured verbatim — create_record, read_record, update_record, delete_record, query_records all answer HTTP Error 404: {"error":"Not found"}; update_record additionally issues PUT where the route is PATCH. Only api_call and wait execute (run_script has no adapter branch and throws loudly, which the liveness ledger already records). This is a product fix in packages/core, not a checklist edit.
  2. A zero-match glob exits 0. os test 'qa/nothing-matches-*.test.json' prints No test files found matching: … and returns 0 — a green exit from a run that loaded no suite. Whether that is a defect or a deliberate posture is a product call; the item's evidence rule works around it by requiring a run to quote the Found N test suites. line with N > 0.

Also noted, not touched: docs/qa/platform-checklist/README.md's closing paragraph still says qa "currently has no runtime consumer … qa has no liveness ledger entry" — stale since #6247 seeded the ledger and enforced the parse. README is held by a parallel unit this wave, so it is left alone.

Changeset

None. Docs/QA ledger + an example-app fixture (examples/* is private: true, nothing published changes). skip-changeset handling is the PM's per the dispatch.


Generated by Claude Code

…ver (#7347)

`check:platform-checklist` has been red on `main` since the `qa` liveness
ledger was seeded (#6247 / PR #7255): the coverage ratchet derives its universe
of capabilities from `packages/spec/liveness/*.json`, and `coverage.json`
carried no `qa` key. Two dispatched devs reproduced the same single problem in
one day and each paid the read-and-explain tax, which is what promoted it.

The exit is the one the card argued for: `os test` is a shipped, documented CLI
command, so a waiver would have had to claim the capability is out of the
checklist's scope. Instead this authors the mapping:

- `cli.qa-suite-execution` (surface: cli) — the `os test` load/execute/verdict
  contract. Every clause was measured on a booted showcase app before it was
  written: the green path and its exit 0, `capture` + `{{var}}` threading state
  between steps, the #6247 load-time TestSuiteSchema refusal (named file,
  offending paths, siblings still run), the #7256 unevaluable-`contains`
  failure, teardown running after a failed step, the 8-member action-type sweep
  and the #7363 lazy glob. `enumSource` pins TestActionTypeSchema at 8 members
  so a new action type makes the matrix stale instead of drifting.
- `examples/app-showcase/qa/platform-smoke.test.json` — the repo's first real
  Quality Protocol suite, and the fixture that item drives. It sits where the
  command's DEFAULT glob finds it with no argument, and its teardown leaves the
  fixture exactly as it found it, so the run repeats.
- `coverage.json` gains the `qa` row; the validator is now green
  (28 kinds mapped, 2 waived).

No `automated` entry: the three existing unit pins cover the load boundary, the
glob resolver and one assertion operator, and none of them proves a suite
reaches a real server — which is the whole point of the item.

Recorded, deliberately NOT fixed here (out of scope, reported on #7347): five of
the eight action types answer HTTP 404 against a stock server because
`HttpTestAdapter` builds `${baseUrl}/api/data/:object` while the server serves
`/api/v1/data/:object`; and a zero-match glob exits 0, so a run that loaded no
suite looks green. Both are carried as `negative` clauses so a run records them
instead of rediscovering them.

Fixes #7347

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NzRhAgKEGiKCWe9tN5Ww3H
@vercel

vercel Bot commented Aug 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 11, 2026 2:47pm

Request Review

@huangyiirene huangyiirene added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 11, 2026 — with Claude
@huangyiirene
huangyiirene marked this pull request as ready for review August 11, 2026 16:07
@huangyiirene
huangyiirene added this pull request to the merge queue Aug 11, 2026
@github-actions

Copy link
Copy Markdown
Contributor

⛔ merge queue 构建失败 — 先分诊,再决定要不要重排

队列构建 31510771208 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集),
所以失败的测试可能在本 PR 没碰过的包里 —— 那不是重排能修的。每次盲目重排都会让排在后面的所有 PR 重建一轮。

失败的 job(日志抽取,best effort):

  • Test Core (1/3) — 失败步骤: Run this shard's tests

    �[41m�[1m FAIL �[22m�[49m src/data/api-methods-batch-conformance.test.ts�[2m > �[22mapiMethods conformance — single-record writes imply batch (#3026)�[2m > �[22mgrants bulk wherever it grants create /
    

历史信号:

  • 本 PR 过去 24h 无队列失败记录(首次)。
  • 过去 24h 队列共有 19 个失败构建(不含本次)。

分诊清单:

  1. 失败测试在本 PR 改动的包里 → 真回归,修 PR。
  2. 失败测试与本 PR 无关 → 在其他 PR 的同类评论里搜同名测试;出现过 ⇒ flaky 实锤,开 issue 修/隔离那条测试。修好前重排只会再烧一轮全队列。
  3. 两者都不是 → 可能与同组 PR 语义冲突;等前面的 PR 落地或失败出队后再重排一次即可,不要连续重排。

Generated by Claude Code · merge-queue-triage workflow (#4859)

@github-actions

Copy link
Copy Markdown
Contributor

⛔ merge queue 构建失败 — 先分诊,再决定要不要重排

队列构建 31513733632 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集),
所以失败的测试可能在本 PR 没碰过的包里 —— 那不是重排能修的。每次盲目重排都会让排在后面的所有 PR 重建一轮。

失败的 job(日志抽取,best effort):

  • Test Core (1/3) — 失败步骤: Run this shard's tests

    �[41m�[1m FAIL �[22m�[49m src/data/api-methods-batch-conformance.test.ts�[2m > �[22mapiMethods conformance — single-record writes imply batch (#3026)�[2m > �[22mgrants bulk wherever it grants create /
    

历史信号:

  • ⚠️ 本 PR 过去 24h 已在队列失败 1 次(不含本次)。 内容未变而反复失败 ⇒ 高度怀疑 flaky 测试或与同组 PR 的语义冲突,重排不解决。
  • 过去 24h 队列共有 40 个失败构建(不含本次)。

分诊清单:

  1. 失败测试在本 PR 改动的包里 → 真回归,修 PR。
  2. 失败测试与本 PR 无关 → 在其他 PR 的同类评论里搜同名测试;出现过 ⇒ flaky 实锤,开 issue 修/隔离那条测试。修好前重排只会再烧一轮全队列。
  3. 两者都不是 → 可能与同组 PR 语义冲突;等前面的 PR 落地或失败出队后再重排一次即可,不要连续重排。

Generated by Claude Code · merge-queue-triage workflow (#4859)

@github-actions

Copy link
Copy Markdown
Contributor

⛔ merge queue 构建失败 — 先分诊,再决定要不要重排

队列构建 31514484754 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集),
所以失败的测试可能在本 PR 没碰过的包里 —— 那不是重排能修的。每次盲目重排都会让排在后面的所有 PR 重建一轮。

失败的 job(日志抽取,best effort):

  • Test Core (1/3) — 失败步骤: Run this shard's tests

    �[41m�[1m FAIL �[22m�[49m src/data/api-methods-batch-conformance.test.ts�[2m > �[22mapiMethods conformance — single-record writes imply batch (#3026)�[2m > �[22mgrants bulk wherever it grants create /
    

历史信号:

  • ⚠️ 本 PR 过去 24h 已在队列失败 2 次(不含本次)。 内容未变而反复失败 ⇒ 高度怀疑 flaky 测试或与同组 PR 的语义冲突,重排不解决。
  • 过去 24h 队列共有 46 个失败构建(不含本次)。

分诊清单:

  1. 失败测试在本 PR 改动的包里 → 真回归,修 PR。
  2. 失败测试与本 PR 无关 → 在其他 PR 的同类评论里搜同名测试;出现过 ⇒ flaky 实锤,开 issue 修/隔离那条测试。修好前重排只会再烧一轮全队列。
  3. 两者都不是 → 可能与同组 PR 语义冲突;等前面的 PR 落地或失败出队后再重排一次即可,不要连续重排。

Generated by Claude Code · merge-queue-triage workflow (#4859)

@github-actions

Copy link
Copy Markdown
Contributor

⛔ merge queue 构建失败 — 先分诊,再决定要不要重排

队列构建 31515155984 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集),
所以失败的测试可能在本 PR 没碰过的包里 —— 那不是重排能修的。每次盲目重排都会让排在后面的所有 PR 重建一轮。

失败的 job(日志抽取,best effort):

  • Test Core (1/3) — 失败步骤: Run this shard's tests

    �[41m�[1m FAIL �[22m�[49m src/data/api-methods-batch-conformance.test.ts�[2m > �[22mapiMethods conformance — single-record writes imply batch (#3026)�[2m > �[22mgrants bulk wherever it grants create /
    

历史信号:

  • ⚠️ 本 PR 过去 24h 已在队列失败 3 次(不含本次)。 内容未变而反复失败 ⇒ 高度怀疑 flaky 测试或与同组 PR 的语义冲突,重排不解决。
  • 过去 24h 队列共有 49 个失败构建(不含本次)。

分诊清单:

  1. 失败测试在本 PR 改动的包里 → 真回归,修 PR。
  2. 失败测试与本 PR 无关 → 在其他 PR 的同类评论里搜同名测试;出现过 ⇒ flaky 实锤,开 issue 修/隔离那条测试。修好前重排只会再烧一轮全队列。
  3. 两者都不是 → 可能与同组 PR 语义冲突;等前面的 PR 落地或失败出队后再重排一次即可,不要连续重排。

Generated by Claude Code · merge-queue-triage workflow (#4859)

@github-actions

Copy link
Copy Markdown
Contributor

⛔ merge queue 构建失败 — 先分诊,再决定要不要重排

队列构建 31516020568 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集),
所以失败的测试可能在本 PR 没碰过的包里 —— 那不是重排能修的。每次盲目重排都会让排在后面的所有 PR 重建一轮。

失败的 job(日志抽取,best effort):

  • Test Core (1/3) — 失败步骤: Run this shard's tests

    �[41m�[1m FAIL �[22m�[49m src/data/api-methods-batch-conformance.test.ts�[2m > �[22mapiMethods conformance — single-record writes imply batch (#3026)�[2m > �[22mgrants bulk wherever it grants create /
    

历史信号:

  • ⚠️ 本 PR 过去 24h 已在队列失败 4 次(不含本次)。 内容未变而反复失败 ⇒ 高度怀疑 flaky 测试或与同组 PR 的语义冲突,重排不解决。
  • 过去 24h 队列共有 55 个失败构建(不含本次)。

分诊清单:

  1. 失败测试在本 PR 改动的包里 → 真回归,修 PR。
  2. 失败测试与本 PR 无关 → 在其他 PR 的同类评论里搜同名测试;出现过 ⇒ flaky 实锤,开 issue 修/隔离那条测试。修好前重排只会再烧一轮全队列。
  3. 两者都不是 → 可能与同组 PR 语义冲突;等前面的 PR 落地或失败出队后再重排一次即可,不要连续重排。

Generated by Claude Code · merge-queue-triage workflow (#4859)

@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Aug 11, 2026
@github-actions

Copy link
Copy Markdown
Contributor

⛔ merge queue 构建失败 — 先分诊,再决定要不要重排

队列构建 31516761124 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集),
所以失败的测试可能在本 PR 没碰过的包里 —— 那不是重排能修的。每次盲目重排都会让排在后面的所有 PR 重建一轮。

失败的 job(日志抽取,best effort):

  • Test Core (1/3) — 失败步骤: Run this shard's tests

    �[41m�[1m FAIL �[22m�[49m src/data/api-methods-batch-conformance.test.ts�[2m > �[22mapiMethods conformance — single-record writes imply batch (#3026)�[2m > �[22mgrants bulk wherever it grants create /
    

历史信号:

  • ⚠️ 本 PR 过去 24h 已在队列失败 5 次(不含本次)。 内容未变而反复失败 ⇒ 高度怀疑 flaky 测试或与同组 PR 的语义冲突,重排不解决。
  • 过去 24h 队列共有 58 个失败构建(不含本次)。

分诊清单:

  1. 失败测试在本 PR 改动的包里 → 真回归,修 PR。
  2. 失败测试与本 PR 无关 → 在其他 PR 的同类评论里搜同名测试;出现过 ⇒ flaky 实锤,开 issue 修/隔离那条测试。修好前重排只会再烧一轮全队列。
  3. 两者都不是 → 可能与同组 PR 语义冲突;等前面的 PR 落地或失败出队后再重排一次即可,不要连续重排。

Generated by Claude Code · merge-queue-triage workflow (#4859)

@huangyiirene
huangyiirene added this pull request to the merge queue Aug 11, 2026
Merged via the queue into main with commit c5ed36c Aug 11, 2026
27 of 28 checks passed
@huangyiirene
huangyiirene deleted the claude/issue-7347-coverage-qa-row branch August 11, 2026 19:49
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

Development

Successfully merging this pull request may close these issues.

finding: check:platform-checklist is red on main — the new qa liveness ledger is neither mapped nor waived in coverage.json

2 participants