@soleur/opencode 0.0.0-stage → 3.354.2
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/.claude-plugin/agents.manifest.json +476 -0
- package/.claude-plugin/plugin.json +42 -0
- package/README.md +44 -2
- package/agents/community/.gitkeep +0 -0
- package/agents/engineering/cto.md +87 -0
- package/agents/engineering/design/ddd-architect.md +95 -0
- package/agents/engineering/discovery/agent-finder.md +214 -0
- package/agents/engineering/discovery/functional-discovery.md +182 -0
- package/agents/engineering/infra/infra-security.md +151 -0
- package/agents/engineering/infra/platform-strategist.md +109 -0
- package/agents/engineering/infra/terraform-architect.md +171 -0
- package/agents/engineering/prompt-engineer.md +37 -0
- package/agents/engineering/research/best-practices-researcher.md +115 -0
- package/agents/engineering/research/framework-docs-researcher.md +93 -0
- package/agents/engineering/research/git-history-analyzer.md +53 -0
- package/agents/engineering/research/learnings-researcher.md +285 -0
- package/agents/engineering/research/repo-research-analyst.md +118 -0
- package/agents/engineering/review/agent-native-reviewer.md +279 -0
- package/agents/engineering/review/architecture-strategist.md +61 -0
- package/agents/engineering/review/code-quality-analyst.md +92 -0
- package/agents/engineering/review/code-simplicity-reviewer.md +109 -0
- package/agents/engineering/review/data-integrity-guardian.md +82 -0
- package/agents/engineering/review/data-migration-expert.md +98 -0
- package/agents/engineering/review/deployment-verification-agent.md +183 -0
- package/agents/engineering/review/dhh-rails-reviewer.md +46 -0
- package/agents/engineering/review/kieran-rails-reviewer.md +87 -0
- package/agents/engineering/review/legacy-code-expert.md +55 -0
- package/agents/engineering/review/observability-coverage-reviewer.md +147 -0
- package/agents/engineering/review/pattern-recognition-specialist.md +59 -0
- package/agents/engineering/review/performance-oracle.md +130 -0
- package/agents/engineering/review/security-sentinel.md +167 -0
- package/agents/engineering/review/semgrep-sast.md +36 -0
- package/agents/engineering/review/test-design-reviewer.md +150 -0
- package/agents/engineering/review/user-impact-reviewer.md +70 -0
- package/agents/engineering/workflow/pr-comment-resolver.md +69 -0
- package/agents/finance/budget-analyst.md +29 -0
- package/agents/finance/cfo.md +44 -0
- package/agents/finance/financial-reporter.md +30 -0
- package/agents/finance/revenue-analyst.md +30 -0
- package/agents/legal/clo.md +115 -0
- package/agents/legal/legal-compliance-auditor.md +110 -0
- package/agents/legal/legal-document-generator.md +134 -0
- package/agents/marketing/analytics-analyst.md +25 -0
- package/agents/marketing/brand-architect.md +181 -0
- package/agents/marketing/cmo.md +76 -0
- package/agents/marketing/conversion-optimizer.md +19 -0
- package/agents/marketing/copywriter.md +20 -0
- package/agents/marketing/fact-checker.md +70 -0
- package/agents/marketing/growth-strategist.md +145 -0
- package/agents/marketing/paid-media-strategist.md +28 -0
- package/agents/marketing/pricing-strategist.md +17 -0
- package/agents/marketing/programmatic-seo-specialist.md +25 -0
- package/agents/marketing/retention-strategist.md +23 -0
- package/agents/marketing/seo-aeo-analyst.md +164 -0
- package/agents/operations/coo.md +50 -0
- package/agents/operations/ops-advisor.md +78 -0
- package/agents/operations/ops-provisioner.md +101 -0
- package/agents/operations/ops-research.md +52 -0
- package/agents/operations/service-automator.md +278 -0
- package/agents/product/business-validator.md +206 -0
- package/agents/product/competitive-intelligence.md +89 -0
- package/agents/product/cpo.md +63 -0
- package/agents/product/design/ux-design-lead.md +209 -0
- package/agents/product/spec-flow-analyzer.md +122 -0
- package/agents/sales/cro.md +44 -0
- package/agents/sales/deal-architect.md +29 -0
- package/agents/sales/outbound-strategist.md +29 -0
- package/agents/sales/pipeline-analyst.md +29 -0
- package/agents/support/cco.md +48 -0
- package/agents/support/community-manager.md +570 -0
- package/agents/support/ticket-triage.md +70 -0
- package/bin/soleur-opencode.js +29 -0
- package/commands/go.md +660 -0
- package/commands/help.md +273 -0
- package/commands/sync.md +977 -0
- package/commands/version.md +103 -0
- package/hooks/antigravity-hooks.json +84 -0
- package/hooks/antigravity-session-start.sh +15 -0
- package/hooks/bare-root-cwd-guard.sh +131 -0
- package/hooks/browser-snapshot-credential-guard.sh +200 -0
- package/hooks/codex-session-start.sh +9 -0
- package/hooks/compaction-state.sh +525 -0
- package/hooks/destructive-command-guard.sh +1387 -0
- package/hooks/devin-session-start.sh +90 -0
- package/hooks/ext-filter-detect.sh +171 -0
- package/hooks/hooks.json +133 -0
- package/hooks/lib/hook-tool-kind.sh +24 -0
- package/hooks/lib/log-rotation.sh +176 -0
- package/hooks/lib/shell-argv.pl +576 -0
- package/hooks/memory-backstop.sh +1114 -0
- package/hooks/operator-stage-approval.sh +391 -0
- package/hooks/stop-hook.sh +367 -0
- package/hooks/unkept-promise-hook.sh +383 -0
- package/hooks/version-banner.sh +127 -0
- package/hooks/welcome-hook.sh +50 -0
- package/install.js +29 -0
- package/lib/agent-registry.ts +154 -0
- package/lib/c4-canonical-cli.mjs +34 -0
- package/lib/c4-canonical.mjs +46 -0
- package/lib/c4-from-components.ts +554 -0
- package/lib/go-routing.ts +81 -0
- package/lib/grok-inspect-contract.ts +311 -0
- package/lib/harness-model-map.ts +101 -0
- package/lib/harness-parity.ts +726 -0
- package/lib/harness-tool-map.ts +180 -0
- package/lib/harness.ts +716 -0
- package/lib/heartbeat-live-reconcile.ts +1153 -0
- package/lib/heartbeat-manifest.ts +361 -0
- package/lib/kb-coverage.ts +252 -0
- package/lib/pr-merge-poll.ts +103 -0
- package/lib/workflow-fidelity.ts +388 -0
- package/opencode/INSTRUCTIONS.md +171 -0
- package/opencode/agents/engineering/cto.md +10 -0
- package/opencode/agents/engineering/design/ddd-architect.md +10 -0
- package/opencode/agents/engineering/discovery/agent-finder.md +10 -0
- package/opencode/agents/engineering/discovery/functional-discovery.md +10 -0
- package/opencode/agents/engineering/infra/infra-security.md +10 -0
- package/opencode/agents/engineering/infra/platform-strategist.md +10 -0
- package/opencode/agents/engineering/infra/terraform-architect.md +10 -0
- package/opencode/agents/engineering/prompt-engineer.md +10 -0
- package/opencode/agents/engineering/research/best-practices-researcher.md +10 -0
- package/opencode/agents/engineering/research/framework-docs-researcher.md +10 -0
- package/opencode/agents/engineering/research/git-history-analyzer.md +10 -0
- package/opencode/agents/engineering/research/learnings-researcher.md +10 -0
- package/opencode/agents/engineering/research/repo-research-analyst.md +10 -0
- package/opencode/agents/engineering/review/agent-native-reviewer.md +10 -0
- package/opencode/agents/engineering/review/architecture-strategist.md +10 -0
- package/opencode/agents/engineering/review/code-quality-analyst.md +10 -0
- package/opencode/agents/engineering/review/code-simplicity-reviewer.md +10 -0
- package/opencode/agents/engineering/review/data-integrity-guardian.md +10 -0
- package/opencode/agents/engineering/review/data-migration-expert.md +10 -0
- package/opencode/agents/engineering/review/deployment-verification-agent.md +10 -0
- package/opencode/agents/engineering/review/dhh-rails-reviewer.md +10 -0
- package/opencode/agents/engineering/review/kieran-rails-reviewer.md +10 -0
- package/opencode/agents/engineering/review/legacy-code-expert.md +10 -0
- package/opencode/agents/engineering/review/observability-coverage-reviewer.md +10 -0
- package/opencode/agents/engineering/review/pattern-recognition-specialist.md +10 -0
- package/opencode/agents/engineering/review/performance-oracle.md +10 -0
- package/opencode/agents/engineering/review/security-sentinel.md +10 -0
- package/opencode/agents/engineering/review/semgrep-sast.md +10 -0
- package/opencode/agents/engineering/review/test-design-reviewer.md +10 -0
- package/opencode/agents/engineering/review/user-impact-reviewer.md +10 -0
- package/opencode/agents/engineering/workflow/pr-comment-resolver.md +10 -0
- package/opencode/agents/finance/budget-analyst.md +10 -0
- package/opencode/agents/finance/cfo.md +10 -0
- package/opencode/agents/finance/financial-reporter.md +10 -0
- package/opencode/agents/finance/revenue-analyst.md +10 -0
- package/opencode/agents/legal/clo.md +10 -0
- package/opencode/agents/legal/legal-compliance-auditor.md +10 -0
- package/opencode/agents/legal/legal-document-generator.md +10 -0
- package/opencode/agents/marketing/analytics-analyst.md +10 -0
- package/opencode/agents/marketing/brand-architect.md +10 -0
- package/opencode/agents/marketing/cmo.md +10 -0
- package/opencode/agents/marketing/conversion-optimizer.md +10 -0
- package/opencode/agents/marketing/copywriter.md +10 -0
- package/opencode/agents/marketing/fact-checker.md +10 -0
- package/opencode/agents/marketing/growth-strategist.md +10 -0
- package/opencode/agents/marketing/paid-media-strategist.md +10 -0
- package/opencode/agents/marketing/pricing-strategist.md +10 -0
- package/opencode/agents/marketing/programmatic-seo-specialist.md +10 -0
- package/opencode/agents/marketing/retention-strategist.md +10 -0
- package/opencode/agents/marketing/seo-aeo-analyst.md +10 -0
- package/opencode/agents/operations/coo.md +10 -0
- package/opencode/agents/operations/ops-advisor.md +10 -0
- package/opencode/agents/operations/ops-provisioner.md +10 -0
- package/opencode/agents/operations/ops-research.md +10 -0
- package/opencode/agents/operations/service-automator.md +10 -0
- package/opencode/agents/product/business-validator.md +10 -0
- package/opencode/agents/product/competitive-intelligence.md +10 -0
- package/opencode/agents/product/cpo.md +10 -0
- package/opencode/agents/product/design/ux-design-lead.md +10 -0
- package/opencode/agents/product/spec-flow-analyzer.md +10 -0
- package/opencode/agents/sales/cro.md +10 -0
- package/opencode/agents/sales/deal-architect.md +10 -0
- package/opencode/agents/sales/outbound-strategist.md +10 -0
- package/opencode/agents/sales/pipeline-analyst.md +10 -0
- package/opencode/agents/support/cco.md +10 -0
- package/opencode/agents/support/community-manager.md +10 -0
- package/opencode/agents/support/ticket-triage.md +10 -0
- package/opencode/commands/go.md +10 -0
- package/opencode/commands/help.md +10 -0
- package/opencode/commands/sync.md +10 -0
- package/opencode/commands/version.md +11 -0
- package/opencode/opencode.json +8 -0
- package/opencode/plugin.ts +818 -0
- package/package.json +36 -4
- package/scripts/admin-merge-ready.sh +545 -0
- package/scripts/admin-merge-ready.test.sh +753 -0
- package/scripts/affected-tests.sh +908 -0
- package/scripts/affected-tests.test.sh +1797 -0
- package/scripts/alpha-metrics.sh +78 -0
- package/scripts/alpha-metrics.test.sh +115 -0
- package/scripts/ancestor-signal-helpers.baseline.txt +16 -0
- package/scripts/audit-flag-flip.sh +107 -0
- package/scripts/check-red-on-main.sh +316 -0
- package/scripts/ci-head-verdict.sh +411 -0
- package/scripts/cloud-detect.sh +193 -0
- package/scripts/delegation-verify.sh +657 -0
- package/scripts/delegation-verify.test.sh +1424 -0
- package/scripts/deploy-arm.sh +475 -0
- package/scripts/domain-model-drift.sh +419 -0
- package/scripts/emit-decision.sh +144 -0
- package/scripts/emit-decision.test.sh +144 -0
- package/scripts/ext-filter-divergence-corpus.txt +15 -0
- package/scripts/ext-filter-divergence.sh +189 -0
- package/scripts/generate-c4-from-components.ts +442 -0
- package/scripts/grok-fidelity-gate.sh +68 -0
- package/scripts/grok-pre-push-gate.sh +232 -0
- package/scripts/harness-discovery-smoke.ts +906 -0
- package/scripts/harness-parity-census.ts +92 -0
- package/scripts/inngest-luks-alert-armed-probe.ts +29 -0
- package/scripts/install-opencode-adapter.ts +509 -0
- package/scripts/lib/affected-tests/common.sh +365 -0
- package/scripts/lib/affected-tests/go.sh +157 -0
- package/scripts/lib/affected-tests/js.sh +188 -0
- package/scripts/lib/affected-tests/nx-turbo.sh +98 -0
- package/scripts/lib/affected-tests/python.sh +185 -0
- package/scripts/lib/context-sanitize.sh +49 -0
- package/scripts/lib/domain-model-lib.sh +180 -0
- package/scripts/lib/ext-filter-grammar.tsv +34 -0
- package/scripts/lib/operator-script.sh +1236 -0
- package/scripts/lib/proc.sh +580 -0
- package/scripts/lib/session-state.sh +748 -0
- package/scripts/lib/tmp-classify.sh +843 -0
- package/scripts/lib/wrapper-boundary.sh +47 -0
- package/scripts/lint-ratchet.py +1547 -0
- package/scripts/monitor-pr-checks.sh +441 -0
- package/scripts/pipeline-tally.sh +756 -0
- package/scripts/pipeline-tally.test.sh +740 -0
- package/scripts/plugin-version.sh +528 -0
- package/scripts/precommit-guard.sh +115 -0
- package/scripts/precommit-guard.test.sh +254 -0
- package/scripts/reconcile-live-heartbeats.ts +705 -0
- package/scripts/render-c4-model.sh +217 -0
- package/scripts/resolve-git-root.sh +55 -0
- package/scripts/resolve-regenerable-conflicts.sh +363 -0
- package/scripts/resolve-regenerable-conflicts.test.sh +780 -0
- package/scripts/ruff-requirements.txt +22 -0
- package/scripts/run-in-pid-namespace.sh +98 -0
- package/scripts/run-in-pid-namespace.test.sh +290 -0
- package/scripts/scan-ancestor-signal-helpers.py +556 -0
- package/scripts/scan-ancestor-signal-helpers.test.sh +670 -0
- package/scripts/setup-ralph-loop.sh +238 -0
- package/scripts/sync-cursor-name-map.ts +316 -0
- package/scripts/sync-grok-agent-compat.ts +188 -0
- package/scripts/sync-npm-package.ts +165 -0
- package/scripts/sync-opencode-adapter.ts +498 -0
- package/scripts/sync-pr-behind.sh +647 -0
- package/scripts/sync-pr-behind.test.sh +252 -0
- package/scripts/taste-profile-update.sh +180 -0
- package/scripts/taste-profile-update.test.sh +167 -0
- package/scripts/write-budget-marker.sh +23 -0
- package/scripts/write-kb-coverage.ts +113 -0
- package/skills/admin-ip-refresh/SKILL.md +81 -0
- package/skills/admin-ip-refresh/references/admin-ip-refresh-procedure.md +201 -0
- package/skills/agent-browser/SKILL.md +698 -0
- package/skills/agent-browser/scripts/playwright-mcp-profile-slot.sh +304 -0
- package/skills/agent-browser/scripts/playwright-mcp-redact-proxy.py +964 -0
- package/skills/agent-browser/scripts/redact-a11y-snapshot.py +443 -0
- package/skills/agent-browser/test/fixtures/capture-playwright-mcp-fixtures.py +217 -0
- package/skills/agent-browser/test/fixtures/fake-passthrough-proxy.py +24 -0
- package/skills/agent-browser/test/fixtures/fake-playwright-mcp.py +131 -0
- package/skills/agent-browser/test/fixtures/make-proxy-mutant.py +48 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/dialog-link-injection.json +10 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/empty-content.json +5 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/error-and-result.json +4 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/error-code-bool.json +6 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/error-code-string.json +6 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/error-message-tree.json +6 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/error-no-data.json +6 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/error-string.json +4 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/error-with-data.json +9 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/evaluate-escaped-object.json +10 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/invalid-utf8.json +4 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/link-result.json +10 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/list-two-results.json +6 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/meta-in-result.json +13 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/no-content.json +5 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/quoted-key.json +10 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/resource-block.json +18 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/result-and-method.json +11 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/result-string.json +3 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/run-code-escaped-one-row.json +10 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/run-code-escaped.json +10 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/structured-content.json +13 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/tools-list-no-tools.json +5 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/tree-no-credential.json +10 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/two-text-blocks.json +14 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/unparsable-line.json +3 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/value-contains-brace.json +10 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/value-contains-link-substring.json +10 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/close.json +12 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/evaluate.json +12 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/find.json +12 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/framing.json +6 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/initialize.json +14 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/navigate-link.json +12 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/navigate.json +12 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/roots-list-request.json +5 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/screenshot.json +17 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/snapshot-filename.json +12 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/snapshot-meta-json.json +12 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/snapshot-meta-raw.json +12 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/snapshot.json +12 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/tools-list.json +827 -0
- package/skills/agent-browser/test/fixtures/proxy-session-driver.py +138 -0
- package/skills/agent-browser/test/fixtures/session-facts.py +102 -0
- package/skills/agent-browser/test/playwright-mcp-lifetime.test.sh +1620 -0
- package/skills/agent-browser/test/playwright-mcp-redact-proxy.test.sh +1599 -0
- package/skills/agent-browser/test/redact-a11y-snapshot.test.sh +527 -0
- package/skills/agent-native-architecture/SKILL.md +479 -0
- package/skills/agent-native-architecture/references/action-parity-discipline.md +430 -0
- package/skills/agent-native-architecture/references/agent-execution-patterns.md +483 -0
- package/skills/agent-native-architecture/references/agent-native-testing.md +605 -0
- package/skills/agent-native-architecture/references/architecture-patterns.md +493 -0
- package/skills/agent-native-architecture/references/dynamic-context-injection.md +358 -0
- package/skills/agent-native-architecture/references/files-universal-interface.md +314 -0
- package/skills/agent-native-architecture/references/from-primitives-to-domain-tools.md +381 -0
- package/skills/agent-native-architecture/references/mcp-tool-design.md +524 -0
- package/skills/agent-native-architecture/references/mobile-patterns.md +897 -0
- package/skills/agent-native-architecture/references/product-implications.md +478 -0
- package/skills/agent-native-architecture/references/refactoring-to-prompt-native.md +342 -0
- package/skills/agent-native-architecture/references/self-modification.md +294 -0
- package/skills/agent-native-architecture/references/shared-workspace-architecture.md +700 -0
- package/skills/agent-native-architecture/references/system-prompt-design.md +263 -0
- package/skills/agent-native-audit/SKILL.md +300 -0
- package/skills/agent-native-audit/workflows/agent-native-audit.workflow.js +423 -0
- package/skills/andrew-kane-gem-writer/SKILL.md +189 -0
- package/skills/andrew-kane-gem-writer/references/database-adapters.md +231 -0
- package/skills/andrew-kane-gem-writer/references/module-organization.md +121 -0
- package/skills/andrew-kane-gem-writer/references/rails-integration.md +183 -0
- package/skills/andrew-kane-gem-writer/references/resources.md +126 -0
- package/skills/andrew-kane-gem-writer/references/testing-patterns.md +261 -0
- package/skills/architecture/SKILL.md +436 -0
- package/skills/architecture/references/adr-template.md +154 -0
- package/skills/architecture/references/likec4-reference.md +136 -0
- package/skills/architecture/references/nfr-reference.md +126 -0
- package/skills/archive-kb/SKILL.md +86 -0
- package/skills/archive-kb/scripts/archive-kb.sh +300 -0
- package/skills/archive-kb/test/archive-kb-partial-run.test.sh +276 -0
- package/skills/atdd-developer/SKILL.md +65 -0
- package/skills/brainstorm/SKILL.md +701 -0
- package/skills/brainstorm/references/brainstorm-brand-workshop.md +153 -0
- package/skills/brainstorm/references/brainstorm-domain-config.md +63 -0
- package/skills/brainstorm/references/brainstorm-validation-workshop.md +65 -0
- package/skills/brainstorm/references/ui-surface-terms.md +42 -0
- package/skills/brainstorm-techniques/SKILL.md +231 -0
- package/skills/brainstorm-techniques/references/decision-principles.md +150 -0
- package/skills/brainstorm-techniques/references/phase-boundaries.md +103 -0
- package/skills/brainstorm-techniques/references/standing-delegation.md +407 -0
- package/skills/brainstorm-techniques/references/technical-ruling-delegation.md +174 -0
- package/skills/campaign-calendar/SKILL.md +145 -0
- package/skills/cf-token-scope/SKILL.md +164 -0
- package/skills/cf-token-scope/references/widen-playbook.md +114 -0
- package/skills/cf-token-scope/scripts/cf-token-scope.sh +253 -0
- package/skills/changelog/SKILL.md +142 -0
- package/skills/code-to-prd/SKILL.md +66 -0
- package/skills/code-to-prd/references/banner-template.md +12 -0
- package/skills/code-to-prd/references/prd-template.md +41 -0
- package/skills/code-to-prd/scripts/code-to-prd.sh +634 -0
- package/skills/code-to-prd/test/code-to-prd.test.sh +447 -0
- package/skills/code-to-prd/test/fixture/.env.example +7 -0
- package/skills/code-to-prd/test/fixture/app/about/page.tsx +11 -0
- package/skills/code-to-prd/test/fixture/app/api/health/route.ts +10 -0
- package/skills/code-to-prd/test/fixture/app/page.tsx +14 -0
- package/skills/code-to-prd/test/fixture/next.config.mjs +3 -0
- package/skills/code-to-prd/test/fixture/package.json +6 -0
- package/skills/cohort-status/SKILL.md +62 -0
- package/skills/community/SKILL.md +210 -0
- package/skills/community/scripts/bsky-community.sh +644 -0
- package/skills/community/scripts/bsky-setup.sh +631 -0
- package/skills/community/scripts/community-router.sh +93 -0
- package/skills/community/scripts/discord-community.sh +487 -0
- package/skills/community/scripts/discord-setup.sh +784 -0
- package/skills/community/scripts/github-community.sh +706 -0
- package/skills/community/scripts/hn-community.sh +233 -0
- package/skills/community/scripts/lib/hmac-sha1-b64.sh +126 -0
- package/skills/community/scripts/linkedin-community.sh +750 -0
- package/skills/community/scripts/linkedin-setup.sh +758 -0
- package/skills/community/scripts/x-community.sh +890 -0
- package/skills/community/scripts/x-setup.sh +713 -0
- package/skills/community/test/community-argv.test.sh +2922 -0
- package/skills/community/test/github-community.test.sh +981 -0
- package/skills/competitive-analysis/SKILL.md +69 -0
- package/skills/competitive-analysis/references/peer-plugin-audit.md +218 -0
- package/skills/compound/SKILL.md +673 -0
- package/skills/compound/scripts/token-efficiency-report.sh +334 -0
- package/skills/compound/test/phase-16.test.sh +379 -0
- package/skills/compound-capture/SKILL.md +791 -0
- package/skills/compound-capture/assets/critical-pattern-template.md +37 -0
- package/skills/compound-capture/assets/resolution-template.md +116 -0
- package/skills/compound-capture/references/yaml-schema.md +67 -0
- package/skills/compound-capture/schema.yaml +181 -0
- package/skills/constraint-scaffold/SKILL.md +175 -0
- package/skills/constraint-scaffold/references/boundary-readme.template +35 -0
- package/skills/constraint-scaffold/references/constraint-gates-workflow.template +69 -0
- package/skills/constraint-scaffold/references/depcruise-config.template +230 -0
- package/skills/constraint-scaffold/references/fix-constraints-stage-a.template +240 -0
- package/skills/constraint-scaffold/references/fix-constraints-stage-b.template +313 -0
- package/skills/constraint-scaffold/references/shared-runner.template +135 -0
- package/skills/constraint-scaffold/scripts/constraint-scaffold.sh +589 -0
- package/skills/constraint-scaffold/test/bite-proof.test.sh +1338 -0
- package/skills/constraint-scaffold/test/boundary.test.sh +734 -0
- package/skills/constraint-scaffold/test/emit-fix-constraints.test.sh +193 -0
- package/skills/constraint-scaffold/test/generator.test.sh +93 -0
- package/skills/constraint-scaffold/test/parity.test.sh +285 -0
- package/skills/content-writer/SKILL.md +242 -0
- package/skills/content-writer/scripts/blog-jargon-scan.sh +42 -0
- package/skills/cron-delete/SKILL.md +56 -0
- package/skills/cron-list/SKILL.md +54 -0
- package/skills/deepen-plan/SKILL.md +937 -0
- package/skills/deepen-plan/workflows/deepen-plan.workflow.js +488 -0
- package/skills/deploy/SKILL.md +115 -0
- package/skills/deploy/references/hetzner-setup.md +67 -0
- package/skills/deploy/scripts/deploy.sh +37 -0
- package/skills/deploy-docs/SKILL.md +95 -0
- package/skills/dhh-rails-style/SKILL.md +203 -0
- package/skills/dhh-rails-style/references/architecture.md +717 -0
- package/skills/dhh-rails-style/references/controllers.md +323 -0
- package/skills/dhh-rails-style/references/frontend.md +556 -0
- package/skills/dhh-rails-style/references/gems.md +316 -0
- package/skills/dhh-rails-style/references/models.md +388 -0
- package/skills/dhh-rails-style/references/testing.md +354 -0
- package/skills/discord-content/SKILL.md +126 -0
- package/skills/docs-site/SKILL.md +214 -0
- package/skills/drain-labeled-backlog/SKILL.md +203 -0
- package/skills/drain-labeled-backlog/scripts/group-by-area.sh +208 -0
- package/skills/drain-labeled-backlog/workflows/drain-labeled-backlog.workflow.js +433 -0
- package/skills/drain-prs/SKILL.md +143 -0
- package/skills/drain-prs/scripts/triage-prs.sh +192 -0
- package/skills/drain-prs/test/argv-ceiling.test.sh +183 -0
- package/skills/dspy-ruby/SKILL.md +634 -0
- package/skills/dspy-ruby/assets/config-template.rb +359 -0
- package/skills/dspy-ruby/assets/module-template.rb +326 -0
- package/skills/dspy-ruby/assets/signature-template.rb +143 -0
- package/skills/dspy-ruby/references/core-concepts.md +268 -0
- package/skills/dspy-ruby/references/optimization.md +623 -0
- package/skills/dspy-ruby/references/providers.md +335 -0
- package/skills/eval-harness/README.md +194 -0
- package/skills/eval-harness/SKILL.md +157 -0
- package/skills/eval-harness/enums/go-routes.json +13 -0
- package/skills/eval-harness/enums/incident-threshold.json +5 -0
- package/skills/eval-harness/enums/lane.json +5 -0
- package/skills/eval-harness/enums/tool-selection.json +20 -0
- package/skills/eval-harness/enums/triage-levels.json +5 -0
- package/skills/eval-harness/gated-skills.json +34 -0
- package/skills/eval-harness/models.generated.json +5 -0
- package/skills/eval-harness/promptfooconfig-go-routing.yaml +35 -0
- package/skills/eval-harness/promptfooconfig-incident-threshold.yaml +32 -0
- package/skills/eval-harness/promptfooconfig-lane-inference.yaml +33 -0
- package/skills/eval-harness/promptfooconfig-ticket-triage.yaml +34 -0
- package/skills/eval-harness/promptfooconfig-tool-selection.yaml +33 -0
- package/skills/eval-harness/prompts/go-baseline.txt +6 -0
- package/skills/eval-harness/prompts/go-skill.txt +21 -0
- package/skills/eval-harness/prompts/incident-threshold-baseline.txt +6 -0
- package/skills/eval-harness/prompts/incident-threshold-skill.txt +12 -0
- package/skills/eval-harness/prompts/lane-inference-baseline.txt +6 -0
- package/skills/eval-harness/prompts/lane-inference-skill.txt +15 -0
- package/skills/eval-harness/prompts/tool-selection-baseline.txt +19 -0
- package/skills/eval-harness/prompts/tool-selection-skill.txt +22 -0
- package/skills/eval-harness/prompts/triage-baseline.txt +7 -0
- package/skills/eval-harness/prompts/triage-skill.txt +10 -0
- package/skills/eval-harness/scripts/eval-gate.cjs +318 -0
- package/skills/eval-harness/scripts/extract-block.cjs +87 -0
- package/skills/eval-harness/scripts/gate-classification.cjs +28 -0
- package/skills/eval-harness/scripts/gen-models.sh +41 -0
- package/skills/eval-harness/scripts/gen-skill-prompt.cjs +177 -0
- package/skills/eval-harness/scripts/measure-classification.cjs +30 -0
- package/skills/eval-harness/scripts/parse-label.cjs +93 -0
- package/skills/eval-harness/scripts/verdict.cjs +132 -0
- package/skills/eval-harness/tasks/go-routing.jsonl +8 -0
- package/skills/eval-harness/tasks/incident-threshold.jsonl +7 -0
- package/skills/eval-harness/tasks/lane-inference.jsonl +7 -0
- package/skills/eval-harness/tasks/ticket-triage.jsonl +6 -0
- package/skills/eval-harness/tasks/tool-selection.jsonl +15 -0
- package/skills/eval-harness/test/eval-gate.test.sh +132 -0
- package/skills/eval-harness/test/extract-block.test.sh +87 -0
- package/skills/eval-harness/test/gate-classification.test.sh +77 -0
- package/skills/eval-harness/test/gen-models.test.sh +75 -0
- package/skills/eval-harness/test/measure-classification.test.sh +74 -0
- package/skills/eval-harness/test/parse-label.test.sh +129 -0
- package/skills/eval-harness/test/registry-completeness.test.sh +109 -0
- package/skills/eval-harness/test/verdict.test.sh +123 -0
- package/skills/every-style-editor/SKILL.md +142 -0
- package/skills/every-style-editor/references/EVERY_WRITE_STYLE.md +529 -0
- package/skills/feature-tweet/SKILL.md +199 -0
- package/skills/feature-video/SKILL.md +412 -0
- package/skills/feature-video/scripts/check_deps.sh +281 -0
- package/skills/file-todos/SKILL.md +267 -0
- package/skills/file-todos/assets/todo-template.md +166 -0
- package/skills/fix-issue/SKILL.md +278 -0
- package/skills/fix-issue/references/agent-authored-exclusion.md +120 -0
- package/skills/fix-issue/references/exclude-label-jq-snippet.md +97 -0
- package/skills/flag-bootstrap/SETUP.md +142 -0
- package/skills/flag-create/SKILL.md +145 -0
- package/skills/flag-create/scripts/create.sh +273 -0
- package/skills/flag-delete/SKILL.md +167 -0
- package/skills/flag-delete/scripts/delete.sh +288 -0
- package/skills/flag-list/SKILL.md +99 -0
- package/skills/flag-list/scripts/list.sh +275 -0
- package/skills/flag-set-role/SKILL.md +229 -0
- package/skills/flag-set-role/scripts/flip.sh +774 -0
- package/skills/frontend-anti-slop/SKILL.md +106 -0
- package/skills/frontend-anti-slop/references/anti-patterns.md +199 -0
- package/skills/frontend-anti-slop/references/slop-rules.md +65 -0
- package/skills/frontend-anti-slop/scripts/tier1-scan.ts +525 -0
- package/skills/frontend-design/SKILL.md +77 -0
- package/skills/gdpr-gate/NOTICE +136 -0
- package/skills/gdpr-gate/SKILL.md +341 -0
- package/skills/gdpr-gate/references/fields.md +160 -0
- package/skills/gdpr-gate/references/layers/api-layer.md +355 -0
- package/skills/gdpr-gate/references/layers/auth-sessions.md +290 -0
- package/skills/gdpr-gate/references/layers/data-in-transit.md +331 -0
- package/skills/gdpr-gate/references/layers/data-lifecycle.md +341 -0
- package/skills/gdpr-gate/references/layers/frontend.md +249 -0
- package/skills/gdpr-gate/references/layers/testing-seeding.md +256 -0
- package/skills/gdpr-gate/references/leakage-vectors.md +248 -0
- package/skills/gdpr-gate/references/legacy/legal-consent-v1-prose.md +48 -0
- package/skills/gdpr-gate/references/legal-consent.md +140 -0
- package/skills/gdpr-gate/references/non-negotiables.md +60 -0
- package/skills/gdpr-gate/scripts/gdpr-gate.sh +271 -0
- package/skills/gdpr-gate/scripts/notice-frontmatter.sh +337 -0
- package/skills/gdpr-gate/scripts/path-denylist.txt +39 -0
- package/skills/gdpr-gate/scripts/repo-scan.sh +158 -0
- package/skills/gdpr-gate/scripts/vendor-drift-classify.sh +120 -0
- package/skills/gdpr-gate/scripts/vendor-pin-integrity.sh +237 -0
- package/skills/gemini-imagegen/SKILL.md +283 -0
- package/skills/gemini-imagegen/requirements.txt +5 -0
- package/skills/gemini-imagegen/scripts/_error_handling.py +146 -0
- package/skills/gemini-imagegen/scripts/compose_images.py +150 -0
- package/skills/gemini-imagegen/scripts/edit_image.py +137 -0
- package/skills/gemini-imagegen/scripts/gemini_images.py +256 -0
- package/skills/gemini-imagegen/scripts/generate_image.py +147 -0
- package/skills/gemini-imagegen/scripts/multi_turn_chat.py +223 -0
- package/skills/gemini-imagegen/scripts/test_error_handling.py +179 -0
- package/skills/git-worktree/SKILL.md +534 -0
- package/skills/git-worktree/scripts/git-repo-readiness-diag.sh +98 -0
- package/skills/git-worktree/scripts/worktree-manager.sh +4773 -0
- package/skills/git-worktree/test/create-from-origin-main.test.sh +116 -0
- package/skills/git-worktree/test/lease-protects-active.test.sh +1056 -0
- package/skills/git-worktree/test/no-repo-fail-loud.test.sh +88 -0
- package/skills/git-worktree/test/orphan-reaper-honest-count.test.sh +379 -0
- package/skills/git-worktree/test/reap-archive-persistence.test.sh +725 -0
- package/skills/git-worktree/test/stale-lock-sweep.test.sh +176 -0
- package/skills/go/SKILL.md +54 -0
- package/skills/growth/SKILL.md +164 -0
- package/skills/harvest-debt/SKILL.md +78 -0
- package/skills/harvest-debt/scripts/harvest-debt.sh +114 -0
- package/skills/heal-skill/SKILL.md +173 -0
- package/skills/help/SKILL.md +46 -0
- package/skills/incident/NOTICE +39 -0
- package/skills/incident/SKILL.md +395 -0
- package/skills/incident/scripts/dry-run.sh +448 -0
- package/skills/incident/scripts/redact-engine.py +412 -0
- package/skills/incident/scripts/redact-sentinel.sh +44 -0
- package/skills/incident/templates/pir.md +139 -0
- package/skills/incident/test/fixtures/dry-run-incident.json +26 -0
- package/skills/incident/test/fixtures/dry-run-secret-leak.json +26 -0
- package/skills/incident/test/fixtures/legacy-bash-scanner.sh +82 -0
- package/skills/incident/test/fixtures/positive-corpus.md +87 -0
- package/skills/incident/test/redact-sentinel.test.sh +1420 -0
- package/skills/invoice/SKILL.md +206 -0
- package/skills/kb-glossary/SKILL.md +71 -0
- package/skills/kb-glossary/references/glossary-format.md +111 -0
- package/skills/kb-glossary/references/rejected-request-register.md +115 -0
- package/skills/kb-search/SKILL.md +276 -0
- package/skills/kb-search/scripts/kb-search-cache.sh +123 -0
- package/skills/legal-audit/SKILL.md +161 -0
- package/skills/legal-generate/NOTICE +242 -0
- package/skills/legal-generate/SKILL.md +244 -0
- package/skills/legal-generate/references/templates/advisor-agreement/template.md +12 -0
- package/skills/legal-generate/references/templates/business-associate-agreement/template.md +112 -0
- package/skills/legal-generate/references/templates/cookie-notice/template.md +82 -0
- package/skills/legal-generate/references/templates/dpa-global/template.md +439 -0
- package/skills/legal-generate/references/templates/dpa-us/template.md +222 -0
- package/skills/legal-generate/references/templates/employee-offer-letter/template.md +75 -0
- package/skills/legal-generate/references/templates/master-services-agreement/template.md +252 -0
- package/skills/legal-generate/references/templates/mutual-nda/template.md +66 -0
- package/skills/legal-generate/references/templates/one-way-nda/template.md +38 -0
- package/skills/legal-generate/references/templates/privacy-policy-gdpr/template.md +427 -0
- package/skills/legal-generate/references/templates/privacy-policy-us/template.md +313 -0
- package/skills/legal-generate/references/templates/terms-of-use/template.md +75 -0
- package/skills/legal-generate/scripts/strip-vendor-credit.sh +96 -0
- package/skills/linear-fetch/SKILL.md +247 -0
- package/skills/linear-fetch/scripts/assert-no-linear-telemetry.sh +66 -0
- package/skills/linear-fetch/scripts/redact-linear-urls.sh +51 -0
- package/skills/linear-fetch/scripts/render-caller-template.sh +36 -0
- package/skills/linear-fetch/test/assert-no-linear-telemetry.test.sh +113 -0
- package/skills/linear-fetch/test/parity.test.sh +112 -0
- package/skills/linear-fetch/test/persist-safe-integration.test.sh +191 -0
- package/skills/linear-fetch/test/redact-linear-urls.test.sh +226 -0
- package/skills/merge-pr/SKILL.md +670 -0
- package/skills/model-launch-review/SKILL.md +255 -0
- package/skills/model-launch-review/scripts/audit-models.sh +501 -0
- package/skills/one-shot/SKILL.md +316 -0
- package/skills/one-shot/references/token-discipline.md +74 -0
- package/skills/operator-bootstrap/SKILL.md +412 -0
- package/skills/operator-bootstrap/template.sh +439 -0
- package/skills/operator-digest/SKILL.md +287 -0
- package/skills/operator-digest/assets/operator-digest.workflow.yml +175 -0
- package/skills/operator-digest/scripts/digest-scrub.sh +119 -0
- package/skills/operator-digest/scripts/provision-operator-digest-repo.sh +147 -0
- package/skills/operator-rephrase/SKILL.md +98 -0
- package/skills/pencil-setup/SKILL.md +201 -0
- package/skills/pencil-setup/scripts/check_deps.sh +556 -0
- package/skills/pencil-setup/scripts/copy_adapter.sh +80 -0
- package/skills/pencil-setup/scripts/package-lock.json +1172 -0
- package/skills/pencil-setup/scripts/package.json +14 -0
- package/skills/pencil-setup/scripts/pencil-error-enrichment.mjs +21 -0
- package/skills/pencil-setup/scripts/pencil-mcp-adapter.mjs +733 -0
- package/skills/pencil-setup/scripts/pencil-response-classify.mjs +38 -0
- package/skills/pencil-setup/scripts/pencil-save-gate.mjs +26 -0
- package/skills/pencil-setup/scripts/sanitize-filename.mjs +25 -0
- package/skills/plan/SKILL.md +1140 -0
- package/skills/plan/references/differential-migration-testing.md +185 -0
- package/skills/plan/references/plan-community-discovery.md +42 -0
- package/skills/plan/references/plan-founder-check.md +137 -0
- package/skills/plan/references/plan-functional-overlap.md +25 -0
- package/skills/plan/references/plan-host-fanout.md +51 -0
- package/skills/plan/references/plan-issue-templates.md +779 -0
- package/skills/plan/references/plan-network-outage-checklist.md +131 -0
- package/skills/plan/references/plan-scope-check.md +126 -0
- package/skills/plan/references/plan-sharp-edges.md +331 -0
- package/skills/plan/references/plan-signoff-lifecycle.md +12 -0
- package/skills/plan/references/webapp-cwv-observability.md +143 -0
- package/skills/plan-review/SKILL.md +91 -0
- package/skills/plan-review/lib/named-panel.mjs +58 -0
- package/skills/plan-review/workflows/plan-review.workflow.js +477 -0
- package/skills/postmerge/SKILL.md +642 -0
- package/skills/postmerge/references/deploy-status-debugging.md +141 -0
- package/skills/postmerge/references/graceful-degradation.md +20 -0
- package/skills/postmerge/references/sentry-error-count-delta.md +137 -0
- package/skills/preflight/SKILL.md +1553 -0
- package/skills/preflight/references/check-13-founder-check.md +286 -0
- package/skills/preflight/scripts/founder-check.py +1640 -0
- package/skills/preflight/scripts/parse-form-a.awk +107 -0
- package/skills/preflight/scripts/probe-verb-gate.sh +108 -0
- package/skills/product-roadmap/SKILL.md +357 -0
- package/skills/product-roadmap/scripts/roadmap-reconcile.sh +327 -0
- package/skills/provision-cloudflare/SKILL.md +67 -0
- package/skills/provision-cloudflare/scripts/provision-cloudflare.sh +271 -0
- package/skills/provision-doppler/SKILL.md +58 -0
- package/skills/provision-doppler/scripts/provision-doppler.sh +358 -0
- package/skills/provision-github/SKILL.md +59 -0
- package/skills/provision-github/scripts/provision-github.sh +300 -0
- package/skills/provision-hetzner/SKILL.md +76 -0
- package/skills/provision-hetzner/scripts/provision-hetzner.sh +262 -0
- package/skills/provision-hetzner/test/fixture/knowledge-base/legal/tenant-dpa-register.md +26 -0
- package/skills/provision-hetzner/test/fixture/provision-hetzner-dry-run.golden +34 -0
- package/skills/provision-hetzner/test/provision-hetzner-characterization.test.sh +227 -0
- package/skills/qa/SKILL.md +263 -0
- package/skills/qa/references/browser-preflight.md +22 -0
- package/skills/questionnaire-generate/SKILL.md +328 -0
- package/skills/questionnaire-generate/references/questionnaire.template +60 -0
- package/skills/rclone/SKILL.md +162 -0
- package/skills/rclone/scripts/check_setup.sh +63 -0
- package/skills/release-announce/SKILL.md +65 -0
- package/skills/release-docs/SKILL.md +92 -0
- package/skills/reproduce-bug/SKILL.md +358 -0
- package/skills/resolve-debt/SKILL.md +85 -0
- package/skills/resolve-debt/scripts/resolve-debt.py +584 -0
- package/skills/resolve-parallel/SKILL.md +45 -0
- package/skills/resolve-parallel/workflows/resolve-parallel.workflow.js +415 -0
- package/skills/resolve-pr-parallel/SKILL.md +68 -0
- package/skills/resolve-pr-parallel/workflows/resolve-pr-parallel.workflow.js +419 -0
- package/skills/resolve-todo-parallel/SKILL.md +57 -0
- package/skills/resolve-todo-parallel/workflows/resolve-todo-parallel.workflow.js +398 -0
- package/skills/review/SKILL.md +1620 -0
- package/skills/review/references/anti-slop-scanner-hook.md +40 -0
- package/skills/review/references/defect-classes-migrations.md +9 -0
- package/skills/review/references/generated-input-oracle-surfaces.md +15 -0
- package/skills/review/references/review-e2e-testing.md +116 -0
- package/skills/review/references/review-evidence-comment.md +36 -0
- package/skills/review/references/review-todo-structure.md +165 -0
- package/skills/review/references/risk-tier-and-fix-rounds.md +97 -0
- package/skills/review/references/semgrep-custom-rules.yaml +174 -0
- package/skills/review/references/ultrathink-phases.md +98 -0
- package/skills/review/references/wfs.md +6 -0
- package/skills/review/scripts/emit-review-trailer.sh +499 -0
- package/skills/review/scripts/ensure-semgrep.sh +99 -0
- package/skills/review/scripts/fix-round-seats.sh +197 -0
- package/skills/review/test/emit-review-trailer.test.sh +387 -0
- package/skills/review/test/ensure-semgrep.test.sh +111 -0
- package/skills/review/test/fix-round-seats.test.sh +237 -0
- package/skills/review/workflows/README.md +147 -0
- package/skills/review/workflows/review.workflow.js +667 -0
- package/skills/schedule/SKILL.md +796 -0
- package/skills/seo-aeo/SKILL.md +139 -0
- package/skills/seo-aeo/scripts/validate-csp.sh +233 -0
- package/skills/seo-aeo/scripts/validate-seo.sh +262 -0
- package/skills/ship/SKILL.md +3023 -0
- package/skills/ship/references/adr-ordinal-collision.md +47 -0
- package/skills/ship/references/affected-gate-contract.md +115 -0
- package/skills/ship/references/ci-run-diagnosis.md +29 -0
- package/skills/ship/references/ci-workflow-authoring.md +68 -0
- package/skills/ship/references/cleanup-merged-archival.md +39 -0
- package/skills/ship/references/counsel-review-clo-attestation.md +38 -0
- package/skills/ship/references/cto-ruling-armed-push.md +5 -0
- package/skills/ship/references/decision-challenges-render.md +71 -0
- package/skills/ship/references/delegated-act-authoring-form.md +7 -0
- package/skills/ship/references/detached-battery-verdict.md +13 -0
- package/skills/ship/references/epic-close-sweep.md +62 -0
- package/skills/ship/references/feature-tweet-draft.md +42 -0
- package/skills/ship/references/followthrough-issue-body-template.md +47 -0
- package/skills/ship/references/followthrough-stub-template.sh +92 -0
- package/skills/ship/references/merge-queue-dequeue.md +39 -0
- package/skills/ship/references/operator-holds.md +179 -0
- package/skills/ship/references/pipeline-tally-render.md +43 -0
- package/skills/ship/references/pr-overlap.md +153 -0
- package/skills/ship/references/queue-mode.md +7 -0
- package/skills/ship/references/ready-run-wait.md +36 -0
- package/skills/ship/references/red-on-main-quarantine.md +110 -0
- package/skills/ship/references/register-update-pr-pattern.md +88 -0
- package/skills/ship/references/settle-then-admin-merge.md +130 -0
- package/skills/ship/references/supabase-column-probe.md +13 -0
- package/skills/ship/scripts/auto-close-scan.sh +76 -0
- package/skills/ship/scripts/battery-owed.sh +403 -0
- package/skills/ship/scripts/hold-gate-eval.sh +410 -0
- package/skills/ship/scripts/net-issue-flow.sh +665 -0
- package/skills/ship/scripts/pr-overlap-preflight.sh +483 -0
- package/skills/ship/scripts/ship-pir-action-items-gate.sh +246 -0
- package/skills/ship/scripts/technical-ruling-gate.sh +444 -0
- package/skills/skill-creator/SKILL.md +299 -0
- package/skills/skill-creator/references/api-security.md +248 -0
- package/skills/skill-creator/references/authoring-levers.md +110 -0
- package/skills/skill-creator/references/be-clear-and-direct.md +587 -0
- package/skills/skill-creator/references/best-practices.md +431 -0
- package/skills/skill-creator/references/common-patterns.md +639 -0
- package/skills/skill-creator/references/core-principles.md +193 -0
- package/skills/skill-creator/references/executable-code.md +188 -0
- package/skills/skill-creator/references/iteration-and-testing.md +509 -0
- package/skills/skill-creator/references/official-spec.md +193 -0
- package/skills/skill-creator/references/recommended-structure.md +180 -0
- package/skills/skill-creator/references/skill-structure.md +396 -0
- package/skills/skill-creator/references/using-scripts.md +122 -0
- package/skills/skill-creator/references/using-templates.md +120 -0
- package/skills/skill-creator/references/workflows-and-validation.md +541 -0
- package/skills/skill-creator/scripts/init_skill.py +322 -0
- package/skills/skill-creator/scripts/package_skill.py +110 -0
- package/skills/skill-creator/scripts/quick_validate.py +64 -0
- package/skills/skill-creator/templates/router-skill.md +73 -0
- package/skills/skill-creator/templates/simple-skill.md +34 -0
- package/skills/skill-creator/workflows/add-reference.md +96 -0
- package/skills/skill-creator/workflows/add-script.md +104 -0
- package/skills/skill-creator/workflows/add-template.md +83 -0
- package/skills/skill-creator/workflows/add-workflow.md +128 -0
- package/skills/skill-creator/workflows/audit-skill.md +159 -0
- package/skills/skill-creator/workflows/create-domain-expertise-skill.md +623 -0
- package/skills/skill-creator/workflows/create-new-skill.md +207 -0
- package/skills/skill-creator/workflows/get-guidance.md +134 -0
- package/skills/skill-creator/workflows/upgrade-to-router.md +170 -0
- package/skills/skill-creator/workflows/verify-skill.md +226 -0
- package/skills/skill-security-scan/SKILL.md +145 -0
- package/skills/skill-security-scan/references/disclaimer.md +21 -0
- package/skills/skill-security-scan/references/first-party-allowlist.yaml +38 -0
- package/skills/skill-security-scan/references/override-artifact-schema.json +68 -0
- package/skills/skill-security-scan/references/override-mechanism.md +171 -0
- package/skills/skill-security-scan/references/redirect-domains.yaml +27 -0
- package/skills/skill-security-scan/references/regex-patterns.md +136 -0
- package/skills/skill-security-scan/references/rules/code-exec.yaml +70 -0
- package/skills/skill-security-scan/references/rules/filesystem-boundary.yaml +29 -0
- package/skills/skill-security-scan/references/rules/manifest.yaml +44 -0
- package/skills/skill-security-scan/references/rules/supply-chain.yaml +36 -0
- package/skills/skill-security-scan/references/scan-meta-schema.json +63 -0
- package/skills/skill-security-scan/references/test-fixtures/clean-soleur-style.skill.md +23 -0
- package/skills/skill-security-scan/references/test-fixtures/clean-third-party.skill.md +26 -0
- package/skills/skill-security-scan/references/test-fixtures/malicious-codeexec.skill.md +23 -0
- package/skills/skill-security-scan/references/test-fixtures/malicious-curl-pipe-bash.skill.md +69 -0
- package/skills/skill-security-scan/references/test-fixtures/malicious-prompt-injection.skill.md +17 -0
- package/skills/skill-security-scan/references/test-fixtures/malicious-telemetry-beacon.skill.md +23 -0
- package/skills/skill-security-scan/references/typosquat-targets.yaml +65 -0
- package/skills/skill-security-scan/scripts/check-codeexec.sh +41 -0
- package/skills/skill-security-scan/scripts/check-filesystem-boundary.sh +19 -0
- package/skills/skill-security-scan/scripts/check-prompt-injection.sh +95 -0
- package/skills/skill-security-scan/scripts/check-supply-chain.sh +219 -0
- package/skills/skill-security-scan/scripts/check-telemetry-surface.sh +126 -0
- package/skills/skill-security-scan/scripts/lib.sh +197 -0
- package/skills/skill-security-scan/scripts/parse-override.sh +231 -0
- package/skills/skill-security-scan/scripts/run-scan.sh +342 -0
- package/skills/skill-security-scan/scripts/run-self-test.sh +95 -0
- package/skills/skill-security-scan/test/argv-ceiling.test.sh +180 -0
- package/skills/skill-security-scan/test/meta-dir-reap.test.sh +411 -0
- package/skills/skill-security-scan/test/parse-override.test.sh +607 -0
- package/skills/skill-security-scan/test/redact-pii-ghs-shape.test.sh +251 -0
- package/skills/social-distribute/SKILL.md +485 -0
- package/skills/spec-templates/SKILL.md +274 -0
- package/skills/sync/SKILL.md +49 -0
- package/skills/test-browser/SKILL.md +464 -0
- package/skills/test-browser/references/feature-map.md +161 -0
- package/skills/test-fix-loop/SKILL.md +159 -0
- package/skills/test-fix-loop/references/determinism-checklist.md +154 -0
- package/skills/triage/SKILL.md +402 -0
- package/skills/trigger-cron/SKILL.md +136 -0
- package/skills/trigger-cron/scripts/trigger.sh +198 -0
- package/skills/user-set-role/SKILL.md +147 -0
- package/skills/user-set-role/scripts/set-role.sh +218 -0
- package/skills/user-story-writer/SKILL.md +77 -0
- package/skills/ux-audit/SKILL.md +251 -0
- package/skills/ux-audit/references/finding.schema.json +62 -0
- package/skills/ux-audit/references/route-list.yaml +95 -0
- package/skills/ux-audit/scripts/bot-fixture.ts +270 -0
- package/skills/ux-audit/scripts/bot-signin.ts +135 -0
- package/skills/ux-audit/scripts/dedup-hash.ts +46 -0
- package/skills/verification-scaffold/SKILL.md +73 -0
- package/skills/verification-scaffold/references/gitleaks.toml.template +13 -0
- package/skills/verification-scaffold/references/guardrail-audit.md +156 -0
- package/skills/verification-scaffold/references/guards/block-stash-hook.sh.template +72 -0
- package/skills/verification-scaffold/references/guards/commit-on-main-hook.sh.template +82 -0
- package/skills/verification-scaffold/references/guards/orphan-test-check.sh.template +102 -0
- package/skills/verification-scaffold/references/guards/precommit-guard.sh.template +115 -0
- package/skills/verification-scaffold/references/guards/secret-scan-hook.sh.template +176 -0
- package/skills/verification-scaffold/references/guards/verification-gates.yml.template +49 -0
- package/skills/verification-scaffold/references/guards/wrapper-boundary.sh.template +47 -0
- package/skills/verification-scaffold/references/guards.tsv +21 -0
- package/skills/verification-scaffold/references/verification-readme.template +55 -0
- package/skills/verification-scaffold/scripts/verification-scaffold.sh +785 -0
- package/skills/verification-scaffold/test/bite-proof.test.sh +159 -0
- package/skills/verification-scaffold/test/generator.test.sh +319 -0
- package/skills/verification-scaffold/test/manifest.test.sh +144 -0
- package/skills/work/SKILL.md +1480 -0
- package/skills/work/references/end-of-work-resume.md +7 -0
- package/skills/work/references/hook-test-main-cwd.md +24 -0
- package/skills/work/references/key-principles.md +83 -0
- package/skills/work/references/property-testing.md +122 -0
- package/skills/work/references/sql-security-definer-rpc-scaffold.sql +78 -0
- package/skills/work/references/work-agent-teams.md +97 -0
- package/skills/work/references/work-lifecycle-parallel.md +147 -0
- package/skills/work/references/work-lockfile-bumps.md +97 -0
- package/skills/work/references/work-scratch-sandboxes.md +212 -0
- package/skills/work/references/work-subagent-fanout.md +61 -0
- package/skills/work/references/work-test-harness-sharp-edges.md +73 -0
- package/skills/xcode-test/SKILL.md +360 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Bite-proof coverage for verification-scaffold.sh (#10404): installs the v1 set
|
|
3
|
+
# into a fixture repo and drives each emitted guard pass -> fail -> pass —
|
|
4
|
+
# independent of the generator's own internal bite (this suite RE-drives the
|
|
5
|
+
# emitted artifacts as a consumer would). Needs gitleaks on PATH for the
|
|
6
|
+
# secret-scan arm; that arm is skipped loudly when the binary is absent
|
|
7
|
+
# (matching the guard's own contract: a missing scanner is a tool error, not a
|
|
8
|
+
# finding). Runs in the scripts shard. Accumulate-then-exit.
|
|
9
|
+
set -uo pipefail
|
|
10
|
+
export TMPDIR="${TMPDIR:-/var/tmp}"
|
|
11
|
+
|
|
12
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
13
|
+
REPO_ROOT="$(cd "$SCRIPT_DIR/../../../../.." && pwd)"
|
|
14
|
+
GEN="$REPO_ROOT/plugins/soleur/skills/verification-scaffold/scripts/verification-scaffold.sh"
|
|
15
|
+
|
|
16
|
+
passes=0; fails=0
|
|
17
|
+
pass() { printf 'ok - %s\n' "$1"; passes=$((passes + 1)); }
|
|
18
|
+
fail() { printf 'FAIL - %s\n' "$1"; fails=$((fails + 1)); }
|
|
19
|
+
|
|
20
|
+
TMPROOT="$(mktemp -d)"
|
|
21
|
+
# The body below is the CANONICAL copy of assert_fixture_dir (#7652) — do not reword.
|
|
22
|
+
assert_fixture_dir() {
|
|
23
|
+
case "${1-}" in
|
|
24
|
+
"") printf 'FATAL: fixture dir is EMPTY; git -C "" would operate on %s\n' "$PWD" >&2; exit 2 ;;
|
|
25
|
+
*/../*|*/..) printf 'FATAL: fixture dir %s contains ..; refusing\n' "$1" >&2; exit 2 ;;
|
|
26
|
+
/proc/*|/sys/*|/dev/*) printf 'FATAL: fixture dir %s is a synthetic-fs path; refusing\n' "$1" >&2; exit 2 ;;
|
|
27
|
+
/|//|/.) printf 'FATAL: fixture dir resolves to the filesystem root; refusing\n' >&2; exit 2 ;;
|
|
28
|
+
/*) : ;;
|
|
29
|
+
*) printf 'FATAL: fixture dir %s is RELATIVE; refusing\n' "$1" >&2; exit 2 ;;
|
|
30
|
+
esac
|
|
31
|
+
}
|
|
32
|
+
trap 'rm -rf "$TMPROOT"' EXIT
|
|
33
|
+
|
|
34
|
+
mkrepo() { # mkrepo <name> -> committed fixture repo on main
|
|
35
|
+
local d="$TMPROOT/$1"
|
|
36
|
+
mkdir -p "$d"
|
|
37
|
+
git -C "$d" init -q
|
|
38
|
+
git -C "$d" config user.email t@t
|
|
39
|
+
git -C "$d" config user.name t
|
|
40
|
+
local t c
|
|
41
|
+
t="$(git -C "$d" write-tree)"
|
|
42
|
+
c="$(echo init | git -C "$d" commit-tree "$t")"
|
|
43
|
+
git -C "$d" update-ref refs/heads/main "$c"
|
|
44
|
+
git -C "$d" symbolic-ref HEAD refs/heads/main
|
|
45
|
+
printf '%s' "$d"
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
payload() { jq -nc --arg c "$1" --arg w "$2" '{tool_name:"Bash",tool_input:{command:$c},cwd:$w}'; }
|
|
49
|
+
decide() { sed -n 's/.*"permissionDecision": *"\([a-z]*\)".*/\1/p' | head -n 1; }
|
|
50
|
+
|
|
51
|
+
# --- install into the fixture ---------------------------------------------------
|
|
52
|
+
FX="$(mkrepo installed)"; assert_fixture_dir "$FX"
|
|
53
|
+
OUT="$(bash "$GEN" --target "$FX" --headless 2>&1)" || { fail "install failed: $OUT"; printf '\n%d pass(es), %d fail(s)\n' "$passes" "$fails"; exit 1; }
|
|
54
|
+
grep -q 'bite-proof' <<<"$OUT" \
|
|
55
|
+
&& pass "install reports the internal bite-proof per guard" \
|
|
56
|
+
|| fail "install output carries no bite-proof lines: $OUT"
|
|
57
|
+
# The internal bite must have run all four arms (a SKIP is a failure HERE —
|
|
58
|
+
# gitleaks is expected on this host; on a host without it the arm prints SKIP).
|
|
59
|
+
for g in secret-scan commit-on-main block-stash orphan-test; do
|
|
60
|
+
if grep -q "bite-proof $g: pass -> fail" <<<"$OUT"; then
|
|
61
|
+
pass "internal bite-proof: $g pass -> fail -> pass"
|
|
62
|
+
elif [[ "$g" == "secret-scan" ]] && ! command -v gitleaks >/dev/null 2>&1 \
|
|
63
|
+
&& grep -q "bite-proof secret-scan: SKIP" <<<"$OUT"; then
|
|
64
|
+
pass "internal bite-proof: secret-scan SKIP (no gitleaks on PATH — documented)"
|
|
65
|
+
else
|
|
66
|
+
fail "internal bite-proof arm missing or failed for $g: $(grep 'bite-proof' <<<"$OUT" | tr '\n' ';')"
|
|
67
|
+
fi
|
|
68
|
+
done
|
|
69
|
+
|
|
70
|
+
# --- commit-on-main, re-driven against the emitted pair --------------------------
|
|
71
|
+
HOOK="$FX/.claude/hooks/commit-on-main.sh"
|
|
72
|
+
# A fixture repo ON a feature branch: pass arm.
|
|
73
|
+
F2="$TMPROOT/feat-repo"; assert_fixture_dir "$F2"
|
|
74
|
+
mkdir -p "$F2"
|
|
75
|
+
git -C "$F2" init -q; git -C "$F2" config user.email t@t; git -C "$F2" config user.name t
|
|
76
|
+
git -C "$F2" symbolic-ref HEAD refs/heads/main
|
|
77
|
+
t="$(git -C "$F2" write-tree)"; c="$(echo x | git -C "$F2" commit-tree "$t")"; git -C "$F2" update-ref refs/heads/main "$c"
|
|
78
|
+
git -C "$F2" checkout -qb feat-x
|
|
79
|
+
OUT="$(cd "$FX" && payload "git -C $F2 commit -m x" "$F2" | bash "$HOOK")"
|
|
80
|
+
[[ "$(decide <<<"$OUT")" == "allow" ]] && pass "commit-on-main: feature-branch payload allowed" \
|
|
81
|
+
|| fail "commit-on-main feature branch: $OUT"
|
|
82
|
+
# On main: advisory warn+allow with a refusal WARN on stderr.
|
|
83
|
+
git -C "$F2" checkout -q main
|
|
84
|
+
ERR="$TMPROOT/err"; OUT="$(cd "$FX" && payload "git -C $F2 commit -m x" "$F2" | bash "$HOOK" 2>"$ERR")"
|
|
85
|
+
if [[ "$(decide <<<"$OUT")" == "allow" ]] && grep -qE 'not allowed|refused' "$ERR"; then
|
|
86
|
+
pass "commit-on-main: main payload warns+allows (advisory)"
|
|
87
|
+
else
|
|
88
|
+
fail "commit-on-main main arm: out=$OUT err=$(cat "$ERR")"
|
|
89
|
+
fi
|
|
90
|
+
# Enforce flip is one line: MODE=enforce denies.
|
|
91
|
+
sed 's/^MODE="advisory"$/MODE="enforce"/' "$HOOK" > "$TMPROOT/hook-enf.sh"
|
|
92
|
+
OUT="$(cd "$FX" && payload "git -C $F2 commit -m x" "$F2" | bash "$TMPROOT/hook-enf.sh" 2>/dev/null)"
|
|
93
|
+
[[ "$(decide <<<"$OUT")" == "deny" ]] && pass "commit-on-main: MODE=enforce flip denies (one-line promotion)" \
|
|
94
|
+
|| fail "enforce flip did not deny: $OUT"
|
|
95
|
+
|
|
96
|
+
# --- block-stash ------------------------------------------------------------------
|
|
97
|
+
HOOK="$FX/.claude/hooks/block-stash.sh"
|
|
98
|
+
OUT="$(cd "$FX" && payload "git status" "$FX" | bash "$HOOK")"
|
|
99
|
+
[[ "$(decide <<<"$OUT")" == "allow" ]] && pass "block-stash: git status allowed" \
|
|
100
|
+
|| fail "block-stash status: $OUT"
|
|
101
|
+
ERR="$TMPROOT/err2"; OUT="$(cd "$FX" && payload "git add x && git stash pop" "$FX" | bash "$HOOK" 2>"$ERR")"
|
|
102
|
+
if [[ "$(decide <<<"$OUT")" == "allow" ]] && grep -q 'not allowed' "$ERR"; then
|
|
103
|
+
pass "block-stash: chained 'git stash pop' warns+allows"
|
|
104
|
+
else
|
|
105
|
+
fail "block-stash stash arm: out=$OUT err=$(cat "$ERR")"
|
|
106
|
+
fi
|
|
107
|
+
OUT="$(cd "$FX" && payload "git stash list" "$FX" | bash "$HOOK")"
|
|
108
|
+
[[ "$(decide <<<"$OUT")" == "allow" ]] && pass "block-stash: read-only 'git stash list' allowed" \
|
|
109
|
+
|| fail "block-stash stash list: $OUT"
|
|
110
|
+
|
|
111
|
+
# --- orphan-test ------------------------------------------------------------------
|
|
112
|
+
CHECK="$FX/scripts/verification/orphan-test-check.sh"
|
|
113
|
+
OUT="$(cd "$FX" && bash "$CHECK" 2>&1)" && pass "orphan-test: clean tree passes" \
|
|
114
|
+
|| fail "orphan-test clean tree: $OUT"
|
|
115
|
+
printf '#!/usr/bin/env bash\nexit 0\n' > "$FX/scratch.test.sh"
|
|
116
|
+
git -C "$FX" add scratch.test.sh
|
|
117
|
+
RC=0; OUT="$(cd "$FX" && bash "$CHECK" 2>&1)" || RC=$?
|
|
118
|
+
if [[ "$RC" -ne 0 && "$OUT" == *scratch.test.sh* ]]; then
|
|
119
|
+
pass "orphan-test: injected unregistered suite named by path"
|
|
120
|
+
else
|
|
121
|
+
fail "orphan-test injected suite: rc=$RC out=$OUT"
|
|
122
|
+
fi
|
|
123
|
+
# Reason-carrying exclusion registers it.
|
|
124
|
+
printf 'scratch.test.sh # deliberate exclusion for the bite suite\n' >> "$FX/.github/verification-known-orphans.txt"
|
|
125
|
+
OUT="$(cd "$FX" && bash "$CHECK" 2>&1)" && pass "orphan-test: reasoned exclusion passes" \
|
|
126
|
+
|| fail "orphan-test exclusion arm: $OUT"
|
|
127
|
+
# A reasonless exclusion line is itself a finding.
|
|
128
|
+
printf 'scratch.test.sh\n' >> "$FX/.github/verification-known-orphans.txt"
|
|
129
|
+
RC=0; OUT="$(cd "$FX" && bash "$CHECK" 2>&1)" || RC=$?
|
|
130
|
+
[[ "$RC" -ne 0 && "$OUT" == *reasonless* ]] && pass "orphan-test: reasonless exclusion is a finding" \
|
|
131
|
+
|| fail "orphan-test reasonless arm: rc=$RC out=$OUT"
|
|
132
|
+
git -C "$FX" rm -q --cached scratch.test.sh 2>/dev/null; rm -f "$FX/scratch.test.sh"
|
|
133
|
+
git -C "$FX" checkout -q -- .github/verification-known-orphans.txt 2>/dev/null \
|
|
134
|
+
|| git -C "$FX" restore --staged --worktree .github/verification-known-orphans.txt 2>/dev/null || true
|
|
135
|
+
|
|
136
|
+
# --- secret-scan (skipped without gitleaks) ---------------------------------------
|
|
137
|
+
HOOK="$FX/.claude/hooks/secret-scan.sh"
|
|
138
|
+
if command -v gitleaks >/dev/null 2>&1; then
|
|
139
|
+
printf 'x\n' > "$FX/clean.txt"; git -C "$FX" add clean.txt
|
|
140
|
+
OUT="$(cd "$FX" && payload "git commit -m x" "$FX" | bash "$HOOK" 2>/dev/null)"
|
|
141
|
+
[[ "$(decide <<<"$OUT")" == "allow" ]] && pass "secret-scan: clean staged file allows" \
|
|
142
|
+
|| fail "secret-scan clean arm: $OUT"
|
|
143
|
+
# Synthetic-but-shaped secret (the AWS docs example key is allowlisted in
|
|
144
|
+
# gitleaks's default ruleset — this variant keeps the 40-char shape only).
|
|
145
|
+
printf 'AWS_SECRET_ACCESS_KEY = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYSYNTHETIC0"\n' > "$FX/secret.txt"
|
|
146
|
+
git -C "$FX" add secret.txt
|
|
147
|
+
OUT="$(cd "$FX" && payload "git commit -m x" "$FX" | bash "$HOOK" 2>/dev/null)"
|
|
148
|
+
[[ "$(decide <<<"$OUT")" == "ask" ]] && pass "secret-scan: staged secret surfaces as ask (advisory)" \
|
|
149
|
+
|| fail "secret-scan secret arm: $OUT"
|
|
150
|
+
git -C "$FX" rm -q --cached secret.txt; rm -f "$FX/secret.txt"
|
|
151
|
+
OUT="$(cd "$FX" && payload "git commit -m x" "$FX" | bash "$HOOK" 2>/dev/null)"
|
|
152
|
+
[[ "$(decide <<<"$OUT")" == "allow" ]] && pass "secret-scan: reverted tree allows again" \
|
|
153
|
+
|| fail "secret-scan revert arm: $OUT"
|
|
154
|
+
else
|
|
155
|
+
pass "secret-scan arms skipped (no gitleaks on PATH — the hook warns+allows per commit)"
|
|
156
|
+
fi
|
|
157
|
+
|
|
158
|
+
printf '\n%d pass(es), %d fail(s)\n' "$passes" "$fails"
|
|
159
|
+
[[ "$fails" -eq 0 ]]
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Generator coverage for verification-scaffold.sh (#10404) against HERMETIC
|
|
3
|
+
# fixture repos — a throwaway `git init` per arm under a mktemp dir. Covers the
|
|
4
|
+
# flag/exit-matrix paths that need no gitleaks:
|
|
5
|
+
# 64 --mode bogus; unknown guard
|
|
6
|
+
# 65 --target outside a git work tree
|
|
7
|
+
# 66 refuse-if-exists (pre-placed artifact; full second run)
|
|
8
|
+
# 69 malformed .claude/settings.json refused BEFORE any write
|
|
9
|
+
# settings merge: absent created, unrelated keys preserved, re-run dedupe
|
|
10
|
+
# --dry-run writes nothing; --uninstall is surgical + idempotent
|
|
11
|
+
# --guards subset emits only that guard's artifacts
|
|
12
|
+
# Runs in the scripts shard. Accumulate-then-exit.
|
|
13
|
+
set -uo pipefail
|
|
14
|
+
export TMPDIR="${TMPDIR:-/var/tmp}"
|
|
15
|
+
|
|
16
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
17
|
+
REPO_ROOT="$(cd "$SCRIPT_DIR/../../../../.." && pwd)"
|
|
18
|
+
GEN="$REPO_ROOT/plugins/soleur/skills/verification-scaffold/scripts/verification-scaffold.sh"
|
|
19
|
+
|
|
20
|
+
passes=0; fails=0
|
|
21
|
+
pass() { printf 'ok - %s\n' "$1"; passes=$((passes + 1)); }
|
|
22
|
+
fail() { printf 'FAIL - %s\n' "$1"; fails=$((fails + 1)); }
|
|
23
|
+
|
|
24
|
+
TMPROOT="$(mktemp -d)"
|
|
25
|
+
# The body below is the CANONICAL copy of assert_fixture_dir (#7652) — do not reword.
|
|
26
|
+
assert_fixture_dir() {
|
|
27
|
+
case "${1-}" in
|
|
28
|
+
"") printf 'FATAL: fixture dir is EMPTY; git -C "" would operate on %s\n' "$PWD" >&2; exit 2 ;;
|
|
29
|
+
*/../*|*/..) printf 'FATAL: fixture dir %s contains ..; refusing\n' "$1" >&2; exit 2 ;;
|
|
30
|
+
/proc/*|/sys/*|/dev/*) printf 'FATAL: fixture dir %s is a synthetic-fs path; refusing\n' "$1" >&2; exit 2 ;;
|
|
31
|
+
/|//|/.) printf 'FATAL: fixture dir resolves to the filesystem root; refusing\n' >&2; exit 2 ;;
|
|
32
|
+
/*) : ;;
|
|
33
|
+
*) printf 'FATAL: fixture dir %s is RELATIVE; refusing\n' "$1" >&2; exit 2 ;;
|
|
34
|
+
esac
|
|
35
|
+
}
|
|
36
|
+
trap 'rm -rf "$TMPROOT"' EXIT
|
|
37
|
+
|
|
38
|
+
mkrepo() { # mkrepo <name> -> fixture git repo path (empty tree, one commit)
|
|
39
|
+
local d="$TMPROOT/$1"
|
|
40
|
+
mkdir -p "$d"
|
|
41
|
+
git -C "$d" init -q
|
|
42
|
+
git -C "$d" config user.email t@t
|
|
43
|
+
git -C "$d" config user.name t
|
|
44
|
+
local t c
|
|
45
|
+
t="$(git -C "$d" write-tree)"
|
|
46
|
+
c="$(echo init | git -C "$d" commit-tree "$t")"
|
|
47
|
+
git -C "$d" update-ref refs/heads/main "$c"
|
|
48
|
+
git -C "$d" symbolic-ref HEAD refs/heads/main
|
|
49
|
+
printf '%s' "$d"
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
run_gen() { # run_gen <repo> <args...> -> rc (never aborts the suite)
|
|
53
|
+
local root="$1"; shift
|
|
54
|
+
local rc=0
|
|
55
|
+
bash "$GEN" --target "$root" "$@" >/dev/null 2>&1 || rc=$?
|
|
56
|
+
printf '%s' "$rc"
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
run_gen_out() { # run_gen_out <repo> <args...> -> "rc|stdout"
|
|
60
|
+
local root="$1"; shift
|
|
61
|
+
local rc=0 out
|
|
62
|
+
out="$(bash "$GEN" --target "$root" "$@" 2>/dev/null)" || rc=$?
|
|
63
|
+
printf '%s|%s' "$rc" "$out"
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
# --- 65: not a git work tree ---------------------------------------------------
|
|
67
|
+
NOTREPO="$TMPROOT/notrepo"; mkdir -p "$NOTREPO"
|
|
68
|
+
RC="$(run_gen "$NOTREPO" --headless)"
|
|
69
|
+
[[ "$RC" == "65" ]] && pass "exit 65: target outside a git work tree refused" \
|
|
70
|
+
|| fail "expected 65 for non-repo target, got $RC"
|
|
71
|
+
|
|
72
|
+
# --- 64: --mode bogus / unknown guard -------------------------------------------
|
|
73
|
+
FX="$(mkrepo modebogus)"; assert_fixture_dir "$FX"
|
|
74
|
+
RC="$(run_gen "$FX" --mode bogus --headless)"
|
|
75
|
+
[[ "$RC" == "64" ]] && pass "exit 64: --mode bogus refused pre-write" \
|
|
76
|
+
|| fail "expected 64 for --mode bogus, got $RC"
|
|
77
|
+
RC="$(run_gen "$FX" --guards nosuchguard --headless)"
|
|
78
|
+
[[ "$RC" == "64" ]] && pass "exit 64: unknown guard refused" \
|
|
79
|
+
|| fail "expected 64 for unknown guard, got $RC"
|
|
80
|
+
|
|
81
|
+
# --- 69: malformed settings.json refused BEFORE any write -----------------------
|
|
82
|
+
FX="$(mkrepo badsettings)"; assert_fixture_dir "$FX"
|
|
83
|
+
mkdir -p "$FX/.claude"
|
|
84
|
+
printf '{not json' > "$FX/.claude/settings.json"
|
|
85
|
+
RC="$(run_gen "$FX" --headless)"
|
|
86
|
+
if [[ "$RC" == "69" ]] && [[ ! -e "$FX/.claude/hooks/secret-scan.sh" ]] \
|
|
87
|
+
&& [[ "$(cat "$FX/.claude/settings.json")" == '{not json' ]]; then
|
|
88
|
+
pass "exit 69: malformed settings.json refused before any write (file untouched)"
|
|
89
|
+
else
|
|
90
|
+
fail "malformed settings.json arm: rc=$RC settings=$(cat "$FX/.claude/settings.json" 2>/dev/null)"
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
# --- 66: pre-existing artifact refuses -------------------------------------------
|
|
94
|
+
FX="$(mkrepo collides)"; assert_fixture_dir "$FX"
|
|
95
|
+
mkdir -p "$FX/.claude/hooks"
|
|
96
|
+
printf '# mine\n' > "$FX/.claude/hooks/secret-scan.sh"
|
|
97
|
+
RC="$(run_gen "$FX" --headless)"
|
|
98
|
+
[[ "$RC" == "66" && "$(cat "$FX/.claude/hooks/secret-scan.sh")" == '# mine' ]] \
|
|
99
|
+
&& pass "exit 66: pre-existing hook refuses, zero writes (file untouched)" \
|
|
100
|
+
|| fail "expected 66 with untouched file, got rc=$RC"
|
|
101
|
+
|
|
102
|
+
# pre-existing .gitleaks.toml also refuses (AC5)
|
|
103
|
+
FX="$(mkrepo glcollide)"; assert_fixture_dir "$FX"
|
|
104
|
+
printf '[extend]\nuseDefault = false\n' > "$FX/.gitleaks.toml"
|
|
105
|
+
RC="$(run_gen "$FX" --headless)"
|
|
106
|
+
[[ "$RC" == "66" && "$(cat "$FX/.gitleaks.toml")" == "[extend]
|
|
107
|
+
useDefault = false" ]] \
|
|
108
|
+
&& pass "exit 66: pre-existing .gitleaks.toml refuses (never overwrites a user ruleset)" \
|
|
109
|
+
|| fail "expected 66 for pre-existing .gitleaks.toml, got rc=$RC"
|
|
110
|
+
|
|
111
|
+
# --- --guards subset -------------------------------------------------------------
|
|
112
|
+
FX="$(mkrepo subset)"; assert_fixture_dir "$FX"
|
|
113
|
+
RC="$(run_gen "$FX" --guards block-stash --headless)"
|
|
114
|
+
if [[ "$RC" == "0" && -f "$FX/.claude/hooks/block-stash.sh" \
|
|
115
|
+
&& ! -e "$FX/.claude/hooks/secret-scan.sh" && ! -e "$FX/.github/workflows/verification-gates.yml" ]]; then
|
|
116
|
+
pass "--guards block-stash emits only that guard's artifacts"
|
|
117
|
+
else
|
|
118
|
+
fail "subset install wrong: rc=$RC $(ls "$FX/.claude/hooks" 2>/dev/null | tr '\n' ' ')"
|
|
119
|
+
fi
|
|
120
|
+
grep -q 'block-stash' "$FX/.claude/settings.json" 2>/dev/null \
|
|
121
|
+
&& pass "subset install registered the hook in settings.json" \
|
|
122
|
+
|| fail "subset install: no settings.json hook entry"
|
|
123
|
+
|
|
124
|
+
# --- --dry-run writes nothing ----------------------------------------------------
|
|
125
|
+
FX="$(mkrepo dryrun)"; assert_fixture_dir "$FX"
|
|
126
|
+
OUT="$(run_gen_out "$FX" --dry-run)"
|
|
127
|
+
if [[ "${OUT%%|*}" == "0" && ! -e "$FX/.claude/hooks/secret-scan.sh" && ! -e "$FX/.claude/settings.json" ]]; then
|
|
128
|
+
pass "--dry-run exits 0 and writes nothing"
|
|
129
|
+
else
|
|
130
|
+
fail "dry-run arm: rc=${OUT%%|*}"
|
|
131
|
+
fi
|
|
132
|
+
|
|
133
|
+
# --- full install + advisory markers (AC3) ---------------------------------------
|
|
134
|
+
FX="$(mkrepo full)"; assert_fixture_dir "$FX"
|
|
135
|
+
RC="$(run_gen "$FX" --headless)"
|
|
136
|
+
[[ "$RC" == "0" ]] || fail "advisory install failed rc=$RC"
|
|
137
|
+
G=1
|
|
138
|
+
for p in .claude/hooks/secret-scan.sh .claude/hooks/commit-on-main.sh .claude/hooks/block-stash.sh \
|
|
139
|
+
scripts/verification/precommit-guard.sh scripts/verification/lib/wrapper-boundary.sh \
|
|
140
|
+
scripts/verification/orphan-test-check.sh .gitleaks.toml \
|
|
141
|
+
.github/workflows/verification-gates.yml .github/verification-known-orphans.txt \
|
|
142
|
+
.claude/settings.json VERIFICATION.md; do
|
|
143
|
+
[[ -f "$FX/$p" ]] || { G=0; fail "missing emitted artifact: $p"; }
|
|
144
|
+
done
|
|
145
|
+
[[ "$G" == "1" ]] && pass "advisory install emits all v1 artifacts"
|
|
146
|
+
grep -q 'MODE="advisory"' "$FX/.claude/hooks/secret-scan.sh" \
|
|
147
|
+
&& grep -q 'MODE="advisory"' "$FX/.claude/hooks/commit-on-main.sh" \
|
|
148
|
+
&& grep -q 'MODE="advisory"' "$FX/.claude/hooks/block-stash.sh" \
|
|
149
|
+
&& pass "advisory install stamps MODE=advisory in every hook" \
|
|
150
|
+
|| fail "MODE=advisory stamp missing in an emitted hook"
|
|
151
|
+
test "$(grep -c 'continue-on-error: true' "$FX/.github/workflows/verification-gates.yml")" = 2 \
|
|
152
|
+
&& pass "advisory workflow carries continue-on-error: true on both jobs" \
|
|
153
|
+
|| fail "advisory workflow continue-on-error wrong: $(grep -c 'continue-on-error' "$FX/.github/workflows/verification-gates.yml")"
|
|
154
|
+
if grep -rqE '@(MODE|CI_CONTINUE_ON_ERROR|DEFAULT_BRANCHES|GUARD_LIST|GUARD_TABLE|DATE)@' \
|
|
155
|
+
"$FX/.claude/hooks" "$FX/scripts/verification" "$FX/.github/workflows/verification-gates.yml" "$FX/VERIFICATION.md" 2>/dev/null; then
|
|
156
|
+
fail "unsubstituted placeholder leaked into emitted artifacts"
|
|
157
|
+
else
|
|
158
|
+
pass "no unsubstituted @PLACEHOLDER@ leaks into emitted artifacts"
|
|
159
|
+
fi
|
|
160
|
+
grep -q 'verification-scaffold:readme:start' "$FX/VERIFICATION.md" \
|
|
161
|
+
&& pass "VERIFICATION.md created with the marker-keyed doc block" \
|
|
162
|
+
|| fail "VERIFICATION.md doc block missing"
|
|
163
|
+
|
|
164
|
+
# settings.json: hook entries present, dedupe on command string
|
|
165
|
+
node -e '
|
|
166
|
+
const d = JSON.parse(require("fs").readFileSync(process.argv[1], "utf8"));
|
|
167
|
+
const cmds = d.hooks.PreToolUse.flatMap(m => m.hooks.map(h => h.command));
|
|
168
|
+
for (const n of ["secret-scan", "commit-on-main", "block-stash"])
|
|
169
|
+
if (!cmds.some(c => c.includes("/.claude/hooks/" + n + ".sh"))) process.exit(3);
|
|
170
|
+
' "$FX/.claude/settings.json" \
|
|
171
|
+
&& pass "settings.json registers all three hook commands" \
|
|
172
|
+
|| fail "settings.json hook entries missing"
|
|
173
|
+
|
|
174
|
+
# --- enforce mode flips only the decision verb (AC3/Guard 6) ---------------------
|
|
175
|
+
FX="$(mkrepo enforce)"; assert_fixture_dir "$FX"
|
|
176
|
+
RC="$(run_gen "$FX" --mode enforce --headless)"
|
|
177
|
+
if [[ "$RC" == "0" ]]; then
|
|
178
|
+
grep -q 'MODE="enforce"' "$FX/.claude/hooks/block-stash.sh" \
|
|
179
|
+
&& grep -q 'continue-on-error: false' "$FX/.github/workflows/verification-gates.yml" \
|
|
180
|
+
&& pass "enforce install stamps MODE=enforce + continue-on-error: false" \
|
|
181
|
+
|| fail "enforce stamps wrong"
|
|
182
|
+
else
|
|
183
|
+
fail "enforce install failed rc=$RC"
|
|
184
|
+
fi
|
|
185
|
+
|
|
186
|
+
# --- re-run refuses (AC5) ---------------------------------------------------------
|
|
187
|
+
RC="$(run_gen "$FX" --headless)"
|
|
188
|
+
[[ "$RC" == "66" ]] && pass "second full run refuses (66), zero writes" \
|
|
189
|
+
|| fail "expected 66 on second run, got $RC"
|
|
190
|
+
|
|
191
|
+
# --- idempotent merge: manually re-add the same command -> stays single ----------
|
|
192
|
+
# (The generator refuses before reaching the merge, so prove dedupe via a repo
|
|
193
|
+
# whose ONLY drift is a missing settings entry while artifacts exist is refused
|
|
194
|
+
# anyway — instead assert the emitted file itself: a merge that ran twice would
|
|
195
|
+
# carry two identical command strings.)
|
|
196
|
+
node -e '
|
|
197
|
+
const d = JSON.parse(require("fs").readFileSync(process.argv[1], "utf8"));
|
|
198
|
+
const cmds = d.hooks.PreToolUse.flatMap(m => m.hooks.map(h => h.command));
|
|
199
|
+
if (new Set(cmds).size !== cmds.length) process.exit(3);
|
|
200
|
+
' "$FX/.claude/settings.json" \
|
|
201
|
+
&& pass "settings.json has no duplicate hook commands" \
|
|
202
|
+
|| fail "duplicate hook commands in settings.json"
|
|
203
|
+
|
|
204
|
+
# --- merge preserves unrelated entries ------------------------------------------
|
|
205
|
+
FX="$(mkrepo preserve)"; assert_fixture_dir "$FX"
|
|
206
|
+
mkdir -p "$FX/.claude"
|
|
207
|
+
printf '%s\n' '{"permissions":{"allow":["Bash(ls:*)"]},"hooks":{"PreToolUse":[{"matcher":"Write","hooks":[{"type":"command","command":"keepme"}]}]}}' > "$FX/.claude/settings.json"
|
|
208
|
+
RC="$(run_gen "$FX" --guards block-stash --headless)"
|
|
209
|
+
if [[ "$RC" == "0" ]]; then
|
|
210
|
+
node -e '
|
|
211
|
+
const d = JSON.parse(require("fs").readFileSync(process.argv[1], "utf8"));
|
|
212
|
+
const ok = d.permissions.allow.includes("Bash(ls:*)")
|
|
213
|
+
&& d.hooks.PreToolUse.some(m => m.hooks.some(h => h.command === "keepme"))
|
|
214
|
+
&& d.hooks.PreToolUse.some(m => m.hooks.some(h => h.command.includes("block-stash")));
|
|
215
|
+
process.exit(ok ? 0 : 3);
|
|
216
|
+
' "$FX/.claude/settings.json" \
|
|
217
|
+
&& pass "merge preserves unrelated permissions + hook entries" \
|
|
218
|
+
|| fail "merge clobbered unrelated settings.json entries"
|
|
219
|
+
else
|
|
220
|
+
fail "preserve install failed rc=$RC"
|
|
221
|
+
fi
|
|
222
|
+
|
|
223
|
+
# --- --uninstall: surgical + idempotent (AC5/SpecFlow 5) --------------------------
|
|
224
|
+
RC="$(run_gen "$FX" --uninstall block-stash)"
|
|
225
|
+
if [[ "$RC" == "0" && ! -e "$FX/.claude/hooks/block-stash.sh" ]]; then
|
|
226
|
+
node -e '
|
|
227
|
+
const d = JSON.parse(require("fs").readFileSync(process.argv[1], "utf8"));
|
|
228
|
+
const cmds = d.hooks.PreToolUse.flatMap(m => m.hooks.map(h => h.command));
|
|
229
|
+
process.exit(cmds.some(c => c.includes("block-stash")) || !cmds.includes("keepme") ? 3 : 0);
|
|
230
|
+
' "$FX/.claude/settings.json" \
|
|
231
|
+
&& pass "--uninstall removes the artifact + settings entry, leaves siblings" \
|
|
232
|
+
|| fail "uninstall left a block-stash settings entry or removed keepme"
|
|
233
|
+
else
|
|
234
|
+
fail "uninstall block-stash: rc=$RC artifact=$(ls "$FX/.claude/hooks" 2>/dev/null | tr '\n' ' ')"
|
|
235
|
+
fi
|
|
236
|
+
RC="$(run_gen "$FX" --uninstall block-stash)"
|
|
237
|
+
[[ "$RC" == "0" ]] && pass "--uninstall on a removed guard is a clean no-op (exit 0)" \
|
|
238
|
+
|| fail "idempotent uninstall expected rc=0, got $RC"
|
|
239
|
+
|
|
240
|
+
# --- --list ----------------------------------------------------------------------
|
|
241
|
+
OUT="$(run_gen_out "$FX" --list)"
|
|
242
|
+
[[ "${OUT%%|*}" == "0" ]] && grep -q 'secret-scan' <<<"${OUT#*|}" \
|
|
243
|
+
&& pass "--list prints the guard manifest" \
|
|
244
|
+
|| fail "--list failed: ${OUT%%|*}"
|
|
245
|
+
|
|
246
|
+
# --- 64: a v2-candidate guard is refused (#10759) --------------------------------
|
|
247
|
+
FX="$(mkrepo v2refuse)"; assert_fixture_dir "$FX"
|
|
248
|
+
RC="$(run_gen "$FX" --guards block-rm-rf --headless)"
|
|
249
|
+
[[ "$RC" == "64" && ! -e "$FX/.claude/hooks/block-rm-rf.sh" ]] \
|
|
250
|
+
&& pass "exit 64: v2-candidate guard refused, nothing emitted" \
|
|
251
|
+
|| fail "expected 64 for v2-tier guard, got $RC"
|
|
252
|
+
|
|
253
|
+
# --- 69: TMPDIR resolving inside the repo is refused pre-write (#10759) ----------
|
|
254
|
+
FX="$(mkrepo tmpinside)"; assert_fixture_dir "$FX"
|
|
255
|
+
mkdir -p "$FX/tmp"
|
|
256
|
+
RC=0; TMPDIR="$FX/tmp" bash "$GEN" --target "$FX" --headless >/dev/null 2>&1 || RC=$?
|
|
257
|
+
if [[ "$RC" == "69" && ! -e "$FX/.claude/hooks/secret-scan.sh" && ! -e "$FX/.claude/settings.json" ]]; then
|
|
258
|
+
pass "exit 69: TMPDIR inside the target repo refused before any artifact"
|
|
259
|
+
else
|
|
260
|
+
fail "TMPDIR-inside-repo arm: expected 69, got rc=$RC"
|
|
261
|
+
fi
|
|
262
|
+
|
|
263
|
+
# --- --uninstall secret-scan: strip only its job from the shared workflow --------
|
|
264
|
+
FX="$(mkrepo jobstrip)"; assert_fixture_dir "$FX"
|
|
265
|
+
RC="$(run_gen "$FX" --guards secret-scan,orphan-test --headless)"
|
|
266
|
+
[[ "$RC" == "0" ]] || fail "secret-scan+orphan-test install failed rc=$RC"
|
|
267
|
+
OUT="$(run_gen_out "$FX" --uninstall secret-scan)"
|
|
268
|
+
if [[ "${OUT%%|*}" == "0" && "${OUT#*|}" == *job-stripped* \
|
|
269
|
+
&& -f "$FX/.github/workflows/verification-gates.yml" \
|
|
270
|
+
&& -f "$FX/scripts/verification/orphan-test-check.sh" \
|
|
271
|
+
&& ! -e "$FX/.claude/hooks/secret-scan.sh" && ! -e "$FX/.gitleaks.toml" ]]; then
|
|
272
|
+
pass "--uninstall secret-scan strips only its job block from the shared workflow"
|
|
273
|
+
else
|
|
274
|
+
fail "shared-artifact uninstall arm: rc=${OUT%%|*} out=${OUT#*|}"
|
|
275
|
+
fi
|
|
276
|
+
WF="$FX/.github/workflows/verification-gates.yml"
|
|
277
|
+
if grep -qF '# verification-scaffold:begin:orphan-test' "$WF" \
|
|
278
|
+
&& ! grep -qF 'verification-scaffold:begin:secret-scan' "$WF"; then
|
|
279
|
+
pass "shared workflow keeps the orphan-test job, drops secret-scan's"
|
|
280
|
+
else
|
|
281
|
+
fail "shared workflow job blocks wrong after strip: $(grep -c 'begin:' "$WF" 2>/dev/null)"
|
|
282
|
+
fi
|
|
283
|
+
|
|
284
|
+
# --- --uninstall of a never-installed ci guard: no phantom job-strip (#10759) -----
|
|
285
|
+
FX="$(mkrepo neverci)"; assert_fixture_dir "$FX"
|
|
286
|
+
RC="$(run_gen "$FX" --guards secret-scan --headless)"
|
|
287
|
+
[[ "$RC" == "0" ]] || fail "secret-scan-only install failed rc=$RC"
|
|
288
|
+
OUT="$(run_gen_out "$FX" --uninstall orphan-test)"
|
|
289
|
+
if [[ "${OUT%%|*}" == "0" && "${OUT#*|}" == *"not installed"* && "${OUT#*|}" != *"job-stripped"* ]]; then
|
|
290
|
+
pass "--uninstall of a never-installed ci guard reports not-installed (no phantom job-strip)"
|
|
291
|
+
else
|
|
292
|
+
fail "never-installed ci guard arm: rc=${OUT%%|*} out=${OUT#*|}"
|
|
293
|
+
fi
|
|
294
|
+
grep -qF 'verification-scaffold:begin:secret-scan' "$FX/.github/workflows/verification-gates.yml" \
|
|
295
|
+
&& pass "shared workflow untouched by the never-installed guard's uninstall" \
|
|
296
|
+
|| fail "workflow lost its secret-scan block on a phantom uninstall"
|
|
297
|
+
|
|
298
|
+
# --- doc block is pruned once no v1 artifact remains (#10759) --------------------
|
|
299
|
+
OUT="$(run_gen_out "$FX" --uninstall secret-scan)"
|
|
300
|
+
if [[ "${OUT%%|*}" == "0" && ! -e "$FX/VERIFICATION.md" \
|
|
301
|
+
&& ! -e "$FX/.github/workflows/verification-gates.yml" ]]; then
|
|
302
|
+
pass "last-guard uninstall prunes the stale VERIFICATION.md marker block"
|
|
303
|
+
else
|
|
304
|
+
fail "doc-block prune arm: rc=${OUT%%|*} VERIFICATION.md=$(ls "$FX/VERIFICATION.md" 2>/dev/null || echo absent)"
|
|
305
|
+
fi
|
|
306
|
+
|
|
307
|
+
# --- default branch named a&b still emits a working regex (#10759) ----------------
|
|
308
|
+
FX="$(mkrepo ampbranch)"; assert_fixture_dir "$FX"
|
|
309
|
+
git -C "$FX" update-ref refs/remotes/origin/a\&b "$(git -C "$FX" rev-parse HEAD)"
|
|
310
|
+
git -C "$FX" symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/a\&b
|
|
311
|
+
RC="$(run_gen "$FX" --guards commit-on-main --mode enforce --headless)"
|
|
312
|
+
if [[ "$RC" == "0" ]] && ! grep -qF '@DEFAULT_BRANCHES@' "$FX/scripts/verification/precommit-guard.sh"; then
|
|
313
|
+
pass "default branch 'a&b': emitted regex is literal — enforce install + bite green"
|
|
314
|
+
else
|
|
315
|
+
fail "a&b default-branch arm: rc=$RC"
|
|
316
|
+
fi
|
|
317
|
+
|
|
318
|
+
printf '\n%d pass(es), %d fail(s)\n' "$passes" "$fails"
|
|
319
|
+
[[ "$fails" -eq 0 ]]
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Manifest consistency for verification-scaffold (#10404):
|
|
3
|
+
# 1. every guards.tsv v1 row's templates exist under references/, and every
|
|
4
|
+
# references/guards/*.template is named by some v1 row (no orphans either way);
|
|
5
|
+
# 2. every audit corpus member (.claude/hooks/**/*.sh non-test + scripts/lint-*
|
|
6
|
+
# minus .test.sh/.baseline.txt/.highwater) appears in guardrail-audit.md —
|
|
7
|
+
# the census is git-ls-files driven, so a NEW unclassified member reds CI;
|
|
8
|
+
# 3. one-hunk parity (AC11): precommit-guard.sh.template renders byte-identical
|
|
9
|
+
# to plugins/soleur/scripts/precommit-guard.sh under the default
|
|
10
|
+
# main|master substitution and the VERIFICATION_->SOLEUR_ rename; the
|
|
11
|
+
# wrapper-boundary pair is the same rename-normalized cmp;
|
|
12
|
+
# 4. emitted-content hygiene (AC8): zero SOLEUR_/knowledge-base//plugins/soleur
|
|
13
|
+
# refs and zero curl|wget|https?:// tokens outside comments in templates;
|
|
14
|
+
# 5. portability floor: no GNU-only tokens (sed -i, readlink -f, stat -c,
|
|
15
|
+
# date -d, bc, /usr/bin/time, unguarded `timeout`) in emitted templates;
|
|
16
|
+
# 6. the emitted verification-gates.yml renders actionlint-clean (when
|
|
17
|
+
# actionlint is on PATH).
|
|
18
|
+
# Runs in the scripts shard. Accumulate-then-exit.
|
|
19
|
+
set -uo pipefail
|
|
20
|
+
|
|
21
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
22
|
+
REPO_ROOT="$(cd "$SCRIPT_DIR/../../../../.." && pwd)"
|
|
23
|
+
SKILL="$REPO_ROOT/plugins/soleur/skills/verification-scaffold"
|
|
24
|
+
TSV="$SKILL/references/guards.tsv"
|
|
25
|
+
AUDIT="$SKILL/references/guardrail-audit.md"
|
|
26
|
+
|
|
27
|
+
passes=0; fails=0
|
|
28
|
+
pass() { printf 'ok - %s\n' "$1"; passes=$((passes + 1)); }
|
|
29
|
+
fail() { printf 'FAIL - %s\n' "$1"; fails=$((fails + 1)); }
|
|
30
|
+
|
|
31
|
+
# --- 1. guards.tsv v1 rows <-> templates -----------------------------------------
|
|
32
|
+
missing=0
|
|
33
|
+
while IFS=$'\t' read -r name verdict surfaces templates dmode deps src emits tier; do
|
|
34
|
+
case "$name" in \#*|name) continue ;; esac
|
|
35
|
+
[[ "$tier" == "v1" ]] || continue
|
|
36
|
+
[[ -n "$name" && -n "$templates" && -n "$emits" ]] || { fail "guards.tsv row malformed: $name"; missing=1; continue; }
|
|
37
|
+
IFS=';' read -ra tp <<<"$templates"
|
|
38
|
+
for t in "${tp[@]}"; do
|
|
39
|
+
[[ -f "$SKILL/$t" ]] || { fail "guards.tsv $name names missing template: $t"; missing=1; }
|
|
40
|
+
done
|
|
41
|
+
done < "$TSV"
|
|
42
|
+
[[ "$missing" -eq 0 ]] && pass "every v1 row's templates exist"
|
|
43
|
+
|
|
44
|
+
orphaned=0
|
|
45
|
+
while IFS= read -r t; do
|
|
46
|
+
rel="${t#"$SKILL/"}"
|
|
47
|
+
# A template is owned by a guards.tsv row (guard artifacts) or by the
|
|
48
|
+
# generator itself (the doc block: verification-readme.template).
|
|
49
|
+
grep -qF "$rel" "$TSV" || grep -qF "$rel" "$SKILL/scripts/verification-scaffold.sh" \
|
|
50
|
+
|| { fail "orphaned template (named by nothing): $rel"; orphaned=1; }
|
|
51
|
+
done < <(find "$SKILL/references" -name '*.template' | sort)
|
|
52
|
+
[[ "$orphaned" -eq 0 ]] && pass "every template is named by a guards.tsv row or the generator"
|
|
53
|
+
|
|
54
|
+
# --- 2. audit census over the live tree -------------------------------------------
|
|
55
|
+
# The producer is git ls-files — identical to this file's own corpus definition,
|
|
56
|
+
# so a new member lacking an audit row is caught here, not by review.
|
|
57
|
+
uncov=0
|
|
58
|
+
while IFS= read -r f; do
|
|
59
|
+
base="$(basename "$f")"
|
|
60
|
+
grep -qF "$base" "$AUDIT" || { fail "audit has no row for $f"; uncov=1; }
|
|
61
|
+
done < <(git -C "$REPO_ROOT" ls-files '.claude/hooks/*.sh' | grep -v '\.test\.sh$' | grep -v '/test/')
|
|
62
|
+
while IFS= read -r f; do
|
|
63
|
+
base="$(basename "$f")"
|
|
64
|
+
grep -qF "$base" "$AUDIT" || { fail "audit has no row for $f"; uncov=1; }
|
|
65
|
+
done < <(git -C "$REPO_ROOT" ls-files 'scripts/lint-*' | grep -v '\.test\.sh$\|\.baseline\.txt$\|\.highwater')
|
|
66
|
+
[[ "$uncov" -eq 0 ]] && pass "audit covers every corpus member (git ls-files census)"
|
|
67
|
+
|
|
68
|
+
# --- 3. one-hunk parity (AC11) ------------------------------------------------------
|
|
69
|
+
SRC_GUARD="$REPO_ROOT/plugins/soleur/scripts/precommit-guard.sh"
|
|
70
|
+
SRC_WRAP="$REPO_ROOT/plugins/soleur/scripts/lib/wrapper-boundary.sh"
|
|
71
|
+
rendered="$(mktemp)"; trap 'rm -f "$rendered"' EXIT
|
|
72
|
+
sed -e 's/VERIFICATION_/SOLEUR_/g' -e 's/@DEFAULT_BRANCHES@/main|master/g' \
|
|
73
|
+
"$SKILL/references/guards/precommit-guard.sh.template" > "$rendered"
|
|
74
|
+
cmp -s "$rendered" "$SRC_GUARD" \
|
|
75
|
+
&& pass "precommit-guard template renders byte-identical to source under main|master" \
|
|
76
|
+
|| fail "precommit-guard template/source drifted (run: diff <(sed -e s/VERIFICATION_/SOLEUR_/g -e s/@DEFAULT_BRANCHES@/main\\\\|master/g .../precommit-guard.sh.template) plugins/soleur/scripts/precommit-guard.sh)"
|
|
77
|
+
sed 's/VERIFICATION_/SOLEUR_/g' "$SKILL/references/guards/wrapper-boundary.sh.template" > "$rendered"
|
|
78
|
+
cmp -s "$rendered" "$SRC_WRAP" \
|
|
79
|
+
&& pass "wrapper-boundary template is rename-normalized byte-identical to source" \
|
|
80
|
+
|| fail "wrapper-boundary template/source drifted"
|
|
81
|
+
|
|
82
|
+
# --- 4. emitted-content hygiene (AC8) ----------------------------------------------
|
|
83
|
+
# Templates contain @PLACEHOLDER@ markers; the runtime text must carry zero
|
|
84
|
+
# Soleur couplings and zero network egress.
|
|
85
|
+
hyg=0
|
|
86
|
+
while IFS= read -r t; do
|
|
87
|
+
if grep -nE 'SOLEUR_|knowledge-base/|plugins/soleur' "$t" >/dev/null; then
|
|
88
|
+
fail "Soleur coupling in template $(basename "$t"): $(grep -nE 'SOLEUR_|knowledge-base/|plugins/soleur' "$t" | head -3 | tr '\n' ';')"
|
|
89
|
+
hyg=1
|
|
90
|
+
fi
|
|
91
|
+
# egress tokens outside comments: strip comment lines then grep.
|
|
92
|
+
if grep -vE '^[[:space:]]*#' "$t" | grep -nE 'curl|wget|https?://' >/dev/null; then
|
|
93
|
+
fail "network egress token in template $(basename "$t")"
|
|
94
|
+
hyg=1
|
|
95
|
+
fi
|
|
96
|
+
done < <(find "$SKILL/references" -name '*.template' | sort)
|
|
97
|
+
[[ "$hyg" -eq 0 ]] && pass "zero Soleur couplings + zero egress tokens in emitted templates"
|
|
98
|
+
|
|
99
|
+
# --- 5. portability floor ----------------------------------------------------------
|
|
100
|
+
# GNU-only forms banned in emitted templates (stock macOS must run them).
|
|
101
|
+
port=0
|
|
102
|
+
while IFS= read -r t; do
|
|
103
|
+
case "$t" in *.yml.template) continue ;; esac
|
|
104
|
+
if grep -nE 'sed -i|readlink -f|realpath|stat -c|date -d|/usr/bin/time|(^|[;&| ]|^[^#]*[;&| ])bc |mapfile' "$t" | grep -vE '^[0-9]+:[[:space:]]*#' >/dev/null; then
|
|
105
|
+
fail "GNU-only token in template $(basename "$t"): $(grep -nE 'sed -i|readlink -f|realpath|stat -c|date -d|/usr/bin/time|bc |mapfile' "$t" | grep -vE '^[0-9]+:[[:space:]]*#' | head -3 | tr '\n' ';')"
|
|
106
|
+
port=1
|
|
107
|
+
fi
|
|
108
|
+
if grep -nE '(^|[^_a-zA-Z])timeout [0-9]' "$t" | grep -v 'command -v timeout\|gtimeout' >/dev/null; then
|
|
109
|
+
fail "unguarded timeout invocation in $(basename "$t")"
|
|
110
|
+
port=1
|
|
111
|
+
fi
|
|
112
|
+
done < <(find "$SKILL/references" -name '*.template' | sort)
|
|
113
|
+
[[ "$port" -eq 0 ]] && pass "portability floor: no GNU-only forms in emitted templates"
|
|
114
|
+
|
|
115
|
+
# --- 6. actionlint on the RENDERED workflow ------------------------------------------
|
|
116
|
+
if command -v actionlint >/dev/null 2>&1; then
|
|
117
|
+
WF="$(mktemp -d)"
|
|
118
|
+
# Render like the generator does: keep both job blocks, stamp continue-on-error.
|
|
119
|
+
awk '{print}' "$SKILL/references/guards/verification-gates.yml.template" \
|
|
120
|
+
| sed 's/@CI_CONTINUE_ON_ERROR@/true/g' > "$WF/verification-gates.yml"
|
|
121
|
+
if actionlint -oneline "$WF/verification-gates.yml" >"$WF/lint.log" 2>&1; then
|
|
122
|
+
pass "rendered verification-gates.yml is actionlint-clean"
|
|
123
|
+
else
|
|
124
|
+
fail "actionlint reds on rendered workflow: $(cat "$WF/lint.log" | head -5 | tr '\n' ';')"
|
|
125
|
+
fi
|
|
126
|
+
rm -rf "$WF"
|
|
127
|
+
else
|
|
128
|
+
pass "actionlint not on PATH — workflow lint arm skipped (CI must provide it)"
|
|
129
|
+
fi
|
|
130
|
+
|
|
131
|
+
# --- 7. SKILL.md + audit + tsv exist and are non-empty -------------------------------
|
|
132
|
+
for f in "$SKILL/SKILL.md" "$AUDIT" "$TSV" "$SKILL/references/verification-readme.template" "$SKILL/references/gitleaks.toml.template"; do
|
|
133
|
+
[[ -s "$f" ]] || fail "missing/empty: ${f#"$REPO_ROOT"/}"
|
|
134
|
+
done
|
|
135
|
+
pass "required skill files exist (SKILL.md presence asserted by the file list)"
|
|
136
|
+
|
|
137
|
+
# guards.tsv: the emitted .gitleaks.toml is a default-ruleset pointer (Guard 1
|
|
138
|
+
# mutation-6 anchor — the template's declared ruleset shape is pinned here).
|
|
139
|
+
grep -q 'useDefault = true' "$SKILL/references/gitleaks.toml.template" \
|
|
140
|
+
&& pass "gitleaks.toml.template is the default-ruleset pointer guards.tsv declares" \
|
|
141
|
+
|| fail "gitleaks.toml.template lost its useDefault=true ruleset shape"
|
|
142
|
+
|
|
143
|
+
printf '\n%d pass(es), %d fail(s)\n' "$passes" "$fails"
|
|
144
|
+
[[ "$fails" -eq 0 ]]
|