@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,444 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# The /ship Phase 5.5 Technical-Ruling Gate (hard rule hr-technical-fork-is-not-an-operator-question).
|
|
3
|
+
#
|
|
4
|
+
# Property: no PR reaches ready with a decision-challenges.md or PR-body line that asks the operator a
|
|
5
|
+
# TECHNICAL question. Every row of the artifact's `| Item | Class | Ruling |` tables has a valid class;
|
|
6
|
+
# every `technical` row carries a `Ruled by CTO|CLO agent, <date>:` cell; no `pending - assumed`
|
|
7
|
+
# placeholder survives; and the "Owner decision needed" / "Owner ruling needed" label appears only with
|
|
8
|
+
# `(operator: <category>)`. The gate checks FORM, never truth: a model that mislabels a technical
|
|
9
|
+
# question as `operator (scope)` still passes (a stated residual, technical-ruling-delegation.md
|
|
10
|
+
# section 6); the check on that is review and the operator-visible rendering of operator rows.
|
|
11
|
+
#
|
|
12
|
+
# Usage:
|
|
13
|
+
# technical-ruling-gate.sh <path> check one decision-challenges.md
|
|
14
|
+
# technical-ruling-gate.sh --branch check this branch's artifact under
|
|
15
|
+
# knowledge-base/project/specs/<branch>/, or under
|
|
16
|
+
# specs/archive/<date>-<slug>/ when archived early;
|
|
17
|
+
# an absent artifact is `[PASS] no decision-challenges artifact`
|
|
18
|
+
# technical-ruling-gate.sh --pr-body <file> check a PR body for an unscoped owner-decision label
|
|
19
|
+
# or a surviving `pending - assumed` placeholder
|
|
20
|
+
#
|
|
21
|
+
# Exit codes:
|
|
22
|
+
# 0 every examined row passes (`[PASS]` on stdout). An artifact with NO table is `[WARN]` + exit 0
|
|
23
|
+
# (legacy artifacts and in-flight branches are not blocked); the label and `pending` lints still run.
|
|
24
|
+
# 1 at least one failure (`[FAIL] <path>:<line>: <reason> - <remedy>` on stderr, one per finding;
|
|
25
|
+
# <line> is always a line of the checked file)
|
|
26
|
+
# 2 could not measure: usage error, an unreadable or EMPTY artifact or PR body (whitespace only counts as
|
|
27
|
+
# empty), a table header with 0 data rows, a header that looks like the Decision Classes header (a
|
|
28
|
+
# separator line follows it) but is not exactly `| Item | Class | Ruling |`, a row whose Class is
|
|
29
|
+
# `technical` that sits OUTSIDE any recognised table (a row after a blank line, a header-less table),
|
|
30
|
+
# an unclosed code fence in the artifact or the PR body (everything after it would be hidden), or an
|
|
31
|
+
# ambiguous archive match. Never a silent pass on something that exists but was not examined.
|
|
32
|
+
#
|
|
33
|
+
# Table rules (GFM): a table ends at the first line that does not start with `|` (a blank line included);
|
|
34
|
+
# a row appended after a blank line is outside the table (a `technical` one is exit 2, never skipped). A
|
|
35
|
+
# later writer adds its own header+separator. Inline `code spans` are ignored by the label and pending
|
|
36
|
+
# lints (a PR that documents this machinery may quote the strings). A UTF-8 BOM is tolerated. Tables without
|
|
37
|
+
# a leading pipe, inside a blockquote or inside a list item are not recognised (residual: the stray-row
|
|
38
|
+
# check above catches a `technical` row there).
|
|
39
|
+
#
|
|
40
|
+
# Reasons (the suite asserts each): bad-class, bad-category, unruled-technical, bad-ruling-shape,
|
|
41
|
+
# owner-label-unscoped, delegation-invalid, delegation-unverifiable, receipt-missing, receipt-mismatch,
|
|
42
|
+
# receipt-unreadable.
|
|
43
|
+
#
|
|
44
|
+
# Delegation arm (ADR-289, hr-menu-option-ack-not-prod-write-auth): a row whose Class is exactly
|
|
45
|
+
# `operator (production-mutating)` and whose Ruling is
|
|
46
|
+
# Authorized by delegation <comment-url>, envelope <path>[, ran <ISO 8601 UTC time>]
|
|
47
|
+
# is validated through plugins/soleur/scripts/delegation-verify.sh. A row WITHOUT `ran` is an authorization for an
|
|
48
|
+
# act that has not happened: plain `verify` (expiry and an open epic are enforced now). A row WITH `ran` records an
|
|
49
|
+
# act that did: `verify --audit --at <time>` (the delegation must have been in force at that time; only a closed
|
|
50
|
+
# epic is forgiven), and the row must also be backed by an execution receipt on the epic: a comment whose FIRST line
|
|
51
|
+
# is `<!-- soleur-delegated-act v1 delegation=<url> envelope=<path> sha256=<verified-envelope-sha256> result=ok|rolled-back
|
|
52
|
+
# run=<url|none> -->`, written by an OWNER, MEMBER or COLLABORATOR, naming this row's delegation URL and envelope
|
|
53
|
+
# path, the sha256 the verifier just reported for that envelope, and a result of ok or rolled-back. Every field is
|
|
54
|
+
# compared EXACTLY, a missing author_association never defaults, and the receipt must lie inside the delegation's life
|
|
55
|
+
# (created at or after the delegation, not after the end of its expiry day, not in the future), must never have been
|
|
56
|
+
# edited (updated_at == created_at), must come from a User (not a bot), must be created at or after the `ran` instant it
|
|
57
|
+
# vouches for (a receipt posted in advance is no receipt), and satisfies at most ONE row (three rows
|
|
58
|
+
# cannot share one receipt). A `ran` time later than now is `delegation-invalid`. A delegation row needs a time-limit tool
|
|
59
|
+
# (timeout or gtimeout); without one it is `delegation-unverifiable`, never an unbounded call. That is all the check proves:
|
|
60
|
+
# a receipt exists, is attributable and matches the row. It is NOT proof of what ran (a receipt-checking
|
|
61
|
+
# hook on the executed command is the stronger follow-up, #10361). Missing, mismatching or unreadable receipts are
|
|
62
|
+
# `receipt-missing`, `receipt-mismatch`, `receipt-unreadable` (exit 2, never a pass).
|
|
63
|
+
# Verdicts: valid passes; invalid is `delegation-invalid` (exit 1); unverifiable, including a missing verifier or a
|
|
64
|
+
# verifier whose rc and first line disagree, is `delegation-unverifiable` (exit 2, never a pass). The same ruling
|
|
65
|
+
# shape on any other Class is `bad-ruling-shape`: a delegation authorizes only production-mutating acts. The row
|
|
66
|
+
# stays required (no row, no pass), every delegation row is examined (the first valid one does not end the scan),
|
|
67
|
+
# one verifier call per (delegation, envelope, time) and one receipt read per epic, and a delegation row outside a
|
|
68
|
+
# recognised table is exit 2. An ARCHIVED artifact (`--branch` found it under specs/archive/) is checked for row
|
|
69
|
+
# shape ONLY, with no network, and says so in its [NOTE] and [PASS] lines. A plain `operator (production-mutating)`
|
|
70
|
+
# row with no delegation text passes on form, as before. Format source:
|
|
71
|
+
# skills/brainstorm-techniques/references/standing-delegation.md.
|
|
72
|
+
#
|
|
73
|
+
# Test seams: TRG_VERIFY_TIMEOUT (seconds, 1-59: it can only SHORTEN the 60 s verifier limit), TRG_EXEC_LOG (append one line per examined row), TRG_SPECS_ROOT and TRG_BRANCH (the
|
|
74
|
+
# `--branch` lookup, so a suite needs no git repository); any of them being set is announced on stderr.
|
|
75
|
+
# Lines carrying `# mut:<name>` are the mutation points the suite edits to prove each check can fail.
|
|
76
|
+
#
|
|
77
|
+
# `set -uo pipefail`, deliberately NOT `-e`: the scanners are pipelines whose `grep` exits 1 on no match.
|
|
78
|
+
# Portable to bash 3.2 and to mawk (no `${var,,}`, no `sed -i`, no awk `{m,n}` intervals).
|
|
79
|
+
|
|
80
|
+
set -uo pipefail
|
|
81
|
+
export LC_ALL=C
|
|
82
|
+
shopt -s nocasematch
|
|
83
|
+
|
|
84
|
+
CATEGORIES="money scope priority schedule irreversible production-mutating legal-risk brand"
|
|
85
|
+
CATS_RE="${CATEGORIES// /|}"
|
|
86
|
+
LABEL_RE='owner[ \t-]+(decision|ruling)s?[ \t]+((is|are)[ \t]+)?(needed|required)|decision[ \t]+needed[ \t]+from[ \t]+the[ \t]+owner|needs?[ \t]+(the[ \t]+)?owner[ \t]+(decision|ruling)'
|
|
87
|
+
RULING_RE='^Ruled by (CTO|CLO) agent, [0-9]{4}-[0-9]{2}-[0-9]{2}: .+'
|
|
88
|
+
PENDING_RE='pending[ \t]*[^a-z0-9 \t]+[ \t]*assumed'
|
|
89
|
+
VERIFIER="$(cd -P "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)/../../../scripts/delegation-verify.sh"
|
|
90
|
+
|
|
91
|
+
# Shared context-sanitize lib (#10395), three levels up at scripts/lib/. When it
|
|
92
|
+
# is unreadable the same-name fallback carries this site's pre-change strip set
|
|
93
|
+
# (tr's [[:cntrl:]] class, under the ambient locale exactly as before — no
|
|
94
|
+
# LC_ALL=C pin, so the fallback never strips less than the site did) — never
|
|
95
|
+
# weaker than today.
|
|
96
|
+
_ctx_lib="$(cd -P "${BASH_SOURCE[0]%/*}/../../../scripts/lib" 2>/dev/null && pwd -P)/context-sanitize.sh"
|
|
97
|
+
_ctx_lib="${_ctx_lib:-/nonexistent/context-sanitize.sh}"
|
|
98
|
+
# shellcheck source=/dev/null
|
|
99
|
+
[[ -r "$_ctx_lib" ]] && . "$_ctx_lib" || true
|
|
100
|
+
declare -F soleur_ctx_sanitize >/dev/null 2>&1 \
|
|
101
|
+
|| soleur_ctx_sanitize() { tr -d '[:cntrl:]'; }
|
|
102
|
+
DELEG_RE='^Authorized by delegation (https://github\.com/([A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+)/(issues|pull)/([0-9]+)#issuecomment-[0-9]+), envelope ([A-Za-z0-9_./#@ -]+)(, ran ([0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z))?$'
|
|
103
|
+
SHAPE_ONLY=0
|
|
104
|
+
SHAPE_ROWS=0
|
|
105
|
+
DR=0
|
|
106
|
+
TOG=(); TOV=(); HAVE_TO=0; TOBIN=""
|
|
107
|
+
CONSUMED=""
|
|
108
|
+
if command -v timeout >/dev/null 2>&1; then TOBIN=timeout
|
|
109
|
+
elif command -v gtimeout >/dev/null 2>&1; then TOBIN=gtimeout; fi # mut:gtimeout
|
|
110
|
+
if [[ -n "$TOBIN" ]]; then
|
|
111
|
+
HAVE_TO=1
|
|
112
|
+
VT=60
|
|
113
|
+
case "${TRG_VERIFY_TIMEOUT:-}" in ''|*[!0-9]*) ;; *) [[ "$TRG_VERIFY_TIMEOUT" -ge 1 && "$TRG_VERIFY_TIMEOUT" -lt 60 ]] && VT="$TRG_VERIFY_TIMEOUT" ;; esac
|
|
114
|
+
TOG=("$TOBIN" 60); TOV=("$TOBIN" "$VT")
|
|
115
|
+
fi
|
|
116
|
+
CTO_REMEDY='spawn soleur:engineering:cto now (at most two attempts, see technical-ruling-delegation.md), write the Ruled by cell, re-run; after two failed attempts leave the PR draft and file one domain/engineering issue, never an operator question'
|
|
117
|
+
|
|
118
|
+
work_dir=""
|
|
119
|
+
UNCLOSED_SEEN=0
|
|
120
|
+
cleanup() { [[ -n "$work_dir" ]] && rm -rf "${work_dir:?}"; return 0; }
|
|
121
|
+
trap cleanup EXIT
|
|
122
|
+
|
|
123
|
+
cat_ok() { case " $CATEGORIES " in *" $1 "*) return 0 ;; esac; return 1; } # mut:cat
|
|
124
|
+
is_unruled() { [[ -z "$1" ]]; } # mut:unruled
|
|
125
|
+
shape_ok() { [[ "$1" =~ $RULING_RE ]]; } # mut:shape
|
|
126
|
+
|
|
127
|
+
die2() { printf '[ERROR] %s\n' "$*" >&2; cleanup; exit 2; }
|
|
128
|
+
|
|
129
|
+
# unfenced_match <file> <regex>: `<line>\t<text>` for every unfenced line whose lowercase form matches, with
|
|
130
|
+
# inline `code spans` removed first. A fence closes only on the same character, at least as long, with no info
|
|
131
|
+
# string (CommonMark); a backtick fence whose info string contains a backtick is inline code, not a fence.
|
|
132
|
+
# `@UNCLOSED` is printed when a fence is still open at end of file.
|
|
133
|
+
unfenced_match() {
|
|
134
|
+
awk -v re="$2" '
|
|
135
|
+
function fence_toggle( tok, c, n) {
|
|
136
|
+
tok = $0; sub(/^ +/, "", tok)
|
|
137
|
+
match(tok, /^(`+|~+)/); c = substr(tok, 1, 1); n = RLENGTH
|
|
138
|
+
if (!f) { if (c == "`" && substr(tok, n + 1) ~ /`/) return; f = 1; fc = c; fn = n; return }
|
|
139
|
+
if (c == fc && n >= fn && tok ~ /^(`+|~+)[ \t]*$/) f = 0
|
|
140
|
+
}
|
|
141
|
+
{ sub(/\r$/, ""); if (NR == 1) sub(/^\357\273\277/, "") }
|
|
142
|
+
/^ ? ? ?(```+|~~~+)/ { fence_toggle(); next } # mut:fence
|
|
143
|
+
f { next }
|
|
144
|
+
{ line = $0; gsub(/`[^`]*`/, "", line); if (tolower(line) ~ re) printf "%d\t%s\n", NR, $0 }
|
|
145
|
+
END { if (f) print "@UNCLOSED" }
|
|
146
|
+
' "$1"
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
# table_rows <file>: per unfenced `| Item | Class | Ruling |` header `@TABLE`, then `<line>\t<row>` per data
|
|
150
|
+
# row; `@EMPTY` for a table with no data row, `@BADHEADER` for a header-like row followed by a separator
|
|
151
|
+
# that is not exactly ours, `@STRAY` for a `technical` row outside any recognised table, `@UNCLOSED` when a
|
|
152
|
+
# code fence is still open at end of file.
|
|
153
|
+
table_rows() {
|
|
154
|
+
awk '
|
|
155
|
+
function fence_toggle( tok, c, n) {
|
|
156
|
+
tok = $0; sub(/^ +/, "", tok)
|
|
157
|
+
match(tok, /^(`+|~+)/); c = substr(tok, 1, 1); n = RLENGTH
|
|
158
|
+
if (!f) { if (c == "`" && substr(tok, n + 1) ~ /`/) return; f = 1; fc = c; fn = n; return }
|
|
159
|
+
if (c == fc && n >= fn && tok ~ /^(`+|~+)[ \t]*$/) f = 0
|
|
160
|
+
}
|
|
161
|
+
function end_table() { if ((state == 3 && rows_in == 0) || state == 2) print "@EMPTY"; state = 0 }
|
|
162
|
+
{ sub(/\r$/, ""); if (NR == 1) sub(/^\357\273\277/, "") }
|
|
163
|
+
/^ ? ? ?(```+|~~~+)/ { fence_toggle(); next } # mut:fence-table
|
|
164
|
+
f { next }
|
|
165
|
+
{ if (hdr_pending) { if ($0 ~ /^ ? ? ?\|[ :|-]+$/) print "@BADHEADER"; hdr_pending = 0 } }
|
|
166
|
+
{ if ((state != 3 || $0 !~ /^ ? ? ?\|/) && tolower($0) ~ /\|[ \t]*technical[ \t]*\|/) print "@STRAY" }
|
|
167
|
+
{ if ((state != 3 || $0 !~ /^ ? ? ?\|/) && $0 ~ /^ ? ? ?\|/ && tolower($0) ~ /authorized by delegation/) print "@STRAY" } # mut:stray-deleg
|
|
168
|
+
/^ ? ? ?\|/ {
|
|
169
|
+
line = $0; sub(/^ +/, "", line); sub(/[ \t]+$/, "", line); low = tolower(line)
|
|
170
|
+
if (line ~ /^\|[ \t]*Item[ \t]*\|[ \t]*Class[ \t]*\|[ \t]*Ruling[ \t]*\|$/) { end_table(); print "@TABLE"; state = 2; rows_in = 0; next }
|
|
171
|
+
if (low ~ /item/ && low ~ /class/ && low ~ /ruling/ && state != 3) { hdr_pending = 1; next }
|
|
172
|
+
if (state == 2 && line ~ /^\|[ :|-]+$/) { state = 3; next }
|
|
173
|
+
if (state == 3) { printf "%d\t%s\n", NR, line; rows_in++; next }
|
|
174
|
+
end_table(); next
|
|
175
|
+
}
|
|
176
|
+
{ end_table() }
|
|
177
|
+
END { end_table(); if (f) print "@UNCLOSED" }
|
|
178
|
+
' "$1"
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
check_labels() { # <file> <display-path>; prints [FAIL] lines, returns the count (capped: a status wraps at 256)
|
|
182
|
+
local file="$1" shown="$2" n=0 ln text
|
|
183
|
+
while IFS=$'\t' read -r ln text; do
|
|
184
|
+
[[ -n "$ln" ]] || continue
|
|
185
|
+
if [[ "$ln" == "@UNCLOSED" ]]; then UNCLOSED_SEEN=1; continue; fi
|
|
186
|
+
if [[ ! "$text" =~ \(operator:\ ($CATS_RE)\) ]]; then
|
|
187
|
+
printf '[FAIL] %s:%s: owner-label-unscoped - the owner-decision label may only carry an operator-class item; append (operator: <category>) with a category from the closed list (%s), or route the question to the CTO (technical-ruling-delegation.md)\n' "$shown" "$ln" "$CATEGORIES" >&2
|
|
188
|
+
n=$((n + 1))
|
|
189
|
+
fi
|
|
190
|
+
done < <(unfenced_match "$file" "$LABEL_RE")
|
|
191
|
+
(( n > 255 )) && n=255
|
|
192
|
+
return "$n"
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
check_pending() { # <file> <display-path>; an unresolved placeholder anywhere in the file, returns the count (capped)
|
|
196
|
+
local file="$1" shown="$2" n=0 ln text
|
|
197
|
+
while IFS=$'\t' read -r ln text; do
|
|
198
|
+
[[ -n "$ln" ]] || continue
|
|
199
|
+
if [[ "$ln" == "@UNCLOSED" ]]; then UNCLOSED_SEEN=1; continue; fi
|
|
200
|
+
printf '[FAIL] %s:%s: unruled-technical - a "pending - assumed" placeholder survives: %s\n' "$shown" "$ln" "$CTO_REMEDY" >&2
|
|
201
|
+
n=$((n + 1))
|
|
202
|
+
done < <(unfenced_match "$file" "$PENDING_RE") # mut:pending
|
|
203
|
+
(( n > 255 )) && n=255
|
|
204
|
+
return "$n"
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
# memo_find <keyfile> <key>: prints the 1-based entry number of <key>, or nothing. One key per line.
|
|
208
|
+
memo_find() { [[ -f "$1" ]] || return 0; grep -nxF -- "$2" "$1" 2>/dev/null </dev/null | head -1 | cut -d: -f1; } # mut:memo
|
|
209
|
+
|
|
210
|
+
# receipt_check <delegation-url> <repo> <epic> <envelope-path> <sha> <verified-created-at> <verified-expiry>: sets
|
|
211
|
+
# RC_REASON to ok, receipt-missing, receipt-mismatch or receipt-unreadable. One read of the epic's comments per epic;
|
|
212
|
+
# every call has stdin closed. A receipt counts only if: its delegation and envelope equal the row's EXACTLY, its sha256
|
|
213
|
+
# is the verifier's, its result is ok or rolled-back, its author_association is OWNER, MEMBER or COLLABORATOR (a missing
|
|
214
|
+
# one never defaults), it was created inside the delegation's life (not before the delegation, not after the end of its
|
|
215
|
+
# expiry day) and not in the future, it was never edited (updated_at == created_at), its author is a User (not a bot),
|
|
216
|
+
# and it has not already satisfied another row (a receipt is consumed by the row that uses it).
|
|
217
|
+
receipt_check() {
|
|
218
|
+
local durl="$1" repo="$2" epic="$3" env="$4" sha="$5" vcre="$6" vexp="$7" ran="$8" key="$2#$3" n rd re rs rr ra rk rcre rupd rtyp nrec=0 okrec=0 now
|
|
219
|
+
RC_REASON=unreadable
|
|
220
|
+
now="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
221
|
+
n="$(memo_find "$work_dir/rcpt.keys" "$key")"
|
|
222
|
+
if [[ -z "$n" ]]; then
|
|
223
|
+
echo "$key" >> "$work_dir/rcpt.keys"; n="$(wc -l < "$work_dir/rcpt.keys" | tr -d ' ')"
|
|
224
|
+
if ${TOG[@]+"${TOG[@]}"} gh api "repos/$repo/issues/$epic/comments" --paginate >"$work_dir/rcpt.$n.json" 2>/dev/null </dev/null \
|
|
225
|
+
&& jq -r -s '[.[][]] | to_entries | .[] | .key as $k | .value
|
|
226
|
+
| (.body // "" | split("\n") | (.[0] // "") | sub("\r$"; "")) as $l
|
|
227
|
+
| ([$l | capture("^<!-- soleur-delegated-act v1 delegation=(?<d>[^ ]+) envelope=(?<e>.+?) sha256=(?<s>[0-9a-f]{64}) result=(?<r>[A-Za-z-]+) run=(?<u>[^ ]+) -->$")] | .[0]) as $m
|
|
228
|
+
| select($m != null) | [$m.d, $m.e, $m.s, $m.r, (.author_association // "ABSENT"), ($k | tostring), (.created_at // "none"), (.updated_at // "none2"), (.user.type // "NONE")] | @tsv' "$work_dir/rcpt.$n.json" >"$work_dir/rcpt.$n.tsv" 2>/dev/null </dev/null; then
|
|
229
|
+
echo ok > "$work_dir/rcpt.$n.st"
|
|
230
|
+
else
|
|
231
|
+
echo bad > "$work_dir/rcpt.$n.st"
|
|
232
|
+
fi
|
|
233
|
+
fi
|
|
234
|
+
[[ "$(cat "$work_dir/rcpt.$n.st")" == ok ]] || return 0
|
|
235
|
+
while IFS=$'\t' read -r rd re rs rr ra rk rcre rupd rtyp; do
|
|
236
|
+
[[ "$rd" == "$durl" ]] || continue # mut:receipt-deleg
|
|
237
|
+
case " $CONSUMED " in *" $n:$rk "*) continue ;; esac # mut:receipt-consume
|
|
238
|
+
nrec=$((nrec + 1))
|
|
239
|
+
[[ "$re" == "$env" ]] || continue # mut:receipt-env
|
|
240
|
+
[[ "$rs" == "$sha" ]] || continue # mut:receipt-sha
|
|
241
|
+
case "$rr" in ok|rolled-back) ;; *) continue ;; esac # mut:receipt-result
|
|
242
|
+
case "$ra" in OWNER|MEMBER|COLLABORATOR) ;; *) continue ;; esac # mut:receipt-author
|
|
243
|
+
[[ "$rcre" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ ]] || continue
|
|
244
|
+
# created >= ran also bounds the receipt below by the delegation itself: the verifier enforces delegation created <= ran
|
|
245
|
+
[[ "$rcre" < "$ran" ]] && continue # mut:receipt-before-ran
|
|
246
|
+
[[ "$rcre" > "$now" ]] && continue # mut:receipt-future
|
|
247
|
+
[[ "$rcre" > "${vexp}T23:59:59Z" ]] && continue # mut:receipt-expiry
|
|
248
|
+
[[ "$rupd" == "$rcre" ]] || continue # mut:receipt-edited
|
|
249
|
+
[[ "$rtyp" == User ]] || continue # mut:receipt-bot
|
|
250
|
+
okrec=1; CONSUMED="$CONSUMED $n:$rk"; break
|
|
251
|
+
done < "$work_dir/rcpt.$n.tsv"
|
|
252
|
+
if (( okrec )); then RC_REASON=ok; elif (( nrec > 0 )); then RC_REASON=receipt-mismatch; else RC_REASON=receipt-missing; fi
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
# check_delegation_row <line> <class> <ruling>: DR=0 pass, 1 a finding was printed, 2 could not verify (printed).
|
|
256
|
+
# Runs with nocasematch OFF: the phrase, the class and the link are matched exactly.
|
|
257
|
+
check_delegation_row() {
|
|
258
|
+
local had=0
|
|
259
|
+
shopt -q nocasematch && had=1
|
|
260
|
+
shopt -u nocasematch # mut:case-off
|
|
261
|
+
check_delegation_row_inner "$@"
|
|
262
|
+
(( had )) && shopt -s nocasematch
|
|
263
|
+
return 0
|
|
264
|
+
}
|
|
265
|
+
check_delegation_row_inner() {
|
|
266
|
+
local ln="$1" cls="$2" ruling="$3" durl repo epic dpath dran reason why dv_rc dv_line key n sha vcre vexp now
|
|
267
|
+
DR=0
|
|
268
|
+
[[ "$cls" == "operator (production-mutating)" ]] || { printf '[FAIL] %s:%s: bad-ruling-shape - a delegation can authorize only an operator (production-mutating) act, not "%s"\n' "$shown" "$ln" "$cls" >&2; DR=1; return; } # mut:deleg-class
|
|
269
|
+
[[ "$ruling" =~ $DELEG_RE ]] || { printf '[FAIL] %s:%s: bad-ruling-shape - a delegation ruling must read: Authorized by delegation <comment-url>, envelope <path>[, ran <time as 2026-01-31T09:30:00Z>] (standing-delegation.md)\n' "$shown" "$ln" >&2; DR=1; return; }
|
|
270
|
+
durl="${BASH_REMATCH[1]}"; repo="${BASH_REMATCH[2]}"; epic="${BASH_REMATCH[4]}"; dpath="${BASH_REMATCH[5]}"; dran="${BASH_REMATCH[7]:-}"
|
|
271
|
+
[[ -n "${TRG_EXEC_LOG:-}" ]] && echo "delegation $shown:$ln" >> "${TRG_EXEC_LOG:?}" # mut:deleg-log
|
|
272
|
+
if (( SHAPE_ONLY )); then SHAPE_ROWS=$((SHAPE_ROWS + 1)); DR=0; return; fi
|
|
273
|
+
(( HAVE_TO )) || { printf '[FAIL] %s:%s: delegation-unverifiable - no time limit tool (timeout or gtimeout) is installed, so the delegation was not checked, which is never a pass\n' "$shown" "$ln" >&2; DR=2; return; } # mut:need-timeout
|
|
274
|
+
now="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
275
|
+
[[ -n "$dran" && "$dran" > "$now" ]] && { printf '[FAIL] %s:%s: delegation-invalid - the row says the act ran at %s, which is in the future, so it cannot have run yet (reason: ran-in-future)\n' "$shown" "$ln" "$dran" >&2; DR=1; return; } # mut:ran-future
|
|
276
|
+
[[ -f "$VERIFIER" ]] || { printf '[FAIL] %s:%s: delegation-unverifiable - the delegation checker was not found next to this gate, so the row was not examined\n' "$shown" "$ln" >&2; DR=2; return; }
|
|
277
|
+
key="$durl|$dpath|$dran"
|
|
278
|
+
n="$(memo_find "$work_dir/dv.keys" "$key")"
|
|
279
|
+
if [[ -z "$n" ]]; then
|
|
280
|
+
echo "$key" >> "$work_dir/dv.keys"; n="$(wc -l < "$work_dir/dv.keys" | tr -d ' ')"
|
|
281
|
+
if [[ -z "$dran" ]]; then
|
|
282
|
+
${TOV[@]+"${TOV[@]}"} bash "$VERIFIER" verify --delegation "$durl" --envelope "$dpath" </dev/null >"$work_dir/dv.$n.out" 2>"$work_dir/dv.$n.err"; dv_rc=$? # mut:deleg-call
|
|
283
|
+
else
|
|
284
|
+
${TOV[@]+"${TOV[@]}"} bash "$VERIFIER" verify --delegation "$durl" --envelope "$dpath" --audit --at "$dran" </dev/null >"$work_dir/dv.$n.out" 2>"$work_dir/dv.$n.err"; dv_rc=$? # mut:deleg-audit
|
|
285
|
+
fi
|
|
286
|
+
echo "$dv_rc" > "$work_dir/dv.$n.rc"
|
|
287
|
+
fi
|
|
288
|
+
dv_rc="$(cat "$work_dir/dv.$n.rc")"
|
|
289
|
+
dv_line="$(head -1 "$work_dir/dv.$n.out")"
|
|
290
|
+
reason="$(printf '%s\n' "$dv_line" | sed -n 's/^delegation: [a-z]* reason=\(.*\)$/\1/p' | soleur_ctx_sanitize | cut -c1-60)"
|
|
291
|
+
why="$(head -1 "$work_dir/dv.$n.err" | soleur_ctx_sanitize | cut -c1-200)"
|
|
292
|
+
if (( dv_rc == 0 )) && [[ "$dv_line" != "delegation: valid reason="* ]]; then dv_rc=2; reason="verifier-error"; why="the delegation checker exited cleanly without saying valid"; fi # mut:deleg-line
|
|
293
|
+
(( dv_rc == 1 )) && { printf '[FAIL] %s:%s: delegation-invalid - %s (reason: %s)\n' "$shown" "$ln" "$why" "$reason" >&2; DR=1; return; }
|
|
294
|
+
(( dv_rc == 0 )) || { printf '[FAIL] %s:%s: delegation-unverifiable - %s (reason: %s); the row was not examined, which is never a pass\n' "$shown" "$ln" "$why" "${reason:-none}" >&2; DR=2; return; } # mut:deleg-unv
|
|
295
|
+
if [[ -n "$dran" ]]; then
|
|
296
|
+
sha="$(sed -n 's/^verified-envelope-sha256: \([0-9a-f]\{64\}\)$/\1/p' "$work_dir/dv.$n.out" | head -1)"
|
|
297
|
+
if [[ -z "$sha" ]]; then
|
|
298
|
+
printf '[FAIL] %s:%s: receipt-unreadable - the delegation checker did not report the runbook fingerprint, so the execution receipt cannot be matched; the row was not examined, which is never a pass\n' "$shown" "$ln" >&2; DR=2; return
|
|
299
|
+
fi
|
|
300
|
+
vcre="$(sed -n 's/^verified-created-at: \([0-9T:Z-]*\)$/\1/p' "$work_dir/dv.$n.out" | head -1)"
|
|
301
|
+
vexp="$(sed -n 's/^verified-expiry: \([0-9-]*\)$/\1/p' "$work_dir/dv.$n.out" | head -1)"
|
|
302
|
+
if [[ ! "$vcre" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ || ! "$vexp" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]; then
|
|
303
|
+
printf '[FAIL] %s:%s: receipt-unreadable - the delegation checker did not report when the delegation was recorded and when it ends, so the receipt window cannot be checked; the row was not examined, which is never a pass\n' "$shown" "$ln" >&2; DR=2; return
|
|
304
|
+
fi
|
|
305
|
+
receipt_check "$durl" "$repo" "$epic" "$dpath" "$sha" "$vcre" "$vexp" "$dran"
|
|
306
|
+
case "$RC_REASON" in
|
|
307
|
+
ok) ;;
|
|
308
|
+
receipt-missing) printf '[FAIL] %s:%s: receipt-missing - no execution receipt for this delegation is on epic #%s; the CTO writes one comment per delegated act (standing-delegation.md section 8) before this row may say the act ran\n' "$shown" "$ln" "$epic" >&2; DR=2; return ;;
|
|
309
|
+
receipt-mismatch) printf '[FAIL] %s:%s: receipt-mismatch - epic #%s has a receipt for this delegation but none names this envelope path and its verified fingerprint with result ok or rolled-back, written by an owner, member or collaborator\n' "$shown" "$ln" "$epic" >&2; DR=2; return ;;
|
|
310
|
+
*) printf '[FAIL] %s:%s: receipt-unreadable - the comments on epic #%s could not be read, so the execution receipt was not checked, which is never a pass\n' "$shown" "$ln" "$epic" >&2; DR=2; return ;;
|
|
311
|
+
esac
|
|
312
|
+
fi
|
|
313
|
+
echo 'SOLEUR_RULE_APPLIED rule=hr-menu-option-ack-not-prod-write-auth note=delegation-verified'
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
check_artifact() { # <file> <display-path>
|
|
317
|
+
local file="$1" shown="$2" idx=0 fails=0 unv=0 tables=0 ln row inner pipes c2 c3
|
|
318
|
+
[[ -e "$file" ]] || die2 "$shown: no such file"
|
|
319
|
+
[[ -f "$file" && -r "$file" ]] || die2 "$shown: not a readable regular file"
|
|
320
|
+
grep -q '[^[:space:]]' "$file" || die2 "$shown: the artifact is EMPTY; nothing was examined"
|
|
321
|
+
work_dir="$(mktemp -d -t trg.XXXXXXXX)" || die2 "mktemp failed"
|
|
322
|
+
table_rows "$file" > "$work_dir/raw"
|
|
323
|
+
grep -qxF '@UNCLOSED' "$work_dir/raw" && die2 "$shown: a code fence is never closed, so the rest of the file was not examined (close it)"
|
|
324
|
+
grep -qxF '@BADHEADER' "$work_dir/raw" && die2 "$shown: a table header names Item, Class and Ruling but is not exactly '| Item | Class | Ruling |' (fix the header; the rows were not examined)"
|
|
325
|
+
grep -qxF '@STRAY' "$work_dir/raw" && die2 "$shown: a row with Class technical sits outside any '| Item | Class | Ruling |' table (a row after a blank line, or a table without the header); put it in the table or add the header and separator"
|
|
326
|
+
grep -qxF '@EMPTY' "$work_dir/raw" && die2 "$shown: Decision Classes table has 0 rows examined (a header without data rows, or without its separator line)"
|
|
327
|
+
tables="$(grep -cxF '@TABLE' "$work_dir/raw" || true)"
|
|
328
|
+
grep -v '^@' "$work_dir/raw" > "$work_dir/rows" || true
|
|
329
|
+
while IFS=$'\t' read -r ln row; do
|
|
330
|
+
idx=$((idx + 1)) # mut:count
|
|
331
|
+
[[ -n "${TRG_EXEC_LOG:-}" ]] && echo "row $shown:$idx" >> "${TRG_EXEC_LOG:?}"
|
|
332
|
+
inner="${row#|}"; inner="${inner%|}"
|
|
333
|
+
inner="${inner//\\|/$'\001'}"
|
|
334
|
+
pipes="${inner//[^|]/}"
|
|
335
|
+
if [[ ${#pipes} -ne 2 ]]; then
|
|
336
|
+
printf '[FAIL] %s:%s: bad-class - the row must have exactly three cells: Item | Class | Ruling (write a literal pipe as \\|)\n' "$shown" "$ln" >&2
|
|
337
|
+
fails=$((fails + 1)); continue
|
|
338
|
+
fi
|
|
339
|
+
IFS='|' read -r _ c2 c3 _ <<<"$inner"
|
|
340
|
+
c2="${c2#"${c2%%[![:space:]]*}"}"; c2="${c2%"${c2##*[![:space:]]}"}"
|
|
341
|
+
c3="${c3#"${c3%%[![:space:]]*}"}"; c3="${c3%"${c3##*[![:space:]]}"}"
|
|
342
|
+
c2="${c2//$'\001'/|}"; c3="${c3//$'\001'/|}"
|
|
343
|
+
if [[ "$c3" == "Authorized by delegation"* ]]; then check_delegation_row "$ln" "$c2" "$c3"; case "$DR" in 0) ;; 1) fails=$((fails + 1)) ;; *) unv=$((unv + 1)) ;; esac; continue; fi # mut:deleg-all
|
|
344
|
+
if [[ "$c2" == technical ]]; then
|
|
345
|
+
if [[ "$c3" == "pending - assumed"* ]]; then
|
|
346
|
+
: # reported once, with its line, by the file-wide pending lint below
|
|
347
|
+
elif is_unruled "$c3"; then
|
|
348
|
+
printf '[FAIL] %s:%s: unruled-technical - the row is technical with no ruling: %s\n' "$shown" "$ln" "$CTO_REMEDY" >&2
|
|
349
|
+
fails=$((fails + 1))
|
|
350
|
+
elif ! shape_ok "$c3"; then
|
|
351
|
+
printf '[FAIL] %s:%s: bad-ruling-shape - a technical ruling must start: Ruled by CTO agent, <date>: <decision> - <rationale> (anything else, a bare "pending" included, is not a ruling)\n' "$shown" "$ln" >&2
|
|
352
|
+
fails=$((fails + 1))
|
|
353
|
+
fi
|
|
354
|
+
elif [[ "$c2" == taste ]]; then
|
|
355
|
+
: # user-legible Taste: auto-decided with a recommendation, rendered under Model Dissents, no ruling cell
|
|
356
|
+
elif [[ "$c2" =~ ^operator\ \(([a-z-]+)\)$ ]]; then
|
|
357
|
+
if ! cat_ok "${BASH_REMATCH[1]}"; then
|
|
358
|
+
printf '[FAIL] %s:%s: bad-category - category "%s" is not in the closed list (%s)\n' "$shown" "$ln" "${BASH_REMATCH[1]}" "$CATEGORIES" >&2
|
|
359
|
+
fails=$((fails + 1))
|
|
360
|
+
elif [[ -z "$c3" ]]; then
|
|
361
|
+
printf '[FAIL] %s:%s: bad-ruling-shape - an operator row must name the ACTION being authorised in its Ruling cell\n' "$shown" "$ln" >&2
|
|
362
|
+
fails=$((fails + 1))
|
|
363
|
+
fi
|
|
364
|
+
elif [[ "$c2" == operator ]]; then
|
|
365
|
+
printf '[FAIL] %s:%s: bad-category - a bare "operator" is invalid; write operator (<category>) with a category from the closed list (%s)\n' "$shown" "$ln" "$CATEGORIES" >&2
|
|
366
|
+
fails=$((fails + 1))
|
|
367
|
+
else
|
|
368
|
+
printf '[FAIL] %s:%s: bad-class - Class must be "technical", "taste" or "operator (<category>)", got "%s"\n' "$shown" "$ln" "$c2" >&2
|
|
369
|
+
fails=$((fails + 1))
|
|
370
|
+
fi
|
|
371
|
+
done < "$work_dir/rows"
|
|
372
|
+
check_pending "$file" "$shown"; fails=$((fails + $?))
|
|
373
|
+
check_labels "$file" "$shown"; fails=$((fails + $?))
|
|
374
|
+
if (( fails > 0 )); then return 1; fi
|
|
375
|
+
if (( unv > 0 )); then return 2; fi
|
|
376
|
+
if (( tables == 0 )); then
|
|
377
|
+
printf '[WARN] %s: no "| Item | Class | Ruling |" table outside a fenced block; label and pending lints ran, rows were not examined (add the table: technical-ruling-delegation.md section 6)\n' "$shown"
|
|
378
|
+
return 0
|
|
379
|
+
fi
|
|
380
|
+
if (( SHAPE_ROWS > 0 )); then
|
|
381
|
+
printf '[PASS] %s: %s rows examined (archived: %s delegation rows were checked for shape only and were NOT verified)\n' "$shown" "$idx" "$SHAPE_ROWS"
|
|
382
|
+
else
|
|
383
|
+
printf '[PASS] %s: %s rows examined\n' "$shown" "$idx"
|
|
384
|
+
fi
|
|
385
|
+
return 0
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
if [[ -n "${TRG_SPECS_ROOT:-}${TRG_BRANCH:-}${TRG_EXEC_LOG:-}${TRG_VERIFY_TIMEOUT:-}" ]]; then
|
|
389
|
+
printf '[NOTE] test seam active (TRG_SPECS_ROOT=%s TRG_BRANCH=%s): this is not the live repository lookup\n' "${TRG_SPECS_ROOT:-}" "${TRG_BRANCH:-}" >&2
|
|
390
|
+
fi
|
|
391
|
+
|
|
392
|
+
mode="${1:-}"
|
|
393
|
+
case "$mode" in
|
|
394
|
+
--pr-body)
|
|
395
|
+
f="${2:-}"; [[ -n "$f" ]] || die2 "usage: --pr-body <file>"
|
|
396
|
+
[[ -f "$f" && -r "$f" ]] || die2 "$f: not a readable regular file"
|
|
397
|
+
if ! { [[ -s "$f" ]] && grep -q '[^[:space:]]' "$f"; }; then
|
|
398
|
+
die2 "$f: the PR body is EMPTY (the fetch that wrote it most likely failed); nothing was examined"
|
|
399
|
+
fi
|
|
400
|
+
fails=0
|
|
401
|
+
check_pending "$f" "$f"; fails=$((fails + $?))
|
|
402
|
+
check_labels "$f" "$f"; fails=$((fails + $?))
|
|
403
|
+
(( UNCLOSED_SEEN )) && die2 "$f: a code fence in the PR body is never closed, so the rest of it was not examined (close it)"
|
|
404
|
+
if (( fails > 0 )); then exit 1; fi
|
|
405
|
+
printf '[PASS] %s: no unscoped owner-decision label and no pending placeholder\n' "$f"
|
|
406
|
+
exit 0 ;;
|
|
407
|
+
--branch)
|
|
408
|
+
branch="${TRG_BRANCH:-$(git rev-parse --abbrev-ref HEAD 2>/dev/null)}"
|
|
409
|
+
[ -n "$branch" ] && [ "$branch" != HEAD ] || die2 "cannot resolve the branch (detached HEAD or no git)"
|
|
410
|
+
if [[ -n "${TRG_SPECS_ROOT:-}" ]]; then
|
|
411
|
+
root="$TRG_SPECS_ROOT"
|
|
412
|
+
else
|
|
413
|
+
top="$(git rev-parse --show-toplevel 2>/dev/null)" || top=""
|
|
414
|
+
[[ -n "$top" ]] || die2 "not inside a git repository, so the specs directory cannot be located"
|
|
415
|
+
root="$top/knowledge-base/project/specs"
|
|
416
|
+
fi
|
|
417
|
+
safe="${branch//\//-}"; slug="$safe"
|
|
418
|
+
slug="${slug#feature-}"; slug="${slug#feat-}"; slug="${slug#fix-}"
|
|
419
|
+
matches=()
|
|
420
|
+
add_match() { local m; for m in ${matches[@]+"${matches[@]}"}; do [[ "$m" == "$1" ]] && return 0; done; matches+=("$1"); }
|
|
421
|
+
[[ -f "$root/$safe/decision-challenges.md" ]] && add_match "$root/$safe/decision-challenges.md"
|
|
422
|
+
[[ -f "$root/archive/$safe/decision-challenges.md" ]] && add_match "$root/archive/$safe/decision-challenges.md"
|
|
423
|
+
# archive directories are `<date>-<name>`, `<date>-<time>-<name>` or `<date>-<name>`: anchor the whole prefix
|
|
424
|
+
# so a short slug never suffix-matches another feature's longer name.
|
|
425
|
+
for pre in '????-??-??' '????????-??????' '????????'; do
|
|
426
|
+
for nm in "$slug" "$safe"; do
|
|
427
|
+
for cand in "$root"/archive/$pre-"$nm"/decision-challenges.md; do
|
|
428
|
+
[[ -f "$cand" ]] && add_match "$cand"
|
|
429
|
+
done
|
|
430
|
+
done
|
|
431
|
+
done
|
|
432
|
+
if (( ${#matches[@]} == 0 )); then
|
|
433
|
+
printf '[PASS] no decision-challenges artifact for %s\n' "$branch"
|
|
434
|
+
exit 0
|
|
435
|
+
fi
|
|
436
|
+
(( ${#matches[@]} == 1 )) || die2 "ambiguous: ${#matches[@]} decision-challenges.md files match branch $branch (${matches[*]}); examine the right one by path"
|
|
437
|
+
case "${matches[0]}" in */archive/*) SHAPE_ONLY=1; printf '[NOTE] archived artifact: delegation rows are checked for shape only and are NOT verified (no network)\n' >&2 ;; esac
|
|
438
|
+
check_artifact "${matches[0]}" "${matches[0]}"; exit $? ;;
|
|
439
|
+
""|-h|--help)
|
|
440
|
+
die2 "usage: $(basename "$0") <path> | --branch | --pr-body <file>" ;;
|
|
441
|
+
-*) die2 "unknown option: $mode" ;;
|
|
442
|
+
*)
|
|
443
|
+
check_artifact "$mode" "$mode"; exit $? ;;
|
|
444
|
+
esac
|