@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,271 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# gdpr-gate advisory pre-commit hook (lefthook).
|
|
3
|
+
#
|
|
4
|
+
# Always exits 0 — the hook is advisory, never blocking. Blocking enforcement
|
|
5
|
+
# lives in /soleur:ship Phase 5.5 (post-PR). This hook prints a one-line
|
|
6
|
+
# stderr breadcrumb when staged paths match the canonical regulated-data
|
|
7
|
+
# regex (single source of truth: SKILL.md §"Path globs (canonical)").
|
|
8
|
+
#
|
|
9
|
+
# Telemetry: emits, via .claude/hooks/lib/incidents.sh, an
|
|
10
|
+
# `hr-gdpr-gate-on-regulated-data-surfaces` event when a regulated-data path
|
|
11
|
+
# is touched, plus `gdpr-gate-staleness` and `gdpr-gate-cron-binding` events
|
|
12
|
+
# for the corpus-freshness signals. Telemetry survives even when the
|
|
13
|
+
# operator's terminal swallows stderr.
|
|
14
|
+
#
|
|
15
|
+
# This block previously documented a `gdpr-gate-touch` event. No such event
|
|
16
|
+
# has ever been emitted by this file (#7710). The name was corrected rather
|
|
17
|
+
# than the emit: `hr-gdpr-gate-on-regulated-data-surfaces` is the rule this
|
|
18
|
+
# gate enforces, and it is accepted by the incident allow-list via the
|
|
19
|
+
# closed-corpus arm of `_valid_rule` (it is a real `[id: ...]` in
|
|
20
|
+
# AGENTS.rules.md), not via the synthetic `gdpr-gate-*` prefix arm.
|
|
21
|
+
#
|
|
22
|
+
# Invoked from lefthook.yml:
|
|
23
|
+
# gdpr-gate-advisory:
|
|
24
|
+
# priority: 6
|
|
25
|
+
# run: bash plugins/soleur/skills/gdpr-gate/scripts/gdpr-gate.sh {staged_files}
|
|
26
|
+
|
|
27
|
+
set -euo pipefail
|
|
28
|
+
|
|
29
|
+
# Refuse to run under `set -x` while a live credential is in the environment
|
|
30
|
+
# (#7797). An xtrace of this script echoes every expansion, and the token would
|
|
31
|
+
# land in whatever captured that trace — a CI log, a `bash -x` debugging
|
|
32
|
+
# session, a pasted transcript. Placed immediately after `set` so nothing
|
|
33
|
+
# credential-bearing executes ahead of it.
|
|
34
|
+
case "$-" in
|
|
35
|
+
*x*)
|
|
36
|
+
if [ -n "${GH_TOKEN:+x}${GITHUB_TOKEN:+x}" ]; then
|
|
37
|
+
printf '[FATAL] refusing to trace with a live credential set (see #7797)\n' >&2
|
|
38
|
+
exit 78
|
|
39
|
+
fi
|
|
40
|
+
;;
|
|
41
|
+
esac
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
# REPO_ROOT was REMOVED here (#7450 round-2 review). After `NOTICE_PARSER` moved to
|
|
45
|
+
# $BASH_SOURCE-relative resolution it had ZERO remaining expansions, leaving a bare
|
|
46
|
+
# `git rev-parse --show-toplevel` as the only statement in this file that could abort the
|
|
47
|
+
# run: it sits under `set -euo pipefail`, and this gate is documented at the top as
|
|
48
|
+
# "always exits 0 ... never blocking". It fails on a non-repo CWD, a broken .git worktree
|
|
49
|
+
# pointer, or a `safe.directory` ownership refusal — all routine on a fresh install or a
|
|
50
|
+
# container mount — and would have aborted the operator's `git commit` via lefthook.
|
|
51
|
+
|
|
52
|
+
# Source telemetry helper if present. Downstream installs of the Soleur plugin
|
|
53
|
+
# may not ship .claude/hooks/lib/incidents.sh — preserve the always-exit-0
|
|
54
|
+
# advisory contract by no-op'ing emit_incident in that case rather than
|
|
55
|
+
# letting `set -e` abort before the breadcrumb.
|
|
56
|
+
#
|
|
57
|
+
# CODE ROOT, not a data root (#7450; ADR-179's classification). This path gets
|
|
58
|
+
# SOURCED, so it executes in THIS shell — and it must therefore never be derived
|
|
59
|
+
# from `git rev-parse --show-toplevel`, which on the review path resolves to the
|
|
60
|
+
# contributor's checked-out tree. `review/SKILL.md` instructs `gh pr checkout`,
|
|
61
|
+
# and this script is itself a compliance gate, so a same-named file in a hostile
|
|
62
|
+
# PR would run with the gate's authority. CLAUDE_PROJECT_DIR is supplied by the
|
|
63
|
+
# harness rather than by the tree under review.
|
|
64
|
+
#
|
|
65
|
+
# There is no `REPO_ROOT` in this file any more (see above). Two successive revisions of
|
|
66
|
+
# this comment were wrong about it, and both are recorded because the second was written
|
|
67
|
+
# to correct the first:
|
|
68
|
+
# 1. It first claimed every remaining `REPO_ROOT` use was a data-root read. FALSE —
|
|
69
|
+
# `NOTICE_PARSER` below is EXECUTED (a code root by this ADR's classification) and was
|
|
70
|
+
# resolved from it, with `GH_TOKEN` exported into the child. On the review path that
|
|
71
|
+
# handed a GitHub token to a contributor-supplied script from inside the compliance
|
|
72
|
+
# gate, in the very file edited to remove that vector.
|
|
73
|
+
# 2. The correction then claimed `REPO_ROOT` "stays for data-root reads". Also FALSE —
|
|
74
|
+
# once `NOTICE_PARSER` moved to $BASH_SOURCE-relative there were no reads left at all,
|
|
75
|
+
# so the assignment was dead code that could still abort the operator's commit.
|
|
76
|
+
# Resolution, in trust order, and NEVER from `git rev-parse --show-toplevel`:
|
|
77
|
+
# 1. CLAUDE_PROJECT_DIR — supplied by the harness, not by the tree under review.
|
|
78
|
+
# Measured 2026-08-12: unset in a plain Claude Code session and in git hooks,
|
|
79
|
+
# so it cannot be the ONLY arm without silently retiring this telemetry.
|
|
80
|
+
# 2. This script's OWN location. Layout-invariant per ADR-178, and crucially NOT
|
|
81
|
+
# CWD-derived: a `gh pr checkout` cannot redirect it, because by the time this
|
|
82
|
+
# line runs the anchor decision has already been made — if a hostile script
|
|
83
|
+
# were executing, sourcing its sibling lib adds nothing. On a plugin INSTALL
|
|
84
|
+
# the walk lands somewhere with no such lib, so it no-ops, which is correct.
|
|
85
|
+
# The `-f` test is the safety net for both arms: a wrong root simply no-ops.
|
|
86
|
+
_incidents_root="${CLAUDE_PROJECT_DIR:-$(cd -P "$(dirname "${BASH_SOURCE[0]}")/../../../../.." 2>/dev/null && pwd -P)}"
|
|
87
|
+
INCIDENTS_LIB="${_incidents_root:+${_incidents_root}/.claude/hooks/lib/incidents.sh}"
|
|
88
|
+
if [[ -n "$INCIDENTS_LIB" && -f "$INCIDENTS_LIB" ]]; then
|
|
89
|
+
# shellcheck source=/dev/null
|
|
90
|
+
source "$INCIDENTS_LIB"
|
|
91
|
+
else
|
|
92
|
+
emit_incident() { :; }
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
# Runtime staleness check (FR6 / TR2 / TR6).
|
|
96
|
+
#
|
|
97
|
+
# The gdpr-gate skill is partially driven by detection rules lifted from
|
|
98
|
+
# upstream gosprinto/compliance-skills (see plugins/soleur/skills/gdpr-gate/NOTICE).
|
|
99
|
+
# When the cron-driven re-vendor pipeline silently breaks (workflow disabled,
|
|
100
|
+
# GH outage, PR queued), the lifted rules go stale and the gate's
|
|
101
|
+
# "no findings" output becomes a false-clean signal on regulated PRs.
|
|
102
|
+
# The runtime banner is the load-bearing user-protection layer in that case.
|
|
103
|
+
#
|
|
104
|
+
# Banner emits to STDOUT (not stderr) — agent runtimes commonly swallow stderr.
|
|
105
|
+
# Gate exits 0 in all paths (advisory contract preserved).
|
|
106
|
+
# Subshell-exec (not source) so parser failure / deletion / future date all
|
|
107
|
+
# resolve to days_stale=999 → banner fires → gate stays advisory.
|
|
108
|
+
#
|
|
109
|
+
# Trust-binding (#3535): invoke parser twice and compute MIN in the caller
|
|
110
|
+
# frame. NOTICE last-verified is operator-controlled (a PR can backdate it);
|
|
111
|
+
# the content-vendor-drift cron's run timestamp is not. Taking the MIN ensures
|
|
112
|
+
# a fresh-looking last-verified cannot suppress a stale-cron banner.
|
|
113
|
+
# NOTICE_FILE and GH_TOKEN propagate explicitly — Bash subshell-exec does NOT
|
|
114
|
+
# inherit them otherwise. Operator-attested-mode banner fires only when the
|
|
115
|
+
# cron binding is unavailable AND last-verified is parseable — when both are
|
|
116
|
+
# 999 the existing 30d/90d banners cover the case.
|
|
117
|
+
#
|
|
118
|
+
# The cron half of this binding was inert from the Inngest migration until
|
|
119
|
+
# #7255 fixed the probe: `cron_days_stale` then resolved to 999 on every call
|
|
120
|
+
# because the query targeted a deleted GHA workflow, and the MIN below was
|
|
121
|
+
# always MIN(notice, 999) == notice — the fail-safe direction, which is why
|
|
122
|
+
# it went unnoticed. The probe now reads the check's own GitHub artifact
|
|
123
|
+
# (the `ci/vendor-attest-*` PR the cron writes each run — see the DATA SOURCE
|
|
124
|
+
# comment in `notice-frontmatter.sh` `cmd_cron_run_stale`), so the
|
|
125
|
+
# anti-backdating property described above is in force again whenever a
|
|
126
|
+
# token is present.
|
|
127
|
+
# SIBLING of this script, so it needs no root at all: `$BASH_SOURCE`-relative is
|
|
128
|
+
# layout-invariant (ADR-178) and leaves NO operand for a checked-out tree to shadow —
|
|
129
|
+
# strictly better here than any root-anchored form, including CLAUDE_PROJECT_DIR.
|
|
130
|
+
# It was `"$REPO_ROOT/plugins/soleur/…"` (i.e. `git rev-parse --show-toplevel`) until
|
|
131
|
+
# #7450 review: EXECUTED below, three times, once with GH_TOKEN exported to the child.
|
|
132
|
+
NOTICE_PARSER="$(cd -P "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd -P)/notice-frontmatter.sh"
|
|
133
|
+
notice_days_stale=$(NOTICE_FILE="${NOTICE_FILE:-}" \
|
|
134
|
+
bash "$NOTICE_PARSER" days-stale 2>/dev/null || echo 999)
|
|
135
|
+
cron_days_stale=$(NOTICE_FILE="${NOTICE_FILE:-}" \
|
|
136
|
+
GH_TOKEN="${GH_TOKEN:-${GITHUB_TOKEN:-}}" \
|
|
137
|
+
bash "$NOTICE_PARSER" cron-run-stale 2>/dev/null || echo 999)
|
|
138
|
+
|
|
139
|
+
# MIN-of-both compute (caller frame — Bash env exports drop across the
|
|
140
|
+
# subshell-exec boundary, so the comparison must live here).
|
|
141
|
+
if [[ "$cron_days_stale" != "999" && "$notice_days_stale" != "999" ]]; then
|
|
142
|
+
if (( cron_days_stale < notice_days_stale )); then
|
|
143
|
+
days_stale="$cron_days_stale"
|
|
144
|
+
emit_incident gdpr-gate-cron-binding min-wins \
|
|
145
|
+
"cron=${cron_days_stale} notice=${notice_days_stale}" \
|
|
146
|
+
2>/dev/null || true
|
|
147
|
+
else
|
|
148
|
+
days_stale="$notice_days_stale"
|
|
149
|
+
emit_incident gdpr-gate-cron-binding applied \
|
|
150
|
+
"cron=${cron_days_stale} notice=${notice_days_stale}" \
|
|
151
|
+
2>/dev/null || true
|
|
152
|
+
fi
|
|
153
|
+
elif [[ "$cron_days_stale" != "999" ]]; then
|
|
154
|
+
days_stale="$cron_days_stale"
|
|
155
|
+
emit_incident gdpr-gate-cron-binding applied \
|
|
156
|
+
"cron-only=${cron_days_stale}" 2>/dev/null || true
|
|
157
|
+
else
|
|
158
|
+
days_stale="$notice_days_stale"
|
|
159
|
+
fi
|
|
160
|
+
|
|
161
|
+
last_verified=$(NOTICE_FILE="${NOTICE_FILE:-}" \
|
|
162
|
+
bash "$NOTICE_PARSER" field last-verified 2>/dev/null || echo "unknown")
|
|
163
|
+
[[ -n "$last_verified" ]] || last_verified="unknown"
|
|
164
|
+
if (( days_stale > 30 )); then
|
|
165
|
+
printf '⚠ gdpr-gate rules %s days stale (last verified %s) — output is advisory only and may miss recently-patched detection rules. Refresh: see "Corpus freshness" in this skill'"'"'s SKILL.md.\n' \
|
|
166
|
+
"$days_stale" "$last_verified"
|
|
167
|
+
emit_incident gdpr-gate-staleness warn "${days_stale}-days-stale" \
|
|
168
|
+
2>/dev/null || true
|
|
169
|
+
fi
|
|
170
|
+
if (( days_stale > 90 )); then
|
|
171
|
+
printf 'POSTURE_FAIL: gdpr-gate rules >90 days stale — compliance/critical posture row required. Operator chain: see "POSTURE_FAIL operator chain" in this skill'"'"'s SKILL.md.\n'
|
|
172
|
+
emit_incident gdpr-gate-staleness deny "${days_stale}-days-stale-posture-fail" \
|
|
173
|
+
2>/dev/null || true
|
|
174
|
+
fi
|
|
175
|
+
|
|
176
|
+
# Single source of truth — mirrors SKILL.md §"Path globs (canonical)".
|
|
177
|
+
CANONICAL_REGEX='^(apps/web-platform/supabase/migrations/|apps/web-platform/lib/auth/|apps/web-platform/server/.*auth.*\.(ts|tsx|js)|apps/web-platform/app/api/.*\.(ts|tsx)$|.*\.sql$)'
|
|
178
|
+
|
|
179
|
+
matched=()
|
|
180
|
+
examined=0
|
|
181
|
+
# DEDUPE BY PATH. lefthook passes a path once PER MATCHING GLOB, not once per
|
|
182
|
+
# staged file, and the `gdpr-gate-advisory` stanza carries overlapping globs by
|
|
183
|
+
# construction: in gobwas a single `*` CROSSES `/`, so
|
|
184
|
+
# `apps/web-platform/lib/auth/*.ts` already matches a nested file that
|
|
185
|
+
# `apps/web-platform/lib/auth/**/*.ts` also matches, and bare `*.sql` already
|
|
186
|
+
# matches `apps/web-platform/supabase/migrations/*.sql`.
|
|
187
|
+
#
|
|
188
|
+
# Measured against real lefthook 2 on the real stanza's shape: three staged
|
|
189
|
+
# files — one SQL migration, one nested auth module, one nested API route —
|
|
190
|
+
# arrive as SIX arguments. The two most common regulated shapes in this repo
|
|
191
|
+
# are therefore ALWAYS doubled, so the un-deduped line told a customer who
|
|
192
|
+
# staged one migration that two paths were examined. That is the wrong number
|
|
193
|
+
# on the one artifact this change exists to produce.
|
|
194
|
+
#
|
|
195
|
+
# Deduping HERE rather than by trimming the glob list is deliberate: the
|
|
196
|
+
# script must report what it examined whatever it is handed, and a future
|
|
197
|
+
# overlapping glob must not be able to re-break the count. `seen` is keyed on
|
|
198
|
+
# the literal argument, so a genuine repeat on one command line collapses too
|
|
199
|
+
# — which is correct, it is the same file.
|
|
200
|
+
declare -A _gdpr_seen=()
|
|
201
|
+
for f in "$@"; do
|
|
202
|
+
[[ -n "${_gdpr_seen[$f]+x}" ]] && continue
|
|
203
|
+
_gdpr_seen["$f"]=1
|
|
204
|
+
examined=$((examined + 1))
|
|
205
|
+
if [[ "$f" =~ $CANONICAL_REGEX ]]; then
|
|
206
|
+
matched+=("$f")
|
|
207
|
+
fi
|
|
208
|
+
done
|
|
209
|
+
|
|
210
|
+
# Scan-completion line (#7710). UNCONDITIONAL and AFTER the loop, reporting
|
|
211
|
+
# what the loop actually counted.
|
|
212
|
+
#
|
|
213
|
+
# Before this line existed, "the scan ran and matched nothing" and "the scan
|
|
214
|
+
# never ran" produced byte-identical output — nothing at all. On a corpus
|
|
215
|
+
# past the 90-day threshold the gate printed a staleness banner and a
|
|
216
|
+
# POSTURE_FAIL and no evidence that any path had been examined, so the
|
|
217
|
+
# refusal read as the whole output and a reader could not tell a healthy
|
|
218
|
+
# no-findings scan from a gate that never looked. That is the defect #7710
|
|
219
|
+
# reported, and it is why this line must NOT be gated on
|
|
220
|
+
# `${#matched[@]} > 0`: the zero-match case is precisely the state the
|
|
221
|
+
# property forbids being silent about.
|
|
222
|
+
#
|
|
223
|
+
# STDOUT, because agent runtimes commonly swallow stderr — the same reason
|
|
224
|
+
# the staleness banners are on stdout. The path-naming breadcrumb below stays
|
|
225
|
+
# on stderr.
|
|
226
|
+
#
|
|
227
|
+
# COUNTS ONLY, never path names: this line goes to a customer's terminal, and
|
|
228
|
+
# path structure is third-party-content-adjacent
|
|
229
|
+
# (hr-third-party-content-grep-on-undertaking; #7331 is the live scar). The
|
|
230
|
+
# stderr breadcrumb already names paths for the local operator.
|
|
231
|
+
#
|
|
232
|
+
# It carries neither `days stale` nor `POSTURE_FAIL`, so its presence is
|
|
233
|
+
# independent of the corpus's freshness state. That independence is the
|
|
234
|
+
# point: the evidence that a scan occurred must not be entangled with the
|
|
235
|
+
# age of the rules the scan used. It also keeps the existing negative
|
|
236
|
+
# assertions on those two strings able to witness a banner regression.
|
|
237
|
+
printf 'gdpr-gate: path scan complete — %d examined, %d matched\n' \
|
|
238
|
+
"$examined" "${#matched[@]}"
|
|
239
|
+
|
|
240
|
+
if (( ${#matched[@]} > 0 )); then
|
|
241
|
+
echo "gdpr-gate: regulated-data path touched (${matched[*]}); run /soleur:gdpr-gate" >&2
|
|
242
|
+
emit_incident hr-gdpr-gate-on-regulated-data-surfaces applied \
|
|
243
|
+
"regulated-data path touched: ${matched[0]}" 2>/dev/null || true
|
|
244
|
+
|
|
245
|
+
# Operator-attested-mode banner — fires ONLY when (a) a regulated path is
|
|
246
|
+
# being judged this commit AND (b) the cron binding is unavailable but
|
|
247
|
+
# NOTICE last-verified is parseable.
|
|
248
|
+
#
|
|
249
|
+
# The #3541 relevance property is real, but this conditional is not what
|
|
250
|
+
# delivers it, and the previous wording here was false (#7710). It claimed
|
|
251
|
+
# that without the matched-path gate the banner "would fire on every
|
|
252
|
+
# commit". It would not: lefthook invokes this script only when a staged
|
|
253
|
+
# path matches the `gdpr-gate-advisory` glob, so on the pre-commit path
|
|
254
|
+
# relevance is already bought by the glob and this conditional is a second,
|
|
255
|
+
# narrower filter over an already-filtered set.
|
|
256
|
+
#
|
|
257
|
+
# What the conditional actually buys is relevance on the paths the glob does
|
|
258
|
+
# NOT gate: direct invocation, the CI self-test, and `/soleur:gdpr-gate`,
|
|
259
|
+
# where arbitrary arguments reach the script. That is a real property and
|
|
260
|
+
# worth keeping — it is simply a different one from the claim it replaced.
|
|
261
|
+
#
|
|
262
|
+
# Banner literal is load-bearing: the self-test asserts it verbatim. See
|
|
263
|
+
# review finding from user-impact-reviewer #3541.
|
|
264
|
+
if [[ "$cron_days_stale" == "999" && "$notice_days_stale" != "999" ]]; then
|
|
265
|
+
printf 'ℹ gdpr-gate: operator-attested mode (no GH_TOKEN available — cron-run timestamp unverified, falling back to NOTICE last-verified)\n'
|
|
266
|
+
emit_incident gdpr-gate-cron-binding unavailable \
|
|
267
|
+
"no-token-or-gh-cli" 2>/dev/null || true
|
|
268
|
+
fi
|
|
269
|
+
fi
|
|
270
|
+
|
|
271
|
+
exit 0
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# notice-frontmatter.sh — pure-bash parser for the NOTICE YAML frontmatter.
|
|
3
|
+
#
|
|
4
|
+
# Subcommands:
|
|
5
|
+
# field <name> Print scalar value (upstream, pinned-commit,
|
|
6
|
+
# last-verified, registry).
|
|
7
|
+
# days-stale Integer days since last-verified. Future date / parse
|
|
8
|
+
# fail / missing frontmatter all return 999 (treat as
|
|
9
|
+
# stale immediately, per plan TR2 + SpecFlow P1.5).
|
|
10
|
+
# Always exits 0 — the gdpr-gate hook subshell-execs this
|
|
11
|
+
# and depends on the always-exit-0 advisory contract.
|
|
12
|
+
# cron-run-stale Integer days since the content-vendor-drift check last
|
|
13
|
+
# produced its attestation artifact — the weekly
|
|
14
|
+
# `ci/vendor-attest-*` PR the Inngest cron writes on every
|
|
15
|
+
# completed run (ADR-203), read via `gh pr list --search
|
|
16
|
+
# head:ci/vendor-attest`. 999 on any failure mode (no
|
|
17
|
+
# GH_TOKEN, no gh CLI, network blocked, empty result,
|
|
18
|
+
# malformed timestamp, timeout). The `gdpr-gate.sh` caller
|
|
19
|
+
# computes MIN(days-stale, cron-run-stale) to defend
|
|
20
|
+
# against a backdated last-verified field (issue #3535).
|
|
21
|
+
# lifted-files One `<path>:<local-blob-sha>` per line. Local blob SHAs
|
|
22
|
+
# pin the file as it exists in this repo (post-attribution
|
|
23
|
+
# header) and are consumed by `vendor-pin-integrity.sh`.
|
|
24
|
+
# soleur-authored One `<path>:<local-blob-sha>` per line, for the reference
|
|
25
|
+
# files written from scratch for this plugin. Same record
|
|
26
|
+
# shape and same consumer as `lifted-files`, but no
|
|
27
|
+
# upstream provenance: these never appear in
|
|
28
|
+
# `upstream-files`. Pinning them keeps a tamper check on
|
|
29
|
+
# the files the gate's own GDPR framing depends on while
|
|
30
|
+
# leaving them editable through the normal update-the-pin
|
|
31
|
+
# flow (#7710).
|
|
32
|
+
# record-count <block>
|
|
33
|
+
# Integer count of `- path:` records DECLARED in the named
|
|
34
|
+
# block, regardless of whether each record is complete.
|
|
35
|
+
#
|
|
36
|
+
# This exists because every other view here is a FILTERED
|
|
37
|
+
# projection: `_emit_files` flushes a record only when BOTH
|
|
38
|
+
# its path key and its sha key are non-empty, so a record
|
|
39
|
+
# that loses `upstream-blob-sha` is silently absent from
|
|
40
|
+
# `upstream-files`. A consumer that derives "how many files
|
|
41
|
+
# should I have compared?" from that view is comparing the
|
|
42
|
+
# parser's output against itself — the denominator shrinks
|
|
43
|
+
# with the numerator and a partial comparison reads as
|
|
44
|
+
# complete (#7710 review). `record-count` is the
|
|
45
|
+
# unfiltered denominator.
|
|
46
|
+
# upstream-files One `<upstream-path>:<upstream-blob-sha>` per line.
|
|
47
|
+
# Upstream blob SHAs pin the file as it exists at
|
|
48
|
+
# `pinned-commit` and are consumed by the drift workflow.
|
|
49
|
+
#
|
|
50
|
+
# NOTICE location: $NOTICE_FILE if set, else <script-dir>/../NOTICE.
|
|
51
|
+
#
|
|
52
|
+
# `set -euo pipefail` is internal; subcommand wrappers catch failures so the
|
|
53
|
+
# caller (`gdpr-gate.sh`) can `bash notice-frontmatter.sh days-stale 2>/dev/null
|
|
54
|
+
# || echo 999` without aborting the gate on parser death.
|
|
55
|
+
#
|
|
56
|
+
# TR2: target p95 <50ms over 100 invocations of `days-stale`.
|
|
57
|
+
|
|
58
|
+
set -euo pipefail
|
|
59
|
+
|
|
60
|
+
# Refuse to run under `set -x` while a live credential is in the environment
|
|
61
|
+
# (#7797). An xtrace of this script echoes every expansion, and the token would
|
|
62
|
+
# land in whatever captured that trace — a CI log, a `bash -x` debugging
|
|
63
|
+
# session, a pasted transcript. Placed immediately after `set` so nothing
|
|
64
|
+
# credential-bearing executes ahead of it.
|
|
65
|
+
case "$-" in
|
|
66
|
+
*x*)
|
|
67
|
+
if [ -n "${GH_TOKEN:+x}${GITHUB_TOKEN:+x}" ]; then
|
|
68
|
+
printf '[FATAL] refusing to trace with a live credential set (see #7797)\n' >&2
|
|
69
|
+
exit 78
|
|
70
|
+
fi
|
|
71
|
+
;;
|
|
72
|
+
esac
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
76
|
+
NOTICE_FILE="${NOTICE_FILE:-$SCRIPT_DIR/../NOTICE}"
|
|
77
|
+
|
|
78
|
+
# Print only the YAML body between the first two `---` lines.
|
|
79
|
+
# Returns empty + exit 1 if no frontmatter.
|
|
80
|
+
extract_frontmatter() {
|
|
81
|
+
[[ -f "$NOTICE_FILE" ]] || return 1
|
|
82
|
+
awk '
|
|
83
|
+
BEGIN { count=0; in_fm=0 }
|
|
84
|
+
/^---[[:space:]]*$/ {
|
|
85
|
+
count++
|
|
86
|
+
if (count == 1) { in_fm = 1; next }
|
|
87
|
+
if (count == 2) { in_fm = 0; exit }
|
|
88
|
+
}
|
|
89
|
+
in_fm { print }
|
|
90
|
+
END { if (count < 2) exit 1 }
|
|
91
|
+
' "$NOTICE_FILE"
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
cmd_field() {
|
|
95
|
+
local name="$1"
|
|
96
|
+
local fm
|
|
97
|
+
fm=$(extract_frontmatter) || return 1
|
|
98
|
+
[[ -n "$fm" ]] || return 1
|
|
99
|
+
# Match top-level scalar lines (`<name>: <value>`); skip indented (nested).
|
|
100
|
+
printf '%s\n' "$fm" | awk -v key="$name" '
|
|
101
|
+
/^[[:space:]]/ { next }
|
|
102
|
+
{
|
|
103
|
+
idx = index($0, ":")
|
|
104
|
+
if (idx == 0) next
|
|
105
|
+
k = substr($0, 1, idx - 1)
|
|
106
|
+
v = substr($0, idx + 1)
|
|
107
|
+
sub(/^[[:space:]]+/, "", v)
|
|
108
|
+
sub(/[[:space:]]+$/, "", v)
|
|
109
|
+
if (k == key) { print v; exit }
|
|
110
|
+
}
|
|
111
|
+
'
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
cmd_days_stale() {
|
|
115
|
+
local last_verified last_epoch today_epoch days
|
|
116
|
+
last_verified=$(cmd_field last-verified 2>/dev/null) || { echo 999; return 0; }
|
|
117
|
+
[[ -n "$last_verified" ]] || { echo 999; return 0; }
|
|
118
|
+
# Strict ISO-8601 date guard. `date -d` otherwise accepts "now",
|
|
119
|
+
# "yesterday", etc., letting a malicious NOTICE PR set last-verified to
|
|
120
|
+
# any natural-language value and pin days-stale at 0 forever.
|
|
121
|
+
[[ "$last_verified" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]] || { echo 999; return 0; }
|
|
122
|
+
# Anchor to UTC midnight so the comparison against `date -u +%s` is
|
|
123
|
+
# consistent across timezones (otherwise a UTC+12 host computes a day
|
|
124
|
+
# off the UTC-anchored today_epoch).
|
|
125
|
+
last_epoch=$(date -u -d "${last_verified}T00:00:00Z" +%s 2>/dev/null) || { echo 999; return 0; }
|
|
126
|
+
today_epoch=$(date -u +%s)
|
|
127
|
+
days=$(( (today_epoch - last_epoch) / 86400 ))
|
|
128
|
+
# Future date → treat as stale immediately (per SpecFlow P1.5).
|
|
129
|
+
if (( days < 0 )); then
|
|
130
|
+
echo 999
|
|
131
|
+
else
|
|
132
|
+
echo "$days"
|
|
133
|
+
fi
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
_emit_files() {
|
|
137
|
+
# Args: $1 = block-key ("lifted-files" | "soleur-authored"), $2 = path-key
|
|
138
|
+
# ("path" | "upstream-path"), $3 = sha-key ("local-blob-sha" |
|
|
139
|
+
# "upstream-blob-sha"). Walks the named block and prints
|
|
140
|
+
# `<path-value>:<sha-value>` per entry.
|
|
141
|
+
#
|
|
142
|
+
# The block key is a parameter rather than a literal because the registry
|
|
143
|
+
# has TWO lists with the same record shape and opposite provenance
|
|
144
|
+
# (#7710): upstream-derived files in `lifted-files`, Soleur-authored files
|
|
145
|
+
# in `soleur-authored`. Both are pinned by `local-blob-sha` and both are
|
|
146
|
+
# checked by vendor-pin-integrity.sh; only the former carries an upstream
|
|
147
|
+
# SHA, so only the former is a valid input to `upstream-files`.
|
|
148
|
+
local block_key="$1"
|
|
149
|
+
local path_key="$2"
|
|
150
|
+
local sha_key="$3"
|
|
151
|
+
local fm
|
|
152
|
+
fm=$(extract_frontmatter) || return 0
|
|
153
|
+
[[ -n "$fm" ]] || return 0
|
|
154
|
+
printf '%s\n' "$fm" | awk -v block_key="$block_key" -v path_key="$path_key" -v sha_key="$sha_key" '
|
|
155
|
+
BEGIN { in_block=0; cur_path=""; cur_sha="" }
|
|
156
|
+
$0 ~ "^" block_key ":[[:space:]]*$" { in_block=1; next }
|
|
157
|
+
/^[A-Za-z]/ { in_block=0 }
|
|
158
|
+
in_block {
|
|
159
|
+
line = $0
|
|
160
|
+
sub(/^[[:space:]]+/, "", line)
|
|
161
|
+
n = split(line, tok, /[[:space:]]+/)
|
|
162
|
+
# New entry sentinel: `- path: <value>` always opens a record. Flush
|
|
163
|
+
# the previous record before starting the new one.
|
|
164
|
+
# Normalize `key : value` (YAML-legal space-before-colon) to `key:`.
|
|
165
|
+
# Without this, tok[1] is the bare key and tok[2] is `:`, silently
|
|
166
|
+
# dropping the entry from the registry view.
|
|
167
|
+
sub(/[[:space:]]+:[[:space:]]+/, ": ", line)
|
|
168
|
+
n = split(line, tok, /[[:space:]]+/)
|
|
169
|
+
if (n >= 3 && tok[1] == "-" && tok[2] == "path:") {
|
|
170
|
+
if (cur_path != "" && cur_sha != "") print cur_path ":" cur_sha
|
|
171
|
+
cur_path = ""
|
|
172
|
+
cur_sha = ""
|
|
173
|
+
if (path_key == "path") cur_path = tok[3]
|
|
174
|
+
} else if (n >= 2 && tok[1] == path_key ":") {
|
|
175
|
+
# tok layout for `path:` and `upstream-path:` lines without leading dash.
|
|
176
|
+
cur_path = tok[2]
|
|
177
|
+
} else if (n >= 2 && tok[1] == sha_key ":") {
|
|
178
|
+
cur_sha = tok[2]
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
END {
|
|
182
|
+
if (cur_path != "" && cur_sha != "") print cur_path ":" cur_sha
|
|
183
|
+
}
|
|
184
|
+
'
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
cmd_cron_run_stale() {
|
|
188
|
+
# Days since the content-vendor-drift check last produced its attestation
|
|
189
|
+
# artifact. Always exits 0 — any failure mode (no token, no gh, network
|
|
190
|
+
# blocked, empty result, malformed timestamp, non-zero clock skew) resolves
|
|
191
|
+
# to 999 so the caller's subshell-exec contract holds. Wrap the network call
|
|
192
|
+
# with `timeout 5s` to bound the runtime-banner wall clock.
|
|
193
|
+
#
|
|
194
|
+
# DATA SOURCE (#7255). The check is the Inngest cron
|
|
195
|
+
# `apps/web-platform/server/inngest/functions/cron-content-vendor-drift.ts`
|
|
196
|
+
# — it has no GitHub Actions run, so a `gh run list` query can never see it
|
|
197
|
+
# (that is exactly how this probe once went dead at 999 with nobody
|
|
198
|
+
# noticing). What the run DOES leave behind on every completed execution is
|
|
199
|
+
# a GitHub artifact: the self-merging attestation PR on head branch
|
|
200
|
+
# `ci/vendor-attest-*` (`ATTEST_BRANCH_PREFIX` in the function file;
|
|
201
|
+
# ADR-203's unchanged-attestation machinery creates one even when zero
|
|
202
|
+
# files drift). "Days since the newest such PR was CREATED" is the honest
|
|
203
|
+
# "days since the check last ran to completion" — PR creation is the run's
|
|
204
|
+
# output, whereas mergedAt lags days behind the run and is unrelated to
|
|
205
|
+
# cron health.
|
|
206
|
+
#
|
|
207
|
+
# Query notes, both measured: `--state all` is load-bearing (the search
|
|
208
|
+
# treats merged/closed PRs correctly; a `--state merged` variant of this
|
|
209
|
+
# same query returned empty while the merged attest PR exists); and the
|
|
210
|
+
# `max` aggregation over `--limit 10` removes any dependence on
|
|
211
|
+
# search-result ordering. If this job's artifact moves again — new branch
|
|
212
|
+
# prefix, different substrate — the probe goes back to 999; the
|
|
213
|
+
# `TS-cron-argv` case in the notice-frontmatter suites pins the query shape
|
|
214
|
+
# so that regression is loud.
|
|
215
|
+
local token raw ts cron_epoch today_epoch days
|
|
216
|
+
token="${GH_TOKEN:-${GITHUB_TOKEN:-}}"
|
|
217
|
+
[[ -n "$token" ]] || { echo 999; return 0; }
|
|
218
|
+
command -v gh >/dev/null 2>&1 || { echo 999; return 0; }
|
|
219
|
+
# `// empty` collapses the empty result set to empty string.
|
|
220
|
+
# Belt-and-suspenders with the strict-ISO regex below — a softened guard
|
|
221
|
+
# alone would silently slip a null through.
|
|
222
|
+
raw=$(GH_TOKEN="$token" timeout 5s gh pr list \
|
|
223
|
+
--search "head:ci/vendor-attest" --state all --limit 10 \
|
|
224
|
+
--json createdAt --jq '[.[].createdAt] | max // empty' \
|
|
225
|
+
2>/dev/null) || { echo 999; return 0; }
|
|
226
|
+
ts="${raw%%[[:space:]]*}"
|
|
227
|
+
[[ -n "$ts" ]] || { echo 999; return 0; }
|
|
228
|
+
[[ "$ts" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ ]] \
|
|
229
|
+
|| { echo 999; return 0; }
|
|
230
|
+
cron_epoch=$(date -u -d "$ts" +%s 2>/dev/null) || { echo 999; return 0; }
|
|
231
|
+
today_epoch=$(date -u +%s)
|
|
232
|
+
days=$(( (today_epoch - cron_epoch) / 86400 ))
|
|
233
|
+
if (( days < 0 )); then echo 999; else echo "$days"; fi
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
cmd_lifted_files() {
|
|
237
|
+
_emit_files lifted-files path local-blob-sha
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
cmd_upstream_files() {
|
|
241
|
+
_emit_files lifted-files upstream-path upstream-blob-sha
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
cmd_record_count() {
|
|
245
|
+
# Count `- path:` record openers in the named block. Deliberately does NOT
|
|
246
|
+
# require the record to be complete: the whole point is to expose records
|
|
247
|
+
# that the filtered views drop.
|
|
248
|
+
local block_key="${1:-lifted-files}"
|
|
249
|
+
local fm
|
|
250
|
+
fm=$(extract_frontmatter) || { echo 0; return 0; }
|
|
251
|
+
[[ -n "$fm" ]] || { echo 0; return 0; }
|
|
252
|
+
printf '%s\n' "$fm" | awk -v block_key="$block_key" '
|
|
253
|
+
BEGIN { in_block=0; n=0 }
|
|
254
|
+
$0 ~ "^" block_key ":[[:space:]]*$" { in_block=1; next }
|
|
255
|
+
/^[A-Za-z]/ { in_block=0 }
|
|
256
|
+
in_block {
|
|
257
|
+
line = $0
|
|
258
|
+
sub(/^[[:space:]]+/, "", line)
|
|
259
|
+
sub(/[[:space:]]+:[[:space:]]+/, ": ", line)
|
|
260
|
+
n_tok = split(line, tok, /[[:space:]]+/)
|
|
261
|
+
if (n_tok >= 3 && tok[1] == "-" && tok[2] == "path:") n++
|
|
262
|
+
}
|
|
263
|
+
END { print n+0 }
|
|
264
|
+
'
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
cmd_key_count() {
|
|
268
|
+
# Count occurrences of a KEY inside the named block, independent of record
|
|
269
|
+
# boundaries.
|
|
270
|
+
#
|
|
271
|
+
# This exists as a SECOND, differently-derived view of the registry's size.
|
|
272
|
+
# `record-count` counts `- path:` openers, so it shares its record-opener
|
|
273
|
+
# predicate with `_emit_files` — which means deleting an OPENER line shrinks
|
|
274
|
+
# both views together and a completeness check comparing them holds while a
|
|
275
|
+
# record was silently absorbed into its predecessor (measured: declared 7,
|
|
276
|
+
# emitted 7, one record lost, #7710 review). Counting a key that every record
|
|
277
|
+
# carries but the opener predicate does NOT consume breaks that coupling.
|
|
278
|
+
local block_key="${1:-lifted-files}"
|
|
279
|
+
local want_key="${2:-status}"
|
|
280
|
+
local fm
|
|
281
|
+
fm=$(extract_frontmatter) || { echo 0; return 0; }
|
|
282
|
+
[[ -n "$fm" ]] || { echo 0; return 0; }
|
|
283
|
+
printf '%s\n' "$fm" | awk -v block_key="$block_key" -v want_key="$want_key" '
|
|
284
|
+
BEGIN { in_block=0; n=0 }
|
|
285
|
+
$0 ~ "^" block_key ":[[:space:]]*$" { in_block=1; next }
|
|
286
|
+
/^[A-Za-z]/ { in_block=0 }
|
|
287
|
+
in_block {
|
|
288
|
+
line = $0
|
|
289
|
+
sub(/^[[:space:]]+/, "", line)
|
|
290
|
+
sub(/[[:space:]]+:[[:space:]]+/, ": ", line)
|
|
291
|
+
split(line, tok, /[[:space:]]+/)
|
|
292
|
+
if (tok[1] == want_key ":") n++
|
|
293
|
+
}
|
|
294
|
+
END { print n+0 }
|
|
295
|
+
'
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
cmd_soleur_authored() {
|
|
299
|
+
# Soleur-authored reference files. These are NOT upstream-derived, so they
|
|
300
|
+
# carry a `local-blob-sha` only and never appear in `upstream-files` — a
|
|
301
|
+
# `lifted-files` row for one of them would attest goSprinto MIT provenance
|
|
302
|
+
# for Soleur's own writing, falsifying provenance in both directions.
|
|
303
|
+
_emit_files soleur-authored path local-blob-sha
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
case "${1:-}" in
|
|
307
|
+
field)
|
|
308
|
+
cmd_field "${2:-}" || true
|
|
309
|
+
;;
|
|
310
|
+
days-stale)
|
|
311
|
+
cmd_days_stale
|
|
312
|
+
;;
|
|
313
|
+
cron-run-stale)
|
|
314
|
+
cmd_cron_run_stale
|
|
315
|
+
;;
|
|
316
|
+
lifted-files)
|
|
317
|
+
cmd_lifted_files
|
|
318
|
+
;;
|
|
319
|
+
soleur-authored)
|
|
320
|
+
cmd_soleur_authored
|
|
321
|
+
;;
|
|
322
|
+
record-count)
|
|
323
|
+
cmd_record_count "${2:-lifted-files}"
|
|
324
|
+
;;
|
|
325
|
+
key-count)
|
|
326
|
+
cmd_key_count "${2:-lifted-files}" "${3:-status}"
|
|
327
|
+
;;
|
|
328
|
+
upstream-files)
|
|
329
|
+
cmd_upstream_files
|
|
330
|
+
;;
|
|
331
|
+
*)
|
|
332
|
+
echo "Usage: $0 {field <name>|days-stale|cron-run-stale|lifted-files|soleur-authored|upstream-files|record-count [block]|key-count [block] [key]}" >&2
|
|
333
|
+
exit 2
|
|
334
|
+
;;
|
|
335
|
+
esac
|
|
336
|
+
|
|
337
|
+
exit 0
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# gdpr-gate `--repo-scan` path deny-list.
|
|
2
|
+
#
|
|
3
|
+
# Single source of truth for paths the repo-scan walker MUST NOT read or
|
|
4
|
+
# forward to the model. Every pattern below is a bash `[[ =~ ]]` extended
|
|
5
|
+
# regex — NOT a shell glob. Patterns that look like globs (e.g. `*.pem`)
|
|
6
|
+
# silently fail to match.
|
|
7
|
+
#
|
|
8
|
+
# `repo-scan.sh` sets `LC_ALL=POSIX` for locale-determinism, but contributors
|
|
9
|
+
# editing patterns should still verify on both Linux and macOS — character
|
|
10
|
+
# classes for non-ASCII bytes still differ between bash builds.
|
|
11
|
+
#
|
|
12
|
+
# Format:
|
|
13
|
+
# - One pattern per line.
|
|
14
|
+
# - `#` lines are comments. Blank lines ignored.
|
|
15
|
+
# - Patterns are matched against the path as `git ls-files` reports it
|
|
16
|
+
# (relative to the repo root, forward-slash-separated, no leading `./`).
|
|
17
|
+
#
|
|
18
|
+
# v2 surface (7 patterns, verified at plan-write time per AC-DENYLIST-2):
|
|
19
|
+
# 1. .env* / .envrc at any depth — NFR-014 explicit. Pattern covers
|
|
20
|
+
# `.env`, `.env.local`, `.env.production`,
|
|
21
|
+
# `.envrc` (direnv files often hold
|
|
22
|
+
# `export KEY=...` lines).
|
|
23
|
+
# 2. secrets/ at any depth — defense-in-depth; intent-driven name.
|
|
24
|
+
# 3. .pem / .key / .crt / etc. — defense-in-depth; private-key shapes.
|
|
25
|
+
# Matched case-insensitively by repo-scan.sh
|
|
26
|
+
# (`shopt -s nocasematch`) so `.PEM`/`.KEY`
|
|
27
|
+
# filenames are also blocked.
|
|
28
|
+
# 4. test snapshot/golden dirs — realistic-shape fixtures.
|
|
29
|
+
# 5. web-platform test fixtures — known fixture root.
|
|
30
|
+
# 6. skill reference catalogues — gate's own layer files.
|
|
31
|
+
# 7. plan / spec markdown — design docs, not regulated data.
|
|
32
|
+
|
|
33
|
+
(^|/)\.env(\.[^/]*|rc)?$
|
|
34
|
+
(^|/)secrets/
|
|
35
|
+
\.(pem|key|crt|p8|pfx|jks|keystore|asc|ppk)$
|
|
36
|
+
(^|/)__synthesized__/|(^|/)__goldens__/|(^|/)__snapshots__/|\.snap$
|
|
37
|
+
^apps/web-platform/test/fixtures/
|
|
38
|
+
^plugins/soleur/skills/[^/]+/references/
|
|
39
|
+
^knowledge-base/(project/)?(plans|specs)/.*\.md$
|