@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,313 @@
|
|
|
1
|
+
name: fix-constraints-stage-b
|
|
2
|
+
|
|
3
|
+
# Stage B — PRIVILEGED consumer of Stage A's recovery artifact (ADR-074, #5814). GENERATED by
|
|
4
|
+
# `plugins/soleur/skills/constraint-scaffold` into __TARGET_DIR__'s CI (the agent owns it).
|
|
5
|
+
# Triggered by Stage A completion via `workflow_run` — GitHub ALWAYS runs this file from the
|
|
6
|
+
# default branch, so its logic is trusted even when Stage A ran fork-controlled code. It holds
|
|
7
|
+
# the write token and delivers the fix as a DRAFT follow-up PR (human merge gate).
|
|
8
|
+
#
|
|
9
|
+
# CRITICAL — the entire Stage A artifact (file contents AND meta.json) is 100% attacker-
|
|
10
|
+
# controlled: `pull_request` runs the FORK'S OWN Stage A definition, so a fork can skip the
|
|
11
|
+
# agent and upload a hand-crafted artifact while keeping Stage A's name: to fire this stage.
|
|
12
|
+
# Therefore Stage B:
|
|
13
|
+
# (1) requires isCrossRepository == false AND exactly one matching open PR before ANY write;
|
|
14
|
+
# (2) sources routing identity (head_sha) from the trusted workflow_run EVENT, never the
|
|
15
|
+
# artifact; resolves pr_number/head_ref by API; cross-checks meta.json and rejects on
|
|
16
|
+
# mismatch;
|
|
17
|
+
# (3) validates every artifact path (charset + traversal + symlink/gitlink mode + allowlist,
|
|
18
|
+
# fail-closed) and enforces file-count/size bounds before the blob loop;
|
|
19
|
+
# (4) builds the commit via the Git Data API (blob -> tree WITH mandatory base_tree ->
|
|
20
|
+
# commit -> ref), verifying each blob's bytes against the per-file sha256 in meta.json.
|
|
21
|
+
# Stage B NEVER `actions/checkout`s the untrusted tree, NEVER `git apply`s, NEVER runs
|
|
22
|
+
# `bun install` or any PR script. The write token never co-locates with untrusted execution,
|
|
23
|
+
# so the untrusted-checkout sink is STRUCTURALLY ABSENT (no checkout step to flag). "0 CodeQL
|
|
24
|
+
# alerts" proves the checkout sink is gone — the explicit gates above are what make the
|
|
25
|
+
# artifact-data trust safe. All PR-derived strings are env/argv-passed, never shell-interpolated.
|
|
26
|
+
|
|
27
|
+
on:
|
|
28
|
+
workflow_run:
|
|
29
|
+
workflows: ["fix-constraints-stage-a"]
|
|
30
|
+
types: [completed]
|
|
31
|
+
|
|
32
|
+
permissions:
|
|
33
|
+
contents: write
|
|
34
|
+
pull-requests: write
|
|
35
|
+
actions: read # REQUIRED for the cross-workflow download-artifact of the Stage A run
|
|
36
|
+
|
|
37
|
+
concurrency:
|
|
38
|
+
# Coarse guard on the immutable head SHA so two Stage A completions on the same head can't
|
|
39
|
+
# race the ref create; the ref-create step is also create-or-update to be safe.
|
|
40
|
+
group: fix-constraints-b-${{ github.event.workflow_run.head_sha }}
|
|
41
|
+
cancel-in-progress: false
|
|
42
|
+
|
|
43
|
+
jobs:
|
|
44
|
+
apply:
|
|
45
|
+
if: github.event.workflow_run.conclusion == 'success'
|
|
46
|
+
runs-on: ubuntu-latest
|
|
47
|
+
timeout-minutes: 15
|
|
48
|
+
steps:
|
|
49
|
+
- name: Check the Stage A run for a recovery artifact
|
|
50
|
+
id: check
|
|
51
|
+
env:
|
|
52
|
+
GH_TOKEN: ${{ github.token }}
|
|
53
|
+
REPO: ${{ github.repository }}
|
|
54
|
+
RUN_ID: ${{ github.event.workflow_run.id }}
|
|
55
|
+
run: |
|
|
56
|
+
set -euo pipefail
|
|
57
|
+
# --paginate, no --jq (gh applies --jq per page); jq -s slurps the
|
|
58
|
+
# concatenated page objects. First-page-only truncation would read as
|
|
59
|
+
# "no recovery artifact" and silently skip a real patch.
|
|
60
|
+
arts=$(gh api --paginate "repos/${REPO}/actions/runs/${RUN_ID}/artifacts" | jq -s '[.[].artifacts[].name]')
|
|
61
|
+
recovery=$(jq '[.[] | select(startswith("fix-constraints-patch-"))] | length' <<<"$arts")
|
|
62
|
+
giveup=$(jq '[.[] | select(startswith("fix-constraints-giveup-"))] | length' <<<"$arts")
|
|
63
|
+
echo "recovery=${recovery}" >> "$GITHUB_OUTPUT"
|
|
64
|
+
echo "giveup=${giveup}" >> "$GITHUB_OUTPUT"
|
|
65
|
+
if [ "${recovery}" = "0" ] && [ "${giveup}" = "0" ]; then
|
|
66
|
+
echo "::notice::Stage A produced no artifact (gate was green — nothing to apply)."
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
- name: Download the Stage A artifact(s)
|
|
70
|
+
if: steps.check.outputs.recovery != '0' || steps.check.outputs.giveup != '0'
|
|
71
|
+
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
|
72
|
+
with:
|
|
73
|
+
# Matches BOTH the recovery patch and the give-up marker; excludes the Stage A run's
|
|
74
|
+
# separate `api-spend-*` artifact.
|
|
75
|
+
pattern: fix-constraints-*
|
|
76
|
+
path: artifact
|
|
77
|
+
run-id: ${{ github.event.workflow_run.id }}
|
|
78
|
+
github-token: ${{ github.token }}
|
|
79
|
+
|
|
80
|
+
- name: Resolve identity, validate artifact, apply via Git Data API
|
|
81
|
+
if: steps.check.outputs.recovery != '0'
|
|
82
|
+
id: apply
|
|
83
|
+
env:
|
|
84
|
+
GH_TOKEN: ${{ github.token }}
|
|
85
|
+
REPO: ${{ github.repository }}
|
|
86
|
+
# Routing identity comes from the TRUSTED event, never the artifact.
|
|
87
|
+
HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
|
|
88
|
+
MAX_FILES: '50'
|
|
89
|
+
MAX_FILE_BYTES: '1048576'
|
|
90
|
+
MAX_TOTAL_BYTES: '5242880'
|
|
91
|
+
run: |
|
|
92
|
+
set -euo pipefail
|
|
93
|
+
|
|
94
|
+
# Strip control chars + unicode line/para separators as escape sequences (never
|
|
95
|
+
# literal chars) before embedding any string in a comment / PR body (log-injection).
|
|
96
|
+
sanitize() { LC_ALL=C sed $'s/[\x01-\x1f\x7f]//g; s/\xc2\x85//g; s/\xe2\x80\xa8//g; s/\xe2\x80\xa9//g'; }
|
|
97
|
+
# `detail` interpolates attacker-controlled artifact data (meta.json fields, rejected
|
|
98
|
+
# paths); a `jq -r`-decoded newline would otherwise inject extra `state=`/`pr_url=`
|
|
99
|
+
# lines into $GITHUB_OUTPUT and forge a success comment. sanitize() strips \n/\r, so
|
|
100
|
+
# emit() is the single choke point that neutralizes it.
|
|
101
|
+
emit() { echo "state=$1" >> "$GITHUB_OUTPUT"; echo "detail=$(printf '%s' "$2" | sanitize)" >> "$GITHUB_OUTPUT"; }
|
|
102
|
+
|
|
103
|
+
# --- Identity from the event; validate SHA shape BEFORE any use ------------------
|
|
104
|
+
if ! [[ "$HEAD_SHA" =~ ^[0-9a-f]{40}$ ]]; then
|
|
105
|
+
emit "identity-mismatch" "workflow_run head_sha is not a 40-hex commit SHA"; exit 0
|
|
106
|
+
fi
|
|
107
|
+
|
|
108
|
+
# Resolve the PR from the trusted head SHA (NOT workflow_run.pull_requests, empty for forks).
|
|
109
|
+
prs_json=$(gh api "repos/${REPO}/commits/${HEAD_SHA}/pulls" \
|
|
110
|
+
| jq --arg repo "$REPO" '[.[] | select(.state=="open") | {number, headRef: .head.ref, cross: (.head.repo.full_name != $repo)}]')
|
|
111
|
+
n=$(jq 'length' <<<"$prs_json")
|
|
112
|
+
if [ "$n" != "1" ]; then
|
|
113
|
+
emit "no-single-pr" "expected exactly one open PR for ${HEAD_SHA}, found ${n}"; exit 0
|
|
114
|
+
fi
|
|
115
|
+
PR_NUMBER=$(jq -r '.[0].number' <<<"$prs_json")
|
|
116
|
+
HEAD_REF=$(jq -r '.[0].headRef' <<<"$prs_json")
|
|
117
|
+
IS_CROSS=$(jq -r '.[0].cross' <<<"$prs_json")
|
|
118
|
+
|
|
119
|
+
# --- Load-bearing fork defense: same-repo only ------------------------------------
|
|
120
|
+
if [ "$IS_CROSS" != "false" ]; then
|
|
121
|
+
echo "pr_number=${PR_NUMBER}" >> "$GITHUB_OUTPUT"
|
|
122
|
+
emit "fork-rejected" "PR #${PR_NUMBER} is cross-repository (fork); auto-recovery cannot run over an attacker-controlled artifact"; exit 0
|
|
123
|
+
fi
|
|
124
|
+
if ! [[ "$PR_NUMBER" =~ ^[0-9]+$ ]]; then
|
|
125
|
+
emit "identity-mismatch" "resolved pr_number is not numeric"; exit 0
|
|
126
|
+
fi
|
|
127
|
+
echo "pr_number=${PR_NUMBER}" >> "$GITHUB_OUTPUT"
|
|
128
|
+
|
|
129
|
+
# --- Locate the single artifact dir ----------------------------------------------
|
|
130
|
+
art_dir=$(find artifact -maxdepth 1 -type d -name 'fix-constraints-patch-*' | head -1)
|
|
131
|
+
if [ -z "$art_dir" ] || [ ! -f "$art_dir/meta.json" ] || [ ! -d "$art_dir/files" ]; then
|
|
132
|
+
emit "integrity-fail" "artifact missing, or has no meta.json / files dir"; exit 0
|
|
133
|
+
fi
|
|
134
|
+
meta="$art_dir/meta.json"
|
|
135
|
+
# A malformed (non-JSON) meta.json must fail as integrity-fail, not crash to the
|
|
136
|
+
# generic "unexpected error" branch — validate it parses before any jq read.
|
|
137
|
+
if ! jq -e . "$meta" >/dev/null 2>&1; then
|
|
138
|
+
emit "integrity-fail" "meta.json is not valid JSON"; exit 0
|
|
139
|
+
fi
|
|
140
|
+
|
|
141
|
+
# --- Cross-check meta.json against the trusted identity (meta is a cross-check only) --
|
|
142
|
+
m_pr=$(jq -r '.pr_number' "$meta")
|
|
143
|
+
m_sha=$(jq -r '.head_sha' "$meta")
|
|
144
|
+
if [ "$m_pr" != "$PR_NUMBER" ] || [ "$m_sha" != "$HEAD_SHA" ]; then
|
|
145
|
+
emit "identity-mismatch" "meta.json (pr=${m_pr}, sha=${m_sha}) disagrees with the event-resolved identity (pr=${PR_NUMBER}, sha=${HEAD_SHA})"; exit 0
|
|
146
|
+
fi
|
|
147
|
+
|
|
148
|
+
# --- Resource bounds BEFORE the blob loop (CWE-400) -------------------------------
|
|
149
|
+
nfiles=$(jq '.files | length' "$meta")
|
|
150
|
+
if [ "$nfiles" -eq 0 ] || [ "$nfiles" -gt "$MAX_FILES" ]; then
|
|
151
|
+
emit "rejected-out-of-scope" "artifact declares ${nfiles} files (bound 1..${MAX_FILES})"; exit 0
|
|
152
|
+
fi
|
|
153
|
+
# Every file physically present must be declared in meta and vice-versa.
|
|
154
|
+
declared=$(jq -r '.files[].path' "$meta" | sort)
|
|
155
|
+
present=$( (cd "$art_dir/files" && find . -type f -o -type l | sed 's|^\./||') | sort )
|
|
156
|
+
if [ "$declared" != "$present" ]; then
|
|
157
|
+
emit "integrity-fail" "artifact files/ set does not match meta.json files[] (extra or missing paths)"; exit 0
|
|
158
|
+
fi
|
|
159
|
+
|
|
160
|
+
allow_re='^__TARGET_DIR__/(app|components|server)/[A-Za-z0-9._/-]+$'
|
|
161
|
+
total=0
|
|
162
|
+
# Build the Git Data API tree entries as we validate.
|
|
163
|
+
tree='[]'
|
|
164
|
+
base_tree=$(gh api "repos/${REPO}/git/commits/${HEAD_SHA}" --jq '.tree.sha')
|
|
165
|
+
while IFS= read -r path; do
|
|
166
|
+
# Path allowlist (positive charset, no traversal, in-scope only). Fail-closed.
|
|
167
|
+
if [[ "$path" == /* ]] || [[ "$path" == *".."* ]] || ! [[ "$path" =~ $allow_re ]]; then
|
|
168
|
+
emit "rejected-out-of-scope" "path rejected by allowlist: ${path}"; exit 0
|
|
169
|
+
fi
|
|
170
|
+
fp="$art_dir/files/$path"
|
|
171
|
+
if [ -L "$fp" ] || [ ! -f "$fp" ]; then
|
|
172
|
+
emit "rejected-out-of-scope" "path is a symlink or not a regular file: ${path}"; exit 0
|
|
173
|
+
fi
|
|
174
|
+
sz=$(stat -c '%s' "$fp")
|
|
175
|
+
if [ "$sz" -gt "$MAX_FILE_BYTES" ]; then
|
|
176
|
+
emit "rejected-out-of-scope" "file exceeds per-file size bound: ${path}"; exit 0
|
|
177
|
+
fi
|
|
178
|
+
total=$((total + sz))
|
|
179
|
+
if [ "$total" -gt "$MAX_TOTAL_BYTES" ]; then
|
|
180
|
+
emit "rejected-out-of-scope" "artifact exceeds total size bound"; exit 0
|
|
181
|
+
fi
|
|
182
|
+
# Byte-round-trip integrity: verify against the declared sha256 BEFORE committing.
|
|
183
|
+
want=$(jq -r --arg p "$path" '.files[] | select(.path==$p) | .sha256' "$meta")
|
|
184
|
+
got=$(sha256sum "$fp" | awk '{print $1}')
|
|
185
|
+
if [ "$want" != "$got" ]; then
|
|
186
|
+
emit "integrity-fail" "sha256 mismatch for ${path}"; exit 0
|
|
187
|
+
fi
|
|
188
|
+
# base64 of RAW bytes (never a UTF-8 string) so CRLF/BOM/trailing-newline survive.
|
|
189
|
+
b64=$(base64 -w0 "$fp")
|
|
190
|
+
blob_sha=$(jq -n --arg c "$b64" '{encoding:"base64", content:$c}' \
|
|
191
|
+
| gh api "repos/${REPO}/git/blobs" --input - --jq '.sha')
|
|
192
|
+
tree=$(jq -c --arg p "$path" --arg b "$blob_sha" \
|
|
193
|
+
'. + [{path:$p, mode:"100644", type:"blob", sha:$b}]' <<<"$tree")
|
|
194
|
+
done <<<"$declared"
|
|
195
|
+
|
|
196
|
+
# --- Build the commit: tree WITH mandatory base_tree (else whole-repo deletion) ---
|
|
197
|
+
new_tree=$(jq -n --arg bt "$base_tree" --argjson t "$tree" '{base_tree:$bt, tree:$t}' \
|
|
198
|
+
| gh api "repos/${REPO}/git/trees" --input - --jq '.sha')
|
|
199
|
+
commit_msg="fix(constraint-gates): auto-recover tripped L1 gate for #${PR_NUMBER}"
|
|
200
|
+
new_commit=$(jq -n --arg m "$commit_msg" --arg t "$new_tree" --arg p "$HEAD_SHA" \
|
|
201
|
+
'{message:$m, tree:$t, parents:[$p]}' \
|
|
202
|
+
| gh api "repos/${REPO}/git/commits" --input - --jq '.sha')
|
|
203
|
+
|
|
204
|
+
branch="soleur/fix-constraints/${PR_NUMBER}"
|
|
205
|
+
if existing_tip=$(gh api "repos/${REPO}/git/ref/heads/${branch}" --jq '.object.sha' 2>/dev/null); then
|
|
206
|
+
# Refuse to force-overwrite HUMAN commits on the bot branch — a maintainer may have
|
|
207
|
+
# pushed review fixes to the draft follow-up PR. Only force-replace a bot-authored
|
|
208
|
+
# tip; a non-bot login means manual work we must not clobber (surface it instead).
|
|
209
|
+
tip_author=$(gh api "repos/${REPO}/commits/${existing_tip}" --jq '.author.login // ""' 2>/dev/null || echo "")
|
|
210
|
+
if [ -n "$tip_author" ] && [ "$tip_author" != "github-actions[bot]" ]; then
|
|
211
|
+
emit "branch-has-manual-commits" "the auto-fix branch has manual commits — a newer fix is available but was not applied; reconcile manually"
|
|
212
|
+
exit 0
|
|
213
|
+
fi
|
|
214
|
+
jq -n --arg s "$new_commit" '{sha:$s, force:true}' \
|
|
215
|
+
| gh api -X PATCH "repos/${REPO}/git/refs/heads/${branch}" --input - >/dev/null
|
|
216
|
+
else
|
|
217
|
+
jq -n --arg r "refs/heads/${branch}" --arg s "$new_commit" '{ref:$r, sha:$s}' \
|
|
218
|
+
| gh api "repos/${REPO}/git/refs" --input - >/dev/null
|
|
219
|
+
fi
|
|
220
|
+
|
|
221
|
+
# --- Draft follow-up PR (human merge gate; NO "pre-verified green" claim) ---------
|
|
222
|
+
safe_ref=$(printf '%s' "$HEAD_REF" | sanitize)
|
|
223
|
+
bt='`'
|
|
224
|
+
file_list=$(printf '%s' "$declared" | sanitize | sed "s/^/- ${bt}/; s/\$/${bt}/")
|
|
225
|
+
title="fix(constraint-gates): auto-recover tripped gate for #${PR_NUMBER}"
|
|
226
|
+
body=$(printf '%s\n' \
|
|
227
|
+
"Ref #${PR_NUMBER}" \
|
|
228
|
+
"" \
|
|
229
|
+
"The L1 client→server-secret constraint-gate tripped on \`${safe_ref}\` (commit \`${HEAD_SHA}\`). Stage A (untrusted, no write token) dispatched the agent to fix the offending import and re-verified the gate green; Stage B applied the change here via the Git Data API." \
|
|
230
|
+
"" \
|
|
231
|
+
"**What Stage B attests:** it applied an allowlisted, byte-verified (per-file sha256), same-repo artifact on top of \`${HEAD_SHA}\`. Stage B does **not** re-run the gate — this is a delivery vehicle, not a green attestation. Review + merge to update the source PR." \
|
|
232
|
+
"" \
|
|
233
|
+
"Files changed:" \
|
|
234
|
+
"${file_list}" )
|
|
235
|
+
|
|
236
|
+
# Open the PR only if one isn't already open for this branch.
|
|
237
|
+
existing=$(gh pr list --repo "$REPO" --head "$branch" --state open --json url --jq '.[0].url // ""')
|
|
238
|
+
if [ -n "$existing" ]; then
|
|
239
|
+
pr_url="$existing"
|
|
240
|
+
else
|
|
241
|
+
pr_url=$(gh pr create --repo "$REPO" --draft \
|
|
242
|
+
--base "$HEAD_REF" --head "$branch" \
|
|
243
|
+
--title "$title" --body "$body")
|
|
244
|
+
fi
|
|
245
|
+
echo "pr_url=${pr_url}" >> "$GITHUB_OUTPUT"
|
|
246
|
+
emit "recovered" "opened follow-up PR ${pr_url}"
|
|
247
|
+
|
|
248
|
+
- name: Comment give-up feedback (red gate, no in-scope fix)
|
|
249
|
+
# Stage A produced a give-up marker instead of a recovery patch (no key, agent made no
|
|
250
|
+
# in-scope fix, still red, or greened out-of-scope). The founder must NEVER be left
|
|
251
|
+
# silently deadlocked, so post exactly one "maintainer needed" comment. Identity is
|
|
252
|
+
# resolved from the TRUSTED event head_sha (never the marker); this step only COMMENTS
|
|
253
|
+
# (no repo write), so it needs none of the artifact-apply gates.
|
|
254
|
+
if: steps.check.outputs.recovery == '0' && steps.check.outputs.giveup != '0'
|
|
255
|
+
env:
|
|
256
|
+
GH_TOKEN: ${{ github.token }}
|
|
257
|
+
REPO: ${{ github.repository }}
|
|
258
|
+
HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
|
|
259
|
+
run: |
|
|
260
|
+
set -euo pipefail
|
|
261
|
+
sanitize() { LC_ALL=C sed $'s/[\x01-\x1f\x7f]//g; s/\xc2\x85//g; s/\xe2\x80\xa8//g; s/\xe2\x80\xa9//g'; }
|
|
262
|
+
[[ "$HEAD_SHA" =~ ^[0-9a-f]{40}$ ]] || { echo "::notice::head_sha not a 40-hex SHA — cannot map to a PR"; exit 0; }
|
|
263
|
+
prs_json=$(gh api "repos/${REPO}/commits/${HEAD_SHA}/pulls" \
|
|
264
|
+
| jq --arg repo "$REPO" '[.[] | select(.state=="open") | {number, cross: (.head.repo.full_name != $repo)}]')
|
|
265
|
+
n=$(jq 'length' <<<"$prs_json")
|
|
266
|
+
[ "$n" = "1" ] || { echo "::notice::expected exactly one open PR for ${HEAD_SHA}, found ${n} — no comment"; exit 0; }
|
|
267
|
+
PR_NUMBER=$(jq -r '.[0].number' <<<"$prs_json")
|
|
268
|
+
IS_CROSS=$(jq -r '.[0].cross' <<<"$prs_json")
|
|
269
|
+
[[ "$PR_NUMBER" =~ ^[0-9]+$ ]] || exit 0
|
|
270
|
+
reason=""
|
|
271
|
+
gd=$(find artifact -maxdepth 1 -type d -name 'fix-constraints-giveup-*' | head -1)
|
|
272
|
+
if [ -n "$gd" ] && [ -f "$gd/meta.json" ] && jq -e . "$gd/meta.json" >/dev/null 2>&1; then
|
|
273
|
+
reason=$(jq -r '.reason // ""' "$gd/meta.json" | sanitize)
|
|
274
|
+
fi
|
|
275
|
+
if [ "$IS_CROSS" != "false" ]; then
|
|
276
|
+
body="Auto-recovery can't run on a fork PR — the workflow's write token is scoped to this repository. A maintainer must run \`constraint-scaffold\` locally and push the fix."
|
|
277
|
+
else
|
|
278
|
+
body="⚠️ The L1 constraint-gate is red and auto-recovery could not deliver a fix (${reason:-no in-scope fix produced}). A maintainer needs to review this gate — it may be a real client→server-secret leak that must be fixed by hand (auto-recovery never grows the suppression baseline)."
|
|
279
|
+
fi
|
|
280
|
+
gh pr comment "$PR_NUMBER" --repo "$REPO" --body "$body"
|
|
281
|
+
|
|
282
|
+
- name: Comment the terminal outcome on the original PR
|
|
283
|
+
# Every non-happy terminal state posts exactly one deterministic comment; never silent.
|
|
284
|
+
if: always() && steps.apply.outputs.pr_number != ''
|
|
285
|
+
env:
|
|
286
|
+
GH_TOKEN: ${{ github.token }}
|
|
287
|
+
REPO: ${{ github.repository }}
|
|
288
|
+
PR_NUMBER: ${{ steps.apply.outputs.pr_number }}
|
|
289
|
+
STATE: ${{ steps.apply.outputs.state }}
|
|
290
|
+
DETAIL: ${{ steps.apply.outputs.detail }}
|
|
291
|
+
PR_URL: ${{ steps.apply.outputs.pr_url }}
|
|
292
|
+
APPLY_OUTCOME: ${{ steps.apply.outcome }}
|
|
293
|
+
run: |
|
|
294
|
+
set -euo pipefail
|
|
295
|
+
case "$STATE" in
|
|
296
|
+
recovered)
|
|
297
|
+
body="✅ Auto-recovery: the constraint-gate fix is ready in a draft follow-up PR — ${PR_URL}. Review and merge it to update this PR's branch." ;;
|
|
298
|
+
fork-rejected)
|
|
299
|
+
body="Auto-recovery can't run on a fork PR — the workflow's write token is scoped to this repository. A maintainer must run \`constraint-scaffold\` locally and push the fix." ;;
|
|
300
|
+
rejected-out-of-scope)
|
|
301
|
+
body="Auto-recovery found a fix but it edits paths outside the allowlist (or exceeds size bounds) — not auto-applicable. A maintainer needs to review. Detail: ${DETAIL}" ;;
|
|
302
|
+
integrity-fail)
|
|
303
|
+
body="Auto-recovery aborted on an integrity check (artifact bytes did not verify against their declared hashes, or the file set was inconsistent) — nothing was written. A maintainer needs to act. Detail: ${DETAIL}" ;;
|
|
304
|
+
identity-mismatch)
|
|
305
|
+
body="Auto-recovery aborted: the recovery artifact's metadata did not match this PR's verified identity — nothing was written. Detail: ${DETAIL}" ;;
|
|
306
|
+
no-single-pr)
|
|
307
|
+
body="Auto-recovery could not map the fix to a single open PR (${DETAIL}) — nothing was written." ;;
|
|
308
|
+
branch-has-manual-commits)
|
|
309
|
+
body="Auto-recovery produced a newer fix, but the draft follow-up branch has manual (maintainer) commits — it was NOT overwritten to avoid discarding that work. Reconcile manually. Detail: ${DETAIL}" ;;
|
|
310
|
+
*)
|
|
311
|
+
body="Auto-recovery hit an unexpected error (apply step: ${APPLY_OUTCOME}) before it could finish — see the workflow run logs. A maintainer can run \`constraint-scaffold\` locally." ;;
|
|
312
|
+
esac
|
|
313
|
+
gh pr comment "$PR_NUMBER" --repo "$REPO" --body "$body"
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Shared constraint-gates runner — owns the single pinned dependency-cruiser
|
|
3
|
+
# invocation. CI and (future) pre-commit both exec THIS file, so the gate's
|
|
4
|
+
# command line lives in exactly one place.
|
|
5
|
+
#
|
|
6
|
+
# GENERATED by `plugins/soleur/skills/constraint-scaffold` (ADR-071). The agent
|
|
7
|
+
# — never the founder — owns this file. Recovery is automatic: when this gate
|
|
8
|
+
# trips on a PR, the two-stage auto-recovery dispatcher (fix-constraints-stage-a/b,
|
|
9
|
+
# ADR-074) fixes the import and opens a follow-up PR if it is auto-fixable; a real
|
|
10
|
+
# leak the agent cannot fix is surfaced for a maintainer (who re-runs the
|
|
11
|
+
# constraint-scaffold skill locally, fixing the import or running
|
|
12
|
+
# `--refresh-baseline`). The gate stays informational/non-blocking. Do NOT hand-edit.
|
|
13
|
+
#
|
|
14
|
+
# Exit-reason matrix (every non-zero exit is a hard FAIL — fail-closed):
|
|
15
|
+
# 0 — clean: no new client->server-secret value-import violations beyond the
|
|
16
|
+
# committed baseline.
|
|
17
|
+
# 1 — FAIL. Either (a) real boundary violation(s), or (b) a dependency-cruiser
|
|
18
|
+
# config/binary error. We discriminate the two only to print the right
|
|
19
|
+
# recovery annotation; both block the merge.
|
|
20
|
+
#
|
|
21
|
+
# Note on dependency-cruiser exit codes (empirically verified, v16): depcruise
|
|
22
|
+
# exits with the *error count* on violations (e.g. rc=10 for ten) and rc=1 on a
|
|
23
|
+
# config/parse/load error. So a non-zero rc alone cannot tell "N violations"
|
|
24
|
+
# from "config error" — we discriminate on whether the report contains the
|
|
25
|
+
# "dependency violations" summary line. ANY non-zero rc fails the gate closed.
|
|
26
|
+
set -euo pipefail
|
|
27
|
+
|
|
28
|
+
# App root: this script lives in <app>/scripts/constraint-gates.sh. The
|
|
29
|
+
# CONSTRAINT_GATES_DIR override points the runner at a synthesized fixture app
|
|
30
|
+
# root for the skill self-tests; in CI it is unset and resolves to <app>.
|
|
31
|
+
APP_DIR="${CONSTRAINT_GATES_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
|
|
32
|
+
cd "$APP_DIR"
|
|
33
|
+
|
|
34
|
+
# Plain output only: a FORCE_COLOR environment (some CI images, some shells) decorates
|
|
35
|
+
# depcruise's `error <rule>:` lines with ANSI escapes, and every anchor on this stream —
|
|
36
|
+
# the scaffold's bite-proof and the ::error:: extraction below — would then match nothing.
|
|
37
|
+
export NO_COLOR=1
|
|
38
|
+
DEPCRUISE="./node_modules/.bin/depcruise"
|
|
39
|
+
CONFIG=".dependency-cruiser.cjs"
|
|
40
|
+
BASELINE=".dependency-cruiser-known-violations.json"
|
|
41
|
+
|
|
42
|
+
if [[ ! -x "$DEPCRUISE" ]]; then
|
|
43
|
+
echo "::error::constraint-gates: dependency-cruiser not found at ${APP_DIR}/${DEPCRUISE} — run 'npm ci --ignore-scripts'. To recover, re-run the constraint-scaffold skill (the agent fixes the import or runs --refresh-baseline); auto-recovery (fix-constraints-stage-a/b, ADR-074) opens a follow-up PR when the gate is auto-fixable." >&2
|
|
44
|
+
exit 1
|
|
45
|
+
fi
|
|
46
|
+
if [[ ! -f "$BASELINE" ]]; then
|
|
47
|
+
echo "::error::constraint-gates: baseline ${APP_DIR}/${BASELINE} missing — regenerate with constraint-scaffold.sh. To recover, re-run the constraint-scaffold skill (the agent fixes the import or runs --refresh-baseline); auto-recovery (fix-constraints-stage-a/b, ADR-074) opens a follow-up PR when the gate is auto-fixable." >&2
|
|
48
|
+
exit 1
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
# Zero-reachability-baseline guard (ADR-071 §Amendment 2026-07-01, #5777). The
|
|
52
|
+
# transitive `reachable` rule's violations are softened per-ORIGIN by
|
|
53
|
+
# dependency-cruiser (matched on `from` + rule NAME only, ignoring `to`/`via` AND
|
|
54
|
+
# the entry's `type`), so a SINGLE baselined entry that names the transitive rule
|
|
55
|
+
# blinds that client to EVERY future transitive client->server-secret leak. The
|
|
56
|
+
# design keeps the reachable baseline EMPTY (value-safe targets excluded via
|
|
57
|
+
# `to.pathNot`; real leaks fixed, never grandfathered). This guard is the ONLY
|
|
58
|
+
# always-on enforcement of that invariant: a PR that edits ONLY the baseline JSON
|
|
59
|
+
# trips this runner (paths: <app>/**) but may NOT trip the scripts shard that runs
|
|
60
|
+
# boundary.test.sh.
|
|
61
|
+
#
|
|
62
|
+
# We key on the transitive rule NAME, not on `type:"reachability"`: a
|
|
63
|
+
# `--output-type baseline` capture emits `type:"reachability"`, but a hand-authored
|
|
64
|
+
# (or auto-recovery-touched) entry with `type:"module"` + the transitive rule name
|
|
65
|
+
# ALSO suppresses the violation via soften-known-violations.mjs's module-level path
|
|
66
|
+
# (matched on from+rule.name), while a type-only count would read it as 0. Reject any
|
|
67
|
+
# entry whose type is "reachability" OR whose rule.name is the transitive rule,
|
|
68
|
+
# regardless of `type`. A non-array or unparseable baseline => -1 => fails closed.
|
|
69
|
+
REACHABILITY_ENTRIES="$(node -e '
|
|
70
|
+
const fs = require("fs");
|
|
71
|
+
const TRANSITIVE_RULE = "no-client-to-server-secret-transitive";
|
|
72
|
+
try {
|
|
73
|
+
const b = JSON.parse(fs.readFileSync(process.argv[1], "utf8"));
|
|
74
|
+
if (!Array.isArray(b)) { process.stdout.write("-1"); }
|
|
75
|
+
else process.stdout.write(String(b.filter((e) => e && (e.type === "reachability" || (e.rule && e.rule.name === TRANSITIVE_RULE))).length));
|
|
76
|
+
} catch (e) { process.stdout.write("-1"); }
|
|
77
|
+
' "$BASELINE" 2>/dev/null)"
|
|
78
|
+
if [[ "$REACHABILITY_ENTRIES" != "0" ]]; then
|
|
79
|
+
echo "::error::constraint-gates: committed baseline ${APP_DIR}/${BASELINE} contains ${REACHABILITY_ENTRIES} entry/entries that suppress the transitive rule (type:\"reachability\", or ANY type naming no-client-to-server-secret-transitive), or the baseline is not a JSON array (unparseable) — such an entry is NEVER benign: dependency-cruiser suppresses the transitive rule per-origin (from+rule.name, ignoring type), so it blinds that client to every transitive client->server-secret leak. The reachable baseline MUST stay empty (exclude value-safe targets via to.pathNot; FIX real leaks). Failing closed. To recover, re-run the constraint-scaffold skill (the agent fixes the import or removes the suppressing baseline entry); auto-recovery (fix-constraints-stage-a/b, ADR-074) opens a follow-up PR when the gate is auto-fixable." >&2
|
|
80
|
+
exit 1
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
set +e
|
|
84
|
+
OUT="$("$DEPCRUISE" --config "$CONFIG" --ignore-known "$BASELINE" --output-type err app components server 2>&1)"
|
|
85
|
+
RC=$?
|
|
86
|
+
set -e
|
|
87
|
+
printf '%s\n' "$OUT"
|
|
88
|
+
|
|
89
|
+
# A terminal Ctrl-C reaches the node child first; it exits 130 and bash does not treat that as
|
|
90
|
+
# its own interrupt. Propagate it as an interrupt, never as a gate verdict (the scaffold's
|
|
91
|
+
# bite-proof would otherwise read a Ctrl-C as "the gate did not reject the probe").
|
|
92
|
+
if [[ "$RC" -eq 130 ]]; then
|
|
93
|
+
echo "constraint-gates: interrupted (dependency-cruiser exited 130)" >&2
|
|
94
|
+
exit 130
|
|
95
|
+
fi
|
|
96
|
+
|
|
97
|
+
if [[ "$RC" -eq 0 ]]; then
|
|
98
|
+
# Baseline-clean. Real-tree alias-resolution self-check (fail-closed): the
|
|
99
|
+
# whole gate is BLIND if `@/server` imports stop resolving (a tsconfig
|
|
100
|
+
# baseUrl/paths regression) — an unresolved edge never matches the
|
|
101
|
+
# `to: ^server/` rule, so a real client->server-secret leak would read green.
|
|
102
|
+
# The synthetic boundary.test.sh fixture asserts couldNotResolve==0, but a
|
|
103
|
+
# change to the REAL app's tsconfig is invisible there. Assert it here on the
|
|
104
|
+
# real tree: 0 couldNotResolve edges whose target is the server tree.
|
|
105
|
+
set +e
|
|
106
|
+
JSON_OUT="$("$DEPCRUISE" --config "$CONFIG" --output-type json app components server 2>/dev/null)"
|
|
107
|
+
set -e
|
|
108
|
+
UNRESOLVED="$(
|
|
109
|
+
printf '%s' "$JSON_OUT" | node -e '
|
|
110
|
+
let s = ""; process.stdin.on("data", (d) => (s += d)); process.stdin.on("end", () => {
|
|
111
|
+
let n = 0;
|
|
112
|
+
try {
|
|
113
|
+
const j = JSON.parse(s);
|
|
114
|
+
for (const m of j.modules || [])
|
|
115
|
+
for (const dep of m.dependencies || [])
|
|
116
|
+
if (dep.couldNotResolve &&
|
|
117
|
+
/(?:^|[@/])server\//.test((dep.module || "") + "\n" + (dep.resolved || ""))) n++;
|
|
118
|
+
} catch (e) { n = -1; }
|
|
119
|
+
process.stdout.write(String(n));
|
|
120
|
+
});
|
|
121
|
+
' 2>/dev/null
|
|
122
|
+
)"
|
|
123
|
+
if [[ "$UNRESOLVED" != "0" ]]; then
|
|
124
|
+
echo "::error::constraint-gates: ${UNRESOLVED} unresolved (couldNotResolve) import(s) target the server tree on the real app — @/* alias resolution is broken (tsconfig baseUrl/paths/@ regression?), so the import-boundary gate is BLIND to client->server-secret leaks. Failing closed. To recover, re-run the constraint-scaffold skill (the agent fixes the tsconfig/import); auto-recovery (fix-constraints-stage-a/b, ADR-074) opens a follow-up PR when the gate is auto-fixable." >&2
|
|
125
|
+
exit 1
|
|
126
|
+
fi
|
|
127
|
+
exit 0
|
|
128
|
+
fi
|
|
129
|
+
|
|
130
|
+
if grep -q 'dependency violations' <<<"$OUT"; then
|
|
131
|
+
echo "::error::constraint-gates: client->server-secret import-boundary violation(s) detected — a \"use client\" module value-imports the server-only tree (server/**), which would ship a server secret into the browser bundle. To recover, re-run the constraint-scaffold skill (the agent fixes the import or runs --refresh-baseline); auto-recovery (fix-constraints-stage-a/b, ADR-074) opens a follow-up PR when the gate is auto-fixable." >&2
|
|
132
|
+
else
|
|
133
|
+
echo "::error::constraint-gates: dependency-cruiser failed to run (config/binary error, rc=${RC}) — gate fails closed. To recover, re-run the constraint-scaffold skill (the agent fixes the import or runs --refresh-baseline); auto-recovery (fix-constraints-stage-a/b, ADR-074) opens a follow-up PR when the gate is auto-fixable." >&2
|
|
134
|
+
fi
|
|
135
|
+
exit 1
|