@ccoalm/ccl-skills 0.6.2 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/hooks.json +11 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/remind-unverified-cli-flag.sh +309 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/test_remind_unverified_cli_flag.sh +483 -0
- package/dist/assets/marketplace/plugins/ccl-skills/packages/opencode-plugin/ccl-skills.ts +5 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/app-cross-platform-dev/SKILL.md +10 -8
- package/dist/assets/marketplace/plugins/ccl-skills/skills/app-cross-platform-dev/references/mobile-quality-release.md +1 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/SKILL.md +16 -17
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/references/client-routing.md +1 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/references/staged-review-contract.md +195 -7
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/references/timeout-auth-and-capabilities.md +3 -3
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/claude_review.sh +13 -5
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/codex_review.sh +9 -3
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/kimi_review.sh +9 -3
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/normalize_review_timeout.sh +22 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/opencode_review.sh +9 -3
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/review_gate.py +1540 -129
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_claude_review_probe.sh +8 -3
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_review_client_compat.py +76 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_review_gate.sh +1858 -3
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_update_review_plan_intent.sh +789 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/update_review_plan_intent.py +513 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/SKILL.md +1 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/architecture-playbook.md +2 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/data-platform-architecture.md +1 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/event-driven-architecture.md +14 -11
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/multi-tenant-isolation.md +2 -2
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/SKILL.md +5 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/SKILL.md +2 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/miniapp-product-dev/SKILL.md +13 -11
- package/dist/assets/marketplace/plugins/ccl-skills/skills/nodejs-service-dev/SKILL.md +64 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/nodejs-service-dev/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/nodejs-service-dev/references/async-lifecycle-and-performance.md +72 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/nodejs-service-dev/references/runtime-and-project-contract.md +58 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/nodejs-service-dev/references/source-map.md +41 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/nodejs-service-dev/references/verification-diagnostics-and-security.md +63 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/SKILL.md +1 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/references/sli-slo-design.md +25 -9
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/references/source-register.md +1 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/SKILL.md +1 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/promotion-gate-and-review.md +16 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/secret-and-config-management.md +7 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/retry-timeout-circuit-breaker.md +11 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/SKILL.md +8 -10
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/design-routing-and-readiness.md +10 -14
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/verify-developer-experience.md +1 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/SKILL.md +135 -86
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/behavioral-aesthetic-logic.md +66 -80
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/delivery-contract.md +275 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/design-execution-checklist.md +88 -214
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/design-impl-naming-and-versioning.md +2 -2
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/design-intake-and-acceptance.md +10 -8
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/design-system-source-of-truth.md +4 -5
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/external-ui-ux-quality-benchmarks.md +112 -95
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/frontend-code-evidence-map.md +30 -21
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/interaction-design-patterns.md +22 -3
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/layout-recipes-and-screenshot-acceptance.md +20 -17
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/multi-project-token-consistency.md +7 -9
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/multi-stack-strategy.md +14 -10
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/operational-processing-workflows.md +2 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/platform-mobile-patterns.md +1 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/product-lifecycle-acceptance-and-iteration.md +9 -6
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/product-surface-patterns.md +3 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/source-map.md +37 -10
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/tokens-and-components.md +7 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/ui-ux-audit.md +8 -5
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/ui-ux-design-development.md +16 -5
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/visual-craft.md +4 -2
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/SKILL.md +5 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/architecture-playbook.md +1 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/audit-history-architecture.md +31 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/data-platform-architecture.md +1 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/event-driven-architecture.md +7 -4
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/multi-tenant-isolation.md +2 -2
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/notification-architecture.md +28 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/packaging-runtime-readiness.md +1 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/replay-comparison-architecture.md +28 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/workflow-state-architecture.md +39 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/SKILL.md +10 -7
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/ai-service-wiring-patterns.md +8 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/audit-history-patterns.md +29 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/background-job-patterns.md +16 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/batch-and-artifact-patterns.md +25 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/notification-patterns.md +40 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/public-api-security-patterns.md +1 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/replay-comparison-patterns.md +30 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/state-machine-task-patterns.md +48 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/testing-and-quality-patterns.md +10 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/release-coordination/SKILL.md +2 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/SKILL.md +4 -4
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/coverage-exhaustion-traps.md +45 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/dual-track-review-gate.md +142 -4
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/external-practice-controls.md +21 -2
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/extraction-quickstart.md +11 -9
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/firing-point-placement.md +8 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/parallel-stack-references-pattern.md +5 -4
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/r0-leakage-audit.md +102 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/source-register.md +69 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/source-to-skill-extraction.md +10 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/uiux-judgment-extraction.md +6 -6
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/validation-and-landing.md +4 -3
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/check-ccl-skills.sh +93 -2
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/check-parallel-stack-parity.sh +119 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/extraction_review_gate.sh +22 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/impact-chain-gate.rb +49 -4
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/obligation-ledger.py +2748 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/register-firing-path-resolution.rb +20 -5
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/shared_git_surface_gate.py +1142 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_parallel_stack_parity.sh +183 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_regressions.sh +19 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_skill_catalog.sh +41 -4
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_ci_checkout_ref_binding.sh +120 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_entrypoint_domain_scan_terms.sh +82 -8
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_extraction_review_gate.sh +336 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_impact_chain_self_adjudication.sh +82 -10
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_obligation_ledger.sh +1416 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_obligation_ledger_repo_audit.sh +57 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_register_firing_path_wiring.sh +141 -4
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_routing_pointer_integrity.sh +3 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_shared_git_surface_gate.sh +1696 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_uiux_delivery_contract.sh +2117 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_uiux_loading_budget.sh +316 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_validate_extraction_review_state.sh +1176 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_validate_skill_cross_refs.sh +31 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/validate-skill.sh +9 -4
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/validate_extraction_review_state.py +980 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/terminal-cli-dev/SKILL.md +9 -6
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/SKILL.md +11 -11
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/client-runtime-test-matrices.md +10 -2
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/fitness-functions.md +16 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/scenario-testing.md +1 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/test-code-authoring-patterns.md +16 -5
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/SKILL.md +5 -3
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/references/delivery-face-closeout.md +16 -6
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/references/self-benchmark-baseline.md +37 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/web-react-dev/SKILL.md +7 -5
- package/dist/assets/marketplace/plugins/ccl-skills/skills/web-react-dev/references/complex-workspace-patterns.md +1 -1
- package/dist/assets/release.json +275 -105
- package/package.json +1 -1
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Integration test for check-parallel-stack-parity.sh (the cross-file mirror gate
|
|
3
|
+
# wired into check-ccl-skills.sh). Builds throwaway sibling trees so verdicts are
|
|
4
|
+
# DETERMINISTIC and do not depend on the real repository's current file content.
|
|
5
|
+
#
|
|
6
|
+
# Cases:
|
|
7
|
+
# a. identical mirrored regions + differing stack-glue => exit 0, ok marker
|
|
8
|
+
# b. one-word drift inside the mirrored region => exit 1, parity_drift + FAIL marker
|
|
9
|
+
# c. dual-tree routing text identical on both sides => exit 0 (the supported shape)
|
|
10
|
+
# d. one-sided sibling-name / routing-reference divergence => exit 1, parity_drift (no normalization)
|
|
11
|
+
# e. missing sibling file => exit 1, parity_missing_file
|
|
12
|
+
# f. missing marker headings => exit 1, parity_malformed_markers
|
|
13
|
+
# g. stop heading duplicated => exit 1, parity_malformed_markers
|
|
14
|
+
# h. canonical (non-routing-mapped) reference swapped one side => exit 1, parity_drift
|
|
15
|
+
# j. extra trailing blank line before one side's stack-glue H2 => exit 1, parity_drift
|
|
16
|
+
# k. unreadable pair file => exit 2, parity_infra
|
|
17
|
+
set -euo pipefail
|
|
18
|
+
|
|
19
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
|
|
20
|
+
PARITY_SCRIPT="$SCRIPT_DIR/check-parallel-stack-parity.sh"
|
|
21
|
+
[ -f "$PARITY_SCRIPT" ] || { echo "FAIL: parity script not found: $PARITY_SCRIPT" >&2; exit 1; }
|
|
22
|
+
|
|
23
|
+
TMP="$(mktemp -d "${TMPDIR:-/tmp}/stackparity.XXXXXX")"
|
|
24
|
+
trap 'rm -rf "$TMP"' EXIT
|
|
25
|
+
|
|
26
|
+
fail() { echo "FAIL: $*" >&2; exit 1; }
|
|
27
|
+
assert_rc() { [ "$1" = "$2" ] || fail "expected rc=$2 got rc=$1${3:+ ($3)}"; }
|
|
28
|
+
assert_contains() { case "$2" in *"$1"*) : ;; *) fail "expected output to contain: $1${3:+ ($3)}";; esac; }
|
|
29
|
+
assert_not_contains() { case "$2" in *"$1"*) fail "expected output NOT to contain: $1${3:+ ($3)}";; *) : ;; esac; }
|
|
30
|
+
|
|
31
|
+
PY_REFS="$TMP/skills/python-service-architecture/references"
|
|
32
|
+
GO_REFS="$TMP/skills/go-microservice-architecture/references"
|
|
33
|
+
mkdir -p "$PY_REFS" "$GO_REFS"
|
|
34
|
+
|
|
35
|
+
# write_pair <mirrored-body-file-py> <mirrored-body-file-go>
|
|
36
|
+
# Wraps each body in the standard skeleton: title + mirrored region + stack glue.
|
|
37
|
+
write_pair() {
|
|
38
|
+
local name="$1" py_body="$2" go_body="$3"
|
|
39
|
+
{
|
|
40
|
+
echo "# $name (Python)"
|
|
41
|
+
echo
|
|
42
|
+
echo "Sibling: go-microservice-architecture mirrors this file."
|
|
43
|
+
echo
|
|
44
|
+
printf '%s\n' "$py_body"
|
|
45
|
+
echo "## Python-specific implementation patterns"
|
|
46
|
+
echo
|
|
47
|
+
echo "- Python glue: asyncio consumer shape."
|
|
48
|
+
} > "$PY_REFS/$name.md"
|
|
49
|
+
{
|
|
50
|
+
echo "# $name (Go)"
|
|
51
|
+
echo
|
|
52
|
+
echo "Sibling: python-service-architecture mirrors this file."
|
|
53
|
+
echo
|
|
54
|
+
printf '%s\n' "$go_body"
|
|
55
|
+
echo "## Go-specific implementation patterns"
|
|
56
|
+
echo
|
|
57
|
+
echo "- Go glue: goroutine consumer shape."
|
|
58
|
+
} > "$GO_REFS/$name.md"
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
MIRROR_BASE='## When this applies / does not apply
|
|
62
|
+
|
|
63
|
+
Apply when the service publishes durable events.
|
|
64
|
+
Skip when it only does in-process pub-sub (use `local-a.md` instead).
|
|
65
|
+
The sibling tree is maintained by python-service-architecture and go-microservice-architecture maintainers.
|
|
66
|
+
|
|
67
|
+
## Operations checklist
|
|
68
|
+
|
|
69
|
+
- Delivery semantics declared explicitly.
|
|
70
|
+
'
|
|
71
|
+
|
|
72
|
+
# The gate iterates a fixed pair list; give all three names the same skeleton, then
|
|
73
|
+
# vary the one under test per case.
|
|
74
|
+
seed_all_identical() {
|
|
75
|
+
write_pair "event-driven-architecture" "$MIRROR_BASE" "$MIRROR_BASE"
|
|
76
|
+
write_pair "multi-tenant-isolation" "$MIRROR_BASE" "$MIRROR_BASE"
|
|
77
|
+
write_pair "data-platform-architecture" "$MIRROR_BASE" "$MIRROR_BASE"
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
run_gate() {
|
|
81
|
+
set +e
|
|
82
|
+
OUT="$(bash "$PARITY_SCRIPT" "$TMP" 2>&1)"
|
|
83
|
+
RC=$?
|
|
84
|
+
set -e
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
# --- case a: identical mirrored regions, differing glue => ok
|
|
88
|
+
seed_all_identical
|
|
89
|
+
run_gate
|
|
90
|
+
assert_rc "$RC" 0 "case a"
|
|
91
|
+
assert_contains "parallel_stack_parity_ok" "$OUT" "case a"
|
|
92
|
+
|
|
93
|
+
# --- case b: one-word drift in a mirrored region => FAIL naming the pair
|
|
94
|
+
GO_DRIFT="${MIRROR_BASE/durable events/durable events plus commands}"
|
|
95
|
+
write_pair "event-driven-architecture" "$MIRROR_BASE" "$GO_DRIFT"
|
|
96
|
+
run_gate
|
|
97
|
+
assert_rc "$RC" 1 "case b"
|
|
98
|
+
assert_contains "parity_drift: event-driven-architecture.md" "$OUT" "case b"
|
|
99
|
+
assert_contains "parallel_stack_parity_FAIL" "$OUT" "case b"
|
|
100
|
+
|
|
101
|
+
# --- case c: the supported dual-tree routing shape — identical bytes on both sides => ok
|
|
102
|
+
DUAL="${MIRROR_BASE/\`local-a.md\`/\`api-contract-and-schema.md\` on the Python tree \/ \`protobuf-contract-architecture.md\` on the Go tree}"
|
|
103
|
+
write_pair "event-driven-architecture" "$DUAL" "$DUAL"
|
|
104
|
+
run_gate
|
|
105
|
+
assert_rc "$RC" 0 "case c"
|
|
106
|
+
assert_contains "parallel_stack_parity_ok" "$OUT" "case c"
|
|
107
|
+
|
|
108
|
+
# --- case d: one-sided divergence is drift — there is NO normalization to hide behind
|
|
109
|
+
# (d1: a routing reference differing per side; d2: an asymmetric sibling-name mention)
|
|
110
|
+
PY_REFS_BODY="${MIRROR_BASE/\`local-a.md\`/\`api-contract-and-schema.md\`}"
|
|
111
|
+
GO_REFS_BODY="${MIRROR_BASE/\`local-a.md\`/\`protobuf-contract-architecture.md\`}"
|
|
112
|
+
write_pair "event-driven-architecture" "$PY_REFS_BODY" "$GO_REFS_BODY"
|
|
113
|
+
run_gate
|
|
114
|
+
assert_rc "$RC" 1 "case d1"
|
|
115
|
+
assert_contains "parity_drift: event-driven-architecture.md" "$OUT" "case d1"
|
|
116
|
+
PY_NAME_BODY="${MIRROR_BASE/python-service-architecture and go-microservice-architecture/python-service-architecture}"
|
|
117
|
+
GO_NAME_BODY="${MIRROR_BASE/python-service-architecture and go-microservice-architecture/go-microservice-architecture}"
|
|
118
|
+
write_pair "event-driven-architecture" "$PY_NAME_BODY" "$GO_NAME_BODY"
|
|
119
|
+
run_gate
|
|
120
|
+
assert_rc "$RC" 1 "case d2"
|
|
121
|
+
assert_contains "parity_drift: event-driven-architecture.md" "$OUT" "case d2"
|
|
122
|
+
|
|
123
|
+
# --- case e: missing sibling file => FAIL with missing token
|
|
124
|
+
rm "$GO_REFS/event-driven-architecture.md"
|
|
125
|
+
run_gate
|
|
126
|
+
assert_rc "$RC" 1 "case e"
|
|
127
|
+
assert_contains "parity_missing_file: event-driven-architecture.md" "$OUT" "case e"
|
|
128
|
+
|
|
129
|
+
# --- case f: start marker missing => FAIL with malformed-markers token
|
|
130
|
+
seed_all_identical
|
|
131
|
+
printf '# t\n\nno markers here\n\n## Go-specific implementation patterns\n\nx\n' > "$GO_REFS/multi-tenant-isolation.md"
|
|
132
|
+
run_gate
|
|
133
|
+
assert_rc "$RC" 1 "case f"
|
|
134
|
+
assert_contains "parity_malformed_markers: multi-tenant-isolation.md" "$OUT" "case f"
|
|
135
|
+
|
|
136
|
+
# --- case g: stop heading duplicated => FAIL with malformed-markers token (a missing or
|
|
137
|
+
# doubled stop must not silently fall through to a drift/ok verdict)
|
|
138
|
+
seed_all_identical
|
|
139
|
+
printf '\n## Go-specific implementation patterns\n\n- dup glue\n' >> "$GO_REFS/event-driven-architecture.md"
|
|
140
|
+
run_gate
|
|
141
|
+
assert_rc "$RC" 1 "case g"
|
|
142
|
+
assert_contains "parity_malformed_markers: event-driven-architecture.md" "$OUT" "case g"
|
|
143
|
+
|
|
144
|
+
# --- case h: canonical-pointer swap on one side only stays drift
|
|
145
|
+
seed_all_identical
|
|
146
|
+
PY_CANON="${MIRROR_BASE/Delivery semantics declared explicitly./Delivery semantics declared explicitly per \`data-modeling-and-migrations.md\`.}"
|
|
147
|
+
GO_CANON="${MIRROR_BASE/Delivery semantics declared explicitly./Delivery semantics declared explicitly per \`background-jobs-and-scheduling.md\`.}"
|
|
148
|
+
write_pair "event-driven-architecture" "$PY_CANON" "$GO_CANON"
|
|
149
|
+
run_gate
|
|
150
|
+
assert_rc "$RC" 1 "case h"
|
|
151
|
+
assert_contains "parity_drift: event-driven-architecture.md" "$OUT" "case h"
|
|
152
|
+
|
|
153
|
+
# --- case i: prefix/suffix-gamed stop heading => malformed, not silent region shrink
|
|
154
|
+
seed_all_identical
|
|
155
|
+
python_side="$PY_REFS/event-driven-architecture.md"
|
|
156
|
+
sed_inplace() { local expr="$1" file="$2"; sed "$expr" "$file" > "$file.tmp" && mv "$file.tmp" "$file"; }
|
|
157
|
+
sed_inplace 's/^## Python-specific implementation patterns$/## Python-specific implementation patterns (v2)/' "$python_side"
|
|
158
|
+
run_gate
|
|
159
|
+
assert_rc "$RC" 1 "case i"
|
|
160
|
+
assert_contains "parity_malformed_markers: event-driven-architecture.md" "$OUT" "case i"
|
|
161
|
+
|
|
162
|
+
# --- case j: extra blank line immediately before one side's stack-specific H2 — command
|
|
163
|
+
# substitution strips trailing newlines, so the gate must compare region FILES, not strings
|
|
164
|
+
seed_all_identical
|
|
165
|
+
python_side="$PY_REFS/event-driven-architecture.md"
|
|
166
|
+
awk '/^## Python-specific implementation patterns$/{print ""} {print}' "$python_side" > "$python_side.tmp" && mv "$python_side.tmp" "$python_side"
|
|
167
|
+
run_gate
|
|
168
|
+
assert_rc "$RC" 1 "case j"
|
|
169
|
+
assert_contains "parity_drift: event-driven-architecture.md" "$OUT" "case j"
|
|
170
|
+
|
|
171
|
+
# --- case k: unreadable pair file => infrastructure failure (exit 2), never a content verdict
|
|
172
|
+
seed_all_identical
|
|
173
|
+
chmod 000 "$GO_REFS/event-driven-architecture.md"
|
|
174
|
+
if [ -r "$GO_REFS/event-driven-architecture.md" ]; then
|
|
175
|
+
echo "SKIP case k: file still readable (running as root?)"
|
|
176
|
+
else
|
|
177
|
+
run_gate
|
|
178
|
+
assert_rc "$RC" 2 "case k"
|
|
179
|
+
assert_contains "parity_infra" "$OUT" "case k"
|
|
180
|
+
fi
|
|
181
|
+
chmod 644 "$GO_REFS/event-driven-architecture.md"
|
|
182
|
+
|
|
183
|
+
echo "test_check_ccl_parallel_stack_parity_ok"
|
|
@@ -14,7 +14,11 @@
|
|
|
14
14
|
# - test_controlled_escalation_pins.sh
|
|
15
15
|
# - test_check_ccl_size_budget.sh
|
|
16
16
|
# - test_check_ccl_skill_catalog.sh
|
|
17
|
+
# - test_check_ccl_parallel_stack_parity.sh
|
|
17
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
|
|
18
22
|
# - test_check_ccl_route_drift.sh
|
|
19
23
|
# - test_check_sync_pointers.sh
|
|
20
24
|
# - test_check_ccl_register_pending_exclusion.sh
|
|
@@ -24,6 +28,9 @@
|
|
|
24
28
|
# - test_validate_skill_credential_cwd.sh
|
|
25
29
|
# - test_validate_skill_root_depth.sh
|
|
26
30
|
# - test_regression_runner_registration.sh
|
|
31
|
+
# - test_uiux_delivery_contract.sh
|
|
32
|
+
# - test_uiux_loading_budget.sh
|
|
33
|
+
# - test_obligation_ledger.sh
|
|
27
34
|
# --full runs --fast plus the heavy full-checker regressions:
|
|
28
35
|
# - test_check_ccl_r0_status.sh
|
|
29
36
|
# - test_check_ccl_source_register_lifecycle.sh
|
|
@@ -101,8 +108,12 @@ fast_tests=(
|
|
|
101
108
|
test_controlled_escalation_pins.sh
|
|
102
109
|
test_check_ccl_size_budget.sh
|
|
103
110
|
test_check_ccl_skill_catalog.sh
|
|
111
|
+
test_check_ccl_parallel_stack_parity.sh
|
|
104
112
|
test_check_mr_target_freshness.sh
|
|
105
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
|
|
106
117
|
test_check_ccl_route_drift.sh
|
|
107
118
|
test_check_sync_pointers.sh
|
|
108
119
|
test_check_ccl_register_pending_exclusion.sh
|
|
@@ -138,7 +149,10 @@ fast_tests=(
|
|
|
138
149
|
test_regression_runner_lanes.sh
|
|
139
150
|
test_routing_pointer_integrity.sh
|
|
140
151
|
test_routing_bank_integrity.sh
|
|
152
|
+
test_uiux_delivery_contract.sh
|
|
153
|
+
test_uiux_loading_budget.sh
|
|
141
154
|
test_governing_chain_diff.sh
|
|
155
|
+
test_obligation_ledger.sh
|
|
142
156
|
# Owned by another skill package; run_test resolves it relative to SCRIPTS_DIR.
|
|
143
157
|
# Registered here because this runner is the repo's only regression lane —
|
|
144
158
|
# a skill-local test left unregistered is the false-green this file guards.
|
|
@@ -148,6 +162,11 @@ fast_tests=(
|
|
|
148
162
|
heavy_tests=(
|
|
149
163
|
test_check_ccl_r0_status.sh
|
|
150
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
|
|
151
170
|
test_check_ccl_source_register_lifecycle.sh
|
|
152
171
|
# Clones the whole repo once; impact-chain cases call the standalone gate and
|
|
153
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
|
|
54
|
-
#
|
|
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 "$
|
|
58
|
-
|
|
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
|
-
#
|
|
17
|
-
#
|
|
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:
|
|
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)"
|