@ccoalm/ccl-skills 0.7.0 → 0.9.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 (127) hide show
  1. package/README.md +2 -2
  2. package/dist/assets/marketplace/plugins/ccl-skills/skills/app-cross-platform-dev/SKILL.md +8 -7
  3. package/dist/assets/marketplace/plugins/ccl-skills/skills/app-cross-platform-dev/references/mobile-quality-release.md +6 -1
  4. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/SKILL.md +16 -17
  5. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/references/client-routing.md +1 -1
  6. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/references/manual-invocation-and-prompts.md +6 -0
  7. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/references/staged-review-contract.md +195 -7
  8. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/references/timeout-auth-and-capabilities.md +3 -3
  9. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/claude_review.sh +13 -5
  10. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/codex_review.sh +9 -3
  11. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/kimi_review.sh +9 -3
  12. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/normalize_review_timeout.sh +22 -0
  13. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/opencode_review.sh +9 -3
  14. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/review_gate.py +1540 -129
  15. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_claude_review_probe.sh +8 -3
  16. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_review_client_compat.py +76 -1
  17. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_review_gate.sh +1858 -3
  18. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_update_review_plan_intent.sh +789 -0
  19. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/update_review_plan_intent.py +513 -0
  20. package/dist/assets/marketplace/plugins/ccl-skills/skills/defect-diagnosis/SKILL.md +1 -0
  21. package/dist/assets/marketplace/plugins/ccl-skills/skills/feature-risk-router/SKILL.md +3 -1
  22. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/architecture-playbook.md +1 -1
  23. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/multi-tenant-isolation.md +1 -1
  24. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/SKILL.md +4 -1
  25. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/state-machine-task-patterns.md +2 -0
  26. package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/SKILL.md +2 -1
  27. package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/inference-capacity-operations.md +24 -0
  28. package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/llm-client-gateway.md +1 -1
  29. package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/model-prompt-evaluation.md +4 -1
  30. package/dist/assets/marketplace/plugins/ccl-skills/skills/miniapp-product-dev/SKILL.md +11 -10
  31. package/dist/assets/marketplace/plugins/ccl-skills/skills/miniapp-product-dev/references/contracts-and-state.md +5 -0
  32. package/dist/assets/marketplace/plugins/ccl-skills/skills/nodejs-service-dev/SKILL.md +64 -0
  33. package/dist/assets/marketplace/plugins/ccl-skills/skills/nodejs-service-dev/agents/openai.yaml +4 -0
  34. package/dist/assets/marketplace/plugins/ccl-skills/skills/nodejs-service-dev/references/async-lifecycle-and-performance.md +73 -0
  35. package/dist/assets/marketplace/plugins/ccl-skills/skills/nodejs-service-dev/references/runtime-and-project-contract.md +58 -0
  36. package/dist/assets/marketplace/plugins/ccl-skills/skills/nodejs-service-dev/references/source-map.md +41 -0
  37. package/dist/assets/marketplace/plugins/ccl-skills/skills/nodejs-service-dev/references/verification-diagnostics-and-security.md +63 -0
  38. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/SKILL.md +3 -2
  39. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/references/metrics-conventions.md +8 -1
  40. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/references/sli-slo-design.md +2 -2
  41. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/canary-and-rollout-strategy.md +16 -2
  42. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/promotion-gate-and-review.md +9 -0
  43. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/SKILL.md +14 -16
  44. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/code-review-checklist.md +4 -0
  45. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/delivery-lifecycle.md +1 -1
  46. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/design-routing-and-readiness.md +10 -14
  47. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/rd-standards-doc-family-checklist.md +1 -0
  48. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/verify-developer-experience.md +1 -1
  49. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/SKILL.md +135 -86
  50. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/behavioral-aesthetic-logic.md +66 -80
  51. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/delivery-contract.md +275 -0
  52. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/design-execution-checklist.md +88 -214
  53. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/design-impl-naming-and-versioning.md +2 -2
  54. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/design-intake-and-acceptance.md +10 -8
  55. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/design-system-source-of-truth.md +6 -5
  56. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/external-ui-ux-quality-benchmarks.md +112 -95
  57. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/frontend-code-evidence-map.md +30 -21
  58. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/interaction-design-patterns.md +22 -3
  59. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/layout-recipes-and-screenshot-acceptance.md +20 -17
  60. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/multi-project-token-consistency.md +7 -9
  61. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/multi-stack-strategy.md +14 -10
  62. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/operational-processing-workflows.md +2 -0
  63. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/platform-mobile-patterns.md +3 -3
  64. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/product-lifecycle-acceptance-and-iteration.md +9 -6
  65. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/product-surface-patterns.md +3 -0
  66. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/source-map.md +37 -10
  67. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/tokens-and-components.md +8 -1
  68. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/ui-ux-audit.md +16 -5
  69. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/ui-ux-design-development.md +16 -5
  70. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/visual-craft.md +4 -2
  71. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/multi-tenant-isolation.md +1 -1
  72. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/SKILL.md +4 -1
  73. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/state-machine-task-patterns.md +2 -0
  74. package/dist/assets/marketplace/plugins/ccl-skills/skills/release-coordination/SKILL.md +1 -1
  75. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/SKILL.md +8 -8
  76. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/description-authoring.md +4 -0
  77. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/dual-track-review-gate.md +104 -5
  78. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/extraction-quickstart.md +11 -9
  79. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/r0-leakage-audit.md +102 -0
  80. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/source-register.md +103 -0
  81. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/source-to-skill-extraction.md +20 -0
  82. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/uiux-judgment-extraction.md +6 -6
  83. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/validation-and-landing.md +4 -3
  84. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/check-ccl-skills.sh +69 -2
  85. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/extraction_review_gate.sh +22 -0
  86. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/impact-chain-gate.rb +49 -4
  87. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/obligation-ledger.py +2748 -0
  88. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/register-firing-path-resolution.rb +20 -5
  89. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/shared_git_surface_gate.py +1142 -0
  90. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_regressions.sh +17 -0
  91. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_skill_catalog.sh +41 -4
  92. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_ci_checkout_ref_binding.sh +120 -0
  93. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_entrypoint_domain_scan_terms.sh +82 -8
  94. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_extraction_review_gate.sh +336 -0
  95. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_impact_chain_self_adjudication.sh +82 -10
  96. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_obligation_ledger.sh +1416 -0
  97. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_obligation_ledger_repo_audit.sh +57 -0
  98. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_register_firing_path_wiring.sh +141 -4
  99. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_routing_pointer_integrity.sh +3 -1
  100. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_shared_git_surface_gate.sh +1696 -0
  101. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_uiux_delivery_contract.sh +2117 -0
  102. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_uiux_loading_budget.sh +316 -0
  103. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_validate_extraction_review_state.sh +1176 -0
  104. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_validate_skill_cross_refs.sh +31 -1
  105. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/validate-skill.sh +9 -4
  106. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/validate_extraction_review_state.py +980 -0
  107. package/dist/assets/marketplace/plugins/ccl-skills/skills/terminal-cli-dev/SKILL.md +8 -6
  108. package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/classical-test-design-techniques.md +1 -1
  109. package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/tc-review-and-prioritization.md +1 -1
  110. package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/update-lifecycle.md +2 -0
  111. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/SKILL.md +16 -15
  112. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/ci-fixtures-and-flake-control.md +5 -1
  113. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/client-runtime-test-matrices.md +10 -2
  114. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/e2e-real-flow-testing.md +2 -2
  115. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/integration-contract-testing.md +10 -0
  116. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/test-code-authoring-patterns.md +2 -2
  117. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/test-topology-and-commands.md +1 -1
  118. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/SKILL.md +2 -1
  119. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/references/annotation-driven-revision.md +9 -0
  120. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/references/figure-and-table-craft.md +8 -2
  121. package/dist/assets/marketplace/plugins/ccl-skills/skills/web-react-dev/SKILL.md +7 -5
  122. package/dist/assets/marketplace/plugins/ccl-skills/skills/web-react-dev/references/complex-workspace-patterns.md +1 -1
  123. package/dist/assets/marketplace/plugins/ccl-skills/skills/web-react-dev/references/react-architecture.md +3 -0
  124. package/dist/assets/marketplace/plugins/ccl-skills/skills/web-react-dev/references/web-quality-release.md +37 -4
  125. package/dist/assets/marketplace/plugins/ccl-skills/skills/web-react-dev/references/web-ui-quality.md +10 -1
  126. package/dist/assets/release.json +215 -105
  127. package/package.json +1 -1
