@soleur/opencode 0.0.0-stage → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.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 +659 -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 +108 -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 +342 -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 +152 -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 +493 -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 +363 -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 +520 -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 +113 -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 +178 -0
- package/scripts/sync-opencode-adapter.ts +479 -0
- package/scripts/sync-pr-behind.sh +534 -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 +65 -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 +142 -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 +118 -0
- package/skills/fix-issue/references/exclude-label-jq-snippet.md +96 -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 +668 -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 +325 -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 +138 -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 +1621 -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-todo-structure.md +165 -0
- package/skills/review/references/risk-tier-and-fix-rounds.md +95 -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 +3022 -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/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/detached-battery-verdict.md +13 -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 +149 -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/work/SKILL.md +1479 -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,410 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# shellcheck disable=SC2015,SC2018,SC2019 # A && B || C is the check idiom; tr A-Z is the portable ASCII lowering
|
|
3
|
+
# The /ship Phase 6 step 5 hold evaluator: turns the recorded `Gate:` predicates of `## Operator Holds` (or of a
|
|
4
|
+
# Production Envelope's `Preconditions:`) into a mechanical verdict, so a hold is discharged by evidence and never
|
|
5
|
+
# by a model's reading of prose. Procedure and wording: skills/ship/references/operator-holds.md. Format source:
|
|
6
|
+
# skills/brainstorm-techniques/references/standing-delegation.md.
|
|
7
|
+
#
|
|
8
|
+
# Property: plan mode verifies the delegation, and a hold is discharged only if a Standing Delegation is cited
|
|
9
|
+
# (verifier rc 0 AND a first line `delegation: valid`) and EVERY one of its `Gate:` predicates is a known kind that
|
|
10
|
+
# evaluates true now. Any other state leaves it standing: an unknown kind, an unreadable probe, a missing,
|
|
11
|
+
# ambiguous or invalid delegation, a missing envelope, a timeout, a missing time-limit tool, a hold with no gate.
|
|
12
|
+
# --file mode does not verify a delegation (the caller just did); it only measures one envelope's `Preconditions:` gates.
|
|
13
|
+
#
|
|
14
|
+
# Usage:
|
|
15
|
+
# hold-gate-eval.sh --plan <plan.md> evaluate `## Operator Holds`
|
|
16
|
+
# hold-gate-eval.sh --file <envelope.md> --section "<title>" evaluate one envelope's gates
|
|
17
|
+
# hold-gate-eval.sh --file "<envelope.md>#<title>" the same, addressed as the verifier does
|
|
18
|
+
# Run from the repository root (repo-relative paths are resolved from the working directory). The title is matched
|
|
19
|
+
# without regard to case against `##`..`####` headings (substring).
|
|
20
|
+
#
|
|
21
|
+
# Plan format (read from the file, never from conversation). The heading is `## Operator Holds` at level 2 to 4,
|
|
22
|
+
# any case; a section ends at the next heading of the same or a shallower level:
|
|
23
|
+
# ## Operator Holds
|
|
24
|
+
# Delegation: <comment url> exactly one; without it no hold can be discharged here (exit 3)
|
|
25
|
+
# Envelope: <path>[#<title>] REQUIRED beside a Delegation line; passed to the verifier
|
|
26
|
+
# - Hold: <the operator's words, verbatim>
|
|
27
|
+
# Gate: pr-merged <N> | no-inflight-run <workflow-file>
|
|
28
|
+
# `command` and `run-green` are deferred. The first real consumer re-adds them, and only by CTO ruling. A `Gate:`
|
|
29
|
+
# line of any other kind is an unknown kind: it exits 2 and the hold stands. Markers (`Hold:`, `Gate:`,
|
|
30
|
+
# `Delegation:`, `Envelope:`) are read in any case, with or without the list dash and a space before the colon.
|
|
31
|
+
# Lines inside a code fence (same character to close, at least as long) are examples and are ignored.
|
|
32
|
+
#
|
|
33
|
+
# Exit: 0 every hold discharged (or none recorded: an absent or empty section is a no-op);
|
|
34
|
+
# 1 at least one hold STANDS; 2 cannot evaluate (treated as STANDS by the caller; includes a hold or a gate
|
|
35
|
+
# outside any section this script can read, a Delegation line with zero holds, two Delegation or
|
|
36
|
+
# Envelope lines, a missing Envelope line, an unknown kind, an unreadable probe, an unreadable delegation,
|
|
37
|
+
# a missing time-limit tool);
|
|
38
|
+
# 3 no `Delegation:` line anywhere in the hold sections: legacy prose holds. Decided BEFORE every structure
|
|
39
|
+
# and tool check, so the caller keeps its prose evaluation (operator-holds.md section 3).
|
|
40
|
+
# stdout: when a delegation was checked, its verdict line first (`delegation: <valid|invalid|unverifiable>
|
|
41
|
+
# reason=<token>`); then one plain line per hold, then `holds: N discharged: M standing: K`. A `Done:` line carries
|
|
42
|
+
# the gate text that was true. Exit 2 and 1 are never converted to a pass by any caller; nothing here retries a
|
|
43
|
+
# failed probe into a pass. Any other status the caller sees (127 script not found, 124, 137) is a hold that was
|
|
44
|
+
# not checked: treat it as 2.
|
|
45
|
+
#
|
|
46
|
+
# `Operator-reserved:` (at the START of a hold's words; case, spaces, hyphens, underscores, bold, quotes, full-width colon and
|
|
47
|
+
# invisible characters are ignored, so `Operator reserved:` and `**Operator-reserved:**` count) marks a hold that reserves the decision to the
|
|
48
|
+
# operator (pricing approval, brand copy, spend). A gate only says WHEN a condition is true, never WHO may clear the
|
|
49
|
+
# hold, so such a hold always STANDS: it is printed `Reserved for you: ... - only you can clear this`, its gates are
|
|
50
|
+
# not probed, and the run exits 2. Every `Hold:` or `Gate:` line must sit inside a readable hold section; one that does
|
|
51
|
+
# not (a misspelt second heading, text after the next heading) is exit 2, never silently dropped. --file mode reads the
|
|
52
|
+
# COMMITTED blob (HEAD), exactly as the verifier does, never the working tree: an untracked, symlinked or dirty file
|
|
53
|
+
# cannot change the answer. Test seam: HGE_VERIFY_TIMEOUT (seconds, 1-59) can only SHORTEN the 60 s verifier limit.
|
|
54
|
+
#
|
|
55
|
+
# The default branch is resolved once (origin/HEAD, else `git ls-remote --symref`); `pr-merged` needs MERGED into
|
|
56
|
+
# it and the merge commit reachable from HEAD after a fresh fetch of it. Every gh, git and verifier call gets
|
|
57
|
+
# `</dev/null`, so a call that drains stdin cannot swallow the remaining gates or holds. In flight means the
|
|
58
|
+
# status is queued, in_progress, waiting, requested or pending (ONE `gh run list`, the last 100 runs); a status
|
|
59
|
+
# this script does not know is exit 2.
|
|
60
|
+
#
|
|
61
|
+
# `set -uo pipefail`, deliberately NOT `-e`. Portable to bash 3.2 and mawk. Lines ending `# mut:<name>` are the
|
|
62
|
+
# mutation points the suite edits to prove each check can fail.
|
|
63
|
+
|
|
64
|
+
set -uo pipefail
|
|
65
|
+
export LC_ALL=C
|
|
66
|
+
|
|
67
|
+
SCRIPT_DIR="$(cd -P "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
|
|
68
|
+
VERIFY="$SCRIPT_DIR/../../../scripts/delegation-verify.sh"
|
|
69
|
+
WORK=""
|
|
70
|
+
cleanup() { [ -n "$WORK" ] && rm -rf "${WORK:?}"; return 0; }
|
|
71
|
+
trap cleanup EXIT
|
|
72
|
+
|
|
73
|
+
die2() { printf '%s\n' "$1" >&2; exit 2; }
|
|
74
|
+
trim() { local s="$1"; s="${s#"${s%%[![:space:]]*}"}"; s="${s%"${s##*[![:space:]]}"}"; printf '%s' "$s"; }
|
|
75
|
+
# Control characters, C1 controls, zero-width and bidi marks and the line/paragraph separators are dropped (byte-wise: LC_ALL=C).
|
|
76
|
+
clean_text() { printf '%s' "$1" | tr -d '[:cntrl:]' | sed -e $'s/\xc2[\x80-\x9f]//g' -e $'s/\xe2\x80[\x8b-\x8f\xa8-\xae]//g' -e $'s/\xe2\x81[\xa6-\xa9]//g' -e $'s/\xef\xbb\xbf//g' | cut -c1-160; } # mut:clean-text
|
|
77
|
+
|
|
78
|
+
VT=60
|
|
79
|
+
case "${HGE_VERIFY_TIMEOUT:-}" in ''|*[!0-9]*) ;; *) [ "$HGE_VERIFY_TIMEOUT" -ge 1 ] && [ "$HGE_VERIFY_TIMEOUT" -lt 60 ] && VT="$HGE_VERIFY_TIMEOUT" ;; esac
|
|
80
|
+
TO10=(); TO30=(); TO60=(); HAVE_TO=0
|
|
81
|
+
if command -v timeout >/dev/null 2>&1; then TO10=(timeout 10); TO30=(timeout 30); TO60=(timeout "$VT"); HAVE_TO=1
|
|
82
|
+
elif command -v gtimeout >/dev/null 2>&1; then TO10=(gtimeout 10); TO30=(gtimeout 30); TO60=(gtimeout "$VT"); HAVE_TO=1; fi
|
|
83
|
+
|
|
84
|
+
DEFBR=""; DEFBR_DONE=""
|
|
85
|
+
resolve_default_branch() { # sets DEFBR to the repository's default branch name, or leaves it empty
|
|
86
|
+
[ -z "$DEFBR_DONE" ] || return 0
|
|
87
|
+
DEFBR_DONE=1
|
|
88
|
+
local ref
|
|
89
|
+
ref="$(git symbolic-ref --quiet --short refs/remotes/origin/HEAD </dev/null 2>/dev/null)"; ref="${ref#origin/}"
|
|
90
|
+
if [ -z "$ref" ]; then
|
|
91
|
+
ref="$(GIT_TERMINAL_PROMPT=0 ${TO10[@]+"${TO10[@]}"} git ls-remote --symref origin HEAD </dev/null 2>/dev/null | sed -n 's|^ref: refs/heads/\(.*\)[[:space:]]HEAD$|\1|p' | head -1)"
|
|
92
|
+
fi
|
|
93
|
+
[[ "$ref" =~ ^[A-Za-z0-9._/-]+$ ]] && DEFBR="$ref" # mut:defbr
|
|
94
|
+
return 0
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
FETCHED=""; FETCH_RC=0
|
|
98
|
+
ensure_fetch() {
|
|
99
|
+
[ -n "$FETCHED" ] && return "$FETCH_RC"
|
|
100
|
+
FETCHED=1
|
|
101
|
+
GIT_TERMINAL_PROMPT=0 ${TO30[@]+"${TO30[@]}"} git fetch --no-tags -q origin "$DEFBR" </dev/null >/dev/null 2>&1; FETCH_RC=$? # mut:fetch
|
|
102
|
+
return "$FETCH_RC"
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
gh_json() { # <outfile> <gh args...>: 0 only when gh succeeded and printed valid JSON
|
|
106
|
+
local out="$1"; shift
|
|
107
|
+
${TO10[@]+"${TO10[@]}"} gh "$@" > "$out" 2>/dev/null </dev/null || return 1 # mut:stdin-gh
|
|
108
|
+
jq -e . "$out" >/dev/null 2>&1 </dev/null
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
known_kind() { case "$1" in pr-merged|no-inflight-run) return 0 ;; esac; return 1; }
|
|
112
|
+
|
|
113
|
+
GRES=""; GWHY=""
|
|
114
|
+
gate_pr_merged() {
|
|
115
|
+
local n="$1" st sha base rc
|
|
116
|
+
[[ "$n" =~ ^[0-9]+$ ]] || { GRES=UNEVAL; GWHY="the earlier change is not named by a plain number"; return; }
|
|
117
|
+
resolve_default_branch
|
|
118
|
+
[ -n "$DEFBR" ] || { GRES=UNEVAL; GWHY="I could not tell which line of work is the main one"; return; }
|
|
119
|
+
ensure_fetch || true
|
|
120
|
+
gh_json "$WORK/pr.json" pr view "$n" --json state,mergeCommit,baseRefName || { GRES=UNEVAL; GWHY="I could not read the state of the earlier change"; return; }
|
|
121
|
+
st="$(jq -r '.state // empty' "$WORK/pr.json" </dev/null)"; sha="$(jq -r '.mergeCommit.oid // empty' "$WORK/pr.json" </dev/null)"; base="$(jq -r '.baseRefName // empty' "$WORK/pr.json" </dev/null)"
|
|
122
|
+
GWHY="the earlier change has not gone live yet"
|
|
123
|
+
if [ "$st" = MERGED ] && [ "$base" = "$DEFBR" ] && [[ "$sha" =~ ^[0-9a-f]{7,40}$ ]]; then
|
|
124
|
+
git merge-base --is-ancestor "$sha" HEAD </dev/null >/dev/null 2>&1; rc=$?
|
|
125
|
+
case "$rc" in
|
|
126
|
+
0) GRES=TRUE ;;
|
|
127
|
+
1) GRES=FALSE; GWHY="the earlier change is live, but this work has not been brought up to date with it yet" ;;
|
|
128
|
+
*) GRES=UNEVAL; GWHY="I could not compare this work with the earlier change" ;;
|
|
129
|
+
esac
|
|
130
|
+
else
|
|
131
|
+
GRES=FALSE
|
|
132
|
+
if [ "$st" = MERGED ] && [ "$base" = "$DEFBR" ]; then GWHY="the earlier change is recorded as live, but I cannot see which version of the work it became"
|
|
133
|
+
elif [ "$st" = MERGED ]; then GWHY="the earlier change went into another line of work, not the main one"; fi
|
|
134
|
+
fi
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
gate_no_inflight() {
|
|
138
|
+
local wf="$1" live unk
|
|
139
|
+
[[ "$wf" =~ ^[A-Za-z0-9._-]+\.ya?ml$ ]] || { GRES=UNEVAL; GWHY="the release is not named as a plain workflow file"; return; }
|
|
140
|
+
if ! gh_json "$WORK/runs.json" run list --workflow "$wf" --limit 100 --json status \
|
|
141
|
+
|| ! jq -e 'type == "array" and all(.[]; type == "object")' "$WORK/runs.json" >/dev/null 2>&1 </dev/null; then
|
|
142
|
+
GRES=UNEVAL; GWHY="I could not read the list of running releases"; return
|
|
143
|
+
fi
|
|
144
|
+
live="$(jq '[.[] | .status as $s | select($s == "queued" or $s == "in_progress" or $s == "waiting" or $s == "requested" or $s == "pending")] | length' "$WORK/runs.json" </dev/null)"
|
|
145
|
+
unk="$(jq '[.[] | .status as $s | select($s != "completed" and $s != "queued" and $s != "in_progress" and $s != "waiting" and $s != "requested" and $s != "pending")] | length' "$WORK/runs.json" </dev/null)"
|
|
146
|
+
GWHY="a release is still running"
|
|
147
|
+
if [ "${live:-1}" -gt 0 ]; then GRES=FALSE
|
|
148
|
+
elif [ "${unk:-1}" -gt 0 ]; then GRES=UNEVAL; GWHY="a release is in a state I do not know" # mut:status-unknown
|
|
149
|
+
else GRES=TRUE; fi
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
eval_gate() { # <gate text after `Gate:`> -> GRES (TRUE|FALSE|UNEVAL), GWHY
|
|
153
|
+
local text="$1" kind rest
|
|
154
|
+
GRES=UNEVAL; GWHY="I do not know this kind of condition, so it stays on hold"
|
|
155
|
+
kind="${text%%[[:space:]]*}"; rest="$(trim "${text#"$kind"}")"
|
|
156
|
+
known_kind "$kind" || { GRES=UNEVAL; return; } # mut:unknown-kind
|
|
157
|
+
case "$kind" in
|
|
158
|
+
pr-merged) gate_pr_merged "$rest" ;;
|
|
159
|
+
no-inflight-run) gate_no_inflight "$rest" ;;
|
|
160
|
+
esac
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
# split_sections <file> <mode> <match>: sections into $WORK/sec.<n> (heads in sec.heads), count in sec.count.
|
|
164
|
+
# Plan mode: a heading of level 2-4 reading "Operator Holds" in any case. File mode: a level 2-4 heading containing
|
|
165
|
+
# <match> (any case). A section ends at the next heading of the same or a shallower level. Fenced lines are text.
|
|
166
|
+
split_sections() {
|
|
167
|
+
awk -v dir="$WORK" -v mode="$2" -v match_text="$3" '
|
|
168
|
+
function trim(s) { sub(/^[ \t]+/, "", s); sub(/[ \t]+$/, "", s); return s }
|
|
169
|
+
function fence( tok, c, n) {
|
|
170
|
+
tok = t; sub(/^ +/, "", tok)
|
|
171
|
+
match(tok, /^(`+|~+)/); c = substr(tok, 1, 1); n = RLENGTH
|
|
172
|
+
if (!f) { if (c == "`" && substr(tok, n + 1) ~ /`/) return; f = 1; fc = c; fn = n; return }
|
|
173
|
+
if (c == fc && n >= fn && tok ~ /^(`+|~+)[ \t]*$/) f = 0
|
|
174
|
+
}
|
|
175
|
+
BEGIN { mt = tolower(match_text) }
|
|
176
|
+
{ t = $0; sub(/\r$/, "", t) }
|
|
177
|
+
t ~ /^ ? ? ?(```+|~~~+)/ { fence() } # mut:fence-split
|
|
178
|
+
f == 0 && (t ~ /^#+[ \t]/ || t ~ /^#+$/) {
|
|
179
|
+
match(t, /^#+/); L = RLENGTH
|
|
180
|
+
if (cur != "" && L <= curlvl) { close(cur); cur = "" }
|
|
181
|
+
if (cur == "" && L >= 2 && L <= 4) {
|
|
182
|
+
rest = tolower(trim(substr(t, L + 1))) # mut:heading-ci
|
|
183
|
+
sub(/[ \t]+#+$/, "", rest)
|
|
184
|
+
if (mode == "plan") hit = (rest ~ /^operator[ \t]+holds$/ || rest ~ /^operator[ \t]+holds[^a-z0-9]/); else hit = (mt != "" && index(rest, mt) > 0)
|
|
185
|
+
if (hit) { n++; cur = dir "/sec." n; curlvl = L; print t > (dir "/sec.heads") }
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
cur != "" { print $0 > cur }
|
|
189
|
+
END { print n + 0 > (dir "/sec.count") }
|
|
190
|
+
' "$1"
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
# Marker spellings (security V4). Both the counter and the parser first NORMALISE a line: full-width colon to ":", NBSP and the
|
|
194
|
+
# other Unicode spaces to " ", zero-width characters and the soft hyphen dropped, Unicode hyphens to "-"; then leading list,
|
|
195
|
+
# quote and emphasis markers (`* ` `+ ` `- ` `1. ` `2) ` `> ` `**` `__`) are stripped, so `* Hold:`, `> Hold:`, `- **Hold:**`,
|
|
196
|
+
# `Hold:` and `Hold<NBSP>:` are all the marker `hold:`. byte-wise (LC_ALL=C).
|
|
197
|
+
NORM_AWK='
|
|
198
|
+
function trim(s) { sub(/^[ \t]+/, "", s); sub(/[ \t]+$/, "", s); return s }
|
|
199
|
+
function norm(s) {
|
|
200
|
+
gsub(/\357\274\232/, ":", s)
|
|
201
|
+
gsub(/\302\240/, " ", s); gsub(/\342\200[\200-\212]/, " ", s); gsub(/\342\200\257/, " ", s); gsub(/\342\201\237/, " ", s); gsub(/\343\200\200/, " ", s)
|
|
202
|
+
gsub(/\342\200[\213-\215]/, "", s); gsub(/\342\201\240/, "", s); gsub(/\357\273\277/, "", s); gsub(/\302\255/, "", s)
|
|
203
|
+
gsub(/\342\200[\220-\225]/, "-", s)
|
|
204
|
+
return s
|
|
205
|
+
}
|
|
206
|
+
function strip_prefix(s) {
|
|
207
|
+
while (match(s, /^([ \t]+|[>*+_-]+|[0-9]+[.)]([ \t]|$))/)) s = substr(s, RLENGTH + 1)
|
|
208
|
+
return s
|
|
209
|
+
}
|
|
210
|
+
function val(s) { s = substr(s, index(s, ":") + 1); sub(/^[*_ \t]+/, "", s); return trim(s) }
|
|
211
|
+
'
|
|
212
|
+
|
|
213
|
+
# marker_count <file>: prints how many unfenced `Hold:` or `Gate:` marker lines the file has.
|
|
214
|
+
marker_count() {
|
|
215
|
+
awk "$NORM_AWK"'
|
|
216
|
+
function fence( tok, c, n) {
|
|
217
|
+
tok = t; sub(/^ +/, "", tok)
|
|
218
|
+
match(tok, /^(`+|~+)/); c = substr(tok, 1, 1); n = RLENGTH
|
|
219
|
+
if (!f) { if (c == "`" && substr(tok, n + 1) ~ /`/) return; f = 1; fc = c; fn = n; return }
|
|
220
|
+
if (c == fc && n >= fn && tok ~ /^(`+|~+)[ \t]*$/) f = 0
|
|
221
|
+
}
|
|
222
|
+
{ t = $0; sub(/\r$/, "", t) }
|
|
223
|
+
t ~ /^ ? ? ?(```+|~~~+)/ { fence(); next }
|
|
224
|
+
f { next }
|
|
225
|
+
{ nt = norm(t) # mut:marker-norm
|
|
226
|
+
st = strip_prefix(nt); lt = tolower(st) # mut:ci-markers
|
|
227
|
+
}
|
|
228
|
+
lt ~ /^(hold|gate)[*_ \t]*:/ { found++ }
|
|
229
|
+
END { print found + 0 }
|
|
230
|
+
' "$1"
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
# parse_items <section file> <mode>: records DELEG / ENVF / HOLD i text / GATE i text / ORPHAN.
|
|
234
|
+
parse_items() {
|
|
235
|
+
awk -v mode="$2" "$NORM_AWK"'
|
|
236
|
+
function fence( tok, c, n) {
|
|
237
|
+
tok = t; sub(/^ +/, "", tok)
|
|
238
|
+
match(tok, /^(`+|~+)/); c = substr(tok, 1, 1); n = RLENGTH
|
|
239
|
+
if (!f) { if (c == "`" && substr(tok, n + 1) ~ /`/) return; f = 1; fc = c; fn = n; return }
|
|
240
|
+
if (c == fc && n >= fn && tok ~ /^(`+|~+)[ \t]*$/) f = 0
|
|
241
|
+
}
|
|
242
|
+
NR == 1 { if (mode == "file") { n = 1; print "HOLD\t1\tthe conditions before the act" } next }
|
|
243
|
+
{ t = $0; sub(/\r$/, "", t)
|
|
244
|
+
if (t ~ /^ ? ? ?(```+|~~~+)/) { fence(); next }
|
|
245
|
+
if (f) next
|
|
246
|
+
nt = norm(t) # mut:marker-norm
|
|
247
|
+
st = strip_prefix(nt); lt = tolower(st) # mut:ci-markers
|
|
248
|
+
if (mode == "plan" && lt ~ /^delegation[*_ \t]*:/) { print "DELEG\t" val(st); next }
|
|
249
|
+
if (mode == "plan" && lt ~ /^envelope[*_ \t]*:/) { print "ENVF\t" val(st); next }
|
|
250
|
+
if (mode == "plan" && lt ~ /^hold[*_ \t]*:/) { n++; print "HOLD\t" n "\t" val(st); next }
|
|
251
|
+
if (lt ~ /^gate[*_ \t]*:/) { if (n > 0) print "GATE\t" n "\t" val(st); else print "ORPHAN"; next }
|
|
252
|
+
}
|
|
253
|
+
' "$1"
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
print_result_line() { # <verdict> <text> <why> <gate text>
|
|
257
|
+
local gsuffix=""
|
|
258
|
+
[ -z "${4:-}" ] || gsuffix=" - checked: $(clean_text "$4")" # mut:done-gates
|
|
259
|
+
case "$1" in
|
|
260
|
+
OK) printf 'Done: %s%s\n' "$(clean_text "$2")" "$gsuffix" ;;
|
|
261
|
+
WAIT) printf 'Still waiting: %s - %s\n' "$(clean_text "$2")" "$3" ;;
|
|
262
|
+
NEEDS) printf 'Needs a person: %s - only a person can settle this\n' "$(clean_text "$2")" ;;
|
|
263
|
+
RESERVED) printf 'Reserved for you: %s - only you can clear this\n' "$(clean_text "$2")" ;;
|
|
264
|
+
*) printf 'Could not check: %s - %s\n' "$(clean_text "$2")" "$3" ;;
|
|
265
|
+
esac
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
# stall_unchecked <sentence> <why>: every hold stays on hold because the record itself cannot be used (exit 2).
|
|
269
|
+
stall_unchecked() {
|
|
270
|
+
local i text
|
|
271
|
+
echo "$1"
|
|
272
|
+
while IFS=$'\t' read -r _ i text; do print_result_line UNEVAL "$text" "$2"; done < <(grep '^HOLD' "$WORK/items")
|
|
273
|
+
echo "holds: $NH discharged: 0 standing: $NH"
|
|
274
|
+
exit 2
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
# stand_all <state> <token> <rc-fits>: the delegation did not verify, so every hold stands (1 when invalid, 2 otherwise).
|
|
278
|
+
stand_all() {
|
|
279
|
+
local i text
|
|
280
|
+
echo "delegation: $1 reason=$2"
|
|
281
|
+
echo "Your standing approval could not be confirmed, so every hold stays on hold."
|
|
282
|
+
while IFS=$'\t' read -r _ i text; do print_result_line WAIT "$text" "waiting for your standing approval"; done < <(grep '^HOLD' "$WORK/items")
|
|
283
|
+
echo "holds: $NH discharged: 0 standing: $NH"
|
|
284
|
+
[ "$1" = invalid ] && [ "$3" = fits ] && exit 1
|
|
285
|
+
exit 2
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
split_file_title() { # --file "<path>#<title>": the title becomes the section; naming it twice is a usage error
|
|
289
|
+
case "$FILE" in
|
|
290
|
+
*'#'*)
|
|
291
|
+
local ht="${FILE#*#}"
|
|
292
|
+
FILE="${FILE%%#*}"
|
|
293
|
+
[ -n "$ht" ] || die2 "the envelope title after # is empty, so no condition can be found"
|
|
294
|
+
[ -z "$SECTION" ] || die2 "the envelope title is named twice (after # and with --section), so no condition can be found"
|
|
295
|
+
SECTION="$ht" ;;
|
|
296
|
+
esac
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
MODE=""; PLAN=""; FILE=""; SECTION=""
|
|
300
|
+
while [ $# -gt 0 ]; do
|
|
301
|
+
case "$1" in
|
|
302
|
+
--plan) [ $# -ge 2 ] || die2 "--plan needs a file"; PLAN="$2"; shift 2 ;;
|
|
303
|
+
--file) [ $# -ge 2 ] || die2 "--file needs a file"; FILE="$2"; shift 2 ;;
|
|
304
|
+
--section) [ $# -ge 2 ] || die2 "--section needs a heading"; SECTION="$2"; shift 2 ;;
|
|
305
|
+
*) die2 "unknown argument: $1" ;;
|
|
306
|
+
esac
|
|
307
|
+
done
|
|
308
|
+
split_file_title # mut:file-title
|
|
309
|
+
if [ -n "$PLAN" ] && [ -z "$FILE" ] && [ -z "$SECTION" ]; then MODE="plan"; SRC="$PLAN"
|
|
310
|
+
elif [ -n "$FILE" ] && [ -n "$SECTION" ] && [ -z "$PLAN" ]; then MODE="file"; SRC="$FILE"
|
|
311
|
+
else die2 "usage: hold-gate-eval.sh --plan <plan.md> | --file <envelope.md> --section <title> | --file <envelope.md>#<title>"; fi
|
|
312
|
+
[ "$MODE" = file ] || { [ -f "$SRC" ] && [ -r "$SRC" ] || die2 "cannot read $SRC, so no hold can be checked"; }
|
|
313
|
+
WORK="$(mktemp -d -t hge.XXXXXXXX)" || die2 "could not create a scratch folder"
|
|
314
|
+
|
|
315
|
+
# read_head_blob <path>: --file mode reads the COMMITTED regular file (as the verifier does), never the working tree.
|
|
316
|
+
read_head_blob() {
|
|
317
|
+
local p="$1" ent
|
|
318
|
+
case "$p" in ""|/*|..|../*|*/..|*/../*|*[*?[]*) die2 "the envelope path is not a plain path inside this repository, so its conditions are treated as not met" ;; esac
|
|
319
|
+
p="${p#./}"
|
|
320
|
+
command -v git >/dev/null 2>&1 || die2 "git is not installed, so no hold can be checked"
|
|
321
|
+
ent="$(GIT_LITERAL_PATHSPECS=1 git ls-tree HEAD -- "./$p" </dev/null 2>/dev/null | head -1)"
|
|
322
|
+
case "$ent" in "100644 blob "*) ;; *) die2 "the envelope file is not saved in the project history as a normal file, so its conditions are treated as not met" ;; esac
|
|
323
|
+
GIT_LITERAL_PATHSPECS=1 git show "HEAD:./$p" > "$WORK/head.md" 2>/dev/null </dev/null || die2 "could not read the saved envelope file, so its conditions are treated as not met"
|
|
324
|
+
}
|
|
325
|
+
if [ "$MODE" = file ]; then read_head_blob "$FILE"; SRC="$WORK/head.md"; fi # mut:file-head
|
|
326
|
+
|
|
327
|
+
need_tools() { # after the no-delegation exit: nothing below can run without these
|
|
328
|
+
command -v jq >/dev/null 2>&1 || die2 "jq is not installed, so no hold can be checked"
|
|
329
|
+
command -v gh >/dev/null 2>&1 || die2 "the GitHub command line tool is not installed, so no hold can be checked"
|
|
330
|
+
command -v git >/dev/null 2>&1 || die2 "git is not installed, so no hold can be checked"
|
|
331
|
+
[ "$HAVE_TO" -eq 1 ] || die2 "no time limit tool (timeout) is available on this machine, so no hold can be checked" # mut:need-timeout
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
split_sections "$SRC" "$MODE" "$SECTION"
|
|
335
|
+
CNT="$(cat "$WORK/sec.count" 2>/dev/null || echo 0)"
|
|
336
|
+
if [ "$MODE" = plan ]; then
|
|
337
|
+
if [ "$CNT" -eq 0 ]; then
|
|
338
|
+
[ "$(marker_count "$SRC")" -gt 0 ] && { echo "I found a hold that is not inside a hold section I can read, so I am treating it as still on hold."; exit 2; } # mut:stray
|
|
339
|
+
echo "No holds are recorded, so there is nothing to wait for."
|
|
340
|
+
echo "holds: 0 discharged: 0 standing: 0"
|
|
341
|
+
exit 0
|
|
342
|
+
fi
|
|
343
|
+
nonblank=0; ND=0; NE=0; NH=0; : > "$WORK/items"
|
|
344
|
+
for ((s = 1; s <= CNT; s++)); do
|
|
345
|
+
awk 'NR > 1 && /[^ \t\r]/ { f = 1 } END { exit (f ? 0 : 1) }' "$WORK/sec.$s" && nonblank=1
|
|
346
|
+
parse_items "$WORK/sec.$s" plan > "$WORK/items.$s"
|
|
347
|
+
cat "$WORK/items.$s" >> "$WORK/items"
|
|
348
|
+
done
|
|
349
|
+
if [ "$nonblank" -eq 0 ]; then
|
|
350
|
+
[ "$(marker_count "$SRC")" -eq 0 ] || { echo "I found a hold that is not inside a hold section I can read, so I am treating it as still on hold."; exit 2; }
|
|
351
|
+
echo "No holds are recorded, so there is nothing to wait for."
|
|
352
|
+
echo "holds: 0 discharged: 0 standing: 0"
|
|
353
|
+
exit 0
|
|
354
|
+
fi
|
|
355
|
+
ND="$(grep -c '^DELEG' "$WORK/items" || true)"; NE="$(grep -c '^ENVF' "$WORK/items" || true)"; NH="$(grep -c '^HOLD' "$WORK/items" || true)"
|
|
356
|
+
[ "$ND" -gt 0 ] || { echo "No standing approval is recorded, so the usual check applies."; [ "$NH" -eq 0 ] || echo "holds: $NH discharged: 0 standing: $NH"; exit 3; } # mut:no-deleg
|
|
357
|
+
PARSED="$(grep -c '^\(HOLD\|GATE\|ORPHAN\)' "$WORK/items" || true)"
|
|
358
|
+
[ "$(marker_count "$SRC")" -eq "$PARSED" ] || { echo "I found a hold that is not inside a hold section I can read, so I am treating every hold as still on hold."; echo "holds: $NH discharged: 0 standing: $NH"; exit 2; } # mut:stray-all
|
|
359
|
+
[ "$ND" -eq 1 ] || stall_unchecked "More than one standing approval is named, so I am treating every hold as still on hold." "the standing approval is not clear" # mut:deleg-multi
|
|
360
|
+
[ "$CNT" -eq 1 ] || stall_unchecked "The plan has more than one hold section, so I am treating every hold as still on hold." "the plan is not clear"
|
|
361
|
+
[ "$NE" -eq 1 ] || stall_unchecked "The standing approval does not name exactly one runbook it covers, so I am treating every hold as still on hold." "the standing approval is incomplete" # mut:envelope-req
|
|
362
|
+
need_tools
|
|
363
|
+
if grep -q '^ORPHAN' "$WORK/items"; then echo "A condition is written outside any hold, so I am treating every hold as still on hold."; echo "holds: $NH discharged: 0 standing: $NH"; exit 2; fi
|
|
364
|
+
[ "$NH" -gt 0 ] || { echo "I found a hold section but could not read any hold in it, so I am treating it as still on hold."; exit 2; } # mut:zero-holds
|
|
365
|
+
DELEG="$(awk -F'\t' '$1 == "DELEG" { print $2; exit }' "$WORK/items")"
|
|
366
|
+
ENVF="$(awk -F'\t' '$1 == "ENVF" { print $2; exit }' "$WORK/items")"
|
|
367
|
+
[ -f "$VERIFY" ] || { echo "I could not find the standing-approval checker, so every hold stays on hold."; echo "holds: $NH discharged: 0 standing: $NH"; exit 2; }
|
|
368
|
+
${TO60[@]+"${TO60[@]}"} bash "$VERIFY" verify --delegation "$DELEG" --envelope "$ENVF" </dev/null > "$WORK/verdict" 2>"$WORK/verdict.err"; VRC=$? # mut:stdin-verify
|
|
369
|
+
VLINE="$(head -1 "$WORK/verdict" 2>/dev/null)"; VSTATE=""; VTOKEN=""
|
|
370
|
+
if [[ "$VLINE" =~ ^delegation:\ (valid|invalid|unverifiable)\ reason=([a-z0-9-]+)$ ]]; then VSTATE="${BASH_REMATCH[1]}"; VTOKEN="${BASH_REMATCH[2]}"; fi
|
|
371
|
+
VOK=0; [ "$VSTATE" = valid ] && [ "$VRC" -eq 0 ] && VOK=1 # mut:deleg-rc
|
|
372
|
+
if [ "$VOK" -eq 1 ]; then
|
|
373
|
+
echo "delegation: valid reason=$VTOKEN"
|
|
374
|
+
else
|
|
375
|
+
[ -n "$VSTATE" ] || { VSTATE=unverifiable; VTOKEN=no-answer; }
|
|
376
|
+
FITS=no; [ "$VSTATE" = invalid ] && [ "$VRC" -eq 1 ] && FITS=fits
|
|
377
|
+
[ "$VSTATE" = valid ] && { VSTATE=unverifiable; VTOKEN=verifier-error; }
|
|
378
|
+
[ "$VSTATE" = invalid ] && [ "$FITS" != fits ] && { VSTATE=unverifiable; VTOKEN=verifier-error; }
|
|
379
|
+
stand_all "$VSTATE" "$VTOKEN" "$FITS" # mut:deleg-valid
|
|
380
|
+
fi
|
|
381
|
+
else
|
|
382
|
+
[ "$CNT" -eq 1 ] || { echo "I could not find exactly one matching envelope section, so I am treating its conditions as not met."; exit 2; }
|
|
383
|
+
need_tools
|
|
384
|
+
parse_items "$WORK/sec.1" "$MODE" > "$WORK/items"
|
|
385
|
+
NH="$(grep -c '^HOLD' "$WORK/items" || true)"
|
|
386
|
+
[ "$(grep -c '^GATE' "$WORK/items" || true)" -ge 1 ] || { echo "The envelope lists no conditions I can check, so I am treating them as not met."; exit 2; }
|
|
387
|
+
fi
|
|
388
|
+
|
|
389
|
+
DISCHARGED=0; STANDING=0; ANY_UNEVAL=0
|
|
390
|
+
while IFS=$'\t' read -r _ i text; do
|
|
391
|
+
lt="$(printf '%s' "$text" | tr 'A-Z' 'a-z')"
|
|
392
|
+
rn="$(printf '%s' "$lt" | tr -cd 'a-z0-9' | cut -c1-16)" # mut:reserved-norm
|
|
393
|
+
case "$rn" in operatorreserved) print_result_line RESERVED "$text" ""; STANDING=$((STANDING + 1)); ANY_UNEVAL=1; continue ;; esac # mut:reserved
|
|
394
|
+
awk -F'\t' -v i="$i" '$1 == "GATE" && $2 == i { print $3 }' "$WORK/items" > "$WORK/g.$i"
|
|
395
|
+
ng="$(wc -l < "$WORK/g.$i" | tr -d ' ')"
|
|
396
|
+
HV=OK; WHY=""; GTXT=""
|
|
397
|
+
[ "$ng" -gt 0 ] || HV=NEEDS # mut:zero-gates
|
|
398
|
+
while IFS= read -r gate; do
|
|
399
|
+
eval_gate "$gate"
|
|
400
|
+
GTXT="${GTXT:+$GTXT; }$gate"
|
|
401
|
+
case "$GRES" in TRUE) ;; FALSE) [ "$HV" = OK ] && { HV=WAIT; WHY="$GWHY"; } ;; *) HV=UNEVAL; WHY="$GWHY"; ANY_UNEVAL=1 ;; esac # mut:all-gates
|
|
402
|
+
done < "$WORK/g.$i"
|
|
403
|
+
print_result_line "$HV" "$text" "$WHY" "$GTXT"
|
|
404
|
+
if [ "$HV" = OK ]; then DISCHARGED=$((DISCHARGED + 1)); else STANDING=$((STANDING + 1)); fi
|
|
405
|
+
done < <(grep '^HOLD' "$WORK/items")
|
|
406
|
+
|
|
407
|
+
echo "holds: $NH discharged: $DISCHARGED standing: $STANDING"
|
|
408
|
+
[ "$ANY_UNEVAL" -eq 0 ] || exit 2
|
|
409
|
+
[ "$STANDING" -eq 0 ] || exit 1
|
|
410
|
+
exit 0
|