@ccoalm/ccl-skills 0.2.0 → 0.4.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/README.md +12 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/classify_envelope.py +34 -3
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_abort_leak_state_helpers.sh +148 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_classify_envelope.sh +28 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_parse_review_json.sh +7 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_review_gate.sh +13 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_review_gate_abort_leak.sh +271 -34
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/SKILL.md +8 -8
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/eval-routing.md +7 -8
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/extraction-quickstart.md +3 -2
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/harness-patterns-and-eval.md +7 -6
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/recurring-anti-patterns-checklist.md +18 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/source-register.md +29 -2
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/source-to-skill-extraction.md +28 -29
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/check-ccl-skills.sh +153 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/eval-health.rb +23 -10
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/impact-chain-gate.rb +303 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_impact_chain_refscripts.sh +222 -91
- 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_impact_chain_gate_dateless_host.sh +6 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_impact_chain_gate_verdict_differential.sh +1 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_impact_chain_round_attribution.sh +12 -12
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_impact_chain_self_adjudication.sh +455 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_impact_chain_source_refuted.sh +20 -20
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_liveness_predicate_gate.sh +288 -0
- package/dist/assets/release.json +60 -25
- package/dist/cli.js +23 -2
- package/dist/update-notice.d.ts +71 -0
- package/dist/update-notice.js +173 -0
- package/dist/version-check.d.ts +2 -0
- package/dist/version-check.js +7 -0
- package/package.json +1 -1
|
@@ -53,7 +53,7 @@ FIRING_F="firing-path: file:skills/product-rd-workflow/SKILL.md#must record a RE
|
|
|
53
53
|
|
|
54
54
|
# ---- A:合规撤回 —— 有类时必须绿,无类时必须红 ----
|
|
55
55
|
new_case case-a; withdraw_fixture
|
|
56
|
-
add_row "| A fixture claim is refuted by its primary source and is withdrawn wholesale | \`downstream-executor\` | behavioral-evidence: source-refuted; observed-failure: no | \`updated\` | zero-loss: \`$ZLOSS#零损失义务对照\`; refuting source: $SRC; \`product-rd-workflow/SKILL.md\` |"
|
|
56
|
+
add_row "| A fixture claim is refuted by its primary source and is withdrawn wholesale | \`downstream-executor\` | behavioral-evidence: source-refuted; observed-failure: no; result-class: failure | \`updated\` | zero-loss: \`$ZLOSS#零损失义务对照\`; refuting source: $SRC; \`product-rd-workflow/SKILL.md\` |"
|
|
57
57
|
commit_case "case A: compliant source-refuted withdrawal"; run_gate
|
|
58
58
|
# A 的期望值在裁决后由绿改红:该类不再顶起 RED 底线(见 frozen-acceptance.md 的裁决记录)。
|
|
59
59
|
# 合规撤回现在仍然被拦——它要么配一条 RED 行,要么由具名风险 owner 人工放行。
|
|
@@ -62,32 +62,32 @@ commit_case "case A: compliant source-refuted withdrawal"; run_gate
|
|
|
62
62
|
# ---- B:真行为变更披该标签 —— 任何时候都必须红 ----
|
|
63
63
|
new_case case-b
|
|
64
64
|
printf '\n- Every fixture change must obtain approval before it lands.\n' >> "$REPO/$OWNER_REF"
|
|
65
|
-
add_row "| A newly added normative rule wearing the withdrawal label | \`downstream-executor\` | behavioral-evidence: source-refuted; observed-failure: no | \`updated\` | zero-loss: \`$ZLOSS#零损失义务对照\`; refuting source: $SRC; \`product-rd-workflow/SKILL.md\` |"
|
|
65
|
+
add_row "| A newly added normative rule wearing the withdrawal label | \`downstream-executor\` | behavioral-evidence: source-refuted; observed-failure: no; result-class: failure | \`updated\` | zero-loss: \`$ZLOSS#零损失义务对照\`; refuting source: $SRC; \`product-rd-workflow/SKILL.md\` |"
|
|
66
66
|
commit_case "case B: real behaviour change wearing the label"; run_gate
|
|
67
67
|
[ "$RC" != "0" ] && ok "B 真行为变更披标签 -> 仍红" || fail "B 不得通过(净增却用撤回类)"
|
|
68
68
|
|
|
69
69
|
# ---- C:缺一手源 URL —— 必须红 ----
|
|
70
70
|
new_case case-c; withdraw_fixture
|
|
71
|
-
add_row "| A withdrawal whose row cites no refuting source | \`downstream-executor\` | behavioral-evidence: source-refuted; observed-failure: no | \`updated\` | zero-loss: \`$ZLOSS#零损失义务对照\`; \`product-rd-workflow/SKILL.md\` |"
|
|
71
|
+
add_row "| A withdrawal whose row cites no refuting source | \`downstream-executor\` | behavioral-evidence: source-refuted; observed-failure: no; result-class: failure | \`updated\` | zero-loss: \`$ZLOSS#零损失义务对照\`; \`product-rd-workflow/SKILL.md\` |"
|
|
72
72
|
commit_case "case C: missing refuting source"; run_gate
|
|
73
73
|
[ "$RC" != "0" ] && ok "C 缺一手源 -> 仍红" || fail "C 不得通过(无源即无据)"
|
|
74
74
|
|
|
75
75
|
# ---- D:缺零损失指针 —— 必须红 ----
|
|
76
76
|
new_case case-d; withdraw_fixture
|
|
77
|
-
add_row "| A withdrawal whose row carries no zero-loss map | \`downstream-executor\` | behavioral-evidence: source-refuted; observed-failure: no | \`updated\` | refuting source: $SRC; \`product-rd-workflow/SKILL.md\` |"
|
|
77
|
+
add_row "| A withdrawal whose row carries no zero-loss map | \`downstream-executor\` | behavioral-evidence: source-refuted; observed-failure: no; result-class: failure | \`updated\` | refuting source: $SRC; \`product-rd-workflow/SKILL.md\` |"
|
|
78
78
|
commit_case "case D: missing zero-loss pointer"; run_gate
|
|
79
79
|
[ "$RC" != "0" ] && ok "D 缺零损失指针 -> 仍红" || fail "D 不得通过(义务保全无对照)"
|
|
80
80
|
|
|
81
|
-
# ---- E:observed-failure: yes —— 必须红 ----
|
|
81
|
+
# ---- E:observed-failure: yes; result-class: failure —— 必须红 ----
|
|
82
82
|
new_case case-e; withdraw_fixture
|
|
83
|
-
add_row "| A withdrawal self-declaring an observed failure | \`downstream-executor\` | behavioral-evidence: source-refuted; observed-failure: yes | \`updated\` | zero-loss: \`$ZLOSS#零损失义务对照\`; refuting source: $SRC; \`product-rd-workflow/SKILL.md\` |"
|
|
83
|
+
add_row "| A withdrawal self-declaring an observed failure | \`downstream-executor\` | behavioral-evidence: source-refuted; observed-failure: yes; result-class: failure | \`updated\` | zero-loss: \`$ZLOSS#零损失义务对照\`; refuting source: $SRC; \`product-rd-workflow/SKILL.md\` |"
|
|
84
84
|
commit_case "case E: observed-failure yes"; run_gate
|
|
85
|
-
[ "$RC" != "0" ] && ok "E observed-failure: yes -> 仍红" || fail "E 不得通过(分类语义不得自选)"
|
|
85
|
+
[ "$RC" != "0" ] && ok "E observed-failure: yes; result-class: failure -> 仍红" || fail "E 不得通过(分类语义不得自选)"
|
|
86
86
|
|
|
87
87
|
# ---- F:既有类不得回归 ----
|
|
88
88
|
new_case case-f
|
|
89
89
|
printf '\n- Every fixture delivery must record a RED-baseline row before it lands.\n' >> "$REPO/$OWNER_REF"
|
|
90
|
-
add_row "| An ordinary behaviour-changing rule with a RED-baseline row | \`downstream-executor\` | behavioral-evidence: RED-baseline; observed-failure: yes; $FIRING_F | \`updated\` | \`product-rd-workflow/SKILL.md\` |"
|
|
90
|
+
add_row "| An ordinary behaviour-changing rule with a RED-baseline row | \`downstream-executor\` | behavioral-evidence: RED-baseline; observed-failure: yes; result-class: failure; $FIRING_F | \`updated\` | \`product-rd-workflow/SKILL.md\` |"
|
|
91
91
|
commit_case "case F: existing RED-baseline path"; run_gate
|
|
92
92
|
if [ "$RC" = "0" ]; then ok "F 既有 RED-baseline 路径 -> 绿(无回归)"; else echo "--- F 完整输出 ---"; printf '%s\n' "$OUT"; fail "F 回归"; fi
|
|
93
93
|
|
|
@@ -95,8 +95,8 @@ if [ "$RC" = "0" ]; then ok "F 既有 RED-baseline 路径 -> 绿(无回归)"
|
|
|
95
95
|
# 独立评审 REVIEW-1:any? 顶起底线时,真行为变更会搭便车。
|
|
96
96
|
new_case case-g; withdraw_fixture
|
|
97
97
|
printf '\n- Every unrelated fixture delivery must obtain approval before it lands. zzmixedrule\n' >> "$REPO/$OWNER_REF"
|
|
98
|
-
add_row "| A compliant withdrawal alongside an unrelated change | \`downstream-executor\` | behavioral-evidence: source-refuted; observed-failure: no | \`updated\` | zero-loss: \`$ZLOSS#零损失义务对照\`; refuting source: $SRC; \`product-rd-workflow/SKILL.md\` |"
|
|
99
|
-
add_row "| An unrelated behaviour change riding along on a stable-control label | \`downstream-executor\` | behavioral-evidence: semantic-control; observed-failure: no; firing-path: file:skills/product-rd-workflow/SKILL.md#must obtain approval before it lands | \`updated\` | \`product-rd-workflow/SKILL.md\` |"
|
|
98
|
+
add_row "| A compliant withdrawal alongside an unrelated change | \`downstream-executor\` | behavioral-evidence: source-refuted; observed-failure: no; result-class: failure | \`updated\` | zero-loss: \`$ZLOSS#零损失义务对照\`; refuting source: $SRC; \`product-rd-workflow/SKILL.md\` |"
|
|
99
|
+
add_row "| An unrelated behaviour change riding along on a stable-control label | \`downstream-executor\` | behavioral-evidence: semantic-control; observed-failure: no; result-class: failure; firing-path: file:skills/product-rd-workflow/SKILL.md#must obtain approval before it lands | \`updated\` | \`product-rd-workflow/SKILL.md\` |"
|
|
100
100
|
commit_case "case G: mixed rows"; run_gate
|
|
101
101
|
[ "$RC" != "0" ] && ok "G 混合行 -> 仍红" || fail "G 不得通过(真行为变更搭撤回的便车)"
|
|
102
102
|
|
|
@@ -104,21 +104,21 @@ commit_case "case G: mixed rows"; run_gate
|
|
|
104
104
|
# 独立挑战 CHALLENGE-1:删无关文字凑净负、加一条新规则、指针写不存在的锚。
|
|
105
105
|
new_case case-h; withdraw_fixture
|
|
106
106
|
printf '\n- Every smuggled fixture rule must be rejected by the withdrawal class. zzsmuggled\n' >> "$REPO/$OWNER_REF"
|
|
107
|
-
add_row "| A smuggled rule hidden behind an offsetting deletion | \`downstream-executor\` | behavioral-evidence: source-refuted; observed-failure: no | \`updated\` | zero-loss: \`README.md#no-such-anchor-exists-here\`; refuting source: $SRC; \`product-rd-workflow/SKILL.md\` |"
|
|
107
|
+
add_row "| A smuggled rule hidden behind an offsetting deletion | \`downstream-executor\` | behavioral-evidence: source-refuted; observed-failure: no; result-class: failure | \`updated\` | zero-loss: \`README.md#no-such-anchor-exists-here\`; refuting source: $SRC; \`product-rd-workflow/SKILL.md\` |"
|
|
108
108
|
commit_case "case H: offset addition with bogus anchor"; run_gate
|
|
109
109
|
[ "$RC" != "0" ] && ok "H 抵消式新增 + 假锚点 -> 仍红" || fail "H 不得通过(新增规范行 / 锚点不解析)"
|
|
110
110
|
|
|
111
111
|
# ---- I:脚本改动、零删除 —— 必须红(旧代理谓词看不见脚本)----
|
|
112
112
|
new_case case-i
|
|
113
113
|
printf '\n# fixture: an added shell line that changes behaviour without matching any prose predicate\n' >> "$REPO/skills/product-rd-workflow/scripts/check-agent-contract-coverage.sh"
|
|
114
|
-
add_row "| A script change wearing the withdrawal label with nothing deleted | \`downstream-executor\` | behavioral-evidence: source-refuted; observed-failure: no | \`updated\` | zero-loss: \`$ZLOSS#零损失义务对照\`; refuting source: $SRC; \`product-rd-workflow/SKILL.md\` |"
|
|
114
|
+
add_row "| A script change wearing the withdrawal label with nothing deleted | \`downstream-executor\` | behavioral-evidence: source-refuted; observed-failure: no; result-class: failure | \`updated\` | zero-loss: \`$ZLOSS#零损失义务对照\`; refuting source: $SRC; \`product-rd-workflow/SKILL.md\` |"
|
|
115
115
|
commit_case "case I: script change, no deletion"; run_gate
|
|
116
116
|
[ "$RC" != "0" ] && ok "I 脚本改动零删除 -> 仍红" || fail "I 不得通过(非 .md、且无删除)"
|
|
117
117
|
|
|
118
118
|
# ---- J:`Always` 规则、零删除 —— 必须红(旧谓词故意排除 always)----
|
|
119
119
|
new_case case-j
|
|
120
120
|
printf '\n- Always authenticate fixture requests before dispatch.\n' >> "$REPO/$OWNER_REF"
|
|
121
|
-
add_row "| An Always-phrased rule wearing the withdrawal label with nothing deleted | \`downstream-executor\` | behavioral-evidence: source-refuted; observed-failure: no | \`updated\` | zero-loss: \`$ZLOSS#零损失义务对照\`; refuting source: $SRC; \`product-rd-workflow/SKILL.md\` |"
|
|
121
|
+
add_row "| An Always-phrased rule wearing the withdrawal label with nothing deleted | \`downstream-executor\` | behavioral-evidence: source-refuted; observed-failure: no; result-class: failure | \`updated\` | zero-loss: \`$ZLOSS#零损失义务对照\`; refuting source: $SRC; \`product-rd-workflow/SKILL.md\` |"
|
|
122
122
|
commit_case "case J: Always rule, no deletion"; run_gate
|
|
123
123
|
[ "$RC" != "0" ] && ok "J Always 规则零删除 -> 仍红" || fail "J 不得通过(有新增行)"
|
|
124
124
|
|
|
@@ -126,33 +126,33 @@ commit_case "case J: Always rule, no deletion"; run_gate
|
|
|
126
126
|
# 独立评审:chmod 在 --name-status 里显示为 M、在 --numstat 里记 0/0。
|
|
127
127
|
new_case case-k; withdraw_fixture
|
|
128
128
|
chmod 755 "$REPO/skills/product-rd-workflow/references/adr-convention.md"
|
|
129
|
-
add_row "| A mode change riding along with a genuine deletion | \`downstream-executor\` | behavioral-evidence: source-refuted; observed-failure: no | \`updated\` | zero-loss: \`$ZLOSS#零损失义务对照\`; refuting source: $SRC; \`product-rd-workflow/SKILL.md\` |"
|
|
129
|
+
add_row "| A mode change riding along with a genuine deletion | \`downstream-executor\` | behavioral-evidence: source-refuted; observed-failure: no; result-class: failure | \`updated\` | zero-loss: \`$ZLOSS#零损失义务对照\`; refuting source: $SRC; \`product-rd-workflow/SKILL.md\` |"
|
|
130
130
|
commit_case "case K: chmod plus deletion"; run_gate
|
|
131
131
|
[ "$RC" != "0" ] && ok "K 改权限 + 删除 -> 仍红" || fail "K 不得通过(mode 变更未被 numstat 反映)"
|
|
132
132
|
|
|
133
133
|
# ---- L:指针路径穿越出仓 —— 必须红 ----
|
|
134
134
|
new_case case-l; withdraw_fixture
|
|
135
|
-
add_row "| A withdrawal whose zero-loss pointer escapes the repository | \`downstream-executor\` | behavioral-evidence: source-refuted; observed-failure: no | \`updated\` | zero-loss: \`../../../etc/hosts#localhost\`; refuting source: $SRC; \`product-rd-workflow/SKILL.md\` |"
|
|
135
|
+
add_row "| A withdrawal whose zero-loss pointer escapes the repository | \`downstream-executor\` | behavioral-evidence: source-refuted; observed-failure: no; result-class: failure | \`updated\` | zero-loss: \`../../../etc/hosts#localhost\`; refuting source: $SRC; \`product-rd-workflow/SKILL.md\` |"
|
|
136
136
|
commit_case "case L: traversal pointer"; run_gate
|
|
137
137
|
[ "$RC" != "0" ] && ok "L 指针穿越出仓 -> 仍红" || fail "L 不得通过(路径逃出仓库)"
|
|
138
138
|
|
|
139
139
|
# ---- M:锚点是存在但无意义的单字符子串 —— 必须红 ----
|
|
140
140
|
new_case case-m; withdraw_fixture
|
|
141
|
-
add_row "| A withdrawal whose anchor is a bare existing substring | \`downstream-executor\` | behavioral-evidence: source-refuted; observed-failure: no | \`updated\` | zero-loss: \`$ZLOSS#a\`; refuting source: $SRC; \`product-rd-workflow/SKILL.md\` |"
|
|
141
|
+
add_row "| A withdrawal whose anchor is a bare existing substring | \`downstream-executor\` | behavioral-evidence: source-refuted; observed-failure: no; result-class: failure | \`updated\` | zero-loss: \`$ZLOSS#a\`; refuting source: $SRC; \`product-rd-workflow/SKILL.md\` |"
|
|
142
142
|
commit_case "case M: one-character substring anchor"; run_gate
|
|
143
143
|
[ "$RC" != "0" ] && ok "M 单字符子串锚 -> 仍红" || fail "M 不得通过(锚点未落在标题上)"
|
|
144
144
|
|
|
145
145
|
# ---- N:锚点是存在但不相干的整词 —— 必须红 ----
|
|
146
146
|
new_case case-n; withdraw_fixture
|
|
147
|
-
add_row "| A withdrawal whose anchor is an unrelated existing word | \`downstream-executor\` | behavioral-evidence: source-refuted; observed-failure: no | \`updated\` | zero-loss: \`$ZLOSS#survives-verbatim\`; refuting source: $SRC; \`product-rd-workflow/SKILL.md\` |"
|
|
147
|
+
add_row "| A withdrawal whose anchor is an unrelated existing word | \`downstream-executor\` | behavioral-evidence: source-refuted; observed-failure: no; result-class: failure | \`updated\` | zero-loss: \`$ZLOSS#survives-verbatim\`; refuting source: $SRC; \`product-rd-workflow/SKILL.md\` |"
|
|
148
148
|
commit_case "case N: unrelated existing substring anchor"; run_gate
|
|
149
149
|
[ "$RC" != "0" ] && ok "N 不相干整词锚 -> 仍红" || fail "N 不得通过(锚点未落在标题上)"
|
|
150
150
|
|
|
151
151
|
# ---- O:既有 semantic-control 路径不得回归(配对 RED 行)----
|
|
152
152
|
new_case case-o
|
|
153
153
|
printf '\n- Every fixture control rule must be recorded before it lands. zzsemctl\n' >> "$REPO/$OWNER_REF"
|
|
154
|
-
add_row "| An unchanged control alongside a RED-baseline row | \`downstream-executor\` | behavioral-evidence: semantic-control; observed-failure: no; firing-path: file:skills/product-rd-workflow/SKILL.md#must be recorded before it lands | \`updated\` | \`product-rd-workflow/SKILL.md\` |"
|
|
155
|
-
add_row "| The behaviour change the control accompanies | \`downstream-executor\` | behavioral-evidence: RED-baseline; observed-failure: yes; firing-path: file:skills/product-rd-workflow/SKILL.md#must be recorded before it lands | \`updated\` | \`product-rd-workflow/SKILL.md\` |"
|
|
154
|
+
add_row "| An unchanged control alongside a RED-baseline row | \`downstream-executor\` | behavioral-evidence: semantic-control; observed-failure: no; result-class: failure; firing-path: file:skills/product-rd-workflow/SKILL.md#must be recorded before it lands | \`updated\` | \`product-rd-workflow/SKILL.md\` |"
|
|
155
|
+
add_row "| The behaviour change the control accompanies | \`downstream-executor\` | behavioral-evidence: RED-baseline; observed-failure: yes; result-class: failure; firing-path: file:skills/product-rd-workflow/SKILL.md#must be recorded before it lands | \`updated\` | \`product-rd-workflow/SKILL.md\` |"
|
|
156
156
|
commit_case "case O: semantic-control beside RED-baseline"; run_gate
|
|
157
157
|
[ "$RC" = "0" ] && ok "O semantic-control + RED-baseline -> 绿(无回归)" || { echo "--- O ---"; printf '%s\n' "$OUT" | tail -3; fail "O 既有路径回归"; }
|
|
158
158
|
|
|
@@ -163,7 +163,7 @@ import io,sys
|
|
|
163
163
|
p=sys.argv[1]
|
|
164
164
|
io.open(p,'w',encoding='utf-8').write("# 零损失义务对照\n\n| before 义务 | 去向 |\n| --- | --- |\n| 某条义务 | survives-verbatim: 别处 |\n")
|
|
165
165
|
PYP
|
|
166
|
-
add_row "| A withdrawal whose map does not quote what was removed | \`downstream-executor\` | behavioral-evidence: source-refuted; observed-failure: no | \`updated\` | zero-loss: \`$ZLOSS#零损失义务对照\`; refuting source: $SRC; \`product-rd-workflow/SKILL.md\` |"
|
|
166
|
+
add_row "| A withdrawal whose map does not quote what was removed | \`downstream-executor\` | behavioral-evidence: source-refuted; observed-failure: no; result-class: failure | \`updated\` | zero-loss: \`$ZLOSS#零损失义务对照\`; refuting source: $SRC; \`product-rd-workflow/SKILL.md\` |"
|
|
167
167
|
commit_case "case P: map does not account for deleted text"; run_gate
|
|
168
168
|
[ "$RC" != "0" ] && ok "P 对照表未逐字交代被删内容 -> 仍红" || fail "P 不得通过(删了什么没抄出来)"
|
|
169
169
|
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Behavior suite for check-ccl-skills.sh's `liveness_predicate_scan` gate
|
|
3
|
+
# (recurring-anti-patterns-checklist.md, Anti-pattern 28).
|
|
4
|
+
#
|
|
5
|
+
# The gate exists because an existence-test liveness predicate fails in the direction
|
|
6
|
+
# that looks like a real defect: the probe reds, names the code under test, and the code
|
|
7
|
+
# under test was fine. Its value therefore rests on two properties that must BOTH be
|
|
8
|
+
# pinned — it fires on the shape that actually shipped, and it stays silent on the
|
|
9
|
+
# legitimate spellings. A gate that also flagged a ppid read used to identify a parent,
|
|
10
|
+
# or the fix's own documentation, is one a later maintainer loosens after the first false
|
|
11
|
+
# positive, and a loosened gate catches nothing.
|
|
12
|
+
#
|
|
13
|
+
# bash skills/skill-extraction-workflow/scripts/test_liveness_predicate_gate.sh
|
|
14
|
+
set -u
|
|
15
|
+
|
|
16
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
|
|
17
|
+
CHECKER="${CHECKER:-$SCRIPT_DIR/check-ccl-skills.sh}"
|
|
18
|
+
[ -f "$CHECKER" ] || { echo "FAIL: checker not found: $CHECKER" >&2; exit 1; }
|
|
19
|
+
|
|
20
|
+
pass=0; fail=0
|
|
21
|
+
note() { fail=$((fail+1)); printf 'FAIL %s\n' "$1" >&2; }
|
|
22
|
+
ok() { pass=$((pass+1)); }
|
|
23
|
+
|
|
24
|
+
TMP=$(mktemp -d "${TMPDIR:-/tmp}/liveness-gate-test.XXXXXX") || exit 1
|
|
25
|
+
TMP=$(cd "$TMP" && pwd -P)
|
|
26
|
+
trap 'rm -rf "$TMP"' EXIT
|
|
27
|
+
|
|
28
|
+
# Run the gate section in isolation rather than standing up a whole synthetic skill tree.
|
|
29
|
+
section=$TMP/gate-section.sh
|
|
30
|
+
{
|
|
31
|
+
echo '#!/usr/bin/env bash'
|
|
32
|
+
# MUST match the host checker's options, or a section that aborts the real checker
|
|
33
|
+
# still passes every probe here.
|
|
34
|
+
echo 'set -euo pipefail'
|
|
35
|
+
echo 'root="$1"'
|
|
36
|
+
awk '/^# Anti-pattern 28 —/{p=1} p; /^echo "liveness_predicate_scan_ok"$/{if(p) exit}' "$CHECKER"
|
|
37
|
+
} > "$section"
|
|
38
|
+
grep -q 'liveness_predicate_scan_ok' "$section" \
|
|
39
|
+
|| { echo "FAIL: could not extract the gate section from $CHECKER (anchor moved?)" >&2; exit 1; }
|
|
40
|
+
grep -q 'ppid=' "$section" \
|
|
41
|
+
|| { echo "FAIL: extracted section carries no predicate — extraction is bogus" >&2; exit 1; }
|
|
42
|
+
|
|
43
|
+
run_gate() { # run_gate <root> -> RC, OUT
|
|
44
|
+
OUT=$( bash "$section" "$1" 2>&1 ); RC=$?
|
|
45
|
+
}
|
|
46
|
+
mk_root() { local r="$TMP/$1"; mkdir -p "$r/scripts"; printf '%s' "$r"; }
|
|
47
|
+
|
|
48
|
+
# The banned spelling is assembled at runtime, never written literally in this file:
|
|
49
|
+
# this suite is itself a `test_*.sh` inside the scanned tree, so a literal would make the
|
|
50
|
+
# repo's own gate flag its regression test. (The scanner-matches-itself trap.)
|
|
51
|
+
PPID_READ='ps -o ppid= -p "$pid"'
|
|
52
|
+
VIOLATION='[ "$('"$PPID_READ"' 2>/dev/null | tr -d " ")" = "1" ] && echo orphan'
|
|
53
|
+
|
|
54
|
+
# --- P1: a clean tree passes ------------------------------------------------
|
|
55
|
+
r=$(mk_root clean)
|
|
56
|
+
printf '#!/usr/bin/env bash\necho hello\n' > "$r/scripts/test_clean.sh"
|
|
57
|
+
run_gate "$r"
|
|
58
|
+
if [ "$RC" -eq 0 ] && printf '%s' "$OUT" | grep -q 'liveness_predicate_scan_ok'; then ok
|
|
59
|
+
else note "p1 clean tree must pass with the ok token (rc=$RC): $OUT"; fi
|
|
60
|
+
|
|
61
|
+
# --- P2: the violation fires (the gate's whole reason to exist) -------------
|
|
62
|
+
r=$(mk_root violation)
|
|
63
|
+
printf '#!/usr/bin/env bash\n%s\n' "$VIOLATION" > "$r/scripts/test_probe.sh"
|
|
64
|
+
run_gate "$r"
|
|
65
|
+
if [ "$RC" -ne 0 ] && printf '%s' "$OUT" | grep -q 'liveness_predicate_scan_failed'; then ok
|
|
66
|
+
else note "p2 planted orphan-oracle must FAIL the gate (rc=$RC): $OUT"; fi
|
|
67
|
+
|
|
68
|
+
# --- P2b: the report names the offending file and line ----------------------
|
|
69
|
+
if printf '%s' "$OUT" | grep -q 'scripts/test_probe.sh:2'; then ok
|
|
70
|
+
else note "p2b failure output must locate the hit (file:line), got: $OUT"; fi
|
|
71
|
+
|
|
72
|
+
# --- P2c: the hit and the diagnosis must not run together on one line -------
|
|
73
|
+
# The sorted-hit list loses its trailing newline to command substitution; without an
|
|
74
|
+
# explicit one the last hit and the message concatenate and neither greps cleanly.
|
|
75
|
+
if printf '%s' "$OUT" | grep -q '^liveness_predicate_scan_failed'; then ok
|
|
76
|
+
else note "p2c the diagnosis must start its own line, got: $OUT"; fi
|
|
77
|
+
|
|
78
|
+
# --- P3: consulting process state clears it (this IS the documented fix) ----
|
|
79
|
+
r=$(mk_root fixed)
|
|
80
|
+
{ printf '#!/usr/bin/env bash\n'
|
|
81
|
+
printf 'st="$(ps -o stat= -p "$pid")"\n'
|
|
82
|
+
printf '%s\n' "$VIOLATION"
|
|
83
|
+
} > "$r/scripts/test_probe.sh"
|
|
84
|
+
run_gate "$r"
|
|
85
|
+
if [ "$RC" -eq 0 ]; then ok
|
|
86
|
+
else note "p3 a state consult within the window must clear the line (rc=$RC): $OUT"; fi
|
|
87
|
+
|
|
88
|
+
# --- P3b: a *_state helper THIS FILE DEFINES over process state clears it ---
|
|
89
|
+
# The real fix's shape: one helper, defined in the same file, reading `ps -o stat=`.
|
|
90
|
+
r=$(mk_root fixed_helper)
|
|
91
|
+
{ printf '#!/usr/bin/env bash\n'
|
|
92
|
+
printf 'wrapper_state() {\n ps -o stat= -p "$1"\n}\n'
|
|
93
|
+
printf 'case "$(wrapper_state "$pid")" in live) : ;; esac\n'
|
|
94
|
+
printf '%s\n' "$VIOLATION"
|
|
95
|
+
} > "$r/scripts/test_probe.sh"
|
|
96
|
+
run_gate "$r"
|
|
97
|
+
if [ "$RC" -eq 0 ]; then ok
|
|
98
|
+
else note "p3b a file-defined state helper must clear the line (rc=$RC): $OUT"; fi
|
|
99
|
+
|
|
100
|
+
# --- P3c: an unrelated *_state call is NOT remediation ----------------------
|
|
101
|
+
# Found by adversarial review: accepting any `*_state` token let a bookkeeping helper
|
|
102
|
+
# that never reads process state clear a real hit, so the blocking gate printed ok.
|
|
103
|
+
r=$(mk_root fake_helper)
|
|
104
|
+
{ printf '#!/usr/bin/env bash\n'
|
|
105
|
+
printf 'record_state "$other_pid"\n'
|
|
106
|
+
printf '%s\n' "$VIOLATION"
|
|
107
|
+
} > "$r/scripts/test_probe.sh"
|
|
108
|
+
run_gate "$r"
|
|
109
|
+
if [ "$RC" -ne 0 ] && printf '%s' "$OUT" | grep -q 'liveness_predicate_scan_failed'; then ok
|
|
110
|
+
else note "p3c an unrelated *_state call must NOT clear the violation (rc=$RC): $OUT"; fi
|
|
111
|
+
|
|
112
|
+
# --- P3d: a defined helper that does NOT read process state is not remediation
|
|
113
|
+
r=$(mk_root hollow_helper)
|
|
114
|
+
{ printf '#!/usr/bin/env bash\n'
|
|
115
|
+
printf 'record_state() {\n echo "$1" >>"$log"\n}\n'
|
|
116
|
+
printf 'record_state "$other_pid"\n'
|
|
117
|
+
printf '%s\n' "$VIOLATION"
|
|
118
|
+
} > "$r/scripts/test_probe.sh"
|
|
119
|
+
run_gate "$r"
|
|
120
|
+
if [ "$RC" -ne 0 ]; then ok
|
|
121
|
+
else note "p3d a defined helper that never reads process state must not clear it (rc=$RC): $OUT"; fi
|
|
122
|
+
|
|
123
|
+
# --- P4: a whole-line comment carrying the spelling is documentation --------
|
|
124
|
+
# The checklist row and the gate's own comment block name the banned spelling; a gate
|
|
125
|
+
# that flags its own documentation gets loosened.
|
|
126
|
+
r=$(mk_root commented)
|
|
127
|
+
printf '#!/usr/bin/env bash\n# %s\n' "$VIOLATION" > "$r/scripts/test_doc.sh"
|
|
128
|
+
run_gate "$r"
|
|
129
|
+
if [ "$RC" -eq 0 ]; then ok
|
|
130
|
+
else note "p4 a whole-line comment must not be flagged (rc=$RC): $OUT"; fi
|
|
131
|
+
|
|
132
|
+
# --- P5: scope is test scripts — a signalling guard elsewhere is legitimate --
|
|
133
|
+
# Outside a test, asking whether a pid exists before signalling it is the right
|
|
134
|
+
# question; flagging it would trade a real false-positive cost for nothing.
|
|
135
|
+
r=$(mk_root nontest)
|
|
136
|
+
printf '#!/usr/bin/env bash\n%s\n' "$VIOLATION" > "$r/scripts/helper.sh"
|
|
137
|
+
run_gate "$r"
|
|
138
|
+
if [ "$RC" -eq 0 ]; then ok
|
|
139
|
+
else note "p5 non-test shell is out of scope and must not fire (rc=$RC): $OUT"; fi
|
|
140
|
+
|
|
141
|
+
# --- P6: a ppid read that IDENTIFIES a parent is not an orphan oracle -------
|
|
142
|
+
# The common, correct use. Flagging it is what would make precision collapse.
|
|
143
|
+
r=$(mk_root identify)
|
|
144
|
+
{ printf '#!/usr/bin/env bash\n'
|
|
145
|
+
printf 'parent="$(%s 2>/dev/null | tr -d " ")"\n' "$PPID_READ"
|
|
146
|
+
printf 'cmd="$(ps -o command= -p "$parent")"\n'
|
|
147
|
+
} > "$r/scripts/test_identify.sh"
|
|
148
|
+
run_gate "$r"
|
|
149
|
+
if [ "$RC" -eq 0 ]; then ok
|
|
150
|
+
else note "p6 a ppid read used for parent identity must not fire (rc=$RC): $OUT"; fi
|
|
151
|
+
|
|
152
|
+
# --- P7: a COMMENT naming the helper must not clear a real violation ---------
|
|
153
|
+
# The waiver has to be code that consults process state, not a note saying someone
|
|
154
|
+
# should. Found by adversarial review of this gate: the window grep read raw text, so a
|
|
155
|
+
# TODO beside the violation made the blocking checker print ok for a line it had found.
|
|
156
|
+
r=$(mk_root comment_waiver)
|
|
157
|
+
{ printf '#!/usr/bin/env bash\n'
|
|
158
|
+
printf '# TODO: use wrapper_state here instead\n'
|
|
159
|
+
printf '%s\n' "$VIOLATION"
|
|
160
|
+
} > "$r/scripts/test_probe.sh"
|
|
161
|
+
run_gate "$r"
|
|
162
|
+
if [ "$RC" -ne 0 ] && printf '%s' "$OUT" | grep -q 'liveness_predicate_scan_failed'; then ok
|
|
163
|
+
else note "p7 a comment mentioning the helper must NOT clear the violation (rc=$RC): $OUT"; fi
|
|
164
|
+
|
|
165
|
+
# --- P8: parameter expansion carrying '#' must not be mistaken for a comment --
|
|
166
|
+
# Stripping trailing comments with a naive `#`-to-end rule would truncate `${var#pre}`
|
|
167
|
+
# and could drop the real state consult that follows it, turning the fix into a hit.
|
|
168
|
+
r=$(mk_root hash_expansion)
|
|
169
|
+
{ printf '#!/usr/bin/env bash\n'
|
|
170
|
+
printf 'rel="${path#"$root"/}"; st="$(ps -o stat= -p "$pid")"\n'
|
|
171
|
+
printf '%s\n' "$VIOLATION"
|
|
172
|
+
} > "$r/scripts/test_probe.sh"
|
|
173
|
+
run_gate "$r"
|
|
174
|
+
if [ "$RC" -eq 0 ]; then ok
|
|
175
|
+
else note "p8 a '#' inside parameter expansion must not void the state consult (rc=$RC): $OUT"; fi
|
|
176
|
+
|
|
177
|
+
# --- P9: the NEGATED assertion is the opposite check and must not fire ------
|
|
178
|
+
# `!= "1"` asserts a process is NOT reparented. An unrestricted `.*=` in the predicate
|
|
179
|
+
# swallowed the `!`, so the gate flagged the very check that does the right thing —
|
|
180
|
+
# found by adversarial review, and the false-positive direction this gate must avoid.
|
|
181
|
+
r=$(mk_root negated)
|
|
182
|
+
{ printf '#!/usr/bin/env bash\n'
|
|
183
|
+
printf '[ "$(%s 2>/dev/null | tr -d " ")" != "1" ] && echo still-parented\n' "$PPID_READ"
|
|
184
|
+
} > "$r/scripts/test_probe.sh"
|
|
185
|
+
run_gate "$r"
|
|
186
|
+
if [ "$RC" -eq 0 ]; then ok
|
|
187
|
+
else note "p9 a negated ppid assertion must NOT fire (rc=$RC): $OUT"; fi
|
|
188
|
+
|
|
189
|
+
# --- P9b: the positive oracle still fires with the tightened operator match --
|
|
190
|
+
# Guards the tightening itself: narrowing the operator must not blunt the real catch.
|
|
191
|
+
r=$(mk_root still_fires)
|
|
192
|
+
printf '#!/usr/bin/env bash\n%s\n' "$VIOLATION" > "$r/scripts/test_probe.sh"
|
|
193
|
+
run_gate "$r"
|
|
194
|
+
if [ "$RC" -ne 0 ] && printf '%s' "$OUT" | grep -q 'liveness_predicate_scan_failed'; then ok
|
|
195
|
+
else note "p9b the real orphan oracle must still fire after tightening (rc=$RC): $OUT"; fi
|
|
196
|
+
|
|
197
|
+
# --- P10: a bare `stat=` assignment is not a process-state read ---------------
|
|
198
|
+
# Found by adversarial review: the waiver grepped bare `stat=`, so an unrelated
|
|
199
|
+
# assignment two lines away cleared a genuine hit and the blocking gate printed ok.
|
|
200
|
+
r=$(mk_root fake_stat)
|
|
201
|
+
{ printf '#!/usr/bin/env bash\n'
|
|
202
|
+
printf 'stat=unknown\n'
|
|
203
|
+
printf '%s\n' "$VIOLATION"
|
|
204
|
+
} > "$r/scripts/test_probe.sh"
|
|
205
|
+
run_gate "$r"
|
|
206
|
+
if [ "$RC" -ne 0 ] && printf '%s' "$OUT" | grep -q 'liveness_predicate_scan_failed'; then ok
|
|
207
|
+
else note "p10 a bare stat= assignment must NOT clear the violation (rc=$RC): $OUT"; fi
|
|
208
|
+
|
|
209
|
+
# --- P10b: the genuine `ps -o stat=` read still clears it --------------------
|
|
210
|
+
r=$(mk_root real_stat)
|
|
211
|
+
{ printf '#!/usr/bin/env bash\n'
|
|
212
|
+
printf 'st="$(ps -o stat= -p "$pid")"\n'
|
|
213
|
+
printf '%s\n' "$VIOLATION"
|
|
214
|
+
} > "$r/scripts/test_probe.sh"
|
|
215
|
+
run_gate "$r"
|
|
216
|
+
if [ "$RC" -eq 0 ]; then ok
|
|
217
|
+
else note "p10b a real ps -o stat= read must still clear the line (rc=$RC): $OUT"; fi
|
|
218
|
+
|
|
219
|
+
# --- P11: a HOLLOW helper plus an unrelated state read elsewhere is not a fix --
|
|
220
|
+
# Found by adversarial review: "the file defines *_state" and "the file reads process
|
|
221
|
+
# state somewhere" were checked independently, so the two were never tied together and a
|
|
222
|
+
# do-nothing helper borrowed an unrelated read to clear a real hit.
|
|
223
|
+
r=$(mk_root hollow_plus_elsewhere)
|
|
224
|
+
{ printf '#!/usr/bin/env bash\n'
|
|
225
|
+
printf 'wrapper_state() {\n echo unknown\n}\n'
|
|
226
|
+
printf 'other() {\n ps -o stat= -p "$1"\n}\n'
|
|
227
|
+
printf 'case "$(wrapper_state "$pid")" in live) : ;; esac\n'
|
|
228
|
+
printf '%s\n' "$VIOLATION"
|
|
229
|
+
} > "$r/scripts/test_probe.sh"
|
|
230
|
+
run_gate "$r"
|
|
231
|
+
if [ "$RC" -ne 0 ] && printf '%s' "$OUT" | grep -q 'liveness_predicate_scan_failed'; then ok
|
|
232
|
+
else note "p11 a hollow helper must NOT borrow an unrelated state read (rc=$RC): $OUT"; fi
|
|
233
|
+
|
|
234
|
+
# --- P12: a ONE-LINE hollow helper must not borrow a later function's read -----
|
|
235
|
+
# Found by the adversarial challenge: the awk rule set inbody and ran `next`, so a
|
|
236
|
+
# definition that opens and closes on one line never met its `}` and stayed "in body"
|
|
237
|
+
# across the following functions, crediting their state read to the hollow helper.
|
|
238
|
+
r=$(mk_root oneline_hollow)
|
|
239
|
+
{ printf '#!/usr/bin/env bash\n'
|
|
240
|
+
printf 'wrapper_state() { echo live; }\n'
|
|
241
|
+
printf 'other() {\n ps -o stat= -p "$other_pid"\n}\n'
|
|
242
|
+
printf 'case "$(wrapper_state "$pid")" in live) : ;; esac\n'
|
|
243
|
+
printf '%s\n' "$VIOLATION"
|
|
244
|
+
} > "$r/scripts/test_probe.sh"
|
|
245
|
+
run_gate "$r"
|
|
246
|
+
if [ "$RC" -ne 0 ] && printf '%s' "$OUT" | grep -q 'liveness_predicate_scan_failed'; then ok
|
|
247
|
+
else note "p12 a one-line hollow helper must NOT borrow a later read (rc=$RC): $OUT"; fi
|
|
248
|
+
|
|
249
|
+
# --- P12b: a genuine ONE-LINE helper that does read state still clears it ------
|
|
250
|
+
r=$(mk_root oneline_real)
|
|
251
|
+
{ printf '#!/usr/bin/env bash\n'
|
|
252
|
+
printf 'wrapper_state() { ps -o stat= -p "$1"; }\n'
|
|
253
|
+
printf 'case "$(wrapper_state "$pid")" in live) : ;; esac\n'
|
|
254
|
+
printf '%s\n' "$VIOLATION"
|
|
255
|
+
} > "$r/scripts/test_probe.sh"
|
|
256
|
+
run_gate "$r"
|
|
257
|
+
if [ "$RC" -eq 0 ]; then ok
|
|
258
|
+
else note "p12b a real one-line state helper must clear the line (rc=$RC): $OUT"; fi
|
|
259
|
+
|
|
260
|
+
# --- P13/P14: the DOCUMENTED limit, pinned rather than left in prose -----------
|
|
261
|
+
# These two assert the gate does NOT fire, which is a hole, not a feature: a state read
|
|
262
|
+
# of a different pid, or one whose result is discarded, still clears the window. Proving
|
|
263
|
+
# a read GOVERNS the verdict needs dataflow over a parsed shell, so the mechanical gate
|
|
264
|
+
# stops here by design (recurring-anti-patterns-checklist.md, Anti-pattern 28).
|
|
265
|
+
# They are here so the limit is exercised, not merely described: if a future change makes
|
|
266
|
+
# the gate stricter these go red, and whoever tightened it must update the checklist
|
|
267
|
+
# rather than discover the prose had silently gone stale.
|
|
268
|
+
r=$(mk_root limit_other_pid)
|
|
269
|
+
{ printf '#!/usr/bin/env bash\n'
|
|
270
|
+
printf 'ps -o stat= -p "$other_pid" >/dev/null\n'
|
|
271
|
+
printf '%s\n' "$VIOLATION"
|
|
272
|
+
} > "$r/scripts/test_probe.sh"
|
|
273
|
+
run_gate "$r"
|
|
274
|
+
if [ "$RC" -eq 0 ]; then ok
|
|
275
|
+
else note "p13 KNOWN LIMIT CHANGED: a different-pid state read now fires — update the checklist (rc=$RC)"; fi
|
|
276
|
+
|
|
277
|
+
r=$(mk_root limit_discarded)
|
|
278
|
+
{ printf '#!/usr/bin/env bash\n'
|
|
279
|
+
printf 'ps -o stat= -p "$pid" >/dev/null\n'
|
|
280
|
+
printf '%s\n' "$VIOLATION"
|
|
281
|
+
} > "$r/scripts/test_probe.sh"
|
|
282
|
+
run_gate "$r"
|
|
283
|
+
if [ "$RC" -eq 0 ]; then ok
|
|
284
|
+
else note "p14 KNOWN LIMIT CHANGED: a discarded same-pid state read now fires — update the checklist (rc=$RC)"; fi
|
|
285
|
+
|
|
286
|
+
printf 'liveness_predicate_gate: pass=%s fail=%s\n' "$pass" "$fail"
|
|
287
|
+
[ "$fail" -eq 0 ] || exit 1
|
|
288
|
+
echo "liveness_predicate_gate_ok"
|