@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
@@ -0,0 +1,336 @@
1
+ #!/usr/bin/env bash
2
+ # Regression for the extraction-specific autonomous review budget wrapper.
3
+ set -euo pipefail
4
+
5
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
6
+ WRAPPER="$SCRIPT_DIR/extraction_review_gate.sh"
7
+ REAL_CONTROLLER="$SCRIPT_DIR/../../code-review/scripts/review_gate.sh"
8
+ REAL_VALIDATOR="$SCRIPT_DIR/validate_extraction_review_state.py"
9
+ ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd -P)"
10
+ [ -x "$WRAPPER" ] || { echo "FAIL: wrapper missing or not executable: $WRAPPER" >&2; exit 1; }
11
+ [ -x "$REAL_CONTROLLER" ] || { echo "FAIL: real controller missing or not executable: $REAL_CONTROLLER" >&2; exit 1; }
12
+ [ -f "$REAL_VALIDATOR" ] || { echo "FAIL: real validator missing: $REAL_VALIDATOR" >&2; exit 1; }
13
+
14
+ TMP="$(mktemp -d "${TMPDIR:-/tmp}/extraction-review-gate.XXXXXX")"
15
+ trap 'rm -rf "$TMP"' EXIT
16
+
17
+ fail() { echo "FAIL: $*" >&2; exit 1; }
18
+ assert_rc() { [ "$1" = "$2" ] || fail "expected rc=$2 got rc=$1 ($3)"; }
19
+ assert_contains() { case "$2" in *"$1"*) : ;; *) fail "expected '$1' ($3): $2";; esac; }
20
+
21
+ mkdir -p "$TMP/skills/skill-extraction-workflow/scripts" "$TMP/skills/code-review/scripts"
22
+ cp "$WRAPPER" "$TMP/skills/skill-extraction-workflow/scripts/extraction_review_gate.sh"
23
+ printf '%s\n' \
24
+ '#!/usr/bin/env bash' \
25
+ 'printf '\''%s\0'\'' "$@" >"$CAPTURE_PATH"' \
26
+ 'exit "${FAKE_RC:-0}"' >"$TMP/skills/code-review/scripts/review_gate.sh"
27
+ chmod +x "$TMP/skills/skill-extraction-workflow/scripts/extraction_review_gate.sh" "$TMP/skills/code-review/scripts/review_gate.sh"
28
+
29
+ CAPTURE_PATH="$TMP/args" "$TMP/skills/skill-extraction-workflow/scripts/extraction_review_gate.sh" \
30
+ --mode review --cwd /synthetic --base base --implementer-family openai
31
+ python3 - "$TMP/args" <<'PY'
32
+ import sys
33
+ from pathlib import Path
34
+
35
+ args = [item.decode() for item in Path(sys.argv[1]).read_bytes().split(b"\0") if item]
36
+ assert args[:2] == ["--challenge-budget", "2"], args
37
+ assert args.count("--challenge-budget") == 1, args
38
+ PY
39
+
40
+ # A caller option with a missing operand must not consume the wrapper-owned
41
+ # budget flag. The real controller will reject the missing operand, but only
42
+ # after seeing the fixed extraction budget as its own option/value pair.
43
+ CAPTURE_PATH="$TMP/args" "$TMP/skills/skill-extraction-workflow/scripts/extraction_review_gate.sh" \
44
+ --mode review --cwd /synthetic --implementer-family openai --base
45
+ python3 - "$TMP/args" <<'PY'
46
+ import sys
47
+ from pathlib import Path
48
+
49
+ args = [item.decode() for item in Path(sys.argv[1]).read_bytes().split(b"\0") if item]
50
+ assert args[:2] == ["--challenge-budget", "2"], args
51
+ assert args[-1] == "--base", args
52
+ assert args.count("--challenge-budget") == 1, args
53
+ PY
54
+
55
+ # Exercise the installed wrapper/controller pair without invoking a model. The
56
+ # same real controller defaults to budget 0 when called directly, while the
57
+ # extraction wrapper must make the emitted receipt report budget 2.
58
+ python3 - "$TMP/real-controller.diff" "$TMP/real-controller-plan.json" <<'PY'
59
+ import json
60
+ import sys
61
+ from pathlib import Path
62
+
63
+ diff_path, plan_path = map(Path, sys.argv[1:])
64
+ diff_path.write_text(
65
+ "diff --git a/skills/skill-extraction-workflow/scripts/extraction_review_gate.sh "
66
+ "b/skills/skill-extraction-workflow/scripts/extraction_review_gate.sh\n"
67
+ "--- a/skills/skill-extraction-workflow/scripts/extraction_review_gate.sh\n"
68
+ "+++ b/skills/skill-extraction-workflow/scripts/extraction_review_gate.sh\n"
69
+ "@@ -1 +1 @@\n-old wrapper\n+new wrapper\n",
70
+ encoding="utf-8",
71
+ )
72
+ conclusions = {
73
+ "correctness": "The real controller receipt exposes the effective extraction budget.",
74
+ "safety": "The probe selects only the implementer family and invokes no external reviewer.",
75
+ "failure_paths": "The no-independent-reviewer boundary remains structured and fail closed.",
76
+ "tests_evidence": "Direct and wrapped calls provide a differential budget assertion.",
77
+ "compatibility": "The generic controller default remains zero while extraction fixes two.",
78
+ }
79
+ skills = {
80
+ "correctness": "skill-extraction-workflow",
81
+ "safety": "code-review",
82
+ "failure_paths": "python-service-dev",
83
+ "tests_evidence": "testing-strategy",
84
+ "compatibility": "terminal-cli-dev",
85
+ }
86
+ plan = {
87
+ "intent": "Prove the extraction wrapper and real review controller agree on budget two.",
88
+ "acceptance": ["The wrapped real-controller receipt reports challenge_budget two."],
89
+ "self_review": [
90
+ {
91
+ "concern": concern,
92
+ "skill": skills[concern],
93
+ "conclusion": conclusion,
94
+ "evidence_refs": ["real-controller-differential"],
95
+ }
96
+ for concern, conclusion in conclusions.items()
97
+ ],
98
+ "evidence": [
99
+ {
100
+ "id": "real-controller-differential",
101
+ "result": "The same real controller is invoked directly and through the extraction wrapper.",
102
+ }
103
+ ],
104
+ }
105
+ plan_path.write_text(json.dumps(plan, indent=2) + "\n", encoding="utf-8")
106
+ PY
107
+
108
+ real_args=(
109
+ --mode review --cwd "$ROOT" --diff-file "$TMP/real-controller.diff"
110
+ --implementer-family openai --review-plan-file "$TMP/real-controller-plan.json"
111
+ --stage build --review-harness --timeout 5 --total-timeout 5
112
+ )
113
+ # Make a Codex executable visibly available, independent of whichever CLI
114
+ # version the host carries. Because the implementer is OpenAI-family, the real
115
+ # controller must reject Codex as same-family before probing or invoking it.
116
+ mkdir -p "$TMP/fake-bin"
117
+ printf '%s\n' \
118
+ '#!/usr/bin/env bash' \
119
+ 'printf invoked >"$CODEX_MARKER"' \
120
+ 'exit 99' >"$TMP/fake-bin/codex"
121
+ chmod +x "$TMP/fake-bin/codex"
122
+ set +e
123
+ direct_out="$(CODEX_MARKER="$TMP/codex-invoked" PATH="$TMP/fake-bin:$PATH" \
124
+ CODE_REVIEW_CLIENT_ORDER=codex bash "$REAL_CONTROLLER" "${real_args[@]}" 2>&1)"
125
+ direct_rc=$?
126
+ wrapped_out="$(CODEX_MARKER="$TMP/codex-invoked" PATH="$TMP/fake-bin:$PATH" \
127
+ CODE_REVIEW_CLIENT_ORDER=codex "$WRAPPER" "${real_args[@]}" \
128
+ --review-chain-id extraction-wrapper-real-controller \
129
+ --autonomous-review-index 1 2>&1)"
130
+ wrapped_rc=$?
131
+ set -e
132
+ assert_rc "$direct_rc" 2 "direct real controller must stop before model inference"
133
+ assert_rc "$wrapped_rc" 2 "wrapped real controller must stop before model inference"
134
+ assert_contains '"reason_code":"no_independent_reviewer_available"' "$direct_out" "direct real-controller boundary"
135
+ assert_contains '"reason_code":"no_independent_reviewer_available"' "$wrapped_out" "wrapped real-controller boundary"
136
+ assert_contains '"challenge_budget":0' "$direct_out" "generic controller default budget"
137
+ assert_contains '"challenge_budget":2' "$wrapped_out" "wrapper-enforced real-controller budget"
138
+ [ ! -e "$TMP/codex-invoked" ] || fail "same-family Codex executable was invoked"
139
+
140
+ # Join the producer and consumer contracts. First feed the exact real receipt
141
+ # to the validator and reach its semantic status boundary. Then normalize only
142
+ # the terminal disposition fields so validation must walk the producer's real
143
+ # chain/scope shape before stopping at the intentionally omitted base evidence.
144
+ printf '%s\n' "$wrapped_out" >"$TMP/wrapped-real-controller.out"
145
+ python3 - "$TMP/wrapped-real-controller.out" "$TMP" <<'PY'
146
+ import copy
147
+ import hashlib
148
+ import json
149
+ import sys
150
+ from pathlib import Path
151
+
152
+ output_path = Path(sys.argv[1])
153
+ root = Path(sys.argv[2])
154
+ receipt = None
155
+ for line in reversed(output_path.read_text(encoding="utf-8").splitlines()):
156
+ try:
157
+ value = json.loads(line)
158
+ except json.JSONDecodeError:
159
+ continue
160
+ if isinstance(value, dict) and value.get("schema_version") == 3:
161
+ receipt = value
162
+ break
163
+ assert receipt is not None
164
+
165
+
166
+ def write_receipt_and_ledger(stem, value, controller_state):
167
+ encoded = (json.dumps(value, ensure_ascii=False, indent=2) + "\n").encode()
168
+ receipt_name = f"{stem}-receipt.json"
169
+ (root / receipt_name).write_bytes(encoded)
170
+ digest = hashlib.sha256(encoded).hexdigest()
171
+ ledger = {
172
+ "schema_version": 3,
173
+ "candidate_sha256": value["candidate_sha256"],
174
+ "controller_receipts": [
175
+ {"sequence": 1, "file": receipt_name, "sha256": digest}
176
+ ],
177
+ "completion_receipt": None,
178
+ "base_attestations": [],
179
+ "autonomous_round": 1,
180
+ "controller_review_state": controller_state,
181
+ "finding_classes": [],
182
+ "unreviewed_delta": [],
183
+ "closeout_state": "ready_for_human_decision",
184
+ }
185
+ (root / f"{stem}-ledger.json").write_text(
186
+ json.dumps(ledger, ensure_ascii=False, indent=2) + "\n",
187
+ encoding="utf-8",
188
+ )
189
+
190
+
191
+ write_receipt_and_ledger("real-emitted", receipt, receipt.get("review_state", "inconclusive"))
192
+ normalized = copy.deepcopy(receipt)
193
+ scope_before = json.dumps(normalized["review_scope"], sort_keys=True)
194
+ normalized.update(
195
+ status="passed",
196
+ findings=[],
197
+ review_state="reviewed",
198
+ human_decision_required=False,
199
+ )
200
+ assert json.dumps(normalized["review_scope"], sort_keys=True) == scope_before
201
+ write_receipt_and_ledger("real-scope", normalized, "reviewed")
202
+ PY
203
+
204
+ set +e
205
+ emitted_state_out="$(python3 "$REAL_VALIDATOR" "$TMP/real-emitted-ledger.json" 2>&1)"
206
+ emitted_state_rc=$?
207
+ scope_state_out="$(python3 "$REAL_VALIDATOR" "$TMP/real-scope-ledger.json" 2>&1)"
208
+ scope_state_rc=$?
209
+ set -e
210
+ assert_rc "$emitted_state_rc" 1 "exact real receipt reaches semantic status validation"
211
+ assert_contains "must have status passed or findings" "$emitted_state_out" "exact real receipt semantic boundary"
212
+ assert_rc "$scope_state_rc" 1 "producer-derived receipt reaches post-scope validation"
213
+ assert_contains "base_attestations must be a non-empty array" "$scope_state_out" "real producer scope shape"
214
+
215
+ # Shorter spellings that do not start with --challenge-b are ambiguous among
216
+ # the controller's budget/index/classes options, so they fail closed instead of
217
+ # becoming a hidden budget override.
218
+ for abbreviated in --challeng --challenge=4; do
219
+ set +e
220
+ out="$(CODE_REVIEW_CLIENT_ORDER=codex "$WRAPPER" "${real_args[@]}" "$abbreviated" 4 2>&1)"
221
+ rc=$?
222
+ set -e
223
+ assert_rc "$rc" 2 "ambiguous budget abbreviation must fail closed"
224
+ assert_contains "ambiguous option" "$out" "ambiguous abbreviation reason"
225
+ done
226
+
227
+ for spelling in --challenge-budget --challenge-budget=4 --challenge-b=4; do
228
+ : >"$TMP/args"
229
+ set +e
230
+ out="$(CAPTURE_PATH="$TMP/args" "$TMP/skills/skill-extraction-workflow/scripts/extraction_review_gate.sh" "$spelling" 4 2>&1)"
231
+ rc=$?
232
+ set -e
233
+ assert_rc "$rc" 2 "caller budget override must be rejected"
234
+ assert_contains "challenge budget is fixed at 2" "$out" "override reason"
235
+ [ ! -s "$TMP/args" ] || fail "controller ran after budget override"
236
+ done
237
+
238
+ set +e
239
+ CAPTURE_PATH="$TMP/args" FAKE_RC=7 "$TMP/skills/skill-extraction-workflow/scripts/extraction_review_gate.sh" \
240
+ --mode review --cwd /synthetic --base base --implementer-family openai >/dev/null 2>&1
241
+ rc=$?
242
+ set -e
243
+ assert_rc "$rc" 7 "wrapper must preserve controller exit status"
244
+
245
+ mv "$TMP/skills/code-review/scripts/review_gate.sh" "$TMP/controller-away"
246
+ set +e
247
+ out="$(CAPTURE_PATH="$TMP/args" "$TMP/skills/skill-extraction-workflow/scripts/extraction_review_gate.sh" \
248
+ --mode review --cwd /synthetic --base base --implementer-family openai 2>&1)"
249
+ rc=$?
250
+ set -e
251
+ assert_rc "$rc" 2 "missing controller must fail closed"
252
+ assert_contains "controller is unavailable" "$out" "missing-controller reason"
253
+
254
+ # The owner-facing start-here documents must route non-wording extraction work
255
+ # through the fixed-budget wrapper and its terminal validator. Strict
256
+ # wording-only changes retain the documented single-review exception; they must
257
+ # not be accidentally pulled into the multi-round ledger contract.
258
+ python3 - "$ROOT" <<'PY'
259
+ import re
260
+ import sys
261
+ from pathlib import Path
262
+
263
+ root = Path(sys.argv[1])
264
+ skill = (root / "skills/skill-extraction-workflow/SKILL.md").read_text(encoding="utf-8")
265
+ quickstart = (
266
+ root / "skills/skill-extraction-workflow/references/extraction-quickstart.md"
267
+ ).read_text(encoding="utf-8")
268
+ dual = (
269
+ root / "skills/skill-extraction-workflow/references/dual-track-review-gate.md"
270
+ ).read_text(encoding="utf-8")
271
+ landing = (
272
+ root / "skills/skill-extraction-workflow/references/validation-and-landing.md"
273
+ ).read_text(encoding="utf-8")
274
+ staged = (
275
+ root / "skills/code-review/references/staged-review-contract.md"
276
+ ).read_text(encoding="utf-8")
277
+ code_review = (root / "skills/code-review/SKILL.md").read_text(encoding="utf-8")
278
+
279
+ for label, text in {
280
+ "SKILL": skill,
281
+ "quickstart": quickstart,
282
+ "dual-track": dual,
283
+ "validation-and-landing": landing,
284
+ }.items():
285
+ assert "scripts/extraction_review_gate.sh" in text, (
286
+ f"{label} does not route the non-wording lane through the owner wrapper"
287
+ )
288
+
289
+ for label, text in {"quickstart": quickstart, "dual-track": dual}.items():
290
+ assert "scripts/validate_extraction_review_state.py <closeout.json>" in text, (
291
+ f"{label} omits the terminal closeout validator"
292
+ )
293
+
294
+ assert re.search(
295
+ r"[Nn]on-wording.{0,240}scripts/extraction_review_gate\.sh",
296
+ skill,
297
+ re.DOTALL,
298
+ ), "SKILL does not scope the fixed-budget wrapper to non-wording changes"
299
+ assert re.search(
300
+ r"[Ww]ording-only.{0,500}(?:single|one)[- ](?:round|review)",
301
+ quickstart,
302
+ re.DOTALL,
303
+ ), "quickstart lost the strict wording-only single-review exception"
304
+ for label, text in {
305
+ "quickstart": quickstart,
306
+ "dual-track": dual,
307
+ "validation-and-landing": landing,
308
+ "code-review": code_review,
309
+ }.items():
310
+ assert "wording_only_boundary" in text, (
311
+ f"{label} does not require independent wording-only semantic confirmation"
312
+ )
313
+ assert "--wording-only-proof-file" in staged
314
+ assert "--challenge-budget 0" in staged
315
+ assert "markdown-punctuation-only" in staged
316
+ assert "markdown-token-replacement" in staged
317
+ assert "opens no challenge chain or `complete` checkpoint" in dual
318
+ assert "codex review --base" not in quickstart
319
+ assert "codex exec adversarial" not in quickstart
320
+ assert "--challenge-budget" not in quickstart, (
321
+ "quickstart must not let callers override the extraction review budget"
322
+ )
323
+ assert re.search(
324
+ r"[Rr]ound 2.{0,500}ready_for_human_decision",
325
+ quickstart,
326
+ re.DOTALL,
327
+ ), "quickstart does not validate an early-clean round-2 terminal checkpoint"
328
+ assert re.search(
329
+ r"[Rr]ound 3.{0,500}continuation_authorization_required",
330
+ quickstart,
331
+ re.DOTALL,
332
+ ), "quickstart does not validate the exhausted-budget terminal checkpoint"
333
+ assert "baseline_race" in quickstart
334
+ PY
335
+
336
+ echo "test_extraction_review_gate: ok"
@@ -60,6 +60,8 @@ git -C "$REPO" commit -qm "seed grammar declaration for the 045 triggers"
60
60
  git -C "$REPO" branch -f fixture-base HEAD >/dev/null
