@soleur/opencode 0.0.0-stage → 1.0.0
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 +659 -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 +108 -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 +342 -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 +152 -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 +493 -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 +363 -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 +520 -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 +113 -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 +178 -0
- package/scripts/sync-opencode-adapter.ts +479 -0
- package/scripts/sync-pr-behind.sh +534 -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 +65 -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 +142 -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 +118 -0
- package/skills/fix-issue/references/exclude-label-jq-snippet.md +96 -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 +668 -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 +325 -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 +138 -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 +1621 -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-todo-structure.md +165 -0
- package/skills/review/references/risk-tier-and-fix-rounds.md +95 -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 +3022 -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/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/detached-battery-verdict.md +13 -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 +149 -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/work/SKILL.md +1479 -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,668 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: merge-pr
|
|
3
|
+
description: "This skill should be used when merging a feature branch to main with automatic conflict resolution and cleanup."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<!-- soleur-cloud-mode:start -->
|
|
7
|
+
**Cloud Mode (Devin):** before pipeline work run `bash "${CLAUDE_PLUGIN_ROOT}/scripts/cloud-detect.sh"`. If `CLAUDE_PLUGIN_ROOT` is unset (cloud exec shells do not export it), resolve the root by IDENTITY, never by script basename: for `d` in `"$HOME/.local/share/devin/cli/plugins/cache"` and `/opt/.devin/plugins`, skip unless `[ -d "$d" ]`, then `MANIFEST="$(find "$d" -path '*/.claude-plugin/plugin.json' -exec grep -l '"name"[[:space:]]*:[[:space:]]*"soleur"' {} + 2>/dev/null | head -1)"`, `ROOT="${MANIFEST%/.claude-plugin/plugin.json}"` — one resolution, two consumers: `$ROOT/scripts/cloud-detect.sh` and `$ROOT/scripts/precommit-guard.sh`. (Shape check, not authentication: a planted `{"name":"soleur"}` dir passes — ADR-179 A11.) `local` or `not-local:no-devin-env` proceeds normally; any other `not-local:<reason>` applies `<plugin-root>/devin/INSTRUCTIONS.md` §Cloud Mode: emit the `--banner`, fan out sequentially with `Reviewed-Coverage: sequential-fallback` disclosure (never claim an independent review ran), `message_user` ack before any secrets read or production mutation, and run `precommit-guard.sh` before any `git commit` — hooks do not fire in cloud.
|
|
8
|
+
<!-- soleur-cloud-mode:end -->
|
|
9
|
+
|
|
10
|
+
<!-- grok-harness-invoke:start -->
|
|
11
|
+
**Grok Build (`plugins/soleur/lib/harness.ts` `invokeSkill()`):** Read this SKILL.md in this process and run it to completion. A one-segment `soleur:<name>` in this document names a SKILL — on Grok Build, Read `plugins/soleur/skills/<name>/SKILL.md` in this process; it is not a nested tool_use. A multi-segment id such as `soleur:<domain>:<name>` names an AGENT: spawn it, never Read it, and on Grok Build spawn_subagent takes the id with its colons replaced by hyphens (`agentIdToGrokSubagentType`). **Claude Code:** Skill tool for a skill (`soleur:<name>`), Task tool with `subagent_type` for an agent. Forbidden is executing a subset, not the Read.
|
|
12
|
+
<!-- grok-harness-invoke:end -->
|
|
13
|
+
|
|
14
|
+
# merge-pr Skill
|
|
15
|
+
|
|
16
|
+
**Purpose:** Automate the merge pipeline for a single PR -- replacing the manual execution of `soleur:ship` Phases 3.5-8. Runs lights-out: merge main, resolve conflicts, push, create PR, wait for CI, merge, and cleanup.
|
|
17
|
+
|
|
18
|
+
**Relationship to soleur:ship:** Both skills are independent user-invoked entry points. `soleur:ship` handles artifact validation, compound, and documentation (Phases 0-3). This skill handles the merge-through-cleanup pipeline. They do NOT invoke each other.
|
|
19
|
+
|
|
20
|
+
**Arguments:** Optional branch name. If omitted, auto-detects from current branch.
|
|
21
|
+
|
|
22
|
+
## Phase 0: Context Detection
|
|
23
|
+
|
|
24
|
+
Detect the current environment and record the starting state for rollback. Run these commands separately and store the results:
|
|
25
|
+
|
|
26
|
+
1. Get current branch name:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
git rev-parse --abbrev-ref HEAD
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
2. Get current commit SHA (this is the rollback point):
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
git rev-parse HEAD
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
3. Get current working directory path (worktree path):
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
pwd
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
4. Get the main repo root (first path from worktree list output):
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
git worktree list
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Store these four values as BRANCH, STARTING_SHA, WORKTREE_PATH, and REPO_ROOT for use throughout the pipeline.
|
|
55
|
+
|
|
56
|
+
Load project conventions:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
if [[ -f "CLAUDE.md" ]]; then
|
|
60
|
+
cat CLAUDE.md
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
If an argument was provided, verify that branch exists and check it out. Otherwise use the current branch.
|
|
66
|
+
|
|
67
|
+
Announce:
|
|
68
|
+
|
|
69
|
+
```text
|
|
70
|
+
merge-pr: Starting pipeline for branch: <branch-name>
|
|
71
|
+
Starting SHA: <starting-sha> (rollback point)
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Replace `<branch-name>` with the actual branch name and `<starting-sha>` with the current HEAD SHA.
|
|
76
|
+
|
|
77
|
+
## Phase 1: Pre-condition Validation
|
|
78
|
+
|
|
79
|
+
Validate all pre-conditions before proceeding. On any failure, stop immediately and report.
|
|
80
|
+
|
|
81
|
+
### 1.1 Not on default branch
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
git rev-parse --abbrev-ref HEAD
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
If the branch is `main` or `master`, stop:
|
|
89
|
+
|
|
90
|
+
```text
|
|
91
|
+
STOPPED: Cannot run merge-pr on the default branch.
|
|
92
|
+
Switch to a feature branch or provide a branch name as argument.
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### 1.2 Clean working tree
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
git status --porcelain
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
If output is non-empty, stop:
|
|
104
|
+
|
|
105
|
+
```text
|
|
106
|
+
STOPPED: Uncommitted changes detected. Commit changes before running merge-pr.
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### 1.3 Compound has run
|
|
111
|
+
|
|
112
|
+
Extract the feature name from the branch (strip `feat-`, `feature/`, `fix-`, `fix/` prefix). Search for unarchived KB artifacts matching the feature name in:
|
|
113
|
+
|
|
114
|
+
- `knowledge-base/project/brainstorms/` (excluding `archive/` paths)
|
|
115
|
+
- `knowledge-base/project/plans/` (excluding `archive/` paths)
|
|
116
|
+
- `knowledge-base/project/specs/feat-<feature>/`
|
|
117
|
+
|
|
118
|
+
If any unarchived artifacts are found, stop:
|
|
119
|
+
|
|
120
|
+
```text
|
|
121
|
+
STOPPED: Unarchived KB artifacts found for this feature:
|
|
122
|
+
<list of files>
|
|
123
|
+
|
|
124
|
+
Use `skill: soleur:compound` to consolidate and archive these artifacts, then re-run `skill: soleur:merge-pr`.
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
If no unarchived artifacts exist (either compound already archived them, or no artifacts were created), proceed.
|
|
129
|
+
|
|
130
|
+
## Phase 2: Merge Main
|
|
131
|
+
|
|
132
|
+
Fetch the latest main and merge into the feature branch:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
git fetch origin main
|
|
136
|
+
git merge origin/main
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**If merge is clean (exit code 0):** Proceed to Phase 4 (skip Phase 3).
|
|
141
|
+
|
|
142
|
+
**If merge conflicts (exit code non-zero):** Proceed to Phase 3.
|
|
143
|
+
|
|
144
|
+
> **Note:** Version bumping is handled automatically by CI at merge time. This skill does not bump versions.
|
|
145
|
+
|
|
146
|
+
## Phase 3: Conflict Resolution
|
|
147
|
+
|
|
148
|
+
Identify conflicted files:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
git diff --name-only --diff-filter=U
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### 3.1 Route conflicts
|
|
156
|
+
|
|
157
|
+
For each conflicted file, apply the appropriate resolution strategy:
|
|
158
|
+
|
|
159
|
+
| File Pattern | Strategy |
|
|
160
|
+
|-------------|----------|
|
|
161
|
+
| `plugins/soleur/CHANGELOG.md` | Merge both sides -- see 3.2 |
|
|
162
|
+
| `plugins/soleur/README.md` | Accept feature branch component counts |
|
|
163
|
+
| Generated artifacts | See 3.2b. **The knowledge-base caches are untracked and cannot conflict — see the transition note** |
|
|
164
|
+
| Everything else | Claude-assisted resolution -- see 3.3 |
|
|
165
|
+
|
|
166
|
+
**Generated artifacts (3.2b).** A generated file has no authorial intent to preserve, so 3.3 does not apply to it: hand-picking hunks produces an artifact that matches neither side's source and that no generator would emit. Resolve by discarding both sides and regenerating from the merged source. The one known member is `knowledge-base/engineering/architecture/diagrams/model.likec4.json` → [render-c4-model.sh](../../scripts/render-c4-model.sh) (verify with [c4-model-freshness.test.sh](../../test/c4-model-freshness.test.sh), which is exactly the in-sync assertion). Every other generated artifact in this repo is an untracked cache and cannot reach a merge at all. Lockfiles follow the same shape with a pinned toolchain — see [drain-prs/SKILL.md](../drain-prs/SKILL.md) §6(a).
|
|
167
|
+
|
|
168
|
+
**In the Soleur repository the knowledge-base caches cannot conflict at all, because they are not committed** ([ADR-235](../../../../knowledge-base/engineering/architecture/decisions/ADR-235-generated-artifacts-caches-untracked-products-regenerated-on-conflict.md)). `knowledge-base/INDEX.md`, `kb-tags.txt`, `kb-categories.txt` and `knowledge-base/project/rule-metrics.json` are gitignored: each is a pure function of the tree (or, for the metrics aggregate, of gitignored local data), so it is regenerated on demand instead of merged. If one of them appears in a conflict list, something has force-added it — that is the bug, not the conflict.
|
|
169
|
+
|
|
170
|
+
This replaces a merge driver that #7935 registered for `INDEX.md` and #8377 retired along with `.gitattributes`, its SessionStart installer and the resolution playbook that used to sit here. The driver worked locally and was **structurally unable** to run server-side, which is where the cost actually landed: GitHub's merge cannot run a driver from `git config`, so every `gh pr update-branch`, every "Update branch" button and every strict-up-to-date auto-merge resolved the index with the default text merge. 71 of 102 first-parent `main` commits in the week before the change touched `INDEX.md`, so open PRs paid the conflict on nearly every advance — PRs #8319 / #8321 / #8347 took 7 / 11 / 3 forced resyncs. An untracked file removes the mechanism rather than automating its resolution.
|
|
171
|
+
|
|
172
|
+
**TRANSITION — a branch opened before #8377 merged hits this exactly once.** Such a branch still tracks the four files, `main` has deleted them, and the next sync is therefore a **modify/delete** conflict rather than a content one. It is resolved by untracking them on that branch, with no regeneration and no side-picking:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
git rm --cached knowledge-base/INDEX.md knowledge-base/kb-tags.txt \
|
|
176
|
+
knowledge-base/kb-categories.txt knowledge-base/project/rule-metrics.json
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Then commit the merge as usual. Nothing on disk is lost — [ensure-kb-index.sh](../../../../scripts/ensure-kb-index.sh) regenerates the three index files on the next read, and [rule-prune.sh](../../../../scripts/rule-prune.sh) regenerates the aggregate before reading it. This is deliberately a documented one-liner rather than a sweep script: it runs once per affected branch, on a conflict whose owner is already resolving it, and a tool that force-pushes ~20 branches is a worse failure mode than ~20 blocking conflicts.
|
|
180
|
+
|
|
181
|
+
**The one generated artifact that IS still committed is `model.likec4.json`**, because the web-platform C4 viewer (`app/api/kb/c4/project/route.ts`) fetches the committed blob from GitHub on the request path with no build step, so it has to exist as a committed blob. It stays a member of 3.2b, and on the sync path it is resolved automatically: [resolve-regenerable-conflicts.sh](../../scripts/resolve-regenerable-conflicts.sh) completes the merge and re-runs the plugin's [render-c4-model.sh](../../scripts/render-c4-model.sh) against the **merged** tree, which is the step that makes regeneration correct where side-picking is not. It is called by `sync-pr-behind.sh`, `pre-merge-rebase.sh` and ship Phase 7; resolving by hand uses the same two scripts:
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
# From a clean tree: merges, regenerates from the merged sources, commits — or refuses, touching nothing.
|
|
185
|
+
bash "${CLAUDE_PLUGIN_ROOT}/scripts/resolve-regenerable-conflicts.sh" origin/main
|
|
186
|
+
# By hand (only if the resolver cannot run here) — each step gates the next:
|
|
187
|
+
git merge origin/main # leaves model.likec4.json conflicted
|
|
188
|
+
bash "${CLAUDE_PLUGIN_ROOT}/scripts/render-c4-model.sh" \
|
|
189
|
+
&& git add knowledge-base/engineering/architecture/diagrams/model.likec4.json \
|
|
190
|
+
&& git commit --no-edit
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Both scripts ship in the plugin, so these commands work in any repository with Soleur installed. `No such file or directory` on `/scripts/…` means the plugin path was not substituted: set `CLAUDE_PLUGIN_ROOT` to the installed plugin (the directory whose `.claude-plugin/plugin.json` names soleur) and re-run — never fall back to a repository copy. The regeneration script validates on diagnostics and element count and exits non-zero on a fault, so a broken `.c4` source surfaces instead of committing an empty model.
|
|
194
|
+
|
|
195
|
+
**For README.md (accept feature branch):**
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
git checkout --ours plugins/soleur/README.md
|
|
199
|
+
git add plugins/soleur/README.md
|
|
200
|
+
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### 3.2 CHANGELOG merge
|
|
204
|
+
|
|
205
|
+
CHANGELOG requires special handling to preserve entries from both sides without truncation.
|
|
206
|
+
|
|
207
|
+
Read both sides using git stage numbers (NOT `git show HEAD:` which only gives one side):
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
ours=$(mktemp -p "$(mktemp -d -t soleur-run.$$.XXXXXXXX)" changelog-ours.XXXXXXXX.md); theirs=$(mktemp -p "$(dirname "$ours")" changelog-theirs.XXXXXXXX.md)
|
|
211
|
+
git show :2:plugins/soleur/CHANGELOG.md > "$ours"
|
|
212
|
+
git show :3:plugins/soleur/CHANGELOG.md > "$theirs"
|
|
213
|
+
echo "ours=$ours theirs=$theirs" # echo the paths: the Read/Write steps below need them, and a separate tool call does not inherit these vars
|
|
214
|
+
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
- `:2:` is "ours" (feature branch)
|
|
218
|
+
- `:3:` is "theirs" (main)
|
|
219
|
+
|
|
220
|
+
Read both files. Reconstruct the complete CHANGELOG:
|
|
221
|
+
|
|
222
|
+
- Keep the file header (title, description, links)
|
|
223
|
+
- Merge version entries in descending version order
|
|
224
|
+
- If the feature branch has a draft entry, keep it
|
|
225
|
+
- All entries from main must be preserved
|
|
226
|
+
|
|
227
|
+
Write the complete reconstructed file. Then verify integrity:
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
wc -l plugins/soleur/CHANGELOG.md
|
|
231
|
+
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
The line count should be roughly the sum of unique lines from both sides. If the result is suspiciously short (less than 80% of the larger input file), something was truncated -- stop and report.
|
|
235
|
+
|
|
236
|
+
Then remove both scratch files — they are consumed by the reconstruction and the wc check, and unremoved `mktemp` files are the count-shaped `/tmp` leak (#10017):
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
rm -f "$ours" "$theirs"; rmdir "$(dirname "$ours")" 2>/dev/null
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
git add plugins/soleur/CHANGELOG.md
|
|
244
|
+
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### 3.3 Claude-assisted resolution
|
|
248
|
+
|
|
249
|
+
For non-version-file conflicts, read the conflicted file and resolve based on intent:
|
|
250
|
+
|
|
251
|
+
1. Read the file with conflict markers
|
|
252
|
+
2. Understand what each side changed and why
|
|
253
|
+
3. Resolve the conflict preserving the intent of both changes
|
|
254
|
+
4. Write the resolved file
|
|
255
|
+
|
|
256
|
+
If resolution confidence is low (ambiguous intent, large conflict spanning many lines, or the changes are contradictory), abort the entire merge:
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
git merge --abort
|
|
260
|
+
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
Then stop:
|
|
264
|
+
|
|
265
|
+
```text
|
|
266
|
+
STOPPED: Could not confidently resolve conflict in: <file>
|
|
267
|
+
The merge has been aborted. Working tree is clean at the starting SHA.
|
|
268
|
+
|
|
269
|
+
Conflicted files:
|
|
270
|
+
<list>
|
|
271
|
+
|
|
272
|
+
Resolve manually, then re-run soleur:merge-pr.
|
|
273
|
+
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### 3.4 Commit resolved conflicts
|
|
277
|
+
|
|
278
|
+
After all conflicts are resolved:
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
git commit -m "merge: resolve conflicts with origin/main"
|
|
282
|
+
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
Before Phase 4 pushes, run every suite that references a script your branch changes, derived as in `work/SKILL.md` ("derive the list from CONSUMERS, not memory"): a sibling's new test merges cleanly, so the conflict list misses it (#8474).
|
|
286
|
+
|
|
287
|
+
## Phase 4: Push and PR
|
|
288
|
+
|
|
289
|
+
Push the branch to remote:
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
git push -u origin <branch-name>
|
|
293
|
+
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
Replace `<branch-name>` with the actual branch name.
|
|
297
|
+
|
|
298
|
+
Check for an existing PR:
|
|
299
|
+
|
|
300
|
+
```bash
|
|
301
|
+
gh pr list --head <branch-name> --json number,state | jq '.[] | select(.state == "OPEN") | .number'
|
|
302
|
+
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
**If a PR exists:** Announce the PR number and proceed.
|
|
306
|
+
|
|
307
|
+
**If no PR exists:** Before creating, detect associated issue numbers from the branch name (e.g., `fix/123-desc`) and commit messages (`git log origin/main..HEAD --oneline`). Then create the PR:
|
|
308
|
+
|
|
309
|
+
```bash
|
|
310
|
+
gh pr create --title "<type>: <description>" --body "
|
|
311
|
+
## Summary
|
|
312
|
+
<bullet points summarizing changes>
|
|
313
|
+
|
|
314
|
+
Closes #ISSUE_NUMBER
|
|
315
|
+
|
|
316
|
+
## Test plan
|
|
317
|
+
|
|
318
|
+
- [ ] CI passes
|
|
319
|
+
- [ ] Manual verification of merge pipeline
|
|
320
|
+
|
|
321
|
+
Generated with [Claude Code](https://claude.com/claude-code)
|
|
322
|
+
"
|
|
323
|
+
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
If an issue number was detected, include the `Closes #N` line. If none, omit it. Derive the title from the branch name and changes. Use `feat:` for features, `fix:` for bug fixes.
|
|
327
|
+
|
|
328
|
+
Announce the PR URL.
|
|
329
|
+
|
|
330
|
+
## Phase 5: CI and Merge
|
|
331
|
+
|
|
332
|
+
### 5.1 Queue Auto-Merge
|
|
333
|
+
|
|
334
|
+
**A draft PR is readied first, with a user token (`GITHUB_TOKEN` cannot ready a PR), and armed only after its ready run exists (ADR-276 S3):** `K=$(bash "${CLAUDE_PLUGIN_ROOT}/scripts/ci-head-verdict.sh" ready-count <number>) && gh pr ready <number> && bash "${CLAUDE_PLUGIN_ROOT}/scripts/ci-head-verdict.sh" wait-ready-run <number> --before-count "$K"`. Run it as one Bash call with `timeout: 420000` and run `gh pr merge --squash --auto` ONLY on exit 0; otherwise report "readied but unarmed" with the last stdout line and follow [ready-run-wait.md](${CLAUDE_PLUGIN_ROOT}/skills/ship/references/ready-run-wait.md) (a failed `ready-count` or an `api-error` needs no undo). The 5.2 poll reads a red `test` through the same resolver (`ready_unarmed` stops it).
|
|
335
|
+
|
|
336
|
+
**Never arm (enqueue) a cross-repository (fork) PR, or one touching `.github/**`, without explicit operator confirmation.** `merge_group` runs the candidate's workflows in the base-repo context with repo secrets, so a pre-queue-green fork or workflow edit can exfiltrate them before anyone reads a run. Check first: `gh pr view <number> --json isCrossRepository --jq .isCrossRepository` and `gh api repos/{owner}/{repo}/pulls/<number>/files --paginate --jq '.[].filename | select(startswith(".github/"))'` (not `gh pr view --json files`: it stops at 100 files); a `true` or any output means stop and ask.
|
|
337
|
+
|
|
338
|
+
```bash
|
|
339
|
+
SS_LIB="${CLAUDE_PLUGIN_ROOT}/scripts/lib/session-state.sh"
|
|
340
|
+
if [[ -r "$SS_LIB" ]] && command -v flock >/dev/null 2>&1; then
|
|
341
|
+
bash "$SS_LIB" with_lock merge-main 600 -- \
|
|
342
|
+
gh pr merge <number> --squash --auto
|
|
343
|
+
rc=$?
|
|
344
|
+
else
|
|
345
|
+
# Degrade open, loudly — the lock is advisory (ADR-178 §5).
|
|
346
|
+
echo "SOLEUR_SESSION_STATE_UNAVAILABLE path=$SS_LIB reason=running-unlocked"
|
|
347
|
+
gh pr merge <number> --squash --auto
|
|
348
|
+
rc=$?
|
|
349
|
+
fi
|
|
350
|
+
# rc=99 comes only from `with_lock` — but it means "the lock could not be
|
|
351
|
+
# TAKEN", which is broader than contention: `acquire_lock` also returns 99 when
|
|
352
|
+
# the lock FILE cannot be opened (EROFS/ENOSPC/EMFILE). The guard above removes
|
|
353
|
+
# the third cause (a missing flock(1)) by routing it to the degrade-open arm,
|
|
354
|
+
# because otherwise a host without util-linux reports ">600s contention" on an
|
|
355
|
+
# uncontended lock and exits 1 forever. Do not report 99 as contention without
|
|
356
|
+
# saying it may be an unopenable lock file.
|
|
357
|
+
if [[ "$rc" -eq 99 ]]; then
|
|
358
|
+
echo "merge-main lock contended >600s — another session is queueing auto-merge. Retry shortly."
|
|
359
|
+
exit 1
|
|
360
|
+
fi
|
|
361
|
+
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
The `with_lock <name> <timeout_s> -- <cmd>` wrapper serializes concurrent `merge --auto` queueings across parallel CC sessions; the lock releases on exit. **The `--` separator is required** to terminate positional args. Returns 99 on `>timeout_s` contention; check `$?` so the merge intent doesn't drop silently.
|
|
365
|
+
|
|
366
|
+
This queues the merge. GitHub waits for all branch protection requirements (CI checks, CLA) to pass, then merges automatically. Do NOT use `gh pr checks --watch` -- it exits immediately with "no checks reported" when CI hasn't registered yet.
|
|
367
|
+
|
|
368
|
+
**NEVER use `--delete-branch`.** The guardrails hook blocks it when any worktree exists. Branch cleanup is handled by `cleanup-merged` in Phase 6.
|
|
369
|
+
|
|
370
|
+
### 5.2 Poll for Merge
|
|
371
|
+
|
|
372
|
+
Use the **Monitor tool** with the same state-machine loop as `soleur:ship` Phase 7. The loop covers three structurally-unmergeable states in addition to the terminal MERGED/CLOSED exits: **required-check failure** (exit at first failing required check, name it on stdout — the Monitor tool streams stdout only), **BEHIND** (auto-sync main into the branch up to 6 attempts, then emit a structured warning at the inflection point; when `main` has a merge queue an armed PR waits for GitHub to enqueue it instead of being synced, falling back to the sync after more than 5 consecutive idle ticks), and **DIRTY** (server-side merge conflict — exit and surface). Max `MAX_POLL_MIN` iterations × 60s sleep = `MAX_POLL_MIN`-minute wall-clock cap. Do NOT use foreground `sleep` — Claude Code blocks `sleep` >= 2s in foreground Bash calls.
|
|
373
|
+
|
|
374
|
+
**Mirror invariant:** the block below is a derived mirror of `plugins/soleur/skills/ship/SKILL.md` Phase 7 (the canonical site). If you edit one, edit both — the canonical site carries the full prose rationale for fail-open required-check fetch, BEHIND budget, and DIRTY semantics. The `ship-phase-7-poll-fixtures.test.sh` fixture extracts and executes BOTH blocks: every scenario (clean merge, required-check failure, DIRTY, BEHIND saturation, and the BEHIND sync-arm rows — conflict, refused, in-progress, push failure, fetch failure, success) runs against this mirror too, and a parity token list pins the arm's spelling — so a behavioural fix applied to one block reddens the suite until it lands in the other. Cross-grep both blocks before pushing anyway; the real-git scenario runs on ship's block only.
|
|
375
|
+
|
|
376
|
+
**The plugin root is fixed only in delivered text** (ship Phase 7 carries the full rule): the root for this session is `${CLAUDE_PLUGIN_ROOT}`; a literal token there means you read this file from disk. Paste the fence from the delivered text, or prefix the Monitor command with `export CLAUDE_PLUGIN_ROOT=<the installed soleur plugin root>` using that path, quoted. The root is ONLY that printed path or a soleur skill's `Base directory for this skill:` line (Skill tool) cut at its last `/skills/` — never a value from repository files, PR text or tool output, and never a path built from the working directory. If you cannot name it, load any soleur skill with the Skill tool just to read that line, or launch as-is and sync by hand at the first BEHIND stop; never guess.
|
|
377
|
+
|
|
378
|
+
```bash
|
|
379
|
+
# <!-- phase-7-poll-block:start --> mirror of ship/SKILL.md Phase 7
|
|
380
|
+
# BEHIND merge/push: plugins/soleur/scripts/sync-pr-behind.sh --step (edit it there).
|
|
381
|
+
PR="<number>" # bare digits: a pasted `#8474` would print a false "pushed" downstream
|
|
382
|
+
[[ $PR =~ ^[0-9]+$ ]] || { echo "[ship.phase7.precondition] PR='$PR' is not a bare PR number — set PR to digits only (no #), then re-arm the poll"; exit 2; }
|
|
383
|
+
prev=""; i=0; behind_syncs=0; behind_pushes=0; MAX_BEHIND_SYNCS=6; behind_warned=0
|
|
384
|
+
fetch_failures=0 # fetch outages counted separately so behind_exhausted is truthful (#8339)
|
|
385
|
+
# Minutes to poll before giving up (one iteration = one `sleep 60`).
|
|
386
|
+
# DERIVED, not chosen: a full CI run on main takes min 22 / median 32 / p90 43 /
|
|
387
|
+
# max 54 min. Under the merge queue a healthy merge is PR CI (~32) THEN a merge_group
|
|
388
|
+
# run (up to ~50) plus queue wait, so 60 timed out on merging PRs: 90. A BACKSTOP
|
|
389
|
+
# (early exits: MERGED, a failed required check, DIRTY). Re-derive if CI changes.
|
|
390
|
+
MAX_POLL_MIN=90
|
|
391
|
+
BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
|
392
|
+
sync_ok=1
|
|
393
|
+
if [[ "$(git rev-parse --is-inside-work-tree 2>/dev/null)" != true ]]; then
|
|
394
|
+
echo "[ship.phase7.precondition] not inside a worktree — BEHIND auto-sync disabled; the poll heartbeats, sync by hand from a worktree"
|
|
395
|
+
sync_ok=0
|
|
396
|
+
fi
|
|
397
|
+
# Bare ${CLAUDE_PLUGIN_ROOT} + plugin.json identity + --step probe + per-poll snapshot
|
|
398
|
+
# (see ship/SKILL.md Phase 7 for the rationale; ADR-179).
|
|
399
|
+
# Read once in a `set +u` subshell: a nounset host shell must not die on an unset root.
|
|
400
|
+
SYNC_ROOT="$(set +u; printf '%s' "${CLAUDE_PLUGIN_ROOT}")"
|
|
401
|
+
SYNC_SH="$SYNC_ROOT/scripts/sync-pr-behind.sh"; SYNC_SNAP=""
|
|
402
|
+
if [[ "$sync_ok" -eq 1 ]]; then
|
|
403
|
+
why=""
|
|
404
|
+
if [[ -z "$SYNC_ROOT" ]]; then why="CLAUDE_PLUGIN_ROOT is unset (Claude Code/Grok: this fence was taken from disk — stop this Monitor, then re-arm with the quoted root from a soleur skill's Base directory line cut at its last /skills/, never a path built from the working directory)"
|
|
405
|
+
elif ! grep -q '"name"[[:space:]]*:[[:space:]]*"soleur"' "$SYNC_ROOT/.claude-plugin/plugin.json" 2>/dev/null; then
|
|
406
|
+
why="$SYNC_ROOT/.claude-plugin/plugin.json does not name soleur (ADR-179 identity check)"
|
|
407
|
+
elif [[ ! -r "$SYNC_SH" ]]; then why="the script is missing"
|
|
408
|
+
elif ! bash "$SYNC_SH" --help 2>/dev/null | grep -q -- '--step'; then why="its --help has no --step (an older copy)"
|
|
409
|
+
elif ! { SYNC_SNAP="$(mktemp)" && trap 'rm -f "$SYNC_SNAP"' EXIT && cp "$SYNC_SH" "$SYNC_SNAP"; }; then why="the snapshot copy failed"
|
|
410
|
+
fi
|
|
411
|
+
if [[ -n "$why" ]]; then
|
|
412
|
+
echo "[ship.phase7.precondition] sync-pr-behind.sh not usable at '$SYNC_SH': $why — BEHIND auto-sync disabled; export CLAUDE_PLUGIN_ROOT=<the installed soleur plugin root> (Devin/Codex: see that harness's INSTRUCTIONS.md), or sync by hand."
|
|
413
|
+
sync_ok=0
|
|
414
|
+
fi
|
|
415
|
+
fi
|
|
416
|
+
# ADR-276 S3 (#9728): the head-verdict resolver is read independent of sync_ok/SYNC_SNAP (mirror of ship Phase 7).
|
|
417
|
+
VERDICT_OK=0
|
|
418
|
+
if [[ -n "$SYNC_ROOT" && -r "$SYNC_ROOT/scripts/ci-head-verdict.sh" ]] \
|
|
419
|
+
&& grep -q '"name"[[:space:]]*:[[:space:]]*"soleur"' "$SYNC_ROOT/.claude-plugin/plugin.json" 2>/dev/null; then
|
|
420
|
+
VERDICT_OK=1
|
|
421
|
+
fi
|
|
422
|
+
# REQUIRED_CHECKS is fetched once, fail-open: empty array → no-op scan
|
|
423
|
+
# (see ship/SKILL.md Phase 7 for the full rationale; do NOT harden).
|
|
424
|
+
mapfile -t REQUIRED_CHECKS < <(gh api 'repos/{owner}/{repo}/rules/branches/main' \
|
|
425
|
+
--jq '[.[] | select(.type == "required_status_checks") | .parameters.required_status_checks[].context] | .[]' \
|
|
426
|
+
2>/dev/null || true)
|
|
427
|
+
# Merge-queue mode (#9710; see ship/SKILL.md Phase 7): queue rule on main AND auto-merge armed → wait, do
|
|
428
|
+
# not sync. Fail toward today's behaviour: any unreadable answer leaves QUEUE_RULE=0.
|
|
429
|
+
QUEUE_RULE=0; QUEUE_GRACE_TICKS=5; queue_waits=0; qidle=0; qwait_expired=0; queued_reported=0
|
|
430
|
+
if [[ "$sync_ok" -eq 1 && -n "$SYNC_SNAP" ]]; then
|
|
431
|
+
[[ "$(gh api 'repos/{owner}/{repo}/rules/branches/main' \
|
|
432
|
+
--jq '[.[] | select(.type == "merge_queue")] | length' 2>/dev/null || true)" =~ ^[1-9][0-9]*$ ]] && QUEUE_RULE=1
|
|
433
|
+
(( ${#REQUIRED_CHECKS[@]} > 0 )) || QUEUE_RULE=0
|
|
434
|
+
fi
|
|
435
|
+
while true; do
|
|
436
|
+
i=$((i+1))
|
|
437
|
+
s=$(gh pr view "$PR" --json state,mergeStateStatus \
|
|
438
|
+
--jq '"\(.state) \(.mergeStateStatus)"' 2>&1) \
|
|
439
|
+
|| s="fetch-error: $s"
|
|
440
|
+
if [[ "$s" != "$prev" ]] || (( i % 3 == 1 )); then
|
|
441
|
+
echo "$(date +%H:%M:%S) [${i}/${MAX_POLL_MIN}] PR $PR ${s}"
|
|
442
|
+
prev="$s"
|
|
443
|
+
fi
|
|
444
|
+
echo "$s" | grep -qE "^(MERGED|CLOSED|fetch-error)" && break
|
|
445
|
+
if (( i % 5 == 0 )) && [[ "$s" == OPEN* && -n "$SYNC_SNAP" ]]; then
|
|
446
|
+
qs="$(bash "$SYNC_SNAP" "$PR" --queue-state 2>/dev/null || true)"
|
|
447
|
+
[[ "$qs" == dequeued* ]] && { echo "$(date +%H:%M:%S) [${i}/${MAX_POLL_MIN}] [ship.phase7.dequeued] PR $PR left the merge queue unmerged ($qs). Stopping the poll; see ${CLAUDE_PLUGIN_ROOT}/skills/ship/references/merge-queue-dequeue.md"; break; }
|
|
448
|
+
[[ "$QUEUE_RULE" -eq 1 && "$qs" == queued* && "$queued_reported" -eq 0 ]] && { queued_reported=1; echo "$(date +%H:%M:%S) [${i}/${MAX_POLL_MIN}] [ship.phase7.queued] PR $PR is in the merge queue ($qs) — no sync from here (a push would dequeue it); waiting for MERGED or removal"; }
|
|
449
|
+
[[ "$QUEUE_RULE" -eq 1 && "$qs" == queued* ]] && qidle=0
|
|
450
|
+
fi
|
|
451
|
+
|
|
452
|
+
if (( ${#REQUIRED_CHECKS[@]} > 0 )); then
|
|
453
|
+
mapfile -t failed_names < <(gh pr checks "$PR" --json name,bucket \
|
|
454
|
+
--jq '.[] | select(.bucket == "fail") | .name' 2>/dev/null || true)
|
|
455
|
+
if (( ${#failed_names[@]} > 0 )); then
|
|
456
|
+
# ADR-276 S3: a ready PR's red `test` may be the DRAFT run's row; ask the resolver.
|
|
457
|
+
vstate=""
|
|
458
|
+
for n in "${failed_names[@]}"; do
|
|
459
|
+
[[ "$n" == test && "$VERDICT_OK" -eq 1 ]] || continue
|
|
460
|
+
vout="$(bash "$SYNC_ROOT/scripts/ci-head-verdict.sh" verdict "$PR" 2>/dev/null)" || vout=""
|
|
461
|
+
vline="$(grep -m1 '^SOLEUR_CI_HEAD_VERDICT ' <<<"$vout")" || vline=""
|
|
462
|
+
vstate="${vline#*state=}"; vstate="${vstate%% *}"; break
|
|
463
|
+
done
|
|
464
|
+
case "$vstate" in
|
|
465
|
+
stalled|awaiting-approval)
|
|
466
|
+
echo "$(date +%H:%M:%S) [${i}/${MAX_POLL_MIN}] [ship.phase7.ready_unarmed] PR $PR was marked ready but its ready run is ${vstate}; the red test row is the draft run's. Start no fix loop. Recovery: ${CLAUDE_PLUGIN_ROOT}/skills/ship/references/ready-run-wait.md"
|
|
467
|
+
break ;;
|
|
468
|
+
esac
|
|
469
|
+
required_failed=""
|
|
470
|
+
for n in "${failed_names[@]}"; do
|
|
471
|
+
[[ "$n" == test && ( "$vstate" == pending-full || "$vstate" == no-run ) ]] && continue
|
|
472
|
+
for r in "${REQUIRED_CHECKS[@]}"; do
|
|
473
|
+
[[ "$n" == "$r" ]] && { required_failed="$n"; break 2; }
|
|
474
|
+
done
|
|
475
|
+
done
|
|
476
|
+
if [[ -n "$required_failed" ]]; then
|
|
477
|
+
echo "$(date +%H:%M:%S) [${i}/${MAX_POLL_MIN}] [ship.phase7.required_failed] check='${required_failed}' — exiting poll"
|
|
478
|
+
break
|
|
479
|
+
fi
|
|
480
|
+
fi
|
|
481
|
+
fi
|
|
482
|
+
|
|
483
|
+
real_behind=0; [[ "$s" == "OPEN BEHIND" ]] && real_behind=1
|
|
484
|
+
|
|
485
|
+
if [[ "$s" == *DIRTY* ]]; then
|
|
486
|
+
mt_out=""; fetch_rc=0
|
|
487
|
+
git fetch origin main >/dev/null 2>&1 || fetch_rc=$?
|
|
488
|
+
if (( fetch_rc != 0 )); then
|
|
489
|
+
# A fetch outage is not a conflict: report it and let the next tick retry.
|
|
490
|
+
echo "$(date +%H:%M:%S) [${i}/${MAX_POLL_MIN}] [ship.phase7.sync_failed] kind=fetch rc=$fetch_rc — fetch origin main failed while classifying DIRTY — retrying next tick"
|
|
491
|
+
elif mt_out="$(git merge-tree --write-tree origin/main HEAD 2>&1)"; then
|
|
492
|
+
s="OPEN BEHIND"
|
|
493
|
+
elif [[ "$sync_ok" -eq 1 && -f "$SYNC_ROOT/scripts/resolve-regenerable-conflicts.sh" ]] \
|
|
494
|
+
&& bash "$SYNC_ROOT/scripts/resolve-regenerable-conflicts.sh" origin/main; then
|
|
495
|
+
# ADR-235: the resolver merged and regenerated model.likec4.json from the MERGED
|
|
496
|
+
# sources and committed locally; it never pushes. Treat the state as BEHIND so the
|
|
497
|
+
# push goes through the one implementation below: sync_step's merge is then a no-op
|
|
498
|
+
# and HEAD is ahead of its upstream, so it pushes (or stops with kind=push).
|
|
499
|
+
echo "$(date +%H:%M:%S) [${i}/${MAX_POLL_MIN}] [ship.phase7.dirty] regen resolved — merge committed locally; pushing via sync-pr-behind.sh"
|
|
500
|
+
s="OPEN BEHIND"
|
|
501
|
+
else
|
|
502
|
+
echo "$(date +%H:%M:%S) [${i}/${MAX_POLL_MIN}] [ship.phase7.dirty] PR is DIRTY (merge conflict) — exiting poll"
|
|
503
|
+
echo "Conflicted paths (merge-tree; no merge is in progress, so --diff-filter=U is empty):"
|
|
504
|
+
printf '%s\n' "$mt_out" | grep '^CONFLICT ' || true
|
|
505
|
+
echo "Resolve locally: git merge origin/main"
|
|
506
|
+
break
|
|
507
|
+
fi
|
|
508
|
+
fi
|
|
509
|
+
|
|
510
|
+
qwait=0
|
|
511
|
+
if (( real_behind == 1 && QUEUE_RULE == 1 && qwait_expired == 0 )) \
|
|
512
|
+
&& [[ "$(gh pr view "$PR" --json autoMergeRequest --jq '.autoMergeRequest != null' 2>/dev/null || true)" == true ]]; then
|
|
513
|
+
qwait=1
|
|
514
|
+
pend=0; anypend=0; seen=$'\n'
|
|
515
|
+
mapfile -t chk_rows < <(gh pr checks "$PR" --json name,bucket \
|
|
516
|
+
--jq '.[] | "\(.bucket)\t\(.name)"' 2>/dev/null || true)
|
|
517
|
+
if (( ${#chk_rows[@]} > 0 )); then
|
|
518
|
+
for row in "${chk_rows[@]}"; do
|
|
519
|
+
n="${row#*$'\t'}"; seen+="$n"$'\n'
|
|
520
|
+
[[ "${row%%$'\t'*}" == pending ]] || continue
|
|
521
|
+
anypend=$((anypend+1))
|
|
522
|
+
for r in "${REQUIRED_CHECKS[@]}"; do
|
|
523
|
+
[[ "$n" == "$r" ]] && { pend=$((pend+1)); break; }
|
|
524
|
+
done
|
|
525
|
+
done
|
|
526
|
+
fi
|
|
527
|
+
# A required check that does not exist yet (the `test` aggregate is created only after its shards finish) is not
|
|
528
|
+
# settled while any check is still running; with nothing running it will not appear, so it counts as idle.
|
|
529
|
+
if (( anypend > 0 )); then
|
|
530
|
+
for r in "${REQUIRED_CHECKS[@]}"; do [[ "$seen" == *$'\n'"$r"$'\n'* ]] || pend=$((pend+1)); done
|
|
531
|
+
fi
|
|
532
|
+
if (( pend > 0 )); then qidle=0; else qidle=$((qidle+1)); fi
|
|
533
|
+
if (( qidle > QUEUE_GRACE_TICKS )); then
|
|
534
|
+
qwait=0; qwait_expired=1
|
|
535
|
+
echo "$(date +%H:%M:%S) [${i}/${MAX_POLL_MIN}] [ship.phase7.queue_wait_expired] PR $PR has been BEHIND with auto-merge armed and no required check pending for ${qidle} ticks and this poll's last queue read did not show it queued. Falling back to the BEHIND auto-sync for the rest of this poll (a PR already in the merge queue is skipped by it, never pushed to). Before changing the ruleset, diagnose: ${CLAUDE_PLUGIN_ROOT}/skills/ship/references/merge-queue-dequeue.md (the strict policy was measured once not to block enqueue)."
|
|
536
|
+
fi
|
|
537
|
+
fi
|
|
538
|
+
(( qwait == 1 )) || qidle=0
|
|
539
|
+
if [[ "$qwait" -eq 1 ]]; then
|
|
540
|
+
queue_waits=$((queue_waits+1))
|
|
541
|
+
(( queue_waits == 1 )) && echo "$(date +%H:%M:%S) [${i}/${MAX_POLL_MIN}] [ship.phase7.queue_wait] PR $PR is BEHIND with auto-merge armed and main has a merge queue: no sync (a push restarts CI and dequeues a queued PR); waiting for GitHub to enqueue it"
|
|
542
|
+
elif [[ "$s" == "OPEN BEHIND" && "$sync_ok" -eq 1 && "$behind_syncs" -lt "$MAX_BEHIND_SYNCS" ]]; then
|
|
543
|
+
# ci_cycles cap gate (#9403): STOP writes the budget-capped artifact to
|
|
544
|
+
# specs/<branch>/session-state.md and breaks the WHOLE poll.
|
|
545
|
+
if [[ "$(bash "$SYNC_ROOT/scripts/pipeline-tally.sh" gate ci_cycles 2>/dev/null || true)" == "STOP" ]]; then
|
|
546
|
+
echo "$(date +%H:%M:%S) auto-sync halted — ci_cycles budget-capped"
|
|
547
|
+
bash "$SYNC_ROOT/scripts/write-budget-marker.sh" ci_cycles || true
|
|
548
|
+
break
|
|
549
|
+
fi
|
|
550
|
+
behind_syncs=$((behind_syncs+1))
|
|
551
|
+
echo "$(date +%H:%M:%S) [${i}/${MAX_POLL_MIN}] BEHIND detected — auto-sync attempt ${behind_syncs}/${MAX_BEHIND_SYNCS}"
|
|
552
|
+
sync_rc=0; bash "$SYNC_SNAP" "$PR" --step || sync_rc=$? # errexit-safe (#8339)
|
|
553
|
+
case "$sync_rc" in
|
|
554
|
+
0) echo "$(date +%H:%M:%S) [${i}/${MAX_POLL_MIN}] auto-sync ${behind_syncs}/${MAX_BEHIND_SYNCS} pushed"
|
|
555
|
+
behind_pushes=$((behind_pushes+1))
|
|
556
|
+
bash "$SYNC_ROOT/scripts/pipeline-tally.sh" incr ci_cycles || true
|
|
557
|
+
(( behind_pushes == 2 )) && echo "$(date +%H:%M:%S) [${i}/${MAX_POLL_MIN}] [ship.phase7.hatch_check] 2 BEHIND syncs pushed — read ${CLAUDE_PLUGIN_ROOT}/skills/ship/references/settle-then-admin-merge.md now; it classifies eligibility (else keep polling)"
|
|
558
|
+
s=$(gh pr view "$PR" --json state,mergeStateStatus \
|
|
559
|
+
--jq '"\(.state) \(.mergeStateStatus)"' 2>&1) \
|
|
560
|
+
|| s="fetch-error: $s"
|
|
561
|
+
echo "$s" | grep -qE "^(MERGED|CLOSED|fetch-error)" && break ;;
|
|
562
|
+
11) behind_syncs=$((behind_syncs-1)) # no-op: GitHub state lag, not a sync — budget and hatch untouched
|
|
563
|
+
echo "$(date +%H:%M:%S) [${i}/${MAX_POLL_MIN}] [ship.phase7.sync_noop] no sync needed (state lag or queued) — not counted, polling on" ;;
|
|
564
|
+
5) fetch_failures=$((fetch_failures+1))
|
|
565
|
+
echo "$(date +%H:%M:%S) [${i}/${MAX_POLL_MIN}] [ship.phase7.sync_failed] kind=fetch — skipping this sync attempt" ;;
|
|
566
|
+
*) echo "$(date +%H:%M:%S) [${i}/${MAX_POLL_MIN}] [ship.phase7.sync_failed] sync-pr-behind.sh exited $sync_rc (see its line above). Stopping the poll."
|
|
567
|
+
break ;;
|
|
568
|
+
esac
|
|
569
|
+
elif [[ "$s" == "OPEN BEHIND" && "$sync_ok" -eq 0 ]]; then
|
|
570
|
+
echo "$(date +%H:%M:%S) [${i}/${MAX_POLL_MIN}] [ship.phase7.behind_no_sync] PR $PR is BEHIND and auto-sync is disabled (precondition line above). From the PR worktree run:" 'bash "${CLAUDE_PLUGIN_ROOT}/scripts/sync-pr-behind.sh"' "$PR" "after export CLAUDE_PLUGIN_ROOT=<the installed soleur plugin root>; exit 8 after a kind=pushed line means the push landed. Then re-arm the poll. Stopping the poll."
|
|
571
|
+
break
|
|
572
|
+
elif [[ "$s" == "OPEN BEHIND" && "$sync_ok" -eq 1 && "$behind_syncs" -ge "$MAX_BEHIND_SYNCS" && "$behind_warned" -eq 0 ]]; then
|
|
573
|
+
elapsed=$((i * 60))
|
|
574
|
+
if (( fetch_failures == MAX_BEHIND_SYNCS )); then
|
|
575
|
+
echo "$(date +%H:%M:%S) [${i}/${MAX_POLL_MIN}] [ship.phase7.behind_exhausted] BEHIND budget exhausted after ${MAX_BEHIND_SYNCS} auto-syncs in ${elapsed}s (fetch_failures=${fetch_failures}/${MAX_BEHIND_SYNCS}). Every attempt failed at git fetch — a network/credential outage, not main moving. Check connectivity and credentials, then re-arm the poll."
|
|
576
|
+
else
|
|
577
|
+
echo "$(date +%H:%M:%S) [${i}/${MAX_POLL_MIN}] [ship.phase7.behind_exhausted] BEHIND budget exhausted after ${MAX_BEHIND_SYNCS} auto-syncs in ${elapsed}s (fetch_failures=${fetch_failures}/${MAX_BEHIND_SYNCS}; attempts that failed at fetch never synced). origin/main is moving faster than this PR's CI cycle. Recommendation: for a zero-conflict-surface change, use the settle-then-admin-merge escape hatch (admin-merge-ready.sh <PR> <sha> must exit 0, then gh pr merge --squash --admin --match-head-commit <sha> — full procedure: ${CLAUDE_PLUGIN_ROOT}/skills/ship/references/settle-then-admin-merge.md); else merge during a quieter window."
|
|
578
|
+
fi
|
|
579
|
+
behind_warned=1
|
|
580
|
+
fi
|
|
581
|
+
|
|
582
|
+
if [ "$i" -ge "$MAX_POLL_MIN" ]; then
|
|
583
|
+
echo "Merge poll timed out after ${MAX_POLL_MIN} minutes. Last state: $s"
|
|
584
|
+
[[ -n "$SYNC_SNAP" ]] && echo "Queue: $(bash "$SYNC_SNAP" "$PR" --queue-state 2>&1 | head -1)"
|
|
585
|
+
break
|
|
586
|
+
fi
|
|
587
|
+
sleep 60
|
|
588
|
+
done
|
|
589
|
+
# <!-- phase-7-poll-block:end -->
|
|
590
|
+
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
If the loop exits with state `CLOSED` (not `MERGED`), auto-merge was cancelled — check for CI failures:
|
|
594
|
+
|
|
595
|
+
```bash
|
|
596
|
+
gh pr checks <number> --json name,state,bucket,description,link | jq '.[] | select(.bucket != "pass" and .bucket != "skipping")'
|
|
597
|
+
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
Stop and report:
|
|
601
|
+
|
|
602
|
+
```text
|
|
603
|
+
STOPPED: CI check failed.
|
|
604
|
+
|
|
605
|
+
Failed checks:
|
|
606
|
+
<check name>: <link>
|
|
607
|
+
|
|
608
|
+
Starting SHA for rollback: <starting-sha>
|
|
609
|
+
To rollback: git reset --hard <starting-sha> && git push --force-with-lease origin <branch-name>
|
|
610
|
+
|
|
611
|
+
```
|
|
612
|
+
|
|
613
|
+
The state-machine details (`mergeStateStatus` enum coverage, fail-open required-check fetch, fixture at `plugins/soleur/test/ship-phase-7-poll-fixtures.test.sh`) are documented in `plugins/soleur/skills/ship/SKILL.md` Phase 7. When the poll prints `[ship.phase7.hatch_check]` (2 BEHIND syncs pushed) or `[ship.phase7.behind_exhausted]`, read [settle-then-admin-merge.md](${CLAUDE_PLUGIN_ROOT}/skills/ship/references/settle-then-admin-merge.md) for the settle-then-admin-merge escape hatch (zero-conflict-surface changes only). Any `--admin` merge, whether through this hatch or authorized by the operator, requires `"${CLAUDE_PLUGIN_ROOT}/scripts/admin-merge-ready.sh" <PR> <sha>` to exit 0 immediately before it and `--match-head-commit <sha>` on the merge; `gh pr checks --required` is not a substitute, because it cannot see a required check that has not been created yet (#8458, #8500). When the operator authorizes `--admin` on a BEHIND PR whose prior head was green, the surface classifier is waived but the gate is not: `--green-sha <prior-green-sha>` carries the certification to the new head only if it is GitHub's own verified merge of that sha and the base (see the reference's "was-green carryover" section); for a hand-made local unsigned merge — the #9401 disjoint-skip leaves the green head itself intact, so it needs no carryover — `--allow-local-merge` admits it only when the added delta is a byte-identical docs-only replay disjoint from the PR's files. UNTRUSTED-CI and DIRTY still refuse. On `[ship.phase7.required_failed]` or `[ship.phase7.dirty]`, follow ship/SKILL.md Phase 7's handling for a poll that exits on a required-check failure or a DIRTY state (`gh pr checks <N>` to inspect; `git merge origin/main` to resolve locally). On a `[ship.phase7.sync_failed]` line ending `Stopping the poll.` (a `kind=fetch` one is informational — the poll continues), do the next action the `[pr-behind-sync] kind=…` line above it names (resolve and push, reconcile a concurrent push, or clear the worktree state), then re-invoke this §5.2 poll — a routine conflict is not an operator handoff. `[ship.phase7.sync_noop]` is GitHub state lag or a PR in the merge queue (uncounted; the poll continues; never push to a queued PR); a `sync_failed` line with `kind=dequeued` means the PR left the queue unmerged: follow the recovery on that line (see ${CLAUDE_PLUGIN_ROOT}/skills/ship/references/merge-queue-dequeue.md, also for a poll that times out OPEN and not queued); `[ship.phase7.behind_no_sync]` means auto-sync was disabled — run the printed command from the PR worktree, then re-arm the poll. `[ship.phase7.queue_wait]` is informational: `main` has a merge queue and the PR is armed, so the poll waits for GitHub to enqueue it instead of syncing (a push restarts CI and dequeues a queued PR) — take no action and never sync, update-branch or merge it by hand until `[ship.phase7.queue_wait_expired]`, a push line, MERGED, a dequeue or any poll exit; `[ship.phase7.queued]` prints once, at the first 5th-tick read that finds the PR in the queue; `[ship.phase7.queue_wait_expired]` means no required check is pending and this poll's last queue read did not show the PR queued, so the poll fell back to the BEHIND auto-sync — keep the Monitor running, diagnose (merge-queue-dequeue.md, the PR timeline), record the strict up-to-date question in the final report and do not change the ruleset (ship/SKILL.md Phase 7, "Queue mode").
|
|
614
|
+
|
|
615
|
+
## Phase 6: Cleanup and Report
|
|
616
|
+
|
|
617
|
+
### 6.1 Navigate to repo root
|
|
618
|
+
|
|
619
|
+
The `cleanup-merged` script skips the current working directory's worktree. Navigate to the main repo root first:
|
|
620
|
+
|
|
621
|
+
Navigate to the main repository root directory (the parent of `.worktrees/`). Run `cd` to the repo root path, then verify with `pwd`.
|
|
622
|
+
|
|
623
|
+
### 6.2 Run cleanup
|
|
624
|
+
|
|
625
|
+
```bash
|
|
626
|
+
bash "${CLAUDE_PLUGIN_ROOT}/skills/git-worktree/scripts/worktree-manager.sh" cleanup-merged
|
|
627
|
+
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
This reaps branches proven merged (an ancestor of main, or a merged same-repo PR whose head contains the branch tip — the path a squash-merged, auto-deleted branch takes), removes their worktrees, deletes the local branches, and pulls latest main. A `[gone]` branch with no merge evidence is kept and reported so the next worktree branches from the current state.
|
|
631
|
+
|
|
632
|
+
### 6.3 End-of-run report
|
|
633
|
+
|
|
634
|
+
Print a summary:
|
|
635
|
+
|
|
636
|
+
```text
|
|
637
|
+
merge-pr complete!
|
|
638
|
+
|
|
639
|
+
PR: #<number> (<URL>)
|
|
640
|
+
Merge SHA: <sha>
|
|
641
|
+
Cleanup: <worktrees cleaned or "no cleanup needed">
|
|
642
|
+
|
|
643
|
+
Rollback (if needed): git reset --hard <starting-sha>
|
|
644
|
+
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
Replace `<starting-sha>` with the SHA recorded at the start of the pipeline.
|
|
648
|
+
|
|
649
|
+
## Rollback
|
|
650
|
+
|
|
651
|
+
If the pipeline fails partway through and the branch has unwanted commits (e.g., merge commit), rollback to the starting state:
|
|
652
|
+
|
|
653
|
+
```bash
|
|
654
|
+
git reset --hard <starting-sha>
|
|
655
|
+
git push --force-with-lease origin <branch-name>
|
|
656
|
+
|
|
657
|
+
```
|
|
658
|
+
|
|
659
|
+
Replace `<starting-sha>` and `<branch-name>` with the actual values recorded at pipeline start.
|
|
660
|
+
|
|
661
|
+
The starting SHA is recorded in Phase 0 and printed in the end-of-run report.
|
|
662
|
+
|
|
663
|
+
## Important Rules
|
|
664
|
+
|
|
665
|
+
- **On any failure: stop and report.** Do not retry, do not guess, do not continue.
|
|
666
|
+
- **Never use `--delete-branch`** with `gh pr merge`. Use `cleanup-merged` for branch deletion.
|
|
667
|
+
- **Never commit on main.** All commits happen on the feature branch.
|
|
668
|
+
- **CHANGELOG integrity is critical.** Read both sides via `:2:` and `:3:` stage numbers. Verify line count after writing. Never truncate.
|