@ccoalm/ccl-skills 0.6.1 → 0.7.0

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.
Files changed (63) hide show
  1. package/README.md +55 -15
  2. package/dist/assets/marketplace/plugins/ccl-skills/hooks/hooks.json +11 -0
  3. package/dist/assets/marketplace/plugins/ccl-skills/hooks/remind-unverified-cli-flag.sh +309 -0
  4. package/dist/assets/marketplace/plugins/ccl-skills/hooks/test_remind_unverified_cli_flag.sh +483 -0
  5. package/dist/assets/marketplace/plugins/ccl-skills/packages/opencode-plugin/ccl-skills.ts +5 -0
  6. package/dist/assets/marketplace/plugins/ccl-skills/skills/app-cross-platform-dev/SKILL.md +2 -1
  7. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/SKILL.md +1 -1
  8. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/architecture-playbook.md +2 -0
  9. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/data-platform-architecture.md +1 -1
  10. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/event-driven-architecture.md +14 -11
  11. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/multi-tenant-isolation.md +2 -2
  12. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/SKILL.md +1 -0
  13. package/dist/assets/marketplace/plugins/ccl-skills/skills/miniapp-product-dev/SKILL.md +2 -1
  14. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/SKILL.md +1 -1
  15. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/references/sli-slo-design.md +25 -9
  16. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/references/source-register.md +1 -0
  17. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/SKILL.md +1 -1
  18. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/promotion-gate-and-review.md +16 -0
  19. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/secret-and-config-management.md +7 -0
  20. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/retry-timeout-circuit-breaker.md +11 -0
  21. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/SKILL.md +5 -1
  22. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/architecture-playbook.md +1 -1
  23. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/audit-history-architecture.md +31 -0
  24. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/data-platform-architecture.md +1 -1
  25. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/event-driven-architecture.md +7 -4
  26. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/multi-tenant-isolation.md +2 -2
  27. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/notification-architecture.md +28 -0
  28. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/packaging-runtime-readiness.md +1 -1
  29. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/replay-comparison-architecture.md +28 -0
  30. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/workflow-state-architecture.md +39 -0
  31. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/SKILL.md +6 -6
  32. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/ai-service-wiring-patterns.md +8 -0
  33. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/audit-history-patterns.md +29 -0
  34. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/background-job-patterns.md +16 -0
  35. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/batch-and-artifact-patterns.md +25 -1
  36. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/notification-patterns.md +40 -0
  37. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/public-api-security-patterns.md +1 -1
  38. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/replay-comparison-patterns.md +30 -0
  39. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/state-machine-task-patterns.md +48 -0
  40. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/testing-and-quality-patterns.md +10 -1
  41. package/dist/assets/marketplace/plugins/ccl-skills/skills/release-coordination/SKILL.md +2 -0
  42. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/coverage-exhaustion-traps.md +45 -0
  43. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/dual-track-review-gate.md +48 -0
  44. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/external-practice-controls.md +21 -2
  45. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/firing-point-placement.md +8 -0
  46. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/parallel-stack-references-pattern.md +5 -4
  47. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/source-register.md +15 -0
  48. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/source-to-skill-extraction.md +2 -0
  49. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/check-ccl-skills.sh +24 -0
  50. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/check-parallel-stack-parity.sh +119 -0
  51. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_parallel_stack_parity.sh +183 -0
  52. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_regressions.sh +2 -0
  53. package/dist/assets/marketplace/plugins/ccl-skills/skills/terminal-cli-dev/SKILL.md +1 -0
  54. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/SKILL.md +3 -4
  55. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/fitness-functions.md +16 -0
  56. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/scenario-testing.md +1 -1
  57. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/test-code-authoring-patterns.md +16 -5
  58. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/SKILL.md +5 -3
  59. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/references/delivery-face-closeout.md +16 -6
  60. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/references/self-benchmark-baseline.md +37 -0
  61. package/dist/assets/marketplace/plugins/ccl-skills/skills/web-react-dev/SKILL.md +1 -0
  62. package/dist/assets/release.json +115 -50
  63. package/package.json +3 -3
@@ -14,6 +14,7 @@
14
14
  # - test_controlled_escalation_pins.sh
15
15
  # - test_check_ccl_size_budget.sh
16
16
  # - test_check_ccl_skill_catalog.sh
17
+ # - test_check_ccl_parallel_stack_parity.sh
17
18
  # - test_generic_r0_leak_scan.sh
18
19
  # - test_check_ccl_route_drift.sh
19
20
  # - test_check_sync_pointers.sh
