@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.
- package/LICENSE +201 -0
- package/README.md +49 -0
- package/dist/assets/marketplace/.agents/plugins/marketplace.json +12 -0
- package/dist/assets/marketplace/.claude-plugin/marketplace.json +13 -0
- package/dist/assets/marketplace/marketplace-manifest.json +12 -0
- package/dist/assets/marketplace/plugins/ccl-skills/.claude-plugin/marketplace.json +16 -0
- package/dist/assets/marketplace/plugins/ccl-skills/.claude-plugin/plugin.json +5 -0
- package/dist/assets/marketplace/plugins/ccl-skills/.codex-plugin/plugin.json +5 -0
- package/dist/assets/marketplace/plugins/ccl-skills/.worktree-only +3 -0
- package/dist/assets/marketplace/plugins/ccl-skills/agent-context/session-start.md +45 -0
- package/dist/assets/marketplace/plugins/ccl-skills/agent-context/subagent-start.md +12 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/AGENTS.md +19 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/guard-delegation-owner.sh +125 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/guard-edit-isolation.sh +102 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/guard-merge-authorization.sh +1156 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/hooks.json +131 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/merge-authorization-prompt.sh +142 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/owner-dispatch-guard.sh +12 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/owner-dispatch-stop.sh +13 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/remind-post-merge-cleanup.sh +144 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/session-context.sh +87 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/session-start.sh +86 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/skill-extraction-gate-stop.sh +69 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/subagent-start.sh +26 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/test_guard_delegation_owner.sh +329 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/test_guard_edit_isolation.sh +322 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/test_guard_merge_authorization.sh +902 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/test_merge_authorization_prompt.sh +178 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/test_remind_post_merge_cleanup.sh +121 -0
- package/dist/assets/marketplace/plugins/ccl-skills/hooks/test_session_start.sh +170 -0
- package/dist/assets/marketplace/plugins/ccl-skills/packages/opencode-plugin/AGENTS.md +17 -0
- package/dist/assets/marketplace/plugins/ccl-skills/packages/opencode-plugin/ccl-skills.ts +564 -0
- package/dist/assets/marketplace/plugins/ccl-skills/packages/opencode-plugin/commands/ccl-install-skills.md +14 -0
- package/dist/assets/marketplace/plugins/ccl-skills/packages/opencode-plugin/commands/ccl-update-skills.md +44 -0
- package/dist/assets/marketplace/plugins/ccl-skills/packages/opencode-plugin/commands/ccl-verify-skills.md +109 -0
- package/dist/assets/marketplace/plugins/ccl-skills/packages/opencode-plugin/commands/ccl-worktree-check.md +36 -0
- package/dist/assets/marketplace/plugins/ccl-skills/scripts/owner-dispatch/AGENTS.md +28 -0
- package/dist/assets/marketplace/plugins/ccl-skills/scripts/owner-dispatch/README.md +276 -0
- package/dist/assets/marketplace/plugins/ccl-skills/scripts/owner-dispatch/owner-dispatch.example.json +10 -0
- package/dist/assets/marketplace/plugins/ccl-skills/scripts/owner-dispatch/owner-dispatch.sh +1307 -0
- package/dist/assets/marketplace/plugins/ccl-skills/scripts/owner-dispatch/test.sh +941 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/agents-file-coverage-gate/SKILL.md +45 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/agents-file-coverage-gate/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/app-cross-platform-dev/SKILL.md +188 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/app-cross-platform-dev/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/app-cross-platform-dev/references/android-dev.md +92 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/app-cross-platform-dev/references/flutter-dev.md +80 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/app-cross-platform-dev/references/ios-dev.md +72 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/app-cross-platform-dev/references/kotlin-multiplatform.md +93 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/app-cross-platform-dev/references/mobile-platform-boundaries.md +77 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/app-cross-platform-dev/references/mobile-quality-release.md +77 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/app-cross-platform-dev/references/source-evidence-map.md +64 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/SKILL.md +353 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/references/client-routing.md +419 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/references/manual-invocation-and-prompts.md +126 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/references/staged-review-contract.md +197 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/references/timeout-auth-and-capabilities.md +179 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/AGENTS.md +98 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/classify_envelope.py +93 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/classify_timeout_exit.sh +15 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/claude_review.sh +1438 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/codex_review.sh +324 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/concern_excerpt.py +295 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/egress_schema.py +214 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/init_policy_matrix.py +642 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/kimi_packet_mcp.py +181 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/kimi_review.sh +1165 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/opencode_review.sh +1190 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/parse_cli_review.py +946 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/parse_opencode_review.py +474 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/parse_probe_result.py +1899 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/parse_review_json.py +200 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/review_gate.py +2845 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/review_gate.sh +6 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/run_claude_capture.py +71 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/runtime-surface-verification-design.md +53 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_classify_envelope.sh +68 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_claude_review_probe.sh +2311 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_cli_review_wrappers.sh +1832 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_code_review_identity.sh +73 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_concern_excerpt.sh +245 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_egress_schema.sh +177 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_init_policy_matrix.sh +272 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_kimi_packet_mcp.py +195 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_opencode_review_concurrency.sh +120 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_opencode_review_retry.sh +1005 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_parse_opencode_review.sh +258 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_parse_probe_result.sh +574 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_parse_review_json.sh +349 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_review_client_compat.py +434 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_review_client_order.sh +264 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_review_gate.sh +2412 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/verify_native_skill_binding.py +123 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/defect-diagnosis/SKILL.md +153 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/defect-diagnosis/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/defect-diagnosis/references/diagnosis-playbook.md +54 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/defect-diagnosis/references/prevention-routing.md +36 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/feature-risk-router/SKILL.md +69 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/feature-risk-router/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/feature-risk-router/references/security-review-gate.md +41 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/SKILL.md +165 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/api-security-boundaries.md +47 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/architecture-playbook.md +160 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/artifact-generation-architecture.md +37 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/audit-history-architecture.md +29 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/bulk-workflow-architecture.md +33 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/config-rule-routing-architecture.md +34 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/cross-cutting-concerns.md +72 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/data-modeling-and-migrations.md +79 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/data-platform-architecture.md +210 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/dependency-platform.md +105 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/developer-tooling-architecture.md +38 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/error-contract-architecture.md +36 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/event-driven-architecture.md +260 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/http-gateway-architecture.md +74 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/mq-consumer-architecture.md +38 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/multi-tenant-isolation.md +275 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/notification-architecture.md +25 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/ops-checklist.md +57 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/performance-capacity-architecture.md +38 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/protobuf-contract-architecture.md +119 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/redis-cache-coordination.md +93 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/release-runtime-readiness.md +65 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/replay-comparison-architecture.md +26 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/runtime-observability.md +94 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/service-scaffold.md +76 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/source-evidence-map.md +55 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-architecture/references/workflow-state-architecture.md +38 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/SKILL.md +159 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/artifact-generation-patterns.md +37 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/audit-history-patterns.md +28 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/bulk-import-export-patterns.md +56 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/config-rule-routing-patterns.md +38 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/data-access-patterns.md +55 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/db-schema-and-dal-patterns.md +109 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/dependency-client-patterns.md +130 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/developer-tooling-patterns.md +70 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/domain-feature-patterns.md +78 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/engineering-patterns.md +119 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/error-contract-patterns.md +55 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/feature-playbook.md +61 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/http-gateway-client-patterns.md +76 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/mq-consumer-patterns.md +55 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/notification-patterns.md +42 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/observability-implementation-patterns.md +101 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/performance-capacity-patterns.md +44 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/protobuf-contract-patterns.md +72 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/public-api-integration-patterns.md +56 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/quality-and-testing-patterns.md +91 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/redis-cache-lock-patterns.md +123 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/release-ops-patterns.md +112 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/reliability-patterns.md +83 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/replay-comparison-patterns.md +32 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/scaffold-and-codegen.md +86 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/source-evidence-map.md +54 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/go-microservice-dev/references/state-machine-task-patterns.md +45 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/grill-me/SKILL.md +80 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/grill-me/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/SKILL.md +117 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-approval-auto-reviewer.md +106 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-command-sandbox.md +441 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-context-freshness.md +47 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-credentials-auth.md +13 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-extensions-skills.md +13 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-file-edit-protocol.md +129 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-ide-integration.md +5 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-input-ingestion.md +13 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-instruction-composition.md +13 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-lifecycle-hooks.md +92 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-messaging.md +5 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-runtime-bootstrap.md +5 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-session-persistence.md +448 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-task-orchestration.md +13 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-tool-dispatch.md +123 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/agent-turn-lifecycle.md +131 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/inference-capacity-operations.md +162 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/llm-client-gateway.md +156 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/model-prompt-evaluation.md +146 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/llm-inference-integration/references/retrieval-agent-safety.md +273 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/miniapp-product-dev/SKILL.md +202 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/miniapp-product-dev/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/miniapp-product-dev/references/contracts-and-state.md +62 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/miniapp-product-dev/references/cross-stack-alignment.md +94 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/miniapp-product-dev/references/framework-choice.md +76 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/miniapp-product-dev/references/online-practice-uptake.md +56 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/miniapp-product-dev/references/platform-capabilities.md +91 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/miniapp-product-dev/references/product-page-checklist.md +40 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/miniapp-product-dev/references/qa-release.md +72 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/miniapp-product-dev/references/source-evidence-map.md +82 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-agent-delegation/SKILL.md +103 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-agent-delegation/agents/openai.yaml +5 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-agent-delegation/references/multi-agent-delegation-playbook.md +100 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-perspective-research/SKILL.md +70 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-perspective-research/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-perspective-research/references/public-data-acquisition.md +549 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-perspective-research/references/public-disclosure-channels.md +97 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-perspective-research/references/research-prompts.md +66 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-perspective-research/scripts/AGENTS.md +32 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-perspective-research/scripts/test-public-data-acquisition-recipes.sh +379 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/SKILL.md +244 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/references/alerting-and-on-call.md +76 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/references/framework-middleware-checklist.md +142 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/references/infra-component-deployment.md +268 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/references/log-correlation-recipe.md +124 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/references/log-schema-canonical.md +208 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/references/metrics-conventions.md +105 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/references/obs-stack-architecture.md +107 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/references/sli-slo-design.md +95 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/references/source-register.md +11 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/SKILL.md +303 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/canary-and-rollout-strategy.md +163 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/config-center-via-etcd.md +245 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/custom-control-plane-boundary.md +298 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/deploy-cli-concrete-recipe.md +312 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/deploy-pipeline.md +165 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/env-and-lane-matrix.md +126 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/lane-orchestration-control-plane.md +383 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/multi-region-and-cluster.md +135 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/promotion-gate-and-review.md +149 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/python-package-registry-release.md +462 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/rollback-playbook.md +123 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/secret-and-config-management.md +231 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-release-engineering/references/version-authority-and-deprecation.md +21 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/SKILL.md +276 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/dual-sidecar-and-traffic-config-center.md +127 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/framework-middleware.md +143 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/grpc-authority-workaround.md +90 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/http-response-envelope-contract.md +24 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/mesh-architecture.md +127 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/multi-env-routing.md +192 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/protobuf-http-contract-signals.md +64 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/retry-timeout-circuit-breaker.md +124 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/rpc-framework-recipe.md +494 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/service-discovery-choice.md +113 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/service-discovery-migration-playbook.md +231 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/service-discovery-recipe.md +131 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/SKILL.md +235 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/adr-convention.md +146 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/algorithm-launch-checklist.md +30 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/algorithm-launch-evaluation-report-template.md +25 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/algorithm-launch-execution-spec.md +108 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/algorithm-launch-sop.md +457 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/algorithm-launch-templates.md +24 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/artifact-egress-confidentiality.md +58 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/code-review-checklist.md +86 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/cross-repo-coordination.md +46 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/delivery-lifecycle.md +192 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/design-review-gate-mechanics.md +62 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/design-routing-and-readiness.md +45 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/diagnostic-spec-match-gate.md +36 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/dispatch-owner-skills.md +35 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/dormant-code-activation.md +47 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/existing-project-assessment-report.md +223 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/external-skill-augmentation.md +46 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/feature-deprecation-cascade.md +15 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/high-risk-resilience-gates.md +73 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/implementation-completeness-and-minimality.md +120 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/implementation-entry-reentry-gate.md +122 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/modular-monolith-heuristic.md +105 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/pre-final-continuation-gate.md +115 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/problem-resolution-and-learning.md +62 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/quality-attributes.md +112 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/quality-remediation-program.md +88 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/rd-standards-doc-family-checklist.md +27 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/refactoring-discipline.md +52 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/review-reception.md +34 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/shared-gate-artifact-classification.md +76 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/source-evidence-map.md +31 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/status-tracker-sync.md +77 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/sync-spec-repo-contract.md +25 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/verify-developer-experience.md +34 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/worktree-mechanics.md +55 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/scripts/AGENTS.md +18 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/scripts/check-agent-contract-coverage.sh +213 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/SKILL.md +136 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/agents/openai.yaml +9 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/analytics-visualization-interactions.md +206 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/behavioral-aesthetic-logic.md +108 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/complex-creation-interactions.md +194 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/design-execution-checklist.md +214 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/design-impl-naming-and-versioning.md +53 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/design-intake-and-acceptance.md +129 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/design-system-source-of-truth.md +97 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/external-ui-ux-quality-benchmarks.md +79 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/frontend-code-evidence-map.md +63 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/interaction-design-patterns.md +146 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/layout-recipes-and-screenshot-acceptance.md +250 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/multi-project-token-consistency.md +237 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/multi-stack-strategy.md +65 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/operational-processing-workflows.md +237 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/platform-mobile-patterns.md +324 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/platform-web-desktop-patterns.md +456 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/product-lifecycle-acceptance-and-iteration.md +114 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/product-surface-patterns.md +79 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/resource-management-interactions.md +113 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/scenario-community-patterns.md +133 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/source-map.md +130 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/tokens-and-components.md +47 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/trust-sensitive-ai-and-data-patterns.md +96 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/ui-ux-audit.md +106 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/ui-ux-design-development.md +176 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-ui-ux-design/references/visual-craft.md +111 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/SKILL.md +157 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/ai-service-integration-boundaries.md +57 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/api-contract-and-schema.md +62 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/api-security-boundaries.md +39 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/architecture-playbook.md +46 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/async-execution-model.md +24 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/background-jobs-and-scheduling.md +18 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/batch-and-pipeline-architecture.md +11 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/config-secrets-runtime.md +22 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/data-modeling-and-migrations.md +64 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/data-platform-architecture.md +211 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/event-driven-architecture.md +263 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/multi-tenant-isolation.md +281 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/observability-and-ops.md +26 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/packaging-runtime-readiness.md +20 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/redis-cache-coordination.md +41 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/reliability-and-error-contract.md +17 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/source-evidence-map.md +55 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-architecture/references/web-framework-boundaries.md +26 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/SKILL.md +143 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/ai-service-wiring-patterns.md +16 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/async-and-worker-patterns.md +24 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/background-job-patterns.md +18 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/batch-and-artifact-patterns.md +13 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/dependency-client-patterns.md +39 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/error-handling-patterns.md +26 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/feature-playbook.md +43 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/observability-implementation-patterns.md +31 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/project-structure-and-tooling.md +24 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/public-api-security-patterns.md +52 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/redis-cache-lock-patterns.md +78 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/schema-and-validation-patterns.md +23 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/source-evidence-map.md +56 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/sqlalchemy-and-migrations-patterns.md +99 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/testing-and-quality-patterns.md +61 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/python-service-dev/references/web-framework-patterns.md +35 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/release-coordination/SKILL.md +91 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/release-coordination/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/release-coordination/references/config-runtime-readback.md +20 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/release-coordination/references/mr-merge-authorization.md +31 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/release-coordination/references/post-release-env-reset.md +31 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/release-coordination/references/release-closeout-evidence.md +20 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/release-coordination/references/release-scope-confirmation.md +21 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/release-coordination/references/tag-and-prod-pipeline-gate.md +20 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/release-coordination/references/test-scope-prompt.md +24 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/release-coordination/references/watcher-discipline.md +14 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/release-doc-writer/SKILL.md +64 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/release-doc-writer/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/release-doc-writer/references/comment-safe-release-doc.md +19 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/release-doc-writer/references/release-evidence-workflow.md +23 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/release-doc-writer/references/release-testing-scope-section.md +15 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/requirement-baseline/SKILL.md +87 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/requirement-baseline/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/requirement-doc-writer/SKILL.md +130 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/requirement-doc-writer/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/requirement-doc-writer/references/prd-composition-contract.md +35 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/requirement-doc-writer/references/requirement-closure-contract.md +86 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/requirement-doc-writer/references/security-four-questions.md +38 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/requirement-intent/SKILL.md +91 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/requirement-intent/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/requirement-scope/SKILL.md +88 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/requirement-scope/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/SKILL.md +337 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/analysis-parse-fix-test-challenge-replay.md +47 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/attribution-verification.md +69 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/bootstrap-slim-c3-obligation-table.md +112 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/coverage-exhaustion-traps.md +45 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/description-authoring.md +162 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/dual-track-review-gate.md +507 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/eval-routing.md +86 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/evidence-card-template.md +51 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/example-domain-preselect.md +79 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/external-practice-controls.md +57 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/extraction-lifecycle-handoff.md +65 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/extraction-quickstart.md +194 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/firing-point-placement.md +75 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/harness-patterns-and-eval.md +286 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/incident-postmortem-extraction.md +190 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/l0-l1-l2-routing.md +114 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/online-skill-review.md +47 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/parallel-stack-references-pattern.md +164 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/r0-leakage-audit.md +90 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/recurring-anti-patterns-checklist.md +320 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/resume-paused-delivery.md +16 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/review-feedback-mining.md +33 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/review-finding-standards.md +57 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/review-rubric.md +40 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/rule-consolidation.md +118 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/skill-listing-budget.md +19 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/source-register.md +254 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/source-to-skill-extraction.md +658 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/two-source-extraction-pattern.md +167 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/uiux-judgment-extraction.md +179 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/uiux-routing-map.md +51 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/validation-and-landing.md +180 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/AGENTS.md +18 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/check-ccl-skills.sh +1452 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/check-evidence-card-leak.sh +491 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/check-mr-target-freshness.sh +173 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/check-size-budget.sh +488 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/check-sync-pointers.sh +419 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/eval-golden-trace.rb +197 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/eval-health.rb +327 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/eval-routing-bank.rb +401 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/eval-routing.rb +248 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/generic-r0-leak-scan.sh +282 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/governing-chain-diff.py +321 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/impact-chain-gate.rb +964 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/register-firing-path-resolution.rb +708 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/skill-behavior-eval.py +540 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/source-register-lifecycle.rb +51 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/source-register-pending-status.rb +55 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_ai_coding_implementation_gates.sh +829 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_impact_chain_refscripts.sh +1203 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_r0_status.sh +75 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_register_pending_exclusion.sh +137 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_regressions.sh +173 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_route_drift.sh +377 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_size_budget.sh +833 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_skill_catalog.sh +491 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_source_register_lifecycle.sh +114 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_mr_target_freshness.sh +261 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_sync_pointers.sh +538 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_controlled_escalation_pins.sh +154 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_eval_routing_bank_grader_diagnostics.sh +190 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_eval_routing_bank_surface_binding.sh +178 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_eval_routing_prose_target.sh +86 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_generic_r0_leak_scan.sh +131 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_git_identity_predicate_gate.sh +243 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_governing_chain_diff.sh +419 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_impact_chain_gate_dateless_host.sh +120 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_register_firing_path_resolution.sh +724 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_register_firing_path_wiring.sh +414 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_regression_runner_registration.sh +34 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_routing_bank_integrity.sh +205 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_routing_pointer_integrity.sh +194 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_validate_skill_credential_cwd.sh +61 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_validate_skill_cross_refs.sh +111 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_validate_skill_root_depth.sh +53 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/validate-skill.sh +257 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/terminal-cli-dev/SKILL.md +98 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/terminal-cli-dev/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/terminal-cli-dev/references/input-state-machines.md +36 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/terminal-cli-dev/references/streaming-rich-output.md +130 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/terminal-cli-dev/references/terminal-side-channels.md +96 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/SKILL.md +408 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/AGENTS.md +18 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/bitable-setup.md +573 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/ci_templates/README.md +120 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/ci_templates/github-actions.yml +119 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/ci_templates/gitlab-ci.yml +76 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/ci_templates/jenkins.Jenkinsfile +106 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/classical-test-design-techniques.md +279 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/gen_report.py +2807 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/makefile-template.md +200 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/report-config-schema.md +272 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/run_pytestless.py +475 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/source-to-case-workflows.md +258 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/tc-marker-conventions.md +316 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/tc-review-and-prioritization.md +145 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/tc_helpers/AGENTS.md +16 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/tc_helpers/tc.dart +129 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/tc_helpers/tc.go +197 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/tc_helpers/tc.py +135 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/tc_helpers/tc.ts +285 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/test_gen_report.py +2144 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/test-artifact-management/references/update-lifecycle.md +62 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/SKILL.md +212 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/ci-fixtures-and-flake-control.md +75 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/client-runtime-test-matrices.md +50 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/data-and-workflow-testing.md +34 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/design-closed-contract-oracles.md +31 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/e2e-real-flow-testing.md +71 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/fitness-functions.md +240 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/integration-contract-testing.md +235 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/non-functional-specialized-scenarios.md +296 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/rd-testing-standard-template.md +126 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/run-killing-mutation-walk.md +43 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/scenario-testing.md +136 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/source-evidence-map.md +59 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/structured-tc-input-translation.md +67 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/test-code-authoring-patterns.md +392 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/test-data-and-determinism.md +39 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/test-topology-and-commands.md +92 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/unit-testing.md +46 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/vendored-contract-drift-checklist.md +64 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/references/verify-enforcement-mechanisms.md +18 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/scripts/AGENTS.md +17 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/scripts/client-terminal-ansi-check.py +140 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/scripts/client-terminal-ansi-check.test.sh +75 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/scripts/lang-basics-ast-check.py +170 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/scripts/lang-basics-ast-check.test.sh +87 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/scripts/lang-basics-go-check.go +198 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/scripts/lang-basics-go-check.test.sh +109 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/testing-strategy/scripts/test_mutation_backup_recipe.sh +237 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/SKILL.md +184 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/references/comment-safe-feishu.md +93 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/references/cross-model-co-review.md +3 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/references/delivery-face-closeout.md +60 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/references/doc-charter-first.md +17 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/references/session-vantage-leakage.md +58 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/web-react-dev/SKILL.md +126 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/web-react-dev/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/web-react-dev/references/complex-workspace-patterns.md +47 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/web-react-dev/references/embedded-h5-in-host.md +87 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/web-react-dev/references/react-architecture.md +194 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/web-react-dev/references/source-evidence-map.md +60 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/web-react-dev/references/web-quality-release.md +190 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/web-react-dev/references/web-ui-quality.md +83 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/worktree-isolation/SKILL.md +179 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/worktree-isolation/agents/openai.yaml +4 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/worktree-isolation/references/shared-branch-rebase.md +25 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/worktree-isolation/scripts/AGENTS.md +23 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/worktree-isolation/scripts/test_worktree_status.sh +207 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/worktree-isolation/scripts/test_worktree_sweep.sh +481 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/worktree-isolation/scripts/worktree-status.sh +325 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/worktree-isolation/scripts/worktree-sweep.sh +245 -0
- package/dist/assets/release.json +2797 -0
- package/dist/claude-adapter.d.ts +9 -0
- package/dist/claude-adapter.js +240 -0
- package/dist/cli-worker.d.ts +1 -0
- package/dist/cli-worker.js +32 -0
- package/dist/cli.d.ts +22 -0
- package/dist/cli.js +214 -0
- package/dist/codex-host.d.ts +30 -0
- package/dist/codex-host.js +162 -0
- package/dist/fs-safe.d.ts +21 -0
- package/dist/fs-safe.js +241 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/manifest.d.ts +8 -0
- package/dist/manifest.js +135 -0
- package/dist/opencode-adapter.d.ts +10 -0
- package/dist/opencode-adapter.js +416 -0
- package/dist/operations.d.ts +3 -0
- package/dist/operations.js +956 -0
- package/dist/paths.d.ts +20 -0
- package/dist/paths.js +4 -0
- package/dist/types.d.ts +58 -0
- package/dist/types.js +1 -0
- package/dist/unified.d.ts +4 -0
- package/dist/unified.js +64 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.js +5 -0
- package/package.json +35 -0
|
@@ -0,0 +1,902 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Deterministic behavior suite for hooks/guard-merge-authorization.sh.
|
|
3
|
+
# Self-contained: builds a throwaway repo (default-branch checkout `main` +
|
|
4
|
+
# a linked feature worktree) under mktemp, feeds constructed PreToolUse JSON
|
|
5
|
+
# to the guard, and asserts the deny set denies and the allow set passes.
|
|
6
|
+
# Registered in the Makefile `test` target; requires jq + git (the guard's
|
|
7
|
+
# own dependencies — when they are missing the guard degrades to allow, so
|
|
8
|
+
# this suite requires them and fails loudly instead of false-greening).
|
|
9
|
+
set -u
|
|
10
|
+
|
|
11
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
|
|
12
|
+
GUARD="${GUARD:-$SCRIPT_DIR/guard-merge-authorization.sh}"
|
|
13
|
+
[ -f "$GUARD" ] || { echo "FAIL: guard not found: $GUARD" >&2; exit 1; }
|
|
14
|
+
command -v jq >/dev/null 2>&1 || { echo "FAIL: jq required for this suite" >&2; exit 1; }
|
|
15
|
+
command -v git >/dev/null 2>&1 || { echo "FAIL: git required for this suite" >&2; exit 1; }
|
|
16
|
+
|
|
17
|
+
tmp="$(mktemp -d "${TMPDIR:-/tmp}/guard-merge-authz-test.XXXXXX")" || exit 1
|
|
18
|
+
trap 'rm -rf "$tmp"' EXIT
|
|
19
|
+
|
|
20
|
+
git -C "$tmp" init -qb main repo-main
|
|
21
|
+
GITC=(git -C "$tmp/repo-main" -c user.email=test@example.invalid -c user.name=test)
|
|
22
|
+
"${GITC[@]}" commit -q --allow-empty -m init
|
|
23
|
+
"${GITC[@]}" branch -q feature
|
|
24
|
+
"${GITC[@]}" worktree add -q "$tmp/wt-feature" feature
|
|
25
|
+
|
|
26
|
+
MAIN_CWD="$tmp/repo-main"
|
|
27
|
+
FEAT_CWD="$tmp/wt-feature"
|
|
28
|
+
|
|
29
|
+
# Second repo whose default branch is NOT main/master: trunk, with
|
|
30
|
+
# origin/HEAD resolvable (exercises the detected-default path, not the
|
|
31
|
+
# hardcoded main|master fallback).
|
|
32
|
+
git -C "$tmp" init -qb trunk repo-trunk
|
|
33
|
+
GITT=(git -C "$tmp/repo-trunk" -c user.email=test@example.invalid -c user.name=test)
|
|
34
|
+
"${GITT[@]}" commit -q --allow-empty -m init
|
|
35
|
+
"${GITT[@]}" branch -q feature
|
|
36
|
+
"${GITT[@]}" remote add origin "$tmp/repo-trunk" # any URL; never contacted
|
|
37
|
+
trunk_sha=$("${GITT[@]}" rev-parse trunk)
|
|
38
|
+
"${GITT[@]}" update-ref refs/remotes/origin/trunk "$trunk_sha"
|
|
39
|
+
"${GITT[@]}" symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/trunk
|
|
40
|
+
"${GITT[@]}" worktree add -q "$tmp/wt-trunk-feature" feature
|
|
41
|
+
TRUNK_CWD="$tmp/repo-trunk"
|
|
42
|
+
TRUNK_FEAT_CWD="$tmp/wt-trunk-feature"
|
|
43
|
+
|
|
44
|
+
# Third repo: origin remote EXISTS but origin/HEAD and init.defaultBranch are
|
|
45
|
+
# both unresolvable → the gate narrows to main|master and must WARN visibly.
|
|
46
|
+
git -C "$tmp" init -qb trunk repo-nohead
|
|
47
|
+
GITN=(git -C "$tmp/repo-nohead" -c user.email=test@example.invalid -c user.name=test)
|
|
48
|
+
"${GITN[@]}" commit -q --allow-empty -m init
|
|
49
|
+
"${GITN[@]}" remote add origin "$tmp/repo-nohead"
|
|
50
|
+
"${GITN[@]}" branch -q feature
|
|
51
|
+
"${GITN[@]}" worktree add -q "$tmp/wt-nohead-feature" feature
|
|
52
|
+
NOHEAD_FEAT_CWD="$tmp/wt-nohead-feature"
|
|
53
|
+
|
|
54
|
+
# Fourth repo: non-simple push.default configs that make a refspec-less
|
|
55
|
+
# push advance the default branch even from a feature branch.
|
|
56
|
+
git -C "$tmp" init -qb main repo-pd
|
|
57
|
+
GITP=(git -C "$tmp/repo-pd" -c user.email=test@example.invalid -c user.name=test)
|
|
58
|
+
"${GITP[@]}" commit -q --allow-empty -m init
|
|
59
|
+
"${GITP[@]}" branch -q feature
|
|
60
|
+
"${GITP[@]}" branch -q feature2
|
|
61
|
+
"${GITP[@]}" worktree add -q "$tmp/wt-pd-feature" feature
|
|
62
|
+
"${GITP[@]}" worktree add -q "$tmp/wt-pd-feature2" feature2
|
|
63
|
+
"${GITP[@]}" config branch.feature.merge refs/heads/main # misconfigured upstream
|
|
64
|
+
"${GITP[@]}" config branch.feature2.merge refs/heads/feature2
|
|
65
|
+
PD_FEAT_CWD="$tmp/wt-pd-feature"
|
|
66
|
+
PD_FEAT2_CWD="$tmp/wt-pd-feature2"
|
|
67
|
+
|
|
68
|
+
pass=0; fail=0
|
|
69
|
+
|
|
70
|
+
probe() { # probe <expect deny|allow> <cwd> <command>
|
|
71
|
+
local expect="$1" cwd="$2" cmd="$3" out got
|
|
72
|
+
out=$(jq -nc --arg c "$cmd" --arg w "$cwd" '{tool_input:{command:$c},cwd:$w}' | bash "$GUARD")
|
|
73
|
+
got="allow"
|
|
74
|
+
printf '%s' "$out" | grep -q '"permissionDecision":"deny"' && got="deny"
|
|
75
|
+
if [ "$got" = "$expect" ]; then
|
|
76
|
+
pass=$((pass+1))
|
|
77
|
+
else
|
|
78
|
+
fail=$((fail+1)); printf 'FAIL [want=%s got=%s @%s] %s\n' "$expect" "$got" "$(basename "$cwd")" "$cmd" >&2
|
|
79
|
+
fi
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
# --- DENY set: merge-executing / default-branch-advancing commands ---
|
|
83
|
+
probe deny "$FEAT_CWD" 'glab mr merge 123 --yes'
|
|
84
|
+
probe deny "$FEAT_CWD" 'glab mr merge 123 --squash --remove-source-branch'
|
|
85
|
+
probe deny "$FEAT_CWD" 'gh pr merge 45 --merge'
|
|
86
|
+
probe deny "$FEAT_CWD" 'gh pr merge https://github.com/o/r/pull/45 --squash'
|
|
87
|
+
probe deny "$FEAT_CWD" 'glab api --method PUT "projects/:id/merge_requests/123/merge" -f sha=abc'
|
|
88
|
+
probe deny "$FEAT_CWD" 'git push origin main'
|
|
89
|
+
probe deny "$FEAT_CWD" 'git push -u origin main'
|
|
90
|
+
probe deny "$FEAT_CWD" 'git push --force origin main'
|
|
91
|
+
probe deny "$FEAT_CWD" 'git push origin HEAD:main'
|
|
92
|
+
probe deny "$FEAT_CWD" 'git push origin feature:main'
|
|
93
|
+
probe deny "$FEAT_CWD" 'git push origin HEAD:refs/heads/main'
|
|
94
|
+
probe deny "$FEAT_CWD" 'git push origin refs/heads/main'
|
|
95
|
+
probe deny "$FEAT_CWD" 'git push origin +main'
|
|
96
|
+
probe deny "$FEAT_CWD" 'git push origin +HEAD:main'
|
|
97
|
+
probe deny "$FEAT_CWD" 'git push origin master'
|
|
98
|
+
probe deny "$MAIN_CWD" 'git push'
|
|
99
|
+
probe deny "$MAIN_CWD" 'git push origin HEAD'
|
|
100
|
+
probe deny "$MAIN_CWD" 'git merge feature'
|
|
101
|
+
probe deny "$MAIN_CWD" 'git merge --no-ff feature'
|
|
102
|
+
probe deny "$MAIN_CWD" 'git pull origin feature'
|
|
103
|
+
probe deny "$MAIN_CWD" 'git pull . feature'
|
|
104
|
+
probe deny "$MAIN_CWD" 'git pull --rebase origin feature'
|
|
105
|
+
probe deny "$FEAT_CWD" 'git commit -m "done" && git push origin main'
|
|
106
|
+
probe deny "$FEAT_CWD" 'cd somewhere; glab mr merge 7'
|
|
107
|
+
probe deny "$FEAT_CWD" 'env FOO=1 glab mr merge 9'
|
|
108
|
+
probe deny "$FEAT_CWD" 'timeout 30 glab mr merge 9'
|
|
109
|
+
probe deny "$FEAT_CWD" 'timeout -k 5 30 git push origin main'
|
|
110
|
+
probe deny "$FEAT_CWD" 'nice -n 10 gh pr merge 45 --merge'
|
|
111
|
+
probe deny "$FEAT_CWD" 'sudo -u deployer git push origin main'
|
|
112
|
+
probe deny "$FEAT_CWD" 'env -u PAGER FOO=1 glab mr merge 9'
|
|
113
|
+
probe deny "$FEAT_CWD" 'git push --all origin'
|
|
114
|
+
probe deny "$FEAT_CWD" 'git push --mirror origin'
|
|
115
|
+
probe deny "$FEAT_CWD" 'git push origin --all'
|
|
116
|
+
|
|
117
|
+
# --- detected-default path (default branch = trunk via origin/HEAD) ---
|
|
118
|
+
probe deny "$TRUNK_FEAT_CWD" 'git push origin trunk'
|
|
119
|
+
probe deny "$TRUNK_FEAT_CWD" 'git push origin HEAD:trunk'
|
|
120
|
+
probe deny "$TRUNK_FEAT_CWD" 'git push origin refs/heads/trunk'
|
|
121
|
+
probe deny "$TRUNK_CWD" 'git merge feature'
|
|
122
|
+
probe deny "$TRUNK_CWD" 'git push'
|
|
123
|
+
probe allow "$TRUNK_CWD" 'git merge --ff-only origin/trunk'
|
|
124
|
+
probe allow "$TRUNK_FEAT_CWD" 'git merge origin/trunk'
|
|
125
|
+
probe allow "$TRUNK_FEAT_CWD" 'git push origin feature'
|
|
126
|
+
# resolved default = trunk → a NON-default branch literally named main is
|
|
127
|
+
# ordinary delivery there, not the protected branch (no main|master union).
|
|
128
|
+
probe allow "$TRUNK_FEAT_CWD" 'git push origin main'
|
|
129
|
+
|
|
130
|
+
# --- global flags before subcommand / quoted single-word branch ---
|
|
131
|
+
probe deny "$FEAT_CWD" 'gh -R owner/repo pr merge 45 --squash'
|
|
132
|
+
probe deny "$FEAT_CWD" 'gh --repo owner/repo pr merge 45 --merge'
|
|
133
|
+
probe deny "$FEAT_CWD" 'glab --host gitlab.example.invalid mr merge 7'
|
|
134
|
+
probe deny "$FEAT_CWD" 'git push origin "main"'
|
|
135
|
+
probe deny "$FEAT_CWD" "git push origin 'main'"
|
|
136
|
+
probe deny "$FEAT_CWD" 'git push origin HEAD:"main"'
|
|
137
|
+
probe allow "$FEAT_CWD" 'gh -R owner/repo pr view 45'
|
|
138
|
+
|
|
139
|
+
# --- API merge spellings (both platforms) vs. legit API use ---
|
|
140
|
+
probe deny "$FEAT_CWD" 'gh api repos/owner/repo/pulls/123/merge --method PUT'
|
|
141
|
+
probe deny "$FEAT_CWD" 'gh api "repos/owner/repo/pulls/123/merge" -X PUT'
|
|
142
|
+
probe allow "$FEAT_CWD" 'gh api repos/owner/repo/pulls/123/comments'
|
|
143
|
+
probe allow "$FEAT_CWD" 'glab api "projects/:id/merge_requests/123/notes" -f body="see merge_requests/9/merge"'
|
|
144
|
+
probe allow "$FEAT_CWD" 'glab api projects/:id/merge_requests/9/notes -f note=see-merge_requests/9/merge'
|
|
145
|
+
|
|
146
|
+
# --- Raw HTTP merge REST calls share the platform authorization gate ---
|
|
147
|
+
probe deny "$FEAT_CWD" 'curl -X PUT https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
148
|
+
probe deny "$FEAT_CWD" 'wget --method=PUT https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
149
|
+
probe deny "$FEAT_CWD" 'curl --request PUT https://git.example.invalid/api/v3/repos/o/r/pulls/42/merge'
|
|
150
|
+
probe deny "$FEAT_CWD" 'curl -XPUT http://git.example.invalid/api/v4/projects/group%2Frepo/merge_requests/546/merge?sha=abc#result'
|
|
151
|
+
probe deny "$FEAT_CWD" 'curl --request=PUT HTTPS://GIT.EXAMPLE.INVALID/repos/o/r/pulls/42/merge/'
|
|
152
|
+
probe deny "$FEAT_CWD" 'curl -X PUT "https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge?sha=abc&should_remove_source_branch=true"'
|
|
153
|
+
probe deny "$FEAT_CWD" "curl --request PUT 'https://git.example.invalid/repos/o/r/pulls/42/merge?mode=fast&confirm=1'"
|
|
154
|
+
probe deny "$FEAT_CWD" 'curl -T payload.bin https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
155
|
+
probe deny "$FEAT_CWD" 'curl --upload-file payload.bin https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
156
|
+
probe deny "$FEAT_CWD" 'curl --upload-file=payload.bin https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
157
|
+
probe deny "$FEAT_CWD" 'wget --method PUT https://git.example.invalid/repos/o/r/pulls/42/merge'
|
|
158
|
+
probe deny "$FEAT_CWD" 'wget --method PUT -H https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
159
|
+
probe deny "$FEAT_CWD" 'wget --method PUT -d https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
160
|
+
probe deny "$FEAT_CWD" 'wget --method PUT -x https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
161
|
+
|
|
162
|
+
# Method, endpoint, and operand negative controls.
|
|
163
|
+
probe allow "$FEAT_CWD" 'curl https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
164
|
+
probe allow "$FEAT_CWD" 'curl --request POST https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
165
|
+
probe allow "$FEAT_CWD" 'curl --data x=1 https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
166
|
+
probe allow "$FEAT_CWD" 'curl -X POST -T payload.bin https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
167
|
+
probe allow "$FEAT_CWD" 'curl -T payload.bin -X POST https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
168
|
+
probe allow "$FEAT_CWD" 'curl -X PUT https://git.example.invalid/api/v4/projects/1/merge_requests/546/notes'
|
|
169
|
+
probe allow "$FEAT_CWD" 'curl -X PUT https://git.example.invalid/prefix/api/v4/projects/1/merge_requests/546/merge'
|
|
170
|
+
probe allow "$FEAT_CWD" 'curl -X PUT https://git.example.invalid/api/v4/projects/1/Merge_requests/546/merge'
|
|
171
|
+
probe allow "$FEAT_CWD" 'curl -X PUT https://git.example.invalid/api/v4/projects//merge_requests/546/merge'
|
|
172
|
+
probe allow "$FEAT_CWD" 'curl -X PUT https://git.example.invalid/api/v4/projects/1/merge_requests/0/merge'
|
|
173
|
+
probe allow "$FEAT_CWD" 'curl -X PUT https://git.example.invalid/api/v4/projects/1/merge_requests/546/%6derge'
|
|
174
|
+
probe allow "$FEAT_CWD" 'curl -X PUT https://:443/api/v4/projects/1/merge_requests/546/merge'
|
|
175
|
+
probe allow "$FEAT_CWD" 'curl -X PUT https://git.example.invalid/ordinary -H https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
176
|
+
probe allow "$FEAT_CWD" 'curl -X PUT https://git.example.invalid/ordinary -H "https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge?x=1&y=2"'
|
|
177
|
+
probe allow "$FEAT_CWD" 'curl -X PUT https://git.example.invalid/ordinary --data https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
178
|
+
probe allow "$FEAT_CWD" 'curl -X PUT https://git.example.invalid/ordinary -o https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
179
|
+
probe allow "$FEAT_CWD" 'curl -X PUT --referer https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge https://git.example.invalid/ordinary'
|
|
180
|
+
probe allow "$FEAT_CWD" 'curl -X PUT --doh-url https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge https://git.example.invalid/ordinary'
|
|
181
|
+
probe allow "$FEAT_CWD" 'curl -X PUT --proxy https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge https://git.example.invalid/ordinary'
|
|
182
|
+
probe allow "$FEAT_CWD" 'curl -X PUT --user-agent https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge https://git.example.invalid/ordinary'
|
|
183
|
+
probe allow "$FEAT_CWD" 'wget --method PUT https://git.example.invalid/ordinary --header https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
184
|
+
probe allow "$FEAT_CWD" 'wget --method PUT https://git.example.invalid/ordinary --body-data https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
185
|
+
probe allow "$FEAT_CWD" 'wget --method PUT https://git.example.invalid/ordinary -O https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
186
|
+
probe allow "$FEAT_CWD" 'curl --method PUT https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
187
|
+
probe allow "$FEAT_CWD" 'wget -X PUT https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
188
|
+
probe allow "$FEAT_CWD" 'wget -T 30 https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
189
|
+
probe allow "$FEAT_CWD" 'echo curl -X PUT https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
190
|
+
probe allow "$FEAT_CWD" "printf '%s' 'curl -X PUT https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'"
|
|
191
|
+
probe allow "$FEAT_CWD" 'true # curl -X PUT https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
192
|
+
|
|
193
|
+
# Existing segment normalization, wrappers, and redirection handling apply to
|
|
194
|
+
# raw HTTP clients without creating a parallel tokenizer.
|
|
195
|
+
probe deny "$FEAT_CWD" 'env FOO=1 curl -X PUT https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
196
|
+
probe deny "$FEAT_CWD" 'timeout 30 wget --method=PUT https://git.example.invalid/repos/o/r/pulls/42/merge'
|
|
197
|
+
probe deny "$FEAT_CWD" '/usr/bin/curl --request PUT https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
198
|
+
probe deny "$FEAT_CWD" 'curl -X PUT https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge 2>/dev/null | jq .'
|
|
199
|
+
probe deny "$FEAT_CWD" 'echo before && curl -X PUT https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge && echo after'
|
|
200
|
+
|
|
201
|
+
# Multiple URL operands share one transfer method; repeated curl request options
|
|
202
|
+
# use the last value, while ambiguous transfer boundaries still deny.
|
|
203
|
+
probe deny "$FEAT_CWD" 'curl -X PUT https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge https://git.example.invalid/ordinary'
|
|
204
|
+
probe deny "$FEAT_CWD" 'curl -X PUT --url https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
205
|
+
probe deny "$FEAT_CWD" 'curl -X PUT --url=https://git.example.invalid/repos/o/r/pulls/42/merge'
|
|
206
|
+
probe allow "$FEAT_CWD" 'curl -X PUT -X POST https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
207
|
+
probe deny "$FEAT_CWD" 'curl -X POST --request PUT https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
208
|
+
probe deny "$FEAT_CWD" 'curl -X PUT https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge --next https://git.example.invalid/ordinary'
|
|
209
|
+
|
|
210
|
+
# Deliberate-circumvention boundaries stay visible and allowed; the detector
|
|
211
|
+
# handles routine direct argv spellings, not a shell interpreter or curl config.
|
|
212
|
+
# shellcheck disable=SC2016 # literal $U is the behavior under test
|
|
213
|
+
probe allow "$FEAT_CWD" 'U=https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge; curl -X PUT "$U"'
|
|
214
|
+
probe allow "$FEAT_CWD" 'curl --config merge-request.conf'
|
|
215
|
+
probe allow "$FEAT_CWD" 'wget --config=merge-request.conf'
|
|
216
|
+
probe allow "$FEAT_CWD" "eval 'curl -X PUT https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'"
|
|
217
|
+
probe allow "$FEAT_CWD" "bash -c 'curl -X PUT https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'"
|
|
218
|
+
probe allow "$FEAT_CWD" "printf '%s' https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge | xargs curl -X PUT"
|
|
219
|
+
|
|
220
|
+
# --- git -C redirection: the acted-on repo decides, not the hook cwd ---
|
|
221
|
+
probe deny "$FEAT_CWD" "git -C $MAIN_CWD merge feature"
|
|
222
|
+
probe deny "$FEAT_CWD" "git -C $MAIN_CWD push"
|
|
223
|
+
probe allow "$MAIN_CWD" "git -C $FEAT_CWD push"
|
|
224
|
+
probe allow "$MAIN_CWD" "git -C $FEAT_CWD merge origin/main"
|
|
225
|
+
|
|
226
|
+
# --- path-prefixed / backslash-escaped command words ---
|
|
227
|
+
probe deny "$FEAT_CWD" '/usr/bin/git push origin main'
|
|
228
|
+
probe deny "$FEAT_CWD" '\git push origin main'
|
|
229
|
+
probe deny "$FEAT_CWD" '/opt/homebrew/bin/glab mr merge 3'
|
|
230
|
+
probe allow "$FEAT_CWD" '/usr/bin/git push origin feature'
|
|
231
|
+
|
|
232
|
+
# --- GraphQL merge mutations via api subcommand ---
|
|
233
|
+
probe deny "$FEAT_CWD" "gh api graphql -f query='mutation { mergePullRequest(input: {pullRequestId: \"x\"}) { pullRequest { merged } } }'"
|
|
234
|
+
probe deny "$FEAT_CWD" "gh api graphql -f query='mutation { enablePullRequestAutoMerge(input: {pullRequestId: \"x\"}) { pullRequest { id } } }'"
|
|
235
|
+
probe deny "$FEAT_CWD" "glab api graphql -f query='mutation { mergeRequestAccept(input: {projectPath: \"a/b\", iid: \"1\"}) { mergeRequest { mergedAt } } }'"
|
|
236
|
+
probe allow "$FEAT_CWD" "gh api graphql -f query='query { repository(owner: \"o\", name: \"r\") { pullRequest(number: 1) { title } } }'"
|
|
237
|
+
probe allow "$FEAT_CWD" "git commit -m 'add mergePullRequest helper' && gh api graphql -f query='query { viewer { login } }'"
|
|
238
|
+
|
|
239
|
+
# --- no-origin local repo: narrow fallback (dev/trunk are pushable) ---
|
|
240
|
+
probe allow "$FEAT_CWD" 'git push origin develop'
|
|
241
|
+
probe allow "$FEAT_CWD" 'git push origin trunk'
|
|
242
|
+
|
|
243
|
+
# --- cd / checkout / switch tracked across segments ---
|
|
244
|
+
probe deny "$FEAT_CWD" "cd $MAIN_CWD && git push"
|
|
245
|
+
probe deny "$FEAT_CWD" "cd ../repo-main && git merge feature"
|
|
246
|
+
probe deny "$FEAT_CWD" 'git checkout main && git merge feature'
|
|
247
|
+
probe deny "$FEAT_CWD" 'git switch main && git push origin HEAD'
|
|
248
|
+
probe deny "$MAIN_CWD" 'git checkout -b hotfix main && git checkout main && git merge hotfix'
|
|
249
|
+
probe allow "$MAIN_CWD" "cd $FEAT_CWD && git push"
|
|
250
|
+
probe allow "$MAIN_CWD" 'git checkout feature && git push origin HEAD'
|
|
251
|
+
probe allow "$FEAT_CWD" 'git checkout -b new-feature && git push -u origin new-feature'
|
|
252
|
+
probe allow "$FEAT_CWD" 'git checkout -- README.md && git push origin feature'
|
|
253
|
+
probe deny "$FEAT_CWD" "pushd $MAIN_CWD && git push"
|
|
254
|
+
probe deny "$MAIN_CWD" "pushd $FEAT_CWD && popd && git push"
|
|
255
|
+
probe allow "$MAIN_CWD" "pushd $FEAT_CWD && git push"
|
|
256
|
+
probe deny "$MAIN_CWD" "cd $FEAT_CWD && cd - && git push"
|
|
257
|
+
probe allow "$FEAT_CWD" "cd $MAIN_CWD && cd - && git push"
|
|
258
|
+
|
|
259
|
+
# --- non-simple push.default: refspec-less push from a feature branch ---
|
|
260
|
+
git -C "$PD_FEAT_CWD" config push.default matching
|
|
261
|
+
probe deny "$PD_FEAT_CWD" 'git push'
|
|
262
|
+
probe allow "$PD_FEAT_CWD" 'git push origin feature'
|
|
263
|
+
git -C "$PD_FEAT_CWD" config push.default upstream
|
|
264
|
+
probe deny "$PD_FEAT_CWD" 'git push' # upstream -> refs/heads/main
|
|
265
|
+
probe allow "$PD_FEAT2_CWD" 'git push' # upstream -> its own branch
|
|
266
|
+
git -C "$PD_FEAT_CWD" config push.default simple
|
|
267
|
+
probe allow "$PD_FEAT_CWD" 'git push'
|
|
268
|
+
|
|
269
|
+
# --- ALLOW set: routine delivery actions that must not false-positive ---
|
|
270
|
+
probe allow "$FEAT_CWD" 'git push origin fix/merge-authorization-gate'
|
|
271
|
+
probe allow "$FEAT_CWD" 'git push -u origin feature'
|
|
272
|
+
probe allow "$FEAT_CWD" 'git push'
|
|
273
|
+
probe allow "$FEAT_CWD" 'git push origin HEAD'
|
|
274
|
+
probe allow "$FEAT_CWD" 'git merge origin/main'
|
|
275
|
+
probe allow "$FEAT_CWD" 'git merge main'
|
|
276
|
+
probe allow "$FEAT_CWD" 'git rebase origin/main'
|
|
277
|
+
probe allow "$MAIN_CWD" 'git merge --ff-only origin/main'
|
|
278
|
+
probe allow "$MAIN_CWD" 'git pull'
|
|
279
|
+
probe allow "$MAIN_CWD" 'git pull origin main'
|
|
280
|
+
probe allow "$MAIN_CWD" 'git pull --ff-only origin main'
|
|
281
|
+
probe allow "$FEAT_CWD" 'git pull origin main'
|
|
282
|
+
probe allow "$MAIN_CWD" 'git status && git log --oneline -5'
|
|
283
|
+
|
|
284
|
+
# --- redirection tokens: the arg walk must not miscount a redirection ---
|
|
285
|
+
# The real defect: 'git pull --ff-only origin main 2>&1 | tail -1' denied,
|
|
286
|
+
# because the '&' segment split left '2>' as a bogus third refspec arg.
|
|
287
|
+
# allow (fixed): routine stderr/stdout plumbing around the designed sync forms
|
|
288
|
+
probe allow "$MAIN_CWD" 'git pull --ff-only origin main 2>&1 | tail -1'
|
|
289
|
+
probe allow "$MAIN_CWD" 'git pull origin main 2>/dev/null'
|
|
290
|
+
probe allow "$MAIN_CWD" 'git pull --ff-only origin main >/tmp/pull.log 2>&1'
|
|
291
|
+
probe allow "$MAIN_CWD" 'git merge --ff-only origin/main 2>&1'
|
|
292
|
+
probe allow "$TRUNK_CWD" 'git pull --ff-only origin trunk 2>&1'
|
|
293
|
+
probe allow "$FEAT_CWD" 'git pull origin feature 2>&1'
|
|
294
|
+
probe allow "$MAIN_CWD" 'git pull --ff-only origin main >|/tmp/log'
|
|
295
|
+
probe allow "$FEAT_CWD" 'git push origin feature 2>&1'
|
|
296
|
+
# '>|' clobber contains a '|' that the segment split would tear; normalized to
|
|
297
|
+
# '>' first, so the sync flags are not stranded and a real advancement is not lost
|
|
298
|
+
probe allow "$MAIN_CWD" 'git merge>|/tmp/gx --ff-only origin/main'
|
|
299
|
+
probe allow "$MAIN_CWD" 'git merge --ff-only origin/main >|/tmp/gx'
|
|
300
|
+
probe deny "$FEAT_CWD" 'git push origin main >|/tmp/gx'
|
|
301
|
+
probe deny "$FEAT_CWD" 'git push origin main>|/tmp/gx'
|
|
302
|
+
# deny preserved: redirection plumbing never launders a real advancement
|
|
303
|
+
probe deny "$MAIN_CWD" 'git pull origin feature 2>&1'
|
|
304
|
+
probe deny "$MAIN_CWD" 'git pull --rebase origin feature 2>/dev/null'
|
|
305
|
+
probe deny "$MAIN_CWD" 'git merge feature 2>&1'
|
|
306
|
+
probe deny "$FEAT_CWD" 'git push origin main 2>&1 | tail -1'
|
|
307
|
+
probe deny "$FEAT_CWD" 'glab mr merge 123 --yes 2>&1'
|
|
308
|
+
# deny preserved: an OPERATOR-led redirection PREFIX (no fd digit) still exposes
|
|
309
|
+
# the command word — such tokens are unambiguous redirections, dropped anywhere
|
|
310
|
+
probe deny "$MAIN_CWD" '>/tmp/log git push origin main'
|
|
311
|
+
probe deny "$FEAT_CWD" '>/tmp/log git push origin main'
|
|
312
|
+
probe deny "$MAIN_CWD" '>>/tmp/log git merge feature'
|
|
313
|
+
# deny preserved: a QUOTED branch name that merely looks like a redirection
|
|
314
|
+
# is an argument, not shell plumbing — masking keeps it as a counted arg
|
|
315
|
+
probe deny "$MAIN_CWD" "git pull origin '2>evil'"
|
|
316
|
+
probe deny "$MAIN_CWD" 'git merge "2>evil"'
|
|
317
|
+
# deny preserved: an escaped/attached redirection keeps 'main' a visible arg,
|
|
318
|
+
# so a real advancement is not laundered
|
|
319
|
+
probe deny "$MAIN_CWD" 'git push origin feature\> main'
|
|
320
|
+
probe deny "$FEAT_CWD" 'git push origin main >/tmp/foo\ bar'
|
|
321
|
+
probe deny "$MAIN_CWD" 'git merge feature>/tmp/log'
|
|
322
|
+
# deny (fixed): a redirection glued directly onto the default refspec must keep
|
|
323
|
+
# 'main'/'HEAD:main' visible — 'main>/log' splits to 'main', not a phantom
|
|
324
|
+
# non-default refspec. This also un-false-denies the attached SYNC form.
|
|
325
|
+
probe deny "$FEAT_CWD" 'git push origin main>/tmp/log'
|
|
326
|
+
probe deny "$FEAT_CWD" 'git push origin main>>/tmp/log'
|
|
327
|
+
probe deny "$FEAT_CWD" 'git push origin HEAD:main>/tmp/log'
|
|
328
|
+
probe allow "$MAIN_CWD" 'git pull --ff-only origin main>/tmp/log'
|
|
329
|
+
# no under-block regression: a quoted single/multi-digit wrapper operand is NOT
|
|
330
|
+
# an fd — a digit-led redirect before the tool word is kept so the wrapper walk
|
|
331
|
+
# still consumes the duration and reaches git
|
|
332
|
+
probe deny "$FEAT_CWD" "timeout '5'>/dev/null git push origin main"
|
|
333
|
+
probe deny "$FEAT_CWD" "timeout '30'>/dev/null git push origin main"
|
|
334
|
+
probe deny "$FEAT_CWD" "nice -n '5'>/dev/null git push origin main"
|
|
335
|
+
probe deny "$FEAT_CWD" 'timeout 5 git push origin main'
|
|
336
|
+
# allow preserved: digit-led fd plumbing AFTER the tool word is still stripped,
|
|
337
|
+
# incl. multi-digit fds
|
|
338
|
+
probe allow "$MAIN_CWD" 'git pull origin main 2>/dev/null'
|
|
339
|
+
probe allow "$MAIN_CWD" 'git pull --ff-only origin main 10>/tmp/log'
|
|
340
|
+
# deny preserved: an INPUT redirect (`<in`) never launders a real advancement —
|
|
341
|
+
# ground-truth: bash still runs `git push origin main`, stdin is unrelated
|
|
342
|
+
probe deny "$FEAT_CWD" 'git push origin main <in'
|
|
343
|
+
probe deny "$FEAT_CWD" 'git push origin main <in 2>&1'
|
|
344
|
+
# no false-deny: a digit-suffixed branch is NOT an fd; the redirect attaches
|
|
345
|
+
# to 'main2'/'release10' (not the default branch), so the push is allowed
|
|
346
|
+
probe allow "$FEAT_CWD" 'git push origin main2>/tmp/log'
|
|
347
|
+
probe allow "$FEAT_CWD" 'git push origin main2>/dev/null'
|
|
348
|
+
probe allow "$FEAT_CWD" 'git push origin release10>/tmp/log'
|
|
349
|
+
probe allow "$FEAT_CWD" 'git push origin feature>/tmp/log'
|
|
350
|
+
# KNOWN best-effort gaps (documented; footgun reminder, not an adversarial
|
|
351
|
+
# boundary — see the guard header). Pinned so a future change that DOES start
|
|
352
|
+
# catching them is a visible, intentional upgrade rather than a surprise.
|
|
353
|
+
probe allow "$FEAT_CWD" '2>&1 git push origin main' # fd-dup before refspec (&-split)
|
|
354
|
+
probe allow "$FEAT_CWD" 'git push 2>&1 origin main' # fd-dup before refspec (&-split)
|
|
355
|
+
probe allow "$FEAT_CWD" 'git push 1>&2 origin main' # fd-dup before refspec (&-split)
|
|
356
|
+
probe allow "$FEAT_CWD" '2>/dev/null git merge feature' # digit-led prefix
|
|
357
|
+
probe allow "$FEAT_CWD" '10>/tmp/log git push origin main' # multi-digit fd prefix
|
|
358
|
+
probe allow "$MAIN_CWD" '>/tmp/foo\ bar git push origin main' # escaped-space prefix
|
|
359
|
+
# and the counterpart that IS caught: fd-dup AFTER the complete refspec
|
|
360
|
+
probe deny "$FEAT_CWD" 'git push origin main 2>&1' # refspec intact before &-split
|
|
361
|
+
probe allow "$FEAT_CWD" 'glab mr create --title "x" --description "y"'
|
|
362
|
+
probe allow "$FEAT_CWD" 'glab mr view 123'
|
|
363
|
+
probe allow "$FEAT_CWD" 'glab api "projects/:id/merge_requests/123/notes" -f body=hi'
|
|
364
|
+
probe allow "$FEAT_CWD" 'gh pr create --fill'
|
|
365
|
+
probe allow "$FEAT_CWD" 'gh pr view 45'
|
|
366
|
+
probe allow "$FEAT_CWD" 'git commit -m "revert glab mr merge guard"'
|
|
367
|
+
probe allow "$FEAT_CWD" 'echo "git push origin main"'
|
|
368
|
+
probe allow "$FEAT_CWD" 'git push origin --delete old-feature'
|
|
369
|
+
probe allow "$FEAT_CWD" 'git push origin main-backup'
|
|
370
|
+
probe allow "$FEAT_CWD" 'git fetch origin main'
|
|
371
|
+
|
|
372
|
+
# --- unresolvable default branch: allow stands, but degrade must be VISIBLE ---
|
|
373
|
+
out=$(jq -nc --arg c 'git push origin release-x' --arg w "$NOHEAD_FEAT_CWD" '{tool_input:{command:$c},cwd:$w}' | bash "$GUARD")
|
|
374
|
+
if printf '%s' "$out" | grep -q '"permissionDecision":"deny"'; then
|
|
375
|
+
fail=$((fail+1)); echo "FAIL nohead: push release-x unexpectedly denied (documented narrowing should allow)" >&2
|
|
376
|
+
elif printf '%s' "$out" | grep -q 'merge-authorization guard'; then
|
|
377
|
+
pass=$((pass+1))
|
|
378
|
+
else
|
|
379
|
+
fail=$((fail+1)); echo "FAIL nohead: expected visible degrade warning, got: $out" >&2
|
|
380
|
+
fi
|
|
381
|
+
# fallback union gates the COMMON default names when unresolved
|
|
382
|
+
probe deny "$NOHEAD_FEAT_CWD" 'git push origin main'
|
|
383
|
+
probe deny "$NOHEAD_FEAT_CWD" 'git push origin trunk'
|
|
384
|
+
probe deny "$NOHEAD_FEAT_CWD" 'git push origin develop'
|
|
385
|
+
probe deny "$NOHEAD_FEAT_CWD" 'git push origin dev'
|
|
386
|
+
# non-push/merge commands must stay quiet (no warning noise)
|
|
387
|
+
out=$(jq -nc --arg c 'git status' --arg w "$NOHEAD_FEAT_CWD" '{tool_input:{command:$c},cwd:$w}' | bash "$GUARD")
|
|
388
|
+
if [ -z "$out" ]; then pass=$((pass+1)); else fail=$((fail+1)); echo "FAIL nohead: git status should be silent, got: $out" >&2; fi
|
|
389
|
+
|
|
390
|
+
# --- DECLARED OUT-OF-SCOPE (documentation probes, not coverage claims) ---
|
|
391
|
+
# The guard does not evaluate shell expansion/substitution or heredoc
|
|
392
|
+
# bodies (see the guard header). These probes PIN the current allow
|
|
393
|
+
# behavior so a future refactor that starts denying them (over-block) or a
|
|
394
|
+
# doc change that silently promises coverage gets a failing, reviewable
|
|
395
|
+
# signal here. The prose layer (bootstrap + worktree-isolation) is the
|
|
396
|
+
# covering control for these spellings.
|
|
397
|
+
probe allow "$FEAT_CWD" 'D=main; git push origin $D'
|
|
398
|
+
probe allow "$FEAT_CWD" 'git push origin $(get-target-branch)'
|
|
399
|
+
|
|
400
|
+
# --- Release valve: user-directive one-shot sentinel (spec 007) ---
|
|
401
|
+
# The UserPromptSubmit hook arms a session-scoped sentinel; the guard
|
|
402
|
+
# consumes it (one-shot) and allows PLATFORM merge shapes only. These
|
|
403
|
+
# probes pin: consume-on-allow, no release for DENY_GIT shapes, compound
|
|
404
|
+
# poisoning, session scoping, staleness, and missing-session fail-closed.
|
|
405
|
+
VSID="sess-valve-test"
|
|
406
|
+
VAUTH_DIR="$tmp/ccl-skills-merge-auth-$(id -u)"
|
|
407
|
+
varm() { # varm [sid] [bound-mr-number]
|
|
408
|
+
mkdir -p "$VAUTH_DIR"; chmod 700 "$VAUTH_DIR"
|
|
409
|
+
printf "armed${2:+ $2}\n" >"$VAUTH_DIR/${1-$VSID}"
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
probe_sid() { # probe_sid <expect deny|allow> <cwd> <sid> <command>
|
|
413
|
+
local expect="$1" cwd="$2" sid="$3" cmd="$4" out got
|
|
414
|
+
out=$(jq -nc --arg c "$cmd" --arg w "$cwd" --arg s "$sid" \
|
|
415
|
+
'{tool_input:{command:$c},cwd:$w,session_id:$s}' | TMPDIR="$tmp" bash "$GUARD")
|
|
416
|
+
got="allow"
|
|
417
|
+
printf '%s' "$out" | grep -q '"permissionDecision":"deny"' && got="deny"
|
|
418
|
+
if [ "$got" = "$expect" ]; then
|
|
419
|
+
pass=$((pass+1))
|
|
420
|
+
else
|
|
421
|
+
fail=$((fail+1)); printf 'FAIL [valve want=%s got=%s] %s\n' "$expect" "$got" "$cmd" >&2
|
|
422
|
+
fi
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
sentinel_state() { # sentinel_state <present|absent> <label>
|
|
426
|
+
local want="$1" label="$2"
|
|
427
|
+
if { [ "$want" = present ] && [ -f "$VAUTH_DIR/$VSID" ]; } \
|
|
428
|
+
|| { [ "$want" = absent ] && [ ! -f "$VAUTH_DIR/$VSID" ]; }; then
|
|
429
|
+
pass=$((pass+1))
|
|
430
|
+
else
|
|
431
|
+
fail=$((fail+1)); printf 'FAIL [sentinel want=%s] %s\n' "$want" "$label" >&2
|
|
432
|
+
fi
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
http_release_consumes() { # http_release_consumes <label> <command>
|
|
436
|
+
local label="$1" cmd="$2"
|
|
437
|
+
varm
|
|
438
|
+
probe_sid allow "$FEAT_CWD" "$VSID" "$cmd"
|
|
439
|
+
sentinel_state absent "$label"
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
# armed -> platform merge (immediate spelling) allowed, sentinel consumed,
|
|
443
|
+
# second attempt denied
|
|
444
|
+
varm
|
|
445
|
+
probe_sid allow "$FEAT_CWD" "$VSID" 'glab mr merge 546 --auto-merge=false --yes'
|
|
446
|
+
sentinel_state absent 'consumed after allow'
|
|
447
|
+
probe_sid deny "$FEAT_CWD" "$VSID" 'glab mr merge 546 --auto-merge=false --yes'
|
|
448
|
+
|
|
449
|
+
# armed -> merge REST API + gh pr merge also released (consumed each time)
|
|
450
|
+
varm
|
|
451
|
+
probe_sid allow "$FEAT_CWD" "$VSID" 'glab api projects/:id/merge_requests/546/merge -X PUT -f should_remove_source_branch=false'
|
|
452
|
+
sentinel_state absent 'consumed after api allow'
|
|
453
|
+
varm
|
|
454
|
+
probe_sid allow "$FEAT_CWD" "$VSID" 'gh pr merge 42 --squash'
|
|
455
|
+
sentinel_state absent 'consumed after gh allow'
|
|
456
|
+
|
|
457
|
+
# Every supported raw-HTTP PUT spelling is releasable by the same one-shot
|
|
458
|
+
# valve and consumes exactly one grant.
|
|
459
|
+
http_release_consumes 'curl -X PUT consumed' 'curl -X PUT https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
460
|
+
http_release_consumes 'curl -XPUT consumed' 'curl -XPUT https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
461
|
+
http_release_consumes 'curl --request PUT consumed' 'curl --request PUT https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
462
|
+
http_release_consumes 'curl --request=PUT consumed' 'curl --request=PUT http://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
463
|
+
http_release_consumes 'curl --silent consumed' 'curl -X PUT --silent https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
464
|
+
http_release_consumes 'curl -T consumed' 'curl -T payload.bin https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
465
|
+
http_release_consumes 'curl --upload-file consumed' 'curl --upload-file payload.bin https://git.example.invalid/repos/o/r/pulls/42/merge'
|
|
466
|
+
http_release_consumes 'curl --upload-file= consumed' 'curl --upload-file=payload.bin https://git.example.invalid/api/v3/repos/o/r/pulls/42/merge'
|
|
467
|
+
http_release_consumes 'wget --method PUT consumed' 'wget --method PUT https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
468
|
+
http_release_consumes 'wget --method=PUT consumed' 'wget --method=PUT https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
469
|
+
http_release_consumes 'wget -H consumed' 'wget --method PUT -H https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
470
|
+
http_release_consumes 'wget -d consumed' 'wget --method PUT -d https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
471
|
+
http_release_consumes 'wget -x consumed' 'wget --method PUT -x https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
472
|
+
http_release_consumes 'one merge among multiple URL operands consumes once' 'curl -X PUT https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge https://git.example.invalid/ordinary'
|
|
473
|
+
|
|
474
|
+
# Non-merge HTTP traffic must not consume a grant.
|
|
475
|
+
varm
|
|
476
|
+
probe_sid allow "$FEAT_CWD" "$VSID" 'curl https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
477
|
+
sentinel_state present 'HTTP GET merge path must not consume'
|
|
478
|
+
probe_sid allow "$FEAT_CWD" "$VSID" 'curl -X PUT https://git.example.invalid/ordinary'
|
|
479
|
+
sentinel_state present 'unrelated HTTP PUT must not consume'
|
|
480
|
+
probe_sid allow "$FEAT_CWD" "$VSID" 'curl --request POST https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
481
|
+
sentinel_state present 'HTTP POST merge path must not consume'
|
|
482
|
+
probe_sid allow "$FEAT_CWD" "$VSID" 'curl -X PUT https://git.example.invalid/ordinary -H https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
483
|
+
sentinel_state present 'HTTP header URL must not consume'
|
|
484
|
+
probe_sid allow "$FEAT_CWD" "$VSID" 'curl -X PUT --doh-url https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge https://git.example.invalid/ordinary'
|
|
485
|
+
sentinel_state present 'curl DoH URL must not consume'
|
|
486
|
+
varm
|
|
487
|
+
probe_sid allow "$FEAT_CWD" "$VSID" 'curl -X PUT --proxy https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge https://git.example.invalid/ordinary'
|
|
488
|
+
sentinel_state present 'curl proxy URL must not consume'
|
|
489
|
+
varm
|
|
490
|
+
probe_sid allow "$FEAT_CWD" "$VSID" 'curl -X PUT --user-agent https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge https://git.example.invalid/ordinary'
|
|
491
|
+
sentinel_state present 'curl user-agent text must not consume'
|
|
492
|
+
rm -f "$VAUTH_DIR/$VSID"
|
|
493
|
+
|
|
494
|
+
# Ambiguous/multiple raw-HTTP shapes and a compound hard deny are never
|
|
495
|
+
# released and leave the grant intact.
|
|
496
|
+
varm
|
|
497
|
+
probe_sid deny "$FEAT_CWD" "$VSID" 'curl -X PUT --cacert https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge https://git.example.invalid/ordinary'
|
|
498
|
+
sentinel_state present 'unknown option association must not consume'
|
|
499
|
+
varm
|
|
500
|
+
probe_sid allow "$FEAT_CWD" "$VSID" 'curl -X PUT -X POST https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
501
|
+
sentinel_state present 'last curl method POST must not consume'
|
|
502
|
+
probe_sid allow "$FEAT_CWD" "$VSID" 'curl -X POST --request PUT https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
503
|
+
sentinel_state absent 'last curl method PUT consumed'
|
|
504
|
+
varm
|
|
505
|
+
probe_sid deny "$FEAT_CWD" "$VSID" 'curl -X PUT https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge --next https://git.example.invalid/ordinary'
|
|
506
|
+
sentinel_state present 'curl --next ambiguity must not consume'
|
|
507
|
+
probe_sid deny "$FEAT_CWD" "$VSID" 'curl -X PUT https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge https://git.example.invalid/api/v4/projects/1/merge_requests/547/merge'
|
|
508
|
+
sentinel_state present 'multiple HTTP merge URLs must not consume'
|
|
509
|
+
probe_sid deny "$FEAT_CWD" "$VSID" 'curl -X PUT https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge && git push origin main'
|
|
510
|
+
sentinel_state present 'HTTP merge plus DENY_GIT must not consume'
|
|
511
|
+
rm -f "$VAUTH_DIR/$VSID"
|
|
512
|
+
|
|
513
|
+
# Number-bound grants use the id extracted from raw HTTP URLs.
|
|
514
|
+
varm "$VSID" 546
|
|
515
|
+
probe_sid deny "$FEAT_CWD" "$VSID" 'curl -X PUT https://git.example.invalid/api/v4/projects/1/merge_requests/999/merge'
|
|
516
|
+
sentinel_state present 'HTTP target mismatch must not consume'
|
|
517
|
+
probe_sid allow "$FEAT_CWD" "$VSID" 'curl -X PUT https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
518
|
+
sentinel_state absent 'matching HTTP target consumed'
|
|
519
|
+
|
|
520
|
+
# armed -> DENY_GIT shapes are NEVER released and do not consume the grant
|
|
521
|
+
varm
|
|
522
|
+
probe_sid deny "$FEAT_CWD" "$VSID" 'git push origin main'
|
|
523
|
+
sentinel_state present 'git-push deny must not consume'
|
|
524
|
+
probe_sid deny "$FEAT_CWD" "$VSID" 'glab mr merge 546 && git push origin main'
|
|
525
|
+
sentinel_state present 'compound with DENY_GIT must not consume'
|
|
526
|
+
rm -f "$VAUTH_DIR/$VSID"
|
|
527
|
+
|
|
528
|
+
# no sentinel / other-session sentinel / stale sentinel -> deny (fail-closed)
|
|
529
|
+
probe_sid deny "$FEAT_CWD" "$VSID" 'glab mr merge 546'
|
|
530
|
+
varm other-session
|
|
531
|
+
probe_sid deny "$FEAT_CWD" "$VSID" 'glab mr merge 546'
|
|
532
|
+
probe_sid deny "$FEAT_CWD" "$VSID" 'curl -X PUT https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
533
|
+
if [ -f "$VAUTH_DIR/other-session" ]; then
|
|
534
|
+
pass=$((pass+1))
|
|
535
|
+
else
|
|
536
|
+
fail=$((fail+1)); echo 'FAIL wrong-session HTTP deny consumed another session grant' >&2
|
|
537
|
+
fi
|
|
538
|
+
rm -f "$VAUTH_DIR/other-session"
|
|
539
|
+
varm
|
|
540
|
+
old_ts=$(date -v-2H +%Y%m%d%H%M 2>/dev/null || date -d '-2 hours' +%Y%m%d%H%M)
|
|
541
|
+
touch -m -t "$old_ts" "$VAUTH_DIR/$VSID"
|
|
542
|
+
probe_sid deny "$FEAT_CWD" "$VSID" 'glab mr merge 546'
|
|
543
|
+
probe_sid deny "$FEAT_CWD" "$VSID" 'wget --method=PUT https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
544
|
+
rm -f "$VAUTH_DIR/$VSID"
|
|
545
|
+
|
|
546
|
+
# review round-1 findings: exactly-one-merge per grant; auto-merge/queued
|
|
547
|
+
# spellings are NEVER released (immediate-merge protocol), grant intact
|
|
548
|
+
varm
|
|
549
|
+
probe_sid deny "$FEAT_CWD" "$VSID" 'glab mr merge 1 && glab mr merge 2'
|
|
550
|
+
sentinel_state present 'multi-merge compound must not consume'
|
|
551
|
+
probe_sid deny "$FEAT_CWD" "$VSID" 'glab mr merge 546 --auto-merge'
|
|
552
|
+
sentinel_state present 'glab auto-merge must not be released nor consume'
|
|
553
|
+
probe_sid deny "$FEAT_CWD" "$VSID" 'gh pr merge 42 --auto --squash'
|
|
554
|
+
sentinel_state present 'gh --auto must not be released nor consume'
|
|
555
|
+
probe_sid deny "$FEAT_CWD" "$VSID" 'glab api projects/:id/merge_requests/546/merge -X PUT -f merge_when_pipeline_succeeds=true'
|
|
556
|
+
sentinel_state present 'REST merge_when_pipeline_succeeds must not be released'
|
|
557
|
+
probe_sid deny "$FEAT_CWD" "$VSID" "gh api graphql -f query='mutation { enablePullRequestAutoMerge(input:{pullRequestId:\"x\"}) }'"
|
|
558
|
+
sentinel_state present 'GraphQL auto-merge mutation must not be released'
|
|
559
|
+
# protocol-recommended immediate-merge spelling IS released
|
|
560
|
+
probe_sid allow "$FEAT_CWD" "$VSID" 'glab mr merge 546 --auto-merge=false --yes'
|
|
561
|
+
sentinel_state absent 'consumed after protocol spelling allow'
|
|
562
|
+
# a single GraphQL merge emits ONE verdict (REST+span double-count fixed)
|
|
563
|
+
varm
|
|
564
|
+
probe_sid allow "$FEAT_CWD" "$VSID" "glab api graphql -f query='mutation { mergeRequestAccept(input:{projectPath:\"g/p\",iid:\"546\"}) }'"
|
|
565
|
+
sentinel_state absent 'consumed after single graphql merge'
|
|
566
|
+
|
|
567
|
+
# challenge round-2: ambiguous spellings are NOT released (glab bare merge
|
|
568
|
+
# defaults to auto-merge while a pipeline runs; gh without an explicit
|
|
569
|
+
# strategy goes interactive/queue-dependent); --admin bypass never released;
|
|
570
|
+
# grant stays intact so the agent can rewrite and retry
|
|
571
|
+
varm
|
|
572
|
+
probe_sid deny "$FEAT_CWD" "$VSID" 'glab mr merge 546 --yes'
|
|
573
|
+
sentinel_state present 'bare glab merge (no --auto-merge=false) must not consume'
|
|
574
|
+
probe_sid deny "$FEAT_CWD" "$VSID" 'gh pr merge 42'
|
|
575
|
+
sentinel_state present 'gh merge without explicit strategy must not consume'
|
|
576
|
+
probe_sid deny "$FEAT_CWD" "$VSID" 'gh pr merge 42 --admin --merge'
|
|
577
|
+
sentinel_state present 'gh --admin bypass must not be released nor consume'
|
|
578
|
+
rm -f "$VAUTH_DIR/$VSID"
|
|
579
|
+
|
|
580
|
+
# challenge round-2: number-bound grant ("merge !546") releases ONLY that id
|
|
581
|
+
varm "$VSID" 546
|
|
582
|
+
probe_sid deny "$FEAT_CWD" "$VSID" 'glab mr merge 999 --auto-merge=false --yes'
|
|
583
|
+
sentinel_state present 'bound grant must not release a different MR'
|
|
584
|
+
probe_sid deny "$FEAT_CWD" "$VSID" "glab api graphql -f query='mutation { mergeRequestAccept(input:{projectPath:\"g/p\",iid:\"546\"}) }'"
|
|
585
|
+
sentinel_state present 'bound grant must not release an id-unresolvable merge'
|
|
586
|
+
probe_sid allow "$FEAT_CWD" "$VSID" 'glab mr merge 546 --auto-merge=false --yes'
|
|
587
|
+
sentinel_state absent 'bound grant consumed by the matching id'
|
|
588
|
+
varm "$VSID" 546
|
|
589
|
+
probe_sid allow "$FEAT_CWD" "$VSID" 'glab api projects/:id/merge_requests/546/merge -X PUT'
|
|
590
|
+
sentinel_state absent 'bound grant consumed by matching REST merge'
|
|
591
|
+
|
|
592
|
+
# challenge round-2: a GraphQL mutation string inside a NON-graphql REST body
|
|
593
|
+
# is not a merge — segment must not classify, grant must survive
|
|
594
|
+
varm
|
|
595
|
+
probe_sid allow "$FEAT_CWD" "$VSID" "gh api repos/o/r/issues -f body='mutation { mergePullRequest(input:{pullRequestId:\"x\"}) { pullRequest { merged } } }'"
|
|
596
|
+
sentinel_state present 'mutation text in non-graphql REST body must not consume'
|
|
597
|
+
rm -f "$VAUTH_DIR/$VSID"
|
|
598
|
+
|
|
599
|
+
# mktemp degrade path: unwritable TMPDIR -> visible degrade warning, no deny
|
|
600
|
+
out=$(jq -nc --arg c 'glab mr merge 546' --arg w "$FEAT_CWD" \
|
|
601
|
+
'{tool_input:{command:$c},cwd:$w}' | TMPDIR="$tmp/nonexistent-tmpdir" bash "$GUARD")
|
|
602
|
+
if printf '%s' "$out" | grep -q 'degraded: mktemp failed' \
|
|
603
|
+
&& ! printf '%s' "$out" | grep -q '"permissionDecision":"deny"'; then
|
|
604
|
+
pass=$((pass+1))
|
|
605
|
+
else
|
|
606
|
+
fail=$((fail+1)); echo "FAIL mktemp degrade must warn visibly and fail open, got: $out" >&2
|
|
607
|
+
fi
|
|
608
|
+
|
|
609
|
+
# final-review P2: a method-less (default GET) call to a merge REST endpoint
|
|
610
|
+
# must not burn the grant — deny without consuming until -X PUT is explicit
|
|
611
|
+
varm
|
|
612
|
+
probe_sid deny "$FEAT_CWD" "$VSID" 'glab api projects/:id/merge_requests/546/merge'
|
|
613
|
+
sentinel_state present 'GET-default REST merge call must not consume'
|
|
614
|
+
rm -f "$VAUTH_DIR/$VSID"
|
|
615
|
+
|
|
616
|
+
# host-compat: Claude Code (CLAUDECODE=1) gets permissionDecision:"allow"
|
|
617
|
+
# (no popup); other hosts (codex bridge rejects "allow") get advisory
|
|
618
|
+
# systemMessage ONLY — no permissionDecision at all. Both consume the grant.
|
|
619
|
+
varm
|
|
620
|
+
out=$(jq -nc --arg c 'glab mr merge 546 --auto-merge=false --yes' --arg w "$FEAT_CWD" --arg s "$VSID" --arg t "$HOME/.claude/projects/x/transcript.jsonl" \
|
|
621
|
+
'{tool_input:{command:$c},cwd:$w,session_id:$s,transcript_path:$t}' \
|
|
622
|
+
| TMPDIR="$tmp" CLAUDECODE=1 CODEX_THREAD_ID= CODEX_SANDBOX= CODEX_CI= CODEX_MANAGED_BY_NPM= CODEX_HOME= bash "$GUARD")
|
|
623
|
+
if printf '%s' "$out" | grep -q '"permissionDecision":"allow"'; then pass=$((pass+1)); else
|
|
624
|
+
fail=$((fail+1)); echo "FAIL full claude signals must emit permissionDecision allow, got: $out" >&2
|
|
625
|
+
fi
|
|
626
|
+
sentinel_state absent 'claude-host allow consumed'
|
|
627
|
+
# CLAUDECODE=1 + clean env but NO .claude transcript_path (a stripped-env
|
|
628
|
+
# codex-like bridge) -> advisory only: the positive input signal is required
|
|
629
|
+
varm
|
|
630
|
+
out=$(jq -nc --arg c 'glab mr merge 546 --auto-merge=false --yes' --arg w "$FEAT_CWD" --arg s "$VSID" \
|
|
631
|
+
'{tool_input:{command:$c},cwd:$w,session_id:$s}' \
|
|
632
|
+
| TMPDIR="$tmp" CLAUDECODE=1 CODEX_THREAD_ID= CODEX_SANDBOX= CODEX_CI= CODEX_MANAGED_BY_NPM= CODEX_HOME= bash "$GUARD")
|
|
633
|
+
if printf '%s' "$out" | grep -q 'systemMessage' && ! printf '%s' "$out" | grep -q 'permissionDecision'; then
|
|
634
|
+
pass=$((pass+1))
|
|
635
|
+
else
|
|
636
|
+
fail=$((fail+1)); echo "FAIL missing .claude transcript_path must emit advisory only, got: $out" >&2
|
|
637
|
+
fi
|
|
638
|
+
sentinel_state absent 'no-transcript advisory release still consumed'
|
|
639
|
+
# nested host: codex spawned from Claude inherits CLAUDECODE=1 but carries
|
|
640
|
+
# codex-positive signals -> advisory only (never the rejected allow field)
|
|
641
|
+
varm
|
|
642
|
+
out=$(jq -nc --arg c 'glab mr merge 546 --auto-merge=false --yes' --arg w "$FEAT_CWD" --arg s "$VSID" \
|
|
643
|
+
'{tool_input:{command:$c},cwd:$w,session_id:$s}' \
|
|
644
|
+
| TMPDIR="$tmp" CLAUDECODE=1 CODEX_THREAD_ID=t1 bash "$GUARD")
|
|
645
|
+
if printf '%s' "$out" | grep -q 'systemMessage' && ! printf '%s' "$out" | grep -q 'permissionDecision'; then
|
|
646
|
+
pass=$((pass+1))
|
|
647
|
+
else
|
|
648
|
+
fail=$((fail+1)); echo "FAIL nested codex host must emit advisory only, got: $out" >&2
|
|
649
|
+
fi
|
|
650
|
+
sentinel_state absent 'nested-host advisory release still consumed'
|
|
651
|
+
varm
|
|
652
|
+
out=$(jq -nc --arg c 'glab mr merge 546 --auto-merge=false --yes' --arg w "$FEAT_CWD" --arg s "$VSID" \
|
|
653
|
+
'{tool_input:{command:$c},cwd:$w,session_id:$s}' | TMPDIR="$tmp" CLAUDECODE= bash "$GUARD")
|
|
654
|
+
if printf '%s' "$out" | grep -q 'systemMessage' && ! printf '%s' "$out" | grep -q 'permissionDecision'; then
|
|
655
|
+
pass=$((pass+1))
|
|
656
|
+
else
|
|
657
|
+
fail=$((fail+1)); echo "FAIL non-claude host must emit systemMessage only, got: $out" >&2
|
|
658
|
+
fi
|
|
659
|
+
sentinel_state absent 'non-claude-host advisory release still consumed'
|
|
660
|
+
|
|
661
|
+
# challenge round-3: `glab mr accept` is the documented merge alias — same
|
|
662
|
+
# gate, same valve, same multi-merge accounting
|
|
663
|
+
probe deny "$FEAT_CWD" 'glab mr accept 546'
|
|
664
|
+
varm
|
|
665
|
+
probe_sid allow "$FEAT_CWD" "$VSID" 'glab mr accept 546 --auto-merge=false --yes'
|
|
666
|
+
sentinel_state absent 'accept alias consumed like merge'
|
|
667
|
+
varm
|
|
668
|
+
probe_sid deny "$FEAT_CWD" "$VSID" 'glab mr accept 1 --auto-merge=false --yes && glab mr merge 2 --auto-merge=false --yes'
|
|
669
|
+
sentinel_state present 'accept+merge compound counts as two merges'
|
|
670
|
+
rm -f "$VAUTH_DIR/$VSID"
|
|
671
|
+
|
|
672
|
+
# challenge round-3: inline config and repo retargeting count
|
|
673
|
+
probe deny "$FEAT_CWD" 'git -c push.default=matching push origin'
|
|
674
|
+
probe deny "$FEAT_CWD" "git --git-dir=$MAIN_CWD/.git merge feature"
|
|
675
|
+
probe deny "$FEAT_CWD" "git --work-tree=$MAIN_CWD --git-dir=$MAIN_CWD/.git merge feature"
|
|
676
|
+
|
|
677
|
+
# challenge round-3: a number-bound grant must not release an explicit
|
|
678
|
+
# cross-repo retarget (-R): 546 in another repo is a different MR
|
|
679
|
+
varm "$VSID" 546
|
|
680
|
+
probe_sid deny "$FEAT_CWD" "$VSID" 'glab mr merge 546 -R other/repo --auto-merge=false --yes'
|
|
681
|
+
sentinel_state present 'bound grant must not release -R retarget'
|
|
682
|
+
probe_sid deny "$FEAT_CWD" "$VSID" 'gh -R other/repo pr merge 546 --squash'
|
|
683
|
+
sentinel_state present 'bound grant must not release gh -R retarget'
|
|
684
|
+
# value-taking flags before the id must not corrupt id extraction
|
|
685
|
+
probe_sid allow "$FEAT_CWD" "$VSID" 'glab mr merge --sha abc123 546 --auto-merge=false --yes'
|
|
686
|
+
sentinel_state absent 'value flag before id still resolves the bound id'
|
|
687
|
+
varm
|
|
688
|
+
probe_sid allow "$FEAT_CWD" "$VSID" 'gh pr merge 42 --match-head-commit deadbeef --squash'
|
|
689
|
+
sentinel_state absent 'gh value flag before id still releases'
|
|
690
|
+
# DOCUMENTATION PROBE (residual, spec 007): an UNBOUND grant still releases
|
|
691
|
+
# an explicit -R retarget — the duty to target the discussed MR stays with
|
|
692
|
+
# the agent prose contract. Pins current behavior for reviewability.
|
|
693
|
+
varm
|
|
694
|
+
probe_sid allow "$FEAT_CWD" "$VSID" 'glab mr merge 546 -R other/repo --auto-merge=false --yes'
|
|
695
|
+
sentinel_state absent 'unbound grant + -R (pinned residual)'
|
|
696
|
+
|
|
697
|
+
# armed -> non-merge commands never touch the grant
|
|
698
|
+
varm
|
|
699
|
+
probe_sid allow "$FEAT_CWD" "$VSID" 'git status'
|
|
700
|
+
sentinel_state present 'non-merge command must not consume'
|
|
701
|
+
rm -f "$VAUTH_DIR/$VSID"
|
|
702
|
+
|
|
703
|
+
# no session_id in input (legacy probe path) stays hard-deny even when a
|
|
704
|
+
# sentinel file exists for some session
|
|
705
|
+
varm
|
|
706
|
+
probe deny "$FEAT_CWD" 'glab mr merge 546'
|
|
707
|
+
rm -f "$VAUTH_DIR/$VSID"
|
|
708
|
+
|
|
709
|
+
# --- Batch grant (spec 008): `armed batch N` — one unit per platform merge ---
|
|
710
|
+
varm_batch() { # varm_batch <count> [sid]
|
|
711
|
+
mkdir -p "$VAUTH_DIR"; chmod 700 "$VAUTH_DIR"
|
|
712
|
+
printf 'armed batch %s\n' "$1" >"$VAUTH_DIR/${2-$VSID}"
|
|
713
|
+
}
|
|
714
|
+
sentinel_content() { # sentinel_content <expected-first-line> <label>
|
|
715
|
+
local want="$1" label="$2" got
|
|
716
|
+
got=$(sed -n '1p' "$VAUTH_DIR/$VSID" 2>/dev/null || echo '<absent>')
|
|
717
|
+
if [ "$got" = "$want" ]; then pass=$((pass+1)); else
|
|
718
|
+
fail=$((fail+1)); printf 'FAIL [sentinel-content want=%s got=%s] %s\n' "$want" "$got" "$label" >&2
|
|
719
|
+
fi
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
# decrement chain: 3 -> 2 -> 1 -> consumed -> deny
|
|
723
|
+
varm_batch 3
|
|
724
|
+
probe_sid allow "$FEAT_CWD" "$VSID" 'glab mr merge 101 --auto-merge=false --yes'
|
|
725
|
+
sentinel_content 'armed batch 2' 'batch decrements to 2'
|
|
726
|
+
probe_sid allow "$FEAT_CWD" "$VSID" 'gh pr merge 202 --squash'
|
|
727
|
+
sentinel_content 'armed batch 1' 'batch decrements to 1'
|
|
728
|
+
probe_sid allow "$FEAT_CWD" "$VSID" 'glab api projects/:id/merge_requests/303/merge -X PUT'
|
|
729
|
+
sentinel_state absent 'last batch unit fully consumed'
|
|
730
|
+
probe_sid deny "$FEAT_CWD" "$VSID" 'glab mr merge 404 --auto-merge=false --yes'
|
|
731
|
+
|
|
732
|
+
# Raw HTTP merges consume the same batch counter one unit at a time.
|
|
733
|
+
varm_batch 2
|
|
734
|
+
probe_sid allow "$FEAT_CWD" "$VSID" 'curl -X PUT https://git.example.invalid/api/v4/projects/1/merge_requests/546/merge'
|
|
735
|
+
sentinel_content 'armed batch 1' 'HTTP merge decrements batch to 1'
|
|
736
|
+
probe_sid allow "$FEAT_CWD" "$VSID" 'wget --method=PUT https://git.example.invalid/repos/o/r/pulls/42/merge'
|
|
737
|
+
sentinel_state absent 'last batch unit consumed by HTTP merge'
|
|
738
|
+
|
|
739
|
+
# batch grant is UNBOUND: different repos/ids release (units still counted)
|
|
740
|
+
varm_batch 2
|
|
741
|
+
probe_sid allow "$FEAT_CWD" "$VSID" 'glab mr merge 546 -R other/repo --auto-merge=false --yes'
|
|
742
|
+
sentinel_content 'armed batch 1' 'batch unbound retarget consumed one unit'
|
|
743
|
+
rm -f "$VAUTH_DIR/$VSID"
|
|
744
|
+
|
|
745
|
+
# batch + bad spelling: deny WITHOUT consuming (agent rewrites and retries)
|
|
746
|
+
varm_batch 5
|
|
747
|
+
probe_sid deny "$FEAT_CWD" "$VSID" 'glab mr merge 546 --yes'
|
|
748
|
+
sentinel_content 'armed batch 5' 'bad spelling must not burn a batch unit'
|
|
749
|
+
# batch + DENY_GIT / auto-merge / multi-merge compound: never released, intact
|
|
750
|
+
probe_sid deny "$FEAT_CWD" "$VSID" 'git push origin main'
|
|
751
|
+
sentinel_content 'armed batch 5' 'DENY_GIT must not touch batch grant'
|
|
752
|
+
probe_sid deny "$FEAT_CWD" "$VSID" 'glab mr merge 546 --auto-merge'
|
|
753
|
+
sentinel_content 'armed batch 5' 'auto-merge never released under batch'
|
|
754
|
+
probe_sid deny "$FEAT_CWD" "$VSID" 'glab mr merge 1 --auto-merge=false --yes && glab mr merge 2 --auto-merge=false --yes'
|
|
755
|
+
sentinel_content 'armed batch 5' 'multi-merge compound denied under batch (split = one unit each)'
|
|
756
|
+
probe_sid deny "$FEAT_CWD" "$VSID" 'curl -X PUT https://git.example.invalid/api/v4/projects/1/merge_requests/1/merge https://git.example.invalid/api/v4/projects/1/merge_requests/2/merge'
|
|
757
|
+
sentinel_content 'armed batch 5' 'multi-HTTP merge denied without batch consumption'
|
|
758
|
+
probe_sid allow "$FEAT_CWD" "$VSID" 'curl -X PUT --request POST https://git.example.invalid/api/v4/projects/1/merge_requests/1/merge'
|
|
759
|
+
sentinel_content 'armed batch 5' 'last curl method POST leaves batch intact'
|
|
760
|
+
# non-merge commands never touch batch units
|
|
761
|
+
probe_sid allow "$FEAT_CWD" "$VSID" 'git push origin feature'
|
|
762
|
+
sentinel_content 'armed batch 5' 'non-merge command must not consume batch unit'
|
|
763
|
+
rm -f "$VAUTH_DIR/$VSID"
|
|
764
|
+
|
|
765
|
+
# batch TTL is 240 min anchored to arming: 3h-old grant still fresh,
|
|
766
|
+
# 5h-old grant stale (one-shot stays 60 min — 2h-old one-shot already denies
|
|
767
|
+
# above). Decrement must PRESERVE the arming mtime, not refresh it.
|
|
768
|
+
varm_batch 2
|
|
769
|
+
old_ts=$(date -v-3H +%Y%m%d%H%M 2>/dev/null || date -d '-3 hours' +%Y%m%d%H%M)
|
|
770
|
+
touch -m -t "$old_ts" "$VAUTH_DIR/$VSID"
|
|
771
|
+
probe_sid allow "$FEAT_CWD" "$VSID" 'glab mr merge 546 --auto-merge=false --yes'
|
|
772
|
+
sentinel_content 'armed batch 1' '3h-old batch grant still releases'
|
|
773
|
+
# mtime preserved through the decrement: file must still be ~3h old
|
|
774
|
+
if [ -z "$(find "$VAUTH_DIR/$VSID" -mmin -170 2>/dev/null)" ]; then pass=$((pass+1)); else
|
|
775
|
+
fail=$((fail+1)); echo 'FAIL batch decrement must preserve arming mtime (found fresher than 170min)' >&2
|
|
776
|
+
fi
|
|
777
|
+
rm -f "$VAUTH_DIR/$VSID"
|
|
778
|
+
varm_batch 9
|
|
779
|
+
old_ts=$(date -v-5H +%Y%m%d%H%M 2>/dev/null || date -d '-5 hours' +%Y%m%d%H%M)
|
|
780
|
+
touch -m -t "$old_ts" "$VAUTH_DIR/$VSID"
|
|
781
|
+
probe_sid deny "$FEAT_CWD" "$VSID" 'glab mr merge 546 --auto-merge=false --yes'
|
|
782
|
+
rm -f "$VAUTH_DIR/$VSID"
|
|
783
|
+
|
|
784
|
+
# malformed batch grants are NO grant (fail-closed): zero, junk, leading zero,
|
|
785
|
+
# >999
|
|
786
|
+
for bad in 0 abc 007 1000; do
|
|
787
|
+
varm_batch "$bad"
|
|
788
|
+
probe_sid deny "$FEAT_CWD" "$VSID" 'glab mr merge 546 --auto-merge=false --yes'
|
|
789
|
+
rm -f "$VAUTH_DIR/$VSID"
|
|
790
|
+
done
|
|
791
|
+
|
|
792
|
+
# challenge R2 P0: a GraphQL body with multiple aliased merge mutations must
|
|
793
|
+
# deny (multi) and NOT consume — one command must not execute several merges
|
|
794
|
+
varm_batch 5
|
|
795
|
+
probe_sid deny "$FEAT_CWD" "$VSID" "glab api graphql -f query='mutation { a: mergeRequestAccept(input:{projectPath:\"g/p\",iid:\"1\"}){x} b: mergeRequestAccept(input:{projectPath:\"g/p\",iid:\"2\"}){x} }'"
|
|
796
|
+
sentinel_content 'armed batch 5' 'multi-alias graphql merge denied, batch intact'
|
|
797
|
+
probe_sid deny "$FEAT_CWD" "$VSID" "gh api graphql -f query='mutation { a: mergePullRequest(input:{pullRequestId:\"x\"}){x} b: mergePullRequest(input:{pullRequestId:\"y\"}){x} }'"
|
|
798
|
+
sentinel_content 'armed batch 5' 'multi-alias gh graphql merge denied, batch intact'
|
|
799
|
+
rm -f "$VAUTH_DIR/$VSID"
|
|
800
|
+
|
|
801
|
+
# challenge R2 P0: a loop body `for … do glab mr merge …; done` splits to a
|
|
802
|
+
# `do glab …` segment — the leading `do` keyword must be stripped so the
|
|
803
|
+
# merge is still detected (denied when no grant present)
|
|
804
|
+
probe deny "$FEAT_CWD" 'for id in 1 2; do glab mr merge $id --auto-merge=false --yes; done'
|
|
805
|
+
probe deny "$FEAT_CWD" 'if true; then glab mr merge 5 --auto-merge=false --yes; fi'
|
|
806
|
+
|
|
807
|
+
# session lock (review P1): a FRESH lock held by a peer → deny WITHOUT
|
|
808
|
+
# consuming (fail-closed; agent retries); a STALE (≥1 min) lock is broken
|
|
809
|
+
# and the consume proceeds; the guard releases the lock on exit.
|
|
810
|
+
GLOCK="$VAUTH_DIR/$VSID.lock"
|
|
811
|
+
varm_batch 3
|
|
812
|
+
mkdir "$GLOCK"
|
|
813
|
+
probe_sid deny "$FEAT_CWD" "$VSID" 'glab mr merge 546 --auto-merge=false --yes'
|
|
814
|
+
sentinel_content 'armed batch 3' 'held fresh lock must deny without consuming'
|
|
815
|
+
rmdir "$GLOCK" 2>/dev/null
|
|
816
|
+
varm_batch 3
|
|
817
|
+
mkdir "$GLOCK"
|
|
818
|
+
old_ts=$(date -v-5M +%Y%m%d%H%M 2>/dev/null || date -d '-5 minutes' +%Y%m%d%H%M)
|
|
819
|
+
touch -t "$old_ts" "$GLOCK"
|
|
820
|
+
probe_sid allow "$FEAT_CWD" "$VSID" 'glab mr merge 546 --auto-merge=false --yes'
|
|
821
|
+
sentinel_content 'armed batch 2' 'stale lock broken, unit consumed'
|
|
822
|
+
if [ ! -d "$GLOCK" ]; then pass=$((pass+1)); else
|
|
823
|
+
fail=$((fail+1)); echo 'FAIL guard must release the lock on exit' >&2
|
|
824
|
+
fi
|
|
825
|
+
rm -f "$VAUTH_DIR/$VSID"
|
|
826
|
+
|
|
827
|
+
# batch release reports remaining units in the visible systemMessage
|
|
828
|
+
varm_batch 3
|
|
829
|
+
out=$(jq -nc --arg c 'glab mr merge 546 --auto-merge=false --yes' --arg w "$FEAT_CWD" --arg s "$VSID" \
|
|
830
|
+
'{tool_input:{command:$c},cwd:$w,session_id:$s}' | TMPDIR="$tmp" CLAUDECODE= bash "$GUARD")
|
|
831
|
+
if printf '%s' "$out" | grep -q '剩余 2 个'; then pass=$((pass+1)); else
|
|
832
|
+
fail=$((fail+1)); echo "FAIL batch release must report remaining units, got: $out" >&2
|
|
833
|
+
fi
|
|
834
|
+
rm -f "$VAUTH_DIR/$VSID"
|
|
835
|
+
|
|
836
|
+
# --- degrade: malformed input must fail-open (allow, no output) ---
|
|
837
|
+
out=$(printf '{}' | bash "$GUARD")
|
|
838
|
+
if [ -z "$out" ]; then pass=$((pass+1)); else fail=$((fail+1)); echo "FAIL empty input -> $out" >&2; fi
|
|
839
|
+
out=$(printf 'not-json' | bash "$GUARD")
|
|
840
|
+
if [ -z "$out" ]; then pass=$((pass+1)); else fail=$((fail+1)); echo "FAIL bad json -> $out" >&2; fi
|
|
841
|
+
|
|
842
|
+
# --- POSIX reserved words that can prefix a simple command ---------------
|
|
843
|
+
# Regression for a class that silently bypassed a gate whose entire job is
|
|
844
|
+
# stopping an unauthorized merge. `if <merge>; then …; fi` is an ordinary
|
|
845
|
+
# scripted spelling, not the eval/subshell obfuscation the header excludes.
|
|
846
|
+
# The stripped set is closed (derived from the POSIX reserved-word list), so
|
|
847
|
+
# these pin the whole class, not just the instances that were reported.
|
|
848
|
+
probe deny "$FEAT_CWD" 'if glab mr merge 546 --yes; then echo ok; fi'
|
|
849
|
+
probe deny "$FEAT_CWD" 'if git push origin main; then echo ok; fi'
|
|
850
|
+
probe deny "$FEAT_CWD" 'while glab mr merge 546 --yes; do echo x; done'
|
|
851
|
+
probe deny "$FEAT_CWD" 'until glab mr merge 546 --yes; do :; done'
|
|
852
|
+
probe deny "$FEAT_CWD" '! git push origin main'
|
|
853
|
+
# The words themselves must stay inert in prose.
|
|
854
|
+
probe allow "$FEAT_CWD" 'echo if merge and while merge'
|
|
855
|
+
probe allow "$FEAT_CWD" 'git push origin feature-if'
|
|
856
|
+
# Transparent special builtins are the same bypass class as the reserved words
|
|
857
|
+
# above, and were still open after the first pass at this fix.
|
|
858
|
+
probe deny "$FEAT_CWD" 'exec git push origin main'
|
|
859
|
+
probe deny "$FEAT_CWD" 'exec glab mr merge 546 --yes'
|
|
860
|
+
probe deny "$FEAT_CWD" 'builtin git push origin main'
|
|
861
|
+
probe allow "$FEAT_CWD" 'exec git push origin feature-x'
|
|
862
|
+
|
|
863
|
+
# ---- -C target legibility ----------------------------------------------------
|
|
864
|
+
# Merging main INTO a feature worktree is an ALLOWED shape, and `git -C <wt> merge
|
|
865
|
+
# origin/main` from the main checkout is how it gets written. That works only when the
|
|
866
|
+
# target is legible: this guard reads command TEXT, so a variable target cannot be
|
|
867
|
+
# expanded and the branch context falls back to the cwd (fail-closed, since the unknown
|
|
868
|
+
# path may be the default checkout). Both verdicts are pinned here so neither drifts,
|
|
869
|
+
# plus the deny REASON — an accurate reason is the whole point, because a deny that
|
|
870
|
+
# blames "advances main" for an unexpandable variable reads as a broken gate and trains
|
|
871
|
+
# people to route around it.
|
|
872
|
+
probe allow "$MAIN_CWD" "git -C $FEAT_CWD merge origin/main --no-edit"
|
|
873
|
+
probe allow "$MAIN_CWD" "git -C $FEAT_CWD merge main"
|
|
874
|
+
probe deny "$MAIN_CWD" 'git -C "$WT" merge origin/main --no-edit'
|
|
875
|
+
probe deny "$MAIN_CWD" 'git -C "$WT" push origin main'
|
|
876
|
+
# …and the unresolved fallback must never become an ALLOW: an unknown -C target on a
|
|
877
|
+
# genuinely default-advancing shape stays denied even from a feature worktree.
|
|
878
|
+
probe deny "$FEAT_CWD" 'git -C "$SOMEWHERE" push origin main'
|
|
879
|
+
|
|
880
|
+
reason_has() { # reason_has <want-substring|!want> <cwd> <cmd>
|
|
881
|
+
local want="$1" cwd="$2" cmd="$3" out
|
|
882
|
+
out=$(jq -nc --arg c "$cmd" --arg w "$cwd" '{tool_input:{command:$c},cwd:$w}' | bash "$GUARD")
|
|
883
|
+
case "$want" in
|
|
884
|
+
'!'*) if printf '%s' "$out" | grep -q -- "${want#!}"; then
|
|
885
|
+
fail=$((fail+1)); printf 'FAIL [reason should NOT mention %s] %s\n' "${want#!}" "$cmd" >&2
|
|
886
|
+
else pass=$((pass+1)); fi ;;
|
|
887
|
+
*) if printf '%s' "$out" | grep -q -- "$want"; then pass=$((pass+1))
|
|
888
|
+
else fail=$((fail+1)); printf 'FAIL [reason missing %s] %s\n' "$want" "$cmd" >&2; fi ;;
|
|
889
|
+
esac
|
|
890
|
+
}
|
|
891
|
+
# The unexpandable-target deny explains itself and offers the literal-path escape…
|
|
892
|
+
reason_has '展开不了' "$MAIN_CWD" 'git -C "$WT" merge origin/main --no-edit'
|
|
893
|
+
reason_has '字面绝对路径' "$MAIN_CWD" 'git -C "$WT" merge origin/main --no-edit'
|
|
894
|
+
# …while a REAL default-branch advance keeps the original, more severe reason.
|
|
895
|
+
reason_has '!展开不了' "$MAIN_CWD" 'git merge origin/main'
|
|
896
|
+
reason_has '直接推进' "$MAIN_CWD" 'git merge origin/main'
|
|
897
|
+
|
|
898
|
+
if [ "$fail" -ne 0 ]; then
|
|
899
|
+
echo "test_guard_merge_authorization: FAIL pass=$pass fail=$fail" >&2
|
|
900
|
+
exit 1
|
|
901
|
+
fi
|
|
902
|
+
echo "test_guard_merge_authorization_ok pass=$pass"
|