@ccoalm/ccl-skills 0.18.10 → 0.18.12
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/hooks/headless-background-stop.sh +18 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/hooks.json +7 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/host-input.py +155 -8
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/remind-post-merge-cleanup.sh +9 -4
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/task-entry.sh +24 -3
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/test_headless_background_stop.sh +150 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/test_proposed_next.py +71 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/test_remind_post_merge_cleanup.sh +47 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/test_task_entry.py +63 -0
- package/dist/assets/marketplace/plugins/ccl-skills/packages/opencode-plugin/ccl-skills.ts +7 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/references/development-completion.md +2 -2
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/review_gate.py +77 -6
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_review_gate.sh +112 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-agent-delegation/references/multi-agent-delegation-playbook.md +1 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/pre-final-continuation-gate.md +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/worktree-mechanics.md +10 -3
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/attention-budget-ratchet.md +2 -2
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/external-practice-controls.md +6 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/extraction-lifecycle-handoff.md +1 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/harness-patterns-and-eval.md +2 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/source-register.md +15 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/check-sync-pointers.sh +11 -4
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/skill-paired-eval.py +1546 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_ai_coding_implementation_gates.sh +140 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_regressions.sh +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_sync_pointers.sh +13 -4
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_controlled_escalation_pins.sh +12 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_skill_paired_eval.py +1052 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_teardown_guard_pins.sh +354 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/worktree-isolation/SKILL.md +8 -108
- package/dist/assets/marketplace/plugins/ccl-skills/skills/worktree-isolation/references/merge-and-teardown.md +47 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/worktree-isolation/references/pre-merge-landing-checks.md +73 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/worktree-isolation/references/shared-branch-rebase.md +1 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/worktree-isolation/scripts/test_worktree_sweep.sh +1 -1
- package/dist/assets/release.json +65 -30
- package/package.json +1 -1
|
@@ -270,7 +270,7 @@ assert_in_section "$PRE_FINAL_REF" '## Gate triggers and outcome contract' 'cite
|
|
|
270
270
|
assert_same_line "$REPO_ROOT/AGENTS.md" '授权按用户已明确的交付目标判断' '只授权单项、只问状态、明确停止或限制范围时遵守该边界' "goal authority (root scope and stop)"
|
|
271
271
|
assert_contains "$REPO_ROOT/docs/npm-release.md" 'Do not ask again for each prerequisite' "goal authority (release follows through)"
|
|
272
272
|
assert_contains "$REPO_ROOT/skills/release-coordination/SKILL.md" 'Existing host permission checks and resource-owner requirements still apply' "goal authority (host and resource boundary)"
|
|
273
|
-
assert_contains "$REPO_ROOT/skills/worktree-isolation/
|
|
273
|
+
assert_contains "$REPO_ROOT/skills/worktree-isolation/references/merge-and-teardown.md" '目标/批量授权内由 agent 完成的修复、新提交或新建 MR,先刷新检查、评审与状态,不重复请求权限' "goal authority (repair refreshes evidence)"
|
|
274
274
|
assert_contains "$REPO_ROOT/skills/product-rd-workflow/references/refactoring-discipline.md" 'do not ask again merely because it involves refactoring' "quality gate (authorized cleanup)"
|
|
275
275
|
assert_contains "$REPO_ROOT/skills/product-rd-workflow/references/refactoring-discipline.md" 'Do not abbreviate meaningful names, remove necessary explanations, pack statements, fragment responsibilities arbitrarily, or change the threshold/history just to satisfy a counter.' "quality gate (readability and metric integrity)"
|
|
276
276
|
assert_contains "$REPO_ROOT/skills/product-rd-workflow/references/refactoring-discipline.md" 'Broader redesign and breaking changes retain their scope and approval checks.' "quality gate (scope and compatibility boundary)"
|
|
@@ -871,4 +871,143 @@ assert_contains "$DELEGATION_SKILL" 'method/evidence checkpoint, not renewed tas
|
|
|
871
871
|
assert_contains "$DELEGATION_SKILL" 'unknown completion state or missing authority remains after bounded remediation' "delegation preserves unresolved blockers"
|
|
872
872
|
assert_contains "$DELEGATION_SKILL" 'respecting explicit user limits' "delegation preserves user limits"
|
|
873
873
|
|
|
874
|
+
# 9. Worktree teardown guard on every surface that restates removal (round 162).
|
|
875
|
+
# `git worktree remove` without --force deletes gitignored files and exits 0, so
|
|
876
|
+
# the pre-removal scan is the only guard for costly outputs. Each surface that
|
|
877
|
+
# restates the removal carries the scan, its success condition and a pointer to
|
|
878
|
+
# the canonical teardown section; the sweep below requires the same of any
|
|
879
|
+
# Markdown surface added later. Rows are data so test_teardown_guard_pins.sh can
|
|
880
|
+
# apply one mutation per row: kind|repo-relative file|scope|phrase|label, where
|
|
881
|
+
# scope is a section heading (section, order) or the anchor of the line that
|
|
882
|
+
# must carry the phrase (line); an order row's phrase reads `first ⟶ second`,
|
|
883
|
+
# both inside the section and in that order.
|
|
884
|
+
assert_order_in_section() {
|
|
885
|
+
local file="$1" heading="$2" pair="$3" label="$4"
|
|
886
|
+
local first="${pair%% ⟶ *}" second="${pair#* ⟶ }"
|
|
887
|
+
[[ "$first" != "$pair" && -n "$first" && -n "$second" ]] || fail "$label: order row must read 'first ⟶ second'"
|
|
888
|
+
[[ -f "$file" ]] || fail "$label: missing file $file"
|
|
889
|
+
local section a b
|
|
890
|
+
section="$(awk -v h="$heading" '$0 == h {inside = 1; next} inside && /^#/ {exit} inside {print}' "$file")"
|
|
891
|
+
[[ -n "$section" ]] || fail "$label: section not found or empty: $heading"
|
|
892
|
+
a="$(grep -n -F -m1 -- "$first" <<< "$section")" || fail "$label: \`$first\` absent from section $heading"
|
|
893
|
+
b="$(grep -n -F -m1 -- "$second" <<< "$section")" || fail "$label: \`$second\` absent from section $heading"
|
|
894
|
+
(( ${a%%:*} < ${b%%:*} )) || fail "$label: \`$first\` must come before \`$second\` in section $heading"
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
TEARDOWN_PINS="$(cat <<'PINS'
|
|
898
|
+
section|skills/product-rd-workflow/references/worktree-mechanics.md|## Closeout Cleanup|the closeout section (`## 收尾`) of `worktree-isolation/references/merge-and-teardown.md`|product-rd cleanup names the canonical teardown
|
|
899
|
+
section|skills/product-rd-workflow/references/worktree-mechanics.md|## Closeout Cleanup|you must run `git -C <path> status --ignored -s` from the primary checkout|product-rd cleanup scans gitignored outputs first
|
|
900
|
+
section|skills/product-rd-workflow/references/worktree-mechanics.md|## Closeout Cleanup|It must exit 0; a failed scan counts as no scan|product-rd cleanup treats a failed scan as no scan
|
|
901
|
+
section|skills/product-rd-workflow/references/worktree-mechanics.md|## Closeout Cleanup|copy costly ones (long-running results, collected data, trained artifacts) back to the primary checkout before removal|product-rd cleanup rescues costly outputs
|
|
902
|
+
section|skills/product-rd-workflow/references/worktree-mechanics.md|## Closeout Cleanup|When unsure, treat an entry as costly|product-rd cleanup treats uncertain entries as costly
|
|
903
|
+
section|skills/product-rd-workflow/references/worktree-mechanics.md|## Closeout Cleanup|wait for it to finish; never kill it to clean up|product-rd cleanup waits for in-flight side effects
|
|
904
|
+
section|skills/product-rd-workflow/references/worktree-mechanics.md|## Closeout Cleanup|Never pass `--force` to `git worktree remove` or use `git branch -D`|product-rd cleanup forbids forced removal
|
|
905
|
+
section|skills/product-rd-workflow/references/worktree-mechanics.md|## Closeout Cleanup|Never delete a permanent or integration branch, or any branch whose name contains `release`|product-rd cleanup keeps permanent and release branches
|
|
906
|
+
order|skills/product-rd-workflow/references/worktree-mechanics.md|## Closeout Cleanup|status --ignored -s # must exit 0 ⟶ git worktree remove <path>|product-rd recipe scans before it removes
|
|
907
|
+
line|skills/multi-agent-delegation/references/multi-agent-delegation-playbook.md|Every worktree removal below must run the pre-removal scan|`worktree-isolation/references/merge-and-teardown.md`|delegation cleanup names the canonical teardown
|
|
908
|
+
line|skills/multi-agent-delegation/references/multi-agent-delegation-playbook.md|Every worktree removal below must run the pre-removal scan|`git -C <worktree-path> status --ignored -s` must exit 0, and a failed scan counts as no scan|delegation cleanup scans gitignored outputs first
|
|
909
|
+
line|skills/multi-agent-delegation/references/multi-agent-delegation-playbook.md|Every worktree removal below must run the pre-removal scan|Copy costly gitignored outputs the worker produced (long-running results, collected data, trained artifacts) into the target checkout before removal|delegation cleanup rescues costly outputs
|
|
910
|
+
line|skills/multi-agent-delegation/references/multi-agent-delegation-playbook.md|Every worktree removal below must run the pre-removal scan|Record the scan exit status and each kept or dropped entry in `cleanup_proof`|delegation cleanup records the scan in cleanup_proof
|
|
911
|
+
order|skills/multi-agent-delegation/references/multi-agent-delegation-playbook.md|## Handoff-Style Delivery Recipe|Every worktree removal below must run the pre-removal scan ⟶ For local-commit-only handoff|delegation scan precedes the removal paths
|
|
912
|
+
line|skills/skill-extraction-workflow/references/extraction-lifecycle-handoff.md|**Isolate each change with a worktree, not a clone.**|`worktree-isolation/references/merge-and-teardown.md`|extraction worktree names the canonical teardown
|
|
913
|
+
line|skills/skill-extraction-workflow/references/extraction-lifecycle-handoff.md|**Isolate each change with a worktree, not a clone.**|you must scan its gitignored outputs before removal (`git -C <worktree> status --ignored -s`, which must exit 0)|extraction worktree scans before removal
|
|
914
|
+
line|skills/skill-extraction-workflow/references/extraction-lifecycle-handoff.md|**Isolate each change with a worktree, not a clone.**|copy any output that is costly to recreate back to the standing checkout|extraction worktree rescues costly outputs
|
|
915
|
+
line|skills/worktree-isolation/references/merge-and-teardown.md|**任何方式删除单个 worktree 目录之前**|都必须先 `git -C <worktree路径> status --ignored -s` 扫 gitignored 产物|canonical scan precedes any removal
|
|
916
|
+
line|skills/worktree-isolation/references/merge-and-teardown.md|**任何方式删除单个 worktree 目录之前**|① 该命令**必须 exit 0**|canonical scan must succeed
|
|
917
|
+
line|skills/worktree-isolation/references/merge-and-teardown.md|**任何方式删除单个 worktree 目录之前**|② 输出非空即逐条判定保留/丢弃并向用户列出结论|canonical lists each kept or dropped entry
|
|
918
|
+
line|skills/worktree-isolation/references/merge-and-teardown.md|**任何方式删除单个 worktree 目录之前**|③ 判据看**重算代价**|canonical judges by recompute cost
|
|
919
|
+
line|skills/worktree-isolation/references/merge-and-teardown.md|**任何方式删除单个 worktree 目录之前**|宿主原生移除如 Claude Code `ExitWorktree` 的 remove|canonical scan covers host-native removal
|
|
920
|
+
line|skills/worktree-isolation/references/merge-and-teardown.md|**交互式 merge 选项菜单**|删前照样先按上文扫 gitignored 产物|canonical handoff keeps the scan for external finishing skills
|
|
921
|
+
order|skills/worktree-isolation/references/merge-and-teardown.md|## 收尾:worktree 一集成就清理(本地 + 远端,不留垃圾)|git -C <path> status --ignored -s # sweep 之外 ⟶ git worktree remove <path> # 删本地|canonical recipe scans before it removes
|
|
922
|
+
PINS
|
|
923
|
+
)"
|
|
924
|
+
teardown_rows=0
|
|
925
|
+
while IFS='|' read -r kind rel scope phrase label extra; do
|
|
926
|
+
[[ -n "$kind" ]] || continue
|
|
927
|
+
[[ -z "$extra" && -n "$label" ]] || fail "teardown guard: malformed pin row: $kind|$rel|$scope"
|
|
928
|
+
teardown_rows=$((teardown_rows + 1))
|
|
929
|
+
case "$kind" in
|
|
930
|
+
section) assert_in_section "$REPO_ROOT/$rel" "$scope" "$phrase" "teardown guard: $label" ;;
|
|
931
|
+
line) assert_same_line "$REPO_ROOT/$rel" "$scope" "$phrase" "teardown guard: $label" ;;
|
|
932
|
+
order) assert_order_in_section "$REPO_ROOT/$rel" "$scope" "$phrase" "teardown guard: $label" ;;
|
|
933
|
+
*) fail "teardown guard: unknown pin kind $kind in row $label" ;;
|
|
934
|
+
esac
|
|
935
|
+
done <<< "$TEARDOWN_PINS"
|
|
936
|
+
(( teardown_rows >= 20 )) || fail "teardown guard: only $teardown_rows pin rows parsed"
|
|
937
|
+
|
|
938
|
+
# Sweep: a Markdown surface that names `worktree remove` must also carry the
|
|
939
|
+
# ignored-output scan with its exit-0 requirement on the same line, and a
|
|
940
|
+
# pointer to the canonical teardown, `worktree-isolation/references/merge-and-teardown.md`
|
|
941
|
+
# (inside that package the package-relative path; the canonical file is itself
|
|
942
|
+
# the target). It keys on the command because prose wording is not ours to
|
|
943
|
+
# enumerate; prose-only removal steps are pinned per surface above. The set is
|
|
944
|
+
# the repository's own Markdown as git lists it, tracked plus untracked files
|
|
945
|
+
# git does not ignore, so local build output and caches stay out; outside a git
|
|
946
|
+
# work tree there is no such set and the sweep fails rather than guess one.
|
|
947
|
+
# specs/ and eval/ hold round records and evaluation inputs, not guidance, and
|
|
948
|
+
# the append-only source register describes the defects it records, so none of
|
|
949
|
+
# them is scanned. Anything git reports while listing, an unreadable file or a
|
|
950
|
+
# failed classification fails the sweep, since a file it skipped would
|
|
951
|
+
# otherwise pass unseen.
|
|
952
|
+
teardown_list="$(mktemp "${TMPDIR:-/tmp}/teardown-sweep.XXXXXX")"
|
|
953
|
+
trap 'rm -f "$teardown_list"' EXIT
|
|
954
|
+
teardown_fail() { rm -f "$teardown_list"; fail "teardown guard sweep: $1"; }
|
|
955
|
+
[[ "$(git -C "$REPO_ROOT" rev-parse --show-toplevel 2>/dev/null)" == "$REPO_ROOT" ]] ||
|
|
956
|
+
teardown_fail "not a git work tree, so the repository's Markdown cannot be listed"
|
|
957
|
+
teardown_errors="$(git -C "$REPO_ROOT" ls-files -z --cached --others --exclude-standard -- '*.md' 2>&1 >"$teardown_list")" ||
|
|
958
|
+
teardown_fail "could not list the repository's Markdown: $teardown_errors"
|
|
959
|
+
[[ -z "$teardown_errors" ]] || teardown_fail "git could not list every file: $teardown_errors"
|
|
960
|
+
# One pass reads every listed file (a grep per file made this sweep the slowest
|
|
961
|
+
# part of the fixture, which the pin walks run dozens of times). Its exit status
|
|
962
|
+
# carries the verdict; the printed text only names what it found.
|
|
963
|
+
teardown_rc=0
|
|
964
|
+
teardown_report="$(python3 - "$teardown_list" "$REPO_ROOT" <<'PY'
|
|
965
|
+
import sys
|
|
966
|
+
listing, root = sys.argv[1:3]
|
|
967
|
+
package = root + "/skills/worktree-isolation/"
|
|
968
|
+
canonical = package + "references/merge-and-teardown.md"
|
|
969
|
+
register = root + "/skills/skill-extraction-workflow/references/source-register.md"
|
|
970
|
+
def shown(name):
|
|
971
|
+
return "".join(c if c.isprintable() else repr(c)[1:-1] for c in name)
|
|
972
|
+
visited = False
|
|
973
|
+
offenders = []
|
|
974
|
+
for raw in open(listing, "rb").read().split(b"\0"):
|
|
975
|
+
if not raw:
|
|
976
|
+
continue
|
|
977
|
+
rel = raw.decode("utf-8", "surrogateescape")
|
|
978
|
+
path = root + "/" + rel
|
|
979
|
+
if rel.startswith(("specs/", "eval/")) or path == register:
|
|
980
|
+
continue
|
|
981
|
+
try:
|
|
982
|
+
text = open(path, "rb").read().decode("utf-8", "replace")
|
|
983
|
+
except OSError:
|
|
984
|
+
print(shown(rel))
|
|
985
|
+
sys.exit(5)
|
|
986
|
+
if "worktree remove" not in text:
|
|
987
|
+
continue
|
|
988
|
+
visited = visited or path == canonical
|
|
989
|
+
pointer = "references/merge-and-teardown.md" if path.startswith(package) else "worktree-isolation/references/merge-and-teardown.md"
|
|
990
|
+
if "status --ignored" not in text:
|
|
991
|
+
offenders.append(shown(rel) + ": no ignored-output scan")
|
|
992
|
+
elif not any("status --ignored" in line and "exit 0" in line for line in text.splitlines()):
|
|
993
|
+
offenders.append(shown(rel) + ": no exit-0 requirement on the scan line")
|
|
994
|
+
elif path != canonical and pointer not in text:
|
|
995
|
+
offenders.append(shown(rel) + ": no pointer to the canonical teardown")
|
|
996
|
+
if offenders:
|
|
997
|
+
print("; ".join(offenders))
|
|
998
|
+
sys.exit(3)
|
|
999
|
+
if not visited:
|
|
1000
|
+
sys.exit(4)
|
|
1001
|
+
PY
|
|
1002
|
+
)" || teardown_rc=$?
|
|
1003
|
+
rm -f "$teardown_list"
|
|
1004
|
+
trap - EXIT
|
|
1005
|
+
case "$teardown_rc" in
|
|
1006
|
+
0) ;;
|
|
1007
|
+
3) fail "teardown guard sweep: $teardown_report" ;;
|
|
1008
|
+
4) fail "teardown guard sweep: the canonical teardown was never scanned, so the listing is wrong" ;;
|
|
1009
|
+
5) fail "teardown guard sweep: could not read $teardown_report" ;;
|
|
1010
|
+
*) fail "teardown guard sweep: the classification pass failed" ;;
|
|
1011
|
+
esac
|
|
1012
|
+
|
|
874
1013
|
echo "test_ai_coding_implementation_gates: ok"
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
# - test_ai_coding_implementation_gates.sh
|
|
14
14
|
# - test_locale_independent_gates.sh
|
|
15
15
|
# - test_controlled_escalation_pins.sh
|
|
16
|
+
# - test_teardown_guard_pins.sh
|
|
16
17
|
# - test_check_ccl_size_budget.sh
|
|
17
18
|
# - test_check_ccl_skill_catalog.sh
|
|
18
19
|
# - test_check_ccl_parallel_stack_parity.sh
|
|
@@ -113,6 +114,9 @@ fast_tests=(
|
|
|
113
114
|
# family 8 out of the fixture above and proves each pin reds under its own
|
|
114
115
|
# applied deletion mutation in a throwaway copy (spec 031 review disposition).
|
|
115
116
|
test_controlled_escalation_pins.sh
|
|
117
|
+
# Applied-mutation walk for the worktree teardown guard rows (family 9 of the
|
|
118
|
+
# fixture above) plus decoy surfaces for its sweep; throwaway copy, seconds.
|
|
119
|
+
test_teardown_guard_pins.sh
|
|
116
120
|
test_check_ccl_size_budget.sh
|
|
117
121
|
# Entrypoint guidance-form census (what counts as one rule, a prohibition, a
|
|
118
122
|
# named baseline failure): synthetic fixtures plus the shipped entrypoint,
|
|
@@ -61,7 +61,7 @@ git -C "$REPO" config user.name "Test User"
|
|
|
61
61
|
git -C "$REPO" branch -f fixture-base HEAD
|
|
62
62
|
git -C "$REPO" switch -q -C fixture-work fixture-base
|
|
63
63
|
git -C "$REPO" branch --set-upstream-to=fixture-base fixture-work >/dev/null 2>&1
|
|
64
|
-
WT="$REPO/skills/worktree-isolation/
|
|
64
|
+
WT="$REPO/skills/worktree-isolation/references/merge-and-teardown.md"
|
|
65
65
|
SEC4="$REPO/skills/requirement-doc-writer/references/security-four-questions.md"
|
|
66
66
|
DTREF="$REPO/skills/skill-extraction-workflow/references/dual-track-review-gate.md"
|
|
67
67
|
|
|
@@ -77,7 +77,7 @@ replace_in_file "$WT" "合并执行协议(canonical" "合并落地协议(can
|
|
|
77
77
|
run_sync
|
|
78
78
|
assert_rc "$rc" 1 "reworded canonical section must block"
|
|
79
79
|
assert_contains "sync_pointer_block: merge-exec-protocol-section" "$out" "block names the pair"
|
|
80
|
-
git -C "$REPO" checkout -- skills/worktree-isolation/
|
|
80
|
+
git -C "$REPO" checkout -- skills/worktree-isolation/references/merge-and-teardown.md
|
|
81
81
|
|
|
82
82
|
# s2 RED: section heading renamed => 收尾节 pointer dangles (the pinned
|
|
83
83
|
# literal carries the colon so a longer heading cannot substring-satisfy it).
|
|
@@ -85,6 +85,15 @@ replace_in_file "$WT" "## 收尾:" "## 收尾清理:"
|
|
|
85
85
|
run_sync
|
|
86
86
|
assert_rc "$rc" 1 "renamed teardown heading must block"
|
|
87
87
|
assert_contains "sync_pointer_block: worktree-teardown-section" "$out" "block names the pair"
|
|
88
|
+
git -C "$REPO" checkout -- skills/worktree-isolation/references/merge-and-teardown.md
|
|
89
|
+
|
|
90
|
+
# s2b RED: the entrypoint's forwarding sentence removed => the always-on
|
|
91
|
+
# pointer still names the skill, but nothing in SKILL.md leads to the
|
|
92
|
+
# reference that carries the teardown section and the merge protocol.
|
|
93
|
+
replace_in_file "$REPO/skills/worktree-isolation/SKILL.md" "都在 \`references/merge-and-teardown.md\`" "见各 reference"
|
|
94
|
+
run_sync
|
|
95
|
+
assert_rc "$rc" 1 "a removed forwarding sentence must block"
|
|
96
|
+
assert_contains "sync_pointer_block: worktree-reference-forwarding" "$out" "block names the forwarding pair"
|
|
88
97
|
git -C "$REPO" checkout -- skills/worktree-isolation/SKILL.md
|
|
89
98
|
|
|
90
99
|
# s3 RED: bootstrap side reworded => pointer literal lost on the source side.
|
|
@@ -314,7 +323,7 @@ replace_in_file "$WT" "**合并执行协议(canonical——" "(既往)合
|
|
|
314
323
|
run_sync
|
|
315
324
|
assert_rc "$rc" 1 "a demoted-to-narrative section label must block"
|
|
316
325
|
assert_contains "sync_pointer_block: merge-exec-protocol-section" "$out" "block names the pair"
|
|
317
|
-
git -C "$REPO" checkout -- skills/worktree-isolation/
|
|
326
|
+
git -C "$REPO" checkout -- skills/worktree-isolation/references/merge-and-teardown.md
|
|
318
327
|
|
|
319
328
|
# s24 RED: a compliant decoy line inserted before the real reflection makes
|
|
320
329
|
# the extraction anchor ambiguous (scan requires exactly one hit).
|
|
@@ -358,7 +367,7 @@ run_sync
|
|
|
358
367
|
assert_rc "$rc" 1 "two-sided drift must block"
|
|
359
368
|
assert_contains "agent-context/session-start.md lost the registered pointer literal" "$out" "source side reported"
|
|
360
369
|
assert_contains "canonical target" "$out" "target side reported in the same run"
|
|
361
|
-
git -C "$REPO" checkout -- agent-context/session-start.md skills/worktree-isolation/
|
|
370
|
+
git -C "$REPO" checkout -- agent-context/session-start.md skills/worktree-isolation/references/merge-and-teardown.md
|
|
362
371
|
|
|
363
372
|
# s29a: the semantic gate resolves beside the validator, so pruning the IN-TREE
|
|
364
373
|
# copy changes nothing — on a clean tree the validator still evaluates with its
|
|
@@ -11,6 +11,11 @@
|
|
|
11
11
|
# tree. The pin list is parsed from the fixture itself so a new pin cannot be
|
|
12
12
|
# added without automatically entering this walk.
|
|
13
13
|
set -euo pipefail
|
|
14
|
+
# The copy gets its own repository; inherited git variables (set inside git
|
|
15
|
+
# hooks, for one) would point git at the real one instead.
|
|
16
|
+
unset GIT_DIR GIT_WORK_TREE GIT_INDEX_FILE GIT_OBJECT_DIRECTORY \
|
|
17
|
+
GIT_ALTERNATE_OBJECT_DIRECTORIES GIT_COMMON_DIR GIT_CEILING_DIRECTORIES \
|
|
18
|
+
GIT_NAMESPACE
|
|
14
19
|
|
|
15
20
|
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
|
|
16
21
|
repo_root="$(cd "$script_dir/../../.." && pwd -P)"
|
|
@@ -27,6 +32,12 @@ cp -R "$repo_root/skills" "$tmp_root/skills"
|
|
|
27
32
|
cp -R "$repo_root/agent-context" "$tmp_root/agent-context"
|
|
28
33
|
cp -R "$repo_root/docs" "$tmp_root/docs"
|
|
29
34
|
cp "$repo_root/AGENTS.md" "$tmp_root/AGENTS.md"
|
|
35
|
+
# The fixture's teardown sweep lists the repository's Markdown through git, so
|
|
36
|
+
# the copy needs an index; nothing is committed, which keeps user commit hooks
|
|
37
|
+
# and signing out of the run.
|
|
38
|
+
cp "$repo_root/.gitignore" "$tmp_root/.gitignore"
|
|
39
|
+
git -C "$tmp_root" init -q
|
|
40
|
+
git -C "$tmp_root" add -A
|
|
30
41
|
copy_fixture="$tmp_root/$fixture_rel"
|
|
31
42
|
copy_ref="$tmp_root/$ref_rel"
|
|
32
43
|
[[ -f "$copy_fixture" && -f "$copy_ref" ]] || fail "copy is missing the fixture or the reference"
|
|
@@ -63,7 +74,7 @@ pin_count="$(wc -l < "$pins_file" | tr -d ' ')"
|
|
|
63
74
|
raw_count="$(grep -c 'assert_in_section "\$EXTRACTION_METHOD_REF" "\$BLOCKED_VERIFICATION_SECTION"' "$repo_root/$fixture_rel")"
|
|
64
75
|
[[ "$pin_count" == "$raw_count" ]] || fail "parser dropped family-8 assertions: parsed $pin_count of $raw_count calls"
|
|
65
76
|
|
|
66
|
-
run_copy() { bash "$copy_fixture" 2>&1; }
|
|
77
|
+
run_copy() { TMPDIR="$tmp_root" bash "$copy_fixture" 2>&1; }
|
|
67
78
|
|
|
68
79
|
# Control: the unmutated copy is green, proving the harness reads the copy.
|
|
69
80
|
control_out="$(run_copy)" || fail "pre-control not green: $control_out"
|