@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,22 @@
|
|
|
1
|
+
# Pinned ruff for plugins/soleur/scripts/lint-ratchet.py (installed with pip --require-hashes --only-binary=:all:).
|
|
2
|
+
# Bump recipe: take the version and one sha256 per wheel from https://pypi.org/pypi/ruff/<version>/json,
|
|
3
|
+
# replace the pin and ALL hash lines below, then run: python3 plugins/soleur/scripts/lint-ratchet.py ruff --update
|
|
4
|
+
# (a hash line carries no trailing comment: pip rejects a continuation followed by one).
|
|
5
|
+
ruff==0.16.10 \
|
|
6
|
+
--hash=sha256:1dfc6f0088149fb6a362c1c446bcbb3fd2157b3852fe2fa68409276eab9ad9b3 \
|
|
7
|
+
--hash=sha256:25a65fe998c4e6861ec079ada5826a2fc605e6cbccbe9dcd7fac1f54e791621b \
|
|
8
|
+
--hash=sha256:2a12e01cb9156c10c466f63b46eaae5ecea28dfbd21b5836353ae498e7d1349a \
|
|
9
|
+
--hash=sha256:3031a4a2e8e7b8a46f70be45f198c35a11ece509a94b80334d8d397a33c67550 \
|
|
10
|
+
--hash=sha256:3e70175e29cc94c26ea296c80e470180b744b7419026898e58f520c6ab32578e \
|
|
11
|
+
--hash=sha256:488b0fe3f3574210e5cf80d9f59b9e3ab17a127a8155de3f307b392589cfb511 \
|
|
12
|
+
--hash=sha256:494401c86df4c4c25f69b9419605d944467ee98c42fb6ad405ef4fa40b8fb67d \
|
|
13
|
+
--hash=sha256:6553498afc35f580f036030795810b9e6bcea31604b0fd9e8d352795473042e3 \
|
|
14
|
+
--hash=sha256:7ae7375f803b5520dc9f546bed7e3a0acb70b91812e9bb4b19927de22f25b77d \
|
|
15
|
+
--hash=sha256:92e59a70bcbd9d3a5483656da906ec28edfdacfce00afd99edb8b4e9d15644be \
|
|
16
|
+
--hash=sha256:97f2015c92aa97105b0eab19eb5d224884399281cfc5da86a92db4ab5e7fb2ca \
|
|
17
|
+
--hash=sha256:a3b8471dea115d37f123882be852bed13403746d3a76c11de4a19ec5f9ff5a03 \
|
|
18
|
+
--hash=sha256:bc2610fb269fa56dd8a68669ae470fa6272902668c0fc2ebc3aa112b2633d5b8 \
|
|
19
|
+
--hash=sha256:bd83d1235a5258d318477bc5b576303974cbdef5df0c01a1bff14efcc23bd12a \
|
|
20
|
+
--hash=sha256:d203abc0ff2b773ee33d00ab8df0bb67046fbc7c07b119332f08b9b345cf8221 \
|
|
21
|
+
--hash=sha256:e748ff95c934c4e978783b8e687bc174e7bd84e8ad24e3243e1ecfcda5e0282d \
|
|
22
|
+
--hash=sha256:f33f43a864a8483eebd160e713336c8bab02c934feaff0a33cf5ccb41546d09a
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# run-in-pid-namespace.sh [--] <command> [args...]
|
|
3
|
+
#
|
|
4
|
+
# Runs <command> as PID 1 of a fresh PID namespace (own /proc), via
|
|
5
|
+
# unshare -Urpf --kill-child --mount-proc
|
|
6
|
+
# and REFUSES (rc 125, no unsandboxed fallback) when it cannot arrange that. Use it to run a
|
|
7
|
+
# MUTANT of any helper that signals processes: a helper that walks $PPID upward and signals the
|
|
8
|
+
# outermost ancestor whose argv matches is bounded only by its own match predicate, so a mutant
|
|
9
|
+
# of that predicate (-v, a dropped pattern, a catch-all) walks to the top of the user's session
|
|
10
|
+
# and ends it. Inside the namespace the command has no ancestor at all, so such a walk stops at
|
|
11
|
+
# the command itself. The incident this exists for: see
|
|
12
|
+
# knowledge-base/project/learnings/test-failures/2026-10-09-an-inverted-match-mutant-of-an-ancestor-walking-helper-ended-the-desktop-session-four-times.md
|
|
13
|
+
#
|
|
14
|
+
# Exit codes: the command's own code on success; 125 = refused (the command never started; the
|
|
15
|
+
# FIRST stderr line is "RUN_IN_PID_NAMESPACE_REFUSED reason=<missing-unshare|userns-unavailable|
|
|
16
|
+
# not-isolating> ..."; a wrapped command that itself exits 125 prints no such line, so a caller
|
|
17
|
+
# tells them apart by the marker, not the code); 2 = usage error.
|
|
18
|
+
#
|
|
19
|
+
# Trust anchor: PATH. The probe and the run use one absolute unshare, but sh, awk and the other tools
|
|
20
|
+
# resolve through the caller's PATH, so a caller who controls PATH controls them.
|
|
21
|
+
#
|
|
22
|
+
# What a PID namespace does NOT bound: filesystem writes (the mount namespace is created for
|
|
23
|
+
# /proc only), network, IPC, abstract unix sockets, the D-Bus session bus, path-based sockets under XDG_RUNTIME_DIR (hyprctl,
|
|
24
|
+
# tmux, sway/i3 IPC) and the session manager (loginctl terminate-session still reaches the host). The caller is mapped to uid 0
|
|
25
|
+
# inside, so id -u and root-guard branches differ. The command is PID 1 there, so a signal it
|
|
26
|
+
# sends ITSELF is ignored: bound a run with `timeout -k <grace> <secs> <this script> ...`, never
|
|
27
|
+
# a plain `timeout`. A backgrounded child does not outlive the command (--kill-child).
|
|
28
|
+
set -u
|
|
29
|
+
|
|
30
|
+
readonly MARKER=RUN_IN_PID_NAMESPACE_REFUSED
|
|
31
|
+
|
|
32
|
+
# Shared context-sanitize lib (#10395), beside this script under lib/. When it
|
|
33
|
+
# is unreadable the same-name fallback carries this site's pre-change strip set
|
|
34
|
+
# (C0+DEL) — never weaker than today.
|
|
35
|
+
_ctx_lib="$(cd "${BASH_SOURCE[0]%/*}" 2>/dev/null && pwd -P)/lib/context-sanitize.sh"
|
|
36
|
+
_ctx_lib="${_ctx_lib:-/nonexistent/context-sanitize.sh}"
|
|
37
|
+
# shellcheck source=/dev/null
|
|
38
|
+
[[ -r "$_ctx_lib" ]] && . "$_ctx_lib" || true
|
|
39
|
+
declare -F soleur_ctx_sanitize >/dev/null 2>&1 \
|
|
40
|
+
|| soleur_ctx_sanitize() { LC_ALL=C tr -d '\000-\037\177'; }
|
|
41
|
+
|
|
42
|
+
[[ "${1:-}" == "--" ]] && shift
|
|
43
|
+
if [[ $# -eq 0 ]]; then
|
|
44
|
+
printf 'usage: %s [--] <command> [args...]\n' "${0##*/}" >&2
|
|
45
|
+
exit 2
|
|
46
|
+
fi
|
|
47
|
+
# `exec` reads a leading dash as an option, and `exec --` is not portable (dash, the sh of Debian and
|
|
48
|
+
# Ubuntu, rejects it), so a command word that begins with a dash is refused here, before anything
|
|
49
|
+
# starts. A file whose name begins with a dash runs when given as a path (./-name).
|
|
50
|
+
if [[ "$1" == -* ]]; then
|
|
51
|
+
printf '%s: the command must not begin with "-" (give a path such as ./%s)\n' "${0##*/}" "$1" >&2
|
|
52
|
+
exit 2
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
# The isolation property, written ONCE and used by the probe and by the run: this shell is PID 1
|
|
56
|
+
# and /proc is the namespace's own (NSpid has exactly one field; a wrapper that drops
|
|
57
|
+
# --mount-proc keeps $$ at 1 but shows the host's process list, so $$ alone is not enough).
|
|
58
|
+
# shellcheck disable=SC2016 # the single quotes are intentional: this text runs inside the namespace
|
|
59
|
+
CHECK='[ "$$" = 1 ] && [ "$(awk "/^NSpid:/{print NF-1}" /proc/self/status 2>/dev/null)" = 1 ]'
|
|
60
|
+
|
|
61
|
+
refuse() { # reason cause remedy
|
|
62
|
+
{
|
|
63
|
+
printf '%s reason=%s\n' "$MARKER" "$1"
|
|
64
|
+
printf 'cause: %s\n' "$2"
|
|
65
|
+
printf 'remedy: %s\n' "$3"
|
|
66
|
+
printf 'no unsandboxed fallback: run the mutant on a host that allows user namespaces, or do not run it.\n'
|
|
67
|
+
} >&2
|
|
68
|
+
exit 125
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
# Resolve unshare ONCE to an absolute path: `type -P` consults PATH only, so a shell function or alias
|
|
72
|
+
# named unshare cannot decide the probe, a relative PATH entry is refused, and the probe and the run use
|
|
73
|
+
# the same binary.
|
|
74
|
+
u="$(type -P unshare 2>/dev/null || true)"
|
|
75
|
+
if [[ -z "$u" || "$u" != /* ]]; then
|
|
76
|
+
refuse missing-unshare "unshare (util-linux) was not found on PATH as an absolute path" \
|
|
77
|
+
"use a Linux host with util-linux; stock macOS has no unshare, so use a Linux VM"
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
probe_err="$("$u" -Urpf --kill-child --mount-proc -- sh -c "$CHECK || exit 97" 2>&1 >/dev/null)"
|
|
81
|
+
probe_rc=$?
|
|
82
|
+
if [[ "$probe_rc" -ne 0 ]]; then
|
|
83
|
+
# One line, control characters stripped, cut short: the text comes from whatever unshare is.
|
|
84
|
+
first="$(printf '%s\n' "$probe_err" | head -n 1 | soleur_ctx_sanitize | cut -c1-200)"
|
|
85
|
+
if [[ "$probe_rc" -eq 97 ]]; then
|
|
86
|
+
refuse not-isolating "the unshare on PATH ran the command without a fresh PID namespace and its own /proc (or awk or /proc/self/status was unusable inside it)" \
|
|
87
|
+
"check which unshare resolves first on PATH and that it is util-linux unshare"
|
|
88
|
+
fi
|
|
89
|
+
refuse userns-unavailable "unshare failed (rc $probe_rc): ${first:-no message}" \
|
|
90
|
+
"run the mutant on a disposable VM or container that allows unprivileged user namespaces; enabling them on a workstation (sysctl kernel.unprivileged_userns_clone, kernel.apparmor_restrict_unprivileged_userns, user.max_user_namespaces) or allowing unshare in a container seccomp profile weakens that host, so do it only on a throwaway host. On a restricted CI runner every seat on a signalling helper refuses until the runner relaxes the sysctl"
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
# The same check runs again inside the namespace right before the command (it keeps the property
|
|
94
|
+
# true at the instant of the exec even if the probe and this run disagreed). A plain `exec` (never
|
|
95
|
+
# `exec --`, which dash rejects) leaves the command as PID 1 with no ancestor; a command word that
|
|
96
|
+
# begins with a dash was refused above, so exec cannot read it as an option.
|
|
97
|
+
RUN="$CHECK || { printf '%s\\n' '$MARKER reason=not-isolating (re-check inside the namespace failed)' >&2; exit 125; }; exec \"\$@\""
|
|
98
|
+
exec "$u" -Urpf --kill-child --mount-proc -- sh -c "$RUN" sh "$@"
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Tests for plugins/soleur/scripts/run-in-pid-namespace.sh: the helper that runs a command as PID 1 of
|
|
3
|
+
# a fresh PID namespace and REFUSES (rc 125, marker line, command never started) when it cannot.
|
|
4
|
+
#
|
|
5
|
+
# Two kinds of rows. ALWAYS-RUN rows use a stub `unshare` on a private PATH, so the helper's logic is
|
|
6
|
+
# proven on every host (CI shapes where user namespaces are restricted, macOS). REAL-NAMESPACE rows
|
|
7
|
+
# need working user namespaces; one probe decides, and where they are unavailable they are COUNTED as
|
|
8
|
+
# skipped (a SKIP line names how many and why) and the real helper's refusal is asserted instead (R8).
|
|
9
|
+
# SOLEUR_REQUIRE_REAL_NS=1 turns "unavailable" into a FAIL.
|
|
10
|
+
#
|
|
11
|
+
# The containment row (N4) never runs a lethal walker: it uses a nonce-scoped fixture walker
|
|
12
|
+
# (plugins/soleur/test/fixtures/ancestor-signal/walker-nonce.txt) that signals only ancestors whose
|
|
13
|
+
# argv carries a per-run 32-hex nonce, so even a helper that regressed to run in place could only
|
|
14
|
+
# reach the fixture's own `victim`.
|
|
15
|
+
#
|
|
16
|
+
# Run: bash plugins/soleur/scripts/run-in-pid-namespace.test.sh
|
|
17
|
+
|
|
18
|
+
# shellcheck disable=SC2319 # check() deliberately consumes the status of the condition on the line above
|
|
19
|
+
set -uo pipefail
|
|
20
|
+
export TMPDIR="${TMPDIR:-/var/tmp}"
|
|
21
|
+
unset GIT_DIR GIT_WORK_TREE GIT_INDEX_FILE GIT_COMMON_DIR 2>/dev/null || true
|
|
22
|
+
|
|
23
|
+
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
24
|
+
SUT="$DIR/run-in-pid-namespace.sh"
|
|
25
|
+
WALKER="$DIR/../test/fixtures/ancestor-signal/walker-nonce.txt"
|
|
26
|
+
BASH_BIN="$(type -P bash)"
|
|
27
|
+
|
|
28
|
+
FIX="$(mktemp -d -t runinns.XXXXXXXX)" || { echo "FATAL: mktemp failed" >&2; exit 2; }
|
|
29
|
+
trap 'rm -rf "$FIX"' EXIT
|
|
30
|
+
|
|
31
|
+
# shellcheck source=../test/test-helpers.sh
|
|
32
|
+
source "$DIR/../test/test-helpers.sh" || { echo "FATAL: could not source test-helpers.sh" >&2; exit 2; }
|
|
33
|
+
set +e -uo pipefail
|
|
34
|
+
assert_fixture_dir "$FIX"
|
|
35
|
+
[[ -f "$SUT" ]] || { printf '[FATAL] SUT missing at %s\n' "$SUT" >&2; exit 1; }
|
|
36
|
+
[[ -f "$WALKER" ]] || { printf '[FATAL] walker fixture missing at %s\n' "$WALKER" >&2; exit 1; }
|
|
37
|
+
|
|
38
|
+
passes=0; fails=0; cases=0; skipped=0
|
|
39
|
+
FAILURES=()
|
|
40
|
+
ok() { passes=$((passes + 1)); printf ' ok: %s\n' "$1"; }
|
|
41
|
+
bad() { fails=$((fails + 1)); FAILURES+=("$1"); printf ' FAIL: %s\n' "$1"; }
|
|
42
|
+
check() { # description condition-result(0=true)
|
|
43
|
+
cases=$((cases + 1))
|
|
44
|
+
if [[ "$2" -eq 0 ]]; then ok "$1"; else bad "$1"; fi
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
# Instrument self-test: drive both verdict helpers once, require both counters to move, then unwind.
|
|
48
|
+
_p0=$passes; _f0=$fails; _c0=$cases; _l0=${#FAILURES[@]}
|
|
49
|
+
ok "selftest" >/dev/null; bad "selftest" >/dev/null
|
|
50
|
+
if [[ $passes -ne $((_p0 + 1)) || $fails -ne $((_f0 + 1)) ]]; then
|
|
51
|
+
printf 'FATAL: ok()/bad() do not record verdicts\n' >&2; exit 1
|
|
52
|
+
fi
|
|
53
|
+
passes=$_p0; fails=$_f0; cases=$_c0; FAILURES=()
|
|
54
|
+
|
|
55
|
+
# --- private PATHs ------------------------------------------------------------
|
|
56
|
+
mkdir -p "$FIX/nobin" "$FIX/stub"
|
|
57
|
+
assert_fixture_dir "$FIX"
|
|
58
|
+
for t in bash sh awk tr cut head cat env; do
|
|
59
|
+
src="$(type -P "$t" 2>/dev/null || true)"
|
|
60
|
+
[[ -n "$src" ]] && ln -sf "$src" "$FIX/nobin/$t"
|
|
61
|
+
done
|
|
62
|
+
REAL_UNSHARE="$(type -P unshare 2>/dev/null || true)"
|
|
63
|
+
W="$FIX/witness"
|
|
64
|
+
|
|
65
|
+
# run the helper with a private PATH; sets OUT (stdout+stderr) and RC
|
|
66
|
+
run_helper() { # path-dir cmd...
|
|
67
|
+
local pdir="$1"; shift
|
|
68
|
+
RC=0
|
|
69
|
+
OUT="$(PATH="$pdir" "$BASH_BIN" "$SUT" "$@" 2>&1)" || RC=$?
|
|
70
|
+
}
|
|
71
|
+
first_line() { printf '%s\n' "$1" | head -n 1; }
|
|
72
|
+
witness_cmd=(sh -c ': > "$1"' sh "$W")
|
|
73
|
+
|
|
74
|
+
mkstub() { # name body -- writes $FIX/stub/<name>/unshare
|
|
75
|
+
mkdir -p "$FIX/stub/$1"; assert_fixture_dir "$FIX"
|
|
76
|
+
printf '#!/bin/sh\n%s\n' "$2" > "$FIX/stub/$1/unshare"; chmod +x "$FIX/stub/$1/unshare"
|
|
77
|
+
for t in bash sh awk tr cut head cat env; do ln -sf "$FIX/nobin/$t" "$FIX/stub/$1/$t" 2>/dev/null || true; done
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
echo "=== always-run rows (stub unshare) ==="
|
|
81
|
+
|
|
82
|
+
# R6 witness control: the witness command, run directly, DOES create the witness.
|
|
83
|
+
rm -f "$W"; "${witness_cmd[@]}"
|
|
84
|
+
[[ -e "$W" ]]; check "R6 witness control: the witness command writes its file when it runs" $?
|
|
85
|
+
rm -f "$W"
|
|
86
|
+
|
|
87
|
+
# R1 unshare absent.
|
|
88
|
+
rm -f "$W"; run_helper "$FIX/nobin" "${witness_cmd[@]}"
|
|
89
|
+
[[ "$RC" -eq 125 && "$(first_line "$OUT")" == "RUN_IN_PID_NAMESPACE_REFUSED reason=missing-unshare"* && ! -e "$W" ]]
|
|
90
|
+
check "R1 no unshare on PATH: rc 125, marker reason=missing-unshare, command never started" $?
|
|
91
|
+
|
|
92
|
+
# R2 unshare fails (EPERM): rc 125, the stub's first line quoted on one line.
|
|
93
|
+
mkstub fail 'echo "unshare: unshare failed: Operation not permitted" >&2; exit 1'
|
|
94
|
+
rm -f "$W"; run_helper "$FIX/stub/fail" "${witness_cmd[@]}"
|
|
95
|
+
[[ "$RC" -eq 125 && "$(first_line "$OUT")" == "RUN_IN_PID_NAMESPACE_REFUSED reason=userns-unavailable"* && ! -e "$W" ]]
|
|
96
|
+
check "R2 failing unshare: rc 125, reason=userns-unavailable, command never started" $?
|
|
97
|
+
printf '%s\n' "$OUT" | grep -cF >/dev/null -- "Operation not permitted"
|
|
98
|
+
check "R2b the unshare message is quoted in the refusal" $?
|
|
99
|
+
[[ "$(printf '%s\n' "$OUT" | grep -c '^RUN_IN_PID_NAMESPACE_REFUSED')" -eq 1 ]]
|
|
100
|
+
check "R2c exactly one marker line" $?
|
|
101
|
+
|
|
102
|
+
# R3 dishonest unshare: exits 0 and runs the command in place.
|
|
103
|
+
mkstub dishonest 'while [ "$1" != "--" ]; do shift; done; shift; exec "$@"'
|
|
104
|
+
rm -f "$W"; run_helper "$FIX/stub/dishonest" "${witness_cmd[@]}"
|
|
105
|
+
[[ "$RC" -eq 125 && "$(first_line "$OUT")" == "RUN_IN_PID_NAMESPACE_REFUSED reason=not-isolating"* && ! -e "$W" ]]
|
|
106
|
+
check "R3 dishonest unshare (runs in place): rc 125, reason=not-isolating, command never started" $?
|
|
107
|
+
|
|
108
|
+
# R4 argv: a recording stub (lies on both calls by exiting 0 without running anything).
|
|
109
|
+
mkstub rec 'n=$(cat "'"$FIX"'/calln" 2>/dev/null || echo 0); n=$((n+1)); echo $n > "'"$FIX"'/calln"; printf "%s\n" "$@" > "'"$FIX"'/argv.$n"; exit 0'
|
|
110
|
+
rm -f "$FIX"/calln "$FIX"/argv.*; run_helper "$FIX/stub/rec" -- sh -c 'echo hi' x '' -n "a b"
|
|
111
|
+
[[ "$RC" -eq 0 && -s "$FIX/argv.2" ]]; check "R4 recording stub sees a probe call and a run call" $?
|
|
112
|
+
flags_ok=0
|
|
113
|
+
for f in -U -r -p -f --kill-child --mount-proc; do
|
|
114
|
+
# combined -Urpf is equivalent to the split spellings
|
|
115
|
+
if [[ "$f" == --* ]]; then
|
|
116
|
+
[[ "$(grep -cxF -- "$f" "$FIX/argv.2")" -eq 1 ]] || flags_ok=1
|
|
117
|
+
else
|
|
118
|
+
letter="${f#-}"
|
|
119
|
+
[[ "$(sed -n '1,/^--$/p' "$FIX/argv.2" | grep -E -- '^-[A-Za-z]+$' | grep -c "$letter")" -ge 1 ]] || flags_ok=1
|
|
120
|
+
fi
|
|
121
|
+
done
|
|
122
|
+
check "R4b all of -U -r -p -f --kill-child --mount-proc precede -- in the run call" "$flags_ok"
|
|
123
|
+
mapfile -t AV < "$FIX/argv.2"
|
|
124
|
+
di=-1; for i in "${!AV[@]}"; do [[ "${AV[$i]}" == "--" ]] && { di=$i; break; }; done
|
|
125
|
+
rest=""; if [[ "$di" -ge 0 ]]; then for ((i = di + 5; i < ${#AV[@]}; i++)); do rest+="${AV[$i]}|"; done; fi
|
|
126
|
+
[[ "$di" -ge 0 && "${AV[$((di + 1))]:-}" == "sh" && "${AV[$((di + 2))]:-}" == "-c" && "${AV[$((di + 3))]:-}" == *'; exec "$@"' && "${AV[$((di + 4))]:-}" == "sh" && "$rest" == 'sh|-c|echo hi|x||-n|a b|' ]]
|
|
127
|
+
check "R4c the whole argv after -- is sh -c <RUN ending exec \"\$@\"> sh then the command verbatim (spaces, an empty argument, a leading -n)" $?
|
|
128
|
+
|
|
129
|
+
# R11 a command word that begins with a dash is refused before anything starts (exec would read it as an
|
|
130
|
+
# option, and dash rejects exec --): rc 2, named message, no unshare call, command never started.
|
|
131
|
+
rm -f "$W" "$FIX"/calln "$FIX"/argv.*; run_helper "$FIX/stub/rec" -touch "$W"
|
|
132
|
+
[[ "$RC" -eq 2 && "$OUT" == *'must not begin with "-"'* && ! -e "$W" && ! -e "$FIX/calln" ]]
|
|
133
|
+
check "R11 a command beginning with a dash is refused: rc 2, no unshare call, never started" $?
|
|
134
|
+
|
|
135
|
+
# R5 usage.
|
|
136
|
+
run_helper "$FIX/nobin"
|
|
137
|
+
[[ "$RC" -eq 2 && "$OUT" == usage:* ]]; check "R5 no command: usage, rc 2" $?
|
|
138
|
+
|
|
139
|
+
# R7 the in-namespace re-check: the probe call lies (exit 0), the run call executes in place.
|
|
140
|
+
mkstub lateliar 'n=$(cat "'"$FIX"'/call7" 2>/dev/null || echo 0); n=$((n+1)); echo $n > "'"$FIX"'/call7"
|
|
141
|
+
if [ "$n" -eq 1 ]; then echo probe-isolated >> "'"$FIX"'/log7"; exit 0; fi
|
|
142
|
+
echo run-in-place >> "'"$FIX"'/log7"; while [ "$1" != "--" ]; do shift; done; shift; exec "$@"'
|
|
143
|
+
rm -f "$W" "$FIX"/call7 "$FIX"/log7; run_helper "$FIX/stub/lateliar" "${witness_cmd[@]}"
|
|
144
|
+
[[ "$RC" -eq 125 && "$OUT" == *"RUN_IN_PID_NAMESPACE_REFUSED reason=not-isolating"* && ! -e "$W" ]]
|
|
145
|
+
check "R7 the check inside the namespace refuses when the run is not isolated: rc 125, marker, command never started" $?
|
|
146
|
+
[[ "$(cat "$FIX/log7" 2>/dev/null | tr '\n' ' ')" == "probe-isolated run-in-place " ]]
|
|
147
|
+
check "R7b positive control: the stub took the isolated branch on the probe and the in-place branch on the run" $?
|
|
148
|
+
|
|
149
|
+
# R9 an exported function named unshare must not decide the probe: a failing unshare is on PATH, the function
|
|
150
|
+
# would succeed, and the refusal must come from the PATH binary.
|
|
151
|
+
rm -f "$W"
|
|
152
|
+
RC=0; OUT="$(unshare() { return 0; }; export -f unshare; PATH="$FIX/stub/fail" "$BASH_BIN" "$SUT" "${witness_cmd[@]}" 2>&1)" || RC=$?
|
|
153
|
+
[[ "$RC" -eq 125 && "$OUT" == "RUN_IN_PID_NAMESPACE_REFUSED reason=userns-unavailable"* && ! -e "$W" ]]
|
|
154
|
+
check "R9 an exported shell function unshare does not decide the probe (the PATH binary does)" $?
|
|
155
|
+
|
|
156
|
+
# R10 below: the helper must not refuse where the host itself can create the namespace.
|
|
157
|
+
|
|
158
|
+
# --- probe decides the real-namespace branch ---------------------------------
|
|
159
|
+
REAL_NS=no; REAL_WHY="no unshare on PATH"
|
|
160
|
+
if [[ -n "$REAL_UNSHARE" ]]; then
|
|
161
|
+
PROBE_OUT="$("$BASH_BIN" "$SUT" sh -c 'echo ok' 2>&1)"; PROBE_RC=$?
|
|
162
|
+
if [[ "$PROBE_RC" -eq 0 && "$PROBE_OUT" == "ok" ]]; then REAL_NS=yes
|
|
163
|
+
else REAL_WHY="$(first_line "$PROBE_OUT" | cut -c1-120)"; fi
|
|
164
|
+
fi
|
|
165
|
+
|
|
166
|
+
# An INDEPENDENT host probe (the SUT is not involved): where the host can create the namespace and the helper
|
|
167
|
+
# still refuses, the helper is broken, and that must be a FAIL, never a SKIP.
|
|
168
|
+
HOST_NS=no
|
|
169
|
+
if [[ -n "$REAL_UNSHARE" ]]; then
|
|
170
|
+
HOST_OUT="$("$REAL_UNSHARE" -Urpf --kill-child --mount-proc -- sh -c 'echo ok' 2>&1)"; HOST_RC=$?
|
|
171
|
+
[[ "$HOST_RC" -eq 0 && "$HOST_OUT" == "ok" ]] && HOST_NS=yes
|
|
172
|
+
fi
|
|
173
|
+
[[ "$HOST_NS" != "yes" || "$REAL_NS" == "yes" ]]
|
|
174
|
+
check "R10 the helper does not refuse where the host itself can create the namespace (host=$HOST_NS, helper=$REAL_NS)" $?
|
|
175
|
+
|
|
176
|
+
if [[ "$REAL_NS" == "yes" ]]; then
|
|
177
|
+
echo "=== real-namespace rows ==="
|
|
178
|
+
# N1 PID 1, no parent, own /proc.
|
|
179
|
+
OUT="$("$BASH_BIN" "$SUT" sh -c 'echo "$$ $PPID $(awk "/^NSpid:/{print NF-1}" /proc/self/status)"' 2>&1)"
|
|
180
|
+
[[ "$OUT" == "1 0 1" ]]; check "N1 the command is PID 1 with PPID 0 and its own /proc" $?
|
|
181
|
+
# N2 exit codes pass through; a wrapped 125 carries no marker.
|
|
182
|
+
"$BASH_BIN" "$SUT" sh -c 'exit 0'; r0=$?; "$BASH_BIN" "$SUT" sh -c 'exit 3'; r3=$?
|
|
183
|
+
OUT="$("$BASH_BIN" "$SUT" sh -c 'exit 125' 2>&1)"; r125=$?
|
|
184
|
+
[[ "$r0" -eq 0 && "$r3" -eq 3 ]]; check "N2 exit codes 0 and 3 pass through" $?
|
|
185
|
+
[[ "$r125" -eq 125 && "$OUT" != *RUN_IN_PID_NAMESPACE_REFUSED* ]]; check "N2b a wrapped command's own 125 passes through with no marker" $?
|
|
186
|
+
# N3 stdin, stdout, stderr, cwd; a dash-leading command name.
|
|
187
|
+
mkdir -p "$FIX/cwd"; assert_fixture_dir "$FIX"
|
|
188
|
+
OUT="$(cd "$FIX/cwd" && printf 'in\n' | "$BASH_BIN" "$SUT" sh -c 'read x; echo "out:$x:$(pwd)"; echo err >&2' 2>"$FIX/err3")"
|
|
189
|
+
[[ "$OUT" == "out:in:$FIX/cwd" && "$(cat "$FIX/err3")" == "err" ]]
|
|
190
|
+
check "N3 stdin, stdout, stderr and cwd pass through, nothing added on stderr" $?
|
|
191
|
+
cat > "$FIX/-dashcmd" <<'EOS'
|
|
192
|
+
#!/bin/sh
|
|
193
|
+
echo dash-ran
|
|
194
|
+
EOS
|
|
195
|
+
chmod +x "$FIX/-dashcmd"
|
|
196
|
+
OUT="$(cd "$FIX" && "$BASH_BIN" "$SUT" -- ./-dashcmd 2>&1)"
|
|
197
|
+
[[ "$OUT" == "dash-ran" ]]; check "N3b a command whose file name begins with a dash runs when given as a path (./-name)" $?
|
|
198
|
+
# N4 containment: victim (outside, argv carries the nonce) -> helper -> top (PID 1, nonce) -> mid (nonce) -> walker.
|
|
199
|
+
NONCE="$(od -An -tx1 -N16 /dev/urandom | tr -d ' \n')"
|
|
200
|
+
[[ "$NONCE" =~ ^[0-9a-f]{32}$ ]]; check "N4 precondition: the nonce is 32 hex characters" $?
|
|
201
|
+
assert_fixture_dir "$FIX"
|
|
202
|
+
cat > "$FIX/top.sh" <<'EOS'
|
|
203
|
+
#!/bin/sh
|
|
204
|
+
sh "$FIX_DIR/mid.sh" "mid-$1"
|
|
205
|
+
echo top-done > "$FIX_DIR/top-done"
|
|
206
|
+
EOS
|
|
207
|
+
cat > "$FIX/mid.sh" <<'EOS'
|
|
208
|
+
#!/bin/sh
|
|
209
|
+
echo mid-started > "$FIX_DIR/mid-started"
|
|
210
|
+
sh "$WALKER_PATH"
|
|
211
|
+
echo mid-survived > "$FIX_DIR/mid-survived"
|
|
212
|
+
EOS
|
|
213
|
+
rm -f "$FIX/mid-started" "$FIX/mid-survived" "$FIX/top-done" "$FIX/victim-survived"
|
|
214
|
+
FIX_DIR="$FIX" WALKER_PATH="$WALKER" WALKER_NONCE="$NONCE" SOLEUR_TEST_SUITE_PID=$$ VOUT="$FIX/victim-survived" \
|
|
215
|
+
timeout -k 5 60 "$BASH_BIN" -c '"$@"; echo victim-survived > "$VOUT"' "victim-$NONCE" \
|
|
216
|
+
"$BASH_BIN" "$SUT" sh "$FIX/top.sh" "top-$NONCE" > "$FIX/n4.out" 2>&1
|
|
217
|
+
[[ -e "$FIX/mid-started" && ! -e "$FIX/mid-survived" ]]
|
|
218
|
+
check "N4b positive control: the walker signalled the in-namespace middle process (it started, and died before its next line)" $?
|
|
219
|
+
[[ -e "$FIX/top-done" && -e "$FIX/victim-survived" ]]
|
|
220
|
+
check "N4c containment: PID 1 of the namespace finished and the outside ancestor carrying the nonce survived" $?
|
|
221
|
+
# Fail-closed preconditions of the fixture walker, rehearsed with kill replaced by echo on the host chain.
|
|
222
|
+
for pre in empty-nonce short-nonce nonhex-nonce unset-suite; do
|
|
223
|
+
case "$pre" in
|
|
224
|
+
empty-nonce) n=""; sp=$$ ;;
|
|
225
|
+
short-nonce) n="abc123"; sp=$$ ;;
|
|
226
|
+
nonhex-nonce) n="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"; sp=$$ ;;
|
|
227
|
+
unset-suite) n="$NONCE"; sp="" ;;
|
|
228
|
+
esac
|
|
229
|
+
O="$(WALKER_KILL=echo WALKER_NONCE="$n" SOLEUR_TEST_SUITE_PID="$sp" "$BASH_BIN" -c 'sh "$1"' "carrier-$n" "$WALKER" 2>&1)"
|
|
230
|
+
[[ -z "$O" ]]; check "N4d the fixture walker signals nothing: $pre" $?
|
|
231
|
+
done
|
|
232
|
+
O="$(WALKER_KILL=echo WALKER_NONCE="$NONCE" SOLEUR_TEST_SUITE_PID=$$ "$BASH_BIN" -c 'echo $$ > "$2"; sh "$1"; :' "carrier-$NONCE" "$WALKER" "$FIX/carrier.pid" 2>&1)"
|
|
233
|
+
[[ "$O" == "-TERM $(cat "$FIX/carrier.pid" 2>/dev/null)" ]]
|
|
234
|
+
check "N4e rehearsal with kill replaced by echo targets exactly the nonce-carrying ancestor, nothing above it" $?
|
|
235
|
+
# N5 a backgrounded child is gone after the helper returns; N5b the same after the helper is SIGKILLed.
|
|
236
|
+
has_proc() { # tag -> 0 when some process cmdline carries the tag (the bracket keeps this grep's own argv from matching)
|
|
237
|
+
grep -alqE -- "[${1:0:1}]${1:1}" /proc/[0-9]*/cmdline 2>/dev/null
|
|
238
|
+
}
|
|
239
|
+
T5="bgtag-$NONCE"
|
|
240
|
+
"$BASH_BIN" "$SUT" "$BASH_BIN" -c 'exec -a "$1" sleep 40 & exit 0' sh "$T5" >/dev/null 2>&1
|
|
241
|
+
gone=1; for _ in 1 2 3 4 5 6 7 8 9 10; do has_proc "$T5" || { gone=0; break; }; sleep 0.2; done
|
|
242
|
+
check "N5 a backgrounded child does not outlive the command (the helper returned)" "$gone"
|
|
243
|
+
T5b="bgkill-$NONCE"
|
|
244
|
+
"$BASH_BIN" "$SUT" "$BASH_BIN" -c 'exec -a "$1" sleep 40' sh "$T5b" >/dev/null 2>&1 &
|
|
245
|
+
hp=$!
|
|
246
|
+
up=1; for _ in 1 2 3 4 5 6 7 8 9 10; do has_proc "$T5b" && { up=0; break; }; sleep 0.2; done
|
|
247
|
+
[[ "$up" -eq 0 ]]; check "N5b control: the tagged child is running while the helper runs" $?
|
|
248
|
+
kill -KILL "$hp" 2>/dev/null; wait "$hp" 2>/dev/null
|
|
249
|
+
gone=1; for _ in 1 2 3 4 5 6 7 8 9 10; do has_proc "$T5b" || { gone=0; break; }; sleep 0.2; done
|
|
250
|
+
check "N5c SIGKILL of the helper reaps the tree (--kill-child)" "$gone"
|
|
251
|
+
# N6 nested use.
|
|
252
|
+
OUT="$("$BASH_BIN" "$SUT" "$BASH_BIN" "$SUT" sh -c 'echo "$$ $PPID"' 2>&1)"
|
|
253
|
+
[[ "$OUT" == "1 0" ]]; check "N6 a nested helper call works" $?
|
|
254
|
+
# N7 a wrapper unshare that drops --mount-proc is refused.
|
|
255
|
+
mkdir -p "$FIX/stub/noproc"; assert_fixture_dir "$FIX"
|
|
256
|
+
cat > "$FIX/stub/noproc/unshare" <<EOS
|
|
257
|
+
#!/bin/sh
|
|
258
|
+
for x; do shift; [ "\$x" = "--mount-proc" ] || set -- "\$@" "\$x"; done
|
|
259
|
+
exec $REAL_UNSHARE "\$@"
|
|
260
|
+
EOS
|
|
261
|
+
chmod +x "$FIX/stub/noproc/unshare"
|
|
262
|
+
for t in bash sh awk tr cut head cat env; do ln -sf "$FIX/nobin/$t" "$FIX/stub/noproc/$t" 2>/dev/null || true; done
|
|
263
|
+
rm -f "$W"; run_helper "$FIX/stub/noproc" "${witness_cmd[@]}"
|
|
264
|
+
[[ "$RC" -eq 125 && "$OUT" == *"reason=not-isolating"* && ! -e "$W" ]]
|
|
265
|
+
check "N7 a wrapper that drops --mount-proc is refused (host /proc has two NSpid fields)" $?
|
|
266
|
+
else
|
|
267
|
+
# R8: where namespaces are unavailable the REAL helper must still refuse.
|
|
268
|
+
echo "SKIP real-namespace rows: user namespaces unavailable here ($REAL_WHY)"
|
|
269
|
+
skipped=$((skipped + 18)) # the 18 real-namespace rows: N1 N2 N2b N3 N3b N4 N4b N4c N4d x4 N4e N5 N5b N5c N6 N7
|
|
270
|
+
rm -f "$W"; RC=0; OUT="$("$BASH_BIN" "$SUT" "${witness_cmd[@]}" 2>&1)" || RC=$?
|
|
271
|
+
[[ "$RC" -eq 125 && "$(first_line "$OUT")" == "RUN_IN_PID_NAMESPACE_REFUSED reason="* && ! -e "$W" ]]
|
|
272
|
+
check "R8 the real helper refuses (rc 125, marker, command never started) where namespaces are unavailable" $?
|
|
273
|
+
if [[ "${SOLEUR_REQUIRE_REAL_NS:-}" == "1" ]]; then check "SOLEUR_REQUIRE_REAL_NS=1 but user namespaces are unavailable ($REAL_WHY)" 1; fi
|
|
274
|
+
fi
|
|
275
|
+
|
|
276
|
+
# --- verdict ------------------------------------------------------------------
|
|
277
|
+
echo ""
|
|
278
|
+
printf '=== run-in-pid-namespace: %d passed, %d failed (%d cases, %d skipped, real-namespace=%s) ===\n' "$passes" "$fails" "$cases" "$skipped" "$REAL_NS"
|
|
279
|
+
if [[ "$REAL_NS" != "yes" ]]; then printf 'SKIP: %d real-namespace rows (%s)\n' "$skipped" "$REAL_WHY"; fi
|
|
280
|
+
for f in ${FAILURES[@]+"${FAILURES[@]}"}; do printf ' - %s\n' "$f"; done
|
|
281
|
+
# Anti-vacuity floors: literal thresholds on the line above each test, reported by printf, appended to the ledger the verdict reads.
|
|
282
|
+
if [[ "$cases" -lt 16 ]]; then printf 'FAIL: vacuity floor: only %d cases ran (>= 16 always-run rows expected, R8 counted when namespaces are unavailable)\n' "$cases" >&2; FAILURES+=("always-run floor"); fi
|
|
283
|
+
if [[ "$REAL_NS" == "yes" ]]; then
|
|
284
|
+
if [[ "$cases" -lt 33 ]]; then printf 'FAIL: vacuity floor: only %d cases ran (>= 33 expected with real namespaces)\n' "$cases" >&2; FAILURES+=("real-namespace floor"); fi
|
|
285
|
+
if [[ "$cases" -ne 33 ]]; then printf 'FAIL: conservation: %d cases ran, 33 planned with real namespaces\n' "$cases" >&2; FAILURES+=("planned total"); fi
|
|
286
|
+
else
|
|
287
|
+
if [[ "$((cases + skipped))" -ne 34 ]]; then printf 'FAIL: conservation: %d cases + %d skipped != 34 planned\n' "$cases" "$skipped" >&2; FAILURES+=("planned total"); fi
|
|
288
|
+
fi
|
|
289
|
+
if [[ "$((passes + fails))" -ne "$cases" ]]; then printf 'FAIL: verdict conservation: %d passes + %d fails != %d cases\n' "$passes" "$fails" "$cases" >&2; FAILURES+=("conservation"); fi
|
|
290
|
+
[[ "${#FAILURES[@]}" -eq 0 ]]
|