@ccoalm/ccl-skills 0.1.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 (561) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +49 -0
  3. package/dist/assets/marketplace/.agents/plugins/marketplace.json +12 -0
  4. package/dist/assets/marketplace/.claude-plugin/marketplace.json +13 -0
  5. package/dist/assets/marketplace/marketplace-manifest.json +12 -0
  6. package/dist/assets/marketplace/plugins/ccl-skills/.claude-plugin/marketplace.json +16 -0
  7. package/dist/assets/marketplace/plugins/ccl-skills/.claude-plugin/plugin.json +5 -0
  8. package/dist/assets/marketplace/plugins/ccl-skills/.codex-plugin/plugin.json +5 -0
  9. package/dist/assets/marketplace/plugins/ccl-skills/.worktree-only +3 -0
  10. package/dist/assets/marketplace/plugins/ccl-skills/agent-context/session-start.md +45 -0
  11. package/dist/assets/marketplace/plugins/ccl-skills/agent-context/subagent-start.md +12 -0
  12. package/dist/assets/marketplace/plugins/ccl-skills/hooks/AGENTS.md +19 -0
  13. package/dist/assets/marketplace/plugins/ccl-skills/hooks/guard-delegation-owner.sh +125 -0
  14. package/dist/assets/marketplace/plugins/ccl-skills/hooks/guard-edit-isolation.sh +102 -0
  15. package/dist/assets/marketplace/plugins/ccl-skills/hooks/guard-merge-authorization.sh +1156 -0
  16. package/dist/assets/marketplace/plugins/ccl-skills/hooks/hooks.json +131 -0
  17. package/dist/assets/marketplace/plugins/ccl-skills/hooks/merge-authorization-prompt.sh +142 -0
  18. package/dist/assets/marketplace/plugins/ccl-skills/hooks/owner-dispatch-guard.sh +12 -0
  19. package/dist/assets/marketplace/plugins/ccl-skills/hooks/owner-dispatch-stop.sh +13 -0
  20. package/dist/assets/marketplace/plugins/ccl-skills/hooks/remind-post-merge-cleanup.sh +144 -0
  21. package/dist/assets/marketplace/plugins/ccl-skills/hooks/session-context.sh +87 -0
  22. package/dist/assets/marketplace/plugins/ccl-skills/hooks/session-start.sh +86 -0
  23. package/dist/assets/marketplace/plugins/ccl-skills/hooks/skill-extraction-gate-stop.sh +69 -0
  24. package/dist/assets/marketplace/plugins/ccl-skills/hooks/subagent-start.sh +26 -0
  25. package/dist/assets/marketplace/plugins/ccl-skills/hooks/test_guard_delegation_owner.sh +329 -0
  26. package/dist/assets/marketplace/plugins/ccl-skills/hooks/test_guard_edit_isolation.sh +322 -0
  27. package/dist/assets/marketplace/plugins/ccl-skills/hooks/test_guard_merge_authorization.sh +902 -0
  28. package/dist/assets/marketplace/plugins/ccl-skills/hooks/test_merge_authorization_prompt.sh +178 -0
  29. package/dist/assets/marketplace/plugins/ccl-skills/hooks/test_remind_post_merge_cleanup.sh +121 -0
  30. package/dist/assets/marketplace/plugins/ccl-skills/hooks/test_session_start.sh +170 -0
  31. package/dist/assets/marketplace/plugins/ccl-skills/packages/opencode-plugin/AGENTS.md +17 -0
  32. package/dist/assets/marketplace/plugins/ccl-skills/packages/opencode-plugin/ccl-skills.ts +564 -0
  33. package/dist/assets/marketplace/plugins/ccl-skills/packages/opencode-plugin/commands/ccl-install-skills.md +14 -0
  34. package/dist/assets/marketplace/plugins/ccl-skills/packages/opencode-plugin/commands/ccl-update-skills.md +44 -0
  35. package/dist/assets/marketplace/plugins/ccl-skills/packages/opencode-plugin/commands/ccl-verify-skills.md +109 -0
  36. package/dist/assets/marketplace/plugins/ccl-skills/packages/opencode-plugin/commands/ccl-worktree-check.md +36 -0
  37. package/dist/assets/marketplace/plugins/ccl-skills/scripts/owner-dispatch/AGENTS.md +28 -0
  38. package/dist/assets/marketplace/plugins/ccl-skills/scripts/owner-dispatch/README.md +276 -0
  39. package/dist/assets/marketplace/plugins/ccl-skills/scripts/owner-dispatch/owner-dispatch.example.json +10 -0
  40. package/dist/assets/marketplace/plugins/ccl-skills/scripts/owner-dispatch/owner-dispatch.sh +1307 -0
  41. package/dist/assets/marketplace/plugins/ccl-skills/scripts/owner-dispatch/test.sh +941 -0
  42. package/dist/assets/marketplace/plugins/ccl-skills/skills/agents-file-coverage-gate/SKILL.md +45 -0
  43. package/dist/assets/marketplace/plugins/ccl-skills/skills/agents-file-coverage-gate/agents/openai.yaml +4 -0
  44. package/dist/assets/marketplace/plugins/ccl-skills/skills/app-cross-platform-dev/SKILL.md +188 -0
  45. package/dist/assets/marketplace/plugins/ccl-skills/skills/app-cross-platform-dev/agents/openai.yaml +4 -0
  46. package/dist/assets/marketplace/plugins/ccl-skills/skills/app-cross-platform-dev/references/android-dev.md +92 -0
  47. package/dist/assets/marketplace/plugins/ccl-skills/skills/app-cross-platform-dev/references/flutter-dev.md +80 -0
  48. package/dist/assets/marketplace/plugins/ccl-skills/skills/app-cross-platform-dev/references/ios-dev.md +72 -0
  49. package/dist/assets/marketplace/plugins/ccl-skills/skills/app-cross-platform-dev/references/kotlin-multiplatform.md +93 -0
  50. package/dist/assets/marketplace/plugins/ccl-skills/skills/app-cross-platform-dev/references/mobile-platform-boundaries.md +77 -0
  51. package/dist/assets/marketplace/plugins/ccl-skills/skills/app-cross-platform-dev/references/mobile-quality-release.md +77 -0
  52. package/dist/assets/marketplace/plugins/ccl-skills/skills/app-cross-platform-dev/references/source-evidence-map.md +64 -0
  53. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/SKILL.md +353 -0
  54. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/agents/openai.yaml +4 -0
  55. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/references/client-routing.md +419 -0
  56. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/references/manual-invocation-and-prompts.md +126 -0
  57. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/references/staged-review-contract.md +197 -0
  58. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/references/timeout-auth-and-capabilities.md +179 -0
  59. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/AGENTS.md +98 -0
  60. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/classify_envelope.py +93 -0
  61. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/classify_timeout_exit.sh +15 -0
  62. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/claude_review.sh +1438 -0
  63. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/codex_review.sh +324 -0
  64. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/concern_excerpt.py +295 -0
  65. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/egress_schema.py +214 -0
  66. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/init_policy_matrix.py +642 -0
  67. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/kimi_packet_mcp.py +181 -0
  68. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/kimi_review.sh +1165 -0
  69. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/opencode_review.sh +1190 -0
  70. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/parse_cli_review.py +946 -0
  71. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/parse_opencode_review.py +474 -0
  72. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/parse_probe_result.py +1899 -0
  73. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/parse_review_json.py +200 -0
  74. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/review_gate.py +2845 -0
  75. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/review_gate.sh +6 -0
  76. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/run_claude_capture.py +71 -0
  77. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/runtime-surface-verification-design.md +53 -0
  78. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_classify_envelope.sh +68 -0
  79. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_claude_review_probe.sh +2311 -0
  80. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_cli_review_wrappers.sh +1832 -0
  81. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_code_review_identity.sh +73 -0
  82. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_concern_excerpt.sh +245 -0
  83. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_egress_schema.sh +177 -0
  84. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_init_policy_matrix.sh +272 -0
  85. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_kimi_packet_mcp.py +195 -0
  86. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_opencode_review_concurrency.sh +120 -0
  87. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_opencode_review_retry.sh +1005 -0
  88. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_parse_opencode_review.sh +258 -0
  89. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_parse_probe_result.sh +574 -0
  90. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_parse_review_json.sh +349 -0
  91. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_review_client_compat.py +434 -0
  92. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_review_client_order.sh +264 -0
  93. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_review_gate.sh +2412 -0
  94. package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/verify_native_skill_binding.py +123 -0
  95. package/dist/assets/marketplace/plugins/ccl-skills/skills/defect-diagnosis/SKILL.md +153 -0
  96. package/dist/assets/marketplace/plugins/ccl-skills/skills/defect-diagnosis/agents/openai.yaml +4 -0
  97. package/dist/assets/marketplace/plugins/ccl-skills/skills/defect-diagnosis/references/diagnosis-playbook.md +54 -0
  98. package/dist/assets/marketplace/plugins/ccl-skills/skills/defect-diagnosis/references/prevention-routing.md +36 -0
  99. package/dist/assets/marketplace/plugins/ccl-skills/skills/feature-risk-router/SKILL.md +69 -0
  100. package/dist/assets/marketplace/plugins/ccl-skills/skills/feature-risk-router/agents/openai.yaml +4 -0
  101. package/dist/assets/marketplace/plugins/ccl-skills/skills/feature-risk-router/references/security-review-gate.md +41 -0
  102. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/SKILL.md +165 -0
  103. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/agents/openai.yaml +4 -0
  104. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/api-security-boundaries.md +47 -0
  105. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/architecture-playbook.md +160 -0
  106. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/artifact-generation-architecture.md +37 -0
  107. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/audit-history-architecture.md +29 -0
  108. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/bulk-workflow-architecture.md +33 -0
  109. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/config-rule-routing-architecture.md +34 -0
  110. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/cross-cutting-concerns.md +72 -0
  111. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/data-modeling-and-migrations.md +79 -0
  112. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/data-platform-architecture.md +210 -0
  113. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/dependency-platform.md +105 -0
  114. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/developer-tooling-architecture.md +38 -0
  115. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/error-contract-architecture.md +36 -0
  116. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/event-driven-architecture.md +260 -0
  117. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/http-gateway-architecture.md +74 -0
  118. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/mq-consumer-architecture.md +38 -0
  119. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/multi-tenant-isolation.md +275 -0
  120. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/notification-architecture.md +25 -0
  121. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/ops-checklist.md +57 -0
  122. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/performance-capacity-architecture.md +38 -0
  123. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/protobuf-contract-architecture.md +119 -0
  124. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/redis-cache-coordination.md +93 -0
  125. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/release-runtime-readiness.md +65 -0
  126. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/replay-comparison-architecture.md +26 -0
  127. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/runtime-observability.md +94 -0
  128. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/service-scaffold.md +76 -0
  129. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/source-evidence-map.md +55 -0
  130. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/workflow-state-architecture.md +38 -0
  131. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/SKILL.md +159 -0
  132. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/agents/openai.yaml +4 -0
  133. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/artifact-generation-patterns.md +37 -0
  134. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/audit-history-patterns.md +28 -0
  135. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/bulk-import-export-patterns.md +56 -0
  136. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/config-rule-routing-patterns.md +38 -0
  137. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/data-access-patterns.md +55 -0
  138. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/db-schema-and-dal-patterns.md +109 -0
  139. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/dependency-client-patterns.md +130 -0
  140. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/developer-tooling-patterns.md +70 -0
  141. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/domain-feature-patterns.md +78 -0
  142. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/engineering-patterns.md +119 -0
  143. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/error-contract-patterns.md +55 -0
  144. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/feature-playbook.md +61 -0
  145. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/http-gateway-client-patterns.md +76 -0
  146. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/mq-consumer-patterns.md +55 -0
  147. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/notification-patterns.md +42 -0
  148. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/observability-implementation-patterns.md +101 -0
  149. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/performance-capacity-patterns.md +44 -0
  150. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/protobuf-contract-patterns.md +72 -0
  151. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/public-api-integration-patterns.md +56 -0
  152. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/quality-and-testing-patterns.md +91 -0
  153. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/redis-cache-lock-patterns.md +123 -0
  154. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/release-ops-patterns.md +112 -0
  155. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/reliability-patterns.md +83 -0
  156. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/replay-comparison-patterns.md +32 -0
  157. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/scaffold-and-codegen.md +86 -0
  158. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/source-evidence-map.md +54 -0
  159. package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/state-machine-task-patterns.md +45 -0
  160. package/dist/assets/marketplace/plugins/ccl-skills/skills/grill-me/SKILL.md +80 -0
  161. package/dist/assets/marketplace/plugins/ccl-skills/skills/grill-me/agents/openai.yaml +4 -0
  162. package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/SKILL.md +117 -0
  163. package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/agents/openai.yaml +4 -0
  164. package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-approval-auto-reviewer.md +106 -0
  165. package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-command-sandbox.md +441 -0
  166. package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-context-freshness.md +47 -0
  167. package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-credentials-auth.md +13 -0
  168. package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-extensions-skills.md +13 -0
  169. package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-file-edit-protocol.md +129 -0
  170. package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-ide-integration.md +5 -0
  171. package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-input-ingestion.md +13 -0
  172. package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-instruction-composition.md +13 -0
  173. package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-lifecycle-hooks.md +92 -0
  174. package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-messaging.md +5 -0
  175. package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-runtime-bootstrap.md +5 -0
  176. package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-session-persistence.md +448 -0
  177. package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-task-orchestration.md +13 -0
  178. package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-tool-dispatch.md +123 -0
  179. package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-turn-lifecycle.md +131 -0
  180. package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/inference-capacity-operations.md +162 -0
  181. package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/llm-client-gateway.md +156 -0
  182. package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/model-prompt-evaluation.md +146 -0
  183. package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/retrieval-agent-safety.md +273 -0
  184. package/dist/assets/marketplace/plugins/ccl-skills/skills/miniapp-product-dev/SKILL.md +202 -0
  185. package/dist/assets/marketplace/plugins/ccl-skills/skills/miniapp-product-dev/agents/openai.yaml +4 -0
  186. package/dist/assets/marketplace/plugins/ccl-skills/skills/miniapp-product-dev/references/contracts-and-state.md +62 -0
  187. package/dist/assets/marketplace/plugins/ccl-skills/skills/miniapp-product-dev/references/cross-stack-alignment.md +94 -0
  188. package/dist/assets/marketplace/plugins/ccl-skills/skills/miniapp-product-dev/references/framework-choice.md +76 -0
  189. package/dist/assets/marketplace/plugins/ccl-skills/skills/miniapp-product-dev/references/online-practice-uptake.md +56 -0
  190. package/dist/assets/marketplace/plugins/ccl-skills/skills/miniapp-product-dev/references/platform-capabilities.md +91 -0
  191. package/dist/assets/marketplace/plugins/ccl-skills/skills/miniapp-product-dev/references/product-page-checklist.md +40 -0
  192. package/dist/assets/marketplace/plugins/ccl-skills/skills/miniapp-product-dev/references/qa-release.md +72 -0
  193. package/dist/assets/marketplace/plugins/ccl-skills/skills/miniapp-product-dev/references/source-evidence-map.md +82 -0
  194. package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-agent-delegation/SKILL.md +103 -0
  195. package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-agent-delegation/agents/openai.yaml +5 -0
  196. package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-agent-delegation/references/multi-agent-delegation-playbook.md +100 -0
  197. package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-perspective-research/SKILL.md +70 -0
  198. package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-perspective-research/agents/openai.yaml +4 -0
  199. package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-perspective-research/references/public-data-acquisition.md +549 -0
  200. package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-perspective-research/references/public-disclosure-channels.md +97 -0
  201. package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-perspective-research/references/research-prompts.md +66 -0
  202. package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-perspective-research/scripts/AGENTS.md +32 -0
  203. package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-perspective-research/scripts/test-public-data-acquisition-recipes.sh +379 -0
  204. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/SKILL.md +244 -0
  205. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/agents/openai.yaml +4 -0
  206. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/references/alerting-and-on-call.md +76 -0
  207. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/references/framework-middleware-checklist.md +142 -0
  208. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/references/infra-component-deployment.md +268 -0
  209. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/references/log-correlation-recipe.md +124 -0
  210. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/references/log-schema-canonical.md +208 -0
  211. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/references/metrics-conventions.md +105 -0
  212. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/references/obs-stack-architecture.md +107 -0
  213. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/references/sli-slo-design.md +95 -0
  214. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/references/source-register.md +11 -0
  215. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/SKILL.md +303 -0
  216. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/agents/openai.yaml +4 -0
  217. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/canary-and-rollout-strategy.md +163 -0
  218. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/config-center-via-etcd.md +245 -0
  219. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/custom-control-plane-boundary.md +298 -0
  220. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/deploy-cli-concrete-recipe.md +312 -0
  221. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/deploy-pipeline.md +165 -0
  222. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/env-and-lane-matrix.md +126 -0
  223. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/lane-orchestration-control-plane.md +383 -0
  224. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/multi-region-and-cluster.md +135 -0
  225. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/promotion-gate-and-review.md +149 -0
  226. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/python-package-registry-release.md +462 -0
  227. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/rollback-playbook.md +123 -0
  228. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/secret-and-config-management.md +231 -0
  229. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/version-authority-and-deprecation.md +21 -0
  230. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/SKILL.md +276 -0
  231. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/agents/openai.yaml +4 -0
  232. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/dual-sidecar-and-traffic-config-center.md +127 -0
  233. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/framework-middleware.md +143 -0
  234. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/grpc-authority-workaround.md +90 -0
  235. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/http-response-envelope-contract.md +24 -0
  236. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/mesh-architecture.md +127 -0
  237. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/multi-env-routing.md +192 -0
  238. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/protobuf-http-contract-signals.md +64 -0
  239. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/retry-timeout-circuit-breaker.md +124 -0
  240. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/rpc-framework-recipe.md +494 -0
  241. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/service-discovery-choice.md +113 -0
  242. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/service-discovery-migration-playbook.md +231 -0
  243. package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/service-discovery-recipe.md +131 -0
  244. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/SKILL.md +235 -0
  245. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/agents/openai.yaml +4 -0
  246. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/adr-convention.md +146 -0
  247. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/algorithm-launch-checklist.md +30 -0
  248. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/algorithm-launch-evaluation-report-template.md +25 -0
  249. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/algorithm-launch-execution-spec.md +108 -0
  250. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/algorithm-launch-sop.md +457 -0
  251. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/algorithm-launch-templates.md +24 -0
  252. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/artifact-egress-confidentiality.md +58 -0
  253. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/code-review-checklist.md +86 -0
  254. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/cross-repo-coordination.md +46 -0
  255. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/delivery-lifecycle.md +192 -0
  256. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/design-review-gate-mechanics.md +62 -0
  257. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/design-routing-and-readiness.md +45 -0
  258. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/diagnostic-spec-match-gate.md +36 -0
  259. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/dispatch-owner-skills.md +35 -0
  260. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/dormant-code-activation.md +47 -0
  261. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/existing-project-assessment-report.md +223 -0
  262. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/external-skill-augmentation.md +46 -0
  263. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/feature-deprecation-cascade.md +15 -0
  264. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/high-risk-resilience-gates.md +73 -0
  265. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/implementation-completeness-and-minimality.md +120 -0
  266. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/implementation-entry-reentry-gate.md +122 -0
  267. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/modular-monolith-heuristic.md +105 -0
  268. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/pre-final-continuation-gate.md +115 -0
  269. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/problem-resolution-and-learning.md +62 -0
  270. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/quality-attributes.md +112 -0
  271. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/quality-remediation-program.md +88 -0
  272. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/rd-standards-doc-family-checklist.md +27 -0
  273. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/refactoring-discipline.md +52 -0
  274. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/review-reception.md +34 -0
  275. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/shared-gate-artifact-classification.md +76 -0
  276. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/source-evidence-map.md +31 -0
  277. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/status-tracker-sync.md +77 -0
  278. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/sync-spec-repo-contract.md +25 -0
  279. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/verify-developer-experience.md +34 -0
  280. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/worktree-mechanics.md +55 -0
  281. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/scripts/AGENTS.md +18 -0
  282. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/scripts/check-agent-contract-coverage.sh +213 -0
  283. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/SKILL.md +136 -0
  284. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/agents/openai.yaml +9 -0
  285. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/analytics-visualization-interactions.md +206 -0
  286. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/behavioral-aesthetic-logic.md +108 -0
  287. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/complex-creation-interactions.md +194 -0
  288. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/design-execution-checklist.md +214 -0
  289. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/design-impl-naming-and-versioning.md +53 -0
  290. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/design-intake-and-acceptance.md +129 -0
  291. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/design-system-source-of-truth.md +97 -0
  292. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/external-ui-ux-quality-benchmarks.md +79 -0
  293. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/frontend-code-evidence-map.md +63 -0
  294. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/interaction-design-patterns.md +146 -0
  295. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/layout-recipes-and-screenshot-acceptance.md +250 -0
  296. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/multi-project-token-consistency.md +237 -0
  297. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/multi-stack-strategy.md +65 -0
  298. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/operational-processing-workflows.md +237 -0
  299. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/platform-mobile-patterns.md +324 -0
  300. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/platform-web-desktop-patterns.md +456 -0
  301. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/product-lifecycle-acceptance-and-iteration.md +114 -0
  302. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/product-surface-patterns.md +79 -0
  303. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/resource-management-interactions.md +113 -0
  304. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/scenario-community-patterns.md +133 -0
  305. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/source-map.md +130 -0
  306. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/tokens-and-components.md +47 -0
  307. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/trust-sensitive-ai-and-data-patterns.md +96 -0
  308. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/ui-ux-audit.md +106 -0
  309. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/ui-ux-design-development.md +176 -0
  310. package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/visual-craft.md +111 -0
  311. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/SKILL.md +157 -0
  312. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/agents/openai.yaml +4 -0
  313. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/ai-service-integration-boundaries.md +57 -0
  314. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/api-contract-and-schema.md +62 -0
  315. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/api-security-boundaries.md +39 -0
  316. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/architecture-playbook.md +46 -0
  317. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/async-execution-model.md +24 -0
  318. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/background-jobs-and-scheduling.md +18 -0
  319. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/batch-and-pipeline-architecture.md +11 -0
  320. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/config-secrets-runtime.md +22 -0
  321. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/data-modeling-and-migrations.md +64 -0
  322. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/data-platform-architecture.md +211 -0
  323. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/event-driven-architecture.md +263 -0
  324. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/multi-tenant-isolation.md +281 -0
  325. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/observability-and-ops.md +26 -0
  326. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/packaging-runtime-readiness.md +20 -0
  327. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/redis-cache-coordination.md +41 -0
  328. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/reliability-and-error-contract.md +17 -0
  329. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/source-evidence-map.md +55 -0
  330. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/web-framework-boundaries.md +26 -0
  331. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/SKILL.md +143 -0
  332. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/agents/openai.yaml +4 -0
  333. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/ai-service-wiring-patterns.md +16 -0
  334. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/async-and-worker-patterns.md +24 -0
  335. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/background-job-patterns.md +18 -0
  336. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/batch-and-artifact-patterns.md +13 -0
  337. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/dependency-client-patterns.md +39 -0
  338. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/error-handling-patterns.md +26 -0
  339. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/feature-playbook.md +43 -0
  340. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/observability-implementation-patterns.md +31 -0
  341. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/project-structure-and-tooling.md +24 -0
  342. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/public-api-security-patterns.md +52 -0
  343. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/redis-cache-lock-patterns.md +78 -0
  344. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/schema-and-validation-patterns.md +23 -0
  345. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/source-evidence-map.md +56 -0
  346. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/sqlalchemy-and-migrations-patterns.md +99 -0
  347. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/testing-and-quality-patterns.md +61 -0
  348. package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/web-framework-patterns.md +35 -0
  349. package/dist/assets/marketplace/plugins/ccl-skills/skills/release-coordination/SKILL.md +91 -0
  350. package/dist/assets/marketplace/plugins/ccl-skills/skills/release-coordination/agents/openai.yaml +4 -0
  351. package/dist/assets/marketplace/plugins/ccl-skills/skills/release-coordination/references/config-runtime-readback.md +20 -0
  352. package/dist/assets/marketplace/plugins/ccl-skills/skills/release-coordination/references/mr-merge-authorization.md +31 -0
  353. package/dist/assets/marketplace/plugins/ccl-skills/skills/release-coordination/references/post-release-env-reset.md +31 -0
  354. package/dist/assets/marketplace/plugins/ccl-skills/skills/release-coordination/references/release-closeout-evidence.md +20 -0
  355. package/dist/assets/marketplace/plugins/ccl-skills/skills/release-coordination/references/release-scope-confirmation.md +21 -0
  356. package/dist/assets/marketplace/plugins/ccl-skills/skills/release-coordination/references/tag-and-prod-pipeline-gate.md +20 -0
  357. package/dist/assets/marketplace/plugins/ccl-skills/skills/release-coordination/references/test-scope-prompt.md +24 -0
  358. package/dist/assets/marketplace/plugins/ccl-skills/skills/release-coordination/references/watcher-discipline.md +14 -0
  359. package/dist/assets/marketplace/plugins/ccl-skills/skills/release-doc-writer/SKILL.md +64 -0
  360. package/dist/assets/marketplace/plugins/ccl-skills/skills/release-doc-writer/agents/openai.yaml +4 -0
  361. package/dist/assets/marketplace/plugins/ccl-skills/skills/release-doc-writer/references/comment-safe-release-doc.md +19 -0
  362. package/dist/assets/marketplace/plugins/ccl-skills/skills/release-doc-writer/references/release-evidence-workflow.md +23 -0
  363. package/dist/assets/marketplace/plugins/ccl-skills/skills/release-doc-writer/references/release-testing-scope-section.md +15 -0
  364. package/dist/assets/marketplace/plugins/ccl-skills/skills/requirement-baseline/SKILL.md +87 -0
  365. package/dist/assets/marketplace/plugins/ccl-skills/skills/requirement-baseline/agents/openai.yaml +4 -0
  366. package/dist/assets/marketplace/plugins/ccl-skills/skills/requirement-doc-writer/SKILL.md +130 -0
  367. package/dist/assets/marketplace/plugins/ccl-skills/skills/requirement-doc-writer/agents/openai.yaml +4 -0
  368. package/dist/assets/marketplace/plugins/ccl-skills/skills/requirement-doc-writer/references/prd-composition-contract.md +35 -0
  369. package/dist/assets/marketplace/plugins/ccl-skills/skills/requirement-doc-writer/references/requirement-closure-contract.md +86 -0
  370. package/dist/assets/marketplace/plugins/ccl-skills/skills/requirement-doc-writer/references/security-four-questions.md +38 -0
  371. package/dist/assets/marketplace/plugins/ccl-skills/skills/requirement-intent/SKILL.md +91 -0
  372. package/dist/assets/marketplace/plugins/ccl-skills/skills/requirement-intent/agents/openai.yaml +4 -0
  373. package/dist/assets/marketplace/plugins/ccl-skills/skills/requirement-scope/SKILL.md +88 -0
  374. package/dist/assets/marketplace/plugins/ccl-skills/skills/requirement-scope/agents/openai.yaml +4 -0
  375. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/SKILL.md +337 -0
  376. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/agents/openai.yaml +4 -0
  377. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/analysis-parse-fix-test-challenge-replay.md +47 -0
  378. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/attribution-verification.md +69 -0
  379. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/bootstrap-slim-c3-obligation-table.md +112 -0
  380. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/coverage-exhaustion-traps.md +45 -0
  381. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/description-authoring.md +162 -0
  382. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/dual-track-review-gate.md +507 -0
  383. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/eval-routing.md +86 -0
  384. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/evidence-card-template.md +51 -0
  385. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/example-domain-preselect.md +79 -0
  386. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/external-practice-controls.md +57 -0
  387. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/extraction-lifecycle-handoff.md +65 -0
  388. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/extraction-quickstart.md +194 -0
  389. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/firing-point-placement.md +75 -0
  390. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/harness-patterns-and-eval.md +286 -0
  391. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/incident-postmortem-extraction.md +190 -0
  392. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/l0-l1-l2-routing.md +114 -0
  393. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/online-skill-review.md +47 -0
  394. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/parallel-stack-references-pattern.md +164 -0
  395. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/r0-leakage-audit.md +90 -0
  396. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/recurring-anti-patterns-checklist.md +320 -0
  397. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/resume-paused-delivery.md +16 -0
  398. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/review-feedback-mining.md +33 -0
  399. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/review-finding-standards.md +57 -0
  400. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/review-rubric.md +40 -0
  401. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/rule-consolidation.md +118 -0
  402. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/skill-listing-budget.md +19 -0
  403. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/source-register.md +254 -0
  404. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/source-to-skill-extraction.md +658 -0
  405. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/two-source-extraction-pattern.md +167 -0
  406. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/uiux-judgment-extraction.md +179 -0
  407. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/uiux-routing-map.md +51 -0
  408. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/validation-and-landing.md +180 -0
  409. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/AGENTS.md +18 -0
  410. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/check-ccl-skills.sh +1452 -0
  411. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/check-evidence-card-leak.sh +491 -0
  412. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/check-mr-target-freshness.sh +173 -0
  413. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/check-size-budget.sh +488 -0
  414. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/check-sync-pointers.sh +419 -0
  415. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/eval-golden-trace.rb +197 -0
  416. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/eval-health.rb +327 -0
  417. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/eval-routing-bank.rb +401 -0
  418. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/eval-routing.rb +248 -0
  419. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/generic-r0-leak-scan.sh +282 -0
  420. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/governing-chain-diff.py +321 -0
  421. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/impact-chain-gate.rb +964 -0
  422. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/register-firing-path-resolution.rb +708 -0
  423. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/skill-behavior-eval.py +540 -0
  424. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/source-register-lifecycle.rb +51 -0
  425. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/source-register-pending-status.rb +55 -0
  426. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_ai_coding_implementation_gates.sh +829 -0
  427. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_impact_chain_refscripts.sh +1203 -0
  428. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_r0_status.sh +75 -0
  429. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_register_pending_exclusion.sh +137 -0
  430. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_regressions.sh +173 -0
  431. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_route_drift.sh +377 -0
  432. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_size_budget.sh +833 -0
  433. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_skill_catalog.sh +491 -0
  434. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_source_register_lifecycle.sh +114 -0
  435. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_mr_target_freshness.sh +261 -0
  436. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_sync_pointers.sh +538 -0
  437. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_controlled_escalation_pins.sh +154 -0
  438. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_eval_routing_bank_grader_diagnostics.sh +190 -0
  439. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_eval_routing_bank_surface_binding.sh +178 -0
  440. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_eval_routing_prose_target.sh +86 -0
  441. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_generic_r0_leak_scan.sh +131 -0
  442. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_git_identity_predicate_gate.sh +243 -0
  443. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_governing_chain_diff.sh +419 -0
  444. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_impact_chain_gate_dateless_host.sh +120 -0
  445. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_register_firing_path_resolution.sh +724 -0
  446. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_register_firing_path_wiring.sh +414 -0
  447. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_regression_runner_registration.sh +34 -0
  448. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_routing_bank_integrity.sh +205 -0
  449. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_routing_pointer_integrity.sh +194 -0
  450. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_validate_skill_credential_cwd.sh +61 -0
  451. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_validate_skill_cross_refs.sh +111 -0
  452. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_validate_skill_root_depth.sh +53 -0
  453. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/validate-skill.sh +257 -0
  454. package/dist/assets/marketplace/plugins/ccl-skills/skills/terminal-cli-dev/SKILL.md +98 -0
  455. package/dist/assets/marketplace/plugins/ccl-skills/skills/terminal-cli-dev/agents/openai.yaml +4 -0
  456. package/dist/assets/marketplace/plugins/ccl-skills/skills/terminal-cli-dev/references/input-state-machines.md +36 -0
  457. package/dist/assets/marketplace/plugins/ccl-skills/skills/terminal-cli-dev/references/streaming-rich-output.md +130 -0
  458. package/dist/assets/marketplace/plugins/ccl-skills/skills/terminal-cli-dev/references/terminal-side-channels.md +96 -0
  459. package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/SKILL.md +408 -0
  460. package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/agents/openai.yaml +4 -0
  461. package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/AGENTS.md +18 -0
  462. package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/bitable-setup.md +573 -0
  463. package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/ci_templates/README.md +120 -0
  464. package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/ci_templates/github-actions.yml +119 -0
  465. package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/ci_templates/gitlab-ci.yml +76 -0
  466. package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/ci_templates/jenkins.Jenkinsfile +106 -0
  467. package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/classical-test-design-techniques.md +279 -0
  468. package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/gen_report.py +2807 -0
  469. package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/makefile-template.md +200 -0
  470. package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/report-config-schema.md +272 -0
  471. package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/run_pytestless.py +475 -0
  472. package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/source-to-case-workflows.md +258 -0
  473. package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/tc-marker-conventions.md +316 -0
  474. package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/tc-review-and-prioritization.md +145 -0
  475. package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/tc_helpers/AGENTS.md +16 -0
  476. package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/tc_helpers/tc.dart +129 -0
  477. package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/tc_helpers/tc.go +197 -0
  478. package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/tc_helpers/tc.py +135 -0
  479. package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/tc_helpers/tc.ts +285 -0
  480. package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/test_gen_report.py +2144 -0
  481. package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/update-lifecycle.md +62 -0
  482. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/SKILL.md +212 -0
  483. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/agents/openai.yaml +4 -0
  484. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/ci-fixtures-and-flake-control.md +75 -0
  485. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/client-runtime-test-matrices.md +50 -0
  486. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/data-and-workflow-testing.md +34 -0
  487. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/design-closed-contract-oracles.md +31 -0
  488. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/e2e-real-flow-testing.md +71 -0
  489. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/fitness-functions.md +240 -0
  490. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/integration-contract-testing.md +235 -0
  491. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/non-functional-specialized-scenarios.md +296 -0
  492. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/rd-testing-standard-template.md +126 -0
  493. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/run-killing-mutation-walk.md +43 -0
  494. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/scenario-testing.md +136 -0
  495. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/source-evidence-map.md +59 -0
  496. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/structured-tc-input-translation.md +67 -0
  497. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/test-code-authoring-patterns.md +392 -0
  498. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/test-data-and-determinism.md +39 -0
  499. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/test-topology-and-commands.md +92 -0
  500. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/unit-testing.md +46 -0
  501. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/vendored-contract-drift-checklist.md +64 -0
  502. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/verify-enforcement-mechanisms.md +18 -0
  503. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/scripts/AGENTS.md +17 -0
  504. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/scripts/client-terminal-ansi-check.py +140 -0
  505. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/scripts/client-terminal-ansi-check.test.sh +75 -0
  506. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/scripts/lang-basics-ast-check.py +170 -0
  507. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/scripts/lang-basics-ast-check.test.sh +87 -0
  508. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/scripts/lang-basics-go-check.go +198 -0
  509. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/scripts/lang-basics-go-check.test.sh +109 -0
  510. package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/scripts/test_mutation_backup_recipe.sh +237 -0
  511. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/SKILL.md +184 -0
  512. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/agents/openai.yaml +4 -0
  513. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/references/comment-safe-feishu.md +93 -0
  514. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/references/cross-model-co-review.md +3 -0
  515. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/references/delivery-face-closeout.md +60 -0
  516. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/references/doc-charter-first.md +17 -0
  517. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/references/session-vantage-leakage.md +58 -0
  518. package/dist/assets/marketplace/plugins/ccl-skills/skills/web-react-dev/SKILL.md +126 -0
  519. package/dist/assets/marketplace/plugins/ccl-skills/skills/web-react-dev/agents/openai.yaml +4 -0
  520. package/dist/assets/marketplace/plugins/ccl-skills/skills/web-react-dev/references/complex-workspace-patterns.md +47 -0
  521. package/dist/assets/marketplace/plugins/ccl-skills/skills/web-react-dev/references/embedded-h5-in-host.md +87 -0
  522. package/dist/assets/marketplace/plugins/ccl-skills/skills/web-react-dev/references/react-architecture.md +194 -0
  523. package/dist/assets/marketplace/plugins/ccl-skills/skills/web-react-dev/references/source-evidence-map.md +60 -0
  524. package/dist/assets/marketplace/plugins/ccl-skills/skills/web-react-dev/references/web-quality-release.md +190 -0
  525. package/dist/assets/marketplace/plugins/ccl-skills/skills/web-react-dev/references/web-ui-quality.md +83 -0
  526. package/dist/assets/marketplace/plugins/ccl-skills/skills/worktree-isolation/SKILL.md +179 -0
  527. package/dist/assets/marketplace/plugins/ccl-skills/skills/worktree-isolation/agents/openai.yaml +4 -0
  528. package/dist/assets/marketplace/plugins/ccl-skills/skills/worktree-isolation/references/shared-branch-rebase.md +25 -0
  529. package/dist/assets/marketplace/plugins/ccl-skills/skills/worktree-isolation/scripts/AGENTS.md +23 -0
  530. package/dist/assets/marketplace/plugins/ccl-skills/skills/worktree-isolation/scripts/test_worktree_status.sh +207 -0
  531. package/dist/assets/marketplace/plugins/ccl-skills/skills/worktree-isolation/scripts/test_worktree_sweep.sh +481 -0
  532. package/dist/assets/marketplace/plugins/ccl-skills/skills/worktree-isolation/scripts/worktree-status.sh +325 -0
  533. package/dist/assets/marketplace/plugins/ccl-skills/skills/worktree-isolation/scripts/worktree-sweep.sh +245 -0
  534. package/dist/assets/release.json +2797 -0
  535. package/dist/claude-adapter.d.ts +9 -0
  536. package/dist/claude-adapter.js +240 -0
  537. package/dist/cli-worker.d.ts +1 -0
  538. package/dist/cli-worker.js +32 -0
  539. package/dist/cli.d.ts +22 -0
  540. package/dist/cli.js +214 -0
  541. package/dist/codex-host.d.ts +30 -0
  542. package/dist/codex-host.js +162 -0
  543. package/dist/fs-safe.d.ts +21 -0
  544. package/dist/fs-safe.js +241 -0
  545. package/dist/index.d.ts +2 -0
  546. package/dist/index.js +1 -0
  547. package/dist/manifest.d.ts +8 -0
  548. package/dist/manifest.js +135 -0
  549. package/dist/opencode-adapter.d.ts +10 -0
  550. package/dist/opencode-adapter.js +416 -0
  551. package/dist/operations.d.ts +3 -0
  552. package/dist/operations.js +956 -0
  553. package/dist/paths.d.ts +20 -0
  554. package/dist/paths.js +4 -0
  555. package/dist/types.d.ts +58 -0
  556. package/dist/types.js +1 -0
  557. package/dist/unified.d.ts +4 -0
  558. package/dist/unified.js +64 -0
  559. package/dist/version.d.ts +2 -0
  560. package/dist/version.js +5 -0
  561. package/package.json +35 -0