@@ -16,6 +16,9 @@
16
16
  # - test_check_ccl_skill_catalog.sh
17
17
  # - test_check_ccl_parallel_stack_parity.sh
18
18
  # - test_generic_r0_leak_scan.sh
19
+ # - test_shared_git_surface_gate.sh
20
+ # - test_extraction_review_gate.sh
21
+ # - test_validate_extraction_review_state.sh
19
22
  # - test_check_ccl_route_drift.sh
20
23
  # - test_check_sync_pointers.sh
21
24
  # - test_check_ccl_register_pending_exclusion.sh
@@ -25,6 +28,9 @@
25
28
  # - test_validate_skill_credential_cwd.sh
26
29
  # - test_validate_skill_root_depth.sh
27
30
  # - test_regression_runner_registration.sh
31
+ # - test_uiux_delivery_contract.sh
32
+ # - test_uiux_loading_budget.sh
33
+ # - test_obligation_ledger.sh
28
34
  # --full runs --fast plus the heavy full-checker regressions:
29
35
  # - test_check_ccl_r0_status.sh
30
36
  # - test_check_ccl_source_register_lifecycle.sh
@@ -105,6 +111,9 @@ fast_tests=(
105
111
  test_check_ccl_parallel_stack_parity.sh
106
112
  test_check_mr_target_freshness.sh
107
113
  test_generic_r0_leak_scan.sh
114
+ test_shared_git_surface_gate.sh
115
+ test_extraction_review_gate.sh
116
+ test_validate_extraction_review_state.sh
108
117
  test_check_ccl_route_drift.sh
109
118
  test_check_sync_pointers.sh
110
119
  test_check_ccl_register_pending_exclusion.sh
@@ -140,7 +149,10 @@ fast_tests=(
140
149
  test_regression_runner_lanes.sh
141
150
  test_routing_pointer_integrity.sh
142
151
  test_routing_bank_integrity.sh
152
+ test_uiux_delivery_contract.sh
153
+ test_uiux_loading_budget.sh
143
154
  test_governing_chain_diff.sh
155
+ test_obligation_ledger.sh
144
156
  # Owned by another skill package; run_test resolves it relative to SCRIPTS_DIR.
145
157
  # Registered here because this runner is the repo's only regression lane —
146
158
  # a skill-local test left unregistered is the false-green this file guards.
@@ -150,6 +162,11 @@ fast_tests=(
150
162
  heavy_tests=(
151
163
  test_check_ccl_r0_status.sh
152
164
  test_entrypoint_domain_scan_terms.sh
165
+ # Audits the REAL specs/065 mapping/ledger against the base SHA pinned in
166
+ # the ledger header. Catches carrier drift the synthetic obligation-ledger
167
+ # fixtures cannot see. Needs full history and walks a 1240-row real corpus,
168
+ # so it stays out of the pre-commit lane; CI --full enforces it.
169
+ test_obligation_ledger_repo_audit.sh
153
170
  test_check_ccl_source_register_lifecycle.sh
154
171
  # Clones the whole repo once; impact-chain cases call the standalone gate and
155
172
  # retain one full-checker wiring case. Still kept out of the pre-commit lane.
@@ -27,6 +27,7 @@ unset GIT_DIR GIT_WORK_TREE GIT_INDEX_FILE GIT_OBJECT_DIRECTORY \
27
27
  # c10 a row whose only clause is a redirect => skill_catalog_missing_use_line
28
28
  # c11 a leaf routed in the always-on layer => skill_bootstrap_leaf_in_region
29
29
  # c12 unset base override covers upstream/fallback x empty/changed diff
30
+ # c13 candidate-only skills and task banks are snapshotted, not read from HEAD
30
31
 
31
32
  SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
32
33
  REPO_ROOT="$(git -C "$SCRIPT_DIR" rev-parse --show-toplevel)"
@@ -37,6 +38,8 @@ CASE_INDEX=0
37
38
 
38
39
  # Each case gets its own clone so a mutation cannot leak into the next one.
39
40
  new_case() {
41
+ local candidate_skill_root="${1:-$REPO_ROOT}"
42
+ local candidate_eval_root="${2:-$REPO_ROOT}"
40
43
  CASE_INDEX=$((CASE_INDEX + 1))
41
44
  CASE_DIR="$TEST_ROOT/case$CASE_INDEX"
42
45
  git clone --quiet --no-local "$REPO_ROOT" "$CASE_DIR"
@@ -50,12 +53,17 @@ new_case() {
50
53
  exit 1
51
54
  }
52
55
  git -C "$CASE_DIR" update-ref refs/heads/ccl-test-base FETCH_HEAD
53
- # The clone carries the default branch; copy the working-tree versions of the
54
- # three files under test so the gate runs against what is about to land.
56
+ # The clone carries committed HEAD, while a newly added or removed skill or
57
+ # eval row can still exist only in the candidate working tree. Snapshot both
58
+ # owner roots and task banks so the pristine arm tests the tree that is about
59
+ # to land, not candidate contracts paired with old evaluation surfaces.
60
+ rm -rf "$CASE_DIR/skills"
61
+ mkdir -p "$CASE_DIR/skills"
62
+ cp -R "$candidate_skill_root/skills/." "$CASE_DIR/skills/"
55
63
  cp "$REPO_ROOT/docs/SKILLS.md" "$CASE_DIR/docs/SKILLS.md"
56
64
  cp "$REPO_ROOT/agent-context/session-start.md" "$CASE_DIR/agent-context/session-start.md"
57
- cp "$REPO_ROOT/skills/skill-extraction-workflow/scripts/check-ccl-skills.sh" \
58
- "$CASE_DIR/skills/skill-extraction-workflow/scripts/check-ccl-skills.sh"
65
+ cp "$candidate_eval_root/eval/routing-tasks.jsonl" "$CASE_DIR/eval/routing-tasks.jsonl"
66
+ cp "$candidate_eval_root/eval/behavior-fixtures.jsonl" "$CASE_DIR/eval/behavior-fixtures.jsonl"
59
67
  }
60
68
 
61
69
  run_case() {
@@ -495,4 +503,33 @@ expect_base_alias_tags_removed c12-fallback-changed
495
503
  run_with_hostile_git_context run_case_with_default_base || :
496
504
  expect_changed_entrypoint_warning c12-fallback-changed "$DEFAULT_CHANGED_SKILL"
497
505
 
506
+ # c13 — a pristine candidate may contain skill roots and task-bank rows that do
507
+ # not exist at committed HEAD yet. Prove new_case copies all three candidate
508
+ # surfaces. The markers stay only in TEST_ROOT and never enter a checker run.
509
+ CANDIDATE_ROOT="$TEST_ROOT/candidate-root"
510
+ mkdir -p "$CANDIDATE_ROOT/eval" \
511
+ "$CANDIDATE_ROOT/skills/catalog-candidate-snapshot"
512
+ printf '%s\n' 'catalog-candidate-skill-snapshot' \
513
+ >"$CANDIDATE_ROOT/skills/catalog-candidate-snapshot/marker.txt"
514
+ cp "$REPO_ROOT/eval/routing-tasks.jsonl" "$CANDIDATE_ROOT/eval/routing-tasks.jsonl"
515
+ cp "$REPO_ROOT/eval/behavior-fixtures.jsonl" "$CANDIDATE_ROOT/eval/behavior-fixtures.jsonl"
516
+ printf '%s\n' '{"id":"route-catalog-candidate-snapshot"}' \
517
+ >>"$CANDIDATE_ROOT/eval/routing-tasks.jsonl"
518
+ printf '%s\n' '{"id":"F-catalog-candidate-snapshot"}' \
519
+ >>"$CANDIDATE_ROOT/eval/behavior-fixtures.jsonl"
520
+ new_case "$CANDIDATE_ROOT" "$CANDIDATE_ROOT"
521
+ grep -Fq 'catalog-candidate-skill-snapshot' \
522
+ "$CASE_DIR/skills/catalog-candidate-snapshot/marker.txt" || {
523
+ echo 'FAIL[c13]: candidate skill roots were not snapshotted' >&2
524
+ exit 1
525
+ }
526
+ grep -Fq 'route-catalog-candidate-snapshot' "$CASE_DIR/eval/routing-tasks.jsonl" || {
527
+ echo 'FAIL[c13]: candidate routing bank was not snapshotted' >&2
528
+ exit 1
529
+ }
530
+ grep -Fq 'F-catalog-candidate-snapshot' "$CASE_DIR/eval/behavior-fixtures.jsonl" || {
531
+ echo 'FAIL[c13]: candidate behavior bank was not snapshotted' >&2
532
+ exit 1
533
+ }
534
+
498
535
  echo "test_check_ccl_skill_catalog: ok"
@@ -42,6 +42,34 @@ import re, sys
42
42
  path, jobs = sys.argv[1], sys.argv[2:]
43
43
  src = open(path, encoding="utf8").read()
44
44
 
45
+ # PR text is mutable without a new commit. The metadata gate must rerun when a
46
+ # title or body edit is the only event, not only when the branch SHA changes.
47
+ trigger = re.search(r"^ pull_request:\s*\n((?: {4}.*\n)*)", src, re.M)
48
+ if trigger is None or not re.search(r"\bedited\b", trigger.group(1)):
49
+ print(
50
+ "FAIL: pull_request trigger does not include `edited`; PR text changes "
51
+ "would bypass the shared Git/PR metadata gate",
52
+ file=sys.stderr,
53
+ )
54
+ sys.exit(1)
55
+
56
+ # The shared metadata gate is also the backstop for authorized direct landing
57
+ # pushes. Both landing branches must trigger CI; the local hook is opt-in.
58
+ push_trigger = re.search(r"^ push:\s*\n((?: {4}.*\n)*)", src, re.M)
59
+ branches = set()
60
+ if push_trigger is not None:
61
+ branch_row = re.search(r"branches:\s*\[([^]]*)\]", push_trigger.group(1))
62
+ if branch_row is not None:
63
+ branches = {item.strip() for item in branch_row.group(1).split(",") if item.strip()}
64
+ missing_push_branches = {"dev", "main"} - branches
65
+ if missing_push_branches:
66
+ print(
67
+ "FAIL: push trigger does not cover landing branch(es): "
68
+ + ", ".join(sorted(missing_push_branches)),
69
+ file=sys.stderr,
70
+ )
71
+ sys.exit(1)
72
+
45
73
  # Split the jobs: mapping stanza at exactly two spaces of indent.
46
74
  job_starts = [(m.start(), m.group(1)) for m in re.finditer(r"^ ([A-Za-z0-9_-]+):$", src, re.M)]
47
75
  if not job_starts:
@@ -76,10 +104,102 @@ for job in jobs:
76
104
  if "fetch-depth: 0" not in body:
77
105
  failures.append(f"{job}: no full history, so the gate cannot resolve its base")
78
106
 
107
+ repository_body = bounds.get("repository-gates", "")
108
+ step_start = re.search(
109
+ r"^ - name:\s*Repository gate suite\s*$", repository_body, re.M
110
+ )
111
+ repository_step = ""
112
+ if step_start is None:
113
+ failures.append(
114
+ "repository-gates: `Repository gate suite` step is missing"
115
+ )
116
+ else:
117
+ next_step = re.search(r"^ - ", repository_body[step_start.end() :], re.M)
118
+ step_end = (
119
+ step_start.end() + next_step.start()
120
+ if next_step is not None
121
+ else len(repository_body)
122
+ )
123
+ repository_step = repository_body[step_start.start() : step_end]
124
+
125
+ if repository_step:
126
+ if not re.search(
127
+ r"^\s+CANDIDATE_BASE_REF:\s*\$\{\{\s*"
128
+ r"github\.event\.pull_request\.base\.sha\s*\|\|\s*"
129
+ r"github\.event\.before\s*\}\}\s*$",
130
+ repository_step,
131
+ re.M,
132
+ ):
133
+ failures.append(
134
+ "repository-gates: `Repository gate suite` does not bind the PR "
135
+ "base SHA with the pre-push event fallback; the commit range could "
136
+ "collapse to HEAD and silently scan zero candidate commits"
137
+ )
138
+ if not re.search(
139
+ r'^\s+if\s+\[\[\s+-n\s+"\$CANDIDATE_BASE_REF"\s+\]\]\s+&&\s+'
140
+ r'git\s+merge-base\s+"\$CANDIDATE_BASE_REF"\s+HEAD\s+'
141
+ r'>/dev/null\s+2>&1;\s+then\s*$\n'
142
+ r'^\s+export\s+CCL_SKILL_BASE_REF="\$CANDIDATE_BASE_REF"\s*$\n'
143
+ r'^\s+fi\s*$\n'
144
+ r"^\s+make test-repo-gates\s*$",
145
+ repository_step,
146
+ re.M,
147
+ ):
148
+ failures.append(
149
+ "repository-gates: `Repository gate suite` must validate the "
150
+ "candidate base, export it, then invoke `make test-repo-gates` in "
151
+ "that order; otherwise the metadata gate can scan the wrong range"
152
+ )
153
+
79
154
  if failures:
80
155
  for f in failures:
81
156
  print(f"FAIL: {f}", file=sys.stderr)
82
157
  sys.exit(1)
83
158
  PY
84
159
 
160
+ default_make_dry_run="$(make --no-print-directory -n -C "$ROOT" test-repo-gates)"
161
+ override_make_dry_run="$(
162
+ make --no-print-directory -n -C "$ROOT" \
163
+ CCL_SKILL_DEFAULT_BASE_REF=refs/remotes/upstream/dev test-repo-gates
164
+ )"
165
+ python3 - "$default_make_dry_run" "$override_make_dry_run" <<'PY'
166
+ import shlex
167
+ import sys
168
+
169
+
170
+ def default_base(dry_run: str) -> str:
171
+ commands = [
172
+ line
173
+ for line in dry_run.splitlines()
174
+ if "shared_git_surface_gate.py" in line
175
+ ]
176
+ if len(commands) != 1:
177
+ raise SystemExit(
178
+ "FAIL: test-repo-gates must invoke the shared Git/PR metadata gate once"
179
+ )
180
+ tokens = shlex.split(commands[0])
181
+ if tokens.count("--default-base-ref") != 1:
182
+ raise SystemExit(
183
+ "FAIL: test-repo-gates must pass exactly one --default-base-ref"
184
+ )
185
+ index = tokens.index("--default-base-ref")
186
+ if index + 1 >= len(tokens):
187
+ raise SystemExit("FAIL: --default-base-ref has no value")
188
+ return tokens[index + 1]
189
+
190
+
191
+ default_value = default_base(sys.argv[1])
192
+ override_value = default_base(sys.argv[2])
193
+ if default_value != "origin/dev":
194
+ raise SystemExit(
195
+ f"FAIL: test-repo-gates compatibility default is {default_value!r}, "
196
+ "expected 'origin/dev'"
197
+ )
198
+ if override_value != "refs/remotes/upstream/dev":
199
+ raise SystemExit(
200
+ f"FAIL: caller default-base override resolved to {override_value!r}, "
201
+ "expected 'refs/remotes/upstream/dev'"
202
+ )
203
+ PY
204
+
85
205
  echo "test_ci_checkout_ref_binding: ok (gate lanes judge the branch head, not the merge ref)"
@@ -13,8 +13,12 @@
13
13
  # Leg 1 (wiring) : the real checker runs the scan and reports it clean here.
14
14
  # Leg 2 (predicate): the retained terms still MATCH — the scan can still fail.
15
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.
16
+ # Leg 4 (public IDs): canonical DOI/W3C identifiers pass; arbitrary paths,
17
+ # attached IDs, query/fragment IDs, noncanonical hosts, and
18
+ # another long ID on the same line all still fail.
19
+ # Leg 5 (failure): a planted retained-domain term prevents certification.
20
+ # Legs 2-3 read the lexical pattern out of the real script, so they cannot drift
21
+ # away from what ships; extraction failure is a hard error, never a silent pass.
18
22
  set -euo pipefail
19
23
 
20
24
  SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
@@ -60,20 +64,16 @@ retained=(
60
64
  for term in "${retained[@]}"; do
61
65
  matches "x ${term} y" || fail "retained domain term no longer matches — the scan was widened/broken, not narrowed"
62
66
  done
63
- # Non-vocabulary alternatives in the same pattern must also still bite.
67
+ # Non-vocabulary host alternatives in the same pattern must also still bite.
64
68
  matches 'see code.example-host.internal for details' \
65
69
  || fail "host-style leak alternative no longer matches"
66
- matches 'ref 123456789' || fail "long-digit alternative no longer matches"
67
70
 
68
71
  # --- Leg 3: the retired term must NOT match, in ordinary prose.
69
72
  retired=$'扫描'
70
73
  ! matches "先跑一遍${retired}再判" \
71
74
  || fail "retired term still blocks ordinary prose; the retirement did not land"
72
75
 
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.
76
+ # --- Leg 4: public identifier allowlist is precise, not line-wide.
77
77
  # Runs against a throwaway --shared clone so the real tree is never written.
78
78
  TMP="$(mktemp -d "${TMPDIR:-/tmp}/domscan.XXXXXX")"
79
79
  trap 'rm -rf "$TMP"' EXIT
@@ -95,6 +95,80 @@ case "$ctl" in
95
95
  esac
96
96
  probe_dir="$TMP/repo/skills/tighten-doc/references"
97
97
  [ -d "$probe_dir" ] || fail "clone has no reference dir to plant the probe in: $probe_dir"
98
+ public_probe="$probe_dir/_public_identifier_probe.md"
99
+ printf '%s\n' \
100
+ '# public identifiers' \
101
+ 'https://doi.org/10.1207/s15516709cog1202_4' \
102
+ 'https://doi.org/10.1038/35057062' \
103
+ 'https://www.w3.org/community/reports/design-tokens/CG-FINAL-format-20251028/' \
104
+ > "$public_probe"
105
+ set +e
106
+ public_out="$(bash "$CHECK_SCRIPT" "$TMP/repo" 2>&1)"
107
+ public_rc=$?
108
+ set -e
109
+ [ "$public_rc" -eq 0 ] || fail "canonical public DOI/W3C identifiers were rejected\n$public_out"
110
+ case "$public_out" in
111
+ *entrypoint_and_reference_domain_scan_ok*) : ;;
112
+ *) fail "public-identifier fixture did not reach the clean domain sentinel\n$public_out" ;;
113
+ esac
114
+
115
+ printf '%s\n' \
116
+ '# invalid public-identifier shapes' \
117
+ 'same-line-id 123456789 https://doi.org/10.1207/s15516709cog1202_4' \
118
+ 'arbitrary-doi-path https://doi.org/not-a-doi/123456789' \
119
+ 'arbitrary-report-path https://www.w3.org/community/reports/not-a-report/123456789' \
120
+ 'query-id https://doi.org/10.1207/s15516709cog1202_4?object=123456789' \
121
+ 'fragment-id https://doi.org/10.1207/s15516709cog1202_4#123456789' \
122
+ 'noncanonical-host https://doi.example.org/10.1207/123456789' \
123
+ 'attached-report-id https://www.w3.org/community/reports/design-tokens/CG-FINAL-format-20251028/123456789' \
124
+ 'laundered-suffix-id https://doi.org/10.1234/20260830123456' \
125
+ 'split-run-id https://doi.org/10.1234/123456789-123456789' \
126
+ 'split-timestamp-id https://doi.org/10.1234/20260830-123456' \
127
+ 'double-separator-id https://doi.org/10.1234/20260830--123456' \
128
+ 'plus-split-id https://doi.org/10.1234/123456789+123456789' \
129
+ 'colon-split-id https://doi.org/10.1234/123456789:123456789' \
130
+ 'report-name-id https://www.w3.org/community/reports/design-tokens/CG-FINAL-123456789-format-20251028/' \
131
+ 'registrant-id https://doi.org/10.123456789/abc' \
132
+ > "$public_probe"
133
+ set +e
134
+ numeric_out="$(bash "$CHECK_SCRIPT" "$TMP/repo" 2>&1)"
135
+ numeric_rc=$?
136
+ set -e
137
+ [ "$numeric_rc" -ne 0 ] || fail "an invalid public-identifier shape escaped the scan"
138
+ case "$numeric_out" in
139
+ *entrypoint_or_reference_domain_scan_failed*) : ;;
140
+ *) fail "long-ID fixture did not raise the domain-scan failure token\n$numeric_out" ;;
141
+ esac
142
+ case "$numeric_out" in
143
+ *_public_identifier_probe.md*) : ;;
144
+ *) fail "long-ID failure did not name the public-identifier fixture\n$numeric_out" ;;
145
+ esac
146
+ for marker in \
147
+ same-line-id \
148
+ arbitrary-doi-path \
149
+ arbitrary-report-path \
150
+ query-id \
151
+ fragment-id \
152
+ noncanonical-host \
153
+ attached-report-id \
154
+ laundered-suffix-id \
155
+ split-run-id \
156
+ split-timestamp-id \
157
+ double-separator-id \
158
+ plus-split-id \
159
+ colon-split-id \
160
+ report-name-id \
161
+ registrant-id; do
162
+ case "$numeric_out" in
163
+ *"$marker"*) : ;;
164
+ *) fail "invalid identifier class escaped the scan: $marker\n$numeric_out" ;;
165
+ esac
166
+ done
167
+ rm "$public_probe"
168
+
169
+ # --- Leg 5: the checker must still FAIL end-to-end on a planted lexical leak.
170
+ # Legs 1-4 cannot see a broken lexical failure branch. Without this leg an
171
+ # inverted or bypassed conditional would keep the whole suite green.
98
172
  printf '# probe\n\nx %s y\n' "${retained[0]}" > "$probe_dir/_domain_scan_probe.md"
99
173
  set +e
100
174
  e2e="$(bash "$CHECK_SCRIPT" "$TMP/repo" 2>&1)"