Ruled: 5863822176 · letter B · 2026-09-28T05:06Z
Filing gate: ① a declared≠enforced family, filed as one sweep card per family under ruling A′ item ④ on #18900 (5727134555). This is triage's standing request 5857165909 on the seat post. Family qa-runner, seat verdict ENFORCE.
reach: the declared authoring door. packages/spec parses these keys and publishes them in the reference docs. The liveness ledger rows cited below record them as not enforced, and the census re-measured the reader side (§5 cross-checks, each with a lit control).
- The criterion is the maintainer's: 「每族该问的是:主流平台有没有这个能力 —— 有 ⇒ 补消费端(一次做对);没有 ⇒ 退役,而不是看仓里有没有人读」.
- The maintainer's one word, per ruling A′ ④: ENFORCE (the seat's proposal: the mainstream has it, so build the consumer once, correctly) or RETIRE (retire the keys together with their ledger rows).
Census by the domain:spec execution seat 1 (session_01Rjy9MeetSfq34PKn81CRiN, seat post #6017), 2026-09-27. Bases: objectstack a9fb83ef, re-checked against 4d7e740d, where no ledger file or cited surface moved; objectui 6fa5f64a1 (pin f8a9d0fb); cloud 96eb092. Ledger instrument: check-liveness.mts --json, whose byStatus equals the committed state-counts.md row for row. ⛔ Filed bare: routing and grading belong to triage. ⛔ Not a claim. The ranking is by value, user-visible risk × keys. This family's rank is 7 of 16. The sibling family cards filed so far are #20273, #20274, #20281 and #20282.
Capability: Named test suites and scenarios in reports, tag-based selection, and declared preconditions that skip with a reason
| key |
ledger status |
ledger row |
what the ledger cites |
qa.name |
dead (verified 2026-08-10) |
packages/spec/liveness/qa.json:5 |
note: Parsed and never read. TestRunner.runSuite (packages/core/src/qa/runner.ts:25-31) touches only suite.scenarios, and the one caller prints path.basename(file) as the suite heading (packages/cli/src/commands/test.ts:95) — so renaming a suite changes not… |
qa.scenarios.name |
dead (verified 2026-08-10) |
packages/spec/liveness/qa.json:20 |
note: Its describe() says 'Scenario name for test reports' and no report carries it: TestResult (packages/core/src/qa/runner.ts:6-12) has scenarioId and no name field, and the CLI prints result.scenarioId (packages/cli/src/commands/test.ts:104). So an autho… |
qa.scenarios.description |
dead (verified 2026-08-10) |
packages/spec/liveness/qa.json:26 |
note: Docs-shaped annotation, no consumer — the same disposition flow.description and hook.label/description carry and for the same reason: an author is not misled by a field that only claims to describe. Exempt from enforce-or-remove (ADR-0033). |
qa.scenarios.tags |
dead (verified 2026-08-10) |
packages/spec/liveness/qa.json:32 |
note: The sharpest row in this file. Its describe() promises 'Tags for filtering and categorization (e.g. "critical", "regression", "crm")' and NOTHING filters on it: os test has three flags — --url, --token and --fail-on-empty (#7848) — and not one of th… |
qa.scenarios.requires |
dead (verified 2026-08-10) |
packages/spec/liveness/qa.json:59 |
note: Declared environment preconditions — requires.params (environment variables) and requires.plugins (plugins that must be loaded) — that nothing checks. Neither the runner nor the CLI reads scenario.requires; there is no skip path and no precondition fa… |
Mainstream evidence:
- ServiceNow Automated Test Framework (ATF): named tests and test suites with descriptions, and results reported per test. Tag filtering in ATF is UNVERIFIED.
- Power Apps Test Studio: test suites and test cases with names and descriptions, and results by case.
- Odoo's own test framework:
@tagged(...) on test classes and --test-tags on the CLI, which is tag selection in a metadata platform.
- Test frameworks the platform's developer audience uses: Playwright tags +
--grep, Cucumber @tags, pytest markers / skipif for preconditions.
Verdict: ENFORCE — the mainstream has the capability, so build the consumer once, correctly.
Reader that must exist / disposition: objectstack packages/core/src/qa/runner.ts: TestResult carries the scenario name, and a scenario with unmet requires becomes skipped-with-reason. packages/cli/src/commands/test.ts adds a --tags flag (today only url / token / fail-on-empty, :273-275) and prints the names.
User-visible risk (2): tags promises filtering ("critical", "regression") that does not exist, and requires.plugins reads as a guard but never skips. Both are misleading rather than benign.
Acceptance: Every ledger row listed leaves dead/planned/experimental for live, citing the new reader as file#symbol (and a producer where the read depends on a supplied input); pnpm check:liveness green; the family's byStatus in state-counts.md regenerated.
Lane: domain:spec parent + domain:engine-core / cli sub-issue, all in objectstack
File surface: packages/spec/src/qa/testing.zod.ts:63-79 · packages/core/src/qa/runner.ts · packages/cli/src/commands/test.ts · packages/spec/liveness/qa.json
Dedupe: TestSuiteSchema \| qa/runner \| scenario\.tags \| scenarios?\.(tags\|requires) \| os test --tags \| testing\.zod → 1 open hit. None carries a key of this family:
四轴:
Ruled: 5863822176 · letter B · 2026-09-28T05:06Z
Filing gate: ① a declared≠enforced family, filed as one sweep card per family under ruling A′ item ④ on #18900 (
5727134555). This is triage's standing request5857165909on the seat post. Familyqa-runner, seat verdict ENFORCE.reach:the declared authoring door.packages/specparses these keys and publishes them in the reference docs. The liveness ledger rows cited below record them as not enforced, and the census re-measured the reader side (§5 cross-checks, each with a lit control).Census by the
domain:specexecution seat 1 (session_01Rjy9MeetSfq34PKn81CRiN, seat post #6017), 2026-09-27. Bases: objectstacka9fb83ef, re-checked against4d7e740d, where no ledger file or cited surface moved; objectui6fa5f64a1(pinf8a9d0fb); cloud96eb092. Ledger instrument:check-liveness.mts --json, whosebyStatusequals the committedstate-counts.mdrow for row. ⛔ Filed bare: routing and grading belong to triage. ⛔ Not a claim. The ranking is by value, user-visible risk × keys. This family's rank is7of 16. The sibling family cards filed so far are #20273, #20274, #20281 and #20282.Capability: Named test suites and scenarios in reports, tag-based selection, and declared preconditions that skip with a reason
qa.namepackages/spec/liveness/qa.json:5TestRunner.runSuite(packages/core/src/qa/runner.ts:25-31) touches onlysuite.scenarios, and the one caller printspath.basename(file)as the suite heading (packages/cli/src/commands/test.ts:95) — so renaming a suite changes not…qa.scenarios.namepackages/spec/liveness/qa.json:20TestResult(packages/core/src/qa/runner.ts:6-12) hasscenarioIdand no name field, and the CLI printsresult.scenarioId(packages/cli/src/commands/test.ts:104). So an autho…qa.scenarios.descriptionpackages/spec/liveness/qa.json:26flow.descriptionandhook.label/descriptioncarry and for the same reason: an author is not misled by a field that only claims to describe. Exempt from enforce-or-remove (ADR-0033).qa.scenarios.tagspackages/spec/liveness/qa.json:32os testhas three flags —--url,--tokenand--fail-on-empty(#7848) — and not one of th…qa.scenarios.requirespackages/spec/liveness/qa.json:59requires.params(environment variables) andrequires.plugins(plugins that must be loaded) — that nothing checks. Neither the runner nor the CLI readsscenario.requires; there is no skip path and no precondition fa…Mainstream evidence:
@tagged(...)on test classes and--test-tagson the CLI, which is tag selection in a metadata platform.--grep, Cucumber@tags, pytest markers /skipiffor preconditions.Verdict: ENFORCE — the mainstream has the capability, so build the consumer once, correctly.
Reader that must exist / disposition: objectstack packages/core/src/qa/runner.ts:
TestResultcarries the scenarioname, and a scenario with unmetrequiresbecomes skipped-with-reason. packages/cli/src/commands/test.ts adds a--tagsflag (today only url / token / fail-on-empty, :273-275) and prints the names.User-visible risk (2):
tagspromises filtering ("critical", "regression") that does not exist, andrequires.pluginsreads as a guard but never skips. Both are misleading rather than benign.Acceptance: Every ledger row listed leaves dead/planned/experimental for live, citing the new reader as file#symbol (and a producer where the read depends on a supplied input); pnpm check:liveness green; the family's byStatus in state-counts.md regenerated.
Lane: domain:spec parent + domain:engine-core / cli sub-issue, all in objectstack
File surface: packages/spec/src/qa/testing.zod.ts:63-79 · packages/core/src/qa/runner.ts · packages/cli/src/commands/test.ts · packages/spec/liveness/qa.json
Dedupe:
TestSuiteSchema \| qa/runner \| scenario\.tags \| scenarios?\.(tags\|requires) \| os test --tags \| testing\.zod→ 1 open hit. None carries a key of this family:四轴:
requires.plugins以为是守卫,实际在缺插件的服务器上会跑出无法解释的 HTTP 错误。执行后改为带原因的跳过。