@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,941 @@
1
+ #!/usr/bin/env bash
2
+ # RED -> GREEN behavioral + adversarial suite for the owner-dispatch firing gate.
3
+ # Each case proves: WITHOUT the rule the action proceeds silently (baseline);
4
+ # WITH it the gate fires; and the safety invariants (fail-open, symlink-safe,
5
+ # per-session, no-trap, CI anti-bypass) hold.
6
+ set -u
7
+ ENGINE="$(cd "$(dirname "$0")" && pwd)/owner-dispatch.sh"
8
+ PASS=0; FAIL=0
9
+ ok() { PASS=$((PASS+1)); printf ' ok %s\n' "$1"; }
10
+ bad() { FAIL=$((FAIL+1)); printf ' FAIL %s\n %s\n' "$1" "${2:-}"; }
11
+
12
+ WORK=$(mktemp -d) || { echo "FATAL: mktemp -d failed (no writable TMPDIR)"; exit 1; }
13
+ trap 'rm -rf "$WORK"' EXIT
14
+ REPO="$WORK/prod"; mkdir -p "$REPO/src"
15
+ git -C "$REPO" init -q
16
+ git -C "$REPO" config user.email t@t; git -C "$REPO" config user.name t
17
+ echo "package x" > "$REPO/src/foo.go"; echo "# readme" > "$REPO/README.md"
18
+ git -C "$REPO" add -A; git -C "$REPO" commit -qm init
19
+ BDIR="$(git -C "$REPO" rev-parse --absolute-git-dir)/owner-dispatch"
20
+
21
+ edit() { printf '{"tool_name":"Edit","tool_input":{"file_path":"%s"},"session_id":"%s"}' "$1" "${2:-S0}"; }
22
+ bashj(){ printf '{"tool_name":"Bash","tool_input":{"command":"%s"}}' "$1"; }
23
+ bashjs(){ printf '{"tool_name":"Bash","tool_input":{"command":"%s"},"session_id":"%s"}' "$1" "$2"; }
24
+ stopj(){ printf '{"session_id":"%s"}' "${1:-}"; }
25
+ # opt-in now requires the config to be TRACKED at the git top-level, so commit it.
26
+ config(){ cat > "$REPO/.owner-dispatch.json"; ( cd "$REPO" && git add .owner-dispatch.json && git commit -q -m cfg -- .owner-dispatch.json ) >/dev/null 2>&1 || true; }
27
+ decision(){ jq -r '.hookSpecificOutput.permissionDecision // "allow"' 2>/dev/null; }
28
+ sdecision(){ local o; o=$(cat); [ -z "$o" ] && { echo stop; return; }; printf '%s' "$o" | jq -r '.decision // "stop"' 2>/dev/null; }
29
+
30
+ echo "owner-dispatch suite"
31
+
32
+ # 1. RED baseline: no config => silent allow.
33
+ out=$(edit "$REPO/src/foo.go" | bash "$ENGINE" pretool)
34
+ [ -z "$out" ] && ok "baseline: no config => silent allow" || bad "baseline" "got:$out"
35
+
36
+ config <<'JSON'
37
+ { "enabled": true, "strict": false, "gate_bash": true,
38
+ "product_globs": ["src/**"], "exclude_globs": ["**/*_test.*"],
39
+ "owner_hint": "product-rd-workflow + the stack *-dev owner" }
40
+ JSON
41
+
42
+ # 2. GREEN gated edit, no boundary => ask.
43
+ [ "$(edit "$REPO/src/foo.go" S1 | bash "$ENGINE" pretool | decision)" = ask ] && ok "gated edit, no boundary => ask" || bad "expected ask"
44
+ # 3. excluded test file => allow.
45
+ echo x > "$REPO/src/foo_test.go"
46
+ [ -z "$(edit "$REPO/src/foo_test.go" | bash "$ENGINE" pretool)" ] && ok "excluded *_test.* => allow" || bad "excluded"
47
+ # 4. non-product => allow.
48
+ [ -z "$(edit "$REPO/README.md" | bash "$ENGINE" pretool)" ] && ok "non-product README => allow" || bad "README"
49
+ # 5. boundary recorded => allow.
50
+ ( cd "$REPO" && bash "$ENGINE" record --owners "product-rd-workflow,go-dev" >/dev/null )
51
+ [ -z "$(edit "$REPO/src/foo.go" | bash "$ENGINE" pretool)" ] && ok "boundary recorded => allow" || bad "boundary allow"
52
+ # 5b. boundary SURVIVES a FORWARD HEAD move. Validity requires ancestry, not equality: the gate
53
+ # requires recording before the first gated edit, and a delivery's own commit lands
54
+ # after that edit — so pinning invalidated every committing delivery's own boundary and
55
+ # made Stop report it as "never recorded". This asserts the HEAD-independent lifetime
56
+ # ONLY — it does not assert anything about actor identity, which the gate does not
57
+ # enforce (see the residual note on boundary_valid).
58
+ git -C "$REPO" commit -q --allow-empty -m moved
59
+ out_v5=$(edit "$REPO/src/foo.go" | bash "$ENGINE" pretool); st_v5=$?
60
+ [ "$st_v5" = 0 ] && [ -z "$out_v5" ] \
61
+ && ok "boundary survives HEAD move => allow" || bad "V5: HEAD move must not invalidate a boundary"
62
+ # 5b-2. …but only FORWARD. A history discontinuity (switch to an unrelated branch, or a
63
+ # reset onto a divergent commit) is a different piece of work and must re-fire the
64
+ # gate. Equality caught this incidentally; ancestry catches it on purpose.
65
+ _orig_branch=$(git -C "$REPO" symbolic-ref --short HEAD); _orig_head=$(git -C "$REPO" rev-parse HEAD)
66
+ # Build a genuine SIBLING line (fork from the commit before the current tip, then add its own
67
+ # commit). Simply checking out the recorded commit is not a discontinuity — it is the very
68
+ # point the boundary was recorded at, so ancestry legitimately still holds there.
69
+ git -C "$REPO" branch od-diverge "HEAD~1" >/dev/null 2>&1
70
+ git -C "$REPO" checkout -q od-diverge && git -C "$REPO" commit -q --allow-empty -m "divergent work"
71
+ git -C "$REPO" checkout -q "$_orig_branch"
72
+ ( cd "$REPO" && bash "$ENGINE" record --owners "product-rd-workflow,go-dev" >/dev/null ) # record on THIS line
73
+ # POSITIVE CONTROL: prove the fresh record is actually valid HERE first. Without it, a
74
+ # broken/malformed record would also produce `ask` after the switch and the test would pass
75
+ # without demonstrating that the switch is what invalidated it.
76
+ [ -z "$(edit "$REPO/src/foo.go" | bash "$ENGINE" pretool)" ] \
77
+ && ok "discontinuity control: fresh record valid on its own line => allow" || bad "V5b control: fresh record must be valid before the switch"
78
+ git -C "$REPO" checkout -q od-diverge # jump to the unrelated line
79
+ [ "$(edit "$REPO/src/foo.go" | bash "$ENGINE" pretool | decision)" = ask ] \
80
+ && ok "boundary does NOT survive a history discontinuity => ask" || bad "V5b: divergent history must re-fire the gate"
81
+ # …and it is the discontinuity specifically, not a generic invalidation: the state must be
82
+ # reported as `discontinuous`, never collapsed into "never recorded".
83
+ ( cd "$REPO" && bash "$ENGINE" status ) 2>/dev/null | grep -q "^boundary: discontinuous" \
84
+ && ok "status: divergent-line boundary reported as discontinuous" || bad "V5b: must report discontinuous, not absent"
85
+ # 5b-4. A `git replace --graft` must NOT be able to manufacture the missing ancestry.
86
+ # merge-base honours replacement refs by default, so without GIT_NO_REPLACE_OBJECTS a
87
+ # graft turns this same divergent state back into "valid". Assert the real-object answer.
88
+ _rec_head=$(jq -r '.head' "$BDIR/boundary.json" 2>/dev/null)
89
+ if git -C "$REPO" replace --graft "$(git -C "$REPO" rev-parse HEAD)" "$_rec_head" >/dev/null 2>&1; then
90
+ [ "$(edit "$REPO/src/foo.go" | bash "$ENGINE" pretool | decision)" = ask ] \
91
+ && ok "graft cannot fake ancestry (replacement refs ignored)" || bad "V5d: replace --graft bypassed the continuity check"
92
+ git -C "$REPO" replace -d "$(git -C "$REPO" rev-parse HEAD)" >/dev/null 2>&1
93
+ else
94
+ ok "graft fixture unavailable on this git => skipped (not a pass for the graft path)"
95
+ fi
96
+ # 5b-5. …and the LEGACY graft path too. GIT_NO_REPLACE_OBJECTS does not disable
97
+ # `.git/info/grafts` (verified on git 2.50) — only GIT_GRAFT_FILE does, so both are
98
+ # load-bearing and this fixture is what keeps the second one from being dropped.
99
+ _gitdir=$(git -C "$REPO" rev-parse --absolute-git-dir)
100
+ mkdir -p "$_gitdir/info"
101
+ printf '%s %s\n' "$(git -C "$REPO" rev-parse HEAD)" "$_rec_head" > "$_gitdir/info/grafts"
102
+ [ "$(edit "$REPO/src/foo.go" | bash "$ENGINE" pretool | decision)" = ask ] \
103
+ && ok "legacy info/grafts cannot fake ancestry either" || bad "V5e: info/grafts bypassed the continuity check"
104
+ rm -f "$_gitdir/info/grafts"
105
+ git -C "$REPO" checkout -q "$_orig_branch" && git -C "$REPO" reset -q --hard "$_orig_head"
106
+ git -C "$REPO" branch -qD od-diverge 2>/dev/null
107
+ # 5b-3. The ancestry probe must FAIL CLOSED on every unusable recorded head — a gc'd or
108
+ # shallow-clone-missing object, a malformed value, or a missing field must re-fire the
109
+ # gate, never silently satisfy it. (merge-base exits non-zero for both "not an
110
+ # ancestor" and "bad object"; both must land on ask.)
111
+ ( cd "$REPO" && bash "$ENGINE" record --owners "product-rd-workflow,go-dev" >/dev/null )
112
+ for _bad in '"0000000000000000000000000000000000000000"' '"not-a-sha"' '""' 'null'; do
113
+ jq ".head = $_bad" "$BDIR/boundary.json" > "$BDIR/b.tmp" && mv "$BDIR/b.tmp" "$BDIR/boundary.json"
114
+ [ "$(edit "$REPO/src/foo.go" | bash "$ENGINE" pretool | decision)" = ask ] \
115
+ || { bad "V5c: unusable recorded head ($_bad) must fail closed"; _v5c_bad=1; }
116
+ done
117
+ [ -n "${_v5c_bad:-}" ] || ok "unusable recorded head fails closed (bad/malformed/empty/null)"
118
+ # 5c-2. …and it must be labelled `absent`, NOT `discontinuous`. A well-formed but nonexistent
119
+ # sha (all-zero, gc'd, shallow-clone-missing) is an unusable record — reporting "a
120
+ # branch switch moved HEAD off it" would be exactly the false diagnosis this change
121
+ # set exists to remove, just relocated to a new state.
122
+ jq '.head = "0000000000000000000000000000000000000000"' "$BDIR/boundary.json" > "$BDIR/b.tmp" && mv "$BDIR/b.tmp" "$BDIR/boundary.json"
123
+ ( cd "$REPO" && bash "$ENGINE" status ) 2>/dev/null | grep -q "^boundary: absent" \
124
+ && ok "status: nonexistent recorded commit => absent, not discontinuous" || bad "V5c2: nonexistent sha must not claim discontinuity"
125
+ # 5c-3. UNBORN repo fails closed. This is a deliberate change from the old equality rule,
126
+ # which ALLOWED here: unborn `rev-parse HEAD` prints "HEAD" on stdout and fails, so the
127
+ # old helper produced "HEAD\nNO_HEAD" on both sides and they compared equal. An unborn
128
+ # repo has no line of work to be continuous with, and orphan-branch switches must not
129
+ # satisfy the gate. Uses its own throwaway repo so the shared fixture is untouched.
130
+ UB=$(mktemp -d); git init -q "$UB"; git -C "$UB" config user.email t@t; git -C "$UB" config user.name t
131
+ mkdir -p "$UB/src"; echo "package main" > "$UB/src/foo.go"
132
+ printf '%s' '{ "enabled": true, "product_globs": ["src/**"] }' > "$UB/.owner-dispatch.json"
133
+ git -C "$UB" add .owner-dispatch.json >/dev/null 2>&1 # tracked-in-index, never committed
134
+ ( cd "$UB" && bash "$ENGINE" record --owners "product-rd-workflow" >/dev/null 2>&1 )
135
+ [ "$(edit "$UB/src/foo.go" | ( cd "$UB" && bash "$ENGINE" pretool ) | decision)" = ask ] \
136
+ && ok "unborn repo fails closed even after record (was allow under equality)" || bad "V5c3: unborn repo must fail closed"
137
+ rm -rf "$UB"
138
+ # 5c. expired boundary (TTL) => ask. TTL is now the only bound on boundary reuse at the
139
+ # PreToolUse layer, so it carries its own assertion. Leaves an INVALID boundary behind
140
+ # on purpose — case 6 (strict => deny) depends on that state.
141
+ ( cd "$REPO" && bash "$ENGINE" record --owners "product-rd-workflow,go-dev" --ttl 0 >/dev/null )
142
+ [ "$(edit "$REPO/src/foo.go" | bash "$ENGINE" pretool | decision)" = ask ] && ok "boundary expired (TTL) => ask" || bad "V3: expired boundary must ask"
143
+ # 5d. `status` reports the real state, not a valid/not-valid collapse. It is the command an
144
+ # agent runs to diagnose a block, so it must separate expired from never-recorded.
145
+ ( cd "$REPO" && bash "$ENGINE" status ) 2>/dev/null | grep -q "^boundary: expired" \
146
+ && ok "status: expired boundary reported as expired" || bad "status must report expired"
147
+ rm -f "$BDIR/boundary.json"
148
+ ( cd "$REPO" && bash "$ENGINE" status ) 2>/dev/null | grep -q "^boundary: absent" \
149
+ && ok "status: no boundary reported as absent" || bad "status must report absent"
150
+ # 5e. a malformed/non-integer expiry is NOT "expired" — it is an unparseable record, so the
151
+ # label must stay on the conservative side rather than implying a usable record existed.
152
+ ( cd "$REPO" && bash "$ENGINE" record --owners "x" >/dev/null )
153
+ jq '.expires_at = true' "$BDIR/boundary.json" > "$BDIR/b.tmp" && mv "$BDIR/b.tmp" "$BDIR/boundary.json"
154
+ ( cd "$REPO" && bash "$ENGINE" status ) 2>/dev/null | grep -q "^boundary: absent" \
155
+ && ok "status: non-integer expires_at => absent, not expired" || bad "malformed expiry must not report expired"
156
+ [ "$(edit "$REPO/src/foo.go" | bash "$ENGINE" pretool | decision)" = ask ] \
157
+ && ok "malformed expiry: gate fails closed (ask, never allow)" || bad "malformed expiry must ask"
158
+ rm -f "$BDIR/boundary.json"
159
+ ( cd "$REPO" && bash "$ENGINE" record --owners "product-rd-workflow,go-dev" --ttl 0 >/dev/null )
160
+
161
+ # 6. strict => deny.
162
+ config <<'JSON'
163
+ { "enabled": true, "strict": true, "product_globs": ["src/**"] }
164
+ JSON
165
+ [ "$(edit "$REPO/src/foo.go" | bash "$ENGINE" pretool | decision)" = deny ] && ok "strict => deny" || bad "strict deny"
166
+ # 6b. strict downgrades to ask when state dir is unsafe (symlinked).
167
+ rm -rf "$BDIR"; ln -s /nonexistent-target "$BDIR"
168
+ [ "$(edit "$REPO/src/foo.go" | bash "$ENGINE" pretool | decision)" = ask ] && ok "strict + unsafe state dir => downgrade to ask (no brick)" || bad "strict downgrade"
169
+ rm -f "$BDIR"
170
+ # 6c. strict deny has an escape: a per-session waiver lets a narrow exempt edit proceed.
171
+ mkdir -p "$BDIR"; touch "$BDIR/s.SX.waiver"
172
+ [ -z "$(edit "$REPO/src/foo.go" SX | bash "$ENGINE" pretool)" ] && ok "strict + per-session waiver => allow (escape, no brick)" || bad "strict waiver escape"
173
+ rm -rf "$BDIR"
174
+
175
+ # 7. Bash write-heuristic is RECORD-ONLY: it records the .bashwrite activity marker
176
+ # and ALLOWS SILENTLY (no user `ask` popup); the Stop hook + ci are the gates.
177
+ config <<'JSON'
178
+ { "enabled": true, "product_globs": ["src/**"], "gate_bash": true }
179
+ JSON
180
+ rm -rf "$BDIR"
181
+ [ -z "$( cd "$REPO" && bashjs "echo hi >> src/foo.go" S7 | bash "$ENGINE" pretool )" ] \
182
+ && ok "bash write-heuristic => allow silently (no popup)" || bad "bash heuristic still prompts"
183
+ [ -r "$BDIR/s.S7.bashwrite" ] && ok "bash write-heuristic still records .bashwrite (Stop backstop)" || bad "bash heuristic did not record"
184
+ [ -z "$( cd "$REPO" && bashj "cat src/foo.go" | bash "$ENGINE" pretool )" ] && ok "bash read-only => allow" || bad "bash read"
185
+ rm -rf "$BDIR"
186
+
187
+ # 8. Stop per-session cap + cross-session isolation. Stop blocks only when this
188
+ # session actually CHANGED a gated path vs the baseline captured at first touch
189
+ # (PreToolUse fires BEFORE the edit, so: capture baseline THEN apply the edit).
190
+ rm -rf "$BDIR"
191
+ edit "$REPO/src/foo.go" S1 | bash "$ENGINE" pretool >/dev/null # baseline (foo.go clean)
192
+ echo "// real gated edit" >> "$REPO/src/foo.go" # the edit applies => dirty
193
+ d1=$( cd "$REPO" && stopj S1 | bash "$ENGINE" stop | sdecision )
194
+ d2=$( cd "$REPO" && stopj S1 | bash "$ENGINE" stop | sdecision )
195
+ { [ "$d1" = block ] && [ "$d2" = stop ]; } && ok "main Stop blocks once per session (cap)" || bad "stop cap" "$d1/$d2"
196
+ d3=$( cd "$REPO" && stopj S2 | bash "$ENGINE" stop | sdecision )
197
+ [ "$d3" = stop ] && ok "fresh session not starved by another session's marker" || bad "cross-session" "$d3"
198
+ git -C "$REPO" checkout -q -- . 2>/dev/null
199
+ # 8b. No session id => fail-open (never trap).
200
+ d=$( cd "$REPO" && stopj "" | bash "$ENGINE" stop | sdecision )
201
+ [ "$d" = stop ] && ok "no session id => stop fail-open" || bad "no-session stop" "$d"
202
+ # 8c. session-scoped waiver => allow (even with a real changed gated file).
203
+ rm -rf "$BDIR"
204
+ edit "$REPO/src/foo.go" S3 | bash "$ENGINE" pretool >/dev/null; echo "// e" >> "$REPO/src/foo.go"
205
+ touch "$BDIR/s.S3.waiver"
206
+ [ "$( cd "$REPO" && stopj S3 | bash "$ENGINE" stop | sdecision )" = stop ] && ok "session-scoped waiver => allow" || bad "waiver"
207
+ git -C "$REPO" checkout -q -- . 2>/dev/null; rm -rf "$BDIR"
208
+ # 8d. after record, a boundary supersedes markers => gated edit ALLOWED (pretool).
209
+ edit "$REPO/src/foo.go" S4 | bash "$ENGINE" pretool >/dev/null
210
+ ( cd "$REPO" && bash "$ENGINE" record --owners "product-rd-workflow" >/dev/null )
211
+ [ -z "$(edit "$REPO/src/foo.go" S4 | bash "$ENGINE" pretool)" ] && ok "record boundary supersedes markers => allow" || bad "record supersede"
212
+ rm -rf "$BDIR"
213
+ # 8e. OVER-FIRE FIX: read-only/dispatch-only session (heuristic match, CLEAN tree)
214
+ # records only the .bashwrite sentinel and must NOT block.
215
+ git -C "$REPO" checkout -q -- . 2>/dev/null; git -C "$REPO" clean -fdq 2>/dev/null
216
+ ( cd "$REPO" && bashjs "cat src/foo.go | python3 -c 'print(1)'" S5 | bash "$ENGINE" pretool ) >/dev/null 2>&1
217
+ [ -r "$BDIR/s.S5.bashwrite" ] && [ ! -e "$BDIR/s.S5.touched" ] \
218
+ && ok "read-only heuristic match records .bashwrite sentinel only" || bad "heuristic wrote wrong marker"
219
+ [ "$( cd "$REPO" && stopj S5 | bash "$ENGINE" stop | sdecision )" = stop ] \
220
+ && ok "stop: read-only heuristic match + clean tree => allow (over-fire fix)" || bad "over-fire: clean tree blocked"
221
+ # 8f. heuristic session that DOES change a gated file => block.
222
+ echo "// real" >> "$REPO/src/foo.go"
223
+ [ "$( cd "$REPO" && stopj S5 | bash "$ENGINE" stop | sdecision )" = block ] \
224
+ && ok "stop: heuristic session + changed gated path => block" || bad "true-positive lost"
225
+ git -C "$REPO" checkout -q -- . 2>/dev/null; rm -rf "$BDIR"
226
+ # 8g. config-shrink anti-bypass: a real gated edit still blocks even after the config
227
+ # is shrunk to de-classify it (baseline globs are unioned with current globs).
228
+ edit "$REPO/src/foo.go" SG | bash "$ENGINE" pretool >/dev/null # baseline globs incl. src/**
229
+ echo "// real gated edit" >> "$REPO/src/foo.go"
230
+ config <<'JSON'
231
+ { "enabled": true, "product_globs": ["other/**"], "gate_bash": true }
232
+ JSON
233
+ [ "$( cd "$REPO" && stopj SG | bash "$ENGINE" stop | sdecision )" = block ] \
234
+ && ok "stop: gated edit + config shrink => still block (baseline-glob union)" || bad "shrink false-negative"
235
+ git -C "$REPO" checkout -q -- . 2>/dev/null; rm -rf "$BDIR"
236
+ config <<'JSON'
237
+ { "enabled": true, "strict": false, "gate_bash": true,
238
+ "product_globs": ["src/**"], "owner_hint": "product-rd-workflow + the stack *-dev owner" }
239
+ JSON
240
+ # 8h. committed-in-session gated edit (clean tree) STILL blocks (baseline HEAD diff
241
+ # sees the commit because `git diff <baseline-head>` compares to the work tree).
242
+ rm -rf "$BDIR"
243
+ edit "$REPO/src/foo.go" SH | bash "$ENGINE" pretool >/dev/null # baseline = pre-edit HEAD
244
+ echo "// committed gated edit" >> "$REPO/src/foo.go"
245
+ git -C "$REPO" add -A; git -C "$REPO" commit -qm "committed in-session" # tree clean, HEAD moved
246
+ [ "$( cd "$REPO" && stopj SH | bash "$ENGINE" stop | sdecision )" = block ] \
247
+ && ok "stop: committed gated edit (clean tree) => still block (baseline HEAD diff)" || bad "commit false-pass"
248
+ rm -rf "$BDIR"
249
+ # 8h-2. Stop WORDING splits absent vs expired. Both still block; the message must not tell
250
+ # an actor that recorded a boundary it "never recorded" one — that wording sent
251
+ # diagnosis looking for a missing record when the record existed and had lapsed.
252
+ edit "$REPO/src/foo.go" SH2 | bash "$ENGINE" pretool >/dev/null
253
+ echo "// gated edit, no boundary at all" >> "$REPO/src/foo.go"
254
+ out_sh2=$( cd "$REPO" && stopj SH2 | bash "$ENGINE" stop 2>&1 )
255
+ # Assert the DECISION as well as the wording: grepping message text alone would pass on an
256
+ # allow response that happened to contain the same words.
257
+ [ "$(printf '%s' "$out_sh2" | sdecision)" = block ] \
258
+ && printf '%s' "$out_sh2" | grep -q "never recorded an owner-dispatch boundary" \
259
+ && ok "stop: absent boundary => block + 'never recorded' wording" || bad "S4 wording"
260
+ rm -rf "$BDIR"
261
+ edit "$REPO/src/foo.go" SH3 | bash "$ENGINE" pretool >/dev/null
262
+ echo "// gated edit, boundary recorded then expired" >> "$REPO/src/foo.go"
263
+ ( cd "$REPO" && bash "$ENGINE" record --owners "product-rd-workflow" --ttl 0 >/dev/null )
264
+ out_sh3=$( cd "$REPO" && stopj SH3 | bash "$ENGINE" stop 2>&1 )
265
+ [ "$(printf '%s' "$out_sh3" | sdecision)" = block ] \
266
+ && printf '%s' "$out_sh3" | grep -q "expired before this actor finished" \
267
+ && ! printf '%s' "$out_sh3" | grep -q "never recorded an owner-dispatch boundary" \
268
+ && ok "stop: expired boundary => block + 'expired' wording, not 'never recorded'" || bad "S5 wording"
269
+ rm -rf "$BDIR"
270
+ git -C "$REPO" checkout -q -- . 2>/dev/null
271
+ # 8i. rejected/undone edit => allow. PreToolUse records the marker+baseline, but the
272
+ # edit never applies (tree stays at baseline) => no new gated change => no false block.
273
+ edit "$REPO/src/foo.go" SI | bash "$ENGINE" pretool >/dev/null # marker+baseline; edit NOT applied
274
+ [ "$( cd "$REPO" && stopj SI | bash "$ENGINE" stop | sdecision )" = stop ] \
275
+ && ok "stop: rejected/undone edit (tree at baseline) => allow (no false block)" || bad "rejected-edit false-block"
276
+ rm -rf "$BDIR"
277
+ # 8j. PRE-EXISTING dirty gated file (dirty BEFORE the session) + a heuristic match =>
278
+ # allow: the baseline records it as pre-existing, not this session's work.
279
+ echo "// pre-existing dirt" >> "$REPO/src/foo.go" # dirty BEFORE any touch
280
+ ( cd "$REPO" && bashjs "cat src/foo.go | python3 -c 'print(1)'" SJ | bash "$ENGINE" pretool ) >/dev/null 2>&1
281
+ [ "$( cd "$REPO" && stopj SJ | bash "$ENGINE" stop | sdecision )" = stop ] \
282
+ && ok "stop: pre-existing dirty gated file + heuristic => allow (baseline excludes it)" || bad "pre-existing-dirty false-block"
283
+ git -C "$REPO" checkout -q -- . 2>/dev/null; rm -rf "$BDIR"
284
+ # 8k. edit reverted/stashed back to baseline => allow (nothing landed).
285
+ edit "$REPO/src/foo.go" SK | bash "$ENGINE" pretool >/dev/null
286
+ echo "// will be reverted" >> "$REPO/src/foo.go"
287
+ git -C "$REPO" checkout -q -- "src/foo.go" # revert to baseline content
288
+ [ "$( cd "$REPO" && stopj SK | bash "$ENGINE" stop | sdecision )" = stop ] \
289
+ && ok "stop: edit reverted to baseline => allow (nothing landed)" || bad "revert false-block"
290
+ rm -rf "$BDIR"
291
+ # 8l. pre-existing dirty gated file that is FURTHER edited this session => block
292
+ # (baseline records its content hash, so a re-edit is distinguishable from dirt).
293
+ echo "// pre-existing dirt" >> "$REPO/src/foo.go" # dirty BEFORE the session
294
+ edit "$REPO/src/foo.go" SL | bash "$ENGINE" pretool >/dev/null # baseline hashes foo.go as-is
295
+ echo "// further session edit" >> "$REPO/src/foo.go" # content now differs from baseline
296
+ [ "$( cd "$REPO" && stopj SL | bash "$ENGINE" stop | sdecision )" = block ] \
297
+ && ok "stop: pre-existing dirty file FURTHER edited => block (content-hash baseline)" || bad "pre-existing re-edit false-pass"
298
+ git -C "$REPO" checkout -q -- . 2>/dev/null; rm -rf "$BDIR"
299
+ # 8m. exclude-widen anti-bypass: adding an exclude that covers the edited file after
300
+ # the first touch still blocks (baseline classification is honored).
301
+ edit "$REPO/src/foo.go" SM | bash "$ENGINE" pretool >/dev/null # baseline: src/** gated, no excl
302
+ echo "// real gated edit" >> "$REPO/src/foo.go"
303
+ config <<'JSON'
304
+ { "enabled": true, "product_globs": ["src/**"], "exclude_globs": ["src/**"], "gate_bash": true }
305
+ JSON
306
+ [ "$( cd "$REPO" && stopj SM | bash "$ENGINE" stop | sdecision )" = block ] \
307
+ && ok "stop: gated edit + exclude-widen => still block (baseline classification)" || bad "exclude-widen false-pass"
308
+ git -C "$REPO" checkout -q -- . 2>/dev/null; rm -rf "$BDIR"
309
+ config <<'JSON'
310
+ { "enabled": true, "strict": false, "gate_bash": true,
311
+ "product_globs": ["src/**"], "owner_hint": "product-rd-workflow + the stack *-dev owner" }
312
+ JSON
313
+
314
+ # 9. Symlink-safe: a planted symlink state file must NOT clobber its target.
315
+ rm -rf "$BDIR"; mkdir -p "$BDIR"
316
+ SENT="$WORK/sentinel"; echo "PRECIOUS" > "$SENT"
317
+ ln -s "$SENT" "$BDIR/boundary.json"
318
+ ( cd "$REPO" && bash "$ENGINE" record --owners "x" >/dev/null )
319
+ [ "$(cat "$SENT")" = "PRECIOUS" ] && ok "symlink-safe: record did not clobber symlink target" || bad "symlink clobber" "sentinel=$(cat "$SENT")"
320
+ [ ! -L "$BDIR/boundary.json" ] && ok "symlink-safe: planted symlink replaced with real file" || bad "symlink not replaced"
321
+ rm -rf "$BDIR"
322
+
323
+ # 9b. A leading **/ glob means "zero or more directories" and MUST gate a
324
+ # TOP-LEVEL (repo-root) product file too. bash `case` is not globstar-aware,
325
+ # so **/*.go alone only matches paths WITH a slash — a repo whose product
326
+ # code is top-level + ["**/*.go"] config silently gates NOTHING (observed:
327
+ # a real adapter repo was a complete no-op until the glob was fixed).
328
+ config <<'JSON'
329
+ { "enabled": true, "strict": false, "gate_bash": true,
330
+ "product_globs": ["**/*.go"], "exclude_globs": ["**/*_test.go"] }
331
+ JSON
332
+ echo "package x" > "$REPO/root.go"
333
+ [ "$(edit "$REPO/root.go" S9 | bash "$ENGINE" pretool | decision)" = ask ] && ok "**/ glob gates top-level root.go (zero-or-more dirs)" || bad "top-level **/*.go NOT gated" "the no-op trap: a repo-root product file is ungated"
334
+ echo "package x" > "$REPO/root_test.go"
335
+ [ -z "$(edit "$REPO/root_test.go" | bash "$ENGINE" pretool)" ] && ok "**/ exclude still excludes top-level root_test.go" || bad "top-level **/*_test.go not excluded"
336
+ [ "$(edit "$REPO/src/foo.go" S9 | bash "$ENGINE" pretool | decision)" = ask ] && ok "**/ glob still gates subdir src/foo.go (no regression)" || bad "subdir regression under **/ glob"
337
+ rm -rf "$BDIR"
338
+
339
+ # ---- 10. CI backstop (raw config writes; commits managed explicitly per scenario) ----
340
+ rawcfg(){ cat > "$REPO/.owner-dispatch.json"; }
341
+ gc(){ git -C "$REPO" add -A; git -C "$REPO" commit -q -m "$1"; }
342
+ EN='{ "enabled": true, "product_globs": ["src/**"], "ci_artifact": "design/map.md" }'
343
+
344
+ # 10a. enabled, gated change, no artifact => fail.
345
+ printf '%s\n' "$EN" | rawcfg; gc cfg
346
+ base=$(git -C "$REPO" rev-parse HEAD)
347
+ echo "// change" >> "$REPO/src/foo.go"; gc change
348
+ ( cd "$REPO" && bash "$ENGINE" ci --base "$base" >/dev/null 2>&1 ) && bad "ci no-artifact should fail" || ok "ci: gated change, no artifact => fail"
349
+ # 10b. artifact updated in the change => ok.
350
+ mkdir -p "$REPO/design"; echo "owners: x" > "$REPO/design/map.md"; gc map
351
+ ( cd "$REPO" && bash "$ENGINE" ci --base "$base" >/dev/null 2>&1 ) && ok "ci: artifact updated in change => ok" || bad "ci ok"
352
+ # 10c. stale artifact (gated change without touching the map) => fail.
353
+ base2=$(git -C "$REPO" rev-parse HEAD)
354
+ echo "// more" >> "$REPO/src/foo.go"; gc change2
355
+ ( cd "$REPO" && bash "$ENGINE" ci --base "$base2" >/dev/null 2>&1 ) && bad "ci stale should fail" || ok "ci: stale artifact => fail"
356
+ # 10d. unsafe ci_artifact path (+ gated change) => fail.
357
+ printf '%s\n' '{ "enabled": true, "product_globs": ["src/**"], "ci_artifact": "../evil" }' | rawcfg
358
+ echo "// c" >> "$REPO/src/foo.go"; gc badcfg
359
+ ( cd "$REPO" && bash "$ENGINE" ci --base "$(git -C "$REPO" rev-parse HEAD~1)" >/dev/null 2>&1 ) && bad "ci unsafe should fail" || ok "ci: unsafe ci_artifact path => fail"
360
+ # 10e. shrink product_globs to dodge a gated change (base globs still apply) => fail.
361
+ printf '%s\n' "$EN" | rawcfg; gc reenable
362
+ shrinkbase=$(git -C "$REPO" rev-parse HEAD)
363
+ printf '%s\n' '{ "enabled": true, "product_globs": ["nonexistent/**"], "ci_artifact": "design/map.md" }' | rawcfg
364
+ echo "// dodge" >> "$REPO/src/foo.go"; gc shrink
365
+ ( cd "$REPO" && bash "$ENGINE" ci --base "$shrinkbase" >/dev/null 2>&1 ) && bad "ci shrink-dodge should fail" || ok "ci: shrink product_globs to dodge => fail (base-glob union)"
366
+ # 10f. disable + gated change in one commit (from enabled base) => fail.
367
+ printf '%s\n' "$EN" | rawcfg; gc reenable2
368
+ enbase=$(git -C "$REPO" rev-parse HEAD)
369
+ printf '%s\n' '{ "enabled": false, "product_globs": ["src/**"] }' | rawcfg
370
+ echo "// sneaky" >> "$REPO/src/foo.go"; gc disable
371
+ ( cd "$REPO" && bash "$ENGINE" ci --base "$enbase" >/dev/null 2>&1 ) && bad "ci disable+gated should fail" || ok "ci: disable gate + gated change => fail (anti-bypass)"
372
+ # 10g. clean decommit: config-only removal, no gated change => allowed (0).
373
+ printf '%s\n' "$EN" | rawcfg; echo "// x" >> "$REPO/src/foo.go"; gc reenable3
374
+ enbase2=$(git -C "$REPO" rev-parse HEAD)
375
+ git -C "$REPO" rm -q .owner-dispatch.json; git -C "$REPO" commit -q -m decommit
376
+ ( cd "$REPO" && bash "$ENGINE" ci --base "$enbase2" >/dev/null 2>&1 ) && ok "ci: clean config-only decommit => allowed(0)" || bad "ci decommit"
377
+ # 10g2. ci_artifact pointing at product code (would self-satisfy) => fail.
378
+ printf '%s\n' "$EN" | rawcfg; gc reN
379
+ b_art=$(git -C "$REPO" rev-parse HEAD)
380
+ printf '%s\n' '{ "enabled": true, "product_globs": ["src/**"], "ci_artifact": "src/foo.go" }' | rawcfg
381
+ echo "// art" >> "$REPO/src/foo.go"; gc artbad
382
+ ( cd "$REPO" && bash "$ENGINE" ci --base "$b_art" >/dev/null 2>&1 ) && bad "ci artifact=product should fail" || ok "ci: ci_artifact pointing at product code => fail"
383
+ # 10g3. enabled but schema-invalid config (product_globs not an array) => fail-closed.
384
+ printf '%s\n' "$EN" | rawcfg; gc reS
385
+ b_sch=$(git -C "$REPO" rev-parse HEAD)
386
+ printf '%s\n' '{ "enabled": true, "product_globs": "src/**" }' | rawcfg
387
+ echo "// s" >> "$REPO/src/foo.go"; gc schbad
388
+ ( cd "$REPO" && bash "$ENGINE" ci --base "$b_sch" >/dev/null 2>&1 ) && bad "ci schema-invalid should fail" || ok "ci: enabled schema-invalid config => fail-closed"
389
+ # 10g5. tracked-but-malformed config + gated change (from a non-enabled base) => fail-closed.
390
+ git -C "$REPO" rm -q .owner-dispatch.json 2>/dev/null; gc noc
391
+ b_m=$(git -C "$REPO" rev-parse HEAD)
392
+ printf '%s' '{ bad json not closed' > "$REPO/.owner-dispatch.json"; echo "// m" >> "$REPO/src/foo.go"; gc malformed
393
+ ( cd "$REPO" && bash "$ENGINE" ci --base "$b_m" >/dev/null 2>&1 ) && bad "ci malformed should fail" || ok "ci: tracked malformed config => fail-closed"
394
+ # 10g5b. tracked-but-non-object JSON is also malformed as a config => fail-closed.
395
+ printf '%s\n' "$EN" | rawcfg; gc reObj
396
+ b_obj=$(git -C "$REPO" rev-parse HEAD)
397
+ printf '%s\n' '[]' > "$REPO/.owner-dispatch.json"; gc nonobject
398
+ ( cd "$REPO" && bash "$ENGINE" ci --base "$b_obj" >/dev/null 2>&1 ) && bad "ci non-object config should fail" || ok "ci: tracked non-object config => fail-closed"
399
+ # 10g6. ./-prefixed ci_artifact resolves to git path form => not false-failed.
400
+ printf '%s\n' '{ "enabled": true, "product_globs": ["src/**"], "ci_artifact": "./design/map.md" }' | rawcfg; gc reDot
401
+ b_dot=$(git -C "$REPO" rev-parse HEAD)
402
+ echo "// d" >> "$REPO/src/foo.go"; mkdir -p "$REPO/design"; echo owners > "$REPO/design/map.md"; gc dotchange
403
+ ( cd "$REPO" && bash "$ENGINE" ci --base "$b_dot" >/dev/null 2>&1 ) && ok "ci: ./-prefixed ci_artifact matches => ok" || bad "ci dot-artifact false-fail"
404
+ # 10g6b. '..' inside a filename is safe; only '..' path components are unsafe.
405
+ printf '%s\n' '{ "enabled": true, "product_globs": ["src/**"], "ci_artifact": "design/v1..2-map.md" }' | rawcfg; gc reDotsName
406
+ b_dots_name=$(git -C "$REPO" rev-parse HEAD)
407
+ echo "// d2" >> "$REPO/src/foo.go"; mkdir -p "$REPO/design"; echo owners > "$REPO/design/v1..2-map.md"; gc dotsname
408
+ ( cd "$REPO" && bash "$ENGINE" ci --base "$b_dots_name" >/dev/null 2>&1 ) && ok "ci: ci_artifact filename containing '..' => ok" || bad "ci dots-in-filename false-fail"
409
+ # 10g7. malforming an enabled config in a config-only change (no product change) => fail-closed.
410
+ printf '%s\n' "$EN" | rawcfg; gc reMM
411
+ b_mm=$(git -C "$REPO" rev-parse HEAD)
412
+ printf '%s' '{ bad' > "$REPO/.owner-dispatch.json"; gc malformonly
413
+ ( cd "$REPO" && bash "$ENGINE" ci --base "$b_mm" >/dev/null 2>&1 ) && bad "malform-only should fail" || ok "ci: malform enabled config (config-only) => fail-closed (not decommit)"
414
+ # 10g4. a gated product path WITH A SPACE is classified correctly (no substring/split bug).
415
+ printf '%s\n' "$EN" | rawcfg; gc reSP
416
+ b_sp=$(git -C "$REPO" rev-parse HEAD)
417
+ echo "x" > "$REPO/src/a b.go"; gc spacefile
418
+ ( cd "$REPO" && bash "$ENGINE" ci --base "$b_sp" >/dev/null 2>&1 ) && bad "ci space-path should fail (gated, no map)" || ok "ci: gated path with a space classified => fail"
419
+ # 10g8. CI fallback: a runner without jq but with python3 still verifies the same
420
+ # backstop semantics instead of warning forever because a shared runner lacks jq.
421
+ NOJQBIN="$WORK/nojqbin"; mkdir -p "$NOJQBIN"
422
+ for _cmd in bash git python3 dirname basename; do ln -sf "$(command -v "$_cmd")" "$NOJQBIN/$_cmd"; done
423
+ EN_NJ='{ "enabled": true, "product_globs": ["src/**"], "ci_artifact": "design/nojq-map.md" }'
424
+ printf '%s\n' "$EN_NJ" | rawcfg; gc reNJ
425
+ b_nj=$(git -C "$REPO" rev-parse HEAD)
426
+ echo "// nojq fail" >> "$REPO/src/foo.go"; gc nojqfail
427
+ ( cd "$REPO" && PATH="$NOJQBIN" bash "$ENGINE" ci --base "$b_nj" >/dev/null 2>&1 ) \
428
+ && bad "ci no-jq no-artifact should fail" || ok "ci: no-jq fallback keeps no-artifact failure"
429
+ mkdir -p "$REPO/design"; printf 'owners nojq\n' > "$REPO/design/nojq-map.md"; gc nojqmap
430
+ ( cd "$REPO" && PATH="$NOJQBIN" bash "$ENGINE" ci --base "$b_nj" >/dev/null 2>&1 ) \
431
+ && ok "ci: no-jq fallback accepts updated artifact" || bad "ci no-jq fallback false-fail"
432
+ jq_rc=0; ( cd "$REPO" && bash "$ENGINE" ci --base "$b_nj" >/dev/null 2>&1 ) || jq_rc=$?
433
+ py_rc=0; ( cd "$REPO" && PATH="$NOJQBIN" bash "$ENGINE" ci --base "$b_nj" >/dev/null 2>&1 ) || py_rc=$?
434
+ [ "$jq_rc" = "$py_rc" ] && ok "ci: jq and no-jq verdicts match on same fixture ($jq_rc)" || bad "ci jq/no-jq parity" "jq=$jq_rc py=$py_rc"
435
+ EN_STAR='{ "enabled": true, "product_globs": ["src/*.go"], "ci_artifact": "design/star-map.md" }'
436
+ printf '%s\n' "$EN_STAR" | rawcfg; gc reStar
437
+ b_star=$(git -C "$REPO" rev-parse HEAD)
438
+ mkdir -p "$REPO/src/nested" "$REPO/design"; echo "package nested" > "$REPO/src/nested/b.go"; echo star > "$REPO/design/star-map.md"; gc starglob
439
+ jq_rc=0; ( cd "$REPO" && bash "$ENGINE" ci --base "$b_star" >/dev/null 2>&1 ) || jq_rc=$?
440
+ py_rc=0; ( cd "$REPO" && PATH="$NOJQBIN" bash "$ENGINE" ci --base "$b_star" >/dev/null 2>&1 ) || py_rc=$?
441
+ [ "$jq_rc" = "$py_rc" ] && ok "ci: jq/no-jq parity for single-star nested path ($jq_rc)" || bad "ci single-star parity" "jq=$jq_rc py=$py_rc"
442
+ EN_EXCL='{ "enabled": true, "product_globs": ["src/**"], "exclude_globs": ["src/*.go"], "ci_artifact": "design/exclude-map.md" }'
443
+ printf '%s\n' "$EN_EXCL" | rawcfg; gc reExcl
444
+ b_excl=$(git -C "$REPO" rev-parse HEAD)
445
+ echo "package excluded" > "$REPO/src/nested/excluded.go"; gc exclglob
446
+ jq_rc=0; ( cd "$REPO" && bash "$ENGINE" ci --base "$b_excl" >/dev/null 2>&1 ) || jq_rc=$?
447
+ py_rc=0; ( cd "$REPO" && PATH="$NOJQBIN" bash "$ENGINE" ci --base "$b_excl" >/dev/null 2>&1 ) || py_rc=$?
448
+ [ "$jq_rc" = "$py_rc" ] && ok "ci: jq/no-jq parity for exclude single-star nested path ($jq_rc)" || bad "ci exclude-star parity" "jq=$jq_rc py=$py_rc"
449
+ EN_ROOTTXT='{ "enabled": true, "product_globs": ["**/*.txt"], "ci_artifact": "design/root-txt-map.md" }'
450
+ printf '%s\n' "$EN_ROOTTXT" | rawcfg; gc reRootTxt
451
+ b_root_txt=$(git -C "$REPO" rev-parse HEAD)
452
+ echo root > "$REPO/root.txt"; gc roottxt
453
+ jq_rc=0; ( cd "$REPO" && bash "$ENGINE" ci --base "$b_root_txt" >/dev/null 2>&1 ) || jq_rc=$?
454
+ py_rc=0; ( cd "$REPO" && PATH="$NOJQBIN" bash "$ENGINE" ci --base "$b_root_txt" >/dev/null 2>&1 ) || py_rc=$?
455
+ [ "$jq_rc" = "$py_rc" ] && ok "ci: jq/no-jq parity for **/ product root path ($jq_rc)" || bad "ci root **/ product parity" "jq=$jq_rc py=$py_rc"
456
+ EN_ROOTMD='{ "enabled": true, "product_globs": ["**/*.md"], "ci_artifact": "design/root-md-map.md" }'
457
+ printf '%s\n' "$EN_ROOTMD" | rawcfg; gc reRootMd
458
+ b_root_md=$(git -C "$REPO" rev-parse HEAD)
459
+ echo root > "$REPO/root.md"; gc rootmd
460
+ jq_rc=0; ( cd "$REPO" && bash "$ENGINE" ci --base "$b_root_md" >/dev/null 2>&1 ) || jq_rc=$?
461
+ py_rc=0; ( cd "$REPO" && PATH="$NOJQBIN" bash "$ENGINE" ci --base "$b_root_md" >/dev/null 2>&1 ) || py_rc=$?
462
+ [ "$jq_rc" = "$py_rc" ] && ok "ci: jq/no-jq parity for default **/*.md root exclude ($jq_rc)" || bad "ci root md exclude parity" "jq=$jq_rc py=$py_rc"
463
+ EN_EMPTY_ART='{ "enabled": true, "product_globs": ["src/**"], "ci_artifact": "" }'
464
+ printf '%s\n' "$EN_EMPTY_ART" | rawcfg; gc reEmptyArt
465
+ b_empty_art=$(git -C "$REPO" rev-parse HEAD)
466
+ echo "// empty art" >> "$REPO/src/foo.go"; gc emptyart
467
+ jq_rc=0; ( cd "$REPO" && bash "$ENGINE" ci --base "$b_empty_art" >/dev/null 2>&1 ) || jq_rc=$?
468
+ py_rc=0; ( cd "$REPO" && PATH="$NOJQBIN" bash "$ENGINE" ci --base "$b_empty_art" >/dev/null 2>&1 ) || py_rc=$?
469
+ [ "$jq_rc" = "$py_rc" ] && ok "ci: jq/no-jq parity for empty ci_artifact ($jq_rc)" || bad "ci empty artifact parity" "jq=$jq_rc py=$py_rc"
470
+ EN_NULL_ART='{ "enabled": true, "product_globs": ["src/**"], "ci_artifact": null }'
471
+ printf '%s\n' "$EN_NULL_ART" | rawcfg; gc reNullArt
472
+ b_null_art=$(git -C "$REPO" rev-parse HEAD)
473
+ echo "// null art" >> "$REPO/src/foo.go"; mkdir -p "$REPO/design"; echo owners > "$REPO/design/owner-dispatch-map.md"; gc nullart
474
+ jq_rc=0; ( cd "$REPO" && bash "$ENGINE" ci --base "$b_null_art" >/dev/null 2>&1 ) || jq_rc=$?
475
+ py_rc=0; ( cd "$REPO" && PATH="$NOJQBIN" bash "$ENGINE" ci --base "$b_null_art" >/dev/null 2>&1 ) || py_rc=$?
476
+ [ "$jq_rc" = "$py_rc" ] && ok "ci: jq/no-jq parity for null ci_artifact default ($jq_rc)" || bad "ci null artifact parity" "jq=$jq_rc py=$py_rc"
477
+ EN_STRICT='{ "enabled": true, "strict": true, "gate_bash": false, "product_globs": ["src/**"], "ci_artifact": "design/strict-map.md" }'
478
+ printf '%s\n' "$EN_STRICT" | rawcfg; gc reStrict
479
+ b_strict=$(git -C "$REPO" rev-parse HEAD)
480
+ echo "// strict" >> "$REPO/src/foo.go"; echo strict > "$REPO/design/strict-map.md"; gc strictci
481
+ jq_rc=0; ( cd "$REPO" && bash "$ENGINE" ci --base "$b_strict" >/dev/null 2>&1 ) || jq_rc=$?
482
+ py_rc=0; ( cd "$REPO" && PATH="$NOJQBIN" bash "$ENGINE" ci --base "$b_strict" >/dev/null 2>&1 ) || py_rc=$?
483
+ [ "$jq_rc" = "$py_rc" ] && ok "ci: jq/no-jq parity for strict+gate_bash schema edge ($jq_rc)" || bad "ci strict/gate_bash parity" "jq=$jq_rc py=$py_rc"
484
+ EN_BAD_BOOL='{ "enabled": true, "strict": 1, "gate_bash": "false", "product_globs": ["src/**"], "ci_artifact": "design/bad-bool-map.md" }'
485
+ printf '%s\n' "$EN_BAD_BOOL" | rawcfg; gc reBadBool
486
+ b_bad_bool=$(git -C "$REPO" rev-parse HEAD)
487
+ echo "// bad bool" >> "$REPO/src/foo.go"; gc badbool
488
+ jq_rc=0; ( cd "$REPO" && bash "$ENGINE" ci --base "$b_bad_bool" >/dev/null 2>&1 ) || jq_rc=$?
489
+ py_rc=0; ( cd "$REPO" && PATH="$NOJQBIN" bash "$ENGINE" ci --base "$b_bad_bool" >/dev/null 2>&1 ) || py_rc=$?
490
+ [ "$jq_rc" = "$py_rc" ] && ok "ci: jq/no-jq parity for non-boolean strict/gate_bash ($jq_rc)" || bad "ci bad bool parity" "jq=$jq_rc py=$py_rc"
491
+ EN_EMPTY_BRANCH='{ "enabled": true, "product_globs": ["src/**"], "ci_artifact": "design/empty-branch-map.md" }'
492
+ printf '%s\n' "$EN_EMPTY_BRANCH" | rawcfg; gc reEmptyBranch
493
+ b_empty_branch=$(git -C "$REPO" rev-parse HEAD)
494
+ git -C "$REPO" update-ref refs/remotes/origin/main "$b_empty_branch"
495
+ echo "// empty branch" >> "$REPO/src/foo.go"; echo branch > "$REPO/design/empty-branch-map.md"; gc emptybranch
496
+ jq_rc=0; ( cd "$REPO" && CI_DEFAULT_BRANCH="" bash "$ENGINE" ci >/dev/null 2>&1 ) || jq_rc=$?
497
+ py_rc=0; ( cd "$REPO" && CI_DEFAULT_BRANCH="" PATH="$NOJQBIN" bash "$ENGINE" ci >/dev/null 2>&1 ) || py_rc=$?
498
+ [ "$jq_rc" = "$py_rc" ] && ok "ci: jq/no-jq parity for empty CI_DEFAULT_BRANCH fallback ($jq_rc)" || bad "ci empty CI_DEFAULT_BRANCH parity" "jq=$jq_rc py=$py_rc"
499
+ printf '%s\n' "$EN_NJ" | rawcfg; gc reNJS
500
+ b_njs=$(git -C "$REPO" rev-parse HEAD)
501
+ printf '%s\n' '{ "enabled": true, "product_globs": "src/**", "ci_artifact": "design/nojq-map.md" }' | rawcfg
502
+ echo "// nojq schema" >> "$REPO/src/foo.go"; gc nojqschema
503
+ py_rc=0; ( cd "$REPO" && PATH="$NOJQBIN" bash "$ENGINE" ci --base "$b_njs" >/dev/null 2>&1 ) || py_rc=$?
504
+ [ "$py_rc" = 2 ] && ok "ci: no-jq fallback schema-invalid => fail-closed(2)" || bad "ci no-jq schema rc" "py=$py_rc"
505
+ printf '%s\n' "$EN_NJ" | rawcfg; gc reNJD
506
+ b_njd=$(git -C "$REPO" rev-parse HEAD)
507
+ printf '%s\n' '{ "enabled": false, "product_globs": ["src/**"], "ci_artifact": "design/nojq-map.md" }' | rawcfg
508
+ echo "// nojq disable" >> "$REPO/src/foo.go"; gc nojqdisable
509
+ py_rc=0; ( cd "$REPO" && PATH="$NOJQBIN" bash "$ENGINE" ci --base "$b_njd" >/dev/null 2>&1 ) || py_rc=$?
510
+ [ "$py_rc" = 1 ] && ok "ci: no-jq fallback disable+gated => fail(1)" || bad "ci no-jq disable rc" "py=$py_rc"
511
+ printf '%s\n' "$EN_NJ" | rawcfg; gc reNJObj
512
+ b_njo=$(git -C "$REPO" rev-parse HEAD)
513
+ printf '%s\n' '[]' > "$REPO/.owner-dispatch.json"; gc nojqnonobject
514
+ jq_rc=0; ( cd "$REPO" && bash "$ENGINE" ci --base "$b_njo" >/dev/null 2>&1 ) || jq_rc=$?
515
+ py_rc=0; ( cd "$REPO" && PATH="$NOJQBIN" bash "$ENGINE" ci --base "$b_njo" >/dev/null 2>&1 ) || py_rc=$?
516
+ [ "$py_rc" = 2 ] && ok "ci: no-jq fallback non-object config => fail-closed(2)" || bad "ci no-jq non-object rc" "py=$py_rc"
517
+ [ "$jq_rc" = "$py_rc" ] && ok "ci: jq/no-jq parity for non-object config ($jq_rc)" || bad "ci non-object parity" "jq=$jq_rc py=$py_rc"
518
+ # 10h. never opted in (absent at base AND head) => skip(0).
519
+ git -C "$REPO" rm -q .owner-dispatch.json 2>/dev/null; gc rmfinal
520
+ nb=$(git -C "$REPO" rev-parse HEAD)
521
+ echo "// z" >> "$REPO/src/foo.go"; gc more
522
+ ( cd "$REPO" && bash "$ENGINE" ci --base "$nb" >/dev/null 2>&1 ) && ok "ci: never opted in => skip(0)" || bad "ci skip"
523
+ # 10i. CI fails CLOSED when it cannot determine a base (no --base, no upstream).
524
+ if ( cd "$REPO" && bash "$ENGINE" ci >/dev/null 2>&1 ); then bad "ci no-base should fail-closed"; else ok "ci: no base => fail-closed (non-zero)"; fi
525
+
526
+ # ---- 11. SubagentStop: agent_id-scoped enforcement (the same engine handles Stop +
527
+ # SubagentStop; agent_id is present only for the latter and scopes markers/cap). ----
528
+ rm -rf "$BDIR"
529
+ config <<'JSON'
530
+ { "enabled": true, "strict": false, "gate_bash": true,
531
+ "product_globs": ["src/**"], "owner_hint": "product-rd-workflow + the stack *-dev owner" }
532
+ JSON
533
+ # pretool/stop input variants that carry agent_id (subagent context).
534
+ edita() { printf '{"tool_name":"Edit","tool_input":{"file_path":"%s"},"session_id":"%s","agent_id":"%s"}' "$1" "$2" "$3"; }
535
+ stopa() { printf '{"session_id":"%s","agent_id":"%s"}' "$1" "$2"; }
536
+ # Mirror the engine's injective agent_id key (jq @base64 of the raw value, base64url-ized).
537
+ akey() { jq -nr --arg a "$1" '$a | @base64' | tr '+/' '-_'; }
538
+
539
+ # 11a. RED baseline: WITHOUT the subagent edit there is no per-agent activity => allow.
540
+ [ "$( cd "$REPO" && stopa SUB A1 | bash "$ENGINE" stop | sdecision )" = stop ] \
541
+ && ok "SubagentStop baseline: no per-agent activity => allow" || bad "subagent baseline"
542
+ # 11b. subagent edits gated code => SubagentStop blocks ONCE for that agent.
543
+ edita "$REPO/src/foo.go" SUB A1 | bash "$ENGINE" pretool >/dev/null # baseline + per-agent .touched
544
+ echo "// sub gated edit" >> "$REPO/src/foo.go"
545
+ s1=$( cd "$REPO" && stopa SUB A1 | bash "$ENGINE" stop | sdecision )
546
+ s2=$( cd "$REPO" && stopa SUB A1 | bash "$ENGINE" stop | sdecision )
547
+ { [ "$s1" = block ] && [ "$s2" = stop ]; } && ok "SubagentStop: subagent gated edit => block once per agent" || bad "subagent cap" "$s1/$s2"
548
+ # 11c. a read-only sibling subagent (same session, no activity) is NOT starved/blocked.
549
+ [ "$( cd "$REPO" && stopa SUB A2 | bash "$ENGINE" stop | sdecision )" = stop ] \
550
+ && ok "SubagentStop: read-only sibling subagent => allow (per-agent activity gate)" || bad "sibling subagent false-block"
551
+ # 11d. the MAIN Stop (no agent_id) has an INDEPENDENT cap — a subagent's block does not
552
+ # consume the main session's nudge (markers exist at session scope too).
553
+ [ "$( cd "$REPO" && stopj SUB | bash "$ENGINE" stop | sdecision )" = block ] \
554
+ && ok "Stop: main session blocks independently of the subagent's cap" || bad "main cap shared with subagent"
555
+ git -C "$REPO" checkout -q -- . 2>/dev/null; rm -rf "$BDIR"
556
+ # 11e. per-subagent waiver => allow (even with a real changed gated file).
557
+ edita "$REPO/src/foo.go" SUB A3 | bash "$ENGINE" pretool >/dev/null
558
+ echo "// gated" >> "$REPO/src/foo.go"
559
+ touch "$BDIR/s.SUB.a.$(akey A3).waiver"
560
+ [ "$( cd "$REPO" && stopa SUB A3 | bash "$ENGINE" stop | sdecision )" = stop ] \
561
+ && ok "SubagentStop: per-subagent waiver => allow" || bad "subagent waiver"
562
+ git -C "$REPO" checkout -q -- . 2>/dev/null; rm -rf "$BDIR"
563
+ # 11f. a session-level waiver suppresses a subagent block too (broad escape hatch).
564
+ edita "$REPO/src/foo.go" SUB A5 | bash "$ENGINE" pretool >/dev/null
565
+ echo "// gated" >> "$REPO/src/foo.go"
566
+ touch "$BDIR/s.SUB.waiver"
567
+ [ "$( cd "$REPO" && stopa SUB A5 | bash "$ENGINE" stop | sdecision )" = stop ] \
568
+ && ok "SubagentStop: session-level waiver suppresses subagent block" || bad "session waiver vs subagent"
569
+ git -C "$REPO" checkout -q -- . 2>/dev/null; rm -rf "$BDIR"
570
+ # 11g. PreToolUse still nudges a subagent editing gated code (ask), and records the
571
+ # per-agent marker for the Stop backstop.
572
+ [ "$( edita "$REPO/src/foo.go" SUB A6 | bash "$ENGINE" pretool | decision )" = ask ] \
573
+ && ok "PreToolUse: subagent gated edit => ask (fires in subagents)" || bad "subagent pretool ask"
574
+ [ -r "$BDIR/s.SUB.a.$(akey A6).touched" ] && ok "PreToolUse: subagent records per-agent .touched marker" || bad "no per-agent marker"
575
+ rm -rf "$BDIR"
576
+ # 11h. ACTOR-PRECISE attribution (the P1 fix): A1 attempts a gated edit (records a marker)
577
+ # but does NOT change anything; A2 changes a DIFFERENT gated file. A1's SubagentStop
578
+ # must ALLOW (not blamed for A2's change); A2's must BLOCK.
579
+ git -C "$REPO" checkout -q -- . 2>/dev/null; git -C "$REPO" clean -fdq 2>/dev/null
580
+ echo "package b" > "$REPO/src/b.go"; git -C "$REPO" add -A; git -C "$REPO" commit -qm addb
581
+ edita "$REPO/src/foo.go" SUB A1 | bash "$ENGINE" pretool >/dev/null # A1 marker on foo.go; edit NOT applied
582
+ edita "$REPO/src/b.go" SUB A2 | bash "$ENGINE" pretool >/dev/null # A2 marker on b.go
583
+ echo "// only A2's file changes" >> "$REPO/src/b.go" # only b.go is dirty
584
+ [ "$( cd "$REPO" && stopa SUB A1 | bash "$ENGINE" stop | sdecision )" = stop ] \
585
+ && ok "SubagentStop: A1 attempted-but-unchanged, sibling A2 changed => A1 allow (no cross-blame)" || bad "cross-agent false-block (P1)"
586
+ [ "$( cd "$REPO" && stopa SUB A2 | bash "$ENGINE" stop | sdecision )" = block ] \
587
+ && ok "SubagentStop: A2 actually changed its gated file => A2 block (true positive kept)" || bad "A2 true-positive lost"
588
+ git -C "$REPO" checkout -q -- . 2>/dev/null; git -C "$REPO" clean -fdq 2>/dev/null; rm -rf "$BDIR"
589
+ # 11i. Bash-only subagent (heuristic sentinel, no .touched path list) is not path-
590
+ # attributable => SubagentStop does NOT block (advisory Bash posture; session Stop/ci
591
+ # remain the backstop). Even with a real gated change present.
592
+ echo "// pre" > "$REPO/src/foo.go"; git -C "$REPO" add -A; git -C "$REPO" commit -qm pre
593
+ ( cd "$REPO" && printf '{"tool_name":"Bash","tool_input":{"command":"echo x >> src/foo.go"},"session_id":"SUB","agent_id":"A7"}' | bash "$ENGINE" pretool ) >/dev/null 2>&1
594
+ echo "// real change" >> "$REPO/src/foo.go"
595
+ [ -r "$BDIR/s.SUB.a.$(akey A7).bashwrite" ] && [ ! -e "$BDIR/s.SUB.a.$(akey A7).touched" ] \
596
+ && ok "Bash-only subagent records per-agent .bashwrite sentinel only" || bad "bash-only subagent marker shape"
597
+ [ "$( cd "$REPO" && stopa SUB A7 | bash "$ENGINE" stop | sdecision )" = stop ] \
598
+ && ok "SubagentStop: Bash-only subagent => allow (not path-attributable, by design)" || bad "bash-only subagent blocked"
599
+ git -C "$REPO" checkout -q -- . 2>/dev/null; git -C "$REPO" clean -fdq 2>/dev/null; rm -rf "$BDIR"
600
+ # 11j. CHALLENGE FIX: baseline state lost mid-session for a subagent => NOT attributable =>
601
+ # allow. Must NOT fall back to the session-wide check (which would blame a sibling).
602
+ echo "// pre" > "$REPO/src/foo.go"; git -C "$REPO" add -A; git -C "$REPO" commit -qm prej
603
+ edita "$REPO/src/foo.go" SUB AJ | bash "$ENGINE" pretool >/dev/null # captures baseline + AJ marker
604
+ rm -f "$BDIR/s.SUB.basehead" # simulate lost/rolled state
605
+ echo "// a gated change exists" >> "$REPO/src/foo.go"
606
+ [ "$( cd "$REPO" && stopa SUB AJ | bash "$ENGINE" stop | sdecision )" = stop ] \
607
+ && ok "SubagentStop: missing baseline => allow (no session-wide contamination fallback)" || bad "basehead-missing fallback contaminates"
608
+ git -C "$REPO" checkout -q -- . 2>/dev/null; git -C "$REPO" clean -fdq 2>/dev/null; rm -rf "$BDIR"
609
+ # 11k. CHALLENGE FIX: NUL-safe exact attribution — a subagent that touched a newline-
610
+ # containing path is NOT cross-blamed when a sibling file whose name is a line-fragment
611
+ # of it changes (the old grep -Fxq split the multi-line pattern and false-blocked).
612
+ nlpath=$'src/a\nb.go'
613
+ printf 'package x\n' > "$REPO/$nlpath"; printf 'package a\n' > "$REPO/src/a"
614
+ git -C "$REPO" add -A; git -C "$REPO" commit -qm nlfiles
615
+ jq -nc --arg fp "$REPO/$nlpath" '{tool_name:"Edit",tool_input:{file_path:$fp},session_id:"SUB",agent_id:"AK"}' \
616
+ | bash "$ENGINE" pretool >/dev/null # AK touched the newline path; not changed
617
+ echo "// only the line-fragment sibling changes" >> "$REPO/src/a" # src/a (a line-fragment) changes
618
+ [ "$( cd "$REPO" && stopa SUB AK | bash "$ENGINE" stop | sdecision )" = stop ] \
619
+ && ok "SubagentStop: newline-path touch not cross-blamed for sibling 'src/a' (NUL exact match)" || bad "newline-path line-fragment cross-attribution"
620
+ git -C "$REPO" checkout -q -- . 2>/dev/null; git -C "$REPO" clean -fdq 2>/dev/null; rm -rf "$BDIR"
621
+ # 11m. CHALLENGE FIX (id collision): two agent_ids that the lossy sid_safe would collapse to
622
+ # the same key ("a/b" and "a:b" -> "a_b") get DISTINCT injective (percent-encoded)
623
+ # markers, so their .touched/.blocked/.waiver never collide.
624
+ edita "$REPO/src/foo.go" SUB 'a/b' | bash "$ENGINE" pretool >/dev/null
625
+ [ -r "$BDIR/s.SUB.a.$(akey 'a/b').touched" ] && [ ! -e "$BDIR/s.SUB.a.$(akey 'a:b').touched" ] && [ "$(akey 'a/b')" != "$(akey 'a:b')" ] \
626
+ && ok "agent_id key is injective ('a/b' ≠ 'a:b'; no marker collision)" || bad "agent_id key collision (lossy sid_safe)"
627
+ git -C "$REPO" checkout -q -- . 2>/dev/null; rm -rf "$BDIR"
628
+ # 11n. CHALLENGE FIX (concurrency): O_APPEND per-agent .touched does not lose entries when
629
+ # the same subagent's PreToolUse fires in parallel (model emitting parallel Edits);
630
+ # the old read-copy-rename dropped entries and could silently miss the real changed path.
631
+ for i in $(seq 1 20); do echo "package p" > "$REPO/src/c$i.go"; done
632
+ git -C "$REPO" add -A; git -C "$REPO" commit -qm cfiles
633
+ edita "$REPO/src/c1.go" SUB CC | bash "$ENGINE" pretool >/dev/null # serial: capture baseline once
634
+ for i in $(seq 1 20); do edita "$REPO/src/c$i.go" SUB CC | bash "$ENGINE" pretool >/dev/null & done; wait
635
+ n=$(tr -cd '\0' < "$BDIR/s.SUB.a.$(akey CC).touched" 2>/dev/null | wc -c | tr -d ' ')
636
+ [ "${n:-0}" -ge 20 ] && ok "concurrent same-agent edits: all touched entries survive ($n, O_APPEND)" || bad "lost touched entries under concurrency: ${n:-0}/20"
637
+ git -C "$REPO" checkout -q -- . 2>/dev/null; git -C "$REPO" clean -fdq 2>/dev/null; rm -rf "$BDIR"
638
+
639
+ # ============================================================================
640
+ # INVOCATION EVIDENCE (name != invoke) — cross-check recorded owners against the
641
+ # skills actually invoked in the session transcript (backlog gate ⑥).
642
+ # ============================================================================
643
+ # Synthetic transcript: one JSONL line per invoked skill (matches the real format:
644
+ # message.content[] tool_use blocks with name=="Skill", input.skill=="plugin:name").
645
+ mktr() { # $1 out-file rest: skill invocations (plugin:name or bare)
646
+ local out="$1"; shift; : > "$out"
647
+ printf 'malformed leading line not json\n' > "$out" # BEFORE skills: must not truncate the stream
648
+ local s
649
+ for s in "$@"; do
650
+ printf '{"type":"assistant","message":{"content":[{"type":"tool_use","name":"Skill","input":{"skill":"%s"}}]}}\n' "$s" >> "$out"
651
+ done
652
+ # a non-Skill line + a malformed line to prove tolerance
653
+ printf '{"type":"user","message":{"content":[{"type":"tool_use","name":"Bash","input":{"command":"ls"}}]}}\n' >> "$out"
654
+ printf 'not json at all\n' >> "$out"
655
+ }
656
+ stopjt(){ printf '{"session_id":"%s","transcript_path":"%s"}' "$1" "$2"; }
657
+ stopjat(){
658
+ printf '{"session_id":"%s","agent_id":"%s","transcript_path":"%s","agent_transcript_path":"%s"}' \
659
+ "$1" "$2" "$3" "$4"
660
+ }
661
+ stopja_legacy(){ printf '{"session_id":"%s","agent_id":"%s","transcript_path":"%s"}' "$1" "$2" "$3"; }
662
+
663
+ TR="$BDIR.transcript.jsonl"; mkdir -p "$(dirname "$TR")"
664
+
665
+ # VI-1: subcommand — an invoked skill-shaped owner passes (exit 0).
666
+ mktr "$TR" "ccl-skills:testing-strategy" "ccl-skills:worktree-isolation"
667
+ bash "$ENGINE" verify-invocations --owners "testing-strategy,worktree-isolation" --transcript "$TR" >/dev/null
668
+ [ $? -eq 0 ] && ok "verify-invocations: all invoked => exit 0" || bad "VI-1"
669
+
670
+ # VI-2: subcommand — a skill-shaped owner never invoked => exit 3 and is named.
671
+ out=$(bash "$ENGINE" verify-invocations --owners "testing-strategy,go-microservice-dev" --transcript "$TR"); rc=$?
672
+ [ "$rc" = 3 ] && printf '%s' "$out" | grep -q 'go-microservice-dev' \
673
+ && ! printf '%s' "$out" | grep -q 'testing-strategy' \
674
+ && ok "verify-invocations: un-invoked owner flagged (exit 3)" || bad "VI-2" "rc=$rc out=$out"
675
+
676
+ # VI-3: no transcript => unverifiable => fail-open exit 0.
677
+ bash "$ENGINE" verify-invocations --owners "anything" --transcript "$BDIR/nope.jsonl" >/dev/null
678
+ [ $? -eq 0 ] && ok "verify-invocations: no transcript => fail-open exit 0" || bad "VI-3"
679
+
680
+ # VI-4: free-text (non-skill-shaped) owner never flags, even when absent.
681
+ out=$(bash "$ENGINE" verify-invocations --owners "then the touched owner" --transcript "$TR"); rc=$?
682
+ [ "$rc" = 0 ] && ok "verify-invocations: free-text owner never flags" || bad "VI-4" "rc=$rc out=$out"
683
+
684
+ # --- Stop-hook wiring: the reliable firing point (transcript_path on stdin) ---
685
+ git -C "$REPO" checkout -q -- . 2>/dev/null; git -C "$REPO" clean -fdq 2>/dev/null; rm -rf "$BDIR"
686
+ echo "package x" > "$REPO/src/foo.go"; git -C "$REPO" add -A; git -C "$REPO" commit -qm reset
687
+
688
+ # VI-5: boundary recorded with an owner that was NEVER invoked + activity + transcript => Stop BLOCKS.
689
+ rm -f "$BDIR/boundary.json"
690
+ edit "$REPO/src/foo.go" SV1 | bash "$ENGINE" pretool >/dev/null # capture baseline
691
+ echo "package x // SV1 change" > "$REPO/src/foo.go" # real post-baseline gated change
692
+ ( cd "$REPO" && bash "$ENGINE" record --owners "testing-strategy,go-microservice-dev" >/dev/null )
693
+ mktr "$TR" "ccl-skills:testing-strategy" # only testing-strategy invoked
694
+ d=$( cd "$REPO" && stopjt SV1 "$TR" | bash "$ENGINE" stop | sdecision )
695
+ [ "$d" = block ] && ok "Stop: recorded owner never invoked => block (name≠invoke)" || bad "VI-5 expected block, got $d"
696
+
697
+ # VI-6: fresh boundary, transcript shows BOTH owners invoked => Stop allows.
698
+ rm -f "$BDIR/boundary.json"
699
+ edit "$REPO/src/foo.go" SV2 | bash "$ENGINE" pretool >/dev/null
700
+ echo "package x // SV2 change" > "$REPO/src/foo.go"
701
+ ( cd "$REPO" && bash "$ENGINE" record --owners "testing-strategy,go-microservice-dev" >/dev/null )
702
+ mktr "$TR" "ccl-skills:testing-strategy" "ccl-skills:go-microservice-dev"
703
+ d=$( cd "$REPO" && stopjt SV2 "$TR" | bash "$ENGINE" stop | sdecision )
704
+ [ "$d" = stop ] && ok "Stop: all recorded owners invoked => allow" || bad "VI-6 expected allow, got $d"
705
+
706
+ # VI-7: boundary recorded, NO transcript_path on stdin => fail-open allow.
707
+ rm -f "$BDIR/boundary.json"
708
+ edit "$REPO/src/foo.go" SV3 | bash "$ENGINE" pretool >/dev/null
709
+ ( cd "$REPO" && bash "$ENGINE" record --owners "go-microservice-dev" >/dev/null )
710
+ d=$( cd "$REPO" && stopj SV3 | bash "$ENGINE" stop | sdecision )
711
+ [ "$d" = stop ] && ok "Stop: boundary recorded but no transcript => fail-open allow" || bad "VI-7 expected allow, got $d"
712
+
713
+ # VI-8: block fires AT MOST ONCE per actor (same safety as the boundary-missing block).
714
+ rm -f "$BDIR/boundary.json"
715
+ edit "$REPO/src/foo.go" SV4 | bash "$ENGINE" pretool >/dev/null
716
+ echo "package x // SV4 change" > "$REPO/src/foo.go"
717
+ ( cd "$REPO" && bash "$ENGINE" record --owners "go-microservice-dev" >/dev/null )
718
+ mktr "$TR" "ccl-skills:testing-strategy"
719
+ d1=$( cd "$REPO" && stopjt SV4 "$TR" | bash "$ENGINE" stop | sdecision )
720
+ d2=$( cd "$REPO" && stopjt SV4 "$TR" | bash "$ENGINE" stop | sdecision )
721
+ [ "$d1" = block ] && [ "$d2" = stop ] && ok "Stop invocation-block fires at most once per actor" || bad "VI-8 d1=$d1 d2=$d2"
722
+ # VI-9: boundary + un-invoked owner but the actor made NO actual gated change this session
723
+ # (edit then revert to baseline) => Stop must NOT block (no-trap safety preserved).
724
+ rm -f "$BDIR/boundary.json"
725
+ edit "$REPO/src/foo.go" SV5 | bash "$ENGINE" pretool >/dev/null # .touched activity...
726
+ git -C "$REPO" checkout -q -- src/foo.go # ...but reverted (no real change)
727
+ ( cd "$REPO" && bash "$ENGINE" record --owners "go-microservice-dev" >/dev/null )
728
+ mktr "$TR" "ccl-skills:testing-strategy" # go-microservice-dev un-invoked
729
+ d=$( cd "$REPO" && stopjt SV5 "$TR" | bash "$ENGINE" stop | sdecision )
730
+ [ "$d" = stop ] && ok "Stop: un-invoked owner but NO actual gated change => allow (no-trap)" || bad "VI-9 expected allow, got $d"
731
+
732
+ # VI-10: transcript with NO Skill invocations at all (empty invoked set) => unverifiable =>
733
+ # fail-open, never flag every owner.
734
+ : > "$TR"; printf '{"message":{"content":[{"type":"tool_use","name":"Bash","input":{"command":"ls"}}]}}\n' > "$TR"
735
+ printf 'garbage line\n' >> "$TR"
736
+ out=$(bash "$ENGINE" verify-invocations --owners "go-microservice-dev,testing-strategy" --transcript "$TR"); rc=$?
737
+ [ "$rc" = 0 ] && ok "verify-invocations: empty invoked set => fail-open (no flags)" || bad "VI-10" "rc=$rc out=$out"
738
+
739
+ # VI-11 (challenge R1): owner recorded in FULL "ccl-skills:foo" form still matches the
740
+ # invoked base name (prefix normalized on both sides).
741
+ mktr "$TR" "ccl-skills:go-microservice-dev"
742
+ bash "$ENGINE" verify-invocations --owners "ccl-skills:go-microservice-dev" --transcript "$TR" >/dev/null
743
+ [ $? -eq 0 ] && ok "verify-invocations: full ccl-skills:owner matches invoked base" || bad "VI-11"
744
+
745
+ # VI-12 (challenge R1): a same-named skill from an UNTRUSTED plugin does NOT satisfy a
746
+ # CCL owner (only ccl-skills: prefix is stripped for base matching).
747
+ : > "$TR"; printf '{"type":"assistant","message":{"content":[{"type":"tool_use","name":"Skill","input":{"skill":"evil-plugin:go-microservice-dev"}}]}}\n' > "$TR"
748
+ out=$(bash "$ENGINE" verify-invocations --owners "go-microservice-dev" --transcript "$TR"); rc=$?
749
+ [ "$rc" = 3 ] && printf '%s' "$out" | grep -q 'go-microservice-dev' \
750
+ && ok "verify-invocations: untrusted-plugin same-name does NOT satisfy CCL owner" || bad "VI-12" "rc=$rc out=$out"
751
+
752
+ # VI-13 (challenge R1): a malformed Skill.input.skill (non-string) BEFORE a valid invocation
753
+ # must not abort the stream — the valid invocation is still found (strings guard).
754
+ : > "$TR"
755
+ printf '{"type":"assistant","message":{"content":[{"type":"tool_use","name":"Skill","input":{"skill":123}}]}}\n' > "$TR"
756
+ printf '{"type":"assistant","message":{"content":[{"type":"tool_use","name":"Skill","input":{"skill":"ccl-skills:go-microservice-dev"}}]}}\n' >> "$TR"
757
+ bash "$ENGINE" verify-invocations --owners "go-microservice-dev" --transcript "$TR" >/dev/null
758
+ [ $? -eq 0 ] && ok "verify-invocations: non-string skill value skipped, later valid one found" || bad "VI-13"
759
+
760
+ # VI-14 (challenge R2): a Skill tool_use block in a NON-assistant (user-role) event must
761
+ # not count as a real invocation (spoof resistance). A real assistant invocation is
762
+ # present so the set is non-empty (not the fail-open path).
763
+ : > "$TR"
764
+ printf '{"type":"assistant","message":{"role":"assistant","content":[{"type":"tool_use","name":"Skill","input":{"skill":"ccl-skills:testing-strategy"}}]}}\n' > "$TR"
765
+ printf '{"type":"user","message":{"role":"user","content":[{"type":"tool_use","name":"Skill","input":{"skill":"ccl-skills:go-microservice-dev"}}]}}\n' >> "$TR"
766
+ out=$(bash "$ENGINE" verify-invocations --owners "go-microservice-dev,testing-strategy" --transcript "$TR"); rc=$?
767
+ [ "$rc" = 3 ] && printf '%s' "$out" | grep -q 'go-microservice-dev' \
768
+ && ! printf '%s' "$out" | grep -q 'testing-strategy' \
769
+ && ok "verify-invocations: non-assistant Skill block does not satisfy owner" || bad "VI-14" "rc=$rc out=$out"
770
+
771
+ # VI-15 (challenge R2): PROACTIVE record — owners recorded BEFORE any edit, then a real
772
+ # gated change, then Stop with a transcript missing an owner => still BLOCKS (the
773
+ # pretool now captures the activity marker even under a valid boundary).
774
+ rm -f "$BDIR/boundary.json"
775
+ ( cd "$REPO" && bash "$ENGINE" record --owners "go-microservice-dev" >/dev/null ) # record FIRST
776
+ edit "$REPO/src/foo.go" SV6 | bash "$ENGINE" pretool >/dev/null # THEN edit (marker captured despite valid boundary)
777
+ echo "package x // SV6 change" > "$REPO/src/foo.go" # real gated change
778
+ mktr "$TR" "ccl-skills:testing-strategy" # go-microservice-dev un-invoked
779
+ d=$( cd "$REPO" && stopjt SV6 "$TR" | bash "$ENGINE" stop | sdecision )
780
+ [ "$d" = block ] && ok "Stop: proactive-record path still caught (marker captured under valid boundary)" || bad "VI-15 expected block, got $d"
781
+
782
+ # VI-16: SubagentStop must inspect the WORKER transcript. Claude supplies the main
783
+ # session transcript in transcript_path and the worker's own evidence in
784
+ # agent_transcript_path. A skill loaded only by the controller cannot satisfy the worker.
785
+ git -C "$REPO" checkout -q -- . 2>/dev/null; git -C "$REPO" clean -fdq 2>/dev/null; rm -rf "$BDIR"
786
+ MAIN_TR="$BDIR.main.jsonl"; AGENT_TR="$BDIR.agent.jsonl"
787
+ edita "$REPO/src/foo.go" SV7 W7 | bash "$ENGINE" pretool >/dev/null
788
+ echo "package x // SV7 worker change" > "$REPO/src/foo.go"
789
+ ( cd "$REPO" && bash "$ENGINE" record --owners "go-microservice-dev" >/dev/null )
790
+ mktr "$MAIN_TR" "ccl-skills:go-microservice-dev" # controller loaded it
791
+ mktr "$AGENT_TR" "ccl-skills:testing-strategy" # worker did not
792
+ d=$( cd "$REPO" && stopjat SV7 W7 "$MAIN_TR" "$AGENT_TR" | bash "$ENGINE" stop | sdecision )
793
+ [ "$d" = block ] && ok "SubagentStop: worker transcript wins over main transcript" || bad "VI-16 expected block, got $d"
794
+
795
+ # VI-17: a worker transcript with a verifiable tool-event shape but ZERO Skill invocations is evidence
796
+ # of a cold worker, not transcript-format drift. Continue that worker once.
797
+ git -C "$REPO" checkout -q -- . 2>/dev/null; rm -rf "$BDIR"
798
+ edita "$REPO/src/foo.go" SV8 W8 | bash "$ENGINE" pretool >/dev/null
799
+ echo "package x // SV8 worker change" > "$REPO/src/foo.go"
800
+ ( cd "$REPO" && bash "$ENGINE" record --owners "go-microservice-dev" >/dev/null )
801
+ mktr "$MAIN_TR" "ccl-skills:go-microservice-dev"
802
+ printf '{"type":"assistant","message":{"content":[{"type":"tool_use","name":"Bash","input":{"command":"go test ./..."}}]}}\n' > "$AGENT_TR"
803
+ d=$( cd "$REPO" && stopjat SV8 W8 "$MAIN_TR" "$AGENT_TR" | bash "$ENGINE" stop | sdecision )
804
+ [ "$d" = block ] && ok "SubagentStop: zero worker Skill invocations => block once" || bad "VI-17 expected block, got $d"
805
+
806
+ # VI-18/19: the standalone verifier exposes the same strict worker mode for host
807
+ # adapters, while malformed-only evidence remains fail-open.
808
+ out=$(bash "$ENGINE" verify-invocations --owners "go-microservice-dev" --transcript "$AGENT_TR" --empty-is-missing); rc=$?
809
+ [ "$rc" = 3 ] && printf '%s' "$out" | grep -q 'go-microservice-dev' \
810
+ && ok "verify-invocations: strict empty set flags required skill" || bad "VI-18" "rc=$rc out=$out"
811
+ printf 'not json\nstill not json\n' > "$AGENT_TR"
812
+ out=$(bash "$ENGINE" verify-invocations --owners "go-microservice-dev" --transcript "$AGENT_TR" --empty-is-missing); rc=$?
813
+ [ "$rc" = 0 ] && ok "verify-invocations: malformed-only transcript stays fail-open" || bad "VI-19" "rc=$rc out=$out"
814
+
815
+ # VI-20: valid JSONL is not enough to prove invocation absence. If the host still emits
816
+ # assistant tool_use events but a Skill block's input shape drifted, strict worker
817
+ # verification must fail open rather than falsely claiming every owner was skipped.
818
+ git -C "$REPO" checkout -q -- . 2>/dev/null; rm -rf "$BDIR"
819
+ edita "$REPO/src/foo.go" SV9 W9 | bash "$ENGINE" pretool >/dev/null
820
+ echo "package x // SV9 worker change" > "$REPO/src/foo.go"
821
+ ( cd "$REPO" && bash "$ENGINE" record --owners "go-microservice-dev" >/dev/null )
822
+ printf '{"type":"assistant","message":{"content":[{"type":"tool_use","name":"Skill","input":{"arguments":{"skill":"ccl-skills:go-microservice-dev"}}},{"type":"tool_use","name":"Edit","input":{"file_path":"src/foo.go"}}]}}\n' > "$AGENT_TR"
823
+ d=$( cd "$REPO" && stopjat SV9 W9 "$MAIN_TR" "$AGENT_TR" | bash "$ENGINE" stop | sdecision )
824
+ [ "$d" = stop ] && ok "SubagentStop: drifted Skill event shape stays fail-open" || bad "VI-20 expected allow, got $d"
825
+
826
+ # VI-21: an older host may omit agent_transcript_path. The main transcript fallback is
827
+ # orientation only and must retain legacy empty-set fail-open behavior; otherwise a
828
+ # controller with no Skill calls is falsely attributed to the worker.
829
+ git -C "$REPO" checkout -q -- . 2>/dev/null; rm -rf "$BDIR"
830
+ edita "$REPO/src/foo.go" SV10 W10 | bash "$ENGINE" pretool >/dev/null
831
+ echo "package x // SV10 worker change" > "$REPO/src/foo.go"
832
+ ( cd "$REPO" && bash "$ENGINE" record --owners "go-microservice-dev" >/dev/null )
833
+ printf '{"type":"assistant","message":{"content":[{"type":"tool_use","name":"Bash","input":{"command":"git status"}}]}}\n' > "$MAIN_TR"
834
+ d=$( cd "$REPO" && stopja_legacy SV10 W10 "$MAIN_TR" | bash "$ENGINE" stop | sdecision )
835
+ [ "$d" = stop ] && ok "SubagentStop: legacy main-transcript fallback keeps empty-set fail-open" || bad "VI-21 expected allow, got $d"
836
+
837
+ git -C "$REPO" checkout -q -- . 2>/dev/null; git -C "$REPO" clean -fdq 2>/dev/null; rm -rf "$BDIR" "$TR" "$MAIN_TR" "$AGENT_TR"
838
+
839
+ # ---- WORKTREE DIMENSION (issue #5) -------------------------------------------
840
+ # Every fixture above builds a PLAIN repo, so none of them can cross the axis where
841
+ # this gate actually runs: `worktree-isolation` mandates developing in a linked
842
+ # worktree, while the Stop hook resolves its repo from $PWD — which the harness
843
+ # routinely resets back to the main checkout. Keying boundary state on
844
+ # `--absolute-git-dir` puts the write in `.git/worktrees/<name>/` and the read in
845
+ # `.git/`, so the gate reports "never recorded" on the repo's OWN standard workflow
846
+ # and then trains everyone to ignore it. These probes pin read/write agreement
847
+ # across that boundary; without the fix W1 fails.
848
+ echo "--- worktree dimension ---"
849
+ WT="$WORK/prod-wt"
850
+ if git -C "$REPO" worktree add -q -b od-wt "$WT" >/dev/null 2>&1; then
851
+ # W1: record INSIDE the worktree must be visible FROM the main checkout.
852
+ rm -rf "$BDIR"
853
+ ( cd "$WT" && bash "$ENGINE" record --owners "product-rd-workflow" >/dev/null )
854
+ main_state=$(bash "$ENGINE" boundary-path "$REPO" 2>/dev/null)
855
+ wt_state=$(bash "$ENGINE" boundary-path "$WT" 2>/dev/null)
856
+ [ -n "$main_state" ] && [ "$main_state" = "$wt_state" ] \
857
+ && ok "worktree: boundary path is identical from the worktree and the main checkout" \
858
+ || bad "W1a: boundary path differs across worktrees" "main=$main_state wt=$wt_state"
859
+ [ -r "$main_state/boundary.json" ] \
860
+ && ok "worktree: a boundary recorded in the worktree is readable from the main checkout" \
861
+ || bad "W1: record-in-worktree is invisible from the main checkout (issue #5)" "looked in $main_state"
862
+
863
+ # W2: the shared path must be ABSOLUTE. `--git-common-dir` returns a RELATIVE
864
+ # `.git` when asked from the main checkout, so a naive swap would make the
865
+ # state dir depend on the caller's cwd — the same class of bug, re-introduced.
866
+ case "$main_state" in
867
+ /*) ok "worktree: boundary path is absolute from the main checkout (cwd-independent)" ;;
868
+ *) bad "W2: boundary path is relative => cwd-dependent state dir" "got=$main_state" ;;
869
+ esac
870
+
871
+ # W3: the gate itself must be satisfied — record in the worktree, Stop in the main
872
+ # checkout (exactly the shape the standard workflow produces).
873
+ rm -rf "$BDIR"
874
+ edit "$REPO/src/foo.go" SW1 | bash "$ENGINE" pretool >/dev/null
875
+ echo "package x // SW1" > "$REPO/src/foo.go"
876
+ ( cd "$WT" && bash "$ENGINE" record --owners "product-rd-workflow" >/dev/null )
877
+ d=$( cd "$REPO" && stopj SW1 | bash "$ENGINE" stop | sdecision )
878
+ [ "$d" = stop ] && ok "worktree: record-in-worktree satisfies a Stop resolved in the main checkout" \
879
+ || bad "W3: Stop still blocks after a worktree record (issue #5 end-to-end)" "got $d"
880
+
881
+ # W6: OLD GIT. `--path-format=absolute` needs git >= 2.31; without it the fallback
882
+ # builds the path itself, and that branch answers a LOGICAL path while git answers
883
+ # a PHYSICAL one. On a symlinked root (macOS /var -> /private/var, i.e. mktemp)
884
+ # the two disagree and the split returns — on exactly the hosts that cannot take
885
+ # the fast path. Shim git to reject the flag so the fallback is what runs.
886
+ REALGIT=$(command -v git)
887
+ SHIM="$WORK/shim"; mkdir -p "$SHIM"
888
+ cat > "$SHIM/git" <<SH
889
+ #!/bin/sh
890
+ for a in "\$@"; do
891
+ [ "\$a" = "--path-format=absolute" ] && { echo "error: unknown option \\\`path-format=absolute'" >&2; exit 129; }
892
+ done
893
+ exec "$REALGIT" "\$@"
894
+ SH
895
+ chmod +x "$SHIM/git"
896
+ old_main=$(PATH="$SHIM:$PATH" bash "$ENGINE" boundary-path "$REPO" 2>/dev/null)
897
+ old_wt=$(PATH="$SHIM:$PATH" bash "$ENGINE" boundary-path "$WT" 2>/dev/null)
898
+ [ -n "$old_main" ] && [ "$old_main" = "$old_wt" ] \
899
+ && ok "worktree: path agrees across worktrees on git without --path-format (>=2.31 fallback)" \
900
+ || bad "W6: fallback path differs across worktrees on old git" "main=$old_main wt=$old_wt"
901
+ case "$old_main" in
902
+ /*) ok "worktree: fallback path is absolute too" ;;
903
+ *) bad "W6b: fallback produced a relative path" "got=$old_main" ;;
904
+ esac
905
+ rm -rf "$SHIM"
906
+
907
+ # W4: the recording worktree is REMOVED — the normal end of a delivery, since
908
+ # worktree-isolation says clean up the moment it is integrated. A boundary keyed
909
+ # on the worktree PATH cannot survive this (the path is gone and `git -C` on it
910
+ # fails), which is why identity is keyed on the common git dir instead.
911
+ rm -rf "$BDIR"
912
+ ( cd "$WT" && bash "$ENGINE" record --owners "product-rd-workflow" >/dev/null )
913
+ git -C "$REPO" worktree remove --force "$WT" >/dev/null 2>&1
914
+ [ -d "$WT" ] && bad "W4 fixture: worktree not actually removed" "$WT still exists"
915
+ [ "$(cd "$REPO" && bash "$ENGINE" status | sed -n 's/^boundary: *//p')" = valid ] \
916
+ && ok "worktree: boundary survives cleanup of the worktree that recorded it" \
917
+ || bad "W4: boundary lost once the recording worktree was removed" "status=$(cd "$REPO" && bash "$ENGINE" status | sed -n 's/^boundary: *//p')"
918
+
919
+ # W5: NEGATIVE — repository identity still has teeth. The path equality this change
920
+ # replaced was there to reject a boundary belonging to somewhere else; a boundary
921
+ # naming a DIFFERENT repo's git dir must still be refused, or the fix would have
922
+ # been a deletion wearing a replacement's clothes.
923
+ OTHER="$WORK/other"; mkdir -p "$OTHER"
924
+ git -C "$OTHER" init -q; git -C "$OTHER" config user.email t@t; git -C "$OTHER" config user.name t
925
+ git -C "$OTHER" commit -q --allow-empty -m init
926
+ other_gd=$(bash "$ENGINE" boundary-path "$OTHER")
927
+ jq --arg gd "$other_gd" '.repo_git_dir=$gd' "$BDIR/boundary.json" > "$BDIR/boundary.json.tmp" \
928
+ && mv "$BDIR/boundary.json.tmp" "$BDIR/boundary.json"
929
+ [ "$(cd "$REPO" && bash "$ENGINE" status | sed -n 's/^boundary: *//p')" = absent ] \
930
+ && ok "worktree: a boundary naming another repository is still refused" \
931
+ || bad "W5: foreign-repo boundary accepted — identity check lost its teeth" "status=$(cd "$REPO" && bash "$ENGINE" status | sed -n 's/^boundary: *//p')"
932
+ rm -rf "$OTHER"
933
+
934
+ git -C "$REPO" checkout -q -- . 2>/dev/null
935
+ git -C "$REPO" branch -qD od-wt >/dev/null 2>&1
936
+ rm -rf "$BDIR"
937
+ else
938
+ bad "W0: could not create a linked worktree — the worktree dimension went untested" "git worktree add failed"
939
+ fi
940
+
941
+ echo "---"; echo "PASS=$PASS FAIL=$FAIL"; [ "$FAIL" -eq 0 ]