@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,193 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Emitter coverage for the two-stage `fix-constraints` recovery dispatcher (#5814, ADR-074).
|
|
3
|
+
# Proves constraint-scaffold.sh emits BOTH stage workflows (Stage A = untrusted pull_request
|
|
4
|
+
# producer; Stage B = privileged workflow_run consumer) into the target, refuses to overwrite,
|
|
5
|
+
# fully substitutes __TARGET_DIR__, and that the security-load-bearing structural invariants
|
|
6
|
+
# hold: Stage A is NOT the privileged issue_comment/pull_request_target trigger; Stage B never
|
|
7
|
+
# checks out the untrusted tree / never bun-installs / never git-applies; and Stage A's `name:`
|
|
8
|
+
# is coupled to Stage B's `on: workflow_run: workflows:` filter (a mismatch silently disables
|
|
9
|
+
# recovery). Hermetic: every fixture is a throwaway `git init` repo under a mktemp dir targeted
|
|
10
|
+
# via CONSTRAINT_SCAFFOLD_REPO_ROOT; the real apps/web-platform tree is never touched. No
|
|
11
|
+
# dependency-cruiser needed — the emit (cp/sed) happens BEFORE baseline capture, so a
|
|
12
|
+
# default-mode run writes the workflows and then bails at the origin/main merge-base step.
|
|
13
|
+
#
|
|
14
|
+
# Runs in the scripts shard (scripts/test-all.sh globs
|
|
15
|
+
# plugins/soleur/skills/*/test/*.test.sh). Accumulate-then-exit; command-substitutions that
|
|
16
|
+
# run grep/sed are guarded with `|| true` so `set -e` does not abort before fail() prints.
|
|
17
|
+
set -euo pipefail
|
|
18
|
+
|
|
19
|
+
REPO_ROOT="$(git -C "$(dirname "${BASH_SOURCE[0]}")" rev-parse --show-toplevel)"
|
|
20
|
+
GEN="$REPO_ROOT/plugins/soleur/skills/constraint-scaffold/scripts/constraint-scaffold.sh"
|
|
21
|
+
FIX_A="apps/web-platform/.github/workflows/fix-constraints-stage-a.yml"
|
|
22
|
+
FIX_B="apps/web-platform/.github/workflows/fix-constraints-stage-b.yml"
|
|
23
|
+
|
|
24
|
+
passes=0
|
|
25
|
+
fails=0
|
|
26
|
+
pass() { printf 'ok - %s\n' "$1"; passes=$((passes + 1)); }
|
|
27
|
+
fail() { printf 'FAIL - %s\n' "$1"; fails=$((fails + 1)); }
|
|
28
|
+
|
|
29
|
+
TMPROOT="$(mktemp -d)"
|
|
30
|
+
trap 'rm -rf "$TMPROOT"' EXIT
|
|
31
|
+
# Hermetic git environment for the fixtures (the repo's chokepoint, #7849): a developer
|
|
32
|
+
# commit.gpgsign / signing key / GIT_DIR must not reach the fixture commits or the scaffold under test.
|
|
33
|
+
# shellcheck source=../../../test/lib/git-fixture-env.sh
|
|
34
|
+
source "$REPO_ROOT/plugins/soleur/test/lib/git-fixture-env.sh"
|
|
35
|
+
mkdir -p "$TMPROOT/anchor"
|
|
36
|
+
git_fixture_env "$TMPROOT/anchor" || { echo "FATAL: git_fixture_env refused $TMPROOT/anchor" >&2; exit 1; }
|
|
37
|
+
|
|
38
|
+
# Throwaway git repo with a valid Next.js-shaped app dir, committed clean, origin/main == HEAD, and
|
|
39
|
+
# a fixture-owned stub `depcruise` (baseline -> [], clean err -> rc 0, probe err -> both rules on
|
|
40
|
+
# their edges, rc 1) so a default-mode run COMPLETES. Since #8288 a run that fails anywhere after
|
|
41
|
+
# the first write removes every artifact it emitted, so the workflows can only be observed after a
|
|
42
|
+
# run that reaches exit 0 — the pre-#8288 "assert on the artifacts a failed run left behind" is the
|
|
43
|
+
# residue class that PR closed.
|
|
44
|
+
make_repo() {
|
|
45
|
+
local fx="$TMPROOT/$1"
|
|
46
|
+
mkdir -p "$fx/apps/web-platform/app" "$fx/apps/web-platform/components" "$fx/apps/web-platform/server"
|
|
47
|
+
git -C "$fx" init -q
|
|
48
|
+
git -C "$fx" config user.email "test@example.com"
|
|
49
|
+
git -C "$fx" config user.name "test"
|
|
50
|
+
printf 'node_modules\n' > "$fx/.gitignore"
|
|
51
|
+
printf 'module.exports = {};\n' > "$fx/apps/web-platform/next.config.js"
|
|
52
|
+
printf '{ "dependencies": { "next": "15.0.0" } }\n' > "$fx/apps/web-platform/package.json"
|
|
53
|
+
printf 'export default function Page() { return null; }\n' > "$fx/apps/web-platform/app/page.tsx"
|
|
54
|
+
printf '"use client";\nexport const G = () => "g";\n' > "$fx/apps/web-platform/components/g.tsx"
|
|
55
|
+
printf 'export const APP = "fixture";\n' > "$fx/apps/web-platform/server/config.ts"
|
|
56
|
+
git -C "$fx" add -A
|
|
57
|
+
git -C "$fx" commit -q -m "seed app"
|
|
58
|
+
git -C "$fx" update-ref refs/remotes/origin/main HEAD
|
|
59
|
+
local stub="$TMPROOT/stub-$1"
|
|
60
|
+
mkdir -p "$stub/.bin" "$stub/dependency-cruiser"
|
|
61
|
+
printf '{ "name": "dependency-cruiser", "version": "0.0.0-stub" }\n' > "$stub/dependency-cruiser/package.json"
|
|
62
|
+
cat > "$stub/.bin/depcruise" <<'STUB'
|
|
63
|
+
#!/usr/bin/env bash
|
|
64
|
+
case " $* " in
|
|
65
|
+
*" --output-type json "*) printf '{"modules":[]}\n' ;;
|
|
66
|
+
*" --output-type baseline "*) printf '[]\n' ;;
|
|
67
|
+
*" --output-type err "*)
|
|
68
|
+
if [[ -e components/__constraint_scaffold_bite_probe__/direct.tsx ]]; then
|
|
69
|
+
printf '\n error no-client-to-server-secret-transitive: components/__constraint_scaffold_bite_probe__/via-hop.tsx → server/__constraint_scaffold_bite_probe__.ts\n error no-client-to-server-secret: components/__constraint_scaffold_bite_probe__/direct.tsx → server/__constraint_scaffold_bite_probe__.ts\n\nx 2 dependency violations (2 errors, 0 warnings). 5 modules, 3 dependencies cruised.\n'
|
|
70
|
+
exit 1
|
|
71
|
+
fi
|
|
72
|
+
printf '\n✔ no dependency violations found (1 modules, 0 dependencies cruised)\n\n'; exit 0 ;;
|
|
73
|
+
*) echo "stub depcruise: unhandled argv: $*" >&2; exit 64 ;;
|
|
74
|
+
esac
|
|
75
|
+
STUB
|
|
76
|
+
chmod +x "$stub/.bin/depcruise"
|
|
77
|
+
ln -s "$stub" "$fx/apps/web-platform/node_modules"
|
|
78
|
+
printf '%s' "$fx"
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
# --- Emit: default mode writes BOTH stage workflows -------------------------------------
|
|
82
|
+
FX="$(make_repo emit)"
|
|
83
|
+
set +e
|
|
84
|
+
CONSTRAINT_SCAFFOLD_REPO_ROOT="$FX" TMPDIR="$TMPROOT" bash "$GEN" >"$TMPROOT/emit.out" 2>"$TMPROOT/emit.err"
|
|
85
|
+
EMIT_RC=$?
|
|
86
|
+
set -e
|
|
87
|
+
# The run must COMPLETE (rc 0) for the artifacts to remain; a non-zero rc here is a real failure.
|
|
88
|
+
if [[ "$EMIT_RC" == "0" ]]; then
|
|
89
|
+
pass "emit: default mode completed (rc 0) against the stub toolchain"
|
|
90
|
+
else
|
|
91
|
+
fail "emit: default mode rc=$EMIT_RC (stdout: $(tail -2 "$TMPROOT/emit.out" | tr '\n' ' '))"
|
|
92
|
+
fi
|
|
93
|
+
for pair in "A:$FIX_A" "B:$FIX_B"; do
|
|
94
|
+
stage="${pair%%:*}"; rel="${pair#*:}"
|
|
95
|
+
if [[ -f "$FX/$rel" ]]; then
|
|
96
|
+
pass "emit: Stage $stage ($rel) written to the target"
|
|
97
|
+
else
|
|
98
|
+
fail "emit: Stage $stage ($rel) NOT written (run rc=$EMIT_RC)"
|
|
99
|
+
fi
|
|
100
|
+
done
|
|
101
|
+
|
|
102
|
+
# __TARGET_DIR__ must be fully substituted (no residual placeholder) in both stages.
|
|
103
|
+
for pair in "A:$FIX_A" "B:$FIX_B"; do
|
|
104
|
+
stage="${pair%%:*}"; rel="${pair#*:}"
|
|
105
|
+
if grep -q '__TARGET_DIR__' "$FX/$rel" 2>/dev/null; then
|
|
106
|
+
fail "emit: __TARGET_DIR__ left UNSUBSTITUTED in Stage $stage"
|
|
107
|
+
else
|
|
108
|
+
pass "emit: __TARGET_DIR__ fully substituted in Stage $stage"
|
|
109
|
+
fi
|
|
110
|
+
done
|
|
111
|
+
|
|
112
|
+
# Runner path substituted to the target dir in Stage A (the gate it runs).
|
|
113
|
+
if grep -qF 'bash apps/web-platform/scripts/constraint-gates.sh' "$FX/$FIX_A" 2>/dev/null; then
|
|
114
|
+
pass "emit: Stage A runner path substituted to the target dir (apps/web-platform)"
|
|
115
|
+
else
|
|
116
|
+
fail "emit: substituted runner path not found in Stage A"
|
|
117
|
+
fi
|
|
118
|
+
|
|
119
|
+
# --- Trigger anchors (on syntactic `on:`-block keys, NOT header prose) ---------------
|
|
120
|
+
# Stage A is the UNTRUSTED pull_request producer — never the privileged issue_comment /
|
|
121
|
+
# pull_request_target trigger (the whole point of the redesign). Anchor on 2-space indent.
|
|
122
|
+
if grep -qE '^[[:space:]]{2}pull_request:' "$FX/$FIX_A" 2>/dev/null; then
|
|
123
|
+
pass "trigger: Stage A fires on pull_request (anchored on:-block key)"
|
|
124
|
+
else
|
|
125
|
+
fail "trigger: Stage A missing the pull_request trigger block"
|
|
126
|
+
fi
|
|
127
|
+
if grep -qE '^[[:space:]]{2}(issue_comment|pull_request_target|workflow_run):' "$FX/$FIX_A" 2>/dev/null; then
|
|
128
|
+
fail "trigger: Stage A declares a privileged/consumer trigger (issue_comment/pull_request_target/workflow_run) — must not"
|
|
129
|
+
else
|
|
130
|
+
pass "trigger: Stage A declares no privileged issue_comment/pull_request_target (nor workflow_run) trigger"
|
|
131
|
+
fi
|
|
132
|
+
# Stage B is the PRIVILEGED workflow_run consumer — never an untrusted PR trigger.
|
|
133
|
+
if grep -qE '^[[:space:]]{2}workflow_run:' "$FX/$FIX_B" 2>/dev/null; then
|
|
134
|
+
pass "trigger: Stage B fires on workflow_run (anchored on:-block key)"
|
|
135
|
+
else
|
|
136
|
+
fail "trigger: Stage B missing the workflow_run trigger block"
|
|
137
|
+
fi
|
|
138
|
+
if grep -qE '^[[:space:]]{2}(pull_request|pull_request_target|issue_comment):' "$FX/$FIX_B" 2>/dev/null; then
|
|
139
|
+
fail "trigger: Stage B declares an untrusted PR trigger — must only be workflow_run"
|
|
140
|
+
else
|
|
141
|
+
pass "trigger: Stage B declares no untrusted pull_request/issue_comment trigger"
|
|
142
|
+
fi
|
|
143
|
+
|
|
144
|
+
# --- Forbidden-pattern: Stage B never executes the untrusted tree --------------------
|
|
145
|
+
# Stage B builds the commit via the Git Data API — no checkout of head, no git apply, no
|
|
146
|
+
# bun install, no PR-script execution. The header/shell COMMENTS in Stage B legitimately
|
|
147
|
+
# NAME these constructs ("never git-applies", "never runs bun install"), so strip comment
|
|
148
|
+
# lines (both YAML `#` and shell `#`) before grepping the executable body.
|
|
149
|
+
B_CODE="$(grep -vE '^[[:space:]]*#' "$FX/$FIX_B" || true)"
|
|
150
|
+
# checkout is a `uses:` step — anchor on the action ref (comments have no `uses:`).
|
|
151
|
+
if grep -qE '(^|[[:space:]-])uses:[[:space:]]*actions/checkout' "$FX/$FIX_B" 2>/dev/null; then
|
|
152
|
+
fail "forbidden: Stage B contains an actions/checkout step (must never check out any tree)"
|
|
153
|
+
else
|
|
154
|
+
pass "forbidden: Stage B has no actions/checkout step (Git Data API only)"
|
|
155
|
+
fi
|
|
156
|
+
for tok in 'bun install' 'setup-bun' 'git apply'; do
|
|
157
|
+
if printf '%s\n' "$B_CODE" | grep -cF >/dev/null "$tok" 2>/dev/null; then
|
|
158
|
+
fail "forbidden: Stage B executable body contains '$tok' (must never run it)"
|
|
159
|
+
else
|
|
160
|
+
pass "forbidden: Stage B executable body has no '$tok'"
|
|
161
|
+
fi
|
|
162
|
+
done
|
|
163
|
+
|
|
164
|
+
# --- Name-coupling: Stage A `name:` == Stage B `workflows:` filter string ------------
|
|
165
|
+
# The `workflows:` filter matches a workflow's `name:` field, NOT its filename — a mismatch
|
|
166
|
+
# makes Stage B silently NEVER trigger (no error). Load-bearing (architecture-strategist P1).
|
|
167
|
+
A_NAME="$(grep -E '^name:' "$FX/$FIX_A" 2>/dev/null | head -1 | sed -E 's/^name:[[:space:]]*//' || true)"
|
|
168
|
+
B_WF="$(grep -E '^[[:space:]]+workflows:' "$FX/$FIX_B" 2>/dev/null | head -1 | sed -E 's/.*workflows:[[:space:]]*\[[[:space:]]*"?([^]"]*)"?[[:space:]]*\].*/\1/' || true)"
|
|
169
|
+
if [[ -n "$A_NAME" && "$A_NAME" == "$B_WF" ]]; then
|
|
170
|
+
pass "name-coupling: Stage A name: ('$A_NAME') == Stage B workflows: filter ('$B_WF')"
|
|
171
|
+
else
|
|
172
|
+
fail "name-coupling: Stage A name: ('$A_NAME') != Stage B workflows: filter ('$B_WF') — Stage B would never trigger"
|
|
173
|
+
fi
|
|
174
|
+
|
|
175
|
+
# --- Refuse-if-exists: a pre-existing stage file blocks the emit (exit 66) -----------
|
|
176
|
+
FX2="$(make_repo refuse)"
|
|
177
|
+
: "${FX2:?fixture dir is empty; git -C <empty> would retarget this write}"
|
|
178
|
+
mkdir -p "$(dirname "$FX2/$FIX_A")"
|
|
179
|
+
printf '# already here\n' > "$FX2/$FIX_A"
|
|
180
|
+
git -C "$FX2" add -A && git -C "$FX2" commit -q -m "pre-place fix-constraints-stage-a"
|
|
181
|
+
set +e
|
|
182
|
+
REFUSE_OUT="$(CONSTRAINT_SCAFFOLD_REPO_ROOT="$FX2" bash "$GEN" 2>&1)"
|
|
183
|
+
REFUSE_RC=$?
|
|
184
|
+
set -e
|
|
185
|
+
if [[ "$REFUSE_RC" == "66" ]] && printf '%s' "$REFUSE_OUT" | grep -c >/dev/null 'fix-constraints-stage-a.yml already present'; then
|
|
186
|
+
pass "refuse: pre-existing fix-constraints-stage-a.yml triggers refuse-if-exists (exit 66)"
|
|
187
|
+
else
|
|
188
|
+
fail "refuse: expected exit 66 naming fix-constraints-stage-a.yml, got rc=$REFUSE_RC: $REFUSE_OUT"
|
|
189
|
+
fi
|
|
190
|
+
|
|
191
|
+
echo "---"
|
|
192
|
+
echo "emit-fix-constraints.test.sh: $passes passed, $fails failed"
|
|
193
|
+
[[ "$fails" -eq 0 ]]
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Generator-script coverage for constraint-scaffold.sh (ADR-071). Exercises the
|
|
3
|
+
# script's guard/exit-matrix paths against HERMETIC fixture repos — the real
|
|
4
|
+
# apps/web-platform emitted files are never read or written. Each fixture is a
|
|
5
|
+
# throwaway `git init` repo under a mktemp dir, targeted via the
|
|
6
|
+
# CONSTRAINT_SCAFFOLD_REPO_ROOT override. None of these paths reach baseline
|
|
7
|
+
# capture (they bail at a precondition/guard), so dependency-cruiser is not
|
|
8
|
+
# needed.
|
|
9
|
+
#
|
|
10
|
+
# Covers:
|
|
11
|
+
# exit 65 not-a-Next.js-app detection (no next.config / no anchored "next").
|
|
12
|
+
# exit 66 refuse-if-exists: default mode on an already-emitted tree.
|
|
13
|
+
# exit 67 --refresh-baseline on a dirty working tree refuses.
|
|
14
|
+
#
|
|
15
|
+
# Runs in the scripts shard (scripts/test-all.sh globs
|
|
16
|
+
# plugins/soleur/skills/*/test/*.test.sh). Accumulate-then-exit.
|
|
17
|
+
set -euo pipefail
|
|
18
|
+
|
|
19
|
+
REPO_ROOT="$(git -C "$(dirname "${BASH_SOURCE[0]}")" rev-parse --show-toplevel)"
|
|
20
|
+
GEN="$REPO_ROOT/plugins/soleur/skills/constraint-scaffold/scripts/constraint-scaffold.sh"
|
|
21
|
+
|
|
22
|
+
passes=0
|
|
23
|
+
fails=0
|
|
24
|
+
pass() { printf 'ok - %s\n' "$1"; passes=$((passes + 1)); }
|
|
25
|
+
fail() { printf 'FAIL - %s\n' "$1"; fails=$((fails + 1)); }
|
|
26
|
+
|
|
27
|
+
TMPROOT="$(mktemp -d)"
|
|
28
|
+
trap 'rm -rf "$TMPROOT"' EXIT
|
|
29
|
+
|
|
30
|
+
# Build a throwaway git repo with an apps/web-platform-shaped app dir. $1 = name,
|
|
31
|
+
# $2 = "next" to make it a valid Next.js app (next.config + anchored "next" dep).
|
|
32
|
+
make_repo() {
|
|
33
|
+
local fx="$TMPROOT/$1"
|
|
34
|
+
mkdir -p "$fx/apps/web-platform/app"
|
|
35
|
+
git -C "$fx" init -q
|
|
36
|
+
git -C "$fx" config user.email "test@example.com"
|
|
37
|
+
git -C "$fx" config user.name "test"
|
|
38
|
+
if [[ "${2:-}" == "next" ]]; then
|
|
39
|
+
printf 'module.exports = {};\n' > "$fx/apps/web-platform/next.config.js"
|
|
40
|
+
printf '{ "dependencies": { "next": "15.0.0" } }\n' > "$fx/apps/web-platform/package.json"
|
|
41
|
+
fi
|
|
42
|
+
printf '%s' "$fx"
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
run_gen() {
|
|
46
|
+
# $1 = repo root, rest = args. Captures rc; never aborts the suite.
|
|
47
|
+
local root="$1"; shift
|
|
48
|
+
set +e
|
|
49
|
+
CONSTRAINT_SCAFFOLD_REPO_ROOT="$root" bash "$GEN" "$@" >/dev/null 2>&1
|
|
50
|
+
local rc=$?
|
|
51
|
+
set -e
|
|
52
|
+
printf '%s' "$rc"
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
# --- exit 65: not a Next.js app ----------------------------------------------
|
|
56
|
+
FX="$(make_repo notnext)" # no next.config, no package.json
|
|
57
|
+
RC="$(run_gen "$FX")"
|
|
58
|
+
if [[ "$RC" == "65" ]]; then
|
|
59
|
+
pass "exit 65: not-a-Next.js-app detected (no next.config / anchored \"next\")"
|
|
60
|
+
else
|
|
61
|
+
fail "exit 65 expected for non-Next.js target, got rc=$RC"
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
# --- exit 66: refuse-if-exists (default mode on an already-emitted tree) ------
|
|
65
|
+
FX="$(make_repo emitted next)"
|
|
66
|
+
# Pre-place an emitted artifact (untracked -> the clean-tree guard still passes,
|
|
67
|
+
# since git diff ignores untracked files) so refuse-if-exists fires.
|
|
68
|
+
printf '// already here\n' > "$FX/apps/web-platform/.dependency-cruiser.cjs"
|
|
69
|
+
RC="$(run_gen "$FX")"
|
|
70
|
+
if [[ "$RC" == "66" ]]; then
|
|
71
|
+
pass "exit 66: default mode refuses when an artifact already exists (no --force)"
|
|
72
|
+
else
|
|
73
|
+
fail "exit 66 expected for already-emitted tree, got rc=$RC"
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
# --- exit 67: --refresh-baseline on a dirty tree refuses ----------------------
|
|
77
|
+
FX="$(make_repo dirty next)"
|
|
78
|
+
: "${FX:?fixture dir is empty; git -C <empty> would retarget this write}"
|
|
79
|
+
printf '// gate config\n' > "$FX/apps/web-platform/.dependency-cruiser.cjs"
|
|
80
|
+
git -C "$FX" add apps/web-platform
|
|
81
|
+
git -C "$FX" commit -q -m "seed gate"
|
|
82
|
+
# Dirty a TRACKED file so `git diff --quiet` reports the tree dirty.
|
|
83
|
+
printf '// edited\n' >> "$FX/apps/web-platform/.dependency-cruiser.cjs"
|
|
84
|
+
RC="$(run_gen "$FX" --refresh-baseline)"
|
|
85
|
+
if [[ "$RC" == "67" ]]; then
|
|
86
|
+
pass "exit 67: --refresh-baseline refuses on a dirty working tree"
|
|
87
|
+
else
|
|
88
|
+
fail "exit 67 expected for --refresh-baseline on dirty tree, got rc=$RC"
|
|
89
|
+
fi
|
|
90
|
+
|
|
91
|
+
echo "---"
|
|
92
|
+
echo "generator.test.sh: $passes passed, $fails failed"
|
|
93
|
+
[[ "$fails" -eq 0 ]]
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Template <-> emission parity for the constraint-scaffold L1 gate (ADR-071).
|
|
3
|
+
#
|
|
4
|
+
# The dependency-cruiser config and the shared runner are emitted as
|
|
5
|
+
# BYTE-IDENTICAL copies of the skill's templates; the CI workflow is a single
|
|
6
|
+
# `sed __TARGET_DIR__ -> apps/web-platform` substitution of the workflow
|
|
7
|
+
# template; and the repo-root dogfood gate lives folded as `jobs.constraint-gates` inside
|
|
8
|
+
# `.github/workflows/pr-quality-guards.yml` (#8902) — structurally compared to the template job. ANY edit to a template
|
|
9
|
+
# MUST be mirrored into every emitted copy (and vice-versa), or the gate Soleur
|
|
10
|
+
# ships diverges from the gate Soleur tests. This test fails loud on any drift.
|
|
11
|
+
#
|
|
12
|
+
# Runs in the scripts shard (scripts/test-all.sh globs
|
|
13
|
+
# plugins/soleur/skills/*/test/*.test.sh). Accumulate-then-exit; diff
|
|
14
|
+
# command-substitutions are guarded with `|| true` so `set -e` does not abort
|
|
15
|
+
# before fail() prints.
|
|
16
|
+
set -euo pipefail
|
|
17
|
+
|
|
18
|
+
REPO_ROOT="$(git -C "$(dirname "${BASH_SOURCE[0]}")" rev-parse --show-toplevel)"
|
|
19
|
+
REF="$REPO_ROOT/plugins/soleur/skills/constraint-scaffold/references"
|
|
20
|
+
APP="$REPO_ROOT/apps/web-platform"
|
|
21
|
+
TARGET_DIR="apps/web-platform"
|
|
22
|
+
|
|
23
|
+
passes=0
|
|
24
|
+
fails=0
|
|
25
|
+
# The INDEPENDENT row counter (ADR-193 #2). Incremented at every CALL SITE, never inside
|
|
26
|
+
# pass()/fail() — the VERDICT helpers touch only the verdict counters — so a stubbed fail() drops
|
|
27
|
+
# a verdict without dropping its count and the conservation check below notices. Top level only,
|
|
28
|
+
# never inside a `$( … )`.
|
|
29
|
+
cases=0
|
|
30
|
+
pass() { printf 'ok - %s\n' "$1"; passes=$((passes + 1)); }
|
|
31
|
+
fail() { printf 'FAIL - %s\n' "$1"; fails=$((fails + 1)); }
|
|
32
|
+
# Instrument self-test — DIRECTION, not only presence (a fail() misrouted to `passes` keeps the
|
|
33
|
+
# conservation check and the floor green). Reported via printf >&2 + exit 1, never through the
|
|
34
|
+
# helper it checks (ADR-193).
|
|
35
|
+
fail "instrument self-test (expected — proves fail() records a FAILURE)" >/dev/null
|
|
36
|
+
pass "instrument self-test (expected — proves pass() records a PASS)" >/dev/null
|
|
37
|
+
if [[ "$fails" != "1" || "$passes" != "1" ]]; then
|
|
38
|
+
printf '[FATAL] HELPER CONTROL BROKEN: after one fail() and one pass(), fails=%s passes=%s (want 1/1)\n' "$fails" "$passes" >&2
|
|
39
|
+
exit 1
|
|
40
|
+
fi
|
|
41
|
+
passes=0; fails=0
|
|
42
|
+
|
|
43
|
+
# 1. dependency-cruiser config — byte-identical to the template.
|
|
44
|
+
D="$(diff "$REF/depcruise-config.template" "$APP/.dependency-cruiser.cjs" 2>&1 || true)"
|
|
45
|
+
cases=$((cases + 1))
|
|
46
|
+
if [[ -z "$D" ]]; then
|
|
47
|
+
pass ".dependency-cruiser.cjs is byte-identical to depcruise-config.template"
|
|
48
|
+
else
|
|
49
|
+
fail ".dependency-cruiser.cjs DIVERGES from depcruise-config.template"
|
|
50
|
+
printf '%s\n' "$D" | sed 's/^/ /'
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
# 2. shared runner — byte-identical to the template.
|
|
54
|
+
D="$(diff "$REF/shared-runner.template" "$APP/scripts/constraint-gates.sh" 2>&1 || true)"
|
|
55
|
+
cases=$((cases + 1))
|
|
56
|
+
if [[ -z "$D" ]]; then
|
|
57
|
+
pass "scripts/constraint-gates.sh is byte-identical to shared-runner.template"
|
|
58
|
+
else
|
|
59
|
+
fail "scripts/constraint-gates.sh DIVERGES from shared-runner.template"
|
|
60
|
+
printf '%s\n' "$D" | sed 's/^/ /'
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
# 3. apps/web-platform workflow == sed(__TARGET_DIR__ -> apps/web-platform) of the template.
|
|
64
|
+
SUBST="$(sed "s|__TARGET_DIR__|$TARGET_DIR|g" "$REF/constraint-gates-workflow.template")"
|
|
65
|
+
D="$(printf '%s\n' "$SUBST" | diff - "$APP/.github/workflows/constraint-gates.yml" 2>&1 || true)"
|
|
66
|
+
cases=$((cases + 1))
|
|
67
|
+
if [[ -z "$D" ]]; then
|
|
68
|
+
pass "apps/web-platform workflow == sed(__TARGET_DIR__) of the workflow template"
|
|
69
|
+
else
|
|
70
|
+
fail "apps/web-platform workflow DIVERGES from the substituted template"
|
|
71
|
+
printf '%s\n' "$D" | sed 's/^/ /'
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
# 4. The folded repo-root gate == the template's constraint-gates job. Since
|
|
75
|
+
# #8902 the dogfood instance lives as `jobs.constraint-gates` inside
|
|
76
|
+
# `.github/workflows/pr-quality-guards.yml` (the standalone root file was
|
|
77
|
+
# folded into the shared PR-gates workflow). Structural compare: parse both
|
|
78
|
+
# sides, drop the fold-added `if:` (PR-only gate — the template file has no
|
|
79
|
+
# merge_group so the arm is equivalent), and diff canonical YAML.
|
|
80
|
+
strip_body() { grep -vE '^[[:space:]]*#' | grep -vE '^[[:space:]]*$' || true; }
|
|
81
|
+
D="$(python3 - "$SUBST" "$REPO_ROOT/.github/workflows/pr-quality-guards.yml" <<'PY' 2>&1 || true
|
|
82
|
+
import sys, yaml
|
|
83
|
+
tmpl = yaml.safe_load(sys.argv[1])["jobs"]["constraint-gates"]
|
|
84
|
+
root = yaml.safe_load(open(sys.argv[2]))["jobs"]["constraint-gates"]
|
|
85
|
+
root.pop("if", None) # fold-added: host file merges merge_group; job is PR-only
|
|
86
|
+
a = yaml.safe_dump(tmpl, sort_keys=True)
|
|
87
|
+
b = yaml.safe_dump(root, sort_keys=True)
|
|
88
|
+
if a != b:
|
|
89
|
+
import difflib
|
|
90
|
+
print("\n".join(difflib.unified_diff(a.splitlines(), b.splitlines(),
|
|
91
|
+
"template.jobs.constraint-gates", "pr-quality-guards.jobs.constraint-gates",
|
|
92
|
+
lineterm="")))
|
|
93
|
+
PY
|
|
94
|
+
)"
|
|
95
|
+
cases=$((cases + 1))
|
|
96
|
+
if [[ -z "$D" ]]; then
|
|
97
|
+
pass "jobs.constraint-gates in pr-quality-guards.yml == substituted template job"
|
|
98
|
+
else
|
|
99
|
+
fail "jobs.constraint-gates in pr-quality-guards.yml DIVERGES from template job"
|
|
100
|
+
printf '%s\n' "$D" | sed 's/^/ /'
|
|
101
|
+
fi
|
|
102
|
+
|
|
103
|
+
# 5. repo-root dogfood Stage B == sed(__TARGET_DIR__) of the Stage B template (comment-stripped
|
|
104
|
+
# body). Stage B is the PRIVILEGED, write-capable recovery consumer and carries the entire
|
|
105
|
+
# fork-defense (isCrossRepository gate, path allowlist, sha256 round-trip, mandatory
|
|
106
|
+
# base_tree); it has NO intentional dogfood divergence, so its body must match the tenant
|
|
107
|
+
# template exactly. Guards the silent-drift class the emit test — which only inspects emitted
|
|
108
|
+
# tenant fixtures, never the committed repo-root dogfood — structurally cannot catch (#5814).
|
|
109
|
+
B_ROOT="$REPO_ROOT/.github/workflows/fix-constraints-stage-b.yml"
|
|
110
|
+
STAGE_B_SUBST="$(sed "s|__TARGET_DIR__|$TARGET_DIR|g" "$REF/fix-constraints-stage-b.template")"
|
|
111
|
+
ROOT_B_BODY="$(strip_body < "$B_ROOT")"
|
|
112
|
+
TMPL_B_BODY="$(printf '%s\n' "$STAGE_B_SUBST" | strip_body)"
|
|
113
|
+
D="$(diff <(printf '%s\n' "$ROOT_B_BODY") <(printf '%s\n' "$TMPL_B_BODY") 2>&1 || true)"
|
|
114
|
+
cases=$((cases + 1))
|
|
115
|
+
if [[ -z "$D" ]]; then
|
|
116
|
+
pass "repo-root fix-constraints-stage-b body == substituted Stage B template body"
|
|
117
|
+
else
|
|
118
|
+
fail "repo-root fix-constraints-stage-b DIVERGES from the substituted template body"
|
|
119
|
+
printf '%s\n' "$D" | sed 's/^/ /'
|
|
120
|
+
fi
|
|
121
|
+
|
|
122
|
+
# 6. Dogfood security invariants on the two repo-root recovery workflows. Stage A intentionally
|
|
123
|
+
# diverges from its template (dogfood-only api-spend steps + a richer anthropic-preflight
|
|
124
|
+
# composite), so it gets invariant assertions rather than a body diff.
|
|
125
|
+
A_ROOT="$REPO_ROOT/.github/workflows/fix-constraints-stage-a.yml"
|
|
126
|
+
|
|
127
|
+
# 6a. Name-coupling: Stage A `name:` == Stage B `workflows:` filter (workflow_run matches by the
|
|
128
|
+
# workflow's name, NOT its filename — a drift makes Stage B silently never trigger).
|
|
129
|
+
A_NAME="$(grep -E '^name:' "$A_ROOT" | head -1 | sed -E 's/^name:[[:space:]]*//' || true)"
|
|
130
|
+
B_WF="$(grep -E '^[[:space:]]+workflows:' "$B_ROOT" | head -1 | sed -E 's/.*workflows:[[:space:]]*\[[[:space:]]*"?([^]"]*)"?[[:space:]]*\].*/\1/' || true)"
|
|
131
|
+
cases=$((cases + 1))
|
|
132
|
+
if [[ -n "$A_NAME" && "$A_NAME" == "$B_WF" ]]; then
|
|
133
|
+
pass "dogfood name-coupling: Stage A name: ('$A_NAME') == Stage B workflows: filter"
|
|
134
|
+
else
|
|
135
|
+
fail "dogfood name-coupling BROKEN: Stage A name: ('$A_NAME') != Stage B workflows: ('$B_WF') — Stage B would never trigger"
|
|
136
|
+
fi
|
|
137
|
+
|
|
138
|
+
# 6a'. The same coupling on the TEMPLATES a founder repo receives: template A `name:` == template B
|
|
139
|
+
# `workflows:` filter (the dogfood pair above can hold while the emitted pair drifts).
|
|
140
|
+
TA_NAME="$(grep -E '^name:' "$REF/fix-constraints-stage-a.template" | head -1 | sed -E 's/^name:[[:space:]]*//' || true)"
|
|
141
|
+
TB_WF="$(grep -E '^[[:space:]]+workflows:' "$REF/fix-constraints-stage-b.template" | head -1 | sed -E 's/.*workflows:[[:space:]]*\[[[:space:]]*"?([^]"]*)"?[[:space:]]*\].*/\1/' || true)"
|
|
142
|
+
cases=$((cases + 1))
|
|
143
|
+
if [[ -n "$TA_NAME" && "$TA_NAME" == "$TB_WF" ]]; then
|
|
144
|
+
pass "template name-coupling: Stage A template name: ('$TA_NAME') == Stage B template workflows: filter"
|
|
145
|
+
else
|
|
146
|
+
fail "template name-coupling BROKEN: Stage A template name: ('$TA_NAME') != Stage B template workflows: ('$TB_WF')"
|
|
147
|
+
fi
|
|
148
|
+
|
|
149
|
+
# 6b. Stage B (privileged) executes no untrusted tree: no checkout-of-head / bun install /
|
|
150
|
+
# git apply in its executable body (full-line comments stripped so the header's prose that
|
|
151
|
+
# NAMES these constructs cannot false-match).
|
|
152
|
+
B_CODE="$(grep -vE '^[[:space:]]*#' "$B_ROOT" || true)"
|
|
153
|
+
bfail=0
|
|
154
|
+
if grep -qE '(^|[[:space:]-])uses:[[:space:]]*actions/checkout' "$B_ROOT"; then bfail=1; fi
|
|
155
|
+
for tok in 'bun install' 'setup-bun' 'git apply'; do
|
|
156
|
+
if printf '%s\n' "$B_CODE" | grep -cF >/dev/null "$tok"; then bfail=1; fi
|
|
157
|
+
done
|
|
158
|
+
cases=$((cases + 1))
|
|
159
|
+
if [[ "$bfail" -eq 0 ]]; then
|
|
160
|
+
pass "dogfood Stage B executes no untrusted tree (no checkout/bun-install/git-apply)"
|
|
161
|
+
else
|
|
162
|
+
fail "dogfood Stage B contains a forbidden execution construct (checkout/bun-install/git-apply)"
|
|
163
|
+
fi
|
|
164
|
+
|
|
165
|
+
# 6c. Stage A (untrusted producer) is read-only: declares contents: read, never contents: write.
|
|
166
|
+
cases=$((cases + 1))
|
|
167
|
+
if grep -qE '^[[:space:]]*contents:[[:space:]]*read' "$A_ROOT" && ! grep -qE '^[[:space:]]*contents:[[:space:]]*write' "$A_ROOT"; then
|
|
168
|
+
pass "dogfood Stage A is read-only (contents: read, no contents: write)"
|
|
169
|
+
else
|
|
170
|
+
fail "dogfood Stage A permission drift: expected contents: read only, found a write scope"
|
|
171
|
+
fi
|
|
172
|
+
|
|
173
|
+
# 7. Dogfood README block == the EMITTER's transform of boundary-readme.template (first-line
|
|
174
|
+
# attribution stripped, __TARGET_DIR__ substituted). `-s` FIRST: a `diff` of two empty
|
|
175
|
+
# operands passes, which is the parity vacuity that matters. The strip expression is pinned by
|
|
176
|
+
# `grep -cF` against the script's `content="$(sed …` ASSIGNMENT (a stale comment quoting the
|
|
177
|
+
# expression cannot stand in for the live one) so the two copies of the one transform cannot
|
|
178
|
+
# diverge silently. The comparison normalises trailing newlines exactly as the emitter does
|
|
179
|
+
# (`content="$(…)"` then `printf '%s\n'`), so a template ending in 0 or 2 newlines compares
|
|
180
|
+
# against what the emitter actually writes.
|
|
181
|
+
README_TMPL="$REF/boundary-readme.template"
|
|
182
|
+
README_DOG="$APP/server/README.md"
|
|
183
|
+
STRIP_EXPR="sed -e '1{/^<!-- Inspired by /d;}' -e \"s|__TARGET_DIR__|\$TARGET_REL|g\""
|
|
184
|
+
GEN_SCRIPT="$REPO_ROOT/plugins/soleur/skills/constraint-scaffold/scripts/constraint-scaffold.sh"
|
|
185
|
+
STRIP_PIN="$(grep -E '^\s*content="\$\(sed ' "$GEN_SCRIPT" 2>/dev/null | grep -cF -- "$STRIP_EXPR" || true)"
|
|
186
|
+
D=""
|
|
187
|
+
if [[ ! -s "$README_TMPL" ]]; then
|
|
188
|
+
D="template $README_TMPL is missing or empty"
|
|
189
|
+
elif [[ ! -s "$README_DOG" ]]; then
|
|
190
|
+
D="dogfood $README_DOG is missing or empty"
|
|
191
|
+
elif [[ "$STRIP_PIN" != "1" ]]; then
|
|
192
|
+
D="strip expression pin: the script contains the literal emitter expression $STRIP_PIN time(s), expected exactly 1"
|
|
193
|
+
elif ! head -1 "$README_TMPL" | grep -c >/dev/null '^<!-- Inspired by '; then
|
|
194
|
+
D="template line 1 is not the attribution comment (the emitter strips exactly that line)"
|
|
195
|
+
else
|
|
196
|
+
EXPECTED_README="$(sed -e '1{/^<!-- Inspired by /d;}' -e "s|__TARGET_DIR__|$TARGET_DIR|g" "$README_TMPL")"
|
|
197
|
+
D="$(printf '%s\n' "$EXPECTED_README" | diff - "$README_DOG" 2>&1 || true)"
|
|
198
|
+
fi
|
|
199
|
+
cases=$((cases + 1))
|
|
200
|
+
if [[ -z "$D" ]]; then
|
|
201
|
+
pass "apps/web-platform/server/README.md == emitter transform of boundary-readme.template (non-empty; strip expression pinned)"
|
|
202
|
+
else
|
|
203
|
+
fail "apps/web-platform/server/README.md DIVERGES from the template transform"
|
|
204
|
+
printf '%s\n' "$D" | sed 's/^/ /'
|
|
205
|
+
fi
|
|
206
|
+
|
|
207
|
+
# 8. Repo-root CLAUDE.md carries the pointer marker EXACTLY once, on a line naming the dogfood
|
|
208
|
+
# README path, with no `@apps/` import form (an `@path` line is a Claude Code import and would
|
|
209
|
+
# load the README into every session). Four selections for a four-dimension claim.
|
|
210
|
+
CLAUDE_MD="$REPO_ROOT/CLAUDE.md"
|
|
211
|
+
POINTER_MARKER='<!-- constraint-scaffold:pointer -->'
|
|
212
|
+
PTR_CT="$(grep -c -- "$POINTER_MARKER" "$CLAUDE_MD" 2>/dev/null || true)"
|
|
213
|
+
PTR_LINE="$(grep -- "$POINTER_MARKER" "$CLAUDE_MD" 2>/dev/null | head -1 || true)"
|
|
214
|
+
D=""
|
|
215
|
+
if [[ ! -s "$CLAUDE_MD" ]]; then
|
|
216
|
+
D="CLAUDE.md is missing or empty"
|
|
217
|
+
elif [[ "$PTR_CT" != "1" ]]; then
|
|
218
|
+
D="pointer marker appears $PTR_CT time(s), expected exactly 1"
|
|
219
|
+
elif [[ "$PTR_LINE" != *"apps/web-platform/server/README.md"* ]]; then
|
|
220
|
+
D="pointer line does not name apps/web-platform/server/README.md: '$PTR_LINE'"
|
|
221
|
+
elif [[ "$PTR_LINE" == *"@apps/"* ]]; then
|
|
222
|
+
D="pointer line uses the forbidden @apps/ import form: '$PTR_LINE'"
|
|
223
|
+
fi
|
|
224
|
+
cases=$((cases + 1))
|
|
225
|
+
if [[ -z "$D" ]]; then
|
|
226
|
+
pass "CLAUDE.md carries the constraint-scaffold pointer once, naming the README path, without @apps/"
|
|
227
|
+
else
|
|
228
|
+
fail "CLAUDE.md pointer: $D"
|
|
229
|
+
fi
|
|
230
|
+
|
|
231
|
+
# 9. Emission census: every `cp`/`sed` of a `$REF_DIR/*.template` in the script's default-mode
|
|
232
|
+
# emit block has a parity row above (rows 1–5 read one template each; the README template is
|
|
233
|
+
# row 7). A sixth emitted template with no dogfood row would otherwise red nothing here.
|
|
234
|
+
EMITTED_TEMPLATES="$(grep -oE '"\$REF_DIR/[a-z-]+\.template"' "$GEN_SCRIPT" 2>/dev/null | sort -u | grep -c . || true)"
|
|
235
|
+
ROW_TEMPLATES="$(grep -oE '"\$REF/[a-z-]+\.template"' "${BASH_SOURCE[0]}" | sort -u | grep -c . || true)"
|
|
236
|
+
cases=$((cases + 1))
|
|
237
|
+
if [[ "$EMITTED_TEMPLATES" -ge 6 && "$EMITTED_TEMPLATES" == "$ROW_TEMPLATES" ]]; then
|
|
238
|
+
pass "emission census: the script reads $EMITTED_TEMPLATES distinct templates and this suite has a row for each"
|
|
239
|
+
else
|
|
240
|
+
fail "emission census: script reads $EMITTED_TEMPLATES distinct templates, this suite reads $ROW_TEMPLATES (want equal, >= 6)"
|
|
241
|
+
fi
|
|
242
|
+
|
|
243
|
+
echo "---"
|
|
244
|
+
|
|
245
|
+
# --- Accounting conservation (ADR-193 #3) --------------------------------------------------
|
|
246
|
+
# Ordered BEFORE the floor (ADR-193 #4): a neutered fail()/pass() deflates the verdict counters, so
|
|
247
|
+
# the floor below would ALSO trip and would report the misleading "arms were deleted". This says
|
|
248
|
+
# "a verdict was discarded" instead. Reported with `printf >&2` + `exit 1` DIRECTLY, never
|
|
249
|
+
# through fail(): a check that reports by calling the verdict helper increments the very counter
|
|
250
|
+
# the exit status reads, so neutering fail() silences the rows AND the check meant to notice the
|
|
251
|
+
# silence. Every row records exactly one verdict, so passes+fails MUST equal cases; because
|
|
252
|
+
# `cases` moves at the CALL SITE and not inside the verdict helpers, the identity is a real
|
|
253
|
+
# constraint rather than a tautology. The literal `[FATAL] accounting` is load-bearing —
|
|
254
|
+
# guard-vacuity-floor's ARM 10 builds its conservation population by grepping that exact string.
|
|
255
|
+
if [[ $((passes + fails)) -ne "$cases" ]]; then
|
|
256
|
+
printf '\n[FATAL] accounting: passes+fails (%d) != cases (%d).\n' "$((passes + fails))" "$cases" >&2
|
|
257
|
+
if [[ $((passes + fails)) -lt "$cases" ]]; then
|
|
258
|
+
printf ' A row was counted but its verdict was not recorded — that is what a neutered pass()/fail() looks like.\n' >&2
|
|
259
|
+
else
|
|
260
|
+
printf ' A verdict was recorded at a call site with no `cases=$((cases + 1))` before it. This is a harness bug, not a product failure: add the increment at that call site.\n' >&2
|
|
261
|
+
fi
|
|
262
|
+
echo "parity.test.sh: $passes passed, $fails failed ($cases rows)"
|
|
263
|
+
exit 1
|
|
264
|
+
fi
|
|
265
|
+
|
|
266
|
+
# --- Anti-vacuity floor (ADR-193 #1) -------------------------------------------------------
|
|
267
|
+
# Reads the INDEPENDENT `cases` counter, and reports with `printf >&2` + `exit 1` DIRECTLY.
|
|
268
|
+
# This suite previously carried NO suite-level floor at all: a harness that silently asserted
|
|
269
|
+
# nothing printed a clean smaller total and exited 0. MIN_ROWS is derived at commit time by
|
|
270
|
+
# counting the `cases=$((cases + 1))` call sites in this file: 8 pre-existing verdict sites (rows
|
|
271
|
+
# 1, 2, 3, 4, 5, 6a, 6b, 6c) + rows 7–8 = 10. The literal sits on the line directly above the `if`
|
|
272
|
+
# because guard-vacuity-floor's backward slice carries only contiguous simple assignments into
|
|
273
|
+
# its neutered-machinery mutant; bound anywhere else, the mutant dies unbound and the floor
|
|
274
|
+
# scores CONSTRUCTION instead of FIRES.
|
|
275
|
+
MIN_ROWS=12
|
|
276
|
+
if [[ "$cases" -lt "$MIN_ROWS" ]]; then
|
|
277
|
+
printf '\n[FATAL] anti-vacuity floor: only %d row(s) ran, expected >= %d.\n' \
|
|
278
|
+
"$cases" "$MIN_ROWS" >&2
|
|
279
|
+
printf ' Rows were deleted or skipped; a green run here would be a coverage loss.\n' >&2
|
|
280
|
+
echo "parity.test.sh: $passes passed, $fails failed ($cases rows)"
|
|
281
|
+
exit 1
|
|
282
|
+
fi
|
|
283
|
+
|
|
284
|
+
echo "parity.test.sh: $passes passed, $fails failed ($cases rows)"
|
|
285
|
+
[[ "$fails" -eq 0 ]]
|