@ccoalm/ccl-skills 0.4.0 → 0.5.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.
- package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-perspective-research/references/public-data-acquisition.md +3 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-perspective-research/references/public-disclosure-channels.md +2 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/SKILL.md +4 -4
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/dual-track-review-gate.md +8 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/external-practice-controls.md +12 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/firing-point-placement.md +8 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/source-register.md +18 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/check-ccl-skills.sh +12 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_regressions.sh +6 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_ci_checkout_ref_binding.sh +85 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_entrypoint_domain_scan_terms.sh +123 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/SKILL.md +4 -4
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/references/deliverable-doc-genre-skeletons.md +133 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/references/doc-charter-first.md +2 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/references/figure-and-table-craft.md +318 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/AGENTS.md +46 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/doc-lint.py +246 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/figure-lint.py +1092 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/mutation_probe.sh +100 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/test_figure_and_doc_lint.sh +375 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/control.md +10 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/empty-header.md +6 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/fake-header.md +13 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/fenced-noise.md +14 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/fig-dangling.md +5 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/fig-orphan-captioned.md +11 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/fig-orphan.md +9 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/fig.png +0 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/imbalance.md +41 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/no-unit.md +8 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/should-be-chart.md +11 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/tables-only-clean.md +35 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/unfilled.md +7 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/wide-table.md +5 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/bad-viewbox.svg +9 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/blackmarker.svg +9 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/control.svg +12 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/crossings.svg +12 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/cvd-confusable.svg +9 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/decorative-line.svg +10 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/edge-no-arrow.svg +11 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/edge-vague.svg +12 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/figure-contract.json +21 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/figure-is-a-list.svg +12 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/flow-mixed.svg +13 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/low-contrast.svg +12 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/malformed.svg +1 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/no-aria.svg +9 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/no-group.svg +10 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/no-legend.svg +9 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/no-title.svg +12 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/no-viewbox.svg +9 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/offcontract-shape.svg +13 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/overflow.svg +13 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/transformed.svg +9 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/ungrouped-card.svg +12 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/unlabeled-edge.svg +13 -0
- package/dist/assets/release.json +244 -14
- package/package.json +1 -1
|
@@ -478,7 +478,9 @@ totB = sum(v[1] for v in rows.values())
|
|
|
478
478
|
- **同人异名**:同一个人在不同期用了不同写法(全名/常用名/中间名有无)→ 差分会同时报"一个人离开、一个人加入"。必须先做归一,且归一规则要写出来
|
|
479
479
|
- **收录范围本身会变**:一份名单页面收谁、不收谁,发布方随时可能调整。**"从名单里消失"不等于"离开了"**——它可能只是不再被收录。差分结果只能当**线索**:每一条要用**独立于这份名单的来源**证实(同一上游数据的另一个展示面不算独立,那是循环确认),并写明该来源的截至日期。证实不了的按 `SKILL.md` 的既有处置走——进待核验清单、不得进入承重结论;**别新造一个"未确认"标签**
|
|
480
480
|
|
|
481
|
-
|
|
481
|
+
- **匹配方法自己会造出"消失"**:按 token 集合 / 精确串做归一时,标签**长出新词**(原名被包进一个更长的名字里)会漏配,差集于是报出一个其实还在的实体"消失了"。**凡由差集得出的缺席结论,落笔前先过一遍包含式复检**(把旧名当子串在新全集里查一遍)。**复检只能推翻缺席,不能确认缺席。** 命中且确认与原实体同一(新名把旧名包进去、指向同一对象)→ 判漏配,缺席结论作废;命中但确认是另一个恰好含该字串的实体,或根本没命中 → **只说明这条路没找到它**,不等于它真的不在:改名后的新名可能完全不含旧名,任何字面匹配都照不到。所以缺席结论的成立仍走上一条的既有处置——用独立于该名单的来源证实,证实不了就进待核验清单,不得因为「复检过了」而升格为结论。这与上一条方向相反:上一条是发布方不再收录,这一条是**我方的匹配口径**造的假缺席——两条都要过,只处理其一仍会出错。缺席结论同时要写明检索边界(查了哪些面、到什么截至日期),"未出现在任何一手材料"这类全称否定不写边界即为过强。
|
|
482
|
+
|
|
483
|
+
这三层不处理,一张"逐年进出表"会看起来非常有说服力而实际大半是噪声。
|
|
482
484
|
|
|
483
485
|
### 3.5 取到的是不是全量
|
|
484
486
|
|
|
@@ -95,3 +95,5 @@
|
|
|
95
95
|
## 三、走过而无产出的渠道要留下原因
|
|
96
96
|
|
|
97
97
|
写清是哪一种:**在声明的检索边界内未命中**、**取到但不足以关闭**(只有标题摘要、正文删节、字段范围不足、版本冲突、真实性无法核验)、**被挡住**(需要密钥或账号、接口下线、被反爬拦截)、还是**没走**。只写"无产出"会把后三种伪装成第一种。这四种都不是闭合判断——按 `SKILL.md` 的覆盖矩阵去裁决哪条主张还差什么。
|
|
98
|
+
|
|
99
|
+
**反过来,把某条渠道写进「下一轮最高性价比」之前,先小成本抽样验它到底产出什么。** 入口的价值由**它实际给出什么**决定,不由它的强制力、权威性或可达性决定——「有强制披露义务」「链接打得开」都不是产出证据。判据:能不能举出该渠道上**已取到的、与本轮载重主张同类**的一条内容;举不出就先抽样几份看内容,再决定要不要为它开一轮。这条防的是把同一个高权威、零产出的入口连续两轮写进建议清单,走完才发现不成立。
|
package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/SKILL.md
CHANGED
|
@@ -56,8 +56,8 @@ Use this skill to turn observed experience into durable agent skills without cop
|
|
|
56
56
|
- Think across the full delivery lifecycle before editing: product intent, design/UX, implementation, debugging, test strategy, launch acceptance, iteration feedback, team onboarding, and normal users without source access. A rule that improves only one slice while leaving another slice ambiguous is incomplete or belongs in a narrower skill.
|
|
57
57
|
- Evidence must come before new rules. Do not add a new conceptual layer, workflow gate, or strong claim first and then backfill supporting sources. If a useful rule appears before source review, keep it as a working hypothesis and do not land it until evidence confirms it, narrows it, or routes it elsewhere. For subjective design, UX, frontend/client, product, architecture, or review rules, unverified external expertise is not enough to land executable guidance.
|
|
58
58
|
- **Product-agnostic / industry-practice skills require an external authoritative source class in the evidence plan, not internal corpus alone.** An extraction sourced only from one internal corpus (an SOP, one repo, one project doc) shows what *this org* does, not whether the skill matches the public state of the art.
|
|
59
|
-
- The trigger is a *public-best-practice / state-of-the-art claim* (architecture, testing-strategy, LLM/inference, observability, release, security, design), not every rule: a rule that encodes an internal-only operating constraint or a postmortem-derived guard, stated with explicit internal scope and no state-of-art claim, does not need external grounding. For rules that do claim to represent industry practice, the charter's evidence plan MUST include authoritative external sources (standards, canonical vendor/tool docs, widely-cited literature, or ≥2 independent practitioner sources) used to confirm, refine, or contradict each such rule — or record per-rule why external grounding is not applicable. Verify any named attribution per the attribution rule; generic established terms (e.g. a well-known named problem or method confirmed by ≥2 independent sources) may be used without person-attribution. Failure shape
|
|
60
|
-
- **Implementing or depending on a named external convention/spec/format verifies it against the primary source FIRST — before building, not after.** This fires on *implementing the named thing itself* — a convention/spec/standard/file-format/protocol such as `AGENTS.md`/CODEOWNERS placement, an RFC, a wire or file format, or a tool's config contract — even with no best-practice claim (distinct from the industry-practice trigger above, which fires on a state-of-the-art *claim*). A prior agent's or a prior commit's reading of that convention is **hypothesis-grade**: re-verify against the primary source before extending it, because a fix-forward built on an inherited interpretation propagates the original error. When the convention uses a term with stack-specific meanings (e.g. "package" = a manifest-bearing directory in npm but *every directory* in Go; likewise module/project/workspace), map it to each concrete target stack before encoding scope. Failure shape
|
|
59
|
+
- The trigger is a *public-best-practice / state-of-the-art claim* (architecture, testing-strategy, LLM/inference, observability, release, security, design), not every rule: a rule that encodes an internal-only operating constraint or a postmortem-derived guard, stated with explicit internal scope and no state-of-art claim, does not need external grounding. For rules that do claim to represent industry practice, the charter's evidence plan MUST include authoritative external sources (standards, canonical vendor/tool docs, widely-cited literature, or ≥2 independent practitioner sources) used to confirm, refine, or contradict each such rule — or record per-rule why external grounding is not applicable. Verify any named attribution per the attribution rule; generic established terms (e.g. a well-known named problem or method confirmed by ≥2 independent sources) may be used without person-attribution. Failure shape 见 `references/external-practice-controls.md`。
|
|
60
|
+
- **Implementing or depending on a named external convention/spec/format verifies it against the primary source FIRST — before building, not after.** This fires on *implementing the named thing itself* — a convention/spec/standard/file-format/protocol such as `AGENTS.md`/CODEOWNERS placement, an RFC, a wire or file format, or a tool's config contract — even with no best-practice claim (distinct from the industry-practice trigger above, which fires on a state-of-the-art *claim*). A prior agent's or a prior commit's reading of that convention is **hypothesis-grade**: re-verify against the primary source before extending it, because a fix-forward built on an inherited interpretation propagates the original error. When the convention uses a term with stack-specific meanings (e.g. "package" = a manifest-bearing directory in npm but *every directory* in Go; likewise module/project/workspace), map it to each concrete target stack before encoding scope. Failure shape 见 `references/external-practice-controls.md`。
|
|
61
61
|
- Match evidence claims to evidence depth. "Full", "complete", "all", "re-read", and "source inventory" claims require named source categories, inspected artifacts, and concrete observations. Use "targeted check" or "no new source read" when that is the real coverage.
|
|
62
62
|
- **A curated digest is one source class, not the repo — its exhaustion is not the repo's exhaustion (digest-masks-corpus trap).** A high-quality maintainer digest (`AGENTS.md`/`CLAUDE.md`, README, CONTRIBUTING, architecture/design doc) that *summarizes* a larger code corpus is a **distinct source class** from the code; a strong digest masks how much went unread. Gates: **(1)** an "exhausted / complete / no-gap / fully-extracted" claim requires the **code corpus as its own register row with a terminal status** (deep-read, inventory+owner-mapping, or a downscope citing an actual user instruction — not self-declared); until then scope the claim ("digest-layer covered; code corpus `pending`") — the sweep is usually inventory+owner-mapping+novelty-spot depth and commonly low-yield, so record that outcome, don't skip the row. **(2) Enumerate the source's OWN top-level structure** before any exhausted claim — a doc's `##`/`###` sections, a repo's top-level dirs (or the next unit: TOC/pages/anchors/line-chunks for a doc; package/module/test/script/config for a repo) — and mark each `read`/`skipped`; un-enumerated structure = unsupported claim (the trap recurs even within one artifact).
|
|
63
63
|
The invariant under both shapes is **an exhaustion claim must be scoped to a unit you actually enumerated** — for the digest/corpus shape that unit is the artifact's own structure; the rule keeps its `digest-masks-corpus` name for continuity, so do not skip it just because no digest is present. **When the claim is over an ACQUISITION CHANNEL SET rather than one artifact** ("the public sources are mined out", "there is no more data"), walking a seed list of channel classes is the cheap way to catch a class you never considered — but a seed list is not a universe, so **the honest output is which classes you walked and with what search boundary, never an exhaustion claim**; the tell that this is the live shape is that each pushback surfaces a class you had not considered rather than another artifact in a known class. Closure and downgrade stay with whatever coverage gate the owning skill already has — do not introduce a parallel status vocabulary here (variant (c) in `references/coverage-exhaustion-traps.md`).
|
|
@@ -147,13 +147,13 @@ Use this skill to turn observed experience into durable agent skills without cop
|
|
|
147
147
|
- Either way the landing must be a **shared** artifact — CCL skill, shared reference, validator, checklist, or project template — naming the exact trigger/gate teammates will hit; for a reusable routing/process/team failure, classify a memory-only landing as insufficient — local-only and "I'll remember next time" count the same (local memory supplements user/workspace context only). A candidate that turns out NOT genuinely reusable may be `discarded` with evidence. When neither path fires, ordinary `routed`/`unchanged` disposition to a different owning skill stays available per bullet A step 3.
|
|
148
148
|
- For any analysis-parse-fix-test-challenge loop, separate five stages explicitly: analysis, parse/decompose, fix, test/verification, and challenge. Add a replay step when validating reusable lessons: rerun the same task shape or a close analog through the proposed workflow and check whether the required outputs and gates still appear in order. Keep four outputs explicit: the project-level fix, the test/verification evidence, the challenge findings, and the reusable workflow lesson. If the same pattern can recur across different domains, lift only the workflow lesson into `skill-extraction-workflow`; keep domain-specific implementation details in the owning project or target skill. See `references/analysis-parse-fix-test-challenge-replay.md` for the replay validation runbook.
|
|
149
149
|
- **The agent failing to self-invoke this workflow (the user had to point out that `skill-extraction-workflow` should have been used) is a tracked failure class that recurs across the session / different tasks, not only within one extraction thread** (so the "twice in one extraction thread" scope above does not catch it). **Honesty:** an in-the-moment self-trigger is recognition-dependent — the always-on bootstrap layer raises its salience but is NOT a mechanical gate; do not overclaim a passive rule "fixes" the recurrence.
|
|
150
|
-
- **One self-detectable firing point does exist and must be used: the moment YOUR OWN output names 沉淀 / 提炼 / 复盘 / "distil this into a skill"
|
|
150
|
+
- **One self-detectable firing point does exist and must be used: the moment YOUR OWN output names 沉淀 / 提炼 / 复盘 / "distil this into a skill", OR **enumerates what an external source has that we lack** (a gap list vs another pack; see `references/firing-point-placement.md`), that naming is a trigger to RECOGNISE the owner and load it** — not a licence to widen scope: shared-skill edits still need the authority you already have, so when the user's request covered only a status review or a narrow fix, record the extraction as `pending` with the owner named and ask rather than self-authorising a shared-skill change off your own suggestion.
|
|
151
151
|
- The mechanical backstops are (a) the closeout gate — a committed skill-change with neither a visible in-session `skill-extraction-workflow` invocation nor the round's durable charter/target-output record is `interim` (per the closeout gate's evidence forms) — and (b) **user-signal escalation**: you generally cannot self-count misses you did not notice, so a user-pointed-out under-trigger is a recurrence check (was there a similar miss earlier this session, even on another task?) and, if so, escalates to tightening the always-on discipline rather than landing another narrow per-case trigger.
|
|
152
152
|
- **Firing-point-placement corollary:** when the SAME meta-class (a precise gate walked past at the routing → pre-code/design transition) recurs at a *new* lifecycle sub-point despite prior bootstrap-salience + the closeout gate, the durable lever is **moving the owning gate's firing point ONTO the transition itself** (pre-substance-draft AND pre-first-impl-edit) and sharpening *name→invoke* — naming/knowing an owner is NOT invoking/loading it, and a named-but-unloaded owner's mechanical rules never fire — at the SAME transition, NOT another bootstrap/per-case bullet or more prose.
|
|
153
153
|
- **Record-field corollary (the forgery surface):** when you land an owner gate as a *field in a record* — a checklist row, a boundary-record line, a CLI flag taking owner names, a "decision:" slot — that field is fillable without invoking the owner, and filling it is what *feels* like discharging the gate; any field naming an owner therefore carries an explicit invoke bar on its triggered values.
|
|
154
154
|
- The self-detect firing point's authority boundary and observed shape, the record-field corollary expansion (the invoke-bar coverage set-diff mechanics, the delegation-dispatch worked case), the worked recurrence-chain, and the landed owner-dispatch implementation: `references/firing-point-placement.md`.
|
|
155
155
|
- **Run your own adversary to convergence BEFORE any "done / fixed / passing / covered / converged / complete" claim — your own such claim is the least-trustworthy thing you emit.** For any non-trivial completion/coverage/convergence claim, you must have already run — **yourself, not deferred to the user** — the verification or adversarial pass that would catch its failure, to a **clean fresh result** (a first clean pass on the current candidate, never a "confirm my fix" pass), OR **downgrade the claim to `interim` and name what you ran vs. didn't**. "Covered / converged / already handled" is a claim, not a status — back it with firing-path or clean-pass evidence or do not emit it; this self-adversary duty never narrows the mandatory dual-track challenge (it is the always-on generalization of self-audit-to-convergence, not a replacement for the gate).
|
|
156
|
-
That pass is a **walked enumeration over the properties the candidate asserts, never a re-read**: a property whose killing mutation you cannot name was never verified, and re-reading your own prose can only ever confirm that the prose is self-consistent with itself. **A mutation you did not APPLY is a hypothesis, not evidence** — bound its blast radius (never disable an authorization, idempotency, or deletion guard and exercise it against a shared or live dependency; mutate against isolated dependencies or at the lowest layer that avoids them, and where neither is possible record the property `unverified`). **Prove the oracle can fail before trusting its clean verdict** — point the check at something you know is broken and watch it report that; a check that can only ever say clean is no evidence, and whatever you produced while fixing a previous round's findings is part of the current candidate and re-owes the whole enumeration. **A validated oracle is still clean only over the DIMENSIONS it crossed** — proving it can fail says nothing about the axis you never varied, so a clean run is reported with the dimensions it covers, and the enumeration walks dimensions (shape / provenance-and-trust / cardinality / semantics / ordering — `testing-strategy` owns that list) before values. If no contradicting observation exists, the property is `unverified` and must be labelled that way rather than counted as audited.
|
|
156
|
+
That pass is a **walked enumeration over the properties the candidate asserts, never a re-read**: a property whose killing mutation you cannot name was never verified, and re-reading your own prose can only ever confirm that the prose is self-consistent with itself. **A mutation you did not APPLY is a hypothesis, not evidence** — bound its blast radius (never disable an authorization, idempotency, or deletion guard and exercise it against a shared or live dependency; mutate against isolated dependencies or at the lowest layer that avoids them, and where neither is possible record the property `unverified`). **Prove the oracle can fail before trusting its clean verdict** — point the check at something you know is broken and watch it report that; a check that can only ever say clean is no evidence, and whatever you produced while fixing a previous round's findings is part of the current candidate and re-owes the whole enumeration. **A failing anchor is first a question about the ANCHOR, not a verdict on the implementation** (§Self-audit). **A validated oracle is still clean only over the DIMENSIONS it crossed** — proving it can fail says nothing about the axis you never varied, so a clean run is reported with the dimensions it covers, and the enumeration walks dimensions (shape / provenance-and-trust / cardinality / semantics / ordering — `testing-strategy` owns that list) before values. If no contradicting observation exists, the property is `unverified` and must be labelled that way rather than counted as audited.
|
|
157
157
|
A scoped "X verified; Y not run" is an interim checkpoint, **not** `done`/`complete`/`landed`: `Y not run` blocks a done/complete/landed claim unless a **risk owner — the user/maintainer, never the agent self-accepting — explicitly accepts the gap AND it is tracked to that owner** (agent self-labeling "risk accepted" or "deferred" does not qualify; scoping is a downgrade, never a license to call the narrowed slice done). **Recurrence signal:** a user prompting you to keep digging / verify / disputing a "covered/converged/done" is a premature-completion signal — on the **2nd** such correction in a session (even across different tasks) escalate to tightening this discipline, not just fixing the one case (per the repeated-correction escalation above).
|
|
158
158
|
The full self-adversary method — the mutation enumeration, the applied-mutation discipline, the independent-oracle validation, the re-owe-after-fixes rule, the graded-verdict calibration, and the recognition-dependent honesty caveat: `references/dual-track-review-gate.md` §Self-audit.
|
|
159
159
|
- Automatically trigger durable learning when extraction work exposes a reusable failure — **and when ordinary delivery work does, capture it here too, but without extraction taking over the delivery**: let the active owner (`product-rd-workflow` / `defect-diagnosis` / `testing-strategy` / …) handle the immediate work first, then route the durable lesson here. **For a premature-stop correction after affirmative continuation**, immediate recovery means first rerun the active owner's current continuation/blocking gate in full (for product R&D, Pre-Final Continuation Gate steps 1–6) against current state, then follow its observable outcome — proceeding only when a literal binding exists (the original proposed-next action/scope plus literal assent, preserved in the visible conversation or quoted exactly in trusted host-owned session/compaction state — never reconstructed, broadened, or substituted — or the user's correction literally naming the paused action and scope) — a semantic compaction paraphrase or a bare "why did you stop" complaint is not path-(b) authority, and a `blocked:` recovery without the step-1 evidence and a specific missing authority/ambiguity is invalid — asking again when neither binds, the user intervened, or scope/gates changed, and never copying real conversation text into a shared repository record. Do not let correction RCA or extraction extend a still-authorized delivery, and do not let stale assent bypass a newly pending or inconclusive gate. After delivery recovery, correction RCA plus the durable prevention landing and verification are still due before the turn can be reported complete; otherwise report `interim`. The full binding rules, the `continuing:`-line form, and the invalid-`blocked:`-recovery rule: `references/resume-paused-delivery.md`.
|
|
@@ -505,3 +505,11 @@ The challenge pass is **structurally different** from review — it must be invo
|
|
|
505
505
|
## Cost note
|
|
506
506
|
|
|
507
507
|
Challenge pass at high reasoning typically costs 2-5× review pass in tokens. For a ~3 kLOC reference diff, expect ~250-500k tokens on challenge vs ~50-100k on review. The value of one P0 finding caught before landing dwarfs the cost difference; do not skip on cost.
|
|
508
|
+
|
|
509
|
+
## 错误锚点:用错的尺子量对的实现
|
|
510
|
+
|
|
511
|
+
验证 oracle 用的**锚点本身可能是错的**,而这比 oracle 出错更难发现——因为**其余锚点会继续通过**。
|
|
512
|
+
|
|
513
|
+
当锚点的预期方向来自**你对一手源的解读**时,该解读是 hypothesis-grade。锚点不过,第一步应是质疑锚点、回到源的机制陈述重新推导预期,而不是判实现有 bug。否则两种后果:要么去「修」一个正确的实现,要么——更危险——因为其余锚点通过而接受一个错的。
|
|
514
|
+
|
|
515
|
+
观测实例:验证色觉障碍模拟时,用「红色模拟后应变暗」作锚点,实测亮度上升。回到一手后确认:模拟把颜色投影到**单侧二色视者双眼一致的不变轴**(protan/deutan 取 475nm 与 575nm),红投到黄轴、亮度上升是算法的**正确行为**;而「红色看起来暗」说的是**红与黑难以区分**,是另一个量。另外两个锚点(灰阶不变、已知色对靠拢)当时都通过。
|
|
@@ -113,3 +113,15 @@ Referenced from `SKILL.md`'s "The mechanism underneath" rule. This section holds
|
|
|
113
113
|
**Why recency is a hazard, not a rule.** Vendor guidance reports that models *tend to follow* whichever instruction sits later — an observation about behaviour, not a licence to resolve conflicts by position. Two ways position becomes dangerous if read as a rule: a later permissive line beats an earlier stricter one (directly contradicting `Conflict Resolution`, which keeps the stricter data-loss/security/contract guard); and text embedded in **untrusted data** — a diff under review, a retrieved document, tool output — sits later within the same authority level and would win by placement alone, which is prompt injection with extra steps. Treat recency as a bias to design against: put the load-bearing rule where the decision happens, and never let placement confer authority.
|
|
114
114
|
|
|
115
115
|
**How to use them.** Vendor guidance and benchmarks are **hypotheses with good provenance** — they tell you what to test on your own corpus, they do not substitute for testing it. Citing them as settled is the same error as landing an unverified claim; so is overruling one with an underpowered probe.
|
|
116
|
+
|
|
117
|
+
## 继承的约定读法:失败形态
|
|
118
|
+
|
|
119
|
+
一道建立在**继承来的错误读法**之上的闸——把 `AGENTS.md` 读成存在「根索引」要求(实际并不存在)——在多轮 dual-track 里以不断打补丁的方式存活,直到用户问「参考网上优秀实践了么」,一手源(nearest-file-wins)才证伪了整个前提。
|
|
120
|
+
|
|
121
|
+
教训:前一个 agent 或前一次提交对某个具名约定的读法是 **hypothesis-grade**;在其之上 fix-forward 会把原始错误一并传播。
|
|
122
|
+
|
|
123
|
+
## 只据内部语料的「深度提炼」:失败形态
|
|
124
|
+
|
|
125
|
+
一次仅以内部 launch-SOP 为源的「深度提炼」会落出**看起来完整**的规则集,却从未核过这套技能声称代表的**公开实践**;下一个用户于是问「参考网上优秀实践了么 / did you check industry practice」。
|
|
126
|
+
|
|
127
|
+
判据:凡规则带 state-of-the-art 主张,charter 的 evidence plan 必须含权威外部源类;只编码内部运行约束、且明标内部范围不作行业主张的规则,不受此限。
|
|
@@ -73,3 +73,11 @@ Honest scope, from the eval that landed this (2 arms x 5 fixtures x 6 samples in
|
|
|
73
73
|
Observed shape: a session produces a reader-facing deliverable end-to-end through a platform/tool skill pack (a collaborative-doc platform, spreadsheet, or browser pack), and the loaded tool skill supplies enough "already being guided" feeling that nobody ever asks which skill owns the DELIVERABLE's quality bar — so the finalization owner's gates (doc charter, completeness audit, closeout sweep, structural-reference re-resolution) stay dormant for the whole effort, surfacing only when the user asks "did you run the doc-optimization skill". This is the behavioral twin of the digest-masks-corpus trap: the tool layer's presence masks the owner layer's absence.
|
|
74
74
|
|
|
75
75
|
Firing point: **producing or first-publishing a reader-facing deliverable is an owner-check transition** — before the first publish to a collaborative or reader-visible surface, answer "which skill owns this deliverable's quality bar" as a separate question from "which tool writes it"; a tool-skill invocation never discharges that check, and a deliverable with no matching owner routes to the finalization skill's Draft mode rather than proceeding ownerless. Mechanical anchors: the no-owner-deliverable triggers on the finalization skill's routing surface (`tighten-doc` description), and this workflow's closeout gate when the session later lands skill changes. Honesty bound as elsewhere in this section: between those anchors the check is recognition-dependent — do not overclaim it as a mechanical gate.
|
|
76
|
+
|
|
77
|
+
## gap-list 形态为什么最易滑过
|
|
78
|
+
|
|
79
|
+
自检触发点列举的是「沉淀 / 提炼 / 复盘 / distil」这类**自述措辞**。但一轮提炼最常见的第一个产出不是这些词,而是**一张缺口清单**——「外部源有 X、Y、Z,我们没有」。它读起来像在**答一个覆盖问题**,不像在提炼,所以 charter-before-findings 那条规则从不觉得被触发。
|
|
80
|
+
|
|
81
|
+
但按该规则自己的定义,**针对外部源的缺口清单就是它所说的 findings 回合**:一旦产出,charter 就只能事后补写。
|
|
82
|
+
|
|
83
|
+
观测实例:一轮里先产出四条「外部有我们没有」的缺口,之后才 invoke 提炼工作流;改前的触发词表逐字检索该轮实际措辞得零命中。
|
|
@@ -322,3 +322,21 @@ and inverted the sense (production, not product), and the coordinator now shares
|
|
|
322
322
|
| A test harness owns a pid only while that pid is outstanding: once it has been reaped the number is the OS's to reissue, so a cleanup list that still carries it aims its signals at a stranger — and a suite that runs eight-way parallel makes that stranger a sibling lane. Drop ownership at the moment of reaping, which is the same prove-it-now rule the code under test applies before it signals anything | `code-review` | behavioral-evidence: RED-baseline; observed-failure: yes; firing-path: command:skills/code-review/scripts/test_abort_leak_state_helpers.sh | updated | `code-review/SKILL.md` is the owner key and is unchanged this round; the change lands in `skills/code-review/scripts/test_abort_leak_state_helpers.sh` (`drop_kid`/`reap_kid`). Observed failure: raised as P1 by the independent review lane against this round's own new test — the harness written to check the probe's ownership discipline violated it, accumulating reaped pids in its cleanup list. RED-baseline: reverting the drop-at-reap change leaves reaped pids in the trap's signal list, which the suite's own accounting shows as entries no longer owned; the hazard is structural rather than timing-reproducible, so the recorded evidence is that accounting rather than a raced kill |
|
|
323
323
|
| A mechanical gate's DOCUMENTED limit belongs in its behaviour suite as a probe asserting the gate does NOT fire, not only in prose: pinned that way, any later tightening turns the probe red and forces the documentation to be corrected, whereas a limit described only in text goes stale silently and is then re-discovered as a finding | `skill-extraction-workflow` | behavioral-evidence: RED-baseline; observed-failure: yes; firing-path: command:skills/skill-extraction-workflow/scripts/test_liveness_predicate_gate.sh | updated | `skill-extraction-workflow/SKILL.md` is the owner key and is unchanged this round; the change lands in `skills/skill-extraction-workflow/scripts/test_liveness_predicate_gate.sh` (P13/P14) with the limit paragraph in `skills/skill-extraction-workflow/references/recurring-anti-patterns-checklist.md` pointing at them. Observed failure: the adversarial challenge re-raised the different-pid / discarded-result waiver hole and correctly noted the suite never exercised it, so the limit existed only as prose. RED-baseline: P13/P14 pass against the current predicate and go red against a stricter one — that inversion is the signal they exist to raise |
|
|
324
324
|
| An obligation whose skip leaves NO artifact is not enforced, however normative its wording: the party it constrains states the entry condition, and a reviewer cannot refuse a claim that was never made. Demoting an overclaim must not demote the obligation riding on it — separate the two, and give the surviving obligation a trigger keyed on a fact of the DIFF (which file changed, which key a row carries) rather than on prose. A round is held only to the grammar its own head declares, or adding a required field retroactively refuses every historical round on replay | `skill-extraction-workflow` | behavioral-evidence: RED-baseline; observed-failure: yes; result-class: failure; firing-path: command:skills/skill-extraction-workflow/scripts/test_impact_chain_self_adjudication.sh | `updated` | `skill-extraction-workflow/SKILL.md` is the owner key and is unchanged this round; the change lands in `scripts/impact-chain-gate.rb` (two refusals: `impact_chain_result_class_missing`, `impact_chain_bank_evidence_missing`, both scoped to owners the round changed and both gated on the head-declared grammar), `references/source-register.md` (the declaration-fragment paragraph that dates them), and the new `scripts/test_impact_chain_self_adjudication.sh` registered in the heavy lane. Observed failure: round 044 withdrew several overclaims and demoted their obligations in the same move; five consecutive challenge rounds returned one shape, each naming an executable bypass — change a description and never run the bank (no absence to detect), omit the result-class cell (static checks pass, nothing emits interim), or write the class the author prefers (the reviewer has no field to refuse). RED-baseline (applied, differential, re-measured on the final suite — an earlier draft of this row froze a twelve-leg table and an `exactly A2/A3/A5 / B2/B3` partition and went stale as legs were added; independent review caught the drift, and the numbers below are the measured ones): the 28-leg decision table is red on the legs each refusal exists for before the gate change. Disabling `impact_chain_bank_evidence_missing` reds exactly A2 A3 A5 A7 A8 A9 A10 A11 A13 A14 A15 A16 A17 A18 A19; disabling `impact_chain_result_class_missing` reds exactly B2 B3 B5; disabling `impact_chain_grammar_withdrawn` reds exactly G2 G3 G4. Clean partition, no overlap, control green either side of every mutation. Bootstrap: removing `result-class` from this row itself, committed, reds the gate naming this row. Scope limit recorded rather than overclaimed: these close OMISSION, not MISCLASSIFICATION — the value stays the author's, and a locator is not proof the measurement ran. Retroactivity was measured, not assumed: naked, the two triggers newly refuse 34 of the 64 replayed historical integration points (5 for the bank trigger alone); gated on the head-declared grammar the differential returns 64/64 with zero new refusals, and leg G1 pins that property. Round plan: `specs/045-self-adjudicated-obligation-trigger/plan.md` |
|
|
325
|
+
| 交付型文档不是一个体裁:起草期缺「非目标 / 备选与落选理由 / 本方案自身的代价 / 外部先例 / 开放决策带闸 / 证据与正文分离」这些节的首稿,会把缺项以打磨轮的形式付回去,且命题定性写错的返工代价与篇幅成正比。因此把族判定与每族起草期必答项作为形态契约落在定稿技能的 charter 之后,实质完整性的裁决权仍留在各族 owner | `tighten-doc` | behavioral-evidence: RED-baseline; observed-failure: yes; result-class: failure; firing-path: file:skills/tighten-doc/references/doc-charter-first.md#也是 charter 与 Genre 两格必须先锁的原因 | updated | `tighten-doc/SKILL.md` 是 owner key,本轮净减 565 字节:原 Diataxis 段的细则下沉到新增的 `skills/tighten-doc/references/deliverable-doc-genre-skeletons.md`,入口只留两轴判据与指针; `skills/tighten-doc/references/doc-charter-first.md` 的 charter 表新增 Genre 一格并补入「全局修订先于局部润色」。 零损失:原 Diataxis 段的六项义务(单一主导模式、muddled purpose 判据、四模式只用于发现混杂而非强制拆四份、 一页纸默认形态属 how-to/reference、只标记拆分候选不自行改文档集、文档生成技能只是执行器)逐条搬入新文件 §0,无删减。 RED-baseline(applied, differential):同一起草任务(把一个后端服务扩成两区长期并行),仅变更所引治理规则文本一个变量, 在仓外中立目录以 `--safe-mode --tools "" --setting-sources ""` 且禁 CLAUDE.md / auto-memory 运行—— base 产出一份 14 节的合理骨架而九个必答项标记(非目标/备选/落选/取证/开放/退出/降级/禁用词)全部为 0, 且其实施路线一节自命名为「迁移」,正是本类返工最贵的那种命题错误;candidate 九项全部出现。 判分器可失败性由 base 产出真实文档而非拒答证明。首次测量在仓内跑、两侧都读到了新文件,判定污染并作废重测。 外部依据:Google design doc 的 non-goals 与 alternatives、公开 RFC 模板的 drawbacks/prior art/unresolved questions、 arc42 的质量目标与术语表、ISO/IEC/IEEE 42010 的关切—视图覆盖、C4 的一图一层、Minto 金字塔的结论先行、 ISA 230 的收录判据与归卷保管、PRISMA 2020/-S、ICH E9(R1)。 十六轮 dual-track 中一类反复误判(安全事件响应策略)判为设计缺陷并整体删除、改为路由给既有安全 owner,删后该类不再复发 |
|
|
326
|
+
| 由差集得出的缺席结论有两条独立的假阳性来源:发布方收录范围变化,以及匹配口径在标签长出新词时漏配。 而包含式复检只能推翻缺席、不能确认缺席——改名后的新名可能完全不含旧名,任何字面匹配都照不到。 另一面,把某条取数入口写进「下一轮最高性价比」之前要先抽样验它的产出:入口的价值由它实际给出什么决定,不由它的强制力或可达性决定 | `multi-perspective-research` | behavioral-evidence: RED-baseline; observed-failure: yes; result-class: failure; firing-path: file:skills/multi-perspective-research/references/public-data-acquisition.md#证实不了就进待核验清单,不得因为「复检过了」而升格为结论 | updated | `multi-perspective-research/SKILL.md` 是 owner key 且本轮未改;改动落在 `skills/multi-perspective-research/references/public-data-acquisition.md`(并入既有的名单差分条,补第二条假阳性来源与「复检不能确认缺席」的方向限制)与 `skills/multi-perspective-research/references/public-disclosure-channels.md`(在「走过而无产出的渠道要留下原因」一节后补其反面:入口按产出选)。 既有的收录范围变化处置、独立来源证实要求与渠道状态词均原样保留,无义务被删。 RED-baseline(applied, differential,幅度如实记):同一提问(逐期名单中某实体本期未出现,能否得出已退出)在仓外中立目录、`--safe-mode --tools "" --setting-sources ""`、禁 CLAUDE.md 与 auto-memory 下只变更所引取数纪律一个变量。 base 本身已拒绝下结论并想到更名与交叉验证——**差分不在一般判断力上**;base 缺的是可执行机制与处置: 包含式复检、复检只能推翻不能确认这一方向限制、以及证实不了即进待核验清单不进承重结论,四项标记(包含/复检/独立/待核验)base 全 0、candidate 全部出现。 判分器可失败性由 base 产出一份合理且谨慎的答复而非拒答证明。 观察到的失败取自一段多轮公开材料调研的逐轮修订表与自评:某实体被误判为消失(实为归一化在新名下漏配), 以及同一条高权威、零产出的入口被连续两轮写进下一步建议、走完才发现不成立 |
|
|
327
|
+
| 一条规则可以触发正常而内容为假:把「反复润色」几乎全部归因于修订伪装成润色、并断言那是最常见的机制,这个最高级没有证据支撑,且会把一个正当的「再润色一遍」误读成实质未定。撤回该断言,并补上被它掩盖的另一支——润色本身多轮收敛:一致性与口径漂移、跨节重复、密块、元语自证是逐位置缺陷,每一遍改动都可能重新引入前一遍已清掉的类。判据必须钉在**实质的状态**而不是本轮请求的措辞,否则实质未定但只收到措辞请求时会放行润色,抵消同段前半句的前置约束 | `tighten-doc` | behavioral-evidence: RED-baseline; observed-failure: yes; result-class: failure; firing-path: file:skills/tighten-doc/references/doc-charter-first.md#反过来不成立:润色本身就是多轮收敛的 | updated | `tighten-doc/SKILL.md` 是 owner key 且本轮未改;改动只在 `skills/tighten-doc/references/doc-charter-first.md` 的同一条 bullet 内。 前半句的前置约束(实质未定不进润色轮、顺序不可倒)逐字保留,新增的只是第二支与其判据;类目、判法与多轮节拍仍由 `tighten-doc/SKILL.md` 单一持有(DELETE 的元语自证类、closeout 的一坨/跨节重复/族内术语漂移、「用户还能单 paste 挑出同类缺陷 = 清单未真跑」与 Full-pass ≠ token-pass 的注意力摊薄诊断),本行不复述也不新增类。 **observed-failure: yes 的依据**:失败由用户的一手实践报告提出(润色确实要多轮,且类目本仓早已持有),并在探针上复现——该规则触发正常,错的是断言内容。 RED-baseline(applied, differential):仓外中立目录、`--safe-mode --tools "" --setting-sources ""`、禁 CLAUDE.md 与 auto-memory,只变更所引纪律文本一个变量,提问「已润色到第 6 轮、每轮仍能挑出一致性/跨节重复/密块,是不是实质没定」——base 答「大概率是……说明命题/结构还没收敛」并建议停下退回 charter/Genre、别再要求再润色一遍;candidate 答「不必回 charter/Genre……这是润色轮的正常特征」并给出按类分趟走查的做法。**两侧给出方向相反的操作建议**,按用户的一手实践 base 的建议是错的。 判分器可失败性:base 产出的是一段自信连贯的建议而非拒答。 两次 A/B 均**未测出行为差分**并如实记账:(1) 「实质已定但一致性差/跨节重复/密块,要求再润色一遍」——base 自己就判定为真正的润色轮且未回 charter,我假设的误判**未复现**; (2) 把 closeout 表头改成「逐位置判」的候选形态——base 与 candidate 对同一份植入四处缺陷的短文档都全数命中,差分可忽略。 因此该形态提议**未落地**(探针文档过小、注意力摊薄这一真实机制未复现;继续构造更长文档直到显效即是偏向性测量,按测量纪律停手)。 本轮落地的只有真值修正,其正当性来自断言无据本身,不来自行为差分 |
|
|
328
|
+
| 一道公共泄漏闸若把**另一个领域的普通词汇**当作专有标识的代理,它会随那个专有对象失效而变成纯误报来源:该项随初始提交带入、无理由记录,维护者确认它当初是为早期提炼项目的一个专有产品模块名而设,模块已不适用,而词本身是通用技术用语。退休它而非继续维护:真实标识符的权威闸是私有 alias 审计,公共词表只是无该命令环境下的弱代理兜底;删除前先量化今天有多少内容依赖该信号,并用保留项做对照证明闸仍能报错。同类对照就在同一目录:`generic-r0-leak-scan.sh` 的谓词是它自己拥有的凭据形状,有套件;这条借别人的词表,此前无任何测试 | `skill-extraction-workflow` | behavioral-evidence: RED-baseline; observed-failure: yes; result-class: failure; firing-path: command:skills/skill-extraction-workflow/scripts/check-ccl-skills.sh | updated | `skill-extraction-workflow/SKILL.md` 是 owner key 且本轮未改。改动三处:`scripts/check-ccl-skills.sh`(正则去掉一个分支,并就地写下该词表的定性——弱代理兜底、权威闸是私有审计、按退休维护而非增长,因为真正的不变量「公共文本是否指向某个具体组织」本就不是公共正则可判的)、新增 `scripts/test_entrypoint_domain_scan_terms.sh`、以及把它注册进 heavy lane(克隆型套件按既有判例入 heavy;未注册即假绿)。 observed-failure:本轮撰写台账时被该项挡下一次,属正常技术用语被误挡。 四腿(applied, differential):腿1 只读跑真仓证明该闸仍在跑且干净;腿2 从脚本**现读**那条正则(用 awk 取,不用 lookahead——要求 PCRE2 会让没编该特性的 rg 整条 lane 挂掉,而被测闸本身并不需要它),验保留项与非词表分支仍匹配(源绑定,不会与出厂内容漂移);腿3 验退休项在正常行文里不再匹配; 腿4 端到端——在 `--shared` 克隆上**先跑一次不带 fixture 的对照**(须 exit 0 且该闸报干净),再植入命中 fixture 跑,要求非零退出、报出失败 token 且点名该 fixture;没有那次对照,删掉 `exit 1` 再叠加克隆上任何无关的后置失败,同样会给出非零与该 token,腿4 会在坏闸上变绿。**该腿的归因主张经过一次撤回**:最初想证明「它停在这一步」(先用『该闸之后的首个 token 缺席』,后改用『终态成功 token 缺席』),连续四轮被两条 lane 指出同一类洞——黑盒测试看不见控制流,任何 token 形态都只是代理:`exit 1` 被删、再叠加一个由 probe 自身触发的后置失败,非零、失败 token、probe 名、终态 token 缺席会同时成立。按同类跨轮复发即设计信号处理,**撤回该主张而不是再加机制**。腿4 现在只主张两件真实成立的事:植入命中后 (a) 该闸报出失败并点名 probe,(b) 整跑拿不到认证。**不主张这次未签发认证由该闸独占造成**——这是明写的残留,不是已验证性质。 **腿4 是评审逼出来的**:只有腿1-3 时,失败分支被绕过或反转仍会整套全绿(腿1 只证明干净时打印了 ok,腿2-3 只验正则本身)。 四个 applied 变异证明非空洞且归因可分:把退休项加回去只红腿3;删掉一个保留项只红腿2;中和失败分支只红腿4、腿1-3 仍绿;只删 `exit 1`(保留 token 输出)红在腿4 的退出码断言;复合变异(删 `exit 1` + 注入后置失败)被干净克隆对照接住。对照均绿。 **残留风险(accepted,风险 owner = 维护者,非 agent 自受)**:无 `ALIAS_AUDIT_CMD` 的环境(CI、他人机器)今后对「唯一公共信号是该项」的内容失去覆盖。 量化:该闸覆盖面(`skills/*/SKILL.md` 与 `skills/*/references/*.md`)内当前 0 处,故今天无任何内容失去覆盖;风险为前瞻性,且该通用词本就是那个模块名的弱代理 |
|
|
329
|
+
| 交付文档的图与表有起草期可判定形态契约:图种由主张形态推出、画了必须满足记法硬约束(标题/图例/连线单向且标签具体)、版式契约冻结后按契约符合性判一致性(不用魔数阈值)、量级对比与结构关系不得全压进表、图文引用一致 | `tighten-doc` | `tighten-doc` 的图/表形态判据从散文升级为可机械判定:`tighten-doc/references/figure-and-table-craft.md` 定判据与其依据档位(外部权威 / 工程约定 / 查证后禁用),`tighten-doc/scripts/figure-lint.py` 与 `tighten-doc/scripts/doc-lint.py` 实现可判定部分,`tighten-doc/scripts/test_figure_and_doc_lint.sh` 做逐谓词差分自测并注册进 `make test-repo-gates`; result-class: failure; behavioral-evidence: RED-baseline; observed-failure: yes; firing-path: command:skills/tighten-doc/scripts/test_figure_and_doc_lint.sh | `updated` | owner key `tighten-doc/SKILL.md`(「表达形式匹配内容」条就地 merge 判据 + 指针,入口净减过体积闸);`tighten-doc/references/deliverable-doc-genre-skeletons.md` §4/§5 就地 merge。**观察到的失败**(本轮实测):18 张真实架构图里 17 张无图例、12 张连线无标签、7 张文本对比度 2.58:1 低于 WCAG AA 4.5、35 处超长文本零 tspan 必溢出、6 张零分组、5 张画布比例偏离;一份 1059 行调研报告 45 表 0 图、23 处数值列无单位、17 处加粗行冒充小节标题。**RED-baseline 差分是可重跑脚本 `tighten-doc/scripts/mutation_probe.sh` 而非声明**:逐谓词把 code 字面量替换使其消失,24/24 均使套件转红,任一仍绿即退出非 0。该实验本身先失败两轮、两轮都是无效突变:改的是 oracle 不观测的维度(severity 而非 code),以及把脚本崩溃读成绿(判据只看 FAIL 行不看退出码)。**四轮独立 review(34 条 / 29 P1)+ 一轮对抗 challenge(6 条 / 5 P1)全部处置**。对抗轮的结论改变了投放形态:C4-LEGEND 与 C4-EDGE-LABEL 实测**两个方向都会错**(两条目的合法图例被拒 / 注释里出现 legend 即放行;中点附近的分区标题掩盖未标注连线 / 标在别处的合法标签被拒),已**降为非阻断 WARN**——C4 规则本身是 [外],用邻近与色块计数去认它是 [工] 代理,代理不该挡他人提交;要恢复阻断需结构化关联(契约声明的组 / aria-labelledby / textPath),不是把阈值调准。另修:比例先舍入再做「精确」比较等于引入未声明容差(16:9 的 1.7777… 会通过 [1.778])→ 改用未舍入值比较;px() 把 1em 当 1px、12pt 当 12px → 按单位换算,不认识的单位报出;doc-lint 对坏文件返回空发现集 + skipped=true 使损坏文档「干净通过」→ 与 figure-lint 对齐报 READ 并继续整批。**独立评审第一轮 10 条发现全部处置**,7 条 P1 均为真缺陷,最重一条推翻了本轮自己的证据声明——run_expect 加参数漏改调用点致控制组断言被吞、弄脏控制组仍全绿;已改为参数不足判红 + 期望表全量对应,两条回归实测通过。其余修法见 tighten-doc/scripts/AGENTS.md 的 Validation 节 |
|
|
330
|
+
|
|
331
|
+
<!-- 053 轮独立评审第一轮处置(候选 4293dbe7…,reviewer 经原生绑定读取 5 个 owner 技能):10 条发现全部处置,7 条 P1 均为真缺陷。最重一条推翻了本轮自己的证据声明——run_expect 加了参数却漏改调用点,控制组断言被当成参数吃掉,弄脏 control.svg 仍全绿;已改为参数不足直接判红 + 期望表全量对应,两条回归实测通过。另六条 P1:path_mid 对单段路径返回终点致终点节点名被当作连线标签(改按弧长取中点并排除节点内文本);GROUPING 只查全图有无任意 <g>(改为逐卡片判定形状与文字是否同组);契约配色只收文本色(改收全部渲染元素的 fill 与 stroke);契约损坏只记不报致退出码为 0(新增 CONTRACT-INVALID 并做类型校验);比例容差内置 0.02 是魔数(改由契约 ratio_tolerance 声明,未声明即精确匹配);只用首个文件的目录找契约(改为逐文件解析最近契约)。P2 的 CARRIER-IMBALANCE 计数阈值被包装成 ICD 203 要求,已降级为 WARN 且仅在存在量级对比表时提示。 -->
|
|
332
|
+
|
|
333
|
+
<!-- 053 轮独立评审第二轮处置(候选 c696c516…):9 条发现全部处置,8 条 P1。最尖锐一条打在本轮论点正中——ICD203-9 检测被标 [外],但其触发阈值(≥6 行 / 数值占比 >0.8 / ≤3 列)是检查器自定的;一条声称按依据分档的规则自己混了档。修法:载体选择原则标 [外]、识别阈值标 [工],且输出里直接带档位,读者当场可见哪半有依据。两处真绕过口:空的 figure-contract.json({})既不报缺失也不报损坏、三项检查全跳过(现三项字段必填非空);分组判据只要求祖先 g 集合有交集,把整图包进一个顶层 g 即全部通过(现要求卡片专属的最近公共组)。最有价值的修法是把突变清单从**源码派生**而非手写:评审指出手写 24 条漏了 PARSE / C4-VIEWBOX / C4-EDGE-VAGUE,补三条治标、让清单不可能漏才治本;派生后立刻暴露 6 条无覆盖并全部补了 fixture,现 28/28。其余:连线改为先全量识别再校验方向(原只收已有箭头的,无箭头连线根本不进检查,而『每条线单向』正要求它有方向);底色解析不了时报 CONTRAST-UNSUPPORTED 而非回退白底(回退白底会产生假绿或假红);悬空图号按实际编号比对而非数量;viewBox 非法不再抛异常而是报 GEOMETRY。 -->
|
|
334
|
+
|
|
335
|
+
<!-- 053 轮全量试跑与删除收束:两轮独立评审后又做了一件评审做不到的事——把检查器放到 392 份本仓正常文档上跑。结果 718 条发现、318 条 ERROR、命中 150/392 份文件,其中四条阈值型谓词(标题过长 / 单元格塞整段 / 段落内并列枚举 / 列表项多句)独占 96.7% 的发现量与 99.7% 的 ERROR,抽样中无一条是其声称的缺陷。判据错误而非过严:它们都拿宽度或计数当「表达好不好」的代理,而这类阈值经本仓既有 bench 查证无可靠来源——等于把 [禁] 档的东西改名重立。四条全删。删后 23 条、ERROR 0、涉及 13/392。全量试跑另暴露两条前提性错误:围栏代码块内容被当成文档结构;「引用悬空」在零图文档里根本不成立(本轮自己写的判据文档就是第一个受害者)。**方法论落点**:fixture 只证明谓词能报,不证明它报得对——fixture 是作者造的、天然符合作者假设;命中率必须在没有为它准备的真实语料上量。该纪律已写入 tighten-doc/scripts/AGENTS.md 与 craft §9。两轮 diff 评审均未抓到这一类,因为评审看不到全仓命中分布——这是评审的结构性盲区,不是评审失职。 -->
|
|
336
|
+
|
|
337
|
+
<!-- 053 轮独立评审第三轮处置(候选 9d8b44a4):8 条发现全部处置,7 P1。又一次打在证据上——突变探针的源码派生只认 add(...),漏掉走 findings.append({'code':...}) 的两条契约谓词,分母偏小使『全部谓词均有覆盖』再次成为未验证声明。修法不是补两条:派生覆盖全部发射路径,并加 DERIVATION-GAP 等价断言(实际输出过的 code 必须都在派生清单里),该断言经反证有效——把一个 code 改成正则识别不了的形态即当场报缺口。现 26/26。两条『修假阳性时制造假阴性』:整体跳过 defs 使箭头 marker 的契约外颜色查不出(改为只纳入被 marker/use 实际引用的定义,反证通过);strip_fences 把 ```mermaid 起始行也清掉致 mermaid 图恒为 0(改为剥离前计数)。一条新引入的误报源:把『所有有描边的 path』当连线,分隔线与网格线会被要求箭头和标签(改为必须显式声明 class 或自带方向 marker,类名可由契约覆盖,且样式沿祖先继承解析)——与本轮删掉那四条同类,**该修法第一次落地时被后续 patch 覆盖丢失,而台账已先写上「已改」,第四轮评审实测出装饰线仍被判红才发现——台账写了没做的事比缺陷本身严重,现已重新落地并双向验证(装饰线不判、声明为 flow 的线仍判)**,说明『判据是否会误报』要在每次新增判据时重问,不是删过一次就免疫。其余:含 transform 时跳过全部依赖几何的 ERROR 而非硬报;有编号图注却无真实图实例判悬空;退出码契约(0/2/1,含 --json)此前全程被 || true 忽略,现已加回归。 -->
|
|
338
|
+
| 图的布局属性有一支真正做过实验的文献,可进 [外] 档:削减边交叉的收益远大于减弯折与提对称,而正交网格对齐与出边夹角统计上不显著(故不值得为它们做取舍);不可避免的交叉角度越大越好但不必直角 | `tighten-doc` | `tighten-doc` 的图判据补上此前完全缺失的布局面:`tighten-doc/references/figure-and-table-craft.md` §4b 记入两项实证及其三条边界(实验对象是抽象点线图非带标签架构图、给的是排序非阈值、只有边交叉与弯折可机械算),`tighten-doc/scripts/figure-lint.py` 新增 GRAPH-CROSSINGS 谓词只报数不设阈; result-class: failure; behavioral-evidence: RED-baseline; observed-failure: yes; firing-path: command:skills/tighten-doc/scripts/test_figure_and_doc_lint.sh; bank-evidence: file:eval/routing-tasks.jsonl#route-figure-craft-unease | `updated` | owner key `tighten-doc/SKILL.md`(本轮未改其正文,改的是其 reference 与 script)。**观察到的失败**:上一轮(053)跑过一次「核行业最佳实践」并就图表密度、行宽等给出「无可靠来源」结论——该结论对**问过的问题**成立,但整支图布局实证文献从未进入视野,是从外部技能仓的一行引用里发现的。**完备性检查只在自己的问题集上跑,报不出没问过的问题**;便宜的补法是看邻近同行引什么。**RED-baseline**:`mutation_probe.sh` 29/29,新谓词由探针的 DERIVATION-GAP 自动纳入清单并当场验出覆盖;双向 fixture 实测——交叉图报「交叉 1 处、最小交叉角 25°」,不交叉的图不报。**只报数不设阈**是刻意的:实证给的是排序不是门槛,设阈即变成 053 轮删掉那四条谓词的同类。另落人读入口 `docs/figure-and-table-handbook.md`(不进 agent 加载面,仅供队友)与三条图表类路由 eval。 |
|
|
339
|
+
| 能力落进技能正文与脚本,不等于入口开了——routing surface(SKILL.md 的 description)没提到的能力,请求根本到不了这个技能 | `tighten-doc` | `tighten-doc` 的 description 补图表触发词并写死边界:图与表的**表示形式**(图种由主张形态推出、记法硬约束、版式契约、对比度、可跑检查器)归本技能,**系统边界与架构决策本身仍归架构技能**;443→594 字符,未超 800 预算; result-class: failure; behavioral-evidence: RED-baseline; observed-failure: yes; firing-path: file:skills/tighten-doc/SKILL.md#description; bank-evidence: file:eval/routing-tasks.jsonl#route-figure-type-choice | `updated` | owner key `tighten-doc/SKILL.md`。**观察到的失败是实测不是推断**:053/054 两轮把判据、reference、两个检查器、29 条谓词、人读手册全部落地,唯独没动 routing surface。**先测后改的差分**:改 description 前跑 Tier-2 routing bank(claude-haiku-4-5 grader)得 **1/3**——「该画时序图还是状态机」被路由到 product-rd-workflow(conf 0.65),「架构图画完总觉得不对劲说不上哪不对」被路由到 grill-me(conf 0.92,措辞完美匹配拷问技能,而它恰是本判据最该接的场景);只有「全是表格要不要补图」命中。改 description 后同一 bank 重测 **3/3**,题未变、顺序为「先测→改→重测」。`make eval-routing` 静态分析零阻断零 advisory(与架构技能无触发词碰撞)。**残余限制如实记**:① co-change 警告结构性存在(本轮确实同时动了 bank 与 description),顺序只能靠本行记录供人核,工具看不到;② grader 是 cheap-LLM、advisory 不阻断、可能错,不是真值裁决;③ 三条任务的 frozen_at_sha 初次填成非 SHA 的 \"054\",被 frozen-drift 排除在回归判定外,已改挂到真实祖先 2a5bc24 后重测仍 3/3。 |
|
|
340
|
+
| 图表判据里唯一有生理机制的一支是色觉障碍:判据不是「避开某些颜色」而是「别让语义只落在同一条混淆线上的色对」,且实算优于模式匹配 | `tighten-doc` | `tighten-doc` 补此前完全缺失的色觉与主题面:`tighten-doc/references/figure-and-table-craft.md` §4c 记混淆线机制与三条边界、§4d 记图值不值得画与退化形态;`tighten-doc/scripts/figure-lint.py` 新增 CVD-DISTANCE / THEME-CONTRAST / THEME-PURE-BLACK / FIGURE-IS-A-LIST / FLOW-DIRECTION-MIXED / VALUE-SHOULD-BE-TOKEN / FIGURE-A11Y-STRUCTURE 七条谓词,契约新增 themes 维度,并按独立评审的七条发现修正后落地; result-class: failure; behavioral-evidence: RED-baseline; observed-failure: yes; firing-path: command:skills/tighten-doc/scripts/test_figure_and_doc_lint.sh | `updated` | owner key `tighten-doc/SKILL.md`(本轮未改其正文,改的是 reference 与 script)。**观察到的失败**:上一轮只读外部仓 README 表格即下结论,正文里有四类 README 看不见的判据——digest-masks-corpus 实例。**实算 vs 模式匹配的差分是实测的**:按外部技能给的「红橙/蓝橙/低饱和」色对模式,在本仓真实 token 集上只命中 warn/critical 一对;改为 Viénot 1999 投影实算后,primary/muted(protan 距 14)与 primary/ok(tritan 距 19)两对也出——模式匹配漏三分之二。参照点:Okabe-Ito 八色最小距离 38、随机八色 10、本仓原 token 集 14。**主题维度**实测:`#111827` 压纯黑仅 1.18:1,说明写死十六进制的 token 表在深色主题下整体失效。**RED-baseline**:`mutation_probe.sh` 37/37,新谓词均由探针的 DERIVATION-GAP 自动纳入并验出覆盖;fixture 全数改用 Okabe-Ito 配色——原配色在 tritan 下仅 19,会让每个 fixture 连带触发 CVD-DISTANCE、谓词隔离不开。**过程瑕疵如实记**:charter 写于前三个源已读之后;对照清单时我对「深色模式」打过一次假勾(实际只落了 CVD、契约主题维度未做),自查时撤回补齐。**独立评审七条全部成立、全部已修**(5×P1):①`themes.*.surface` 只判真值 → `"black"` 过校验后被静默跳过=声明了主题却一次没测;②主题对比度拿全局底色判压在局部卡片上的文字 → 误报,改为只判压在整幅底板上的文字(覆盖≥95% 画布算页面底色);③CVD 比的是全部渲染色(含装饰、边框)并拿 25 当触发条件,而同文件写着「只报数不设阈」——**声明与实现相反**,改为只测契约 `semantic_colors` 显式声明的语义色且无条件报出距离与参照点;④`VALUE-SHOULD-BE-TOKEN` 规则写 >2 次即报、实现要求≥3 个颜色 → 单色重复永不报,已对齐并补一色/多色两个用例;⑤流向判据在几何不可信时仍跑、且忽略 marker-start 与双向边 → 加前提并按 marker 语义定向;⑥主题与 token 两组独立断言用 `\|\| true` 吞掉退出码 → 补退出码断言;⑦发布档要求候选绑定的机器可验证证据 → 产出 `eval/evidence/figure-lint-predicates-2026-08-25/REPLAY.md`(**tracked,在冻结包内**): 列出三条命令与期望退出码/关键行,前两条完全由包内文件决定、评审方可自行复算;第三条依赖维护者私有 alias, 如实标为**不可从包内独立复核**而非当成已验证。此前那版证据放在 gitignore 的 `.work/` 下、根本不在包里, 且第一版把套件退出码取成空(PIPESTATUS 落在子 shell)、又把 gates 写成跑在提交后的 tree 上——正是本条所指的缺陷形态本身。**第二轮 dual-track(review+challenge 同绑候选 1f1e5f06)再报 9 条,两条 lane 独立收敛到同一批**,全部已修: ⑧`CVD-DISTANCE` 走 `WARN` 档 → 退出码非零,「只报数不设阈」这句声明被退出码当场推翻;新增 `INFO` 档,不影响退出码; ⑨`semantic_colors` 未受契约校验 → 数组/字符串在 `.values()` 处直接崩,非法颜色被静默丢成空集,「没报 CVD」分不清是「距离没问题」还是「压根没测」;现校验类型、`#RRGGBB` 语法与 `color_tokens` 子集三项; ⑩`fill="none"` 的描边框被当成卡片底板 → 框住低对比文字的边框把它豁免掉;卡片须为实际填充色; ⑪底色解析不可信时主题检查仍执行 → 圆形/路径/渐变卡片不进 `rects`,「查不到卡片」被当成「文字压在主题底上」,判出假红;改为整条跳过并显式报新谓词 `THEME-UNASSESSED`(未判定必须说成未判定,不能沉默成绿); ⑫两端都没箭头的边按 `d` 的书写顺序被计入流向 → 三条视觉上无向的线仅因端点顺序不同即可触发混合流向;无向边跳过。 **修 ⑧ 时当场炸出探针自身的第二个分母缺陷**:`mutation_probe.sh` 的派生正则只枚举 `ERROR\|WARN` 档, 把一条谓词改成 `INFO` 就让它**静默退出分母**——总数看着没变、覆盖少了一条。 档位改为 `[A-Z]+` 不枚举后为 37/37。**覆盖率的分母若由被测代码的某个属性决定,改那个属性就能无声地让分数变好看**。 **修正后复测**:套件全绿、突变探针 differential_sensitivity=37/37 且 DERIVATION-GAP 无缺口、`make test-repo-gates`=0(含 alias_audit_ok / r0_status=private-ok)。**真实语料复测 55 张 SVG**(非本仓,无契约):`FIGURE-IS-A-LIST` 17、`VALUE-SHOULD-BE-TOKEN` 34、`CVD-*` 0(无契约声明语义色=不测,不是「测过没问题」)、`FLOW-DIRECTION-MIXED` 0——较修正前的 5 条下降,因为 55 张里 45 张含 gradient/非矩形底,几何不可信,那 5 条原本就是拿不可信坐标判出来的。 |
|
|
341
|
+
| 自检触发点漏掉了 gap-list 形态:「列举外部源有而我们没有的」就是 findings 回合,但它读起来像在答覆盖问题,charter-before-findings 从不觉得被触发 | `skill-extraction-workflow` | 自检触发点扩到 gap-list 形态并写明它为何最易滑过;自审纪律补「验证锚点本身可能是错的」——锚点的预期方向若来自你对一手源的解读,该解读是 hypothesis-grade,锚点不过应先质疑锚点而非判实现有 bug; result-class: failure; behavioral-evidence: RED-baseline; observed-failure: yes; firing-path: file:skills/skill-extraction-workflow/SKILL.md#enumerates what an external source has that we lack | `updated` | owner key `skill-extraction-workflow/SKILL.md`。两条均为 **merge 非 append**(并进既有的自检触发点与自审纪律)。**观察到的失败**:①本轮产出四条「外部有我们没有」的缺口清单在先、invoke 提炼工作流在后,而规则明写 charter 要在第一个 findings 回合之前——规则在、没触发,故补触发点而非补规则。②用「红色模拟后应变暗」验 CVD 实现,实测亮度上升;追一手后确认是模拟把红投影到 575nm 黄色不变轴、亮度上升为正确行为,而「红色看起来暗」说的是红与黑难分、是另一个量。**危险在于其余两个锚点通过**——错的尺子量对的实现,比实现出错更难发现。**RED-baseline 差分**:改前的触发点只列举「沉淀 / 提炼 / 复盘 / distil」四种自述措辞,本轮实际产出的是「缺口清单」措辞,逐字不匹配任何一项,故规则在而未触发(本轮即为该差分的观测实例);改后触发点显式含 gap-list 形态。可核对方式:在改前文本上检索本轮的触发措辞得零命中,改后命中。 |
|
|
342
|
+
| 确定性闸对历史形态有前提,而**递给它哪个 ref 是 harness 的选择**:闸按分支自己的一级父链切轮,CI 默认检出的 `refs/pull/N/merge` 的一级父是**目标分支**,于是分支上所有轮塌成一轮,凡「验证依赖本轮很窄」的台账行都会在自己一个字没改的情况下翻红——闸没坏,喂它的历史形态不对 | `skill-extraction-workflow` | 五个跑闸 lane 的 job 全部改为检出分支 head(`ref: pull_request.head.sha \|\| github.sha`,非 PR 事件回落 `github.sha`);新增 `test_ci_checkout_ref_binding.sh` 逐 job 断言该绑定并注册进 fast lane,绑定丢失即闭式失败; result-class: failure; behavioral-evidence: RED-baseline; observed-failure: yes; firing-path: command:skills/skill-extraction-workflow/scripts/test_ci_checkout_ref_binding.sh | `updated` | owner key `skill-extraction-workflow/SKILL.md`(本轮未改其正文,改的是 scripts 与 `.github/workflows/ci.yml`)。**观察到的失败是 CI 实测**:PR #53(dev→main,053–056 四轮 + npm 0.5.0)`repository-gates` 报 `impact_chain_firing_path_missing`(incomplete 点名的是文档技能那个 owner 的入口),`regression-heavy` 两个套件连带红;同一棵树在线性 dev 上闸全绿。055 那轮只改 tighten-doc 的 description、用 `#description` 锚点,该锚点合法的前提是「该 owner 本轮全部 diff 就是 description」;四轮塌成一轮后 tighten-doc 在同一轮里还改了 `references/` 与 `scripts/`,前提失效。**先试过改闸、证否了**:把 round 派生改成「一级父已被 base 包含时走第二个父」,在 merge-ref 树上确实转绿,但打破了 `test_check_ccl_impact_chain_refscripts.sh` 的 round scoping 8——「台账行写在工作提交之前的 worktree 轮必须塌成一个边界」。两种形态在拓扑上**完全相同**(都是 merge X into Y 且 Y==base),git 里没有可区分它们的不变量,而该 fixture 明写 `--first-parent` 是承重的。按仓里对 form 3 的既定裁决(同类复现以删除收束、不再补代理),改的不是闸而是喂给它的 ref。**RED-baseline 是双向差分**:新测试在修好的 workflow 上绿,把 `.github/workflows/ci.yml` 换回 `origin/dev` 版即报三个 job 未绑定。该测试第一次跑就抓到我只改了三个 job、漏了两条 regression lane——**这正是它存在的理由**。**本轮暴露的验证面缺陷**:053–056 四轮我只跑 `make test-repo-gates`、基线取 `origin/dev`;而 CI 的基线是 `origin/main`、检出是 merge ref、还有 fast/heavy 两条 lane——三处都不同,四轮的绿从未覆盖这个形态 |
|
|
@@ -270,7 +270,18 @@ else
|
|
|
270
270
|
end
|
|
271
271
|
' "$root"
|
|
272
272
|
|
|
273
|
-
|
|
273
|
+
# Public DOMAIN word list: a weak-proxy FALLBACK, not the authoritative R0 gate.
|
|
274
|
+
# The real invariant — "this public text identifies one specific organization or
|
|
275
|
+
# project" — is not decidable by a public regex, which is why the private alias
|
|
276
|
+
# audit (ALIAS_AUDIT_CMD -> r0_status=private-ok) is authoritative and this list
|
|
277
|
+
# only covers environments without it. Consequence, stated rather than fought:
|
|
278
|
+
# these terms are ANOTHER domain's ordinary vocabulary, so they decay — a term
|
|
279
|
+
# outlives the project it proxied for and then only produces false positives.
|
|
280
|
+
# Maintain by RETIREMENT, not by growth: when a term no longer proxies anything
|
|
281
|
+
# live, delete it (quantify current hits first, and keep a retained-term control
|
|
282
|
+
# so the scan is proven still able to fail). Do not add generic technical words.
|
|
283
|
+
# Both directions are pinned by test_entrypoint_domain_scan_terms.sh.
|
|
284
|
+
if leak_output="$(rg -n 'code\.[[:alnum:].-]+|figma\.com/files|[0-9]{8,}|\x{6559}\x{5e08}|\x{5b66}\x{751f}|\x{8003}\x{8bd5}|\x{5b66}\x{6821}|\x{9605}\x{5377}|\x{51fa}\x{5377}|\x{5b66}\x{60c5}' "$root"/skills/*/SKILL.md "$root"/skills/*/references/*.md 2>/dev/null)"; then
|
|
274
285
|
echo "$leak_output"
|
|
275
286
|
echo "entrypoint_or_reference_domain_scan_failed" >&2
|
|
276
287
|
exit 1
|
|
@@ -127,6 +127,11 @@ fast_tests=(
|
|
|
127
127
|
test_git_identity_predicate_gate.sh
|
|
128
128
|
test_liveness_predicate_gate.sh
|
|
129
129
|
test_regression_runner_registration.sh
|
|
130
|
+
# Harness binding for the gate lanes themselves: the impact-chain gate's
|
|
131
|
+
# round walk needs the branch's own first-parent chain, which the default
|
|
132
|
+
# refs/pull/N/merge checkout does not provide. Cheap, no clone, and a
|
|
133
|
+
# regression here is otherwise invisible until it refuses an unrelated PR.
|
|
134
|
+
test_ci_checkout_ref_binding.sh
|
|
130
135
|
# Lane-semantics guard for this runner itself (036 challenge P2): proves
|
|
131
136
|
# --heavy-only / --fast / --full each run exactly their lane against a stub
|
|
132
137
|
# fixture via REGRESSION_SCRIPTS_DIR, and that a red heavy stub propagates.
|
|
@@ -142,6 +147,7 @@ fast_tests=(
|
|
|
142
147
|
|
|
143
148
|
heavy_tests=(
|
|
144
149
|
test_check_ccl_r0_status.sh
|
|
150
|
+
test_entrypoint_domain_scan_terms.sh
|
|
145
151
|
test_check_ccl_source_register_lifecycle.sh
|
|
146
152
|
# Clones the whole repo once; impact-chain cases call the standalone gate and
|
|
147
153
|
# retain one full-checker wiring case. Still kept out of the pre-commit lane.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# The gate lane must be judged on the BRANCH, not on the synthetic merge ref.
|
|
3
|
+
#
|
|
4
|
+
# WHY THIS TEST EXISTS. `impact-chain-gate.rb` partitions history into rounds by
|
|
5
|
+
# walking the branch's own first-parent chain. That flag is load-bearing and
|
|
6
|
+
# pinned by its own fixtures (`test_check_ccl_impact_chain_refscripts.sh`, round
|
|
7
|
+
# scoping 8): it is what collapses a merged worktree round to a single boundary
|
|
8
|
+
# when the ledger append precedes the owner work. Dropping it was tried and
|
|
9
|
+
# turned that fixture red.
|
|
10
|
+
#
|
|
11
|
+
# But the walk assumes the first-parent chain IS the branch's history. On the
|
|
12
|
+
# `refs/pull/N/merge` ref that actions/checkout uses by default for a
|
|
13
|
+
# pull_request event, HEAD is a merge whose first parent is the TARGET, so the
|
|
14
|
+
# walk finds only the merge commit and every round on the branch collapses into
|
|
15
|
+
# one. Rows whose validity depends on their round being narrow then flip red
|
|
16
|
+
# with nothing about them changed — observed on PR #53, where a description-only
|
|
17
|
+
# round lost its locator because a sibling round had edited the same owner's
|
|
18
|
+
# body. The two shapes are topologically identical (both are "merge X into Y
|
|
19
|
+
# where Y is the base"), so the gate cannot tell them apart from git alone; the
|
|
20
|
+
# harness has to hand it the right history instead.
|
|
21
|
+
#
|
|
22
|
+
# Hence: every job that runs a gate lane checks out the branch head. This test
|
|
23
|
+
# fails closed if a job loses that binding, because the symptom otherwise shows
|
|
24
|
+
# up as a confusing gate refusal on an unrelated PR months later.
|
|
25
|
+
set -euo pipefail
|
|
26
|
+
|
|
27
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
|
|
28
|
+
ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd -P)"
|
|
29
|
+
CI="$ROOT/.github/workflows/ci.yml"
|
|
30
|
+
[ -f "$CI" ] || { echo "FAIL: workflow not found: $CI" >&2; exit 1; }
|
|
31
|
+
|
|
32
|
+
fail() { echo "FAIL: $*" >&2; exit 1; }
|
|
33
|
+
|
|
34
|
+
# The jobs that run a lane consuming the impact-chain gate. Named explicitly
|
|
35
|
+
# rather than derived: a new gate-running job must be added here deliberately,
|
|
36
|
+
# and a job that stops running gates must be removed deliberately.
|
|
37
|
+
GATE_JOBS="repository-gates regression-fast regression-heavy code-review-regressions-1 code-review-regressions-2"
|
|
38
|
+
|
|
39
|
+
python3 - "$CI" $GATE_JOBS <<'PY'
|
|
40
|
+
import re, sys
|
|
41
|
+
|
|
42
|
+
path, jobs = sys.argv[1], sys.argv[2:]
|
|
43
|
+
src = open(path, encoding="utf8").read()
|
|
44
|
+
|
|
45
|
+
# Split the jobs: mapping stanza at exactly two spaces of indent.
|
|
46
|
+
job_starts = [(m.start(), m.group(1)) for m in re.finditer(r"^ ([A-Za-z0-9_-]+):$", src, re.M)]
|
|
47
|
+
if not job_starts:
|
|
48
|
+
print("FAIL: no jobs parsed out of the workflow", file=sys.stderr)
|
|
49
|
+
sys.exit(1)
|
|
50
|
+
bounds = {}
|
|
51
|
+
for i, (pos, name) in enumerate(job_starts):
|
|
52
|
+
end = job_starts[i + 1][0] if i + 1 < len(job_starts) else len(src)
|
|
53
|
+
bounds[name] = src[pos:end]
|
|
54
|
+
|
|
55
|
+
failures = []
|
|
56
|
+
for job in jobs:
|
|
57
|
+
body = bounds.get(job)
|
|
58
|
+
if body is None:
|
|
59
|
+
failures.append(f"{job}: job not present in the workflow (renamed? then update GATE_JOBS)")
|
|
60
|
+
continue
|
|
61
|
+
if "actions/checkout" not in body:
|
|
62
|
+
failures.append(f"{job}: no checkout step")
|
|
63
|
+
continue
|
|
64
|
+
if "github.event.pull_request.head.sha" not in body:
|
|
65
|
+
failures.append(
|
|
66
|
+
f"{job}: checkout does not pin the branch head — it will run on the "
|
|
67
|
+
f"refs/pull/N/merge ref, where the impact-chain gate's first-parent "
|
|
68
|
+
f"round walk runs through the target and collapses every round into one"
|
|
69
|
+
)
|
|
70
|
+
continue
|
|
71
|
+
# A fallback is required too: on `push` there is no pull_request context, and
|
|
72
|
+
# an empty `ref:` silently checks out the default branch instead of failing.
|
|
73
|
+
if "github.sha" not in body:
|
|
74
|
+
failures.append(f"{job}: head-sha pin has no non-PR fallback (`|| github.sha`)")
|
|
75
|
+
continue
|
|
76
|
+
if "fetch-depth: 0" not in body:
|
|
77
|
+
failures.append(f"{job}: no full history, so the gate cannot resolve its base")
|
|
78
|
+
|
|
79
|
+
if failures:
|
|
80
|
+
for f in failures:
|
|
81
|
+
print(f"FAIL: {f}", file=sys.stderr)
|
|
82
|
+
sys.exit(1)
|
|
83
|
+
PY
|
|
84
|
+
|
|
85
|
+
echo "test_ci_checkout_ref_binding: ok (gate lanes judge the branch head, not the merge ref)"
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Regression test for the entrypoint/reference DOMAIN leak scan inside
|
|
3
|
+
# check-ccl-skills.sh (distinct from generic-r0-leak-scan.sh, which is
|
|
4
|
+
# credential-shaped and has its own suite).
|
|
5
|
+
#
|
|
6
|
+
# Why this exists: that scan's predicate is a list of ANOTHER domain's ordinary
|
|
7
|
+
# vocabulary, so it decays — a term goes stale when the project it proxied for
|
|
8
|
+
# does, and until then it blocks legitimate prose. A term was retired for exactly
|
|
9
|
+
# that reason, and nothing in the repo would have turned red if the retirement
|
|
10
|
+
# had also deleted a live term or the whole scan. This pins both directions.
|
|
11
|
+
#
|
|
12
|
+
# Design: read-only over the real repo (the sibling checker tests' convention).
|
|
13
|
+
# Leg 1 (wiring) : the real checker runs the scan and reports it clean here.
|
|
14
|
+
# Leg 2 (predicate): the retained terms still MATCH — the scan can still fail.
|
|
15
|
+
# Leg 3 (predicate): the retired term does NOT match — the retirement holds.
|
|
16
|
+
# Legs 2-3 read the pattern out of the real script, so they cannot drift away
|
|
17
|
+
# from what ships; extraction failure is a hard error, never a silent pass.
|
|
18
|
+
set -euo pipefail
|
|
19
|
+
|
|
20
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
|
|
21
|
+
CHECK_SCRIPT="$SCRIPT_DIR/check-ccl-skills.sh"
|
|
22
|
+
# scripts -> skill-extraction-workflow -> skills -> repo root
|
|
23
|
+
ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd -P)"
|
|
24
|
+
[ -f "$CHECK_SCRIPT" ] || { echo "FAIL: check script not found: $CHECK_SCRIPT" >&2; exit 1; }
|
|
25
|
+
[ -d "$ROOT/skills" ] || { echo "FAIL: repo root has no skills/ dir: $ROOT" >&2; exit 1; }
|
|
26
|
+
|
|
27
|
+
fail() { echo "FAIL: $*" >&2; exit 1; }
|
|
28
|
+
command -v rg >/dev/null 2>&1 || fail "rg not available; the scan under test needs it"
|
|
29
|
+
|
|
30
|
+
# --- Leg 1: wiring. The scan runs in the real checker and is clean on this tree.
|
|
31
|
+
set +e
|
|
32
|
+
out="$(bash "$CHECK_SCRIPT" "$ROOT" 2>&1)"
|
|
33
|
+
set -e
|
|
34
|
+
case "$out" in
|
|
35
|
+
*entrypoint_and_reference_domain_scan_ok*) : ;;
|
|
36
|
+
*) fail "domain scan did not report clean on the real tree; is it still wired?\n$out" ;;
|
|
37
|
+
esac
|
|
38
|
+
|
|
39
|
+
# --- Extract the shipped pattern (single source of truth: the script itself).
|
|
40
|
+
# lane on an rg built without it, on machines where the checker itself runs fine.
|
|
41
|
+
pattern="$(
|
|
42
|
+
awk 'index($0, "rg -n \047") > 0 {
|
|
43
|
+
rest = substr($0, index($0, "rg -n \047") + 7)
|
|
44
|
+
j = index(rest, "\047 \"$root\""); if (j == 0) next
|
|
45
|
+
print substr(rest, 1, j - 1); exit
|
|
46
|
+
}' "$CHECK_SCRIPT"
|
|
47
|
+
)"
|
|
48
|
+
[ -n "$pattern" ] || fail "could not extract the domain-scan pattern from $CHECK_SCRIPT (line shape changed?)"
|
|
49
|
+
|
|
50
|
+
matches() { # <text> -> rc 0 when the shipped pattern matches
|
|
51
|
+
printf '%s\n' "$1" | rg -q "$pattern"
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
# --- Leg 2: the scan can still fail. Every retained term must match.
|
|
55
|
+
# Written as escapes so this file never carries the literal vocabulary.
|
|
56
|
+
retained=(
|
|
57
|
+
$'教师' $'学生' $'考试' $'学校'
|
|
58
|
+
$'阅卷' $'出卷' $'学情'
|
|
59
|
+
)
|
|
60
|
+
for term in "${retained[@]}"; do
|
|
61
|
+
matches "x ${term} y" || fail "retained domain term no longer matches — the scan was widened/broken, not narrowed"
|
|
62
|
+
done
|
|
63
|
+
# Non-vocabulary alternatives in the same pattern must also still bite.
|
|
64
|
+
matches 'see code.example-host.internal for details' \
|
|
65
|
+
|| fail "host-style leak alternative no longer matches"
|
|
66
|
+
matches 'ref 123456789' || fail "long-digit alternative no longer matches"
|
|
67
|
+
|
|
68
|
+
# --- Leg 3: the retired term must NOT match, in ordinary prose.
|
|
69
|
+
retired=$'扫描'
|
|
70
|
+
! matches "先跑一遍${retired}再判" \
|
|
71
|
+
|| fail "retired term still blocks ordinary prose; the retirement did not land"
|
|
72
|
+
|
|
73
|
+
# --- Leg 4: the checker must still FAIL end-to-end on a planted leak.
|
|
74
|
+
# Legs 1-3 alone cannot see a broken conditional: leg 1 only proves the clean
|
|
75
|
+
# sentinel prints, legs 2-3 exercise the regex in isolation. Without this leg
|
|
76
|
+
# an inverted or bypassed failure branch would keep the whole suite green.
|
|
77
|
+
# Runs against a throwaway --shared clone so the real tree is never written.
|
|
78
|
+
TMP="$(mktemp -d "${TMPDIR:-/tmp}/domscan.XXXXXX")"
|
|
79
|
+
trap 'rm -rf "$TMP"' EXIT
|
|
80
|
+
trap 'exit 130' INT
|
|
81
|
+
trap 'exit 143' TERM
|
|
82
|
+
git clone --shared --quiet "$ROOT" "$TMP/repo" \
|
|
83
|
+
|| fail "could not build the throwaway clone for the end-to-end leg"
|
|
84
|
+
# Control leg on the SAME clone before planting: without it, a removed exit 1
|
|
85
|
+
# plus any unrelated later failure on this clone would still yield non-zero
|
|
86
|
+
# plus the scan's token, and leg 4 would pass on a broken gate.
|
|
87
|
+
set +e
|
|
88
|
+
ctl="$(bash "$CHECK_SCRIPT" "$TMP/repo" 2>&1)"
|
|
89
|
+
ctl_rc=$?
|
|
90
|
+
set -e
|
|
91
|
+
[ "$ctl_rc" -eq 0 ] || fail "clean clone did not pass; leg 4 cannot attribute a failure to the probe\n$ctl"
|
|
92
|
+
case "$ctl" in
|
|
93
|
+
*entrypoint_and_reference_domain_scan_ok*) : ;;
|
|
94
|
+
*) fail "clean clone did not report the domain scan clean; attribution unsafe\n$ctl" ;;
|
|
95
|
+
esac
|
|
96
|
+
probe_dir="$TMP/repo/skills/tighten-doc/references"
|
|
97
|
+
[ -d "$probe_dir" ] || fail "clone has no reference dir to plant the probe in: $probe_dir"
|
|
98
|
+
printf '# probe\n\nx %s y\n' "${retained[0]}" > "$probe_dir/_domain_scan_probe.md"
|
|
99
|
+
set +e
|
|
100
|
+
e2e="$(bash "$CHECK_SCRIPT" "$TMP/repo" 2>&1)"
|
|
101
|
+
e2e_rc=$?
|
|
102
|
+
set -e
|
|
103
|
+
[ "$e2e_rc" -ne 0 ] || fail "checker exited 0 with a planted domain leak — the failure branch does not fire"
|
|
104
|
+
case "$e2e" in
|
|
105
|
+
*entrypoint_or_reference_domain_scan_failed*) : ;;
|
|
106
|
+
*) fail "planted leak did not raise the domain-scan failure token (something else failed first?)\n$e2e" ;;
|
|
107
|
+
esac
|
|
108
|
+
case "$e2e" in
|
|
109
|
+
*_domain_scan_probe.md*) : ;;
|
|
110
|
+
*) fail "failure did not name the planted probe file — attribution is not this leg's scan" ;;
|
|
111
|
+
esac
|
|
112
|
+
# The property worth pinning is NOT "execution stopped at that line" — a black-box
|
|
113
|
+
# test cannot see control flow, and every token-order proxy for it has a hole.
|
|
114
|
+
# It is: a leak in the scanned surface must PREVENT CERTIFICATION. So require the
|
|
115
|
+
# terminal success tokens to be absent; combined with the scan token and the probe
|
|
116
|
+
# filename above, that attributes the withheld certification to this scan.
|
|
117
|
+
case "$e2e" in
|
|
118
|
+
*ccl_skill_check_ok*|*ccl_skill_check_clean_ok*|*ccl_skill_check_interim_ok*)
|
|
119
|
+
fail "checker still certified a tree carrying a planted domain leak" ;;
|
|
120
|
+
*) : ;;
|
|
121
|
+
esac
|
|
122
|
+
|
|
123
|
+
echo "test_entrypoint_domain_scan_terms: ok"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: tighten-doc
|
|
3
|
-
description: "润色文档 / 精简文档 / 改下文档 / AI 味太重 / 废话太多 / polish / make shorter / remove AI tone → finalize wording after substance is settled: clarify, shorten, restructure lightly, preserve decisions, and keep comments safe. Proactively draft a no-owner deliverable doc(「写一份分享/给同事的文档」). Skip while a sibling owns the substance(定稿仍回本技能): spec/PRD/标准 → product-rd-workflow; 技术方案/架构文档 → architecture 技能; 发布文档 → release-doc-writer; 测试用例文档 → test-artifact-management."
|
|
3
|
+
description: "润色文档 / 精简文档 / 改下文档 / AI 味太重 / 废话太多 / polish / make shorter / remove AI tone;**该画时序图还是状态机 / 这里要不要配图 / 图画完了总觉得不对劲说不上哪不对 / 缺图例 / 连线没标签 / 全是表格要不要补图 / 图里字看不清** → finalize wording after substance is settled: clarify, shorten, restructure lightly, preserve decisions, and keep comments safe. Proactively draft a no-owner deliverable doc(「写一份分享/给同事的文档」). 图与表的**表示形式**(图种由主张形态推出、记法硬约束、版式契约、对比度、可跑的检查器)归本技能,**系统边界与架构决策本身仍归架构技能**。Skip while a sibling owns the substance(定稿仍回本技能): spec/PRD/标准 → product-rd-workflow; 技术方案/架构文档 → architecture 技能; 发布文档 → release-doc-writer; 测试用例文档 → test-artifact-management."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# tighten-doc — 文档写作与优化
|
|
@@ -17,7 +17,7 @@ Three modes:
|
|
|
17
17
|
- Rewrite: restructure an existing doc so decisions, owners, gates, and next actions are easier to scan.
|
|
18
18
|
- Tighten: remove filler, duplication, AI tone, meta narration, and over-long sentences without deleting decisions.
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
**先判文档类型,再定形态**:读者是在**用一件已存在的东西**(tutorial / how-to / reference / explanation 四模式),还是要**据此决定或执行一件尚未做完的事**(方案·架构 / 调研 / 现状梳理 / 评审 / 计划)。两轴的判据、每类的首稿必答节、正文与证据分册、图形态,以及「只标记拆分候选、不自行拆分」的收尾边界,见 `references/deliverable-doc-genre-skeletons.md`。一页纸操作手册默认形态对应 how-to / reference,别硬套到其他类型上。
|
|
21
21
|
|
|
22
22
|
For spec/standard/guideline artifacts, the `pre-owner blocked` marker rule applies to all three modes — do not share/publish until the owner marker exists; local wording polish must preserve the blocked label.
|
|
23
23
|
|
|
@@ -59,7 +59,7 @@ owner · 硬规则 · 完成标准/DoD · 里程碑 · 数值阈值 · the real
|
|
|
59
59
|
- **外部基线 / 标准值入文档 = 独立标注 + 命名来源 + 内部门(若有)仍权威。** 引用外部 benchmark、行业阈值、标准默认值(评测目标、性能预算、参考 SLO 等)时,放成独立的列 / 行 / 标注并配命名来源超链,别和本系统自己的验收门 / 阈值混写成同一个数。**当本系统有自己的验收门时**显式声明本系统门为准、外部值只作对标参考(反模式:把外部基线直接当验收标准,读者误以为外部数就是上线门);**若文档本身即标准 / 评测报告 / 无内部门**,则标清来源 / 范围 / 权威,别杜撰一个内部门。**评自己的稿是这条的另一半**:对自己产出的文档评可实测呈现属性(加粗密度、句长、结构层级)前,先建同体裁实测基准——长文或系列交付物在**初稿前**建(写完被纠正后再补测,是实测过的返工形态)——按**预先声明的抽样框与纳排规则**(在实测待评稿自身指标**之前**冻结,防止看完自己的数再挑参照系)取同体裁公开样本(记录样本量、口径与局限;不得挑对自己有利的样本充数,"若干份"本身不构成充分门槛),中英文样本分开统计,把待评稿放进分布里定位;找不到可靠公开样本或体裁不可比时如实记「未对标 + 原因」;流行排版阈值逐条核到一手出处再用,核不到不用。**分布定位的合法输出是描述**("高于/低于所选样本分布"),**不是裁决**:"合适"要再结合读者任务与可用性判断;"优于同类"不得由密度类粗指标推出;无基准时该属性只能报「未对标」——自己的审美不是分布。密度居中更推不出「稿子写得好」:整体质量仍按文档目的、读者任务、事实核验与本 rubric 分轴判断,呈现分布不背书内容正确性。
|
|
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
|
-
- **表达形式匹配内容**:分支关系 / 状态迁移复杂到文字难扫时优先**图**(mermaid 等);字段对比、分桶属性、owner/gate/证据矩阵优先**表**;线性步骤用编号列表;一两点判断一句话或 bullet。别为单个判断加**装饰性**多桶图,但桶间有不同 owner / 阈值 / 例外 /
|
|
62
|
+
- **表达形式匹配内容**:分支关系 / 状态迁移复杂到文字难扫时优先**图**(mermaid 等);字段对比、分桶属性、owner/gate/证据矩阵优先**表**;线性步骤用编号列表;一两点判断一句话或 bullet。别为单个判断加**装饰性**多桶图,但桶间有不同 owner / 阈值 / 例外 / 后果时**必须结构化**(该结构别压成一句)。**目标环境不稳定渲染图时**,文字版流程为准、图只作辅助。**callout / 图内文字 = 概览形态,只承一个要点**:callout 塞成多点密块("一坨")就拆开或降到正文 / 表。**图种由主张形态定**(有事件触发→状态机 / 消息序→时序 / 随完成流转→流程);**画了必须有标题与图例、连线单向且标签具体**;**量级对比别全压进表**。余下见 `references/figure-and-table-craft.md`。
|
|
63
63
|
- **代码进代码块,不进段落**:**多行 / 独立执行步骤 / 长 flag 串命令 / 多命令序列**放代码块(带 lang),不写成段落里的纯文本或一长串内联 `code`。**短的随文 one-liner / 表达式、对照表单元格、「用 `func()`」式符号引用可留 inline**,只要不长到影响扫读(与上面的表格单元格 / 内联引用规则一致,别硬塞进代码块)。多语言对照两端形态对齐——一端给了代码块,另一端别写成「Go:`call(...)`」式内联段落。
|
|
64
64
|
- **Enumeration sections (依赖/兜底/分工/里程碑 子项) = multi-line sub-bullets, NOT a `;`-collapsed single line.** Readability beats compactness here; a `- 依赖:A;B;C;D` run is hard to scan — split to `- 依赖:` + one `- A` sub-bullet per item. Do not collapse to one `;` line just for parity with another card; parity is not a reason to reduce scanability. Single-line `;` is only for a true 2-item short pointer where sub-bullets would be heavier than the content.
|
|
65
65
|
- Table cells that list multiple skills, owners, checks, environments, or evidence items should be split into multiple lines or shorter rows. A readable table beats a compressed cell when the cell is used as an execution checklist.
|
|
@@ -147,7 +147,7 @@ Never destroy collaborative comments. Before editing a collaborative doc, fetch
|
|
|
147
147
|
|
|
148
148
|
**交付前 closeout checklist(阻断项索引,不是通过证书)。** 报「已优化」仍需跑完 Workflow 1-4 + KEEP / decided-point 保全 + 下方 closeout-sweep 全量;本清单只把高频阻断项收敛成可判定的最后一道闸,逐项标 ✓ / N-A、任一未过即不得报已优化(每项指向下方 / FORM 的 canonical 规则,不在此复述全部语义)。发布、同步、commit 前离开生成态,把改过的块当"刚被粘进来"逐行读一遍再判:
|
|
149
149
|
|
|
150
|
-
1. **callout / 图内文字 = 一个要点**:无多点密块(一坨)就拆或降正文 /
|
|
150
|
+
1. **callout / 图内文字 = 一个要点**:无多点密块(一坨)就拆或降正文 / 表;图的形态项过 `figure-and-table-craft.md`。
|
|
151
151
|
2. **管理 / 业务 jargon 对目标读者已 plain-name / gloss**(协议 / API / 字段 / 契约名 + 用户认可的紧凑 `/` `+` 枚举保留;保留项里读者不熟的首次解释)。
|
|
152
152
|
3. **编号连续、父子号同步**;族内同义术语 / label 漂移**全族扫 = 0**。
|
|
153
153
|
4. **图 ↔ 文字无双写**(图承流程、文字留 KEEP 项);外部基线 / 标准值独立列 + 命名来源,门权威按「外部基线」条(有内部门则其为准,无则标清来源不杜撰)。
|