@ccoalm/ccl-skills 0.3.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.
Files changed (79) hide show
  1. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/classify_envelope.py +34 -3
  2. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_abort_leak_state_helpers.sh +148 -0
  3. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_classify_envelope.sh +28 -0
  4. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_parse_review_json.sh +7 -0
  5. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_review_gate.sh +13 -0
  6. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_review_gate_abort_leak.sh +271 -34
  7. package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-perspective-research/references/public-data-acquisition.md +3 -1
  8. package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-perspective-research/references/public-disclosure-channels.md +2 -0
  9. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/SKILL.md +12 -12
  10. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/dual-track-review-gate.md +8 -0
  11. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/eval-routing.md +7 -8
  12. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/external-practice-controls.md +12 -0
  13. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/extraction-quickstart.md +3 -2
  14. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/firing-point-placement.md +8 -0
  15. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/harness-patterns-and-eval.md +7 -6
  16. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/recurring-anti-patterns-checklist.md +18 -0
  17. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/source-register.md +47 -2
  18. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/source-to-skill-extraction.md +28 -29
  19. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/check-ccl-skills.sh +165 -1
  20. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/eval-health.rb +23 -10
  21. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/impact-chain-gate.rb +303 -1
  22. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_impact_chain_refscripts.sh +222 -91
  23. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_regressions.sh +12 -0
  24. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_ci_checkout_ref_binding.sh +85 -0
  25. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_entrypoint_domain_scan_terms.sh +123 -0
  26. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_impact_chain_gate_dateless_host.sh +6 -1
  27. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_impact_chain_gate_verdict_differential.sh +1 -1
  28. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_impact_chain_round_attribution.sh +12 -12
  29. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_impact_chain_self_adjudication.sh +455 -0
  30. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_impact_chain_source_refuted.sh +20 -20
  31. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_liveness_predicate_gate.sh +288 -0
  32. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/SKILL.md +4 -4
  33. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/references/deliverable-doc-genre-skeletons.md +133 -0
  34. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/references/doc-charter-first.md +2 -0
  35. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/references/figure-and-table-craft.md +318 -0
  36. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/AGENTS.md +46 -0
  37. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/doc-lint.py +246 -0
  38. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/figure-lint.py +1092 -0
  39. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/mutation_probe.sh +100 -0
  40. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/test_figure_and_doc_lint.sh +375 -0
  41. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/control.md +10 -0
  42. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/empty-header.md +6 -0
  43. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/fake-header.md +13 -0
  44. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/fenced-noise.md +14 -0
  45. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/fig-dangling.md +5 -0
  46. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/fig-orphan-captioned.md +11 -0
  47. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/fig-orphan.md +9 -0
  48. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/fig.png +0 -0
  49. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/imbalance.md +41 -0
  50. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/no-unit.md +8 -0
  51. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/should-be-chart.md +11 -0
  52. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/tables-only-clean.md +35 -0
  53. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/unfilled.md +7 -0
  54. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/wide-table.md +5 -0
  55. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/bad-viewbox.svg +9 -0
  56. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/blackmarker.svg +9 -0
  57. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/control.svg +12 -0
  58. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/crossings.svg +12 -0
  59. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/cvd-confusable.svg +9 -0
  60. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/decorative-line.svg +10 -0
  61. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/edge-no-arrow.svg +11 -0
  62. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/edge-vague.svg +12 -0
  63. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/figure-contract.json +21 -0
  64. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/figure-is-a-list.svg +12 -0
  65. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/flow-mixed.svg +13 -0
  66. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/low-contrast.svg +12 -0
  67. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/malformed.svg +1 -0
  68. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/no-aria.svg +9 -0
  69. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/no-group.svg +10 -0
  70. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/no-legend.svg +9 -0
  71. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/no-title.svg +12 -0
  72. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/no-viewbox.svg +9 -0
  73. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/offcontract-shape.svg +13 -0
  74. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/overflow.svg +13 -0
  75. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/transformed.svg +9 -0
  76. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/ungrouped-card.svg +12 -0
  77. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/unlabeled-edge.svg +13 -0
  78. package/dist/assets/release.json +276 -31
  79. package/package.json +1 -1