@@ -101,6 +102,7 @@ fast_tests=(
101
102
  test_controlled_escalation_pins.sh
102
103
  test_check_ccl_size_budget.sh
103
104
  test_check_ccl_skill_catalog.sh
105
+ test_check_ccl_parallel_stack_parity.sh
104
106
  test_check_mr_target_freshness.sh
105
107
  test_generic_r0_leak_scan.sh
106
108
  test_check_ccl_route_drift.sh
@@ -73,6 +73,7 @@ When checking a terminal/CLI project against team standards, split conformance i
73
73
 
74
74
  8. Verify on the real terminal surface.
75
75
  - Unit-test width, wrapping, truncation, ANSI parsing, key parsing, state transitions, and capability fallback.
76
+ - When writing the test code itself (structure, naming, smells, fixtures, behavior-vs-state, coverage, isolation, parameterization), pick the matching § from the decision table in `testing-strategy/references/test-code-authoring-patterns.md`; enable the per-stack lint executors for its machine-decidable smells (conditional logic / sleep / assertion-free tests) per `testing-strategy/references/fitness-functions.md` §4.1.4, reusing the row for the implementation language (Go/Python/JS; Rust: sleep bans via `clippy::disallowed_methods`, conditional-logic and assertion-free checks stay agent-review).
76
77
  - Snapshot at the cell/screen-buffer layer when possible; raw string snapshots alone are insufficient for interactive terminal behavior.
77
78
  - Use a PTY or equivalent integration test for raw mode, resize, key/mouse/paste sequences, terminal responses, and process lifecycle.
78
79
  - Run at least one real terminal smoke for visible interactive changes when lower layers cannot prove color, cursor, scrollback, focus, selection, or resize behavior.
@@ -150,7 +150,6 @@ Before editing tests, CI gates, mocks/fakes, fixtures, test scripts, verificatio
150
150
  - If a frontend or app repository has only build/dev/format scripts and no assertion-based UI tests, do not treat that as adequate coverage for interaction changes. Use build/typecheck as a structural gate, then add focused state/API tests or record the missing test layer and require rendered browser/device evidence.
151
151
  - If CI mainly builds images or deploys by branch/environment, classify it as release plumbing. It does not prove product behavior unless assertion-based test jobs run and block delivery.
152
152
  - When adding a new client platform scaffold, inspect whether the generator added default sample tests. Keep a sample only if it asserts real product behavior; otherwise replace it with the smallest deterministic smoke that would fail if the current shell, navigation, entrypoint, or visible state were missing.
153
- - If CI mainly builds or deploys by branch/environment and has little or no assertion-based test stage, classify it as release plumbing, not product correctness evidence.
154
153
 
155
154
  2. Identify the behavior to prove.
156
155
  - User/caller outcome.
@@ -175,14 +174,14 @@ Before editing tests, CI gates, mocks/fakes, fixtures, test scripts, verificatio
175
174
  For client API-backed surfaces, mini-program/mobile/device runtime smoke, runtime-client mechanisms (route guards, permission trees, request interceptors, generated clients, upload wrappers, long-task polling, safe-area/keyboard/orientation handling, foreground/background restore, native bridges, app-hosted H5), terminal/CLI/TUI runtime tests, and streaming/async-finality changes (model streams, queued jobs, MQ consumers, scheduled prompt tasks, cron tasks, persisted tool-output artifacts, long-running exports, long-lived connections), load `references/client-runtime-test-matrices.md` before assigning layers — and again before declaring any runtime/device/browser evidence unavailable, not only at layer assignment. Non-negotiable anchors kept in view here: the default three-boundary client split (unit/component + API client/contract + browser/device smoke) applies unless the repository has a stronger convention; runtime-dependent smoke is **blocking** when lower layers cannot prove the changed behavior, and a missing runner after normal remediation stops at `pre-runtime-test ready` or `blocked` with owner, commands attempted, residual risk, and next unblock action — never converts into a code correctness claim; developer-tool compile/preview is structural evidence only; dangerous or irreversible operations require operator/confirmation/audit/duplicate-submit/final-status assertions before the UI or API is called ready. Build scenario matrices from the reference's reusable dimensions (host/container, identity/permission, data/state, async/finality, visual/interaction, high-consequence); do not paste product-specific matrices into this skill — product-specific lists belong in the project checklist or the owning product/domain skill.
176
175
 
177
176
  4. Define data and dependency strategy.
178
- - Use small fixtures named by scenario.
177
+ - Use small fixtures named by scenario. For repeated/complex fixture construction, pick §4 (factory/builder) from the decision table in `references/test-code-authoring-patterns.md`.
179
178
  - Use fakes for domain behavior and integration tests for external contracts.
180
179
  - Keep real credentials, live services, long sleeps, and network-only dependencies out of default fast tests.
181
180
  - Tests that hit live DB, Redis, MQ, RPC, model service, object storage, or real external APIs must be marked or commanded as integration/e2e/drill tests. They are release evidence, not the default fast gate, and they must not replace lower-layer assertions.
182
181
  - Use temp directories and cleanup hooks for file output. A temporary smoke/instrumentation test file created only as delivery evidence is removed (or promoted to a maintained test) before the MR/PR (or equivalent review gate) is review-ready — the recorded run output/transcript is the evidence, not the lingering file. Prefer a temp dir or a dry-run/`--no-write` flag over mutating a real tracked repo file in place. If a test or verification MUST seed or mutate a tracked file, undo only the exact thing you added (delete that line/file) and re-check `git status` before continuing. In a non-disposable working tree (one with other uncommitted work or that you are not about to delete wholesale), never clean up with a blanket `git checkout .` / `git checkout -- <file>` / `git reset --hard` / `rm` unless `git status` first proves your seeded mutation is the only change present — otherwise it also discards unrelated uncommitted edits or deletes committed files. (A throwaway worktree or fresh clone you will remove entirely is exempt.)
183
182
 
184
183
  5. Define assertions and evidence.
185
- - Assert final user/caller-visible result.
184
+ - Assert final user/caller-visible result. Author code per that table — §8: parameterize same-logic inputs instead of copy-pasting — and its closeout checklist walk is required before review.
186
185
  - Assert persisted state, emitted event, dependency call, trace/log id, or browser-visible state where relevant.
187
186
  - For E2E, collect console errors, failed network requests, screenshots/video/traces when useful, but do not rely on artifacts without assertions. Give smoke/e2e harnesses prod-grade rigor: tolerate benign address/format variation (normalize or match structurally instead of pinning a brittle literal) while still asserting the real outcome, and validate the proof artifact itself — reject malformed, empty, duplicate, or stale evidence — so a green cannot be a false positive resting on non-fresh or corrupt evidence.
188
187
 
@@ -205,7 +204,7 @@ Before editing tests, CI gates, mocks/fakes, fixtures, test scripts, verificatio
205
204
  - For browser, API workflow, real-flow, release smoke, and E2E evidence, read `references/e2e-real-flow-testing.md`.
206
205
  - For CI gates, test data, fixtures, flake control, and verification reporting, read `references/ci-fixtures-and-flake-control.md`.
207
206
  - For translating structured TC lists from `test-artifact-management` or Feishu Bitable into test-layer choices, status handling, TC ID metadata, execution-type routing, and handoff rules, read `references/structured-tc-input-translation.md`.
208
- - For **how to write the test code itself** — AAA / Given-When-Then structure, naming convention, Meszaros test smells, Object Mother / Test Data Builder fixtures, behavior vs state verification, coverage interpretation, isolation, table-driven / parameterized tests — read `references/test-code-authoring-patterns.md`. 8 stack-agnostic engineering patterns + when to use / when not + examples in neutral domains.
207
+ - For **how to write the test code itself** — the 8 stack-agnostic authoring patterns (structure, naming, smells, fixtures, behavior-vs-state, coverage, isolation, parameterization) plus the closeout checklist — read `references/test-code-authoring-patterns.md` (steps 4–5 route here).
209
208
  - For **architecture fitness functions** (Ford et al. 2017) — automated tests that verify architectural invariants (no circular deps / DAL-only DB access / latency budget / module-boundary enforcement / breaking-change detection / security invariants), read `references/fitness-functions.md`. Different from product correctness tests; protects structural commitments declared in ADRs from drift.
210
209
  - For the killing-mutation walk's guarded backup recipe, mutation blast-radius discipline, destructive-artifact probe encoding, and round-trip nuance, read `references/run-killing-mutation-walk.md`.
211
210
  - For closed-contract oracle design — denylist failure shapes, oracle-dimension explanations, and precision near-miss rows — read `references/design-closed-contract-oracles.md`.
@@ -182,6 +182,22 @@ Layering/dependency-direction (**全栈 custom 旗舰,无 out-of-box 规则**)
182
182
 
183
183
  **D. backlog(named owner + 触发条件,不半 ship)**:每栈 dispose 生命周期 / 取消协作(Swift Task `isCancelled`、RN useEffect abort)/ 语义吞异常 / JS-TS finite-value 集中 / 分层自定义规则——需 AST/类型分析或各栈 toolchain,触发=该栈消费仓启用 dep-conformance CI 时拾取。
184
184
 
185
+ ### 4.1.4 测试 smell conformance — 可判定谓词的生态执行器
186
+
187
+ 承载 `test-code-authoring-patterns.md` §3 中三个可机判 test smell 的 lint 下沉:**测试内条件逻辑**(Conditional Test Logic)、**测试内 sleep**(Slow/Erratic 常见成因)、**无断言测试**。原则同 §4.1.3:生态 linter 是默认执行器,**本节不 ship 自写检查器**;无生态规则的格子如实记 agent-review(按 §3 清单人审兜底),不做半成品 parser。均为**消费仓 config**(opt-in,采纳语义同 §4.1.2),由对应 stack `*-dev` owner 提供/维护;六个 stack `*-dev` 技能从各自 verify 步指到本节,`terminal-cli-dev` 按实现语言复用 Go/Python/JS 行(Rust:实扫 rust-lang.github.io/rust-clippy/master/index.html 的 lint 索引——三列均无专用规则,`assert*` 类 lint 均为断言写法类 → agent-review;sleep 可经 `clippy::disallowed_methods`(clippy.toml 配置型,未配置不触发)列禁 `std::thread::sleep`)。
188
+
189
+ | 栈 | 条件逻辑 in test | sleep in test | 无断言测试 |
190
+ |---|---|---|---|
191
+ | JS/TS unit — Jest(web/RN/Taro 单测) | `jest/no-conditional-in-test`;辅 `jest/no-conditional-expect` | 无专用规则(实扫 github.com/jest-community/eslint-plugin-jest README rules 表)→ agent-review(可选 repo 级 core ESLint `no-restricted-syntax`——eslint.org/docs/latest/rules——禁测试内裸 `setTimeout` 等待) | `jest/expect-expect` |
192
+ | JS/TS unit — Vitest(`@vitest/eslint-plugin`) | `vitest/no-conditional-in-test` | 无专用规则(实扫 github.com/vitest-dev/eslint-plugin-vitest README rules 表)→ agent-review(可选 core ESLint `no-restricted-syntax`——eslint.org/docs/latest/rules——禁测试内裸 `setTimeout` 等待) | `vitest/expect-expect` |
193
+ | web E2E — `eslint-plugin-playwright` | `playwright/no-conditional-in-test`(recommended) | `playwright/no-wait-for-timeout`(recommended) | `playwright/expect-expect`(recommended) |
194
+ | Python — pytest | 无生态规则(实扫 docs.astral.sh/ruff/rules 的 PT 集:PT009/PT015/PT017/PT018 均为断言写法类,无「条件逻辑 in test」规则)→ agent-review | Ruff `TID251` banned-api 列禁 `time.sleep`(`[tool.ruff.lint.flake8-tidy-imports.banned-api]`;确需处 `# noqa: TID251`) | 无生态规则(实扫 docs.astral.sh/ruff/rules 的 PT 集:无「测试无断言」规则)→ agent-review |
195
+ | Go | 无生态规则(`golangci-lint help linters` v2.12.2 本机实扫:相邻仅 `forbidigo`/`testifylint`/`thelper`,均不判此类)→ agent-review | `forbidigo` pattern `^time\.Sleep$`(其 `-tests` 默认含测试文件;经 golangci-lint file-based 配置圈定/豁免非测试路径) | 无生态规则(`golangci-lint help linters` v2.12.2 本机实扫)→ agent-review |
196
+ | Android/Kotlin | 无生态规则(实扫 detekt.dev/docs/rules/ 下 comments·complexity·coroutines·empty-blocks·exceptions·libraries·naming·performance·potential-bugs·ruleauthors·style 11 页,最近仅 `CoroutineLaunchedInTestWithoutRunTest`(检测 @Test 内 runTest 外启协程),不判此类;formatting 页 404 未扫——ktlint 格式包装,无测试语义规则)→ agent-review | detekt `coroutines/SleepInsteadOfDelay`(默认启用、需 type resolution;**仅报 suspend 函数/协程块内的 `Thread.sleep`**——非 suspend 测试代码不触发 → agent-review) | 无生态规则(实扫 detekt.dev/docs/rules/ 下 comments·complexity·coroutines·empty-blocks·exceptions·libraries·naming·performance·potential-bugs·ruleauthors·style 11 页;formatting 页 404 未扫——ktlint 格式包装)→ agent-review |
197
+ | iOS/Swift 与 Flutter/Dart | 无生态规则(实扫 realm.github.io/SwiftLint/rule-directory.html 与 dart.dev/tools/linter-rules)→ agent-review | 无生态规则(实扫 realm.github.io/SwiftLint/rule-directory.html 与 dart.dev/tools/linter-rules)→ agent-review | 无生态规则(实扫 realm.github.io/SwiftLint/rule-directory.html 与 dart.dev/tools/linter-rules;SwiftLint `empty_xctest_method` 只判空测试方法、不判「有动作无断言」,不算数)→ agent-review |
198
+
199
+ jest/vitest 各规则的 recommended 覆盖面随插件版本变化——消费仓 config 里**显式启用**上列规则,以所用版本 README 为准。空格子的检索边界(诚实):各空格子均**实扫具名官方规则清单**(清单 URL 或本机命令已写进对应格;2026-08 核验;深度=规则存在+语义匹配,未逐规则跑样例);「无生态规则」= 该清单内未见,非全生态穷尽——新规则出现时按 A 表同款方式登记,不自写。权威源(核验 2026-08,以所用版本为准):github.com/jest-community/eslint-plugin-jest(README rules 表)、github.com/vitest-dev/eslint-plugin-vitest(`@vitest/eslint-plugin` README)、github.com/mskelton/eslint-plugin-playwright(README rules 表 + `src/plugin.ts` recommended 配置)、docs.astral.sh/ruff/rules/banned-api 与 /settings(`[lint.flake8-tidy-imports.banned-api]`)、github.com/ashanbrown/forbidigo(README;`-tests` 默认 true)、detekt.dev/docs/rules/coroutines(SleepInsteadOfDelay 默认启用 since v1.21.0、需 type resolution)、eslint.org/docs/latest/rules(core `no-restricted-syntax`)、rust-lang.github.io/rust-clippy(master lint 索引;`disallowed_methods`)。
200
+
185
201
  ### 4.2 起步 sequencing
186
202
  新项目从最便宜的开始上:
187
203
  1. **Linter rules**(语法 / 命名 / 简单依赖)— 零启动成本,本地 IDE 即时反馈
@@ -130,7 +130,7 @@ When extracting or reviewing an existing project's scenario coverage:
130
130
 
131
131
  ## Source Notes
132
132
 
133
- - Fowler-style test pyramid guidance supports many fast low-level tests, some service/integration tests, and few high-level E2E tests: https://martinfowler.com/articles/practical-test-pyramid.html
133
+ - The test pyramid (Mike Cohn, *Succeeding with Agile*) supports many fast low-level tests, some service/integration tests, and few high-level E2E tests; practical elaboration by Ham Vocke: https://martinfowler.com/articles/practical-test-pyramid.html
134
134
  - Playwright guidance supports user-visible locators and assertions against rendered outcomes rather than brittle implementation details: https://playwright.dev/docs/best-practices
135
135
  - Testing Library guidance supports tests that resemble how users interact with the UI: https://testing-library.com/docs/guiding-principles/
136
136
  - Pytest guidance supports explicit test discovery, package layout, markers, and reusable fixtures for deterministic tests: https://docs.pytest.org/en/stable/explanation/goodpractices.html
@@ -13,7 +13,7 @@
13
13
  - **Daniel Terhorst-North** — "Introducing BDD" (dannorth.net, 2006) — Given-When-Then 来源
14
14
  - **Nat Pryce** — "Test Data Builders: an alternative to the Object Mother pattern" (natpryce.com, 2007) — Test Data Builder
15
15
  - **Go 官方 wiki** — Table Driven Tests (go.dev/wiki/TableDrivenTests) — Go 社区主流模式
16
- - **Brian Marick** — "How to misuse code coverage" (testing.com, 1999) — coverage 不是目标
16
+ - **Brian Marick** — "How to misuse code coverage" (exampler.com/testing-com/,版权页 1997;部分索引作 1999) — coverage 不是目标
17
17
 
18
18
  ---
19
19
 
@@ -84,11 +84,11 @@ def test_export_request_returns_signed_url_when_user_has_quota():
84
84
  |---|---|---|
85
85
  | **Fragile Test**(Meszaros) | 实现细节变动就挂 | 重构成本高 |
86
86
  | **Change-Detector Test**(Fragile 的高频子类;名为团队启发) | 断言"预期会变的数据"的快照(目录/注册表项、版本号字面量、枚举计数、硬编码清单)而非行为 | 例行数据更新即挂 CI、零行为覆盖、浪费工时"修测试" |
87
- | **Erratic Test** 含 Mystery Guest(Meszaros) | 隐含外部依赖 / 顺序敏感 / 时间敏感 | flaky |
88
- | **Assertion Roulette / Eager Test**(Meszaros) | 一个测试塞多场景或多个独立断言 | 失败定位难、报错无意义 |
87
+ | **Erratic Test**(Meszaros;原书 causes 含 Interacting Tests / Unrepeatable Test / Resource Optimism / Test Run Wars) | 共享 fixture 交互 / 顺序敏感 / 时间敏感 / 乐观依赖外部资源 | flaky |
88
+ | **Assertion Roulette**(behavior smell)+ 常见成因 **Eager Test**(原书归 Obscure Test 的 cause) | 一个测试塞多场景或多个独立断言 | 失败定位难、报错无意义 |
89
89
  | **Slow Test**(Meszaros 项;阈值是**团队启发**:单 unit 测 > 100ms / 整 unit 套 > 30s 触警) | 反馈慢 → 开发者跳过 | 见下方"用"段中的层级豁免 |
90
- | **Conditional Test Logic**(Meszaros) | 测试体内有 if/else/loop | 实际测的是什么不明 |
91
- | **Mystery Guest**(Meszaros 子项) | 依赖外部文件/数据但未声明 | 不可复现 |
90
+ | **Conditional Test Logic**(Meszaros) | 测试体内有 if/else/loop(表驱动 case 迭代除外,见 §8) | 实际测的是什么不明 |
91
+ | **Mystery Guest**(Meszaros,Obscure Test 的 cause) | 依赖外部文件/数据但未声明 | 不可读、不可复现;资源被改时连带 flaky(Resource Optimism) |
92
92
 
93
93
  **用**:code review / 重构 / 排查 flaky test 时按这清单查。Slow Test 阈值只对**默认快速单测目标**(unit 层)严卡;integration / E2E / host-smoke / benchmark 测必有独立的更宽 budget,按 marker 分离(如 `@pytest.mark.integration` / Go `-short` 区分)或按 runner 配置级 include 清单隔成独立套(perf/stress 类车道优先用清单——清单可审计,运行时 skip 标记会静默腐烂,见 `ci-fixtures-and-flake-control.md` Coverage As Signal),不混入 unit 套时间预算。
94
94
 
@@ -98,6 +98,7 @@ def test_export_request_returns_signed_url_when_user_has_quota():
98
98
  - 测试矩阵 / CI 报告里发现 flaky → 先按 Sensitive Test 排查(时间/顺序/外部依赖)
99
99
  - 一次 review 抓到 ≥ 3 处同类异味 → 列入技术债跟进,不只口头指出
100
100
  - 自动检查工具:pytest `-x --tb=short` + flake-detector / pytest-randomly;Jest `--bail`;Go `-race -count=10`
101
+ - 可机判子集(条件逻辑 / sleep / 无断言)必须走每栈 lint 执行器登记面处置:`fitness-functions.md` §4.1.4(生态规则优先;无规则格按本节清单人审,不得自写半成品检查器)
101
102
 
102
103
  **例**:
103
104
  ```
@@ -375,6 +376,16 @@ func TestExportTokenTTL(t *testing.T) {
375
376
  | 把测试搬到另一个语言/stack | §9 移植对抗输入本身 |
376
377
  | 行为修复后旧断言变红 | §10 行为纠正时的断言清扫 |
377
378
 
379
+ ## 写完测试走查(closeout checklist,逐行走完再提交)
380
+
381
+ 写完一批测试代码后逐行走一遍;任一行答"否"就回对应 § 改,不靠印象:
382
+
383
+ 1. 每个测试断言的是**结果**(返回值/状态/事件),不是"调用没抛错"?(§1/§5)
384
+ 2. 测试名读出来是**行为与预期**,不是方法名或编号?(§2)
385
+ 3. 测试体内没有决定断言是否执行或变化的条件分支?(§3 Conditional Test Logic;表驱动/参数化的 case 迭代循环不算——那是 §8 的正面形态)
386
+ 4. 重复出现的复杂对象构造已收进按场景命名的工厂/builder?(§4)
387
+ 5. 同一逻辑的多组输入已参数化/表驱动,而不是复制粘贴多个测试函数?(§8)
388
+
378
389
  ---
379
390
 
380
391
  ## 故意不重复(在别处已有)
@@ -56,7 +56,7 @@ owner · 硬规则 · 完成标准/DoD · 里程碑 · 数值阈值 · the real
56
56
  - Collaborative docs that support rich structure (Feishu/Lark Docx/wiki, Confluence-like pages) should use the platform's rich-text structure when creating or materially rewriting a document: headings, tables, bullets, and named hyperlinks should be real document nodes, not plain Markdown pasted as body text. Use Markdown only when the target surface is Markdown-native or the user explicitly asks for it.
57
57
  - In Feishu/Lark standards families, document references must be named hyperlinks, not quoted plain titles such as `《测试规范》`. If a sibling doc is referenced more than once, verify the title once and reuse the same named link across the family.
58
58
  - **断言写到证据等级为止。** 交付文档里的结论按主张状态分「来源明确陈述 / 有证据支持的推论 / 作者判断」三态,不得混写成同一种口气;「来源明确陈述」是归因不是真实性——写成「来源 X 声称」,不得因有出处就用事实定论口气;作者判断句显式带「判断 / 预计 / 我认为」类标记,证据只到推论级就用分级句式写(如「机制可证、参数不可证」)。三态管**解释性/推断性主张**;直接观测豁免只限原始计数/测量值(如「本次查询返回 N 行」按本来面目写,不强套归因句式)——工具生成的分类/评分/裁决仍须标状态并写明工具权威边界。**状态沿用实质 owner 或证据表已定的等级**:润色时不得自行升降格;owner 未定状态的断言不改文、按既有通道标 discrepancy 交还 owner——已生效的决定、门槛、验收标准不因缺状态标签而被标「待确认」降级(调研类交付物的状态产出由 `multi-perspective-research` 合成简报持有,本条管所有交付文档的表达面)。
59
- - **外部基线 / 标准值入文档 = 独立标注 + 命名来源 + 内部门(若有)仍权威。** 引用外部 benchmark、行业阈值、标准默认值(评测目标、性能预算、参考 SLO 等)时,放成独立的列 / 行 / 标注并配命名来源超链,别和本系统自己的验收门 / 阈值混写成同一个数。**当本系统有自己的验收门时**显式声明本系统门为准、外部值只作对标参考(反模式:把外部基线直接当验收标准,读者误以为外部数就是上线门);**若文档本身即标准 / 评测报告 / 无内部门**,则标清来源 / 范围 / 权威,别杜撰一个内部门。**评自己的稿是这条的另一半**:对自己产出的文档评可实测呈现属性(加粗密度、句长、结构层级)前,先建同体裁实测基准——长文或系列交付物在**初稿前**建(写完被纠正后再补测,是实测过的返工形态)——按**预先声明的抽样框与纳排规则**(在实测待评稿自身指标**之前**冻结,防止看完自己的数再挑参照系)取同体裁公开样本(记录样本量、口径与局限;不得挑对自己有利的样本充数,"若干份"本身不构成充分门槛),中英文样本分开统计,把待评稿放进分布里定位;找不到可靠公开样本或体裁不可比时如实记「未对标 + 原因」;流行排版阈值逐条核到一手出处再用,核不到不用。**分布定位的合法输出是描述**("高于/低于所选样本分布"),**不是裁决**:"合适"要再结合读者任务与可用性判断;"优于同类"不得由密度类粗指标推出;无基准时该属性只能报「未对标」——自己的审美不是分布。密度居中更推不出「稿子写得好」:整体质量仍按文档目的、读者任务、事实核验与本 rubric 分轴判断,呈现分布不背书内容正确性。
59
+ - **外部基线 / 标准值入文档 = 独立标注 + 命名来源 + 内部门(若有)仍权威。** 引用外部 benchmark、行业阈值、标准默认值(评测目标、性能预算、参考 SLO 等)时,放成独立的列 / 行 / 标注并配命名来源超链,别和本系统自己的验收门 / 阈值混写成同一个数。**当本系统有自己的验收门时**显式声明本系统门为准、外部值只作对标参考(反模式:把外部基线直接当验收标准,读者误以为外部数就是上线门);**若文档本身即标准 / 评测报告 / 无内部门**,则标清来源 / 范围 / 权威,别杜撰一个内部门。**评自己的稿是这条的另一半**:**评自己产出的文档的可实测呈现属性(加粗密度、句长、结构层级)时,或为可发现性词汇(包 / 仓库的 `description`、`keywords`、tags / topics、搜索面标题词、产品定位名词)选词时**,先按事先冻结的抽样框取同体裁公开样本建实测基准,再下判断 / 选词——**这两类只是已知实例:其他属性只要问的是「相对同类如何」且有同体裁公开样本,同样适用,不得因没被点名就放过;但内部验收门、硬限额与对错 / 安全的直接核验照门判、不记「未对标」;**门里若含「同类怎么做」的前提,它仍欠本条****;没测就在用它**之前**记「未对标 + 原因」,**成本 / 限流不是豁免,只是把结论降级**;**待发布 / 未公开的名字与定位词不拿去外部检索**(查询即送出,按 `product-rd-workflow` artifact-egress 门处理)。**分布定位只是描述、不是裁决**,自己的审美不是分布。**触发本条即先读 `references/self-benchmark-baseline.md` 并照它执行**——抽样框冻结与纳排、不得挑样、中英分开、阈值核源、词频读法、frontmatter 归属都在那。
60
60
  - No inline `|` / pipe-delimited lists (RACI / 分工) — break into bullets or a table.
61
61
  - Short sentences, one point per line, enumerations as tables.
62
62
  - **表达形式匹配内容**:分支关系 / 状态迁移复杂到文字难扫时优先**图**(mermaid 等);字段对比、分桶属性、owner/gate/证据矩阵优先**表**;线性步骤用编号列表;一两点判断一句话或 bullet。别为单个判断加**装饰性**多桶图,但桶间有不同 owner / 阈值 / 例外 / 后果时**必须结构化**(该结构别压成一句)。**目标环境不稳定渲染图时**,文字版流程为准、图只作辅助。**callout / 图内文字 = 概览形态,只承一个要点**:callout 塞成多点密块("一坨")就拆开或降到正文 / 表。**图种由主张形态定**(有事件触发→状态机 / 消息序→时序 / 随完成流转→流程);**画了必须有标题与图例、连线单向且标签具体**;**量级对比别全压进表**。余下见 `references/figure-and-table-craft.md`。
@@ -99,7 +99,7 @@ For a 域卡/执行卡 (a card that sets WHAT a domain must achieve + who owns i
99
99
  - Required flow: STOP line edits → confirm the corrected core with the user (one short question, don't guess again — this failure class recurs precisely from re-guessing) → re-derive 负责人/红线/里程碑/验收/依赖兜底 from the corrected core as a **draft for review** (not a blind blast-write) → publish on approval.
100
100
  - Repeat signal: repeated user "这是什么/什么玩意儿" on the same card = the premise is wrong; escalate to re-derive, do not keep tightening.
101
101
 
102
- ## 句子层(吸收 Strunk《风格的要素》,仅取适合中文交付文档的;英文语法/标点规则不适用,已剔除)
102
+ ## 句子层(吸收 Strunk《风格的要素》与 Google Technical Writing 课程,仅取适合中文交付文档的;英文语法/标点规则不适用,已剔除)
103
103
 
104
104
  > 英文文档:用完整 Strunk 规则(含被本节剔除的语法/标点条),本节只是中文交付子集。
105
105
 
@@ -107,6 +107,7 @@ For a 域卡/执行卡 (a card that sets WHAT a domain must achieve + who owns i
107
107
  - 肯定式陈述:直接说"必须 X",不绕"不是不 X / 并非没有"。
108
108
  - 具体优于空泛:用 数字/对象/阈值,删"全面提升/大力推进/高度重视/至关重要"这类空话(呼应 KEEP 的数值阈值)。
109
109
  - 删冗词的定式:把"是否…的问题/在…的情况下/做出…的决定/关于…方面"压成 "是否…/…时/决定…/…"。
110
+ - 歧义代词消歧:它 / 它们 / 其 必须先有名词、后有代词,指代名词离得远或中间插入另一名词就直接重复名词;指示词 这 / 那 / 该 / 此 要么换成名词,要么后接名词(「这会拖慢构建」→「这次全量扫描会拖慢构建」)。
110
111
  - 相关词靠拢、少套从句:修饰语紧挨被修饰对象,长定语拆短句,避免一句里多层"的…的…"。
111
112
  - 强调位放句首或句尾:最该被记住的词别埋在句子中间。
112
113
  - 结论前置(BLUF / 倒金字塔,业内通行做法):bullet、段落开头先放**结论 / 动作 / 信息词**,例子和非结论性背景后置——读者扫读,埋在后面的结论会被跳过。**但会改变结论的条件不算"例子"**:凡是改变结论、适用范围、红线 / NO-GO / 阈值 / 例外 / 责任边界的条件,必须与结论同句同屏,不得降级到后面或塞进括号弱化(如「满足 A、B、C 时,做 X」,不要用括号把条件视觉降级)。作用范围:bullet/段落级,区别于上一条词级"强调位";只重排各 bullet/段落内部,不得为前置结论删除或降级 KEEP 项,执行卡仍按固定骨架排序。
@@ -170,13 +171,14 @@ Never destroy collaborative comments. Before editing a collaborative doc, fetch
170
171
 
171
172
  - **终版修订不 append,每轮修订过零损核对。** 适用域:**可原位维护的 reader-facing 交付物**(本体即 changelog / 审计记录 / 发布说明 / 正式勘误,或已签发、append-only、必须保留原版的文档,走版本化或附录,不受此禁令)。对适用域内已定稿交付物的后续修订:就地整合进原结构(改正文、改表格、必要时重排节),不得在文末追加「修订 / 更新 / 补充说明」节——逐轮追加会把终版退化成过程日志。**协作文档上 comment-safe 优先于不 append**:评论锚点使安全的原位重排不可行时,允许版本化替代件或明确的勘误/附录(旧版保留并指向新版),不得为满足形式禁令破坏评论。每轮修订收尾跑零损核对:**对照的是稳定标识 + 关键值/单位/结论限定的清单,且核对应关系(哪个值/限定挂在哪个实体/系列/行上——值全在但对应关系接错同样是损),计数只是快速 sanity check**——计数不变可能是错误替换(假绿),计数变化可能是正当的合并/撤回(假红),本轮有意的增删并入预期变更清单后再判;**清单随工作版或访问受控的工作区持久化(工作记录不进 reader-facing 发布目录)并绑定修订前版本**——修订跨会话时从该基线重建 diff,不得从当前输出反推基线(丢了的实体会被当成"本来就没有");**派生物同查**——由本文重生成的图表 / 导出件 / 附件按同一清单比对修订前后,不凭观感扫一眼——重生成是最容易静默丢数据的一步。
172
173
  - **读者版与工作版分离:过程痕迹换归宿,不是删除。** 同一交付物既要服务外部读者、又要承载内部工作记录(全量附录、覆盖工作表、评审史、修订史)时,读者版围绕「怎么读 / 只记三件事 / 怎么用」重构,覆盖工作表、修订史、评审记录只进工作版。**拆分本身是结构决定,不归本技能自裁**:spec / standards / guideline 族按上面 When-to-use 的规则先报拆分候选、owner 确定 doc set 后执行;单体交付物的拆分也须用户或内容 owner 明确同意,拆时登记:**工作版为承重内容的唯一可编辑真值源,读者版单向派生**(承重字段——数字、限定、结论——不得在读者版单独改,发现差异回工作版改再派生;读者版的表达层调整也须回写工作版或存为可重放的派生调整,否则下次重派生会静默覆盖)、工作版的访问边界(评审史等内部内容不随读者版外发)、同步绑定的工作版版本;**读者版评论反向回流**——每次从工作版重生成读者版前,先处置读者版**全部**未解决评论:涉承重内容的登记回工作版处置完再派生,其余按 comment-safe 红线保留锚点,防止两版长期分叉或评论静默丢失。上面 regen 条删的过程自述在有工作版时不是丢弃——移过去。(调研类交付物侧的同款纪律由 `multi-perspective-research` 的"过程自省不进交付物"条持有。)
173
- - **交付面:改完 ≠ 交出去(投放 / 退役 / 导出保真)。** 上两条管的是文内不丢与正副本权威;交付物还有一组**文外的面**——远端副本(飞书 / wiki 页)、附件(pdf / 大图)、导出件(png / jpg),以及历史上生成过的多代同名产物。逐面判定,未判定不得报「已更新 / 已同步」:**①投放要回读远端、不认本地动作**——上传 / 推送命令返回成功不等于那一份已经变(超时后半成、权限被拒、覆盖到错误的页面、缓存仍吐旧版),本地改完、远端还是旧版是最常见的静默残缺;核到本轮的可识别标志才算已投放。「不投放」只能是经授权的排除,**推不上去是 blocked 不是「不投放」**,有 blocked 面或待安全处置面即不得报已同步。**②当前版给稳定入口,旧版退役只用归档或原位标「已过期 → 指向新版」两种可逆做法,本条不授权删除**;反过来,涉凭据 / 个人信息 / 有害错误说明这类**被要求删除**的面,可逆做法不构成处置,但判定与执行都不归本技能——单标 `待安全处置` 转出给安全 / 法务 / 内容 owner,与投放类 blocked 分开列,其结案前不得报已同步。**③交互源(可折叠节点、悬浮标签、可滚动区、分页表)导成静态图前全部展开再导**,导出后对照交互源清点承载性实体。**③的 oracle 与零损核对不同**:那条比的是重生成前后(同一路径两次输出),比不出交互 → 静态这一次性的丢失。三态定义、各自的绕过路径、退役沿革与转出规则见 `references/delivery-face-closeout.md`。
174
+ - **交付面:改完 ≠ 交出去(投放 / 退役 / 导出保真)。** 上两条管的是文内不丢与正副本权威;交付物还有一组**文外的面**——远端副本、附件、导出件,以及历史上生成过的多代同名产物。逐面判定,未判定不得报「已更新 / 已同步」:**①投放与定位都要回读远端、不认本地动作**——上传 / 推送命令返回成功不等于那一份已经变;核到本轮的可识别标志才算已投放,放进多级容器的另核落点。发布面有可用的机器校验器时,回读后跑一遍、失败即返工——校验绿只是人读性的代理,交付物是写给人看的,人读 sweep 照跑。**推不上去是 blocked 不是「不投放」**,有 blocked 面或待安全处置面即不得报已同步。**②当前版给稳定入口,旧版退役只用可逆做法,本条不授权删除**;**被要求删除**的面单标 `待安全处置` 转出给安全 / 法务 / 内容 owner,与投放类 blocked 分开列,其结案前不得报已同步。**③交互源导成静态图前全部展开再导**,导出后对照交互源清点承载性实体。四态定义、定位判据、投放失败形态与绕过路径、退役的两种可逆做法、转出规则与静态导出的 oracle 见 `references/delivery-face-closeout.md`。
174
175
 
175
176
  When the user probes sentence-by-sentence ("这是废话么 / 什么意思 / 能精简么"), answer per this rubric, give the tightened version, and apply it — don't ask permission unless the comment-safe red line is triggered.
176
177
 
177
178
  ## Reference Loading
178
179
 
179
180
  - For Feishu/Lark comment preservation, range update mechanics, overwrite pitfalls, and cross-doc rename safety, read `references/comment-safe-feishu.md`.
181
+ - 「外部基线」条一触发就必读 `references/self-benchmark-baseline.md`:抽样、分布定位输出、可发现性语料与词频读法、两条边界。
180
182
  - 交付面收尾(投放回读、三态定义与绕过路径、旧版退役与「被要求删除」的转出、静态导出全展开)展开在 `references/delivery-face-closeout.md`;closeout 第 7 项与「交付面」条都指向它。
181
183
 
182
184
  ## CROSS-MODEL / CODEX CO-REVIEW CAVEAT
@@ -9,10 +9,20 @@
9
9
  本轮改动是否已推到**每一个**面。
10
10
 
11
11
  - **上传 / 推送命令返回成功 ≠ 那一份已经变**:超时后半成、权限被拒、覆盖到错误的页面、缓存仍吐旧版,都会让本地看着已发、远端还是旧的。回读**远端那一份**,核到本轮的可识别标志(新增段落 / 版本号 / 修订时间)才算已投放。
12
+ - **发布面有可用的机器校验器就跑**:对回读拿到的远端内容过一遍校验器(平台内容结构校验脚本、导出件 lint 等),失败先返工再投放,不把「链接已发出」当完成交付。**校验绿只是人读性的代理,不是替代**——交付物是写给人看的,closeout 的人读 sweep 照跑;本条不绑定单一平台,协作文档、wiki、导出件等任何承接面同此,无校验器的面不因此豁免回读与人读。
12
13
  - **「不投放」只能是经授权的排除**(如「工作版不外发」这类决定)。
13
14
  - **推不上去不是「不投放」,是 blocked**——权限被拒、远端访问不了、工具不可用,一律按 blocked 记:已试的补救、残余风险、下一个解封动作。**只要还有 blocked 面就不得报「已更新 / 已同步」**,只能报「已投放 N 面 + 待投放清单」。
14
15
  - 把 blocked 写成「不投放 + 理由」勾过去,是本条的主要绕过路径,也正是它要防的那个失败。
15
16
 
17
+ ## ①b 定位:放对地方,放前放后都要核
18
+
19
+ ①核的是「那一份变了没」;本节核的是「放没放对地方」——挂错目录 / 空间 / 父容器的文档,内容标志核得再准也是错交付。适用于任何多级容器承接面(知识库、wiki、文件夹树、文档集),不绑定单一平台。
20
+
21
+ - **放置前必须现读目标结构**:目录树 / 容器层级以本次实时读取为准,不依赖技能文本、记忆或历史快照里的结构(结构会变),也不按链接标题猜父容器(标题会骗)。
22
+ - **落点选最具体的稳定容器**:能长期容纳同类内容的最深目录 / 明确的专题容器才是合法父节点。**标题相似本身不构成父子依据**——不得只因一篇既有文档标题相近就把新文档挂在它下面;但在页面即容器的承接面上,现读结构确认该节点确为承载同类的稳定容器时,它可以作父节点。
23
+ - **新建 / 移动后回读定位**:回读该节点的父容器 / 空间 / 完整路径,核到与预期一致才算放对——这里的「预期」也分级:交付任务 / 需求记录**载明落点**的,以该记录为预期(独立于投放者,回读能证「放对」);未载明的,预期只是投放者按上一条判据选定的落点,回读证明的是**执行没走样**(落在了自己决定的位置),不构成「选点正确」的自证——选点正确性由上一条判据与下述边界 / owner 核验约束,交付信息里的完整路径正是把选点暴露给读者与 owner 复核的通道(错挂由此被发现的,按 blocked 修复重投)——且**未载明落点的面,闭环申报要如实分级**:其「已投放」标注须附完整路径并注明**选点自评、未经独立复核**,不得把执行核验报成「放对位置已核实」,该注记随交付信息给到读者与 owner,使复核通道成为申报的一部分而不是可选后续;交付信息里给完整路径(不是只给链接)——但路径披露以**该读者对结构的既有可见范围**为限:层级名称本身受访问限制、读者无权见的,受限段不写进面向该读者的交付信息——但**完整路径仍须保留在核验记录中,并交付给对结构有权的 owner / 读者**(复核方拿到的是全路径;省略只发生在面向无权读者的那份交付信息里,不得因此让任何有权复核方也拿不到全路径),路径披露不得成为新的结构泄露面——定位错误是内容标志核不出来的那一类失败。
24
+ - **落点决定可见性,位置对了也可能泄露**:容器会让内容继承其访问边界(移动进更开放的空间 = 静默扩散,移进更封闭的 = 该看的人看不到)。放置前记下预期受众 / 访问边界**与预期 owner(或其所属的授权主体——该归属 / 授权关系本身也须由独立记录或权威侧记录载明,投放者不得自行把某主体认定为预期 owner 的授权主体,认定不了即按 owner 非预期 / 无法核验分流)**——预期受众与预期 owner 都不是投放时自拟的:以交付任务 / 需求 / 内容密级等**既有记录**为源,且该记录必须**独立于本次落点选择、也独立于投放者**——由任务 / 需求 / 密级各自的 owner 或流程产生 / 确认的记录才算数,投放者自拟或为本次投放临时新写的记录不构成基线(等同无既有依据,走下述路径)(owner 同此:任务 / 需求 / 密级记录载明的那一个;**目标容器自身的 owner / 边界记录不算预期来源**——容器是投放者挑的,拿它当预期会让放后比对恒等成立;无独立记录载明 owner 的按下述「无既有依据」路径走);**没有既有依据的不自拟基线**——边界未定即转对应权威,**由裁决记录一并载明该面的访问边界与预期 owner**——边界那一半归边界权威,owner 那一半须由**持内容归属治理权的一方**作出或确认——内容归属治理权指对「该内容归谁管」有权决定的一方(任务 / 需求 / 密级体系一侧);**目标容器的现任控制方不因控制容器而得此权**,它自署记录把自己指为预期 owner 属自证、不构成基线(边界权威兼持治理权的可一并裁;无治理权的边界权威单方指定的 owner 不构成基线,同缺 owner 论。缺任一半的裁决记录都不构成基线;该面裁决前按 blocked 记),或只放入**读回其生效边界确认仅投放者本人可及**的私有 / 工作容器(「私有」不凭名字或印象认定——工作容器常被同事可及或继承更宽权限,读不到边界、边界含他人或无法核验的,此路不适用,回到转权威那条;确认后无新增暴露,且此暂存面的预期受众与预期 owner 均为投放者本人——放后回读 owner 非本人即失配,按后述分流转待安全处置)——但此路是**暂存,不是交付**:不构成对外交付,也就没有完成原交付义务,原本要交付的那个面仍按 blocked 记(下一步 = 取得边界权威裁决的基线后重投),**不得以「已放入私有容器」抵充该面的已投放**;且此路**不授权新建任何副本**——它只适用于投放者按内容自身的持有规则**本就可持有**的那份工作副本(如自己起草的稿件),内容的持有 / 复制另有约束(密级、专门存放要求等)的,此路不适用、仅余转权威一条——两条路都不产生投放者自定的对外基线,防「先把预期写宽(或自封 owner)再宣称匹配」;并**先读目标容器当前生效的访问边界与控制方(owner)**——比预期受众宽、容器 owner 落在非预期主体(放入即把控制与转授权能力交到该主体手上,放后才发现已是失控)、或**读不到 / 无法核验**任一项以致排除不了这些情形(与放置后同名分流同则),都不得放入;**确知比预期受众窄**(该看的人看不到)的同样不径直放入——那是明知的交付缺陷,先修边界或换容器(普通投放受阻,按 blocked 记:待修复后投放),不做「先放进去再修」;比预期宽 / 无法核验 / owner 非预期的:换合规容器,或停下把「要不要按更宽边界投放」转出裁决——受众扩大是访问边界决定,归**该边界的权威**(安全 / 内容 owner,与放置后发现过宽时的收敛权威同一拨;文档的预期 owner 只有同时就是该边界的权威才有权裁,是否有权拿不准也一并转出问。**转出的问题按命中类型对应权威**:受众扩大问题归边界权威;owner 非预期 / 无法核验的面,转出的问题是「该容器的 owner 归属 / 该内容可否交由该主体控制」,归持内容归属治理权的一方裁决(定义与排除同上)——边界权威仅当同时持有 owner 治理权才可一并裁;两类情形都命中的,两个问题各自结案才可放行),该面在裁决前按 blocked 记(下一步 = 对应权威裁决)——**此 blocked 只适用于尚未放入的面**:没放进去就没有暴露、没有安全事件,是普通投放受阻;一旦内容已放入 / 已发布后才发现比预期宽,即为已暴露,只能按后述 `待安全处置`,**不得因裁决同归边界权威就把已暴露面记回 blocked**(两态互斥,动作与结案条件不同)。**权威身份本身也须独立锚定**:谁是该边界的权威、谁持内容归属治理权,以承接面 / 组织**既有的权威名册或治理记录**(空间 / 平台的管理配置、任务体系的治理记录等)为准——投放者不得自行指认权威人选,找一个配合的主体当「权威」与自拟基线同形态;名册上核不到的按**权威身份无法核验**处理:经承接面 / 组织既有的升级通道问明归属,问明前该面保持 blocked。裁决属该权威,投放者不得代收、转述或自行记录授权——在这里自行判定就是又一处可自证的结论,与被取消的删除三条件同形态(此路径曾允许投放者持授权记录放行,因记录可由投放者自记而取消);只有能**从该权威侧回读到**的裁决记录才算数,**预期受众 / 边界与预期 owner 记录整体随该裁决更新**(裁决载明的两半即新的比对基线——裁定过的 owner 不再被放后回读判成失配),后续回读以更新后的预期为准,不把已裁决的范围再判成暴露。内容一放进更宽的容器即已实际暴露,事后回读只能发现、不能撤销;新建 / 移动后仍要连同落点一起回读**生效的受众 / 权限与 owner**(继承与配置可能在放置动作中变化,放前核过不豁免放后回读),并分流——**比预期更宽(内容已实际暴露给非预期读者)、无法核验以致排除不了更宽的、owner 落到非预期主体上的、或 owner 读不到 / 无法核验以致排除不了非预期主体的(owner 自带控制与转授权能力;该主体是否可留任由收敛结案的 owner 判定,投放者不得自证豁免——沿革:此处曾留「经授权且可证不扩出边界」的例外,因可自证而取消,与删除三条件同形态),按 `待安全处置` 处理**(与 closeout 的「拿不准按命中」同则),转出收敛与结案——**收敛权威同前述对型**:暴露 / 边界类归安全 / 内容 owner(边界权威),owner 失配 / 无法核验类归持内容归属治理权的一方(定义与排除同 ①b——目标容器现任控制方不因控制容器而得此权),结案者须实际持有对应治理权,不并入普通待投放;**确知比预期更窄且 owner 与其余安全核验项均符合预期**(该看的人看不到——可修复的交付缺陷)、或边界与 owner 均符合预期只是其他核验项失败(如路径不符)的,按 blocked(修复后重投)——**分流安全优先**:同一面同时命中任何待安全处置类情形(如边界更窄但 owner 非预期 / 无法核验)的,待安全处置吸收,不得以 blocked 绕开转出。各态都不得报已同步。本节只核不改:结构移动与权限变更各自仍需其自身的授权,定位核验不构成任何一种。
25
+
16
26
  ## ② 当前版可辨识 + 旧版退役
17
27
 
18
28
  多代并存时读者要能不问作者就判断「该看哪一份」。
@@ -49,12 +59,12 @@
49
59
 
50
60
  1. 先列出本交付物的**全部**面——远端副本 / 各附件 / 各导出件 / 历史多代产物。列不出面的清单等于没跑。
51
61
  2. 再逐面标**四态之一——互斥且完备,不叠加**:
52
- - **已投放**——带回读到的标志(新增段落 / 版本号 / 修订时间);只写「已上传 / 命令成功」不算。
53
- - **授权不投放**——+ 理由。
54
- - **blocked**——+ 已试补救 + 下一步(投放侧受阻:权限、网络、工具)。
55
- - **待安全处置**——该面命中删除要求(触发见第 4 条)。它**替代**前三态而不是叠加:命中的面不再标已投放 / 授权不投放 / blocked,单独列,不并进 blocked 或待投放汇总。
62
+ - **已投放**——带回读到的标志(新增段落 / 版本号 / 修订时间);只写「已上传 / 命令成功」不算。**该面本轮涉及新建 / 移动 / 落点变化的,还须 ①b 的定位回读与边界 / owner 回读全部跑完且结果落在「符合预期」**——没跑这些核验的面不得标已投放(跳过核验不产生任何分流触发,正是本条要堵的绕过路径)。
63
+ - **授权不投放**——+ 理由**与授权来源**(谁授权、依据哪条可回读的记录或决定——授权同其他裁决一样以能从授权方侧回读到的记录为准,投放者自写理由不构成授权;没有可回读授权的面不是「授权不投放」,按其实际状态标 blocked 或走对应分流;**授权主体是否有权作此排除,同按 ①b 的权威身份锚定规则核验**——既有权威名册 / 治理记录核到其对该内容交付有排除决定权才算,核不到即按无可回读授权论,配合出具记录的无权主体不构成授权方)。
64
+ - **blocked**——+ 已试补救 + 下一步(投放或定位侧受阻 / 待修复:权限、网络、工具,或 ①b 核验发现落点、路径、过窄边界等待修正后重投)。
65
+ - **待安全处置**——该面命中删除要求,**或定位核验发现生效可见范围比预期更宽、无法排除更宽、owner 非预期或无法核验以致排除不了非预期(见 ①b)**(触发见第 4 条)。它**替代**前三态而不是叠加:命中的面不再标已投放 / 授权不投放 / blocked,单独列,不并进 blocked 或待投放汇总。
56
66
  3. 多代并存时另标:当前版入口、旧版退役方式(只在归档 / 原位标过期两者中选)。
57
- 4. `待安全处置` 的触发是**客观命中或有权 owner 的决定,不是自由判断**:该面上发现凭据 / 密钥、受删除请求约束的个人信息、或已判定有害的错误操作说明;或内容 / 安全 / 法务 owner 已作出删除决定。命中即按上面「当删除是被要求的」转出——判定范围与执行都不在本技能。**拿不准是否命中时按命中处理并问 owner**:误转出的代价是多问一句,漏转出的代价是泄露内容留在可达面上。
67
+ 4. `待安全处置` 的触发是**客观命中或有权 owner 的决定,不是自由判断**:该面上发现凭据 / 密钥、受删除请求约束的个人信息、或已判定有害的错误操作说明;或内容 / 安全 / 法务 owner 已作出删除决定;**或 ①b 的定位核验确认生效可见范围比预期更宽(已实际暴露)、无法核验以致排除不了更宽、owner 落到非预期主体、或 owner 无法核验以致排除不了非预期——这一触发走的是收敛路径(owner 决定收窄权限 / 移回 / 通知等),与删除清理路径不同,但同样由**对应权威**结案(暴露 / 边界类归安全 / 内容 owner;owner 失配 / 无法核验类的结案者须实际持有内容归属治理权(非仅目标容器的控制权))**。命中即按上面「当删除是被要求的」转出(暴露类按收敛处置)——判定范围与执行都不在本技能。**拿不准是否命中时按命中处理并问 owner**:误转出的代价是多问一句,漏转出的代价是泄露内容留在可达面上。
58
68
  5. 有交互源导出的:另标已全展开再导并对照清点。
59
69
 
60
- 有 blocked 面或 `待安全处置` 面即不得报已优化 / 已同步。
70
+ 有 blocked 面或 `待安全处置` 面即不得报已优化 / 已同步。**含「选点自评、未经独立复核」面的,收尾报法不得出现「已同步」字样**——报「已投放 N 面,其中 M 面选点自评、待复核」(放置正确性尚未判定,任何形式的「已同步」都会把未决报成已决)。该注记**附着在已投放态上,不是第五态**(四态枚举与互斥不变):注记存在即代表一项**未结复核项**,限定式报告须随附待复核清单(各面、完整路径、责任复核方),该清单是收尾报告的一部分而不是可选备注——工作流的这一面在复核确认或纠错重投前保持未结;由**投放者本人以外**、对该结构的**内容归置有判断权**的 owner / 维护者复核确认(或纠错重投)并全部结案后,方可改报「已同步」——结构可见权限本身不构成复核资格(能看见层级 ≠ 有权判断内容该归哪),且确认与其他裁决同一证据标准:**只认能从确认方侧回读到的确认记录**,投放者在完成报告里自述「对方已确认」不算数;投放者即便自己兼任有权 owner 也不得自我确认(独立复核要件,与「不得自证豁免」同则):待复核注记与清单是该面选点风险的携带方式,不是可选措辞,提前改报已同步等于把未复核的自选落点报成已核实。
@@ -0,0 +1,37 @@
1
+ # 自评基准:同体裁实测怎么做
2
+
3
+ `SKILL.md`「外部基线 / 标准值入文档」条的「评自己的稿」那一半的展开。触发与硬判据在那条,这里只放执行细节;两处冲突以 `SKILL.md` 为准。
4
+
5
+ ## 什么时候建
6
+
7
+ - **长文或系列交付物在初稿前建。** 写完被纠正后再补测,是实测过的**返工形态**——不是没做,但成本已经付了。
8
+ - 可发现性词汇(`description`、`keywords`、tags / topics、搜索面标题词、产品定位名词)的基准同样**在落笔前**建:选词本身就是那个判断,事后补测只能推翻已发出去的词。
9
+
10
+ ## 抽样框:先冻结,再看自己的数
11
+
12
+ - 按**预先声明的抽样框与纳排规则**取样,并在**实测待评稿自身指标之前**冻结——顺序反过来,就会看完自己的数再挑对自己有利的参照系。
13
+ - 记录**样本量、口径与局限**。
14
+ - **不得挑对自己有利的样本充数**;「若干份」本身不构成充分门槛。
15
+ - **中英文样本分开统计**:体裁不可比的两批数据合并没有意义。
16
+ - 把待评稿放进分布里**定位**。
17
+ - 找不到可靠公开样本、体裁不可比、或因成本 / 限流决定不测:在用这个词、下这个判断**之前**如实记「未对标 + 原因」。采集成本不是豁免,只是把结论降级。
18
+ - **流行排版阈值逐条核到一手出处再用,核不到不用**("每屏最多 N 个加粗"这类数字大量以二手转述流传)。
19
+
20
+ ## 分布定位的合法输出
21
+
22
+ - 合法输出是**描述**("高于 / 低于所选样本分布"),**不是裁决**。
23
+ - 「合适」要再结合**读者任务与可用性**判断;「优于同类」**不得由密度类粗指标推出**。
24
+ - 无基准时该属性只能报「未对标」(无基准时的自评守则在 `SKILL.md` 那条,不在这里重述)。
25
+ - 密度居中更推不出「稿子写得好」:整体质量仍按文档目的、读者任务、事实核验与本 rubric 分轴判断,**呈现分布不背书内容正确性**。
26
+
27
+ ## 可发现性词汇:语料是什么,读法是什么
28
+
29
+ - **语料** = 同类产品在**同一检索面**上的用词分布:registry / 仓库搜索里同类结果的 `keywords`、tags、标题词频。
30
+ - **高频词未必该选**——可能过泛、不区分待评稿。
31
+ - **零频只证明所选同类样本没用这个词**。那是**发布方的用词分布**,不是读者的检索日志:要断言「读者不这么搜」,得另有检索侧证据(搜索量、查询日志、下载归因)。按 `SKILL.md`「断言写到证据等级为止」条,这两者不能混写成同一种口气。
32
+ - 「我觉得这个词更准」连样本都没有,不构成选词理由;未测过的自造词按「未对标」记。
33
+
34
+ ## 两条边界
35
+
36
+ - **待发布 / 未公开的名字与定位词不拿去外部检索。** 查询本身就是把未公开信息送出去,按 `product-rd-workflow` 的 artifact-egress 门处理;改测同类**已公开**产品的词频。
37
+ - **技能 frontmatter 的 `description` 不在本条管辖内。** 那是 agent 路由面,归 `skill-extraction-workflow` 的 description-authoring 参考(4 段结构、80% 精度门槛、真实说法),它不要求语料实测。包 / 仓库的 `description` 才是本条的可发现性词汇。
@@ -88,6 +88,7 @@ When checking a React project against team standards, split findings into determ
88
88
 
89
89
  6. Verify in a real browser.
90
90
  - Run the repo's formatter, typecheck, lint, unit/component tests, and build or affected checks.
91
+ - When writing the test code itself (structure, naming, smells, fixtures, behavior-vs-state, coverage, isolation, parameterization), pick the matching § from the decision table in `testing-strategy/references/test-code-authoring-patterns.md`; enable the per-stack lint executors for its machine-decidable smells (conditional logic / sleep / assertion-free tests) per `testing-strategy/references/fitness-functions.md` §4.1.4 (Jest/Vitest/Playwright ESLint rules).
91
92
  - **TC traceability**: link tests via the `createTcSuite(test, describe)` factory wrapper. Registers at collection time so `.skip` / `.skipIf` / `.todo` still map to Bitable status. Full overloads supported: `.concurrent` / `.each` / `(name, options, fn)` / `(name, fn, timeout)`. Helper from `test-artifact-management/references/tc_helpers/tc.ts`, installed under `test/tc.ts`. See `test-artifact-management/references/tc-marker-conventions.md`. Before adding tests, `grep -rn 'tcTest\|tcDescribe' src/ __tests__/` plus the sidecar `test/results/tc-map.jsonl` to check for existing coverage — extend rather than duplicate. When a TC is marked 废弃, grep both source and sidecar; follow deprecation cascade in `testing-strategy`. Tests without any TC link: prompt user only when the underlying code is also removed.
92
93
  - **废弃级联:业务代码是否仍在用** — TS/JS 用 `madge` 拿依赖图最准,没安装则 grep 兜底:
93
94
  1. `npx madge --dependents src/path/to/Module.tsx`(列出谁 import 了它);或 `grep -rEn "from ['\"][./]*<path>" src/`