@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,300 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
SLUG=""
|
|
5
|
+
TENANT_ORG=""
|
|
6
|
+
REVIEWER=""
|
|
7
|
+
DRY_RUN=false
|
|
8
|
+
|
|
9
|
+
usage() {
|
|
10
|
+
echo "Usage: provision-github <tenant-slug> <tenant-org> <reviewer-github-username> [--dry-run]" >&2
|
|
11
|
+
exit 1
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
while [[ $# -gt 0 ]]; do
|
|
15
|
+
case "$1" in
|
|
16
|
+
--dry-run) DRY_RUN=true; shift ;;
|
|
17
|
+
--help|-h) usage ;;
|
|
18
|
+
-*) echo "Unknown flag: $1" >&2; usage ;;
|
|
19
|
+
*)
|
|
20
|
+
if [[ -z "$SLUG" ]]; then SLUG="$1"
|
|
21
|
+
elif [[ -z "$TENANT_ORG" ]]; then TENANT_ORG="$1"
|
|
22
|
+
elif [[ -z "$REVIEWER" ]]; then REVIEWER="$1"
|
|
23
|
+
else echo "Unexpected argument: $1" >&2; usage
|
|
24
|
+
fi
|
|
25
|
+
shift ;;
|
|
26
|
+
esac
|
|
27
|
+
done
|
|
28
|
+
|
|
29
|
+
[[ -n "$SLUG" ]] || { echo "Error: tenant-slug is required." >&2; usage; }
|
|
30
|
+
[[ -n "$TENANT_ORG" ]] || { echo "Error: tenant-org is required." >&2; usage; }
|
|
31
|
+
[[ -n "$REVIEWER" ]] || { echo "Error: reviewer-github-username is required." >&2; usage; }
|
|
32
|
+
|
|
33
|
+
if ! [[ "$SLUG" =~ ^[a-z0-9]+(-[a-z0-9]+)*$ ]]; then
|
|
34
|
+
echo "Error: tenant-slug must be kebab-case (e.g. 'acme-prd')." >&2
|
|
35
|
+
exit 1
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
if ! [[ "$TENANT_ORG" =~ ^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?$ ]]; then
|
|
39
|
+
echo "Error: tenant-org must be a valid GitHub org name (alphanumerics and hyphens)." >&2
|
|
40
|
+
exit 1
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
if ! [[ "$REVIEWER" =~ ^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?$ ]]; then
|
|
44
|
+
echo "Error: reviewer must be a valid GitHub username (alphanumerics and hyphens)." >&2
|
|
45
|
+
exit 1
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
PROVISIONING_DIR="provisioning/${SLUG}/github"
|
|
49
|
+
CREATED_RESOURCES=()
|
|
50
|
+
|
|
51
|
+
cleanup() {
|
|
52
|
+
local exit_code=$?
|
|
53
|
+
echo ""
|
|
54
|
+
echo "=== Teardown commands (resources created during this run) ==="
|
|
55
|
+
if [[ ${#CREATED_RESOURCES[@]} -eq 0 ]]; then
|
|
56
|
+
echo " (no resources were created)"
|
|
57
|
+
else
|
|
58
|
+
for res in "${CREATED_RESOURCES[@]}"; do
|
|
59
|
+
echo " $res"
|
|
60
|
+
done
|
|
61
|
+
fi
|
|
62
|
+
echo ""
|
|
63
|
+
echo "IMPORTANT: After deleting the App installation, sweep bypass_actors for ghost entries:"
|
|
64
|
+
echo " gh api /repos/${TENANT_ORG}/${SLUG}/rulesets --jq '.[].bypass_actors'"
|
|
65
|
+
echo ""
|
|
66
|
+
echo "Bootstrap cleanup: Revoke the GitHub PAT used for bootstrapping — it is no longer needed."
|
|
67
|
+
exit "$exit_code"
|
|
68
|
+
}
|
|
69
|
+
trap cleanup EXIT INT TERM
|
|
70
|
+
|
|
71
|
+
# --- Pre-checks ---
|
|
72
|
+
|
|
73
|
+
gh auth status >/dev/null 2>&1 || { echo "Error: 'gh' CLI not authenticated. Run 'gh auth login'." >&2; exit 1; }
|
|
74
|
+
command -v terraform >/dev/null 2>&1 || { echo "Error: 'terraform' not found." >&2; exit 1; }
|
|
75
|
+
|
|
76
|
+
# --- DPA gate ---
|
|
77
|
+
|
|
78
|
+
DPA_FILE="knowledge-base/legal/tenant-dpa-register.md"
|
|
79
|
+
[[ -f "$DPA_FILE" ]] || { echo "DPA register not found at $DPA_FILE. Run from Soleur monorepo root." >&2; exit 3; }
|
|
80
|
+
awk -F'|' -v slug="$SLUG" '/^\|/ { gsub(/^ +| +$/, "", $2); if ($2 == slug) found = ($8 ~ /^ *(dpa-signed|provisioning-in-progress) *$/) } END { exit !found }' "$DPA_FILE" \
|
|
81
|
+
|| { echo "No active DPA row for '$SLUG'. Sign DPA (Step 0) first." >&2; exit 3; }
|
|
82
|
+
|
|
83
|
+
# --- Idempotency check ---
|
|
84
|
+
|
|
85
|
+
if gh repo view "${TENANT_ORG}/${SLUG}" >/dev/null 2>&1; then
|
|
86
|
+
echo "WARNING: Repository '${TENANT_ORG}/${SLUG}' already exists."
|
|
87
|
+
echo " Continuing will regenerate TF config. Existing repo is unchanged until 'terraform apply'."
|
|
88
|
+
echo ""
|
|
89
|
+
fi
|
|
90
|
+
|
|
91
|
+
# --- Resolve org-id ---
|
|
92
|
+
|
|
93
|
+
ORG_ID=$(gh api "/orgs/${TENANT_ORG}" --jq .id 2>/dev/null) \
|
|
94
|
+
|| { echo "Error: Could not resolve org ID for '${TENANT_ORG}'. Check org name and permissions." >&2; exit 1; }
|
|
95
|
+
|
|
96
|
+
echo "Resolved org ID: ${TENANT_ORG} → ${ORG_ID}"
|
|
97
|
+
|
|
98
|
+
# --- Resolve reviewer user ID ---
|
|
99
|
+
|
|
100
|
+
REVIEWER_ID=$(gh api "/users/${REVIEWER}" --jq .id 2>/dev/null) \
|
|
101
|
+
|| { echo "Error: Could not resolve user ID for '${REVIEWER}'." >&2; exit 1; }
|
|
102
|
+
|
|
103
|
+
echo "Resolved reviewer ID: ${REVIEWER} → ${REVIEWER_ID}"
|
|
104
|
+
|
|
105
|
+
# --- Generate TF config ---
|
|
106
|
+
|
|
107
|
+
mkdir -p "$PROVISIONING_DIR"
|
|
108
|
+
|
|
109
|
+
cat > "${PROVISIONING_DIR}/github.tf" <<TFEOF
|
|
110
|
+
terraform {
|
|
111
|
+
required_version = ">= 1.6"
|
|
112
|
+
|
|
113
|
+
backend "s3" {
|
|
114
|
+
bucket = "soleur-terraform-state"
|
|
115
|
+
key = "tenants/${SLUG}/github.tfstate"
|
|
116
|
+
region = "auto"
|
|
117
|
+
endpoints = { s3 = "https://4d5ba6f096b2686fbdd404167dd4e125.r2.cloudflarestorage.com" }
|
|
118
|
+
skip_credentials_validation = true
|
|
119
|
+
skip_requesting_account_id = true
|
|
120
|
+
skip_metadata_api_check = true
|
|
121
|
+
skip_region_validation = true
|
|
122
|
+
skip_s3_checksum = true
|
|
123
|
+
use_path_style = true
|
|
124
|
+
use_lockfile = false
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
required_providers {
|
|
128
|
+
github = {
|
|
129
|
+
source = "integrations/github"
|
|
130
|
+
version = "~> 6.0"
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
variable "github_token" {
|
|
136
|
+
description = "GitHub PAT with repo + admin:org scope (re-entered at apply time)"
|
|
137
|
+
type = string
|
|
138
|
+
sensitive = true
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
provider "github" {
|
|
142
|
+
owner = "${TENANT_ORG}"
|
|
143
|
+
token = var.github_token
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
resource "github_repository" "tenant" {
|
|
147
|
+
name = "${SLUG}"
|
|
148
|
+
description = "Tenant repository for ${SLUG}"
|
|
149
|
+
visibility = "private"
|
|
150
|
+
|
|
151
|
+
has_issues = true
|
|
152
|
+
has_projects = false
|
|
153
|
+
has_wiki = false
|
|
154
|
+
|
|
155
|
+
delete_branch_on_merge = true
|
|
156
|
+
allow_squash_merge = true
|
|
157
|
+
allow_merge_commit = false
|
|
158
|
+
allow_rebase_merge = false
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
resource "github_repository_environment" "production" {
|
|
162
|
+
repository = github_repository.tenant.name
|
|
163
|
+
environment = "production"
|
|
164
|
+
|
|
165
|
+
reviewers {
|
|
166
|
+
users = [${REVIEWER_ID}]
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
deployment_branch_policy {
|
|
170
|
+
protected_branches = false
|
|
171
|
+
custom_branch_policies = true
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
resource "github_repository_environment_deployment_policy" "main_only" {
|
|
176
|
+
repository = github_repository.tenant.name
|
|
177
|
+
environment = github_repository_environment.production.environment
|
|
178
|
+
branch_pattern = "main"
|
|
179
|
+
}
|
|
180
|
+
TFEOF
|
|
181
|
+
|
|
182
|
+
echo "Generated ${PROVISIONING_DIR}/github.tf"
|
|
183
|
+
|
|
184
|
+
INSTALL_URL="https://github.com/apps/soleur/installations/new/permissions?target_id=${ORG_ID}"
|
|
185
|
+
|
|
186
|
+
# --- Dry-run output ---
|
|
187
|
+
|
|
188
|
+
if $DRY_RUN; then
|
|
189
|
+
echo ""
|
|
190
|
+
echo "=== DRY RUN — No changes will be made ==="
|
|
191
|
+
echo ""
|
|
192
|
+
echo "--- Generated Terraform config ---"
|
|
193
|
+
cat "${PROVISIONING_DIR}/github.tf"
|
|
194
|
+
echo ""
|
|
195
|
+
echo "--- Copy-pasteable TF apply command ---"
|
|
196
|
+
echo "read -rs -p 'GitHub PAT: ' TF_VAR_github_token && \\"
|
|
197
|
+
echo " export TF_VAR_github_token && \\"
|
|
198
|
+
echo " (cd ${PROVISIONING_DIR} && terraform init && terraform apply); \\"
|
|
199
|
+
echo " unset TF_VAR_github_token"
|
|
200
|
+
echo ""
|
|
201
|
+
echo "--- App install URL (human consent gate, per ToS B.3) ---"
|
|
202
|
+
echo " ${INSTALL_URL}"
|
|
203
|
+
echo ""
|
|
204
|
+
echo "--- Verification ---"
|
|
205
|
+
echo " gh api /repos/${TENANT_ORG}/${SLUG}/installation"
|
|
206
|
+
echo " gh api /repos/${TENANT_ORG}/${SLUG}/environments/production"
|
|
207
|
+
echo ""
|
|
208
|
+
echo "--- Teardown ---"
|
|
209
|
+
echo " gh api -X DELETE /app/installations/<install-id>"
|
|
210
|
+
echo " cd ${PROVISIONING_DIR} && terraform destroy"
|
|
211
|
+
echo " Sweep bypass_actors: gh api /repos/${TENANT_ORG}/${SLUG}/rulesets --jq '.[].bypass_actors'"
|
|
212
|
+
echo ""
|
|
213
|
+
echo "All provisioning complete. Run runbook Steps 5-10 manually."
|
|
214
|
+
exit 0
|
|
215
|
+
fi
|
|
216
|
+
|
|
217
|
+
# --- Interactive flow ---
|
|
218
|
+
|
|
219
|
+
echo ""
|
|
220
|
+
echo "=== GitHub provisioning for '${SLUG}' ==="
|
|
221
|
+
echo ""
|
|
222
|
+
echo "This will:"
|
|
223
|
+
echo " 1. Create repo '${TENANT_ORG}/${SLUG}' via Terraform"
|
|
224
|
+
echo " 2. Create 'production' Environment with required reviewer (${REVIEWER})"
|
|
225
|
+
echo " 3. Pin deployment branch policy to 'main' only"
|
|
226
|
+
echo " 4. Install Soleur GitHub App on the repo (human consent)"
|
|
227
|
+
echo ""
|
|
228
|
+
|
|
229
|
+
echo "--- Step 1: Terraform apply ---"
|
|
230
|
+
echo ""
|
|
231
|
+
echo "Run this command in a separate terminal:"
|
|
232
|
+
echo ""
|
|
233
|
+
echo " read -rs -p 'GitHub PAT: ' TF_VAR_github_token && \\"
|
|
234
|
+
echo " export TF_VAR_github_token && \\"
|
|
235
|
+
echo " (cd ${PROVISIONING_DIR} && terraform init && terraform apply); \\"
|
|
236
|
+
echo " unset TF_VAR_github_token"
|
|
237
|
+
echo ""
|
|
238
|
+
|
|
239
|
+
read -p "TF apply complete? Type 'yes': " ACK
|
|
240
|
+
[[ "$ACK" == "yes" ]] || { echo "Aborted." >&2; exit 1; }
|
|
241
|
+
|
|
242
|
+
# --- Verify TF apply ---
|
|
243
|
+
|
|
244
|
+
if ! gh repo view "${TENANT_ORG}/${SLUG}" >/dev/null 2>&1; then
|
|
245
|
+
echo "Error: Repository '${TENANT_ORG}/${SLUG}' not found. TF apply may not have completed." >&2
|
|
246
|
+
exit 1
|
|
247
|
+
fi
|
|
248
|
+
|
|
249
|
+
CREATED_RESOURCES+=("cd ${PROVISIONING_DIR} && terraform destroy")
|
|
250
|
+
echo "Verified: Repository '${TENANT_ORG}/${SLUG}' exists."
|
|
251
|
+
|
|
252
|
+
# --- Verify Environment ---
|
|
253
|
+
|
|
254
|
+
ENV_CHECK=$(gh api "/repos/${TENANT_ORG}/${SLUG}/environments/production" --jq '.name' 2>/dev/null) || true
|
|
255
|
+
if [[ "$ENV_CHECK" == "production" ]]; then
|
|
256
|
+
echo "Verified: Environment 'production' exists with required reviewers."
|
|
257
|
+
else
|
|
258
|
+
echo "Warning: Could not verify 'production' Environment. Check GitHub settings." >&2
|
|
259
|
+
fi
|
|
260
|
+
|
|
261
|
+
# --- Step 2: App install (human consent gate) ---
|
|
262
|
+
|
|
263
|
+
echo ""
|
|
264
|
+
echo "--- Step 2: Install Soleur GitHub App ---"
|
|
265
|
+
echo ""
|
|
266
|
+
echo "This step requires human consent per GitHub ToS B.3."
|
|
267
|
+
echo "Open this URL and install the Soleur App on '${TENANT_ORG}/${SLUG}':"
|
|
268
|
+
echo ""
|
|
269
|
+
echo " ${INSTALL_URL}"
|
|
270
|
+
echo ""
|
|
271
|
+
echo "Select ONLY the '${SLUG}' repository (not org-wide)."
|
|
272
|
+
echo ""
|
|
273
|
+
|
|
274
|
+
read -p "App installed? Type 'yes': " ACK
|
|
275
|
+
[[ "$ACK" == "yes" ]] || { echo "Aborted." >&2; exit 1; }
|
|
276
|
+
|
|
277
|
+
# --- Verify App install ---
|
|
278
|
+
|
|
279
|
+
INSTALL_JSON=$(gh api "/repos/${TENANT_ORG}/${SLUG}/installation" 2>/dev/null) || true
|
|
280
|
+
INSTALL_CHECK=$(echo "$INSTALL_JSON" | grep -o '"actions":"[^"]*"' | head -1 | cut -d'"' -f4)
|
|
281
|
+
REPO_SELECTION=$(echo "$INSTALL_JSON" | grep -o '"repository_selection":"[^"]*"' | head -1 | cut -d'"' -f4)
|
|
282
|
+
|
|
283
|
+
if [[ "$REPO_SELECTION" == "all" ]]; then
|
|
284
|
+
echo "ERROR: App installed org-wide (repository_selection=all). Must be 'selected' (single repo)." >&2
|
|
285
|
+
echo "Reconfigure: Settings → Integrations → Soleur → Repository access → Only select repositories" >&2
|
|
286
|
+
exit 1
|
|
287
|
+
fi
|
|
288
|
+
|
|
289
|
+
if [[ "$INSTALL_CHECK" == "write" ]]; then
|
|
290
|
+
INSTALL_ID=$(echo "$INSTALL_JSON" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2)
|
|
291
|
+
CREATED_RESOURCES+=("gh api -X DELETE /app/installations/${INSTALL_ID}")
|
|
292
|
+
echo "Verified: Soleur App installed with actions:write permission (repository_selection=${REPO_SELECTION:-selected})."
|
|
293
|
+
else
|
|
294
|
+
echo "Warning: Could not verify App installation or permissions." >&2
|
|
295
|
+
echo "Expected permissions.actions = 'write'. Got: '${INSTALL_CHECK:-empty}'" >&2
|
|
296
|
+
echo "Verify manually: gh api /repos/${TENANT_ORG}/${SLUG}/installation" >&2
|
|
297
|
+
fi
|
|
298
|
+
|
|
299
|
+
echo ""
|
|
300
|
+
echo "All provisioning complete. Run runbook Steps 5-10 manually."
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: provision-hetzner
|
|
3
|
+
description: "This skill should be used when provisioning Hetzner sub-projects and tokens for tenant infrastructure."
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
<!-- soleur-cloud-mode:start -->
|
|
8
|
+
**Cloud Mode (Devin):** before pipeline work run `bash "${CLAUDE_PLUGIN_ROOT}/scripts/cloud-detect.sh"`. If `CLAUDE_PLUGIN_ROOT` is unset (cloud exec shells do not export it), resolve the root by IDENTITY, never by script basename: for `d` in `"$HOME/.local/share/devin/cli/plugins/cache"` and `/opt/.devin/plugins`, skip unless `[ -d "$d" ]`, then `MANIFEST="$(find "$d" -path '*/.claude-plugin/plugin.json' -exec grep -l '"name"[[:space:]]*:[[:space:]]*"soleur"' {} + 2>/dev/null | head -1)"`, `ROOT="${MANIFEST%/.claude-plugin/plugin.json}"` — one resolution, two consumers: `$ROOT/scripts/cloud-detect.sh` and `$ROOT/scripts/precommit-guard.sh`. (Shape check, not authentication: a planted `{"name":"soleur"}` dir passes — ADR-179 A11.) `local` or `not-local:no-devin-env` proceeds normally; any other `not-local:<reason>` applies `<plugin-root>/devin/INSTRUCTIONS.md` §Cloud Mode: emit the `--banner`, fan out sequentially with `Reviewed-Coverage: sequential-fallback` disclosure (never claim an independent review ran), `message_user` ack before any secrets read or production mutation, and run `precommit-guard.sh` before any `git commit` — hooks do not fire in cloud.
|
|
9
|
+
<!-- soleur-cloud-mode:end -->
|
|
10
|
+
|
|
11
|
+
<!-- grok-harness-invoke:start -->
|
|
12
|
+
**Grok Build (`plugins/soleur/lib/harness.ts` `invokeSkill()`):** Read this SKILL.md in this process and run it to completion. A one-segment `soleur:<name>` in this document names a SKILL — on Grok Build, Read `plugins/soleur/skills/<name>/SKILL.md` in this process; it is not a nested tool_use. A multi-segment id such as `soleur:<domain>:<name>` names an AGENT: spawn it, never Read it, and on Grok Build spawn_subagent takes the id with its colons replaced by hyphens (`agentIdToGrokSubagentType`). **Claude Code:** Skill tool for a skill (`soleur:<name>`), Task tool with `subagent_type` for an agent. Forbidden is executing a subset, not the Read.
|
|
13
|
+
<!-- grok-harness-invoke:end -->
|
|
14
|
+
|
|
15
|
+
# Provision Hetzner
|
|
16
|
+
|
|
17
|
+
Guide the operator through Hetzner Console project creation, accept a project-scoped API token, and run a write-class smoke-test to verify scope.
|
|
18
|
+
|
|
19
|
+
## Art. 32 Pre-condition
|
|
20
|
+
|
|
21
|
+
**MUST run on the operator's local machine. MUST NOT run in CI.** The Hetzner token is read from `SOLEUR_BOOTSTRAP_HCLOUD_TOKEN` when that variable is set; otherwise it is prompted for with `read -rs` on a TTY (credential entry is a class-1 interactive carve-out: the agent never asks for the token in chat); with neither, the script exits 64 with `SOLEUR_BOOTSTRAP_INPUT_REQUIRED var=SOLEUR_BOOTSTRAP_HCLOUD_TOKEN`. It is never persisted to disk, never exported beyond the smoke-test subshell, and never placed on CLI args.
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
soleur:provision-hetzner <tenant-slug> [--dry-run]
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
| Argument | Required | Description |
|
|
30
|
+
|----------|----------|-------------|
|
|
31
|
+
| `tenant-slug` | Yes | Canonical tenant identifier (kebab-case) |
|
|
32
|
+
| `--dry-run` | No | Print Console guidance + smoke-test commands without executing |
|
|
33
|
+
|
|
34
|
+
## Execution
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
bash "${CLAUDE_PLUGIN_ROOT}/skills/provision-hetzner/scripts/provision-hetzner.sh" <slug> [--dry-run]
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The script:
|
|
41
|
+
|
|
42
|
+
1. Validates prerequisites (DPA gate, slug format, `hcloud` CLI)
|
|
43
|
+
2. Displays guided instructions for Console project creation + token minting
|
|
44
|
+
3. Accepts the token (environment variable, else the class-1 `read -rs` entry on a TTY, else exit 64) and, after a per-command `yes` acknowledgement that has **no** skip variable, runs the write-class smoke-test (create + delete cx11)
|
|
45
|
+
4. Uses deterministic probe name (`probe-provision-<slug>`) so orphans are findable
|
|
46
|
+
5. Trap handler ensures probe server cleanup on EXIT/INT/TERM
|
|
47
|
+
6. Prints teardown commands on any exit
|
|
48
|
+
|
|
49
|
+
## Environment
|
|
50
|
+
|
|
51
|
+
| Variable | Effect |
|
|
52
|
+
|---|---|
|
|
53
|
+
| `SOLEUR_BOOTSTRAP_HCLOUD_TOKEN` | Supplies the project-scoped token; the `read -rs` prompt is skipped. Set it for the current command only (`SOLEUR_BOOTSTRAP_HCLOUD_TOKEN="$(…)" bash …`), never exported into the shell. |
|
|
54
|
+
| `SOLEUR_BOOTSTRAP_SKIP_HETZNER_TOKEN_BARRIER` | Any non-empty value skips the "Token created? Type 'yes'" barrier. The smoke test that follows is the independent verification the barrier attests to, so skipping it is safe only because that test still runs. |
|
|
55
|
+
| `SOLEUR_BOOTSTRAP_LEDGER` | Run-ledger path. Default: `<cwd>/.soleur/bootstrap-runs.jsonl` (gitignored; the DPA gate already requires cwd to be the monorepo root). |
|
|
56
|
+
|
|
57
|
+
There is **no** variable for the "Create the billable probe server now?" acknowledgement. Without a TTY the script exits 64 there with `SOLEUR_BOOTSTRAP_INPUT_REQUIRED var=destructive-write-ack(no-skip-variable-by-design)`; only a person at a terminal can answer it (`hr-menu-option-ack-not-prod-write-auth`). This script still uses the typed-`yes` TTY acknowledgement; migrating it to the staged agent-run approval gate that generated operator scripts use is tracked in #9387. The agent runs every step it can (prerequisites, instructions, verification) and hands over only that one prompt. Exit codes and every stdout marker: the header of `plugins/soleur/scripts/lib/operator-script.sh`.
|
|
58
|
+
|
|
59
|
+
## Encryption Posture
|
|
60
|
+
|
|
61
|
+
If this run provisions a persistent volume for the tenant, `hcloud_volume` carries no
|
|
62
|
+
`encrypted` attribute -- encryption means the guest-side LUKS apparatus (`random_password` ->
|
|
63
|
+
dedicated Doppler config -> `cryptsetup luksFormat` -> `/dev/mapper/*` mount; see
|
|
64
|
+
soleur:engineering:infra:terraform-architect's Hetzner/Cloudflare requirements). Do not complete the run without adding a
|
|
65
|
+
row to `encryption-posture-ledger.json` (repo-root `scripts/`) for the new volume: `at_rest.mechanism`
|
|
66
|
+
(`luks` or a named `plaintext-exception` with `tracking_issue` + `expires_on`),
|
|
67
|
+
`at_rest.evidence`, `at_rest.does_not_defend`, `at_rest.disclosed_as`, and
|
|
68
|
+
`at_rest.live_verification`. This run provisions sub-projects and tokens, not volumes, so the
|
|
69
|
+
step is normally a no-op -- it applies only when a volume enters scope.
|
|
70
|
+
|
|
71
|
+
## Sharp Edges
|
|
72
|
+
|
|
73
|
+
- Hetzner has no TF resource for project creation or token minting (Console-only). This is the one manual step in this skill; it is tracked as an automation gap with revisit criteria in **Tracks #4604** (per `hr-never-label-any-step-as-manual-without`) — do not treat it as permanently-manual.
|
|
74
|
+
- The smoke-test creates a real cx11 server (~EUR 0.006/hr prorated). Trap handler cleans up.
|
|
75
|
+
- If `hcloud server delete` fails, the probe server must be deleted manually via Console.
|
|
76
|
+
- Read-only tokens silently succeed for reads; the write-class test (server create) is essential.
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# The proving consumer for plugins/soleur/scripts/lib/operator-script.sh (#8287
|
|
3
|
+
# Phase 4). The `--dry-run` stdout is pinned byte-for-byte by
|
|
4
|
+
# test/provision-hetzner-characterization.test.sh; that golden is the safety net
|
|
5
|
+
# for this refactor and it must stay byte-identical.
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
# --- PROLOGUE (must stay ABOVE the `source` line) ----------------------------
|
|
9
|
+
# Duplicated here, never moved into the library — see "SOURCING PRECONDITIONS"
|
|
10
|
+
# §2 in plugins/soleur/scripts/lib/operator-script.sh for why.
|
|
11
|
+
#
|
|
12
|
+
# UNCONDITIONAL, not the conditional `${HCLOUD_TOKEN:+x}` arm: this script
|
|
13
|
+
# ACQUIRES its token with `read -rs` BELOW this point, so the variable is empty
|
|
14
|
+
# at guard time and a conditional arm would be open by construction. The linter
|
|
15
|
+
# cannot see that — its ACQUIRES set knows `doppler secrets get` / `gh auth
|
|
16
|
+
# token` / `_TOKEN="$(`, not `read -rs`.
|
|
17
|
+
#
|
|
18
|
+
# Stdout, not stderr: agent runtimes surface stdout and swallow stderr.
|
|
19
|
+
case "$-" in
|
|
20
|
+
*x*)
|
|
21
|
+
printf '[FATAL] refusing to run under xtrace: this script handles a live credential and -x would print it (see #7797)\n'
|
|
22
|
+
exit 78
|
|
23
|
+
;;
|
|
24
|
+
esac
|
|
25
|
+
|
|
26
|
+
# SSLKEYLOGFILE writes TLS session keys to disk; the smoke test must not
|
|
27
|
+
# inherit it. The CA-pool variables (SSL_CERT_FILE, SSL_CERT_DIR,
|
|
28
|
+
# CURL_CA_BUNDLE) are deliberately NOT stripped: `hcloud` is a Go client that
|
|
29
|
+
# reads them for its root pool, and a founder behind a TLS-inspecting proxy
|
|
30
|
+
# would otherwise see an x509 failure on the billable smoke test reported as
|
|
31
|
+
# "token lacks write scope" (the credential linter requires only the xtrace
|
|
32
|
+
# refusal above — measured).
|
|
33
|
+
unset SSLKEYLOGFILE
|
|
34
|
+
|
|
35
|
+
# --- shared operator-script library ------------------------------------------
|
|
36
|
+
# Sourced, never inlined: there is one distribution mode and therefore no copy to
|
|
37
|
+
# drift from. The library supplies the prompt classes, the run ledger and the
|
|
38
|
+
# secret-write helpers. The `read -rs` below STAYS IN THIS FILE — the prompt
|
|
39
|
+
# string is the operator-facing product, and the prologue rule above is why the
|
|
40
|
+
# surround cannot be moved either.
|
|
41
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
42
|
+
# An override must be ABSOLUTE, for the reason template.sh states at its own
|
|
43
|
+
# resolution ladder: `-r` tests a relative name against cwd while `source`
|
|
44
|
+
# searches PATH for it, so a relative value can pass the readability check and
|
|
45
|
+
# then source a DIFFERENT file into a shell that is about to hold a live token.
|
|
46
|
+
# The generated scripts have carried this guard since R26; the proving consumer
|
|
47
|
+
# is the one place it was missing.
|
|
48
|
+
if [[ -n "${SOLEUR_OP_LIB:-}" && "${SOLEUR_OP_LIB}" != /* ]]; then
|
|
49
|
+
printf 'SOLEUR_BOOTSTRAP_BAD_ARG var=SOLEUR_OP_LIB reason=must-be-absolute value=%s\n' "$SOLEUR_OP_LIB"
|
|
50
|
+
exit 64
|
|
51
|
+
fi
|
|
52
|
+
SOLEUR_OP_LIB="${SOLEUR_OP_LIB:-${SCRIPT_DIR}/../../../scripts/lib/operator-script.sh}"
|
|
53
|
+
if [[ ! -r "$SOLEUR_OP_LIB" ]]; then
|
|
54
|
+
printf 'SOLEUR_BOOTSTRAP_LIB_MISSING path=%s\n' "$SOLEUR_OP_LIB"
|
|
55
|
+
exit 64
|
|
56
|
+
fi
|
|
57
|
+
# shellcheck source=../../../scripts/lib/operator-script.sh disable=SC1091
|
|
58
|
+
source "$SOLEUR_OP_LIB"
|
|
59
|
+
# API contract (library header §API): prints nothing on success. EQUALITY, not
|
|
60
|
+
# -ge — the library auto-updates with the plugin; see the template's comment.
|
|
61
|
+
[[ ${SOLEUR_OP_LIB_API:-0} -eq 1 ]] || {
|
|
62
|
+
printf 'SOLEUR_BOOTSTRAP_LIB_INCOMPATIBLE need=1 got=%s\n' "${SOLEUR_OP_LIB_API:-0}"
|
|
63
|
+
exit 64
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
SLUG=""
|
|
67
|
+
DRY_RUN=false
|
|
68
|
+
|
|
69
|
+
usage() {
|
|
70
|
+
echo "Usage: provision-hetzner <tenant-slug> [--dry-run]" >&2
|
|
71
|
+
exit 1
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
while [[ $# -gt 0 ]]; do
|
|
75
|
+
case "$1" in
|
|
76
|
+
--dry-run) DRY_RUN=true; shift ;;
|
|
77
|
+
--help|-h) usage ;;
|
|
78
|
+
-*) echo "Unknown flag: $1" >&2; usage ;;
|
|
79
|
+
*)
|
|
80
|
+
if [[ -z "$SLUG" ]]; then SLUG="$1"
|
|
81
|
+
else echo "Unexpected argument: $1" >&2; usage
|
|
82
|
+
fi
|
|
83
|
+
shift ;;
|
|
84
|
+
esac
|
|
85
|
+
done
|
|
86
|
+
|
|
87
|
+
[[ -n "$SLUG" ]] || { echo "Error: tenant-slug is required." >&2; usage; }
|
|
88
|
+
|
|
89
|
+
if ! [[ "$SLUG" =~ ^[a-z0-9]+(-[a-z0-9]+)*$ ]]; then
|
|
90
|
+
echo "Error: tenant-slug must be kebab-case (e.g. 'acme-prd')." >&2
|
|
91
|
+
exit 1
|
|
92
|
+
fi
|
|
93
|
+
|
|
94
|
+
PROBE_NAME="probe-provision-${SLUG}"
|
|
95
|
+
CREATED_RESOURCES=()
|
|
96
|
+
|
|
97
|
+
cleanup() {
|
|
98
|
+
local exit_code=$?
|
|
99
|
+
echo ""
|
|
100
|
+
echo "=== Teardown commands (resources created during this run) ==="
|
|
101
|
+
if [[ ${#CREATED_RESOURCES[@]} -eq 0 ]]; then
|
|
102
|
+
echo " (no resources were created)"
|
|
103
|
+
else
|
|
104
|
+
for res in "${CREATED_RESOURCES[@]}"; do
|
|
105
|
+
echo " $res"
|
|
106
|
+
done
|
|
107
|
+
fi
|
|
108
|
+
echo ""
|
|
109
|
+
echo "If the probe server '${PROBE_NAME}' was not cleaned up:"
|
|
110
|
+
echo " hcloud server delete '${PROBE_NAME}'"
|
|
111
|
+
echo ""
|
|
112
|
+
echo "To tear down the Hetzner sub-project:"
|
|
113
|
+
echo " Delete via Hetzner Console → Projects → tenant-${SLUG}-prd → Delete"
|
|
114
|
+
echo " (CLI does not support project deletion)"
|
|
115
|
+
exit "$exit_code"
|
|
116
|
+
}
|
|
117
|
+
trap cleanup EXIT INT TERM
|
|
118
|
+
|
|
119
|
+
# --- Pre-checks ---
|
|
120
|
+
|
|
121
|
+
command -v hcloud >/dev/null 2>&1 || { echo "Error: 'hcloud' CLI not found. Install: https://github.com/hetznercloud/cli" >&2; exit 1; }
|
|
122
|
+
|
|
123
|
+
# --- DPA gate ---
|
|
124
|
+
|
|
125
|
+
DPA_FILE="knowledge-base/legal/tenant-dpa-register.md"
|
|
126
|
+
[[ -f "$DPA_FILE" ]] || { echo "DPA register not found at $DPA_FILE. Run from Soleur monorepo root." >&2; exit 3; }
|
|
127
|
+
awk -F'|' -v slug="$SLUG" '/^\|/ { gsub(/^ +| +$/, "", $2); if ($2 == slug) found = ($8 ~ /^ *(dpa-signed|provisioning-in-progress) *$/) } END { exit !found }' "$DPA_FILE" \
|
|
128
|
+
|| { echo "No active DPA row for '$SLUG'. Sign DPA (Step 0) first." >&2; exit 3; }
|
|
129
|
+
|
|
130
|
+
# --- Dry-run output ---
|
|
131
|
+
|
|
132
|
+
if $DRY_RUN; then
|
|
133
|
+
echo ""
|
|
134
|
+
echo "=== DRY RUN — No changes will be made ==="
|
|
135
|
+
echo ""
|
|
136
|
+
echo "--- Console guidance ---"
|
|
137
|
+
echo "1. Log in to the tenant's Hetzner Cloud Console"
|
|
138
|
+
echo "2. Create a sub-project named 'tenant-${SLUG}-prd'"
|
|
139
|
+
echo "3. Inside the sub-project, go to Security → API Tokens"
|
|
140
|
+
echo "4. Create a project-scoped API token with Read+Write permissions"
|
|
141
|
+
echo "5. Copy the token (shown only once)"
|
|
142
|
+
echo ""
|
|
143
|
+
echo "--- Smoke-test commands (run after token creation) ---"
|
|
144
|
+
echo "read -rs -p 'Hetzner token: ' HCLOUD_TOKEN; echo"
|
|
145
|
+
echo "("
|
|
146
|
+
echo " export HCLOUD_TOKEN"
|
|
147
|
+
echo " hcloud server create --name '${PROBE_NAME}' --type cx11 --image ubuntu-22.04 --location nbg1"
|
|
148
|
+
echo " hcloud server delete '${PROBE_NAME}'"
|
|
149
|
+
echo ")"
|
|
150
|
+
echo "unset HCLOUD_TOKEN"
|
|
151
|
+
echo ""
|
|
152
|
+
echo "--- Teardown ---"
|
|
153
|
+
echo " Delete sub-project via Console: Projects → tenant-${SLUG}-prd → Delete"
|
|
154
|
+
echo " Revoke the API token: Security → API Tokens → Revoke"
|
|
155
|
+
echo ""
|
|
156
|
+
echo "Next step: type /soleur:provision-cloudflare ${SLUG} <zone-id> <account-id> yourself (user-invoked; Soleur cannot run it, ADR-236)"
|
|
157
|
+
exit 0
|
|
158
|
+
fi
|
|
159
|
+
|
|
160
|
+
# --- Interactive flow ---
|
|
161
|
+
|
|
162
|
+
# Run ledger home. The library's default is "beside the main script", which for
|
|
163
|
+
# THIS script is the plugin tree (a marketplace cache, untracked, not ignored —
|
|
164
|
+
# review P2-19). The DPA gate above already requires cwd to be the monorepo
|
|
165
|
+
# root, so the ledger goes under its `.soleur/` (gitignored). Set AFTER the
|
|
166
|
+
# dry-run branch so the golden stdout is untouched, and BEFORE ledger_init.
|
|
167
|
+
: "${SOLEUR_BOOTSTRAP_LEDGER:=$(pwd)/.soleur/bootstrap-runs.jsonl}"
|
|
168
|
+
export SOLEUR_BOOTSTRAP_LEDGER
|
|
169
|
+
|
|
170
|
+
echo ""
|
|
171
|
+
echo "=== Hetzner provisioning for '${SLUG}' ==="
|
|
172
|
+
echo ""
|
|
173
|
+
echo "Hetzner does not have a Terraform resource for project creation or token minting."
|
|
174
|
+
echo "Follow these steps in the Hetzner Cloud Console:"
|
|
175
|
+
echo ""
|
|
176
|
+
echo " 1. Log in to the tenant's Hetzner Cloud master account"
|
|
177
|
+
echo " 2. Create a sub-project named 'tenant-${SLUG}-prd'"
|
|
178
|
+
echo " 3. Inside the sub-project, go to Security → API Tokens"
|
|
179
|
+
echo " 4. Create a project-scoped API token with Read+Write permissions"
|
|
180
|
+
echo " 5. Copy the token (shown only once)"
|
|
181
|
+
echo ""
|
|
182
|
+
|
|
183
|
+
soleur_op_ledger_init 2 "provision-hetzner.sh"
|
|
184
|
+
soleur_op_stage_begin 1 "operator mints the project-scoped token"
|
|
185
|
+
|
|
186
|
+
# CLASS 3 — out-of-band completion barrier. It attests that a human did something
|
|
187
|
+
# OUTSIDE this script, so it takes a named skip variable AND is followed by an
|
|
188
|
+
# independent verification: the write-class smoke test below fails if the
|
|
189
|
+
# attestation was false. Today's behaviour was fail-closed but MUTE — EOF read
|
|
190
|
+
# into an empty ACK and `exit 1` with "Aborted.", the right outcome with an
|
|
191
|
+
# unattributed cause. Now: SOLEUR_BOOTSTRAP_INPUT_REQUIRED and exit 64.
|
|
192
|
+
soleur_op_barrier SOLEUR_BOOTSTRAP_SKIP_HETZNER_TOKEN_BARRIER "Token created? Type 'yes' to continue: "
|
|
193
|
+
|
|
194
|
+
# --- Accept token + smoke-test ---
|
|
195
|
+
|
|
196
|
+
echo ""
|
|
197
|
+
echo "--- Write-class smoke-test ---"
|
|
198
|
+
echo "Creating + deleting probe server '${PROBE_NAME}' (cx11, nbg1) to verify token scope."
|
|
199
|
+
echo ""
|
|
200
|
+
|
|
201
|
+
# Credential ENTRY. The library supplies the SURROUND (named skip variable, TTY
|
|
202
|
+
# gate, exit 64 naming the variable); the `read -rs` itself stays in this file
|
|
203
|
+
# because the prompt string is the operator-facing product (plan D12). The
|
|
204
|
+
# library's class-1 helper echoes its input and is for non-secret values only.
|
|
205
|
+
#
|
|
206
|
+
# The TTY gate sits ABOVE the read, never below it: the property is about the
|
|
207
|
+
# instant BEFORE the read, and a check that runs after it cannot see the hang.
|
|
208
|
+
hcloud_token_skip="$(soleur_op_skip_value SOLEUR_BOOTSTRAP_HCLOUD_TOKEN)"
|
|
209
|
+
if [[ -n "$hcloud_token_skip" ]]; then
|
|
210
|
+
HCLOUD_TOKEN="$hcloud_token_skip"
|
|
211
|
+
else
|
|
212
|
+
[[ -t 0 ]] || soleur_op_input_required SOLEUR_BOOTSTRAP_HCLOUD_TOKEN
|
|
213
|
+
read -rs -p "Hetzner project-scoped API token: " HCLOUD_TOKEN
|
|
214
|
+
echo ""
|
|
215
|
+
fi
|
|
216
|
+
unset hcloud_token_skip
|
|
217
|
+
|
|
218
|
+
soleur_op_stage_end 1 "operator mints the project-scoped token" ok 0
|
|
219
|
+
soleur_op_stage_begin 2 "write-class smoke test (billable)"
|
|
220
|
+
|
|
221
|
+
# CLASS 2 — per-command destructive-write acknowledgement, and it takes NO SKIP
|
|
222
|
+
# VARIABLE by design. `hcloud server create` below bills a real server, and this
|
|
223
|
+
# file had no acknowledgement in front of it: the existing "Token created?" ack
|
|
224
|
+
# acknowledges TOKEN CREATION and is separated from the create by the token read.
|
|
225
|
+
# Giving this one an environment-variable escape would be exactly the "prior
|
|
226
|
+
# approval extending to a new command" that hr-menu-option-ack-not-prod-write-auth
|
|
227
|
+
# forbids — an unattended billable create introduced by the machinery that claims
|
|
228
|
+
# to prevent it (plan revision R8).
|
|
229
|
+
soleur_op_ack_or_die "Create the billable probe server '${PROBE_NAME}' now? Type 'yes': "
|
|
230
|
+
|
|
231
|
+
(
|
|
232
|
+
export HCLOUD_TOKEN
|
|
233
|
+
trap 'echo "Cleaning up probe server..."; hcloud server delete "$PROBE_NAME" 2>/dev/null || true' EXIT INT TERM
|
|
234
|
+
|
|
235
|
+
echo "Creating probe server '${PROBE_NAME}'..."
|
|
236
|
+
if ! hcloud server create --name "$PROBE_NAME" --type cx11 --image ubuntu-22.04 --location nbg1; then
|
|
237
|
+
echo "" >&2
|
|
238
|
+
echo "Error: Server creation failed. The token may have insufficient scope." >&2
|
|
239
|
+
echo "Verify the token has Read+Write permissions for this sub-project." >&2
|
|
240
|
+
exit 1
|
|
241
|
+
fi
|
|
242
|
+
|
|
243
|
+
echo "Probe server created. Deleting..."
|
|
244
|
+
|
|
245
|
+
if ! hcloud server delete "$PROBE_NAME"; then
|
|
246
|
+
echo "" >&2
|
|
247
|
+
echo "Error: Server deletion failed. The probe server '${PROBE_NAME}' may still exist." >&2
|
|
248
|
+
echo "Delete manually: hcloud server delete '${PROBE_NAME}'" >&2
|
|
249
|
+
exit 1
|
|
250
|
+
fi
|
|
251
|
+
|
|
252
|
+
echo "Probe server deleted."
|
|
253
|
+
)
|
|
254
|
+
|
|
255
|
+
unset HCLOUD_TOKEN
|
|
256
|
+
|
|
257
|
+
soleur_op_stage_end 2 "write-class smoke test (billable)" ok 0
|
|
258
|
+
|
|
259
|
+
echo ""
|
|
260
|
+
echo "Smoke-test passed: token has write scope for sub-project 'tenant-${SLUG}-prd'."
|
|
261
|
+
echo ""
|
|
262
|
+
echo "Next step: type /soleur:provision-cloudflare ${SLUG} <zone-id> <account-id> yourself (user-invoked; Soleur cannot run it, ADR-236)"
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Tenant DPA register (SYNTHESIZED TEST FIXTURE — not the live register)"
|
|
3
|
+
type: tenant-dpa-register-fixture
|
|
4
|
+
status: fixture
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Tenant DPA register — synthesized fixture
|
|
8
|
+
|
|
9
|
+
**This file is a test fixture.** Every value is synthesized (`cq-test-fixtures-synthesized-only`);
|
|
10
|
+
no row describes a real tenant, a real legal entity, or a real founder. It exists because the DPA
|
|
11
|
+
gate in `provision-hetzner.sh` runs BEFORE the `--dry-run` branch and reads
|
|
12
|
+
`knowledge-base/legal/tenant-dpa-register.md` relative to the working directory — so a
|
|
13
|
+
characterization suite running outside the repository exits 3 without a register to read.
|
|
14
|
+
|
|
15
|
+
`Status` is the 7th visible column, which is `awk -F'|'` field `$8` (field `$1` is the empty
|
|
16
|
+
string left of the leading pipe).
|
|
17
|
+
|
|
18
|
+
## Rows
|
|
19
|
+
|
|
20
|
+
| Tenant slug | Legal entity | Founder UUID | DPA signed date | DPA counter-signed date | Sub-processors (Schedule 2) | Status | Notes |
|
|
21
|
+
|---|---|---|---|---|---|---|---|
|
|
22
|
+
| fixture-tenant | Fixture Entity SARL | 00000000-0000-4000-8000-000000000000 | 2026-01-01 | 2026-01-02 | hetzner, cloudflare | dpa-signed | synthesized fixture row |
|
|
23
|
+
| fixture-inflight | Fixture Inflight SARL | 00000000-0000-4000-8000-000000000001 | 2026-01-03 | | hetzner | provisioning-in-progress | synthesized fixture row |
|
|
24
|
+
| fixture-revoked | Fixture Revoked SARL | 00000000-0000-4000-8000-000000000002 | 2026-01-04 | 2026-01-05 | hetzner | terminated | synthesized: must NOT pass the gate |
|
|
25
|
+
| fixture-offboarded | Fixture Offboarded SARL | 00000000-0000-4000-8000-000000000003 | 2026-01-06 | 2026-01-07 | hetzner | dpa-signed | synthesized: historical row of an offboarded tenant (register is append-only) |
|
|
26
|
+
| fixture-offboarded | Fixture Offboarded SARL | 00000000-0000-4000-8000-000000000003 | 2026-01-06 | 2026-01-07 | hetzner | terminated | synthesized: the LATER row wins; must NOT pass the gate |
|