@@ -125,7 +125,13 @@ fast_tests=(
125
125
  test_validate_skill_root_depth.sh
126
126
  test_validate_skill_cross_refs.sh
127
127
  test_git_identity_predicate_gate.sh
128
+ test_liveness_predicate_gate.sh
128
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
129
135
  # Lane-semantics guard for this runner itself (036 challenge P2): proves
130
136
  # --heavy-only / --fast / --full each run exactly their lane against a stub
131
137
  # fixture via REGRESSION_SCRIPTS_DIR, and that a red heavy stub propagates.
@@ -141,6 +147,7 @@ fast_tests=(
141
147
 
142
148
  heavy_tests=(
143
149
  test_check_ccl_r0_status.sh
150
+ test_entrypoint_domain_scan_terms.sh
144
151
  test_check_ccl_source_register_lifecycle.sh
145
152
  # Clones the whole repo once; impact-chain cases call the standalone gate and
146
153
  # retain one full-checker wiring case. Still kept out of the pre-commit lane.
@@ -164,6 +171,11 @@ heavy_tests=(
164
171
  # 对照表不交代被删内容)必须每轮都跑。clone + 16 分支对 pre-commit 太慢,进 heavy。
165
172
  test_impact_chain_source_refuted.sh
166
173
  test_impact_chain_gate_verdict_differential.sh
174
+ # 045:两个触发器(routing 面改动欠 bank 证据、台账行欠 result-class)的十条决策表
175
+ # 用例。同样是整仓 clone + 一 case 一分支的形态,故与上面两套同进 heavy。它钉的是
176
+ # 「跳过义务会不会留下可检出的缺席」——044 连续五轮 challenge 都停在这一点上,负向
177
+ # 用例(缺证据、非枚举值、降范围无留痕)必须每轮都跑,否则触发器会悄悄退化成声称。
178
+ test_impact_chain_self_adjudication.sh
167
179
  )
168
180
 
169
181
  # Registration self-audit: every sibling test_*.sh must appear in fast_tests or
@@ -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"
@@ -76,8 +76,13 @@ git -C "$REPO" branch fixture-base HEAD
76
76
  git -C "$REPO" switch -q -C case-dateless fixture-base
77
77
  git -C "$REPO" branch --set-upstream-to=fixture-base case-dateless >/dev/null 2>&1
78
78
  perl -0pi -e 's/^(description: .+)$/$1 Fixture dateless trigger clause./m' "$REPO/skills/product-rd-workflow/SKILL.md"
79
- printf '| Fixture dateless row | `downstream-executor` | behavioral-evidence: RED-baseline; observed-failure: yes; firing-path: file:skills/product-rd-workflow/SKILL.md#description | `updated` | `product-rd-workflow/SKILL.md` description-only fixture change |\n' \
79
+ printf '| Fixture dateless row | `downstream-executor` | behavioral-evidence: RED-baseline; observed-failure: yes; result-class: failure; bank-evidence: downscoped:DATELESS-FIXTURE-NO-BANK; firing-path: file:skills/product-rd-workflow/SKILL.md#description | `updated` | `product-rd-workflow/SKILL.md` description-only fixture change |\n' \
80
80
  >> "$REPO/skills/skill-extraction-workflow/references/source-register.md"
81
+ mkdir -p "$REPO/specs/fixture-dateless"
82
+ # 045: a description change owes bank evidence. This fixture exercises host date
83
+ # handling, not routing measurement, so it downscopes the run ON THE RECORD — the
84
+ # token has to exist somewhere a reader reaches, which is the point of the rule.
85
+ printf -- '- Downscope downscoped:DATELESS-FIXTURE-NO-BANK is recorded here; this round must not be read as having measured routing.\n' > "$REPO/specs/fixture-dateless/plan.md"
81
86
  git -C "$REPO" add -A
82
87
  git -C "$REPO" commit -qm "description-only change with #description row"
83
88
 
@@ -335,7 +335,7 @@ run_case() { # <name> <expected-baseline-rc> <expected-token-or-empty> <declare:
335
335
  local repo="$TMP/case-$name"
336
336
  seed_case "$repo"
337
337
  if [ "$declare_row" = yes ]; then
338
- printf '| Fixture differential row | `downstream-executor` | behavioral-evidence: RED-baseline; observed-failure: yes; firing-path: file:skills/product-rd-workflow/SKILL.md#DIFFERENTIAL-CASE | `updated` | `product-rd-workflow/SKILL.md` fixture change |\n' \
338
+ printf '| Fixture differential row | `downstream-executor` | behavioral-evidence: RED-baseline; observed-failure: yes; result-class: failure; firing-path: file:skills/product-rd-workflow/SKILL.md#DIFFERENTIAL-CASE | `updated` | `product-rd-workflow/SKILL.md` fixture change |\n' \
339
339
  >> "$repo/$LEDGER_REL"
340
340
  fi
341
341
  git -C "$repo" add -A
@@ -120,7 +120,7 @@ mutate_owner_rule() { # <repo-dir> <owner-slug> <marker>
120
120
  # matching mutate_owner_rule added, and the owner key in the evidence cell.
121
121
  append_valid_row() { # <repo-dir> <owner-slug> <marker> <lesson>
122
122
  local repo="$1" owner="$2" marker="$3" lesson="$4"
123
- printf '| %s | `downstream-executor` | behavioral-evidence: RED-baseline; observed-failure: yes; firing-path: file:skills/%s/SKILL.md#%s | `updated` | `%s/SKILL.md` fixture change |\n' \
123
+ printf '| %s | `downstream-executor` | behavioral-evidence: RED-baseline; observed-failure: yes; result-class: failure; firing-path: file:skills/%s/SKILL.md#%s | `updated` | `%s/SKILL.md` fixture change |\n' \
124
124
  "$lesson" "$owner" "$(rule_anchor "$marker")" "$owner" >> "$repo/$LEDGER_REL"
125
125
  }
126
126
 
@@ -276,7 +276,7 @@ mutate_owner_rule "$L" testing-strategy L2
276
276
  # that still merely warns — which is exactly what it must detect.
277
277
  append_valid_row "$L" product-rd-workflow L "Fixture first owner row"
278
278
  append_valid_row "$L" testing-strategy L2 "Fixture second owner row"
279
- printf '| Fixture ambiguous row | `downstream-executor` | behavioral-evidence: RED-baseline; observed-failure: yes; firing-path: file:skills/product-rd-workflow/SKILL.md#%s | `updated` | `product-rd-workflow/SKILL.md` and `testing-strategy/SKILL.md` both changed and are cited in one row |\n' \
279
+ printf '| Fixture ambiguous row | `downstream-executor` | behavioral-evidence: RED-baseline; observed-failure: yes; result-class: failure; firing-path: file:skills/product-rd-workflow/SKILL.md#%s | `updated` | `product-rd-workflow/SKILL.md` and `testing-strategy/SKILL.md` both changed and are cited in one row |\n' \
280
280
  "$(rule_anchor L)" >> "$L/$LEDGER_REL"
281
281
  git -C "$L" add -A
282
282
  git -C "$L" commit -qm "round 1: one row citing two changed selected owners"
@@ -310,7 +310,7 @@ git -C "$M" branch fixture-base HEAD
310
310
  git -C "$M" switch -q -c case-noncurated
311
311
  printf -- '- Rule %s must be recorded before the round lands.\n' "$(rule_anchor M)" \
312
312
  >> "$M/skills/worktree-isolation/SKILL.md"
313
- printf '| Fixture non-curated row | `downstream-executor` | behavioral-evidence: RED-baseline; observed-failure: yes; firing-path: file:skills/worktree-isolation/SKILL.md#%s | `updated` | `worktree-isolation/SKILL.md` changed; this skill is not a curated upstream owner |\n' \
313
+ printf '| Fixture non-curated row | `downstream-executor` | behavioral-evidence: RED-baseline; observed-failure: yes; result-class: failure; firing-path: file:skills/worktree-isolation/SKILL.md#%s | `updated` | `worktree-isolation/SKILL.md` changed; this skill is not a curated upstream owner |\n' \
314
314
  "$(rule_anchor M)" >> "$M/$LEDGER_REL"
315
315
  git -C "$M" add -A
316
316
  git -C "$M" commit -qm "round 1: change a non-curated owner and record it"
@@ -357,7 +357,7 @@ seed_repo "$O"
357
357
  git -C "$O" branch fixture-base HEAD
358
358
  git -C "$O" switch -q -c case-dotslash
359
359
  mutate_owner_rule "$O" product-rd-workflow O
360
- printf '| Fixture dot-slash row | `downstream-executor` | behavioral-evidence: RED-baseline; observed-failure: yes; firing-path: file:skills/product-rd-workflow/SKILL.md#%s | `updated` | see ./skills/product-rd-workflow/references/design-note.md for the rationale |\n' \
360
+ printf '| Fixture dot-slash row | `downstream-executor` | behavioral-evidence: RED-baseline; observed-failure: yes; result-class: failure; firing-path: file:skills/product-rd-workflow/SKILL.md#%s | `updated` | see ./skills/product-rd-workflow/references/design-note.md for the rationale |\n' \
361
361
  "$(rule_anchor O)" >> "$O/$LEDGER_REL"
362
362
  git -C "$O" add -A
363
363
  git -C "$O" commit -qm "round 1: change the owner, cite it with a ./ prefixed path"
@@ -377,7 +377,7 @@ seed_repo "$O2"
377
377
  git -C "$O2" branch fixture-base HEAD
378
378
  git -C "$O2" switch -q -c case-rooted
379
379
  mutate_owner_rule "$O2" product-rd-workflow O2
380
- printf '| Fixture rooted-path row | `downstream-executor` | behavioral-evidence: RED-baseline; observed-failure: yes; firing-path: file:skills/product-rd-workflow/SKILL.md#%s | `updated` | see /skills/product-rd-workflow/references/design-note.md for the rationale |\n' \
380
+ printf '| Fixture rooted-path row | `downstream-executor` | behavioral-evidence: RED-baseline; observed-failure: yes; result-class: failure; firing-path: file:skills/product-rd-workflow/SKILL.md#%s | `updated` | see /skills/product-rd-workflow/references/design-note.md for the rationale |\n' \
381
381
  "$(rule_anchor O2)" >> "$O2/$LEDGER_REL"
382
382
  git -C "$O2" add -A
383
383
  git -C "$O2" commit -qm "round 1: change the owner, cite it with a rooted path"
@@ -399,7 +399,7 @@ seed_repo "$O3"
399
399
  git -C "$O3" branch fixture-base HEAD
400
400
  git -C "$O3" switch -q -c case-remainder
401
401
  mutate_owner_rule "$O3" product-rd-workflow O3
402
- printf '| Fixture remainder row | `downstream-executor` | behavioral-evidence: RED-baseline; observed-failure: yes; firing-path: file:skills/product-rd-workflow/SKILL.md#%s | `updated` | rationale in skills/product-rd-workflow/@design.md and skills/product-rd-workflow/设计说明.md |\n' \
402
+ printf '| Fixture remainder row | `downstream-executor` | behavioral-evidence: RED-baseline; observed-failure: yes; result-class: failure; firing-path: file:skills/product-rd-workflow/SKILL.md#%s | `updated` | rationale in skills/product-rd-workflow/@design.md and skills/product-rd-workflow/设计说明.md |\n' \
403
403
  "$(rule_anchor O3)" >> "$O3/$LEDGER_REL"
404
404
  git -C "$O3" add -A
405
405
  git -C "$O3" commit -qm "round 1: cite the owner with unusual but valid path remainders"
@@ -421,7 +421,7 @@ seed_repo "$O4"
421
421
  git -C "$O4" branch fixture-base HEAD
422
422
  git -C "$O4" switch -q -c case-relative
423
423
  mutate_owner_rule "$O4" product-rd-workflow O4
424
- printf '| Fixture relative-link row | `downstream-executor` | behavioral-evidence: RED-baseline; observed-failure: yes; firing-path: file:skills/product-rd-workflow/SKILL.md#%s | `updated` | rationale in [the design note](../../product-rd-workflow/references/design-note.md) |\n' \
424
+ printf '| Fixture relative-link row | `downstream-executor` | behavioral-evidence: RED-baseline; observed-failure: yes; result-class: failure; firing-path: file:skills/product-rd-workflow/SKILL.md#%s | `updated` | rationale in [the design note](../../product-rd-workflow/references/design-note.md) |\n' \
425
425
  "$(rule_anchor O4)" >> "$O4/$LEDGER_REL"
426
426
  git -C "$O4" add -A
427
427
  git -C "$O4" commit -qm "round 1: cite the owner through a Markdown-relative link"
@@ -471,7 +471,7 @@ S1="$TMP/leg-s"
471
471
  seed_repo "$S1"
472
472
  git -C "$S1" branch fixture-base HEAD
473
473
  git -C "$S1" switch -q -c case-malformed
474
- printf '| Fixture smuggled row | `downstream-executor` | behavioral-evidence: RED-baseline; observed-failure: yes; firing-path: file:skills/product-rd-workflow/SKILL.md#nope | `updated` | rationale in skills/product-rd-workflow/references/note.md, see a|b for the table |\n' \
474
+ printf '| Fixture smuggled row | `downstream-executor` | behavioral-evidence: RED-baseline; observed-failure: yes; result-class: failure; firing-path: file:skills/product-rd-workflow/SKILL.md#nope | `updated` | rationale in skills/product-rd-workflow/references/note.md, see a|b for the table |\n' \
475
475
  >> "$S1/$LEDGER_REL"
476
476
  git -C "$S1" add -A
477
477
  git -C "$S1" commit -qm "round 1: a declaring row for a selected owner with an unescaped pipe"
@@ -504,7 +504,7 @@ S3="$TMP/leg-s3"
504
504
  seed_repo "$S3"
505
505
  git -C "$S3" branch fixture-base HEAD
506
506
  git -C "$S3" switch -q -c case-emptycell
507
- printf '| Fixture empty-cell row | | behavioral-evidence: RED-baseline; observed-failure: yes; firing-path: file:skills/product-rd-workflow/SKILL.md#nope | `updated` | rationale in skills/product-rd-workflow/references/note.md |\n' \
507
+ printf '| Fixture empty-cell row | | behavioral-evidence: RED-baseline; observed-failure: yes; result-class: failure; firing-path: file:skills/product-rd-workflow/SKILL.md#nope | `updated` | rationale in skills/product-rd-workflow/references/note.md |\n' \
508
508
  >> "$S3/$LEDGER_REL"
509
509
  git -C "$S3" add -A
510
510
  git -C "$S3" commit -qm "round 1: a declaring row for a selected owner with an empty cell"
@@ -527,7 +527,7 @@ git -C "$S4" branch fixture-base HEAD
527
527
  git -C "$S4" switch -q -c case-corrected
528
528
  mutate_owner_rule "$S4" product-rd-workflow S4
529
529
  append_valid_row "$S4" product-rd-workflow S4 "Fixture sound row"
530
- printf '| Fixture to-be-corrected row | `downstream-executor` | behavioral-evidence: RED-baseline; observed-failure: yes; firing-path: file:skills/product-rd-workflow/SKILL.md#%s | `updated` | rationale in skills/product-rd-workflow/references/note.md, see a|b |\n' \
530
+ printf '| Fixture to-be-corrected row | `downstream-executor` | behavioral-evidence: RED-baseline; observed-failure: yes; result-class: failure; firing-path: file:skills/product-rd-workflow/SKILL.md#%s | `updated` | rationale in skills/product-rd-workflow/references/note.md, see a|b |\n' \
531
531
  "$(rule_anchor S4b)" >> "$S4/$LEDGER_REL"
532
532
  git -C "$S4" add -A
533
533
  git -C "$S4" commit -qm "round 1: a sound row plus a malformed declaring row"
@@ -550,7 +550,7 @@ S5="$TMP/leg-s5"
550
550
  seed_repo "$S5"
551
551
  git -C "$S5" branch fixture-base HEAD
552
552
  git -C "$S5" switch -q -c case-noleading
553
- printf 'Fixture no-leading-pipe row | `downstream-executor` | behavioral-evidence: RED-baseline; observed-failure: yes; firing-path: file:skills/product-rd-workflow/SKILL.md#nope | `updated` | rationale in skills/product-rd-workflow/references/note.md |\n' \
553
+ printf 'Fixture no-leading-pipe row | `downstream-executor` | behavioral-evidence: RED-baseline; observed-failure: yes; result-class: failure; firing-path: file:skills/product-rd-workflow/SKILL.md#nope | `updated` | rationale in skills/product-rd-workflow/references/note.md |\n' \
554
554
  >> "$S5/$LEDGER_REL"
555
555
  git -C "$S5" add -A
556
556
  git -C "$S5" commit -qm "round 1: a declaring row without its leading pipe"
@@ -561,7 +561,7 @@ S6="$TMP/leg-s6"
561
561
  seed_repo "$S6"
562
562
  git -C "$S6" branch fixture-base HEAD
563
563
  git -C "$S6" switch -q -c case-notrailing
564
- printf '| Fixture no-trailing-pipe row | `downstream-executor` | behavioral-evidence: RED-baseline; observed-failure: yes; firing-path: file:skills/product-rd-workflow/SKILL.md#nope | `updated` | rationale in skills/product-rd-workflow/references/note.md\n' \
564
+ printf '| Fixture no-trailing-pipe row | `downstream-executor` | behavioral-evidence: RED-baseline; observed-failure: yes; result-class: failure; firing-path: file:skills/product-rd-workflow/SKILL.md#nope | `updated` | rationale in skills/product-rd-workflow/references/note.md\n' \
565
565
  >> "$S6/$LEDGER_REL"
566
566
  git -C "$S6" add -A
567
567
  git -C "$S6" commit -qm "round 1: a declaring row without its trailing pipe"