@pzy560117/opentest 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -12,6 +12,8 @@ plan -> author -> run -> accept -> verify -> archive
12
12
 
13
13
  `heal` is a recovery phase for stale test assets and must not hide product behavior failures.
14
14
 
15
+ When OpenTest needs code-level tests and the project does not declare an existing test framework, it defaults to `pytest`. Coverage completeness is enforced through the acceptance-to-test matrix: every applicable behavior, boundary, and risk surface must have evidence or an explicit gap/blocker with a recovery path.
16
+
15
17
  Recommended placement in a development loop:
16
18
 
17
19
  ```text
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.1.5",
2
+ "version": "0.1.6",
3
3
  "languages": [
4
4
  {
5
5
  "id": "en",
@@ -14,6 +14,7 @@ package_script_present() {
14
14
 
15
15
  summary() {
16
16
  printf '=== OpenTest Project Facts ===\n'
17
+ printf 'default_test_framework: pytest\n'
17
18
 
18
19
  if [ -f package.json ]; then
19
20
  printf 'package_json: present\n'
@@ -29,6 +30,11 @@ summary() {
29
30
  else
30
31
  printf 'python_tests: missing\n'
31
32
  fi
33
+ if command -v python >/dev/null 2>&1 && python -m pytest --version >/dev/null 2>&1; then
34
+ printf 'pytest_command: present\n'
35
+ else
36
+ printf 'pytest_command: missing\n'
37
+ fi
32
38
 
33
39
  if [ -f pom.xml ]; then printf 'maven_project: present\n'; else printf 'maven_project: missing\n'; fi
34
40
  if [ -f Cargo.toml ]; then printf 'cargo_project: present\n'; else printf 'cargo_project: missing\n'; fi
@@ -69,7 +69,7 @@ require_state_file() {
69
69
 
70
70
  validate_known_field() {
71
71
  case "$1" in
72
- workflow|phase|plan|matrix|acceptance|run_mode|run_report|verification_result|verification_report|archived|created_at|updated_at)
72
+ workflow|phase|plan|matrix|acceptance|run_mode|run_report|test_framework|coverage_report|verification_result|verification_report|archived|created_at|updated_at)
73
73
  return 0
74
74
  ;;
75
75
  *)
@@ -113,6 +113,8 @@ matrix: null
113
113
  acceptance: null
114
114
  run_mode: targeted
115
115
  run_report: null
116
+ test_framework: pytest
117
+ coverage_report: null
116
118
  verification_result: pending
117
119
  verification_report: null
118
120
  archived: false
@@ -147,6 +149,9 @@ cmd_set() {
147
149
  verification_result)
148
150
  validate_enum "$value" pending pass fail risk-accepted
149
151
  ;;
152
+ test_framework)
153
+ validate_enum "$value" pytest project-existing none
154
+ ;;
150
155
  archived)
151
156
  validate_enum "$value" true false
152
157
  ;;
@@ -1,6 +1,6 @@
1
1
  # Acceptance-to-Test Matrix
2
2
 
3
- | ID | Intent | Trigger/Input | Expected behavior | Risk | Evidence layer | Required evidence | Status |
4
- | --- | --- | --- | --- | --- | --- | --- | --- |
5
- | ACC-001 | Happy path succeeds | | | low | smoke | targeted review | pending |
6
- | ACC-002 | Failure or boundary path | | | medium | acceptance | UI/API acceptance | pending |
3
+ | ID | Intent | Coverage dimension | Trigger/Input | Expected behavior | Risk | Evidence layer | Framework/command | Required evidence | Gap/blocker | Status |
4
+ | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
5
+ | ACC-001 | Happy path succeeds | main path | | | low | smoke | project command or `python -m pytest` | targeted review | none | pending |
6
+ | ACC-002 | Failure or boundary path | failure/boundary | | | medium | acceptance | natural-language acceptance or `python -m pytest` | UI/API acceptance | none | pending |
@@ -15,13 +15,14 @@ This phase turns the matrix into executable evidence. Write tests for behavior t
15
15
 
16
16
  1. Read `matrix` from `.opentest.yaml`.
17
17
  2. For unit/component/integration/contract evidence, create or update test files using the project's existing test framework.
18
- 3. For E2E, smoke, browser acceptance, real APIs, or cross-page flows, write natural language acceptance cases under `docs/opentest/acceptance/`.
19
- 4. For frontend feedback cases, specify the feedback location and shape, such as field-level errors, form-level errors, toast, modal, inline status, or page error state.
20
- 5. Record reasons and risk for evidence that is not applicable or cannot currently be created.
21
- 6. Write the `.opentest.yaml` `acceptance` field.
22
- 7. If the project uses Loop Handoff, update `docs/loop-handoff/latest.md` with test assets, natural language acceptance cases, gaps/risks, and next step.
23
- 8. Run `bash "$OPENTEST_GUARD" author --apply`.
18
+ 3. Default to pytest when code-level tests are required and the project has no explicit framework rule or existing framework. Prefer `tests/` and a command that can run with `python -m pytest`.
19
+ 4. For E2E, smoke, browser acceptance, real APIs, or cross-page flows, write natural language acceptance cases under `docs/opentest/acceptance/`.
20
+ 5. For frontend feedback cases, specify the feedback location and shape, such as field-level errors, form-level errors, toast, modal, inline status, or page error state.
21
+ 6. Record reasons and risk for evidence that is not applicable or cannot currently be created.
22
+ 7. Write the `.opentest.yaml` `acceptance` field.
23
+ 8. If the project uses Loop Handoff, update `docs/loop-handoff/latest.md` with test assets, natural language acceptance cases, gaps/risks, and next step.
24
+ 9. Run `bash "$OPENTEST_GUARD" author --apply`.
24
25
 
25
26
  ## Existing Skill Routing
26
27
 
27
- When the matrix requires code-level test evidence, load the existing TDD guidance first. If project rules require a specific test framework, follow those rules. If the current task is better proven by real acceptance than by adding test framework code, record the reason and hand it to `opentest-accept`.
28
+ When the matrix requires code-level test evidence, load the existing TDD guidance first. If project rules require a specific test framework, follow those rules. If no project framework is present, use pytest as the default instead of inventing a custom harness. If the current task is better proven by real acceptance than by adding test framework code, record the reason and hand it to `opentest-accept`.
@@ -15,10 +15,10 @@ This phase is the entry point for OpenTest-driven development. Before implementa
15
15
 
16
16
  1. Read project rules, requirements, design, diff, existing test commands, and `opentest/references/codex-harness-coverage-heuristics.md`.
17
17
  2. If the change involves frontend UI, forms, navigation, CRUD, status feedback, or motion, first read the project's `docs/frontend/DESIGN.md` and any available `harness-frontend-design` / `product-ui-defaults` rules.
18
- 3. Classify the change type, risk level, and applicable coverage.
18
+ 3. Classify the change type, risk level, applicable coverage dimensions, and whether code-level evidence should use an existing project framework or the default `pytest` framework.
19
19
  4. Mine implicit scenarios: empty input, invalid input, network failure, missing permissions, duplicate submission, long content, empty data, error mapping, mobile behavior, accessibility, cross-page return paths, and state restoration.
20
- 5. Produce a narrow matrix with at least `ID`, `intent`, `trigger/input`, `expected behavior`, `risk`, `evidence layer`, `required evidence`, and `status`.
21
- 6. Mark applicable but uncovered evidence as `gap`.
20
+ 5. Produce a narrow matrix with at least `ID`, `intent`, `coverage dimension`, `trigger/input`, `expected behavior`, `risk`, `evidence layer`, `framework/command`, `required evidence`, `gap/blocker`, and `status`.
21
+ 6. Mark applicable but uncovered evidence as `gap`, and record a concrete blocker or recovery path instead of leaving coverage unknown.
22
22
  7. Write the `.opentest.yaml` `plan` and `matrix` fields.
23
23
  8. If the project uses Loop Handoff, update `docs/loop-handoff/latest.md` with the plan path, matrix path, current phase, and next step.
24
24
  9. Run `bash "$OPENTEST_GUARD" plan --apply`.
@@ -28,3 +28,5 @@ This phase is the entry point for OpenTest-driven development. Before implementa
28
28
  Do not expand the full Codex Harness checklist into fixed required items. Keep a lightweight coverage summary for low-risk changes, and expand detailed acceptance dimensions only for high-risk loops.
29
29
 
30
30
  Do not force all evidence into unit tests. The matrix must state which behavior is proven by unit, component, integration, contract, E2E, smoke, browser acceptance, or security review evidence.
31
+
32
+ Coverage completeness means every applicable product behavior, failure path, boundary, and risk surface has either required evidence or an explicit gap/blocker. It does not mean every task must run every possible test type.
@@ -18,11 +18,14 @@ Run existing project verification commands and write a run report.
18
18
 
19
19
  Evidence layers are decided by the matrix. Do not run only unit tests just because `npm test` exists. If the matrix requires integration, contract, E2E, smoke, or security checks, run the matching project command or record missing command / blocked.
20
20
 
21
+ If `.opentest.yaml` has `test_framework: pytest`, or code-level test evidence is required and no project framework is declared, use `python -m pytest` as the default test command. When the matrix requires coverage evidence, prefer `python -m pytest --cov=. --cov-report=term-missing` and write the coverage output path to `.opentest.yaml` `coverage_report`. If pytest or pytest-cov is unavailable, record `missing command` with the install/remediation step instead of passing the gate.
22
+
21
23
  ## Steps
22
24
 
23
25
  1. Read `run_mode` and the matrix from `.opentest.yaml`.
24
26
  2. Prefer explicit project commands, and select targeted, fast, full, or ci-like mode based on matrix evidence layers.
25
- 3. Record command, exit code, summary, and log path under `docs/opentest/runs/`.
26
- 4. Write the `.opentest.yaml` `run_report` field.
27
- 5. If the project uses Loop Handoff, update `docs/loop-handoff/latest.md` with verification already run, verification not run, failures/blockers, run report path, and next step.
28
- 6. Run `bash "$OPENTEST_GUARD" run --apply`.
27
+ 3. If no explicit command exists for code-level tests, run or document the default pytest command.
28
+ 4. Record command, exit code, summary, coverage output, and log path under `docs/opentest/runs/`.
29
+ 5. Write the `.opentest.yaml` `run_report` field, and write `coverage_report` when coverage evidence was required or produced.
30
+ 6. If the project uses Loop Handoff, update `docs/loop-handoff/latest.md` with verification already run, verification not run, failures/blockers, run report path, and next step.
31
+ 7. Run `bash "$OPENTEST_GUARD" run --apply`.
@@ -19,6 +19,8 @@ If the project uses Loop Handoff, also write the OpenTest verification report pa
19
19
  The verification report must also review the matrix and confirm:
20
20
 
21
21
  - Every required evidence item has a pass, fail, blocked, or risk-accepted conclusion.
22
+ - Coverage completeness is checked: every applicable coverage dimension in the matrix has required evidence, a run/acceptance result, or an explicit gap/blocker with recovery path.
22
23
  - High-risk behavior does not pass merely because tooling, a test framework, or seed data is missing.
24
+ - If code-level coverage was required and `test_framework: pytest` is active, the report must include the `python -m pytest` command result and the `coverage_report` path, or fail/block with a reason.
23
25
  - Blocked evidence includes a blocker reason and recovery path.
24
26
  - If product behavior fails, do not enter `heal` to patch test assets; return to implementation or requirement correction.
@@ -1,6 +1,6 @@
1
1
  # 验收到测试矩阵
2
2
 
3
- | ID | 意图 | 触发/输入 | 期望行为 | 风险 | 证据层级 | 必需证据 | 状态 |
4
- | --- | --- | --- | --- | --- | --- | --- | --- |
5
- | ACC-001 | 主路径成功 | | | low | smoke | targeted review | pending |
6
- | ACC-002 | 失败/边界路径 | | | medium | acceptance | UI/API 验收 | pending |
3
+ | ID | 意图 | 覆盖维度 | 触发/输入 | 期望行为 | 风险 | 证据层级 | 框架/命令 | 必需证据 | 缺口/阻塞 | 状态 |
4
+ | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
5
+ | ACC-001 | 主路径成功 | 主路径 | | | low | smoke | 项目命令或 `python -m pytest` | targeted review | 无 | pending |
6
+ | ACC-002 | 失败/边界路径 | 失败/边界 | | | medium | acceptance | 自然语言验收或 `python -m pytest` | UI/API 验收 | 无 | pending |
@@ -15,13 +15,14 @@ description: "OpenTest 阶段 2:根据矩阵补齐测试资产和自然语言
15
15
 
16
16
  1. 读取 `.opentest.yaml` 中的 `matrix`。
17
17
  2. 对 unit/component/integration/contract 证据,按项目已有测试框架创建或更新测试文件。
18
- 3. E2E、smoke、browser acceptance、真实 API 或跨页面流程,写入 `docs/opentest/acceptance/` 自然语言验收用例。
19
- 4. 对前端反馈类用例,写清反馈位置和形态,例如字段下方错误、表单顶部错误、轻提示、模态框、行内状态或页面错误态。
20
- 5. 对不适用或当前无法补齐的证据,记录原因和风险。
21
- 6. 写入 `.opentest.yaml` 的 `acceptance` 字段。
22
- 7. 更新 `docs/loop-handoff/latest.md`(如果项目使用 Loop Handoff),记录测试资产、自然语言验收用例、gap/risk 和下一步。
23
- 8. 运行 `bash "$OPENTEST_GUARD" author --apply`。
18
+ 3. 当矩阵要求代码级测试、且项目没有明确框架规则或既有框架时,默认使用 pytest;优先放在 `tests/`,并确保可用 `python -m pytest` 运行。
19
+ 4. 对 E2E、smoke、browser acceptance、真实 API 或跨页面流程,写入 `docs/opentest/acceptance/` 自然语言验收用例。
20
+ 5. 对前端反馈类用例,写清反馈位置和形态,例如字段下方错误、表单顶部错误、轻提示、模态框、行内状态或页面错误态。
21
+ 6. 对不适用或当前无法补齐的证据,记录原因和风险。
22
+ 7. 写入 `.opentest.yaml` `acceptance` 字段。
23
+ 8. 更新 `docs/loop-handoff/latest.md`(如果项目使用 Loop Handoff),记录测试资产、自然语言验收用例、gap/risk 和下一步。
24
+ 9. 运行 `bash "$OPENTEST_GUARD" author --apply`。
24
25
 
25
26
  ## 现有技能路由
26
27
 
27
- 当矩阵要求代码级测试证据时,优先加载现有 TDD guidance。若项目规则要求特定测试框架,遵循项目规则。若当前任务更适合真实验收而不是新增测试框架代码,记录原因并交给 `opentest-accept`。
28
+ 当矩阵要求代码级测试证据时,优先加载现有 TDD guidance。若项目规则要求特定测试框架,遵循项目规则。若项目没有测试框架,默认使用 pytest,不临时发明自定义测试壳。若当前任务更适合真实验收而不是新增测试框架代码,记录原因并交给 `opentest-accept`。
@@ -15,10 +15,10 @@ description: "OpenTest 阶段 1:分析变更、风险和项目事实,生成
15
15
 
16
16
  1. 读取项目规则、需求、设计、diff、现有测试命令和 `opentest/references/codex-harness-coverage-heuristics.md`。
17
17
  2. 如果存在前端、表单、导航、CRUD、状态反馈或动效,优先读取项目内 `docs/frontend/DESIGN.md` 和可用的 `harness-frontend-design` / `product-ui-defaults` 规则。
18
- 3. 判断变更类型、风险等级和适用覆盖面。
18
+ 3. 判断变更类型、风险等级、适用覆盖维度,以及代码级证据应使用项目已有框架还是默认 `pytest` 框架。
19
19
  4. 做隐性场景挖掘:空输入、非法输入、网络失败、权限不足、重复提交、长内容、空数据、错误映射、移动端、可访问性、跨页面返回和状态恢复。
20
- 5. 生成窄矩阵,至少包含 `ID`、`意图`、`触发/输入`、`期望行为`、`风险`、`证据层级`、`必需证据`、`状态`。
21
- 6. 对适用但未覆盖的证据面标记 `gap`。
20
+ 5. 生成窄矩阵,至少包含 `ID`、`意图`、`覆盖维度`、`触发/输入`、`期望行为`、`风险`、`证据层级`、`框架/命令`、`必需证据`、`缺口/阻塞`、`状态`。
21
+ 6. 对适用但未覆盖的证据面标记 `gap`,并写清具体阻塞或恢复路径,不把覆盖状态留成 unknown。
22
22
  7. 写入 `.opentest.yaml` 的 `plan` 和 `matrix` 字段。
23
23
  8. 更新 `docs/loop-handoff/latest.md`(如果项目使用 Loop Handoff),记录 plan、matrix 路径、当前阶段和下一步。
24
24
  9. 运行 `bash "$OPENTEST_GUARD" plan --apply`。
@@ -28,3 +28,5 @@ description: "OpenTest 阶段 1:分析变更、风险和项目事实,生成
28
28
  不要把 Codex Harness 全量 checklist 展开成固定必需项。低风险变更保留轻量覆盖摘要,高风险闭环再展开详细验收维度。
29
29
 
30
30
  不要把所有证据都写成 unit test。矩阵要明确哪些用 unit/component/integration/contract/E2E/smoke/browser acceptance/security review 证明。
31
+
32
+ 覆盖完整性指每个适用的产品行为、失败路径、边界和风险面都有必需证据,或有明确的 gap/blocker;不是要求每次任务都跑所有测试类型。
@@ -18,11 +18,14 @@ description: "OpenTest 阶段 3:按 targeted、fast、full 或 ci-like 模式
18
18
 
19
19
  证据层级由矩阵决定。不要因为存在 `npm test` 就只跑 unit test;如果矩阵要求 integration、contract、E2E、smoke 或安全检查,必须运行对应项目命令,或记录 missing command / blocked。
20
20
 
21
+ 如果 `.opentest.yaml` 中 `test_framework: pytest`,或矩阵要求代码级测试但项目没有声明测试框架,默认测试命令使用 `python -m pytest`。当矩阵要求覆盖率证据时,优先使用 `python -m pytest --cov=. --cov-report=term-missing`,并把覆盖率输出路径写入 `.opentest.yaml` 的 `coverage_report`。如果缺少 pytest 或 pytest-cov,记录 `missing command` 和安装/恢复步骤,不允许直接通过质量门。
22
+
21
23
  ## 步骤
22
24
 
23
25
  1. 读取 `.opentest.yaml` 的 `run_mode` 和矩阵。
24
26
  2. 优先使用项目显式命令,按矩阵中的证据层级选择 targeted、fast、full 或 ci-like。
25
- 3. 记录命令、退出码、摘要和日志路径到 `docs/opentest/runs/`。
26
- 4. 写入 `.opentest.yaml` 的 `run_report` 字段。
27
- 5. 更新 `docs/loop-handoff/latest.md`(如果项目使用 Loop Handoff),记录已运行验证、未运行验证、失败/阻塞、run report 路径和下一步。
28
- 6. 运行 `bash "$OPENTEST_GUARD" run --apply`。
27
+ 3. 如果代码级测试没有显式命令,运行或记录默认 pytest 命令。
28
+ 4. 记录命令、退出码、摘要、覆盖率输出和日志路径到 `docs/opentest/runs/`。
29
+ 5. 写入 `.opentest.yaml` `run_report` 字段;当要求或产生覆盖率证据时,也写入 `coverage_report`。
30
+ 6. 更新 `docs/loop-handoff/latest.md`(如果项目使用 Loop Handoff),记录已运行验证、未运行验证、失败/阻塞、run report 路径和下一步。
31
+ 7. 运行 `bash "$OPENTEST_GUARD" run --apply`。
@@ -19,6 +19,8 @@ description: "OpenTest 阶段 5:应用质量门并生成验证报告。"
19
19
  验证报告还必须回看矩阵,确认:
20
20
 
21
21
  - 每个 required evidence 都有 pass、fail、blocked 或 risk-accepted 结论。
22
+ - 覆盖完整性已检查:矩阵中的每个适用覆盖维度都有必需证据、运行/验收结果,或带恢复路径的明确 gap/blocker。
22
23
  - 高风险行为不能因为没有工具、没有测试框架或没有 seed data 就直接通过。
24
+ - 如果要求代码级覆盖率且 `test_framework: pytest` 生效,报告必须包含 `python -m pytest` 命令结果和 `coverage_report` 路径;否则必须 fail/block 并写明原因。
23
25
  - blocked evidence 必须包含阻塞原因和后续恢复路径。
24
26
  - 若产品行为失败,不进入 `heal` 修测试资产;应返回实现或需求修正。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pzy560117/opentest",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "OpenTest quality evidence lifecycle skills for Codex",
5
5
  "keywords": [
6
6
  "opentest",
@@ -156,6 +156,33 @@ function assertPrepublishGateCoversManifestAssets() {
156
156
  assert(prepublishCheck.includes("assets/skills-zh"), '[PREPUBLISH] must validate assets/skills-zh exists');
157
157
  }
158
158
 
159
+ function assertDefaultPytestContracts() {
160
+ const stateScript = readFileSync('assets/skills/opentest/scripts/opentest-state.sh', 'utf8');
161
+ const detectScript = readFileSync('assets/skills/opentest/scripts/opentest-detect.sh', 'utf8');
162
+ const englishAuthor = readFileSync('assets/skills/opentest-author/SKILL.md', 'utf8');
163
+ const chineseAuthor = readFileSync('assets/skills-zh/opentest-author/SKILL.md', 'utf8');
164
+ const englishRun = readFileSync('assets/skills/opentest-run/SKILL.md', 'utf8');
165
+ const chineseRun = readFileSync('assets/skills-zh/opentest-run/SKILL.md', 'utf8');
166
+ const englishVerify = readFileSync('assets/skills/opentest-verify/SKILL.md', 'utf8');
167
+ const chineseVerify = readFileSync('assets/skills-zh/opentest-verify/SKILL.md', 'utf8');
168
+ const englishMatrix = readFileSync('assets/skills/opentest/templates/matrix-template.md', 'utf8');
169
+ const chineseMatrix = readFileSync('assets/skills-zh/opentest/templates/matrix-template.md', 'utf8');
170
+
171
+ assert(stateScript.includes('test_framework: pytest'), '[PYTEST] state init must default test_framework to pytest');
172
+ assert(stateScript.includes('coverage_report: null'), '[PYTEST] state init must track coverage_report');
173
+ assert(stateScript.includes('test_framework|'), '[PYTEST] state script must allow test_framework field updates');
174
+ assert(detectScript.includes('default_test_framework: pytest'), '[PYTEST] detect summary must report pytest as default framework');
175
+ assert(detectScript.includes('pytest_command:'), '[PYTEST] detect summary must report pytest command status');
176
+ assert(englishAuthor.includes('Default to pytest'), '[PYTEST] English author skill must default missing framework to pytest');
177
+ assert(chineseAuthor.includes('默认使用 pytest'), '[PYTEST] Chinese author skill must default missing framework to pytest');
178
+ assert(englishRun.includes('python -m pytest'), '[PYTEST] English run skill must document pytest command');
179
+ assert(chineseRun.includes('python -m pytest'), '[PYTEST] Chinese run skill must document pytest command');
180
+ assert(englishVerify.includes('Coverage completeness'), '[COVERAGE] English verify skill must gate coverage completeness');
181
+ assert(chineseVerify.includes('覆盖完整性'), '[COVERAGE] Chinese verify skill must gate coverage completeness');
182
+ assert(englishMatrix.includes('Coverage dimension') && englishMatrix.includes('Framework/command') && englishMatrix.includes('Gap/blocker'), '[COVERAGE] English matrix template must include coverage, command, and gap columns');
183
+ assert(chineseMatrix.includes('覆盖维度') && chineseMatrix.includes('框架/命令') && chineseMatrix.includes('缺口/阻塞'), '[COVERAGE] Chinese matrix template must include coverage, command, and gap columns');
184
+ }
185
+
159
186
  async function assertPrepublishRejectsPublishSecretTextFiles() {
160
187
  const fixtureDir = path.join('assets', 'opentest-smoke-secret-fixtures');
161
188
  const fixtures = [
@@ -459,6 +486,7 @@ async function assertInitBehavior() {
459
486
  runManifestPathRelativitySelfCheck();
460
487
  assertManifestStructure();
461
488
  assertPrepublishGateCoversManifestAssets();
489
+ assertDefaultPytestContracts();
462
490
  assertOpenTestSearchRootsCoverPlatforms();
463
491
  assertLanguageAssetContracts();
464
492
  await assertPrepublishRejectsPublishSecretTextFiles();