61
61
 
62
62
  OWNER="product-rd-workflow"
63
+ NON_CURATED_OWNER="terminal-cli-dev"
64
+ NON_CURATED_OWNER2="web-react-dev"
63
65
 
64
66
  new_case() { git -C "$REPO" switch -q -C "$1" fixture-base; }
65
67
  commit_case() { git -C "$REPO" add -A >/dev/null; git -C "$REPO" commit -qm "$1"; }
@@ -81,8 +83,8 @@ add_owner_rule() { # <marker>
81
83
  # behaviour under test — a rc=1 that looked like the gate working. A SUFFIX is not
82
84
  # enough either: the locator counts substring hits, so `…-A1-DESC` still contains
83
85
  # `…-A1`. The distinguishing part has to come before the shared stem.
84
- edit_owner_description() { # <marker>
85
- python3 - "$REPO/skills/$OWNER/SKILL.md" "$(anchor "DESC-$1")" <<'PY'
86
+ edit_description_for_owner() { # <owner> <marker>
87
+ python3 - "$REPO/skills/$1/SKILL.md" "$(anchor "DESC-$2")" <<'PY'
86
88
  import io, re, sys
87
89
  path, marker = sys.argv[1], sys.argv[2]
88
90
  s = io.open(path, encoding="utf-8").read()
@@ -93,6 +95,8 @@ io.open(path, "w", encoding="utf-8").write(s[:m.start(1)] + new_front + s[m.end(
93
95
  PY
94
96
  }
95
97
 
98
+ edit_owner_description() { edit_description_for_owner "$OWNER" "$1"; }
99
+
96
100
  touch_bank() { printf '{"utterance":"fixture %s","expected_owner":"%s"}\n' "$1" "$OWNER" >> "$REPO/$BANK_REL"; }
97
101
 
98
102
  write_plan() { # <downscope-token or empty>
@@ -126,20 +130,28 @@ run_gate() {
126
130
  }
127
131
 
128
132
  legs_failed=0
129
- report_leg() { # <leg-name> <expected-rc> <form-summary> [expected-token]
130
- local name="$1" want="$2" summary="$3" token="${4:-}"
131
- if [ "$rc" != "$want" ]; then
132
- echo " $name: RED (rc=$rc, want $want) — $summary"
133
- printf '%s\n' "$out" | sed 's/^/ | /'
133
+ report_leg() { # <leg-name> <expected-rc> <form-summary> [expected-token ...]
134
+ local name="$1" want="$2" summary="$3" token
135
+ shift 3
136
+ if [ "$name" = "A13" ] && ! printf '%s' "$summary" | grep -qF '`-`'; then
137
+ echo ' A13: RED (summary lost literal `-`)'
134
138
  legs_failed=$((legs_failed + 1))
135
139
  return
136
140
  fi
137
- if [ -n "$token" ] && ! printf '%s' "$out" | grep -qF "$token"; then
138
- echo " $name: RED (rc matched but refusal is not '$token') — $summary"
141
+ if [ "$rc" != "$want" ]; then
142
+ echo " $name: RED (rc=$rc, want $want) — $summary"
139
143
  printf '%s\n' "$out" | sed 's/^/ | /'
140
144
  legs_failed=$((legs_failed + 1))
141
145
  return
142
146
  fi
147
+ for token in "$@"; do
148
+ if [ -n "$token" ] && ! printf '%s' "$out" | grep -qF "$token"; then
149
+ echo " $name: RED (rc matched but output is missing '$token') — $summary"
150
+ printf '%s\n' "$out" | sed 's/^/ | /'
151
+ legs_failed=$((legs_failed + 1))
152
+ return
153
+ fi
154
+ done
143
155
  echo " ok $name — $summary"
144
156
  }
145
157
 
@@ -321,7 +333,7 @@ new_case case-a13; add_owner_rule A13; edit_owner_description A13; write_plan
321
333
  append_row A13 'A fixture lesson downscoping with a degenerate token' \
322
334
  '; result-class: failure; bank-evidence: downscoped:-'
323
335
  commit_case "A13"; run_gate
324
- report_leg A13 1 "退化 token 不算留痕(`-` 会命中任意 bullet 的连字符)" "$RC_MISSING"
336
+ report_leg A13 1 '退化 token 不算留痕(`-` 会命中任意 bullet 的连字符)' "$RC_MISSING"
325
337
 
326
338
  # B5 只动 bank 的轮里,声明行同样欠 result-class -> 必须红
327
339
  # B 曾按变更 owner 收敛,而 bank-only 的轮没有变更 owner:那行声明行压根不被检查,
@@ -447,6 +459,66 @@ append_row A19 'A fixture lesson deleting the description entry in place' '; res
447
459
  commit_case "A19"; run_gate
448
460
  report_leg A19 1 "就地删掉 description 也是路由面变更(文件还在,不是删除)" "$RC_MISSING"
449
461
 
462
+ # A20 非 curated owner 的 description 改动 + 唯一有效证据 -> 必须通过
463
+ # routing bank 约束所有技能的 description,但这不等于把该技能提升为 impact-chain owner。
464
+ # 行不声明 behavioral-evidence,专门证明 bank owner 解析与 impact-chain owner 解析彼此独立。
465
+ new_case case-a20; edit_description_for_owner "$NON_CURATED_OWNER" A20; write_plan
466
+ printf '| A fixture non-curated routing surface with bank evidence | `downstream-executor` | bank-evidence: file:%s#%s | `updated` | `%s/SKILL.md` fixture change |\n' "$PLAN_REL" "$(anchor BANKEV)" "$NON_CURATED_OWNER" >> "$REPO/$LEDGER_REL"
467
+ commit_case "A20"; run_gate
468
+ report_leg A20 0 "非 curated owner 的唯一 bank 证据可被解析,但不进入 impact-chain"
469
+
470
+ # A21 非 curated owner 的 description 改动 + 零台账行 -> 必须红
471
+ # 外层入口若只看 curated owner / ledger / bank,这一轮会完全不执行而静默通过。
472
+ new_case case-a21; edit_description_for_owner "$NON_CURATED_OWNER" A21
473
+ commit_case "A21"; run_gate
474
+ report_leg A21 1 "非 curated owner 改 description 且零台账行仍欠 bank 证据" \
475
+ "$RC_MISSING" "owes bank evidence: $NON_CURATED_OWNER/SKILL.md"
476
+
477
+ # A22 一行同时绑定两个非 curated owner -> 不能替任一 owner 清偿
478
+ # owner 解析必须保持一行一 owner;否则一个 locator 会把同轮另一个 description 改动也标绿。
479
+ new_case case-a22
480
+ edit_description_for_owner "$NON_CURATED_OWNER" A22A
481
+ edit_description_for_owner "$NON_CURATED_OWNER2" A22B
482
+ write_plan
483
+ printf '| A fixture ambiguous non-curated routing row | `downstream-executor` | bank-evidence: file:%s#%s | `updated` | `%s/SKILL.md` and `%s/SKILL.md` fixture changes |\n' "$PLAN_REL" "$(anchor BANKEV)" "$NON_CURATED_OWNER" "$NON_CURATED_OWNER2" >> "$REPO/$LEDGER_REL"
484
+ commit_case "A22"; run_gate
485
+ report_leg A22 1 "一行不能替两个非 curated owner 清偿 bank 证据" \
486
+ "$RC_MISSING" \
487
+ "owes bank evidence: $NON_CURATED_OWNER/SKILL.md" \
488
+ "owes bank evidence: $NON_CURATED_OWNER2/SKILL.md"
489
+
490
+ # A23 未知或已删除的 owner 路径在 bank resolver 前就必须被 missing-file 闸拒绝
491
+ # 独立 review 怀疑过滤会把双路径压成唯一 owner;实际调用路径先检查每个精确
492
+ # `<owner>/SKILL.md` 在该轮 head 是否存在,因此拼错/过期路径不能抵达 bank 清偿。
493
+ new_case case-a23; edit_description_for_owner "$NON_CURATED_OWNER" A23; write_plan
494
+ printf '| A fixture routing row with a stale owner alias | `downstream-executor` | bank-evidence: file:%s#%s | `updated` | `%s/SKILL.md` and `fixture-stale-owner/SKILL.md` fixture claims |\n' "$PLAN_REL" "$(anchor BANKEV)" "$NON_CURATED_OWNER" >> "$REPO/$LEDGER_REL"
495
+ commit_case "A23"; run_gate
496
+ report_leg A23 1 "未知 owner 路径在 bank 解析前被 evidence missing-file 闸拒绝" \
497
+ "impact_chain_evidence_missing_file" "missing: fixture-stale-owner/SKILL.md"
498
+
499
+ # A24 Node implementation owner 的 description + 外部 bank 证据 -> 必须绿
500
+ SAVED_OWNER="$OWNER"
501
+ OWNER="nodejs-service-dev"
502
+ new_case case-a20; add_owner_rule A24; edit_owner_description A24; write_plan
503
+ append_row A24 'The Node implementation owner carries external bank evidence' \
504
+ "; result-class: failure; bank-evidence: file:$PLAN_REL#$(anchor BANKEV)"
505
+ commit_case "A24"; run_gate
506
+ report_leg A24 0 "Node implementation owner 的 bank 证据可被 owner-scoped gate 消费"
507
+ OWNER="$SAVED_OWNER"
508
+
509
+ # A25 存量非 curated 技能改 description:义务存在,且经 bank-only 解析可清偿 -> 必须绿
510
+ # 前一轮曾把 created-surface pickup 限定在 base 不存在的技能,理由是「非 curated 的
511
+ # 义务行无法绑定、红无法清偿」;bank-only resolver 合入后该前提不再成立——本腿钉的
512
+ # 就是「可清偿」这一半:欠债的那一半由 A21 钉(零行必须红)。
513
+ new_case case-a21; add_owner_rule A25; write_plan
514
+ append_row A25 'A curated owner row rides along while an existing non-curated sibling edits its description' \
515
+ '; result-class: failure'
516
+ SAVED_OWNER="$OWNER"
517
+ OWNER="web-react-dev"; edit_owner_description A25; OWNER="$SAVED_OWNER"
518
+ printf '| A fixture existing non-curated routing surface with bank evidence | `downstream-executor` | bank-evidence: file:%s#%s | `updated` | `web-react-dev/SKILL.md` fixture change |\n' "$PLAN_REL" "$(anchor BANKEV)" >> "$REPO/$LEDGER_REL"
519
+ commit_case "A25"; run_gate
520
+ report_leg A25 0 '存量非 curated owner 的 description 编辑欠 bank 证据且可被 bank-only 行清偿'
521
+
450
522
  echo "impact_chain_self_adjudication: legs_failed=$legs_failed"
451
523
  if [ "$legs_failed" -ne 0 ]; then
452
524
  echo "impact_chain_self_adjudication_failed=$legs_failed" >&2