@@ -0,0 +1,964 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+ #
4
+ # Impact-chain firing gate: every added source-register row for a changed
5
+ # upstream-owner skill must declare a behavioral-evidence status and an
6
+ # observed-failure state, and (for non-wording changes) name an owner-scoped
7
+ # FIRING PATH that resolves to this diff — an anchor on a changed normative
8
+ # rule line, or a changed owner executable. The statuses are required author
9
+ # declarations; the firing path and the wording-only classification are the
10
+ # machine-verified core. Extracted from the former inline `ruby -e` block in
11
+ # check-ccl-skills.sh so the program gets normal Ruby tooling and no
12
+ # single-quote embedding constraint. Invoked by check-ccl-skills.sh (same
13
+ # scripts/ directory) with the target repo root as ARGV[0]; exits 1 on gate
14
+ # failure, 0 otherwise.
15
+
16
+ require "yaml"
17
+ # `description_is_scalar` passes Date to safe_load's permitted_classes; psych
18
+ # only sometimes loads date transitively (<=5.1 lazily, 5.2.0-5.2.5 never,
19
+ # 5.2.6+ eagerly), so declare the dependency instead of riding on that.
20
+ require "date"
21
+
22
+ root = ARGV.fetch(0)
23
+ # Diff reads FAIL CLOSED: a git failure that returned empty output would
24
+ # otherwise make the gate see no changed owners and silently pass.
25
+ git_read = lambda do |*args|
26
+ out = IO.popen(["git", "-C", root, *args], &:read)
27
+ unless $?.success?
28
+ warn "impact_chain_git_failed: git #{args.join(" ")} exited #{$?.exitstatus}"
29
+ exit 1
30
+ end
31
+ out
32
+ end
33
+ base = ENV["CCL_SKILL_BASE_REF"].to_s.strip
34
+ if base.empty?
35
+ upstream_ref = IO.popen(["git", "-C", root, "rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{upstream}", err: File::NULL], &:read).strip
36
+ base = upstream_ref.empty? ? "origin/main" : upstream_ref
37
+ end
38
+ merge_base = IO.popen(["git", "-C", root, "merge-base", base, "HEAD"], &:read).strip
39
+ if merge_base.empty?
40
+ warn "impact_chain_merge_base_missing: #{base}"
41
+ exit 1
42
+ end
43
+ base_ref = merge_base
44
+ LEDGER_PATH = "skills/skill-extraction-workflow/references/source-register.md"
45
+ # ROUND SCOPING. An evidence row is authored against ONE round's diff, but every
46
+ # classifier below used to read the whole base..HEAD range. The two are different
47
+ # units, so a row's verdict moved after it landed: an already-gated row turned red
48
+ # once a LATER round touched the same owner, and a description-only round lost its
49
+ # locator because an EARLIER round had edited that owner's body. Both are the same
50
+ # defect — the predicate was scoped to the RANGE instead of to the round the row
51
+ # belongs to — and patching the symptoms one at a time (the retarget tolerance in
52
+ # the routing-surface class below was one such patch) only re-instantiates it on
53
+ # the next input. The predicate now reads the round.
54
+ #
55
+ # Rounds are cut at the commits that touch the ledger itself, walked first-parent
56
+ # so one merged worktree round collapses to one boundary. The partition comes from
57
+ # git alone: an author cannot widen, move, or nominate their own scope.
58
+ round_heads = git_read.call("rev-list", "--first-parent", "--reverse", "#{base_ref}..HEAD", "--", LEDGER_PATH)
59
+ .split("\n").map(&:strip).reject(&:empty?)
60
+ # Each round spans (previous ledger boundary, this one] so the work commits that
61
+ # precede a ledger append are inside the round they belong to — landing the change
62
+ # and appending the row in separate commits is the normal shape, not an evasion.
63
+ round_bounds = ([base_ref] + round_heads).each_cons(2).to_a
64
+ # The trailing span — owner changes committed after the last ledger append — is a
65
+ # round too. It holds no rows, so its owners fall through to the presence check
66
+ # and the gate still fails closed on undeclared work.
67
+ round_bounds << [round_heads.last || base_ref, "HEAD"]
68
+ # Everything a predicate needs to judge one span. Built lazily per span and
69
+ # memoized: a round whose rows are all RED-baseline never pays for the rename
70
+ # derivation.
71
+ scope_struct = Struct.new(:base, :head, :changed_paths, :rename_pairs, :rename_pattern)
72
+ scope_cache = {}
73
+ scope_at = lambda do |span_base, span_head|
74
+ scope_cache[[span_base, span_head]] ||= begin
75
+ # --no-renames so a moved-out/renamed upstream reference or script surfaces its
76
+ # OLD path (as a delete) instead of collapsing to a destination outside skills/;
77
+ # otherwise `git mv skills/<owner>/references/x.md docs/x.md` would drop the
78
+ # owner entirely and slip past the row requirement.
79
+ # -z + NUL split so a path containing newline/tab bytes cannot hide from the
80
+ # owner and subject-set enumeration behind Git's line-oriented quoting.
81
+ paths = git_read.call("diff", "--no-renames", "-z", span_base, span_head, "--name-only")
82
+ .split("\0").reject(&:empty?)
83
+ # Rename pairs come from git's own tree state — which owner packages disappeared
84
+ # and which appeared — never from an author declaration. How the pairs are derived
85
+ # does not have to be trustworthy: every consumer below only ever gets stricter
86
+ # when a pair is wrong, and nothing here lets a diff be measured against a
87
+ # DIFFERENT file.
88
+ pairs = git_read.call("diff", "--find-renames", "--diff-filter=R", "-z", "--name-status",
89
+ span_base, span_head, "--", "skills/*/SKILL.md")
90
+ .split("\0").reject(&:empty?).each_slice(3).filter_map do |_status, from, to|
91
+ from_owner = from.to_s[%r{\Askills/([^/]+)/SKILL\.md\z}, 1]
92
+ to_owner = to.to_s[%r{\Askills/([^/]+)/SKILL\.md\z}, 1]
93
+ [from_owner, to_owner] if from_owner && to_owner && from_owner != to_owner
94
+ end.to_h
95
+ # Single-pass alternation so one pair's output can never be re-matched by another
96
+ # pair (a chained gsub would let old -> new -> newer cascade).
97
+ pattern = pairs.empty? ? nil : Regexp.union(pairs.keys.sort_by { |k| -k.length }.map { |k| k.dup.force_encoding(Encoding::BINARY) })
98
+ scope_struct.new(span_base, span_head, paths, pairs, pattern)
99
+ end
100
+ end
101
+ # The CUMULATIVE scope still owns everything that asks "was this owner touched at
102
+ # all between base and HEAD" — subject selection and the presence check. Narrowing
103
+ # those to a round would let an owner changed in one round be declared in another,
104
+ # so they deliberately keep reading the whole range.
105
+ cumulative = scope_at.call(base_ref, "HEAD")
106
+ changed_paths = cumulative.changed_paths
107
+ # Normalize every changed path to the owning "<skill>/SKILL.md" identity (the
108
+ # prefix-free form the select rules and source-register evidence convention both
109
+ # use). ANY path inside an owner package maps to the owner — SKILL.md,
110
+ # references/, scripts/, and every other shipped file (agents/ overlays,
111
+ # templates, assets): the whole package is behavior-bearing, and enumerating
112
+ # "behavioral" subdirectories is how the agents/ overlay slipped through.
113
+ # Scoping to exactly one path segment under skills/ (via [^/]+) is what makes
114
+ # the gate fire without letting stray paths like docs/<x>-architecture/SKILL.md
115
+ # trip it.
116
+ # The source-register itself is the impact-chain LEDGER; appending rows to it is a
117
+ # routine, self-referential operation, so it never counts as an upstream change
118
+ # (otherwise every ledger append would demand a row about editing the ledger).
119
+ changed = changed_paths.map do |path|
120
+ next nil if path == "skills/skill-extraction-workflow/references/source-register.md"
121
+ if (m = path.match(%r{\Askills/([^/]+)/.+\z}m))
122
+ "#{m[1]}/SKILL.md"
123
+ end
124
+ end.compact.uniq
125
+ # Curated upstream-owner list for the automated impact-chain gate.
126
+ # When a new skill becomes an upstream decision owner, add it here in the same
127
+ # change that introduces that responsibility.
128
+ upstream_owner_skills = %w[
129
+ code-review
130
+ defect-diagnosis
131
+ feature-risk-router
132
+ llm-inference-integration
133
+ multi-agent-delegation
134
+ multi-perspective-research
135
+ platform-observability
136
+ platform-release-engineering
137
+ platform-service-connectivity
138
+ product-rd-workflow
139
+ product-ui-ux-design
140
+ skill-extraction-workflow
141
+ test-artifact-management
142
+ testing-strategy
143
+ tighten-doc
144
+ ]
145
+ # Name-level selection predicate, shared by the cumulative subject filter and
146
+ # the per-round rename-away suppression below: whether a NAME is a decision
147
+ # owner is a property of the name, independent of whether it exists at the
148
+ # range endpoints.
149
+ selectable_path = lambda do |path|
150
+ path.end_with?("-architecture/SKILL.md") ||
151
+ path.start_with?("platform-") && path.end_with?("/SKILL.md") ||
152
+ upstream_owner_skills.any? { |skill| path == "#{skill}/SKILL.md" }
153
+ end
154
+ upstream = changed.select { |path| selectable_path.call(path) }
155
+ # Subject selection reasons about the whole range, so it reads the cumulative
156
+ # pairs; the per-round classifiers take their pairs from their own scope.
157
+ rename_pairs = cumulative.rename_pairs
158
+ rename_pattern = cumulative.rename_pattern
159
+ # Blob and package readers, hoisted because BOTH the subject filter below and the
160
+ # no-behaviour classifier need them. Binary, because a package may legitimately
161
+ # track a blob that is not valid UTF-8 and comparing bytes must not depend on
162
+ # decoding them; slugs are ASCII so the substitution is unaffected.
163
+ raw_blob_at = lambda do |ref, relative|
164
+ out = IO.popen(["git", "-C", root, "show", "#{ref}:#{relative}", err: File::NULL], &:read)
165
+ $?.success? ? out.force_encoding(Encoding::BINARY) : nil
166
+ end
167
+ # Existence at a ref must mean A REGULAR FILE. `git show ref:path` also succeeds
168
+ # for a TREE, so a directory named SKILL.md would read as "present" and let a
169
+ # row vouch for an owner whose entrypoint was effectively deleted (the
170
+ # extension-challenge P1). ls-tree exposes the entry's mode; only a regular
171
+ # blob counts, so symlinks, submodules, and directories all read as absent and
172
+ # fall through to the deletion fail-closed path.
173
+ regular_blob_at = lambda do |ref, relative|
174
+ out = IO.popen(["git", "-C", root, "ls-tree", "-z", ref, "--", relative], err: File::NULL, &:read)
175
+ next false unless $?.success?
176
+ entry = out.split("\0").reject(&:empty?).first
177
+ next false unless entry
178
+ mode = entry.split(/\s+/, 2).first
179
+ mode == "100644" || mode == "100755"
180
+ end
181
+ # Every tracked entry in an owner package at one ref, as "<mode> <path>". The MODE
182
+ # is part of the identity: names and contents alone would let a diff drop the
183
+ # executable bit from a script and still reproduce byte-for-byte.
184
+ package_files = lambda do |ref, owner|
185
+ out = IO.popen(["git", "-C", root, "ls-tree", "-r", "-z", ref, "--", "skills/#{owner}/"],
186
+ err: File::NULL, &:read)
187
+ next nil unless $?.success?
188
+ out.split("\0").reject(&:empty?).map do |entry|
189
+ meta, path = entry.split("\t", 2)
190
+ "#{meta.to_s.split(/\s+/, 2).first} #{path}"
191
+ end
192
+ end
193
+ # Canonical form of a package path for comparison. The directory moves, and the
194
+ # substitution is applied to BOTH sides so a FILENAME carrying the old slug — a
195
+ # renamed skill's own playbook reference is exactly that case — compares equal
196
+ # whether or not the author also renamed the file. Normalizing rather than
197
+ # rewriting one side keeps the gate from quietly demanding filename renames it has
198
+ # no business requiring.
199
+ canonical_package_path = lambda do |scope, path, base_owner, owner|
200
+ moved = path.sub("skills/#{base_owner}/", "skills/#{owner}/")
201
+ scope.rename_pattern ? moved.gsub(scope.rename_pattern) { |hit| scope.rename_pairs.fetch(hit) } : moved
202
+ end
203
+ # True when HEAD's `owner` package is base's `base_owner` package MOVED: the same
204
+ # file set, one-to-one. Deliberately structural and content-blind, because a real
205
+ # rename normally also edits a heading or a display name — requiring byte equality
206
+ # here would reject every honest rename. It is still far harder to satisfy than
207
+ # git's similarity score, which pairs two SKILL.md files and can therefore mistake
208
+ # "delete one skill, add a similar one" for a move.
209
+ package_moved = lambda do |scope, base_owner, owner|
210
+ base_files = package_files.call(scope.base, base_owner)
211
+ head_files = package_files.call(scope.head, owner)
212
+ return false if base_files.nil? || head_files.nil? || base_files.empty?
213
+ strip = ->(entries) { entries.map { |e| e.split(" ", 2).last } }
214
+ expected = strip.call(base_files).map { |f| canonical_package_path.call(scope, f, base_owner, owner) }
215
+ actual = strip.call(head_files).map { |f| canonical_package_path.call(scope, f, owner, owner) }
216
+ expected.sort == actual.sort
217
+ end
218
+ # True when HEAD's `owner` package is exactly base's `base_owner` package with the
219
+ # identifiers rewritten: one-to-one entries including mode, and byte-exact content
220
+ # under the substitution.
221
+ package_reproduces = lambda do |scope, base_owner, owner|
222
+ return false if scope.rename_pattern.nil?
223
+ base_files = package_files.call(scope.base, base_owner)
224
+ head_files = package_files.call(scope.head, owner)
225
+ return false if base_files.nil? || head_files.nil? || base_files.empty?
226
+ expected = base_files.map do |entry|
227
+ mode, path = entry.split(" ", 2)
228
+ "#{mode} #{canonical_package_path.call(scope, path, base_owner, owner)}"
229
+ end
230
+ return false unless expected.sort == head_files.sort
231
+ base_lookup = base_files.to_h do |entry|
232
+ path = entry.split(" ", 2).last
233
+ [canonical_package_path.call(scope, path, base_owner, owner), path]
234
+ end
235
+ head_files.map { |entry| entry.split(" ", 2).last }
236
+ .reject { |f| f == LEDGER_PATH }
237
+ .all? do |changed|
238
+ base_path = base_lookup.fetch(canonical_package_path.call(scope, changed, owner, owner))
239
+ base_bytes = raw_blob_at.call(scope.base, base_path)
240
+ head_bytes = raw_blob_at.call(scope.head, changed)
241
+ !base_bytes.nil? && !head_bytes.nil? &&
242
+ base_bytes.gsub(scope.rename_pattern) { |hit| scope.rename_pairs.fetch(hit) } == head_bytes
243
+ end
244
+ end
245
+ # A RENAMED-AWAY owner is excused from the CUMULATIVE subject set: for the
246
+ # rename round itself its successor is in `changed` and carries the declaration,
247
+ # so the rename is declared once, against the surviving name. The excuse is
248
+ # cumulative only — a round BEFORE the rename that substantively changed the
249
+ # owner still owes a row under the old name, and the evidence check reads each
250
+ # row against its own round head, so that row is writable and stays valid after
251
+ # the rename. The per-round subject set below re-admits the excused owner for
252
+ # exactly those rounds.
253
+ #
254
+ # A DELETED owner is not that case and stays a subject. Excluding every missing
255
+ # path would let removing a decision owner outright — the larger change of the
256
+ # two — pass with no declaration at all, which is a hole the pre-existing
257
+ # contradiction did not have (it failed closed). Deletions therefore keep failing
258
+ # until the ledger accounts for them, and only a git-confirmed rename whose
259
+ # destination actually survives is dropped here.
260
+ # --no-renames deliberately surfaces the OLD path so a reference or script moved
261
+ # out of a still-live owner cannot slip past; that intent is untouched, because a
262
+ # live owner still has its SKILL.md.
263
+ # Dropping the old path is only sound when the SUCCESSOR is itself a selected
264
+ # subject. Rename a curated owner to a slug nobody added to the list above and
265
+ # neither name is selected: the old one is dropped here and the new one was never
266
+ # picked, so the rename of a decision owner escapes entirely — worse than the
267
+ # contradiction this replaced, which at least failed closed. The destination must
268
+ # already be in the selected set for the declaration to have somewhere to land.
269
+ selected_paths = upstream.to_h { |path| [path, true] }
270
+ # Owners dropped here are remembered: the per-round subject set and the row
271
+ # recognition below re-admit them for the rounds where their SKILL.md still
272
+ # existed, so the cumulative excuse cannot leak backwards onto pre-rename work.
273
+ rename_excused = {}
274
+ upstream = upstream.reject do |path|
275
+ owner = path.sub(%r{/SKILL\.md\z}, "")
276
+ destination = rename_pairs[owner]
277
+ # git --find-renames is a SIMILARITY heuristic: it can pair a deleted SKILL.md
278
+ # with an unrelated new one. For the classifier a wrong pair is harmless — it
279
+ # only makes reproduction fail — but dropping a subject on a wrong pair is the
280
+ # opposite, so this drop is tied to hard evidence instead: the destination
281
+ # package must actually be the source package with the identifiers rewritten.
282
+ excused = !File.file?(File.join(root, "skills", path)) &&
283
+ destination && File.file?(File.join(root, "skills", destination, "SKILL.md")) &&
284
+ selected_paths["#{destination}/SKILL.md"] &&
285
+ package_moved.call(cumulative, owner, destination) &&
286
+ # The cumulative endpoints also pair a round-A DELETE with a round-B ADD of
287
+ # a lookalike — a laundering shape, not a rename. An honest rename is atomic
288
+ # inside one round, so the excuse additionally requires some single round's
289
+ # OWN pairs to contain the source; a cross-round delete/recreate split has
290
+ # no such pair and stays a deletion, which fails closed.
291
+ round_bounds.any? { |span_base, span_head| scope_at.call(span_base, span_head).rename_pairs.key?(owner) }
292
+ rename_excused[path] = true if excused
293
+ excused
294
+ end
295
+ if upstream.any?
296
+ # Rows are collected PER ROUND and carry the scope they were authored against,
297
+ # so the classifiers below judge a row against its own round's diff. Reading the
298
+ # cumulative register diff instead would re-judge every earlier round's rows
299
+ # against a range that keeps growing — the defect this partition removes.
300
+ rows = []
301
+ round_bounds.each do |span_base, span_head|
302
+ round_scope = scope_at.call(span_base, span_head)
303
+ register_diff = git_read.call("diff", span_base, span_head, "--", LEDGER_PATH)
304
+ register_diff.lines.each do |line|
305
+ next unless line.start_with?("+")
306
+ # Strip the diff "+" and any surrounding whitespace so an indented markdown row
307
+ # (up to 3 leading spaces is valid Markdown) parses the same as a column-0 row;
308
+ # the pending-status scan below normalizes identically, keeping the two
309
+ # consistent (previously "+|" alone falsely blocked a valid indented row).
310
+ stripped = line.sub(/\A\+/, "").strip
311
+ next unless stripped.start_with?("|") && stripped.end_with?("|")
312
+ raw = stripped[1..-2]
313
+ # Honor markdown-escaped pipes (\|) so a literal | inside a cell does not
314
+ # split into spurious columns and silently drop the whole row (which would
315
+ # later surface as a misleading "missing evidence path" for a row that is
316
+ # actually present). Split only on UNescaped |, then unescape each cell.
317
+ # Split on column delimiters with correct backslash parity: protect escaped
318
+ # backslashes (\\) then escaped pipes (\|) behind control-char sentinels,
319
+ # split on the remaining bare |, then restore. This way a | escaped by an ODD
320
+ # number of backslashes is literal, but an even count (e.g. \\ before |) is a
321
+ # real delimiter — so a structurally-malformed row is not silently accepted.
322
+ esc_bs = "\u0001"; esc_pipe = "\u0002"
323
+ cells = raw.gsub("\\\\", esc_bs).gsub("\\|", esc_pipe).split("|").map { |c| c.gsub(esc_pipe, "|").gsub(esc_bs, "\\\\").strip }
324
+ if cells.length != 5
325
+ # A line that otherwise looks like an impact-chain data row (cites a
326
+ # SKILL.md and a valid status word) but has the wrong column count is
327
+ # almost always an unescaped literal | inside a cell. Warn (advisory; does
328
+ # not change exit code): the register carries many OTHER legitimate table
329
+ # shapes whose prose can contain a status word and a SKILL.md citation,
330
+ # so hard-blocking here would false-positive on unrelated ledger rows.
331
+ # A deliberately mangled row evading per-row completeness is dishonest
332
+ # authorship — outside this gate's trust model; the warning plus the
333
+ # mandatory independent review own that residual.
334
+ if raw.include?("SKILL.md") && raw.match?(/(updated|unchanged|routed|not-applicable)/)
335
+ warn "impact_chain_row_malformed: likely an unescaped pipe inside a cell (escape it as backslash-pipe): #{line.strip}"
336
+ end
337
+ next
338
+ end
339
+ next unless !cells.any?(&:empty?) && cells[4] != "---" && cells[1] != "Downstream owner"
340
+ status = cells[3].delete("`").strip
341
+ next unless status.match?(/\A(updated|unchanged|routed|not-applicable)\z/)
342
+ rows << { line: line, status: status, evidence: cells[4], behavior: cells[2], scope: round_scope }
343
+ end
344
+ end
345
+ # A row counts only if it SURVIVES at HEAD. Round scoping alone would accept a
346
+ # row added in one round and deleted in a later one: the cumulative read this
347
+ # replaces saw that as a net zero and failed closed, and losing it would make
348
+ # "append the row, drop it next round" a laundering route. The ledger is
349
+ # append-only, so requiring survival costs an honest author nothing. A missing or
350
+ # undecodable register leaves the set empty and every subject falls through to
351
+ # the presence check, which fails closed.
352
+ # Survival is counted as a MULTISET, not a set. A boolean "this text exists at
353
+ # HEAD" is forgeable when the text ALREADY existed at base: append a duplicate in
354
+ # the round that needs a row, drop one copy in a later ledger-only round, and the
355
+ # ledger ends byte-identical while the transient row still reads as surviving.
356
+ # The budget is therefore how many occurrences the round span ADDED — HEAD's count
357
+ # minus base's — and each accepted row consumes one. That also subsumes the
358
+ # first-round-wins rule: a text re-added by a later round finds the budget spent,
359
+ # so an old row's verdict is never re-litigated against a newer round.
360
+ register_row_counts = lambda do |ref|
361
+ bytes = raw_blob_at.call(ref, LEDGER_PATH).to_s.dup.force_encoding(Encoding::UTF_8)
362
+ next Hash.new(0) unless bytes.valid_encoding?
363
+ bytes.lines.each_with_object(Hash.new(0)) { |l, counts| counts[l.strip] += 1 }
364
+ end
365
+ base_row_counts = register_row_counts.call(base_ref)
366
+ head_row_counts = register_row_counts.call("HEAD")
367
+ row_budget = Hash.new(0)
368
+ head_row_counts.each { |text, count| row_budget[text] = count - base_row_counts[text] }
369
+ rows.select! do |row|
370
+ key = row[:line].sub(/\A\+/, "").strip
371
+ next false unless row_budget[key].positive?
372
+ row_budget[key] -= 1
373
+ true
374
+ end
375
+ bad_evidence_files = []
376
+ ambiguous_evidence_rows = []
377
+ evidence_rows_by_upstream_path = Hash.new(0)
378
+ rows_by_upstream_path = Hash.new { |h, k| h[k] = [] }
379
+ declared_in_round = {}
380
+ upstream_set = upstream.to_h { |path| [path, true] }
381
+ # Selected-owner rename LINEAGE. A transient intermediate name — X renamed to
382
+ # Y in one round, Y to Z in a later one — appears in neither the cumulative
383
+ # diff (which pairs X with Z directly) nor the excused set, yet a round that
384
+ # substantively changed Y owes its row like any other selected owner (both
385
+ # review lanes independently found this laundering path). Walk the rounds in
386
+ # order and propagate selection through each round's OWN rename pairs; every
387
+ # name reached this way is treated exactly like the directly-excused source
388
+ # name: demanded and recognized wherever it exists at a round head. Pairs come
389
+ # from git per span, never from an author declaration, and a name outside the
390
+ # selected lineage can never join, so this only ever adds obligations.
391
+ lineage_extra = rename_excused.dup
392
+ round_bounds.each do |span_base, span_head|
393
+ scope_at.call(span_base, span_head).rename_pairs.each do |from_owner, to_owner|
394
+ from_path = "#{from_owner}/SKILL.md"
395
+ to_path = "#{to_owner}/SKILL.md"
396
+ next unless upstream_set[from_path] || lineage_extra[from_path]
397
+ lineage_extra[to_path] = true unless upstream_set[to_path]
398
+ end
399
+ end
400
+ # One round's subject set: the same normalization the cumulative pass uses,
401
+ # intersected with the cumulative selection — so a round can never demand a row
402
+ # for an owner the curated-list filter never picked. A lineage name (the
403
+ # rename-excused source or a transient intermediate hop) is admitted for
404
+ # exactly the rounds where its SKILL.md still exists at the round head: those
405
+ # rounds' rows cite a name that was real when the round landed and stays
406
+ # checkable against that round's head. In the round that renames it away the
407
+ # SKILL.md is gone at the head, so the old name is not demanded there and the
408
+ # successor carries that round's declaration — which is the whole cumulative
409
+ # excuse, now scoped to the one round it is sound for. A DELETED owner was
410
+ # never excused and is unaffected.
411
+ upstream_for_round = lambda do |scope|
412
+ scope.changed_paths.filter_map do |path|
413
+ next nil if path == LEDGER_PATH
414
+ m = path.match(%r{\Askills/([^/]+)/.+\z}m)
415
+ "#{m[1]}/SKILL.md" if m
416
+ end.uniq.select do |candidate|
417
+ next false unless upstream_set[candidate] || lineage_extra[candidate]
418
+ next true if regular_blob_at.call(scope.head, "skills/#{candidate}")
419
+ # Absent at this round's head. The demand is suppressed ONLY when this
420
+ # round's own git-verified pairs rename the name to a SELECTED successor —
421
+ # that successor carries this round's declaration, and a rename CYCLE
422
+ # (A to B, then B back to A) stays fully declarable without ever asking
423
+ # for a row the evidence check must refuse. Everything else stays
424
+ # demanded: a deletion has no pair and fails closed, and a rename to an
425
+ # unselected slug keeps the curated source bound as the named subject.
426
+ owner = candidate.sub(%r{/SKILL\.md\z}, "")
427
+ destination = scope.rename_pairs[owner]
428
+ !(destination && selectable_path.call("#{destination}/SKILL.md"))
429
+ end
430
+ end
431
+ rows.each do |row|
432
+ paths = row[:evidence].scan(/(?<![\w\/.-])([a-z][a-z0-9_-]+\/SKILL\.md)(?![\w\/.-])/).flatten.uniq
433
+ # A lineage name's rows are recognized as declarations, matching the
434
+ # per-round subject set above — demanding a row the mapping then ignored
435
+ # would be the same contradiction the excuse used to justify.
436
+ upstream_paths_in_row = paths.select { |path| upstream_set[path] || lineage_extra[path] }
437
+ if upstream_paths_in_row.length > 1
438
+ ambiguous_evidence_rows << { line: row[:line].sub(/^\+/, "").strip, paths: upstream_paths_in_row }
439
+ end
440
+ if upstream_paths_in_row.length == 1
441
+ evidence_rows_by_upstream_path[upstream_paths_in_row.first] += 1
442
+ rows_by_upstream_path[upstream_paths_in_row.first] << row
443
+ declared_in_round[[row[:scope].base, row[:scope].head, upstream_paths_in_row.first]] = true
444
+ end
445
+ end
446
+ unless ambiguous_evidence_rows.empty?
447
+ warn "impact_chain_row_ambiguous: source-register evidence row cites multiple changed upstream SKILL.md paths; split into one row per changed upstream SKILL.md"
448
+ ambiguous_evidence_rows.each do |row|
449
+ warn " paths: #{row[:paths].join(", ")}"
450
+ warn " row: #{row[:line]}"
451
+ end
452
+ end
453
+ # Existence is checked against the ROW'S OWN ROUND HEAD, not the working tree.
454
+ # A row is authored against one round's diff, so the name it cites only has to
455
+ # be real when that round landed: reading the working tree instead made a later
456
+ # rename retroactively invalidate honest pre-rename rows — and that impossible
457
+ # row was the stated excuse for dropping renamed-away owners from every round's
458
+ # subject set, which let their pre-rename work escape undeclared. A row citing
459
+ # a name its own round never had stays rejected.
460
+ rows.each do |row|
461
+ row[:evidence].scan(/(?<![\w\/.-])([a-z][a-z0-9_-]+\/SKILL\.md)(?![\w\/.-])/).flatten.each do |path|
462
+ bad_evidence_files << path unless regular_blob_at.call(row[:scope].head, "skills/#{path}")
463
+ end
464
+ end
465
+ if bad_evidence_files.any?
466
+ warn "impact_chain_evidence_missing_file: evidence cites a SKILL.md missing at its round head"
467
+ bad_evidence_files.uniq.each { |path| warn " missing: #{path}" }
468
+ exit 1
469
+ end
470
+ # Presence is checked PER ROUND, not across the range. Cumulative presence let
471
+ # owner work committed after a ledger append ride on an EARLIER round's row —
472
+ # the row said nothing about those bytes. Now that classification is round-scoped
473
+ # this is the matching obligation on the other side: the round that changed an
474
+ # owner is the round that owes the row. Work and its ledger append land in the
475
+ # same round whenever no other append separates them, so the ordinary
476
+ # "commit the change, then append the row" shape is unaffected.
477
+ missing_paths = round_bounds.flat_map do |span_base, span_head|
478
+ round_scope = scope_at.call(span_base, span_head)
479
+ upstream_for_round.call(round_scope).reject do |path|
480
+ declared_in_round[[span_base, span_head, path]]
481
+ end
482
+ end.uniq
483
+ unless missing_paths.empty?
484
+ warn "impact_chain_gate_missing: upstream-owner skill changed without a matching source-register impact-chain row"
485
+ warn " note: for an upstream owner, its references/ and scripts/ count as a change too (they ship decision-surface/operational behavior); cite the owning <skill>/SKILL.md in the row evidence cell"
486
+ warn " fix: add one row per changed upstream owner in skill-extraction-workflow/references/source-register.md"
487
+ warn " row shape: | <upstream rule> | `<downstream owner>` | <expected executable behavior> | `updated|unchanged|routed|not-applicable` | <owning `<skill>/SKILL.md` is the machine key; add any changed reference/script path as supporting evidence> | (escape any literal pipe inside a cell as backslash-pipe)"
488
+ upstream.each { |path| warn " changed: #{path}" }
489
+ missing_paths.each { |path| warn " missing evidence path: #{path}" }
490
+ exit 1
491
+ end
492
+
493
+ # A matching owner path proves only that a ledger row exists. It does not
494
+ # prove the changed rule can fire, or that an observed failure now has a
495
+ # firing path. Require the behavioral-evidence declaration and firing path in
496
+ # the SAME added row so a content-only "already covered" disposition cannot
497
+ # satisfy the impact-chain gate. Intentionally diff-scoped: historical rows
498
+ # are not retrofitted.
499
+ behavior_failures = []
500
+ firing_path_failures = []
501
+ # Lazily computed and memoized per owner: most rows are RED-baseline /
502
+ # semantic-control and never consult the wording-only classification, so the
503
+ # per-owner diff subprocess only runs when a row actually declares
504
+ # `not-required wording-only` (or the owner-level RED floor needs it).
505
+ wording_only_diff_cache = {}
506
+ wording_only_diff_for = lambda do |scope, path|
507
+ cache_key = [scope.base, scope.head, path]
508
+ return wording_only_diff_cache[cache_key] if wording_only_diff_cache.key?(cache_key)
509
+ owner = path.sub(%r{/SKILL\.md\z}, "")
510
+ # The letters/digits bar is a PROSE heuristic: in runnable content,
511
+ # punctuation-only edits (`:` -> `! :`, a deleted `)`) change behavior.
512
+ # The class therefore applies only when EVERY changed owner file is
513
+ # Markdown prose; any non-.md file (script, runnable reference, overlay)
514
+ # disqualifies it outright.
515
+ non_prose_changed = scope.changed_paths.any? do |changed|
516
+ next false unless changed.start_with?("skills/#{owner}/")
517
+ next false if changed == LEDGER_PATH
518
+ changed.start_with?("skills/#{owner}/scripts/") || !changed.end_with?(".md")
519
+ end
520
+ owner_diff = git_read.call("diff", "--no-ext-diff", "--unified=0", scope.base, scope.head, "--",
521
+ "skills/#{owner}", ":(exclude)#{LEDGER_PATH}")
522
+ changed_content = owner_diff.lines.filter_map do |line|
523
+ next if line.start_with?("+++", "---")
524
+ line[1..] if line.start_with?("+", "-")
525
+ end
526
+ wording_only_diff_cache[cache_key] = !non_prose_changed && !changed_content.empty? && changed_content.none? { |line| line.match?(/[\p{L}\p{N}]/) }
527
+ end
528
+ # Rename pairs come from git's own tree state — which owner packages
529
+ # disappeared and which appeared — never from an author declaration. How the
530
+ # pairs are derived does not have to be trustworthy, because a wrong pair can
531
+ # only make the reproduction below fail: the class is granted solely when
532
+ # rewriting the BASE bytes with the pairs reproduces the HEAD bytes exactly,
533
+ # so smuggled content of any size breaks equality and falls back to the normal
534
+ # evidence bar. Every derivation error is therefore strictly conservative.
535
+ # This is not the baseline-nomination mechanism removed from the size budget:
536
+ # nothing here lets a diff be measured against a DIFFERENT file — the
537
+ # comparison is always the same path against a mechanical transform of itself.
538
+ # `rename_pairs` / `rename_pattern` are computed before the subject filter above,
539
+ # which needs them to tell a rename apart from a deletion.
540
+ # Named apart from the `blob_at` defined further down: that one returns entry
541
+ # metadata for the firing-path anchors, and sharing the name would silently
542
+ # rebind this closure to it.
543
+ identifier_rename_cache = {}
544
+ identifier_rename_diff_for = lambda do |scope, path|
545
+ cache_key = [scope.base, scope.head, path]
546
+ return identifier_rename_cache[cache_key] if identifier_rename_cache.key?(cache_key)
547
+ owner = path.sub(%r{/SKILL\.md\z}, "")
548
+ identifier_rename_cache[cache_key] = begin
549
+ # The class is for owners that merely RETARGET a pointer. The renamed owner
550
+ # itself never qualifies: its package bytes may reproduce, but the name is
551
+ # how hosts and callers resolve it, so changing it IS the behaviour change —
552
+ # every caller still saying the old name now resolves to nothing. A
553
+ # destination therefore owes the normal RED evidence and firing path, the
554
+ # same bar its own rename record has to meet.
555
+ if scope.rename_pattern.nil? || scope.rename_pairs.value?(owner)
556
+ false
557
+ else
558
+ owner_changed = scope.changed_paths.select do |changed|
559
+ changed.start_with?("skills/#{owner}/") && changed != LEDGER_PATH
560
+ end
561
+ source_owner = scope.rename_pairs.key(owner)
562
+ !owner_changed.empty? && package_reproduces.call(scope, source_owner || owner, owner)
563
+ end
564
+ end
565
+ end
566
+ # A routing-surface-only change edits the frontmatter `description` and nothing
567
+ # else. The firing path must anchor on a CHANGED numbered/list rule carrying a
568
+ # normative verb; a one-line YAML scalar is neither, so such an owner has no
569
+ # anchor to point at and would otherwise be forced to pad its body with a
570
+ # restatement purely to satisfy the anchor — on entrypoints that a separate
571
+ # zero-growth budget forbids from growing at all.
572
+ #
573
+ # The safety argument is the INVERSE of the identifier-rename class and has to
574
+ # be, because a wrong judgement here is LOOSER than the normal bar rather than
575
+ # stricter: nothing is derived or guessed, so there is no derivation that could
576
+ # err conservatively. Instead the class is granted only when the owner's whole
577
+ # change is accounted for byte-for-byte — one changed file, identical body,
578
+ # identical frontmatter apart from the single description entry. Every shape the
579
+ # split cannot fully account for refuses the class.
580
+ routing_surface_cache = {}
581
+ # The file MODE is part of the entrypoint's identity, exactly as it is for the
582
+ # package comparison above: bytes alone would let `chmod +x` on SKILL.md ride
583
+ # along with a description edit and still read as description-only.
584
+ entry_mode = lambda do |ref, relative|
585
+ out = IO.popen(["git", "-C", root, "ls-tree", "-z", ref, "--", relative], err: File::NULL, &:read)
586
+ next nil unless $?.success?
587
+ entry = out.split("\0").reject(&:empty?).first
588
+ entry && entry.split(/\s+/, 2).first
589
+ end
590
+ # "---\n<frontmatter>\n---\n<body>" -> [frontmatter, body] as BYTES, or nil when
591
+ # the delimiters are not exactly where the format requires.
592
+ split_frontmatter = lambda do |bytes|
593
+ m = bytes.match(/\A---\n(.*?\n)---\n/m)
594
+ next nil unless m
595
+ [m[1], m.post_match]
596
+ end
597
+ # Split the frontmatter into [everything that is not the description entry, the
598
+ # description entry itself]. The entry is its `description:` line plus any
599
+ # indented continuation lines, so a block or folded scalar is one entry rather
600
+ # than a first line and some orphans. Absent or repeated keys return nil, which
601
+ # refuses the class rather than picking one.
602
+ split_description_entry = lambda do |frontmatter|
603
+ lines = frontmatter.lines
604
+ # YAML allows the key quoted or spaced before the colon; refusing those forms
605
+ # would block a legitimate description-only change with no satisfiable anchor.
606
+ key = /\A(?:"description"|'description'|description)[ \t]*:/
607
+ starts = lines.each_index.select { |i| lines[i].match?(key) }
608
+ next nil unless starts.length == 1
609
+ first = starts.first
610
+ # The entry runs to the next TOP-LEVEL key, not to the first unindented line:
611
+ # a folded scalar may contain blank lines between paragraphs, and stopping at
612
+ # one would move the later paragraphs into the "other keys" set and refuse a
613
+ # perfectly ordinary description edit. Indentation is a shape proxy; "where the
614
+ # next top-level key starts" is the structure YAML itself uses.
615
+ last = first + 1
616
+ last += 1 while last < lines.length && !lines[last].match?(/\A\S/)
617
+ [lines[0...first] + lines[last..], lines[first...last]]
618
+ end
619
+ # Whatever the line split decides, the value must still BE a description: a
620
+ # string. Widening the entry to the next top-level key means a nested mapping
621
+ # (`description:` followed by indented `key: value` pairs) would otherwise ride
622
+ # inside the entry, letting arbitrary frontmatter through and even carrying the
623
+ # anchor. Parsing settles it with the format's own rules rather than another
624
+ # shape heuristic; anything that fails to parse, or whose description is not a
625
+ # string, refuses the class.
626
+ # Whatever the line split decides, the value must still BE a description: a
627
+ # string. Widening the entry to the next top-level key means a nested mapping
628
+ # (`description:` followed by indented `key: value` pairs) would otherwise ride
629
+ # inside the entry, letting arbitrary frontmatter through and even carrying the
630
+ # locator. Parse ONLY the entry, never the whole frontmatter: a sibling key that
631
+ # deserializes to a Date or uses an alias makes `safe_load` raise, and rescuing
632
+ # that to nil would refuse a legitimate owner for a key this class does not care
633
+ # about. Anything that still fails to parse, or whose description is not a
634
+ # string, refuses the class.
635
+ description_is_scalar = lambda do |frontmatter|
636
+ text = frontmatter.dup.force_encoding(Encoding::UTF_8)
637
+ next false unless text.valid_encoding?
638
+ parsed = begin
639
+ YAML.safe_load(text, permitted_classes: [Date, Time], aliases: true)
640
+ rescue StandardError
641
+ nil
642
+ end
643
+ parsed.is_a?(Hash) && parsed["description"].is_a?(String)
644
+ end
645
+ routing_surface_diff_for = lambda do |scope, path|
646
+ cache_key = [scope.base, scope.head, path]
647
+ return routing_surface_cache[cache_key] if routing_surface_cache.key?(cache_key)
648
+ owner = path.sub(%r{/SKILL\.md\z}, "")
649
+ routing_surface_cache[cache_key] = begin
650
+ # NO register exclusion here, unlike the classifiers above. The ledger lives
651
+ # inside one owner's package, and for that owner "the entire change is the
652
+ # description" would otherwise be satisfiable while arbitrary normative
653
+ # ledger content rode along. Dropping the exclusion costs the other owners
654
+ # nothing (the ledger is not under their package) and correctly makes the
655
+ # class unavailable to the owner that ships it.
656
+ owner_changed = scope.changed_paths.select { |changed| changed.start_with?("skills/#{owner}/") }
657
+ entrypoint = "skills/#{owner}/SKILL.md"
658
+ # The rest of the package may differ ONLY by a rename retarget — the same
659
+ # class the gate already machine-proves carries no obligation. This tolerance
660
+ # was added when the classifier still read the whole accumulating range and an
661
+ # owner whose only behaviour was its description got refused for retargets
662
+ # already declared no-behaviour; the round scoping now removes that pressure
663
+ # at the source, and the tolerance stays only because a retarget landing in
664
+ # the SAME round is still genuinely no-behaviour. The bound is the identical
665
+ # byte-exact reproduction used there: apply git's own rename pairs to the base
666
+ # bytes and require the head bytes exactly, mode included. A file that cannot
667
+ # be accounted for that way — one real byte of content — takes the locator away.
668
+ # One normalizer for both halves: the entrypoint's own body and non-description
669
+ # keys mention renamed slugs too, so comparing them raw would refuse the very
670
+ # shape this composition exists for. The description entry is exempt because
671
+ # it is the change being evidenced.
672
+ retarget = lambda do |bytes|
673
+ next bytes unless scope.rename_pattern
674
+ bytes.gsub(scope.rename_pattern) { |hit| scope.rename_pairs.fetch(hit).dup.force_encoding(Encoding::BINARY) }
675
+ end
676
+ others_reproduce = (owner_changed - [entrypoint]).all? do |other|
677
+ # Prose only, for the same reason the wording-only class refuses non-.md
678
+ # files: a substitution reproducing a SCRIPT's bytes says nothing about
679
+ # whether rewriting that identifier was safe there. Some occurrences of an
680
+ # old slug are deliberately kept — a persisted key, an uninstall manifest —
681
+ # and rewriting one is a behaviour change the normalizer would wave through.
682
+ next false if other.start_with?("skills/#{owner}/scripts/") || !other.end_with?(".md")
683
+ # Regular files only, on BOTH sides. A symlink's blob is its TARGET, so a
684
+ # `.md` symlink whose target carries an old slug reproduces under the
685
+ # substitution while what the path resolves to changes — a filesystem
686
+ # behaviour the normalizer has no business clearing. Same for a mode flip.
687
+ next false unless entry_mode.call(scope.base, other) == "100644"
688
+ next false unless entry_mode.call(scope.head, other) == "100644"
689
+ base_bytes = raw_blob_at.call(scope.base, other)
690
+ head_bytes = raw_blob_at.call(scope.head, other)
691
+ next false if base_bytes.nil? || head_bytes.nil?
692
+ retarget.call(base_bytes) == head_bytes
693
+ end
694
+ if !owner_changed.include?(entrypoint) || !others_reproduce
695
+ false
696
+ else
697
+ # `path` is owner-relative in this loop; blob reads need the repo path.
698
+ base_bytes = raw_blob_at.call(scope.base, entrypoint)
699
+ head_bytes = raw_blob_at.call(scope.head, entrypoint)
700
+ base_parts = base_bytes && split_frontmatter.call(base_bytes)
701
+ head_parts = head_bytes && split_frontmatter.call(head_bytes)
702
+ if base_parts.nil? || head_parts.nil?
703
+ false
704
+ else
705
+ base_split = split_description_entry.call(base_parts[0])
706
+ head_split = split_description_entry.call(head_parts[0])
707
+ !base_split.nil? && !head_split.nil? &&
708
+ base_split[0].map { |l| retarget.call(l) } == head_split[0] &&
709
+ retarget.call(base_parts[1]) == head_parts[1] &&
710
+ base_split[1].map { |l| retarget.call(l) } != head_split[1] &&
711
+ description_is_scalar.call(base_parts[0]) && description_is_scalar.call(head_parts[0]) &&
712
+ entry_mode.call(scope.base, entrypoint) == entry_mode.call(scope.head, entrypoint) &&
713
+ !entry_mode.call(scope.head, entrypoint).nil?
714
+ end
715
+ end
716
+ end
717
+ end
718
+ added_lines_cache = {}
719
+ added_lines_for = lambda do |scope, relative|
720
+ rel = relative.to_s.strip
721
+ added_lines_cache[[scope.base, scope.head, rel]] ||=
722
+ git_read.call("diff", "--no-ext-diff", "--unified=0", scope.base, scope.head, "--", rel).lines.filter_map do |line|
723
+ next if line.start_with?("+++")
724
+ line[1..]&.chomp if line.start_with?("+")
725
+ end
726
+ end
727
+ # Raw tree entry at a path (memoized, including nil): `mode type oid\tpath`,
728
+ # or nil when no entry of ANY type exists. `-z` keeps the path raw so entries
729
+ # for paths with unusual bytes still compare equal to the requested rel
730
+ # instead of failing on git's line-oriented quoting.
731
+ tree_entry_cache = {}
732
+ tree_entry_at = lambda do |treeish, relative|
733
+ rel = relative.to_s.strip
734
+ next nil if rel.empty? || rel.start_with?("/") || rel.include?(":") || rel.split("/").include?("..")
735
+ key = [treeish, rel]
736
+ next tree_entry_cache[key] if tree_entry_cache.key?(key)
737
+ entry = IO.popen(["git", "-C", root, "ls-tree", "-z", treeish, "--", rel], &:read).split("\0").first.to_s
738
+ tree_entry_cache[key] = entry.empty? ? nil : entry
739
+ end
740
+ # Memoized (including nil results): the same (treeish, path) blob can be
741
+ # fetched by several locator checks; without the cache each fetch costs git
742
+ # subprocesses. Only a regular blob (100644/100755) resolves; symlinks,
743
+ # submodules, and trees return nil.
744
+ blob_cache = {}
745
+ blob_at = lambda do |treeish, relative|
746
+ rel = relative.to_s.strip
747
+ key = [treeish, rel]
748
+ next blob_cache[key] if blob_cache.key?(key)
749
+ entry = tree_entry_at.call(treeish, rel)
750
+ blob_cache[key] = if entry
751
+ meta, listed = entry.split("\t", 2)
752
+ mode, type, _oid = meta.to_s.split(/\s+/, 3)
753
+ if %w[100644 100755].include?(mode) && type == "blob" && listed == rel
754
+ content = IO.popen(["git", "-C", root, "show", "#{treeish}:#{rel}"], &:read)
755
+ { path: rel, mode: mode, content: content }
756
+ end
757
+ end
758
+ end
759
+ # The locator must resolve in the round's own head, not the branch tip: a later
760
+ # round that deletes or rewrites the anchored file must not retroactively
761
+ # invalidate — or silently re-validate — an earlier round's locator.
762
+ head_blob = ->(scope, relative) { blob_at.call(scope.head, relative) }
763
+ locator_parts = lambda do |raw|
764
+ locator = raw.to_s.strip
765
+ if (m = locator.match(/\Acommand:([^\s;]+)\z/))
766
+ { kind: "command", path: m[1] }
767
+ elsif (m = locator.match(/\Afile:([^#\s;]+)#(.+)\z/))
768
+ anchor = m[2].strip
769
+ { kind: "file", path: m[1], anchor: anchor } unless anchor.empty?
770
+ end
771
+ end
772
+ locator_valid = lambda do |scope, raw|
773
+ parts = locator_parts.call(raw)
774
+ next false unless parts
775
+ blob = head_blob.call(scope, parts[:path])
776
+ added = added_lines_for.call(scope, parts[:path])
777
+ next false unless blob && !added.empty?
778
+ if parts[:kind] == "command"
779
+ # An executable firing surface must actually be a script: mode 100755
780
+ # AND a shebang. Without this, any changed file with the executable bit
781
+ # (even a chmod'ed Markdown file) satisfies a command locator.
782
+ blob[:mode] == "100755" && blob[:content].start_with?("#!")
783
+ else
784
+ anchor = parts[:anchor]
785
+ anchor.length >= 16 &&
786
+ added.count { |line| line.include?(anchor) } == 1 &&
787
+ blob[:content].scan(Regexp.new(Regexp.escape(anchor))).length == 1
788
+ end
789
+ end
790
+ enforcing_file_locator_valid = lambda do |scope, parts|
791
+ next false unless parts && parts[:kind] == "file"
792
+ next false unless parts[:path].end_with?(".md")
793
+ next false unless locator_valid.call(scope, "file:#{parts[:path]}##{parts[:anchor]}")
794
+ line = added_lines_for.call(scope, parts[:path]).find { |added| added.include?(parts[:anchor]) }
795
+ next false unless line
796
+ # A non-rendered HTML comment can smuggle normative vocabulary past the
797
+ # heuristic (`- <!-- must ... -->`); an anchor line carrying a comment
798
+ # marker is never an enforcing rule surface.
799
+ next false if line.include?("<!--")
800
+ list_rule = line.lstrip.match?(/\A(?:[-*+]\s+|\d+[.)]\s+)/)
801
+ # Normative-action vocabulary. This is a recall heuristic, not a semantic
802
+ # parser: it accepts common imperative/prohibitive phrasings in English and
803
+ # Chinese (never/do not/应当/务必/不能 included so a genuinely normative
804
+ # rule is not rejected for its verb choice) while still refusing anchors on
805
+ # purely descriptive prose. Deliberately excluded for precision: "always"
806
+ # and "does not" (dominant descriptive uses — "the host always exposes",
807
+ # "the adapter does not support"), and single characters with broad
808
+ # compounds (应/只/别 — 应用/只是/区别).
809
+ normative = line.match?(/(?:\b(?:must|shall|never|do\s+not|don'?t|required?|requires?|block(?:s|ed)?|reject(?:s|ed)?|deny|denied|invalidates?|forbid(?:s|den)?|cannot|enforcement)\b|必须|不得|禁止|拒绝|作废|仅限|只能|应当|应该|务必|不能|不允许|不可)/i)
810
+ list_rule && normative
811
+ end
812
+ # A routing-surface-only owner has no changed rule line to anchor on: its whole
813
+ # change is one YAML scalar. The answer is NOT to exempt it — a description edit
814
+ # IS a routing behaviour change (it decides which requests reach the skill), so
815
+ # exempting it would drop the evidence requirement from the class that carries
816
+ # the most behaviour, and its evidence exists anyway as a measured routing delta.
817
+ # Instead the anchor may land on the changed description entry itself. Every other
818
+ # requirement is unchanged — owner-scoped path, minimum length, unique in the
819
+ # file, present in this diff's added lines — and only the "numbered/list rule with
820
+ # a normative verb" SHAPE is lifted, because a YAML scalar can never take it.
821
+ # The widening is bounded by the same byte-exact predicate: an owner that changed
822
+ # anything besides the description keeps the ordinary anchor bar.
823
+ routing_surface_anchor_valid = lambda do |scope, parts, owner|
824
+ next false unless parts[:kind] == "file"
825
+ next false unless parts[:path] == "skills/#{owner}/SKILL.md"
826
+ # A CANONICAL FIELD LOCATOR, not a text search. Three designs tried to make a
827
+ # substring anchor prove which bytes changed — a numbered/list rule shape, then
828
+ # the `description:` line, then any line of the entry — and each was refuted in
829
+ # turn, the last because a substring that merely SURVIVES the edit identifies
830
+ # nothing. Same class three times is the signal to drop the proxy rather than
831
+ # patch it again: the predicate below already proves the entire owner diff IS
832
+ # the description entry, so the locator's only job is to name that field. The
833
+ # length/uniqueness rules that guard a free-text anchor have nothing to guard
834
+ # here, and applying them to a constant would be ceremony dressed as evidence.
835
+ next false unless parts[:anchor] == "description"
836
+ routing_surface_diff_for.call(scope, "#{owner}/SKILL.md")
837
+ end
838
+ firing_locator_valid = lambda do |scope, parts, owner|
839
+ next false unless parts && parts[:path].start_with?("skills/#{owner}/")
840
+ if parts[:kind] == "command"
841
+ locator_valid.call(scope, "command:#{parts[:path]}")
842
+ else
843
+ routing_surface_anchor_valid.call(scope, parts, owner) ||
844
+ enforcing_file_locator_valid.call(scope, parts)
845
+ end
846
+ end
847
+ # Lineage names join the walk: their recognized rows must clear the same
848
+ # behavior-evidence and firing-path bar as everyone else's (each row judged
849
+ # against its own round, where its anchors resolve), or the admission above
850
+ # would accept rows it never validates.
851
+ (upstream + lineage_extra.keys).each do |path|
852
+ owner_rows = rows_by_upstream_path[path]
853
+ next if owner_rows.empty? # reported by impact_chain_gate_missing above
854
+ owner = path.sub(%r{/SKILL\.md\z}, "")
855
+
856
+ # Parse and validate each row exactly once; both the pass/fail decision and
857
+ # the failure-bucket classification below consume these structs, so the row
858
+ # grammar lives in one place and a failing owner does not pay a second full
859
+ # validation walk (each walk costs git subprocesses via the blob lookups).
860
+ evaluated = owner_rows.map do |row|
861
+ # Every predicate below reads the row's OWN round. This is what makes a
862
+ # verdict stable: the span it is judged against is fixed when the row lands
863
+ # and cannot grow afterwards.
864
+ row_scope = row[:scope]
865
+ text = row[:behavior]
866
+ # Declarations parse from semicolon-delimited fragments, each field
867
+ # anchored at its fragment start: a key embedded mid-prose ("no
868
+ # behavioral-evidence: ...") or carrying a suffixed value never counts.
869
+ declarations = {}
870
+ text.split(";").each do |fragment|
871
+ if (m = fragment.match(/\A\s*(behavioral-evidence|observed-failure|firing-path):\s*(.+?)\s*\z/i))
872
+ declarations[m[1].downcase] ||= m[2]
873
+ end
874
+ end
875
+ status = declarations["behavioral-evidence"]&.[](/\A(RED-baseline|semantic-control|not-required\s+wording-only|not-required\s+identifier-rename)\z/i, 1)
876
+ normalized_status = status&.downcase&.gsub(/\s+/, " ")
877
+ declared_wording_only = normalized_status == "not-required wording-only"
878
+ wording_only = declared_wording_only && wording_only_diff_for.call(row_scope, path)
879
+ declared_identifier_rename = normalized_status == "not-required identifier-rename"
880
+ identifier_rename = declared_identifier_rename && identifier_rename_diff_for.call(row_scope, path)
881
+ # Both no-behavior classes are machine-verified, so they share a branch. A
882
+ # routing-surface-only change is NOT one of them: it carries behaviour, so it
883
+ # keeps the RED-baseline bar and only gains a place its anchor can bind.
884
+ no_behavior_class = wording_only || identifier_rename
885
+ observed = declarations["observed-failure"]&.[](/\A(yes|no)\z/i, 1)&.downcase
886
+ semantic_control = normalized_status == "semantic-control" && observed == "no"
887
+ status_allowed = no_behavior_class || normalized_status == "red-baseline" || semantic_control
888
+ firing_path = declarations["firing-path"]&.[](/\A((?:command|file):.+)\z/i, 1)&.strip
889
+ firing_parts = locator_parts.call(firing_path)
890
+ firing_path_valid = firing_locator_valid.call(row_scope, firing_parts, owner)
891
+ # The machine-checked core is the FIRING PATH (an owner-scoped anchor on a
892
+ # changed normative rule, or a changed owner executable) plus the
893
+ # deterministic wording-only classification. The behavioral-evidence
894
+ # status and observed-failure fields are required author declarations —
895
+ # honest labels, not digest-verified artifacts: a digest-bound evidence
896
+ # apparatus was evaluated here and removed because its per-iteration
897
+ # regeneration cost (full-suite reruns on every owner-script byte change)
898
+ # far outweighed the staleness detection it added under the
899
+ # unsigned-repository-local trust model.
900
+ row_valid = if no_behavior_class
901
+ # Neither `not-required` class is an author-controlled waiver: each is
902
+ # accepted only when the owner diff itself passes the matching
903
+ # deterministic classifier — letters/digits-free for wording-only,
904
+ # byte-exact reproduction under the git-derived rename pairs for
905
+ # identifier-rename. Both record no observed failure, and neither can
906
+ # carry a firing path, because a retarget changes no normative rule to
907
+ # anchor one on.
908
+ status_allowed && observed == "no"
909
+ else
910
+ status_allowed && firing_path_valid &&
911
+ (observed == "no" || (observed == "yes" && status&.casecmp?("RED-baseline")))
912
+ end
913
+ {
914
+ red_declared: normalized_status == "red-baseline",
915
+ row_valid: row_valid,
916
+ firing_path_valid: firing_path_valid
917
+ }
918
+ end
919
+
920
+ # A stable-control label can say one named behavior did not change, but it
921
+ # cannot vouch for the rest of a non-wording owner diff. Require at least
922
+ # one RED-baseline row per non-wording owner so a package cannot self-clear
923
+ # on semantic-control labels alone. The floor is lifted only for the two
924
+ # machine-verified no-behavior classes, whose whole point is that there is
925
+ # nothing left for a label to hide: an owner whose bytes are reproduced by
926
+ # rewriting identifiers has no unvouched-for remainder, so demanding an
927
+ # observed delta there would only be satisfiable by inventing one.
928
+ # The floor deliberately reads the CUMULATIVE diff, not a round. It asks
929
+ # whether anything in this owner's whole change is left unvouched-for, so
930
+ # narrowing it to one round would let a package self-clear on the one round
931
+ # that happened to be punctuation-only. Cumulative is the strictly stricter
932
+ # reading of the two, so the round scoping cannot loosen this floor.
933
+ valid = evaluated.all? { |entry| entry[:row_valid] }
934
+ valid &&= evaluated.any? { |entry| entry[:red_declared] } ||
935
+ wording_only_diff_for.call(cumulative, path) ||
936
+ identifier_rename_diff_for.call(cumulative, path)
937
+ next if valid
938
+
939
+ # Bucket the failure for the diagnostic: a declared RED row whose firing
940
+ # path is broken gets the firing-path message; every other failure shape
941
+ # gets the behavior-evidence message. (A declared wording-only row can
942
+ # never be a RED row, so no exclusion is needed here.)
943
+ firing_path_incomplete = evaluated.any? do |entry|
944
+ entry[:red_declared] && !entry[:firing_path_valid]
945
+ end
946
+ if firing_path_incomplete
947
+ firing_path_failures << path
948
+ else
949
+ behavior_failures << path
950
+ end
951
+ end
952
+ unless firing_path_failures.empty?
953
+ warn "impact_chain_firing_path_missing: RED-baseline row has no owner-scoped firing path in this committed diff"
954
+ warn " fix: point to this owner with `firing-path: command:<changed repo executable>` or `firing-path: file:<changed markdown>#<unique token on a changed numbered/list rule with a normative action>`"
955
+ firing_path_failures.each { |path| warn " incomplete: #{path}" }
956
+ exit 1
957
+ end
958
+ unless behavior_failures.empty?
959
+ warn "impact_chain_behavior_evidence_missing: at least one added upstream-owner row lacks a complete behavioral-evidence declaration"
960
+ warn " fix: every added row for a changed upstream owner needs `behavioral-evidence: RED-baseline` (observed deltas; observed-failure: yes requires it) or `semantic-control` (only with observed-failure: no), plus `observed-failure: yes/no` and an owner-scoped `firing-path:`; a non-wording owner package needs at least one RED-baseline row; only deterministically wording-only diffs (no letters or digits changed) may use `not-required wording-only`, and only diffs whose base bytes are reproduced exactly by applying git-derived skill-rename pairs may use `not-required identifier-rename` (both drop the firing-path requirement and require observed-failure: no); an owner whose ENTIRE change is the SKILL.md frontmatter description entry keeps the RED-baseline bar and may anchor its firing path on that changed description line"
961
+ behavior_failures.each { |path| warn " incomplete: #{path}" }
962
+ exit 1
963
+ end
964
+ end