@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,607 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# parse-override.test.sh — required-field presence check in
|
|
3
|
+
# skill-security-scan/scripts/parse-override.sh (#10167).
|
|
4
|
+
#
|
|
5
|
+
# WHAT THIS GUARDS. Every required frontmatter key is gated on a presence
|
|
6
|
+
# check. Before #10167 that check was `grep -qE "^${f}:[[:space:]]"` — any
|
|
7
|
+
# whitespace (even alone) after the colon, same line — which false-rejects the
|
|
8
|
+
# schema-permitted
|
|
9
|
+
# block-mapping spelling of findings_json (`findings_json:` + indented keys;
|
|
10
|
+
# override-artifact-schema.json admits oneOf string|object, and
|
|
11
|
+
# override-mechanism.md documents the inline-object form for artifacts that
|
|
12
|
+
# must outlive the .scan-meta.json retention window). The rejected artifact
|
|
13
|
+
# surfaces as `missing fields: findings_json` → invalid_schema → the
|
|
14
|
+
# PreToolUse hook denies the Write and the pr-quality-guards CI job reddens.
|
|
15
|
+
#
|
|
16
|
+
# THE RULING (decision-challenges.md `#10167` ruling row, CTO). A required
|
|
17
|
+
# field counts PRESENT iff a `^f:` top-level key line exists AND either (a)
|
|
18
|
+
# non-whitespace non-null content follows the colon on the same line, or (b) a
|
|
19
|
+
# following INDENTED (whitespace-led) line carries content before the block
|
|
20
|
+
# ends — where "the block ends" is the next recognized key OR any other
|
|
21
|
+
# column-0 content line. Comments and blank lines are neutral — they neither
|
|
22
|
+
# satisfy presence nor close the block. Rejects: `f:` bare, `f: `
|
|
23
|
+
# (whitespace-only — the dissent), `f: null`/`~` (YAML null), `f:value` (no
|
|
24
|
+
# separation space — YAML reads a plain scalar, not a mapping).
|
|
25
|
+
#
|
|
26
|
+
# THE FIXTURE. Each arm builds a scratch repo under $SUITE_TMP: `git init`, one
|
|
27
|
+
# empty base commit on ref `base`, then the synthesized override artifact(s)
|
|
28
|
+
# committed on top, so `git diff base...HEAD --diff-filter=A` enumerates them —
|
|
29
|
+
# the same door the PreToolUse hook and the two CI jobs walk through.
|
|
30
|
+
# parse-override.sh is run with cwd = the fixture repo (it diffs in $PWD and
|
|
31
|
+
# reads artifacts from the working tree). Fixtures are synthesized
|
|
32
|
+
# (cq-test-fixtures-synthesized-only); rule_pack_sha256 is seeded from the real
|
|
33
|
+
# manifest's sha256sum at runtime so the freshness arm never enters the
|
|
34
|
+
# assertion path.
|
|
35
|
+
#
|
|
36
|
+
# ANTI-VACUITY. Every reject arm pairs a compliant `ok-skill` artifact in the
|
|
37
|
+
# SAME fixture repo and asserts it lands in `matched`: a run that enumerates
|
|
38
|
+
# zero artifacts (a broken --diff-filter=A enumeration) fails the positive
|
|
39
|
+
# control instead of passing vacuously (Guard 1 mutation row 6). Every arm
|
|
40
|
+
# also asserts on the RESULT JSON naming the specific artifact path, never on
|
|
41
|
+
# the exit code alone.
|
|
42
|
+
|
|
43
|
+
set -uo pipefail
|
|
44
|
+
|
|
45
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
46
|
+
PARSE="$SCRIPT_DIR/../scripts/parse-override.sh"
|
|
47
|
+
MANIFEST="$SCRIPT_DIR/../references/rules/manifest.yaml"
|
|
48
|
+
|
|
49
|
+
# Session scratch root (#7004, ADR-250): adopt the owned `soleur-run.<pid>.*`
|
|
50
|
+
# root so a SIGKILL's residue is attributable to this suite — the same pattern
|
|
51
|
+
# this PR ships for cloud-init-inngest-bootstrap.test.sh (eat your own
|
|
52
|
+
# cooking). Load-bearing, not opportunistic: a missing lib means the path
|
|
53
|
+
# rotted (exit 2) — a silently-degrading [[ -f ]] guard is exactly how a
|
|
54
|
+
# wrong-depth path shipped dead in the first fix round. An environmental
|
|
55
|
+
# begin failure still degrades via `|| true` (never block the suite).
|
|
56
|
+
_SCRATCH_LIB="$SCRIPT_DIR/../../../../../scripts/lib/scratch-root.sh"
|
|
57
|
+
[[ -f "$_SCRATCH_LIB" ]] || { echo "FATAL: scratch-root.sh not found at $_SCRATCH_LIB" >&2; exit 2; }
|
|
58
|
+
# shellcheck source=../../../../../scripts/lib/scratch-root.sh
|
|
59
|
+
source "$_SCRATCH_LIB"
|
|
60
|
+
declare -F soleur_scratch_session_begin >/dev/null 2>&1 || { echo "FATAL: scratch-root.sh sourced but begin missing" >&2; exit 2; }
|
|
61
|
+
declare -F _soleur_scratch_cleanup >/dev/null 2>&1 || { echo "FATAL: scratch-root.sh sourced but cleanup missing" >&2; exit 2; }
|
|
62
|
+
# No arg: derived base normalizes a PrivateTmp-style TMPDIR up to /tmp where
|
|
63
|
+
# the reapers can enumerate (no private measured-base contract here).
|
|
64
|
+
soleur_scratch_session_begin || true
|
|
65
|
+
|
|
66
|
+
# Scratch root with its owning trap installed before ANY source or further
|
|
67
|
+
# allocation — the trap is this file's only cleanup owner (ADR-129). Under a
|
|
68
|
+
# bound session, SUITE_TMP already lands inside the owned root; the splice
|
|
69
|
+
# reclaims the (empty) root itself on clean exit.
|
|
70
|
+
SUITE_TMP="$(mktemp -d -t parse-override.XXXXXXXX)"
|
|
71
|
+
trap 'rm -rf "$SUITE_TMP"; _soleur_scratch_cleanup || true' EXIT
|
|
72
|
+
|
|
73
|
+
# The shared fixture git environment — sweeps inherited GIT_* location vars,
|
|
74
|
+
# pins a discovery ceiling, config hermeticity, and a synthesized identity.
|
|
75
|
+
# Sourced AFTER the EXIT trap above on purpose: the lib composes with a trap
|
|
76
|
+
# that already exists, and lint rule (c) wants ownership registered first.
|
|
77
|
+
# shellcheck source=../../../test/lib/git-fixture-env.sh
|
|
78
|
+
source "$SCRIPT_DIR/../../../test/lib/git-fixture-env.sh"
|
|
79
|
+
|
|
80
|
+
REPOS="$SUITE_TMP/repos"
|
|
81
|
+
mkdir -p "$REPOS"
|
|
82
|
+
git_fixture_env "$REPOS" || { printf '[FATAL] git_fixture_env refused %s\n' "$REPOS" >&2; exit 2; }
|
|
83
|
+
|
|
84
|
+
# The body below is a COPY. The canonical definition lives in
|
|
85
|
+
# plugins/soleur/test/test-helpers.sh; plugins/soleur/test/fixture-dir-operand-assert.test.sh
|
|
86
|
+
# asserts this copy is byte-equal to it. Do not reword it in one file only. #7652
|
|
87
|
+
assert_fixture_dir() {
|
|
88
|
+
case "${1-}" in
|
|
89
|
+
"") printf 'FATAL: fixture dir is EMPTY; git -C "" would operate on %s\n' "$PWD" >&2; exit 2 ;;
|
|
90
|
+
*/../*|*/..) printf 'FATAL: fixture dir %s contains ..; refusing\n' "$1" >&2; exit 2 ;;
|
|
91
|
+
/proc/*|/sys/*|/dev/*) printf 'FATAL: fixture dir %s is a synthetic-fs path; refusing\n' "$1" >&2; exit 2 ;;
|
|
92
|
+
/|//|/.) printf 'FATAL: fixture dir resolves to the filesystem root; refusing\n' >&2; exit 2 ;;
|
|
93
|
+
/*) : ;;
|
|
94
|
+
*) printf 'FATAL: fixture dir %s is RELATIVE; refusing\n' "$1" >&2; exit 2 ;;
|
|
95
|
+
esac
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
command -v git >/dev/null 2>&1 || { echo "UNRESOLVED: git missing — this suite asserted nothing; install git"; exit 3; }
|
|
99
|
+
command -v jq >/dev/null 2>&1 || { echo "UNRESOLVED: jq missing — this suite asserted nothing; install jq"; exit 3; }
|
|
100
|
+
command -v sha256sum >/dev/null 2>&1 || { echo "UNRESOLVED: sha256sum missing — this suite asserted nothing"; exit 3; }
|
|
101
|
+
[[ -f "$PARSE" ]] || { echo "FATAL: not found: $PARSE" >&2; exit 2; }
|
|
102
|
+
[[ -f "$MANIFEST" ]] || { echo "FATAL: not found: $MANIFEST" >&2; exit 2; }
|
|
103
|
+
|
|
104
|
+
# Seeded at runtime from the REAL manifest — the artifact's rule_pack_sha256
|
|
105
|
+
# then matches the freshness check byte-for-byte and stays out of every arm.
|
|
106
|
+
MANIFEST_SHA="$(sha256sum "$MANIFEST" | cut -d' ' -f1)"
|
|
107
|
+
[[ -n "$MANIFEST_SHA" ]] || { echo "FATAL: could not sha256 $MANIFEST" >&2; exit 2; }
|
|
108
|
+
|
|
109
|
+
PASS=0
|
|
110
|
+
FAIL=0
|
|
111
|
+
ok() { PASS=$((PASS + 1)); echo " [ok] $1"; }
|
|
112
|
+
bad() {
|
|
113
|
+
FAIL=$((FAIL + 1)); echo " [FAIL] $1" >&2
|
|
114
|
+
# Surface the gate's stderr on failure — run_parse redirects it to a file
|
|
115
|
+
# the EXIT trap deletes, so a crash's diagnostics are otherwise lost.
|
|
116
|
+
if [[ -s "$SUITE_TMP/parse.err" ]]; then tail -3 "$SUITE_TMP/parse.err" >&2; fi
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
OVERRIDE_DIR="knowledge-base/engineering/security/skill-overrides"
|
|
120
|
+
|
|
121
|
+
# mk_repo <dir> — a scratch repo whose `base` ref sits one commit behind HEAD.
|
|
122
|
+
mk_repo() {
|
|
123
|
+
local d="$1"
|
|
124
|
+
assert_fixture_dir "$d"
|
|
125
|
+
mkdir -p "$d"
|
|
126
|
+
git -C "$d" init -q
|
|
127
|
+
git -C "$d" commit -q --allow-empty -m "base"
|
|
128
|
+
git -C "$d" branch -f base
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
# commit_all <dir> <msg> — stage and commit everything the arm wrote.
|
|
132
|
+
commit_all() {
|
|
133
|
+
local d="$1" msg="$2"
|
|
134
|
+
assert_fixture_dir "$d"
|
|
135
|
+
git -C "$d" add -A
|
|
136
|
+
git -C "$d" commit -qm "$msg"
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
# write_artifact <repo> <slug> <findings-lines> [verdict] [omit-fields]
|
|
140
|
+
#
|
|
141
|
+
# Writes $OVERRIDE_DIR/2026-10-13-<slug>.md with a compliant frontmatter.
|
|
142
|
+
# <findings-lines> is emitted VERBATIM between `source:` and `justification:` —
|
|
143
|
+
# empty omits the field entirely, a multi-line $'…\n…' string carries the
|
|
144
|
+
# block-mapping spelling, and a whitespace-led line nests the key under
|
|
145
|
+
# `source:`. [omit-fields] is a space-separated list of required names to drop
|
|
146
|
+
# (the missing-timestamp arm). The body stays free of any email-shaped token —
|
|
147
|
+
# the PII arm is not under test here and must not fire.
|
|
148
|
+
write_artifact() {
|
|
149
|
+
local d="$1" slug="$2" findings="$3" verdict="${4:-HIGH-RISK}"
|
|
150
|
+
local omit=" ${5:-} "
|
|
151
|
+
assert_fixture_dir "$d"
|
|
152
|
+
local dir="$d/$OVERRIDE_DIR"
|
|
153
|
+
local f="$dir/2026-10-13-$slug.md"
|
|
154
|
+
mkdir -p "$dir"
|
|
155
|
+
assert_fixture_dir "$f"
|
|
156
|
+
{
|
|
157
|
+
printf -- '---\n'
|
|
158
|
+
[[ "$omit" == *" skill "* ]] || printf 'skill: %s\n' "$slug"
|
|
159
|
+
[[ "$omit" == *" source "* ]] || printf 'source: https://example.com/skills/%s\n' "$slug"
|
|
160
|
+
[[ -z "$findings" ]] || printf '%s\n' "$findings"
|
|
161
|
+
[[ "$omit" == *" justification "* ]] || printf 'justification: operator accepted the residual risk after review\n'
|
|
162
|
+
[[ "$omit" == *" approver "* ]] || printf 'approver: fixture@example.com\n'
|
|
163
|
+
[[ "$omit" == *" scanner_version "* ]] || printf 'scanner_version: 0.1.0\n'
|
|
164
|
+
[[ "$omit" == *" rule_pack_sha256 "* ]] || printf 'rule_pack_sha256: %s\n' "$MANIFEST_SHA"
|
|
165
|
+
[[ "$omit" == *" verdict "* ]] || printf 'verdict: %s\n' "$verdict"
|
|
166
|
+
[[ "$omit" == *" timestamp "* ]] || printf 'timestamp: 2026-10-13T00:00:00Z\n'
|
|
167
|
+
printf -- '---\n\n'
|
|
168
|
+
printf '# Override: %s\n\n## Findings\n%s/redacted.scan-meta.json\n\n## Justification\nReviewed and accepted.\n' "$slug" "$dir"
|
|
169
|
+
} > "$f"
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
# run_parse <repo> — run the gate from inside the fixture repo; sets
|
|
173
|
+
# PARSE_OUT (stdout JSON) and PARSE_RC.
|
|
174
|
+
PARSE_OUT=""
|
|
175
|
+
PARSE_RC=0
|
|
176
|
+
run_parse() {
|
|
177
|
+
local d="$1"
|
|
178
|
+
assert_fixture_dir "$d"
|
|
179
|
+
: > "$SUITE_TMP/parse.err"
|
|
180
|
+
PARSE_OUT="$(cd "$d" && bash "$PARSE" --base base --head HEAD 2>"$SUITE_TMP/parse.err")"
|
|
181
|
+
PARSE_RC=$?
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
# in_bucket <bucket> <relpath> — the result JSON names <relpath> under .<bucket>.
|
|
185
|
+
in_bucket() {
|
|
186
|
+
printf '%s' "$PARSE_OUT" | jq -e --arg b "$1" --arg p "$2" \
|
|
187
|
+
'any(.[$b][]; .path == $p)' >/dev/null
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
# reason_for <relpath> — the invalid_schema reason recorded for <relpath> ("" if none).
|
|
191
|
+
reason_for() {
|
|
192
|
+
printf '%s' "$PARSE_OUT" | jq -r --arg p "$1" \
|
|
193
|
+
'first(.invalid_schema[] | select(.path == $p) | .reason) // ""'
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
echo "=== parse-override.sh presence check (#10167) ==="
|
|
197
|
+
|
|
198
|
+
# --- Arm 0: instrument self-check --------------------------------------------
|
|
199
|
+
# Drive both counters once each (output suppressed — the assertion is the
|
|
200
|
+
# counter delta, not the line). A suite whose ok/bad never move reports a
|
|
201
|
+
# green vacuously; the exit gate below also pins an arm-count floor.
|
|
202
|
+
_self_pass=$PASS; _self_fail=$FAIL
|
|
203
|
+
ok "self-check" >/dev/null
|
|
204
|
+
bad "self-check" 2>/dev/null
|
|
205
|
+
if [[ $PASS -eq $((_self_pass + 1)) && $FAIL -eq $((_self_fail + 1)) ]]; then
|
|
206
|
+
PASS=$_self_pass; FAIL=$_self_fail
|
|
207
|
+
else
|
|
208
|
+
echo "FATAL: ok/bad counters did not move — instrument dead" >&2; exit 2
|
|
209
|
+
fi
|
|
210
|
+
|
|
211
|
+
# --- Arm 1 (MUST-PASS, non-canonical): block-mapping findings_json ACCEPT -----
|
|
212
|
+
# The defect itself: schema-permitted spelling the old grep rejected.
|
|
213
|
+
R="$REPOS/arm-block-map"
|
|
214
|
+
rel="$OVERRIDE_DIR/2026-10-13-demo-skill.md"
|
|
215
|
+
mk_repo "$R"
|
|
216
|
+
write_artifact "$R" "demo-skill" \
|
|
217
|
+
$'findings_json:\n code-execution: {"verdict": "HIGH-RISK", "count": 1}\n filesystem-boundary: {"verdict": "REVIEW", "count": 0}'
|
|
218
|
+
commit_all "$R" "add override artifact"
|
|
219
|
+
run_parse "$R"
|
|
220
|
+
if [[ "$PARSE_RC" -eq 0 ]] && in_bucket matched "$rel" && ! in_bucket invalid_schema "$rel"; then
|
|
221
|
+
ok "block-mapping findings_json validates (matched, rc=0)"
|
|
222
|
+
else
|
|
223
|
+
bad "block-mapping findings_json rejected — the #10167 defect (rc=$PARSE_RC, out=$PARSE_OUT)"
|
|
224
|
+
fi
|
|
225
|
+
|
|
226
|
+
# --- Arm 2: flow-style findings_json ACCEPT -----------------------------------
|
|
227
|
+
# Same-line `{…}` — present before and after the fix; regression cover.
|
|
228
|
+
R="$REPOS/arm-flow"
|
|
229
|
+
rel="$OVERRIDE_DIR/2026-10-13-flow-skill.md"
|
|
230
|
+
mk_repo "$R"
|
|
231
|
+
write_artifact "$R" "flow-skill" 'findings_json: {"code-execution": {"verdict": "HIGH-RISK", "count": 1}}'
|
|
232
|
+
commit_all "$R" "add override artifact"
|
|
233
|
+
run_parse "$R"
|
|
234
|
+
if [[ "$PARSE_RC" -eq 0 ]] && in_bucket matched "$rel" && ! in_bucket invalid_schema "$rel"; then
|
|
235
|
+
ok "flow-style findings_json validates (matched, rc=0)"
|
|
236
|
+
else
|
|
237
|
+
bad "flow-style findings_json regressed (rc=$PARSE_RC, out=$PARSE_OUT)"
|
|
238
|
+
fi
|
|
239
|
+
|
|
240
|
+
# --- Arm 3: absent findings_json REJECT (+ positive control) ------------------
|
|
241
|
+
# `findings` arg empty → the field never reaches the frontmatter.
|
|
242
|
+
R="$REPOS/arm-absent"
|
|
243
|
+
rel="$OVERRIDE_DIR/2026-10-13-absent-skill.md"
|
|
244
|
+
rel_ok="$OVERRIDE_DIR/2026-10-13-ok-skill.md"
|
|
245
|
+
mk_repo "$R"
|
|
246
|
+
write_artifact "$R" "ok-skill" 'findings_json: {"code-execution": {"verdict": "REVIEW", "count": 2}}'
|
|
247
|
+
write_artifact "$R" "absent-skill" ""
|
|
248
|
+
commit_all "$R" "add override artifacts"
|
|
249
|
+
run_parse "$R"
|
|
250
|
+
reason="$(reason_for "$rel")"
|
|
251
|
+
if [[ "$PARSE_RC" -ne 0 ]] && in_bucket invalid_schema "$rel" && in_bucket matched "$rel_ok" \
|
|
252
|
+
&& [[ "$reason" == *"missing fields"* && "$reason" == *"findings_json"* ]]; then
|
|
253
|
+
ok "absent findings_json still rejects (missing fields; ok-skill matched)"
|
|
254
|
+
else
|
|
255
|
+
bad "absent findings_json not rejected as missing fields (rc=$PARSE_RC, reason='$reason', out=$PARSE_OUT)"
|
|
256
|
+
fi
|
|
257
|
+
|
|
258
|
+
# --- Arm 4: declared-but-empty findings_json REJECT ---------------------------
|
|
259
|
+
# `findings_json:` then the NEXT top-level key — the presence check must not
|
|
260
|
+
# degenerate into key-line existence (Guard 1 mutation row 3).
|
|
261
|
+
R="$REPOS/arm-empty"
|
|
262
|
+
rel="$OVERRIDE_DIR/2026-10-13-empty-skill.md"
|
|
263
|
+
rel_ok="$OVERRIDE_DIR/2026-10-13-ok-skill.md"
|
|
264
|
+
mk_repo "$R"
|
|
265
|
+
write_artifact "$R" "ok-skill" 'findings_json: {"code-execution": {"verdict": "REVIEW", "count": 2}}'
|
|
266
|
+
write_artifact "$R" "empty-skill" 'findings_json:'
|
|
267
|
+
commit_all "$R" "add override artifacts"
|
|
268
|
+
run_parse "$R"
|
|
269
|
+
reason="$(reason_for "$rel")"
|
|
270
|
+
if [[ "$PARSE_RC" -ne 0 ]] && in_bucket invalid_schema "$rel" && in_bucket matched "$rel_ok" \
|
|
271
|
+
&& [[ "$reason" == *"missing fields"* && "$reason" == *"findings_json"* ]]; then
|
|
272
|
+
ok "declared-but-empty findings_json still rejects (missing fields)"
|
|
273
|
+
else
|
|
274
|
+
bad "declared-but-empty findings_json not rejected (rc=$PARSE_RC, reason='$reason', out=$PARSE_OUT)"
|
|
275
|
+
fi
|
|
276
|
+
|
|
277
|
+
# --- Arm 4b (CTO dissent): whitespace-only findings_json REJECT ---------------
|
|
278
|
+
# `f: ` — same key line, whitespace-only value. The dissent's named case.
|
|
279
|
+
R="$REPOS/arm-ws-empty"
|
|
280
|
+
rel="$OVERRIDE_DIR/2026-10-13-ws-empty-skill.md"
|
|
281
|
+
rel_ok="$OVERRIDE_DIR/2026-10-13-ok-skill.md"
|
|
282
|
+
mk_repo "$R"
|
|
283
|
+
write_artifact "$R" "ok-skill" 'findings_json: {"code-execution": {"verdict": "REVIEW", "count": 2}}'
|
|
284
|
+
write_artifact "$R" "ws-empty-skill" 'findings_json: '
|
|
285
|
+
commit_all "$R" "add override artifacts"
|
|
286
|
+
run_parse "$R"
|
|
287
|
+
reason="$(reason_for "$rel")"
|
|
288
|
+
if [[ "$PARSE_RC" -ne 0 ]] && in_bucket invalid_schema "$rel" && in_bucket matched "$rel_ok" \
|
|
289
|
+
&& [[ "$reason" == *"missing fields"* && "$reason" == *"findings_json"* ]]; then
|
|
290
|
+
ok "whitespace-only findings_json rejects (CTO dissent: f:<ws-only> is empty)"
|
|
291
|
+
else
|
|
292
|
+
bad "whitespace-only findings_json not rejected (rc=$PARSE_RC, reason='$reason', out=$PARSE_OUT)"
|
|
293
|
+
fi
|
|
294
|
+
|
|
295
|
+
# --- Arm 4c (comments are neutral): comment-only block REJECT -----------------
|
|
296
|
+
# `findings_json:` followed by an indented COMMENT then the next key. A comment
|
|
297
|
+
# is not content — the block arm must not count it (ruling: comments neutral).
|
|
298
|
+
R="$REPOS/arm-comment-only"
|
|
299
|
+
rel="$OVERRIDE_DIR/2026-10-13-comment-skill.md"
|
|
300
|
+
rel_ok="$OVERRIDE_DIR/2026-10-13-ok-skill.md"
|
|
301
|
+
mk_repo "$R"
|
|
302
|
+
write_artifact "$R" "ok-skill" 'findings_json: {"code-execution": {"verdict": "REVIEW", "count": 2}}'
|
|
303
|
+
write_artifact "$R" "comment-skill" $'findings_json:\n # redacted copy lives in .scan-meta.json'
|
|
304
|
+
commit_all "$R" "add override artifacts"
|
|
305
|
+
run_parse "$R"
|
|
306
|
+
reason="$(reason_for "$rel")"
|
|
307
|
+
if [[ "$PARSE_RC" -ne 0 ]] && in_bucket invalid_schema "$rel" && in_bucket matched "$rel_ok" \
|
|
308
|
+
&& [[ "$reason" == *"missing fields"* && "$reason" == *"findings_json"* ]]; then
|
|
309
|
+
ok "comment-only findings_json block rejects (comments are not content)"
|
|
310
|
+
else
|
|
311
|
+
bad "comment-only findings_json block not rejected (rc=$PARSE_RC, reason='$reason', out=$PARSE_OUT)"
|
|
312
|
+
fi
|
|
313
|
+
|
|
314
|
+
# --- Arm 5: nested-under-another-key findings_json REJECT ---------------------
|
|
315
|
+
# ` findings_json:` whitespace-led under `source:` — the `^` anchor must keep
|
|
316
|
+
# a nested same-named key from false-presenting (the plan's Sharp Edge).
|
|
317
|
+
R="$REPOS/arm-nested"
|
|
318
|
+
rel="$OVERRIDE_DIR/2026-10-13-nested-skill.md"
|
|
319
|
+
rel_ok="$OVERRIDE_DIR/2026-10-13-ok-skill.md"
|
|
320
|
+
mk_repo "$R"
|
|
321
|
+
write_artifact "$R" "ok-skill" 'findings_json: {"code-execution": {"verdict": "REVIEW", "count": 2}}'
|
|
322
|
+
write_artifact "$R" "nested-skill" ' findings_json: {"code-execution": {"verdict": "REVIEW", "count": 1}}'
|
|
323
|
+
commit_all "$R" "add override artifacts"
|
|
324
|
+
run_parse "$R"
|
|
325
|
+
reason="$(reason_for "$rel")"
|
|
326
|
+
if [[ "$PARSE_RC" -ne 0 ]] && in_bucket invalid_schema "$rel" && in_bucket matched "$rel_ok" \
|
|
327
|
+
&& [[ "$reason" == *"missing fields"* && "$reason" == *"findings_json"* ]]; then
|
|
328
|
+
ok "nested findings_json rejects (^-anchored; nested keys do not count)"
|
|
329
|
+
else
|
|
330
|
+
bad "nested findings_json not rejected (rc=$PARSE_RC, reason='$reason', out=$PARSE_OUT)"
|
|
331
|
+
fi
|
|
332
|
+
|
|
333
|
+
# --- Arm 6: second artifact missing timestamp REJECT --------------------------
|
|
334
|
+
# The check must not stop at the first member (Guard 1 mutation row 5): a
|
|
335
|
+
# compliant ok-skill AND a bad-skill missing `timestamp` in one diff.
|
|
336
|
+
R="$REPOS/arm-second"
|
|
337
|
+
rel="$OVERRIDE_DIR/2026-10-13-bad-skill.md"
|
|
338
|
+
rel_ok="$OVERRIDE_DIR/2026-10-13-ok-skill.md"
|
|
339
|
+
mk_repo "$R"
|
|
340
|
+
write_artifact "$R" "ok-skill" 'findings_json: {"code-execution": {"verdict": "REVIEW", "count": 2}}'
|
|
341
|
+
write_artifact "$R" "bad-skill" 'findings_json: {"code-execution": {"verdict": "REVIEW", "count": 1}}' "REVIEW" "timestamp"
|
|
342
|
+
commit_all "$R" "add override artifacts"
|
|
343
|
+
run_parse "$R"
|
|
344
|
+
reason="$(reason_for "$rel")"
|
|
345
|
+
if [[ "$PARSE_RC" -ne 0 ]] && in_bucket invalid_schema "$rel" && in_bucket matched "$rel_ok" \
|
|
346
|
+
&& [[ "$reason" == *"missing fields"* && "$reason" == *"timestamp"* ]]; then
|
|
347
|
+
ok "a second artifact missing timestamp rejects (enumeration does not stop at member one)"
|
|
348
|
+
else
|
|
349
|
+
bad "missing-timestamp second artifact not rejected (rc=$PARSE_RC, reason='$reason', out=$PARSE_OUT)"
|
|
350
|
+
fi
|
|
351
|
+
|
|
352
|
+
# --- Arm 7: verdict: LOW-RISK REJECT (downstream check intact) ----------------
|
|
353
|
+
# An otherwise-valid artifact with a forbidden verdict — the presence fix must
|
|
354
|
+
# not weaken the downstream value checks (Guard 1 mutation row 7).
|
|
355
|
+
R="$REPOS/arm-lowrisk"
|
|
356
|
+
rel="$OVERRIDE_DIR/2026-10-13-lowrisk-skill.md"
|
|
357
|
+
rel_ok="$OVERRIDE_DIR/2026-10-13-ok-skill.md"
|
|
358
|
+
mk_repo "$R"
|
|
359
|
+
write_artifact "$R" "ok-skill" 'findings_json: {"code-execution": {"verdict": "REVIEW", "count": 2}}'
|
|
360
|
+
write_artifact "$R" "lowrisk-skill" 'findings_json: {"code-execution": {"verdict": "LOW-RISK", "count": 0}}' "LOW-RISK"
|
|
361
|
+
commit_all "$R" "add override artifacts"
|
|
362
|
+
run_parse "$R"
|
|
363
|
+
reason="$(reason_for "$rel")"
|
|
364
|
+
if [[ "$PARSE_RC" -ne 0 ]] && in_bucket invalid_schema "$rel" && in_bucket matched "$rel_ok" \
|
|
365
|
+
&& [[ "$reason" == *"verdict"* && "$reason" == *"LOW-RISK"* ]]; then
|
|
366
|
+
ok "verdict: LOW-RISK rejects (downstream value check intact)"
|
|
367
|
+
else
|
|
368
|
+
bad "verdict: LOW-RISK not rejected (rc=$PARSE_RC, reason='$reason', out=$PARSE_OUT)"
|
|
369
|
+
fi
|
|
370
|
+
|
|
371
|
+
# --- Arm 4d: stale-cur — indented stray under an UNRECOGNIZED col-0 key -------
|
|
372
|
+
# `findings_json:` bare, then `other :` (space-before-colon — legal YAML, not
|
|
373
|
+
# recognized by this gate's key regex), then an indented line. The block ends
|
|
374
|
+
# at ANY col-0 content line, so ` k: v` must NOT credit findings_json. A
|
|
375
|
+
# predicate that only resets `cur` on recognized key lines back-fills the
|
|
376
|
+
# pending field — the security-sentinel/structural-enum review finding.
|
|
377
|
+
R="$REPOS/arm-stale-cur"
|
|
378
|
+
rel="$OVERRIDE_DIR/2026-10-13-stalecur-skill.md"
|
|
379
|
+
rel_ok="$OVERRIDE_DIR/2026-10-13-ok-skill.md"
|
|
380
|
+
mk_repo "$R"
|
|
381
|
+
write_artifact "$R" "ok-skill" 'findings_json: {"code-execution": {"verdict": "REVIEW", "count": 2}}'
|
|
382
|
+
write_artifact "$R" "stalecur-skill" $'findings_json:\nother :\n k: v'
|
|
383
|
+
commit_all "$R" "add override artifacts"
|
|
384
|
+
run_parse "$R"
|
|
385
|
+
reason="$(reason_for "$rel")"
|
|
386
|
+
if [[ "$PARSE_RC" -ne 0 ]] && in_bucket invalid_schema "$rel" && in_bucket matched "$rel_ok" \
|
|
387
|
+
&& [[ "$reason" == *"missing fields"* && "$reason" == *"findings_json"* ]]; then
|
|
388
|
+
ok "indented stray under an unrecognized col-0 key does not back-fill (missing fields)"
|
|
389
|
+
else
|
|
390
|
+
bad "stale-cur back-fill accepted (rc=$PARSE_RC, reason='$reason', out=$PARSE_OUT)"
|
|
391
|
+
fi
|
|
392
|
+
|
|
393
|
+
# --- Arm 4e: no-separation-space key REJECT ------------------------------------
|
|
394
|
+
# `verdict:HIGH-RISK` — YAML requires `:` + space/EOL for a mapping entry;
|
|
395
|
+
# without it the whole line is a plain scalar and the field is absent. The
|
|
396
|
+
# pre-#10167 grep rejected this spelling; an `^f:`-alone predicate accepts it,
|
|
397
|
+
# and the file's downstream extractors read `f:v` too — an end-to-end bypass
|
|
398
|
+
# (review P2). write_artifact always emits `verdict: <v>`, so this arm writes
|
|
399
|
+
# the artifact directly.
|
|
400
|
+
R="$REPOS/arm-nospace"
|
|
401
|
+
rel="$OVERRIDE_DIR/2026-10-13-nospace-skill.md"
|
|
402
|
+
rel_ok="$OVERRIDE_DIR/2026-10-13-ok-skill.md"
|
|
403
|
+
mk_repo "$R"
|
|
404
|
+
write_artifact "$R" "ok-skill" 'findings_json: {"code-execution": {"verdict": "REVIEW", "count": 2}}'
|
|
405
|
+
mkdir -p "$R/$OVERRIDE_DIR"
|
|
406
|
+
{
|
|
407
|
+
printf -- '---\n'
|
|
408
|
+
printf 'skill: nospace-skill\n'
|
|
409
|
+
printf 'source: https://example.com/skills/nospace-skill\n'
|
|
410
|
+
printf 'findings_json: {"code-execution": {"verdict": "HIGH-RISK", "count": 1}}\n'
|
|
411
|
+
printf 'justification: operator accepted the residual risk after review\n'
|
|
412
|
+
printf 'approver: fixture@example.com\n'
|
|
413
|
+
printf 'scanner_version: 0.1.0\n'
|
|
414
|
+
printf 'rule_pack_sha256: %s\n' "$MANIFEST_SHA"
|
|
415
|
+
printf 'verdict:HIGH-RISK\n'
|
|
416
|
+
printf 'timestamp: 2026-10-13T00:00:00Z\n'
|
|
417
|
+
printf -- '---\n\n'
|
|
418
|
+
printf '# Override: nospace-skill\n\n## Findings\n%s/redacted.scan-meta.json\n\n## Justification\nReviewed and accepted.\n' "$OVERRIDE_DIR"
|
|
419
|
+
} > "$R/$rel"
|
|
420
|
+
commit_all "$R" "add override artifacts"
|
|
421
|
+
run_parse "$R"
|
|
422
|
+
reason="$(reason_for "$rel")"
|
|
423
|
+
if [[ "$PARSE_RC" -ne 0 ]] && in_bucket invalid_schema "$rel" && in_bucket matched "$rel_ok" \
|
|
424
|
+
&& [[ "$reason" == *"missing fields"* && "$reason" == *"verdict"* ]]; then
|
|
425
|
+
ok "no-separation-space verdict:HIGH-RISK rejects (a scalar, not a mapping)"
|
|
426
|
+
else
|
|
427
|
+
bad "no-separation-space key accepted — end-to-end bypass (rc=$PARSE_RC, reason='$reason', out=$PARSE_OUT)"
|
|
428
|
+
fi
|
|
429
|
+
|
|
430
|
+
# --- Arm 4f: findings_json: null REJECT ----------------------------------------
|
|
431
|
+
# A YAML null is not "present" for a schema-required field — `f: null`/`f: ~`
|
|
432
|
+
# must report missing, not satisfy presence.
|
|
433
|
+
R="$REPOS/arm-null"
|
|
434
|
+
rel="$OVERRIDE_DIR/2026-10-13-null-skill.md"
|
|
435
|
+
rel_ok="$OVERRIDE_DIR/2026-10-13-ok-skill.md"
|
|
436
|
+
mk_repo "$R"
|
|
437
|
+
write_artifact "$R" "ok-skill" 'findings_json: {"code-execution": {"verdict": "REVIEW", "count": 2}}'
|
|
438
|
+
write_artifact "$R" "null-skill" 'findings_json: null'
|
|
439
|
+
commit_all "$R" "add override artifacts"
|
|
440
|
+
run_parse "$R"
|
|
441
|
+
reason="$(reason_for "$rel")"
|
|
442
|
+
if [[ "$PARSE_RC" -ne 0 ]] && in_bucket invalid_schema "$rel" && in_bucket matched "$rel_ok" \
|
|
443
|
+
&& [[ "$reason" == *"missing fields"* && "$reason" == *"findings_json"* ]]; then
|
|
444
|
+
ok "findings_json: null rejects (YAML null is absent for a required field)"
|
|
445
|
+
else
|
|
446
|
+
bad "findings_json: null not rejected (rc=$PARSE_RC, reason='$reason', out=$PARSE_OUT)"
|
|
447
|
+
fi
|
|
448
|
+
|
|
449
|
+
# --- Arm 4g: duplicate key — LAST occurrence wins -------------------------------
|
|
450
|
+
# `findings_json: {}` then a bare `findings_json:` — YAML last-wins makes the
|
|
451
|
+
# field null; a first-seen latch would keep it present (review P3).
|
|
452
|
+
R="$REPOS/arm-dup"
|
|
453
|
+
rel="$OVERRIDE_DIR/2026-10-13-dup-skill.md"
|
|
454
|
+
rel_ok="$OVERRIDE_DIR/2026-10-13-ok-skill.md"
|
|
455
|
+
mk_repo "$R"
|
|
456
|
+
write_artifact "$R" "ok-skill" 'findings_json: {"code-execution": {"verdict": "REVIEW", "count": 2}}'
|
|
457
|
+
write_artifact "$R" "dup-skill" $'findings_json: {}\nfindings_json:'
|
|
458
|
+
commit_all "$R" "add override artifacts"
|
|
459
|
+
run_parse "$R"
|
|
460
|
+
reason="$(reason_for "$rel")"
|
|
461
|
+
if [[ "$PARSE_RC" -ne 0 ]] && in_bucket invalid_schema "$rel" && in_bucket matched "$rel_ok" \
|
|
462
|
+
&& [[ "$reason" == *"missing fields"* && "$reason" == *"findings_json"* ]]; then
|
|
463
|
+
ok "duplicate findings_json resolves last-wins (trailing bare key is missing)"
|
|
464
|
+
else
|
|
465
|
+
bad "duplicate key latched first-wins (rc=$PARSE_RC, reason='$reason', out=$PARSE_OUT)"
|
|
466
|
+
fi
|
|
467
|
+
|
|
468
|
+
# --- Arm 8: empty-diff baseline -------------------------------------------------
|
|
469
|
+
# The modal CI path: a diff containing no override artifacts at all must
|
|
470
|
+
# return rc 0 with all three buckets empty (pr-quality-guards.yml consumes
|
|
471
|
+
# this shape directly).
|
|
472
|
+
R="$REPOS/arm-empty-diff"
|
|
473
|
+
mk_repo "$R"
|
|
474
|
+
git -C "$R" commit -q --allow-empty -m "no artifacts"
|
|
475
|
+
run_parse "$R"
|
|
476
|
+
if [[ "$PARSE_RC" -eq 0 ]] \
|
|
477
|
+
&& [[ "$(printf '%s' "$PARSE_OUT" | jq '[.matched[], .invalid_schema[], .stale_findings[]] | length')" == "0" ]]; then
|
|
478
|
+
ok "empty-diff baseline: rc=0, all buckets empty"
|
|
479
|
+
else
|
|
480
|
+
bad "empty-diff baseline broken (rc=$PARSE_RC, out=$PARSE_OUT)"
|
|
481
|
+
fi
|
|
482
|
+
|
|
483
|
+
# --- Arm 9: stale rule_pack_sha256 → stale_findings bucket ---------------------
|
|
484
|
+
# The third bucket, unexercised until now: a wrong-but-well-formed sha must
|
|
485
|
+
# land in stale_findings and fail closed (rc=1) while ok-skill still matches.
|
|
486
|
+
R="$REPOS/arm-stale-sha"
|
|
487
|
+
rel="$OVERRIDE_DIR/2026-10-13-stale-skill.md"
|
|
488
|
+
rel_ok="$OVERRIDE_DIR/2026-10-13-ok-skill.md"
|
|
489
|
+
mk_repo "$R"
|
|
490
|
+
write_artifact "$R" "ok-skill" 'findings_json: {"code-execution": {"verdict": "REVIEW", "count": 2}}'
|
|
491
|
+
# write_artifact seeds MANIFEST_SHA verbatim; emit this artifact by hand with a
|
|
492
|
+
# bogus sha (64-hex, well-formed, deliberately not the live manifest's).
|
|
493
|
+
mkdir -p "$R/$OVERRIDE_DIR"
|
|
494
|
+
{
|
|
495
|
+
printf -- '---\n'
|
|
496
|
+
printf 'skill: stale-skill\n'
|
|
497
|
+
printf 'source: https://example.com/skills/stale-skill\n'
|
|
498
|
+
printf 'findings_json: {"code-execution": {"verdict": "REVIEW", "count": 0}}\n'
|
|
499
|
+
printf 'justification: operator accepted the residual risk after review\n'
|
|
500
|
+
printf 'approver: fixture@example.com\n'
|
|
501
|
+
printf 'scanner_version: 0.1.0\n'
|
|
502
|
+
printf 'rule_pack_sha256: %064d\n' 0
|
|
503
|
+
printf 'verdict: REVIEW\n'
|
|
504
|
+
printf 'timestamp: 2026-10-13T00:00:00Z\n'
|
|
505
|
+
printf -- '---\n\n'
|
|
506
|
+
printf '# Override: stale-skill\n\n## Findings\n%s/redacted.scan-meta.json\n\n## Justification\nReviewed and accepted.\n' "$OVERRIDE_DIR"
|
|
507
|
+
} > "$R/$rel"
|
|
508
|
+
commit_all "$R" "add override artifacts"
|
|
509
|
+
run_parse "$R"
|
|
510
|
+
if [[ "$PARSE_RC" -ne 0 ]] && in_bucket stale_findings "$rel" && in_bucket matched "$rel_ok" \
|
|
511
|
+
&& ! in_bucket matched "$rel"; then
|
|
512
|
+
ok "stale rule_pack_sha256 lands in stale_findings and fails closed"
|
|
513
|
+
else
|
|
514
|
+
bad "stale sha not bucketed (rc=$PARSE_RC, out=$PARSE_OUT)"
|
|
515
|
+
fi
|
|
516
|
+
|
|
517
|
+
# --- Arm 10: tab-separated key REJECT ------------------------------------------
|
|
518
|
+
# `findings_json:\t{…}` — a tab is forbidden as key separator AND indentation
|
|
519
|
+
# in YAML. The key arm's ` ` (literal space, not [[:space:]]) and the block
|
|
520
|
+
# arm's leading-space requirement deny it; an `[[:space:]]` regression would
|
|
521
|
+
# silently re-accept a document no YAML parser can read (verification-pass P3).
|
|
522
|
+
R="$REPOS/arm-tab"
|
|
523
|
+
rel="$OVERRIDE_DIR/2026-10-13-tab-skill.md"
|
|
524
|
+
rel_ok="$OVERRIDE_DIR/2026-10-13-ok-skill.md"
|
|
525
|
+
mk_repo "$R"
|
|
526
|
+
write_artifact "$R" "ok-skill" 'findings_json: {"code-execution": {"verdict": "REVIEW", "count": 2}}'
|
|
527
|
+
write_artifact "$R" "tab-skill" $'findings_json:\t{"code-execution": {"verdict": "REVIEW", "count": 0}}'
|
|
528
|
+
commit_all "$R" "add override artifacts"
|
|
529
|
+
run_parse "$R"
|
|
530
|
+
reason="$(reason_for "$rel")"
|
|
531
|
+
if [[ "$PARSE_RC" -ne 0 ]] && in_bucket invalid_schema "$rel" && in_bucket matched "$rel_ok" \
|
|
532
|
+
&& [[ "$reason" == *"missing fields"* && "$reason" == *"findings_json"* ]]; then
|
|
533
|
+
ok "tab-separated findings_json rejects (YAML forbids tab separators)"
|
|
534
|
+
else
|
|
535
|
+
bad "tab-separated findings_json accepted (rc=$PARSE_RC, reason='$reason', out=$PARSE_OUT)"
|
|
536
|
+
fi
|
|
537
|
+
|
|
538
|
+
# --- Arm 11: valued-duplicate keys resolve last-wins end-to-end ---------------
|
|
539
|
+
# Presence recomputes on each key occurrence; the value extractors must read
|
|
540
|
+
# the SAME occurrence. Two verdict orders pin the direction both ways: the
|
|
541
|
+
# dup-high arm must MATCH (last is HIGH-RISK) and the dup-low arm must reject
|
|
542
|
+
# (last is LOW-RISK). A first-match extractor passes arm A and fails arm B
|
|
543
|
+
# backwards — each direction discriminates. (ship-advisor finding)
|
|
544
|
+
R="$REPOS/arm-duphi"
|
|
545
|
+
rel="$OVERRIDE_DIR/2026-10-13-duphi-skill.md"
|
|
546
|
+
mk_repo "$R"
|
|
547
|
+
write_artifact "$R" "duphi-skill" \
|
|
548
|
+
$'findings_json: {"code-execution": {"verdict": "REVIEW", "count": 1}}\nverdict: LOW-RISK' \
|
|
549
|
+
"HIGH-RISK"
|
|
550
|
+
commit_all "$R" "add override artifact"
|
|
551
|
+
run_parse "$R"
|
|
552
|
+
dup_hi_ok=0
|
|
553
|
+
[[ "$PARSE_RC" -eq 0 ]] && in_bucket matched "$rel" && dup_hi_ok=1
|
|
554
|
+
|
|
555
|
+
R="$REPOS/arm-duplo"
|
|
556
|
+
rel="$OVERRIDE_DIR/2026-10-13-duplo-skill.md"
|
|
557
|
+
mk_repo "$R"
|
|
558
|
+
write_artifact "$R" "duplo-skill" \
|
|
559
|
+
$'findings_json: {"code-execution": {"verdict": "REVIEW", "count": 1}}\nverdict: HIGH-RISK' \
|
|
560
|
+
"LOW-RISK"
|
|
561
|
+
commit_all "$R" "add override artifact"
|
|
562
|
+
run_parse "$R"
|
|
563
|
+
reason="$(reason_for "$rel")"
|
|
564
|
+
if [[ "$dup_hi_ok" -eq 1 && "$PARSE_RC" -ne 0 ]] && in_bucket invalid_schema "$rel" \
|
|
565
|
+
&& [[ "$reason" == *"verdict must be"* ]]; then
|
|
566
|
+
ok "valued-duplicate verdict resolves last-wins (HIGH-RISK-last matched, LOW-RISK-last rejected)"
|
|
567
|
+
else
|
|
568
|
+
bad "valued-dup divergence (hi_rc/dup_ok=$dup_hi_ok lo_rc=$PARSE_RC reason='$reason' out=$PARSE_OUT)"
|
|
569
|
+
fi
|
|
570
|
+
|
|
571
|
+
# --- Arm 12: embedded-colon values must not truncate to a valid prefix --------
|
|
572
|
+
# `-F:`/`print $2` extraction reads `sha:junk` as `sha` and `slug:junk` as
|
|
573
|
+
# `slug` — the gate then validates a prefix the document never wrote. Two
|
|
574
|
+
# artifacts in one repo: the sha-suffixed one lands in stale_findings (prefix
|
|
575
|
+
# compare on the full scalar), the skill-suffixed one fails the slug regex.
|
|
576
|
+
R="$REPOS/arm-trunc"
|
|
577
|
+
rel_sha="$OVERRIDE_DIR/2026-10-13-sha-trunc-skill.md"
|
|
578
|
+
rel_sk="$OVERRIDE_DIR/2026-10-13-sk-trunc-skill.md"
|
|
579
|
+
mk_repo "$R"
|
|
580
|
+
write_artifact "$R" "sha-trunc-skill" \
|
|
581
|
+
"findings_json: {\"code-execution\": {\"verdict\": \"REVIEW\", \"count\": 0}}"$'\n'"rule_pack_sha256: ${MANIFEST_SHA}:junk" \
|
|
582
|
+
"HIGH-RISK" "rule_pack_sha256"
|
|
583
|
+
write_artifact "$R" "sk-trunc-skill" \
|
|
584
|
+
"findings_json: {\"code-execution\": {\"verdict\": \"REVIEW\", \"count\": 0}}"$'\n'"skill: sk-trunc-skill:junk" \
|
|
585
|
+
"HIGH-RISK" "skill"
|
|
586
|
+
commit_all "$R" "add override artifacts"
|
|
587
|
+
run_parse "$R"
|
|
588
|
+
reason="$(reason_for "$rel_sk")"
|
|
589
|
+
if [[ "$PARSE_RC" -ne 0 ]] && in_bucket stale_findings "$rel_sha" \
|
|
590
|
+
&& in_bucket invalid_schema "$rel_sk" && [[ "$reason" == *"skill: field invalid"* ]]; then
|
|
591
|
+
ok "embedded-colon values reject (sha:junk -> stale, slug:junk -> invalid)"
|
|
592
|
+
else
|
|
593
|
+
bad "embedded-colon truncation accepted (rc=$PARSE_RC, reason='$reason', out=$PARSE_OUT)"
|
|
594
|
+
fi
|
|
595
|
+
|
|
596
|
+
echo "=== parse-override: $PASS passed, $FAIL failed ==="
|
|
597
|
+
# Real failures first — report them as failures, not as vacuity.
|
|
598
|
+
if [[ "$FAIL" -gt 0 ]]; then exit 1; fi
|
|
599
|
+
# Assertion floor: a run that executed fewer than every arm reads RED, never
|
|
600
|
+
# vacuously green — the `(( PASS < N ))` counter-comparison shape is the one
|
|
601
|
+
# guard-vacuity-floor.test.sh derives floors from.
|
|
602
|
+
if (( PASS < 18 )); then
|
|
603
|
+
echo "VACUITY: only $PASS of 18 arms passed — refusing green" >&2
|
|
604
|
+
exit 1
|
|
605
|
+
fi
|
|
606
|
+
echo "OK: $PASS assertions"
|
|
607
|
+
exit 0
|