@soleur/opencode 0.0.0-stage → 3.354.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/agents.manifest.json +476 -0
- package/.claude-plugin/plugin.json +42 -0
- package/README.md +44 -2
- package/agents/community/.gitkeep +0 -0
- package/agents/engineering/cto.md +87 -0
- package/agents/engineering/design/ddd-architect.md +95 -0
- package/agents/engineering/discovery/agent-finder.md +214 -0
- package/agents/engineering/discovery/functional-discovery.md +182 -0
- package/agents/engineering/infra/infra-security.md +151 -0
- package/agents/engineering/infra/platform-strategist.md +109 -0
- package/agents/engineering/infra/terraform-architect.md +171 -0
- package/agents/engineering/prompt-engineer.md +37 -0
- package/agents/engineering/research/best-practices-researcher.md +115 -0
- package/agents/engineering/research/framework-docs-researcher.md +93 -0
- package/agents/engineering/research/git-history-analyzer.md +53 -0
- package/agents/engineering/research/learnings-researcher.md +285 -0
- package/agents/engineering/research/repo-research-analyst.md +118 -0
- package/agents/engineering/review/agent-native-reviewer.md +279 -0
- package/agents/engineering/review/architecture-strategist.md +61 -0
- package/agents/engineering/review/code-quality-analyst.md +92 -0
- package/agents/engineering/review/code-simplicity-reviewer.md +109 -0
- package/agents/engineering/review/data-integrity-guardian.md +82 -0
- package/agents/engineering/review/data-migration-expert.md +98 -0
- package/agents/engineering/review/deployment-verification-agent.md +183 -0
- package/agents/engineering/review/dhh-rails-reviewer.md +46 -0
- package/agents/engineering/review/kieran-rails-reviewer.md +87 -0
- package/agents/engineering/review/legacy-code-expert.md +55 -0
- package/agents/engineering/review/observability-coverage-reviewer.md +147 -0
- package/agents/engineering/review/pattern-recognition-specialist.md +59 -0
- package/agents/engineering/review/performance-oracle.md +130 -0
- package/agents/engineering/review/security-sentinel.md +167 -0
- package/agents/engineering/review/semgrep-sast.md +36 -0
- package/agents/engineering/review/test-design-reviewer.md +150 -0
- package/agents/engineering/review/user-impact-reviewer.md +70 -0
- package/agents/engineering/workflow/pr-comment-resolver.md +69 -0
- package/agents/finance/budget-analyst.md +29 -0
- package/agents/finance/cfo.md +44 -0
- package/agents/finance/financial-reporter.md +30 -0
- package/agents/finance/revenue-analyst.md +30 -0
- package/agents/legal/clo.md +115 -0
- package/agents/legal/legal-compliance-auditor.md +110 -0
- package/agents/legal/legal-document-generator.md +134 -0
- package/agents/marketing/analytics-analyst.md +25 -0
- package/agents/marketing/brand-architect.md +181 -0
- package/agents/marketing/cmo.md +76 -0
- package/agents/marketing/conversion-optimizer.md +19 -0
- package/agents/marketing/copywriter.md +20 -0
- package/agents/marketing/fact-checker.md +70 -0
- package/agents/marketing/growth-strategist.md +145 -0
- package/agents/marketing/paid-media-strategist.md +28 -0
- package/agents/marketing/pricing-strategist.md +17 -0
- package/agents/marketing/programmatic-seo-specialist.md +25 -0
- package/agents/marketing/retention-strategist.md +23 -0
- package/agents/marketing/seo-aeo-analyst.md +164 -0
- package/agents/operations/coo.md +50 -0
- package/agents/operations/ops-advisor.md +78 -0
- package/agents/operations/ops-provisioner.md +101 -0
- package/agents/operations/ops-research.md +52 -0
- package/agents/operations/service-automator.md +278 -0
- package/agents/product/business-validator.md +206 -0
- package/agents/product/competitive-intelligence.md +89 -0
- package/agents/product/cpo.md +63 -0
- package/agents/product/design/ux-design-lead.md +209 -0
- package/agents/product/spec-flow-analyzer.md +122 -0
- package/agents/sales/cro.md +44 -0
- package/agents/sales/deal-architect.md +29 -0
- package/agents/sales/outbound-strategist.md +29 -0
- package/agents/sales/pipeline-analyst.md +29 -0
- package/agents/support/cco.md +48 -0
- package/agents/support/community-manager.md +570 -0
- package/agents/support/ticket-triage.md +70 -0
- package/bin/soleur-opencode.js +29 -0
- package/commands/go.md +660 -0
- package/commands/help.md +273 -0
- package/commands/sync.md +977 -0
- package/commands/version.md +103 -0
- package/hooks/antigravity-hooks.json +84 -0
- package/hooks/antigravity-session-start.sh +15 -0
- package/hooks/bare-root-cwd-guard.sh +131 -0
- package/hooks/browser-snapshot-credential-guard.sh +200 -0
- package/hooks/codex-session-start.sh +9 -0
- package/hooks/compaction-state.sh +525 -0
- package/hooks/destructive-command-guard.sh +1387 -0
- package/hooks/devin-session-start.sh +90 -0
- package/hooks/ext-filter-detect.sh +171 -0
- package/hooks/hooks.json +133 -0
- package/hooks/lib/hook-tool-kind.sh +24 -0
- package/hooks/lib/log-rotation.sh +176 -0
- package/hooks/lib/shell-argv.pl +576 -0
- package/hooks/memory-backstop.sh +1114 -0
- package/hooks/operator-stage-approval.sh +391 -0
- package/hooks/stop-hook.sh +367 -0
- package/hooks/unkept-promise-hook.sh +383 -0
- package/hooks/version-banner.sh +127 -0
- package/hooks/welcome-hook.sh +50 -0
- package/install.js +29 -0
- package/lib/agent-registry.ts +154 -0
- package/lib/c4-canonical-cli.mjs +34 -0
- package/lib/c4-canonical.mjs +46 -0
- package/lib/c4-from-components.ts +554 -0
- package/lib/go-routing.ts +81 -0
- package/lib/grok-inspect-contract.ts +311 -0
- package/lib/harness-model-map.ts +101 -0
- package/lib/harness-parity.ts +726 -0
- package/lib/harness-tool-map.ts +180 -0
- package/lib/harness.ts +716 -0
- package/lib/heartbeat-live-reconcile.ts +1153 -0
- package/lib/heartbeat-manifest.ts +361 -0
- package/lib/kb-coverage.ts +252 -0
- package/lib/pr-merge-poll.ts +103 -0
- package/lib/workflow-fidelity.ts +388 -0
- package/opencode/INSTRUCTIONS.md +171 -0
- package/opencode/agents/engineering/cto.md +10 -0
- package/opencode/agents/engineering/design/ddd-architect.md +10 -0
- package/opencode/agents/engineering/discovery/agent-finder.md +10 -0
- package/opencode/agents/engineering/discovery/functional-discovery.md +10 -0
- package/opencode/agents/engineering/infra/infra-security.md +10 -0
- package/opencode/agents/engineering/infra/platform-strategist.md +10 -0
- package/opencode/agents/engineering/infra/terraform-architect.md +10 -0
- package/opencode/agents/engineering/prompt-engineer.md +10 -0
- package/opencode/agents/engineering/research/best-practices-researcher.md +10 -0
- package/opencode/agents/engineering/research/framework-docs-researcher.md +10 -0
- package/opencode/agents/engineering/research/git-history-analyzer.md +10 -0
- package/opencode/agents/engineering/research/learnings-researcher.md +10 -0
- package/opencode/agents/engineering/research/repo-research-analyst.md +10 -0
- package/opencode/agents/engineering/review/agent-native-reviewer.md +10 -0
- package/opencode/agents/engineering/review/architecture-strategist.md +10 -0
- package/opencode/agents/engineering/review/code-quality-analyst.md +10 -0
- package/opencode/agents/engineering/review/code-simplicity-reviewer.md +10 -0
- package/opencode/agents/engineering/review/data-integrity-guardian.md +10 -0
- package/opencode/agents/engineering/review/data-migration-expert.md +10 -0
- package/opencode/agents/engineering/review/deployment-verification-agent.md +10 -0
- package/opencode/agents/engineering/review/dhh-rails-reviewer.md +10 -0
- package/opencode/agents/engineering/review/kieran-rails-reviewer.md +10 -0
- package/opencode/agents/engineering/review/legacy-code-expert.md +10 -0
- package/opencode/agents/engineering/review/observability-coverage-reviewer.md +10 -0
- package/opencode/agents/engineering/review/pattern-recognition-specialist.md +10 -0
- package/opencode/agents/engineering/review/performance-oracle.md +10 -0
- package/opencode/agents/engineering/review/security-sentinel.md +10 -0
- package/opencode/agents/engineering/review/semgrep-sast.md +10 -0
- package/opencode/agents/engineering/review/test-design-reviewer.md +10 -0
- package/opencode/agents/engineering/review/user-impact-reviewer.md +10 -0
- package/opencode/agents/engineering/workflow/pr-comment-resolver.md +10 -0
- package/opencode/agents/finance/budget-analyst.md +10 -0
- package/opencode/agents/finance/cfo.md +10 -0
- package/opencode/agents/finance/financial-reporter.md +10 -0
- package/opencode/agents/finance/revenue-analyst.md +10 -0
- package/opencode/agents/legal/clo.md +10 -0
- package/opencode/agents/legal/legal-compliance-auditor.md +10 -0
- package/opencode/agents/legal/legal-document-generator.md +10 -0
- package/opencode/agents/marketing/analytics-analyst.md +10 -0
- package/opencode/agents/marketing/brand-architect.md +10 -0
- package/opencode/agents/marketing/cmo.md +10 -0
- package/opencode/agents/marketing/conversion-optimizer.md +10 -0
- package/opencode/agents/marketing/copywriter.md +10 -0
- package/opencode/agents/marketing/fact-checker.md +10 -0
- package/opencode/agents/marketing/growth-strategist.md +10 -0
- package/opencode/agents/marketing/paid-media-strategist.md +10 -0
- package/opencode/agents/marketing/pricing-strategist.md +10 -0
- package/opencode/agents/marketing/programmatic-seo-specialist.md +10 -0
- package/opencode/agents/marketing/retention-strategist.md +10 -0
- package/opencode/agents/marketing/seo-aeo-analyst.md +10 -0
- package/opencode/agents/operations/coo.md +10 -0
- package/opencode/agents/operations/ops-advisor.md +10 -0
- package/opencode/agents/operations/ops-provisioner.md +10 -0
- package/opencode/agents/operations/ops-research.md +10 -0
- package/opencode/agents/operations/service-automator.md +10 -0
- package/opencode/agents/product/business-validator.md +10 -0
- package/opencode/agents/product/competitive-intelligence.md +10 -0
- package/opencode/agents/product/cpo.md +10 -0
- package/opencode/agents/product/design/ux-design-lead.md +10 -0
- package/opencode/agents/product/spec-flow-analyzer.md +10 -0
- package/opencode/agents/sales/cro.md +10 -0
- package/opencode/agents/sales/deal-architect.md +10 -0
- package/opencode/agents/sales/outbound-strategist.md +10 -0
- package/opencode/agents/sales/pipeline-analyst.md +10 -0
- package/opencode/agents/support/cco.md +10 -0
- package/opencode/agents/support/community-manager.md +10 -0
- package/opencode/agents/support/ticket-triage.md +10 -0
- package/opencode/commands/go.md +10 -0
- package/opencode/commands/help.md +10 -0
- package/opencode/commands/sync.md +10 -0
- package/opencode/commands/version.md +11 -0
- package/opencode/opencode.json +8 -0
- package/opencode/plugin.ts +818 -0
- package/package.json +36 -4
- package/scripts/admin-merge-ready.sh +545 -0
- package/scripts/admin-merge-ready.test.sh +753 -0
- package/scripts/affected-tests.sh +908 -0
- package/scripts/affected-tests.test.sh +1797 -0
- package/scripts/alpha-metrics.sh +78 -0
- package/scripts/alpha-metrics.test.sh +115 -0
- package/scripts/ancestor-signal-helpers.baseline.txt +16 -0
- package/scripts/audit-flag-flip.sh +107 -0
- package/scripts/check-red-on-main.sh +316 -0
- package/scripts/ci-head-verdict.sh +411 -0
- package/scripts/cloud-detect.sh +193 -0
- package/scripts/delegation-verify.sh +657 -0
- package/scripts/delegation-verify.test.sh +1424 -0
- package/scripts/deploy-arm.sh +475 -0
- package/scripts/domain-model-drift.sh +419 -0
- package/scripts/emit-decision.sh +144 -0
- package/scripts/emit-decision.test.sh +144 -0
- package/scripts/ext-filter-divergence-corpus.txt +15 -0
- package/scripts/ext-filter-divergence.sh +189 -0
- package/scripts/generate-c4-from-components.ts +442 -0
- package/scripts/grok-fidelity-gate.sh +68 -0
- package/scripts/grok-pre-push-gate.sh +232 -0
- package/scripts/harness-discovery-smoke.ts +906 -0
- package/scripts/harness-parity-census.ts +92 -0
- package/scripts/inngest-luks-alert-armed-probe.ts +29 -0
- package/scripts/install-opencode-adapter.ts +509 -0
- package/scripts/lib/affected-tests/common.sh +365 -0
- package/scripts/lib/affected-tests/go.sh +157 -0
- package/scripts/lib/affected-tests/js.sh +188 -0
- package/scripts/lib/affected-tests/nx-turbo.sh +98 -0
- package/scripts/lib/affected-tests/python.sh +185 -0
- package/scripts/lib/context-sanitize.sh +49 -0
- package/scripts/lib/domain-model-lib.sh +180 -0
- package/scripts/lib/ext-filter-grammar.tsv +34 -0
- package/scripts/lib/operator-script.sh +1236 -0
- package/scripts/lib/proc.sh +580 -0
- package/scripts/lib/session-state.sh +748 -0
- package/scripts/lib/tmp-classify.sh +843 -0
- package/scripts/lib/wrapper-boundary.sh +47 -0
- package/scripts/lint-ratchet.py +1547 -0
- package/scripts/monitor-pr-checks.sh +441 -0
- package/scripts/pipeline-tally.sh +756 -0
- package/scripts/pipeline-tally.test.sh +740 -0
- package/scripts/plugin-version.sh +528 -0
- package/scripts/precommit-guard.sh +115 -0
- package/scripts/precommit-guard.test.sh +254 -0
- package/scripts/reconcile-live-heartbeats.ts +705 -0
- package/scripts/render-c4-model.sh +217 -0
- package/scripts/resolve-git-root.sh +55 -0
- package/scripts/resolve-regenerable-conflicts.sh +363 -0
- package/scripts/resolve-regenerable-conflicts.test.sh +780 -0
- package/scripts/ruff-requirements.txt +22 -0
- package/scripts/run-in-pid-namespace.sh +98 -0
- package/scripts/run-in-pid-namespace.test.sh +290 -0
- package/scripts/scan-ancestor-signal-helpers.py +556 -0
- package/scripts/scan-ancestor-signal-helpers.test.sh +670 -0
- package/scripts/setup-ralph-loop.sh +238 -0
- package/scripts/sync-cursor-name-map.ts +316 -0
- package/scripts/sync-grok-agent-compat.ts +188 -0
- package/scripts/sync-npm-package.ts +165 -0
- package/scripts/sync-opencode-adapter.ts +498 -0
- package/scripts/sync-pr-behind.sh +647 -0
- package/scripts/sync-pr-behind.test.sh +252 -0
- package/scripts/taste-profile-update.sh +180 -0
- package/scripts/taste-profile-update.test.sh +167 -0
- package/scripts/write-budget-marker.sh +23 -0
- package/scripts/write-kb-coverage.ts +113 -0
- package/skills/admin-ip-refresh/SKILL.md +81 -0
- package/skills/admin-ip-refresh/references/admin-ip-refresh-procedure.md +201 -0
- package/skills/agent-browser/SKILL.md +698 -0
- package/skills/agent-browser/scripts/playwright-mcp-profile-slot.sh +304 -0
- package/skills/agent-browser/scripts/playwright-mcp-redact-proxy.py +964 -0
- package/skills/agent-browser/scripts/redact-a11y-snapshot.py +443 -0
- package/skills/agent-browser/test/fixtures/capture-playwright-mcp-fixtures.py +217 -0
- package/skills/agent-browser/test/fixtures/fake-passthrough-proxy.py +24 -0
- package/skills/agent-browser/test/fixtures/fake-playwright-mcp.py +131 -0
- package/skills/agent-browser/test/fixtures/make-proxy-mutant.py +48 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/dialog-link-injection.json +10 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/empty-content.json +5 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/error-and-result.json +4 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/error-code-bool.json +6 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/error-code-string.json +6 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/error-message-tree.json +6 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/error-no-data.json +6 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/error-string.json +4 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/error-with-data.json +9 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/evaluate-escaped-object.json +10 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/invalid-utf8.json +4 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/link-result.json +10 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/list-two-results.json +6 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/meta-in-result.json +13 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/no-content.json +5 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/quoted-key.json +10 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/resource-block.json +18 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/result-and-method.json +11 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/result-string.json +3 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/run-code-escaped-one-row.json +10 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/run-code-escaped.json +10 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/structured-content.json +13 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/tools-list-no-tools.json +5 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/tree-no-credential.json +10 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/two-text-blocks.json +14 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/unparsable-line.json +3 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/value-contains-brace.json +10 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/value-contains-link-substring.json +10 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/close.json +12 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/evaluate.json +12 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/find.json +12 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/framing.json +6 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/initialize.json +14 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/navigate-link.json +12 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/navigate.json +12 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/roots-list-request.json +5 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/screenshot.json +17 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/snapshot-filename.json +12 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/snapshot-meta-json.json +12 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/snapshot-meta-raw.json +12 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/snapshot.json +12 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/tools-list.json +827 -0
- package/skills/agent-browser/test/fixtures/proxy-session-driver.py +138 -0
- package/skills/agent-browser/test/fixtures/session-facts.py +102 -0
- package/skills/agent-browser/test/playwright-mcp-lifetime.test.sh +1620 -0
- package/skills/agent-browser/test/playwright-mcp-redact-proxy.test.sh +1599 -0
- package/skills/agent-browser/test/redact-a11y-snapshot.test.sh +527 -0
- package/skills/agent-native-architecture/SKILL.md +479 -0
- package/skills/agent-native-architecture/references/action-parity-discipline.md +430 -0
- package/skills/agent-native-architecture/references/agent-execution-patterns.md +483 -0
- package/skills/agent-native-architecture/references/agent-native-testing.md +605 -0
- package/skills/agent-native-architecture/references/architecture-patterns.md +493 -0
- package/skills/agent-native-architecture/references/dynamic-context-injection.md +358 -0
- package/skills/agent-native-architecture/references/files-universal-interface.md +314 -0
- package/skills/agent-native-architecture/references/from-primitives-to-domain-tools.md +381 -0
- package/skills/agent-native-architecture/references/mcp-tool-design.md +524 -0
- package/skills/agent-native-architecture/references/mobile-patterns.md +897 -0
- package/skills/agent-native-architecture/references/product-implications.md +478 -0
- package/skills/agent-native-architecture/references/refactoring-to-prompt-native.md +342 -0
- package/skills/agent-native-architecture/references/self-modification.md +294 -0
- package/skills/agent-native-architecture/references/shared-workspace-architecture.md +700 -0
- package/skills/agent-native-architecture/references/system-prompt-design.md +263 -0
- package/skills/agent-native-audit/SKILL.md +300 -0
- package/skills/agent-native-audit/workflows/agent-native-audit.workflow.js +423 -0
- package/skills/andrew-kane-gem-writer/SKILL.md +189 -0
- package/skills/andrew-kane-gem-writer/references/database-adapters.md +231 -0
- package/skills/andrew-kane-gem-writer/references/module-organization.md +121 -0
- package/skills/andrew-kane-gem-writer/references/rails-integration.md +183 -0
- package/skills/andrew-kane-gem-writer/references/resources.md +126 -0
- package/skills/andrew-kane-gem-writer/references/testing-patterns.md +261 -0
- package/skills/architecture/SKILL.md +436 -0
- package/skills/architecture/references/adr-template.md +154 -0
- package/skills/architecture/references/likec4-reference.md +136 -0
- package/skills/architecture/references/nfr-reference.md +126 -0
- package/skills/archive-kb/SKILL.md +86 -0
- package/skills/archive-kb/scripts/archive-kb.sh +300 -0
- package/skills/archive-kb/test/archive-kb-partial-run.test.sh +276 -0
- package/skills/atdd-developer/SKILL.md +65 -0
- package/skills/brainstorm/SKILL.md +701 -0
- package/skills/brainstorm/references/brainstorm-brand-workshop.md +153 -0
- package/skills/brainstorm/references/brainstorm-domain-config.md +63 -0
- package/skills/brainstorm/references/brainstorm-validation-workshop.md +65 -0
- package/skills/brainstorm/references/ui-surface-terms.md +42 -0
- package/skills/brainstorm-techniques/SKILL.md +231 -0
- package/skills/brainstorm-techniques/references/decision-principles.md +150 -0
- package/skills/brainstorm-techniques/references/phase-boundaries.md +103 -0
- package/skills/brainstorm-techniques/references/standing-delegation.md +407 -0
- package/skills/brainstorm-techniques/references/technical-ruling-delegation.md +174 -0
- package/skills/campaign-calendar/SKILL.md +145 -0
- package/skills/cf-token-scope/SKILL.md +164 -0
- package/skills/cf-token-scope/references/widen-playbook.md +114 -0
- package/skills/cf-token-scope/scripts/cf-token-scope.sh +253 -0
- package/skills/changelog/SKILL.md +142 -0
- package/skills/code-to-prd/SKILL.md +66 -0
- package/skills/code-to-prd/references/banner-template.md +12 -0
- package/skills/code-to-prd/references/prd-template.md +41 -0
- package/skills/code-to-prd/scripts/code-to-prd.sh +634 -0
- package/skills/code-to-prd/test/code-to-prd.test.sh +447 -0
- package/skills/code-to-prd/test/fixture/.env.example +7 -0
- package/skills/code-to-prd/test/fixture/app/about/page.tsx +11 -0
- package/skills/code-to-prd/test/fixture/app/api/health/route.ts +10 -0
- package/skills/code-to-prd/test/fixture/app/page.tsx +14 -0
- package/skills/code-to-prd/test/fixture/next.config.mjs +3 -0
- package/skills/code-to-prd/test/fixture/package.json +6 -0
- package/skills/cohort-status/SKILL.md +62 -0
- package/skills/community/SKILL.md +210 -0
- package/skills/community/scripts/bsky-community.sh +644 -0
- package/skills/community/scripts/bsky-setup.sh +631 -0
- package/skills/community/scripts/community-router.sh +93 -0
- package/skills/community/scripts/discord-community.sh +487 -0
- package/skills/community/scripts/discord-setup.sh +784 -0
- package/skills/community/scripts/github-community.sh +706 -0
- package/skills/community/scripts/hn-community.sh +233 -0
- package/skills/community/scripts/lib/hmac-sha1-b64.sh +126 -0
- package/skills/community/scripts/linkedin-community.sh +750 -0
- package/skills/community/scripts/linkedin-setup.sh +758 -0
- package/skills/community/scripts/x-community.sh +890 -0
- package/skills/community/scripts/x-setup.sh +713 -0
- package/skills/community/test/community-argv.test.sh +2922 -0
- package/skills/community/test/github-community.test.sh +981 -0
- package/skills/competitive-analysis/SKILL.md +69 -0
- package/skills/competitive-analysis/references/peer-plugin-audit.md +218 -0
- package/skills/compound/SKILL.md +673 -0
- package/skills/compound/scripts/token-efficiency-report.sh +334 -0
- package/skills/compound/test/phase-16.test.sh +379 -0
- package/skills/compound-capture/SKILL.md +791 -0
- package/skills/compound-capture/assets/critical-pattern-template.md +37 -0
- package/skills/compound-capture/assets/resolution-template.md +116 -0
- package/skills/compound-capture/references/yaml-schema.md +67 -0
- package/skills/compound-capture/schema.yaml +181 -0
- package/skills/constraint-scaffold/SKILL.md +175 -0
- package/skills/constraint-scaffold/references/boundary-readme.template +35 -0
- package/skills/constraint-scaffold/references/constraint-gates-workflow.template +69 -0
- package/skills/constraint-scaffold/references/depcruise-config.template +230 -0
- package/skills/constraint-scaffold/references/fix-constraints-stage-a.template +240 -0
- package/skills/constraint-scaffold/references/fix-constraints-stage-b.template +313 -0
- package/skills/constraint-scaffold/references/shared-runner.template +135 -0
- package/skills/constraint-scaffold/scripts/constraint-scaffold.sh +589 -0
- package/skills/constraint-scaffold/test/bite-proof.test.sh +1338 -0
- package/skills/constraint-scaffold/test/boundary.test.sh +734 -0
- package/skills/constraint-scaffold/test/emit-fix-constraints.test.sh +193 -0
- package/skills/constraint-scaffold/test/generator.test.sh +93 -0
- package/skills/constraint-scaffold/test/parity.test.sh +285 -0
- package/skills/content-writer/SKILL.md +242 -0
- package/skills/content-writer/scripts/blog-jargon-scan.sh +42 -0
- package/skills/cron-delete/SKILL.md +56 -0
- package/skills/cron-list/SKILL.md +54 -0
- package/skills/deepen-plan/SKILL.md +937 -0
- package/skills/deepen-plan/workflows/deepen-plan.workflow.js +488 -0
- package/skills/deploy/SKILL.md +115 -0
- package/skills/deploy/references/hetzner-setup.md +67 -0
- package/skills/deploy/scripts/deploy.sh +37 -0
- package/skills/deploy-docs/SKILL.md +95 -0
- package/skills/dhh-rails-style/SKILL.md +203 -0
- package/skills/dhh-rails-style/references/architecture.md +717 -0
- package/skills/dhh-rails-style/references/controllers.md +323 -0
- package/skills/dhh-rails-style/references/frontend.md +556 -0
- package/skills/dhh-rails-style/references/gems.md +316 -0
- package/skills/dhh-rails-style/references/models.md +388 -0
- package/skills/dhh-rails-style/references/testing.md +354 -0
- package/skills/discord-content/SKILL.md +126 -0
- package/skills/docs-site/SKILL.md +214 -0
- package/skills/drain-labeled-backlog/SKILL.md +203 -0
- package/skills/drain-labeled-backlog/scripts/group-by-area.sh +208 -0
- package/skills/drain-labeled-backlog/workflows/drain-labeled-backlog.workflow.js +433 -0
- package/skills/drain-prs/SKILL.md +143 -0
- package/skills/drain-prs/scripts/triage-prs.sh +192 -0
- package/skills/drain-prs/test/argv-ceiling.test.sh +183 -0
- package/skills/dspy-ruby/SKILL.md +634 -0
- package/skills/dspy-ruby/assets/config-template.rb +359 -0
- package/skills/dspy-ruby/assets/module-template.rb +326 -0
- package/skills/dspy-ruby/assets/signature-template.rb +143 -0
- package/skills/dspy-ruby/references/core-concepts.md +268 -0
- package/skills/dspy-ruby/references/optimization.md +623 -0
- package/skills/dspy-ruby/references/providers.md +335 -0
- package/skills/eval-harness/README.md +194 -0
- package/skills/eval-harness/SKILL.md +157 -0
- package/skills/eval-harness/enums/go-routes.json +13 -0
- package/skills/eval-harness/enums/incident-threshold.json +5 -0
- package/skills/eval-harness/enums/lane.json +5 -0
- package/skills/eval-harness/enums/tool-selection.json +20 -0
- package/skills/eval-harness/enums/triage-levels.json +5 -0
- package/skills/eval-harness/gated-skills.json +34 -0
- package/skills/eval-harness/models.generated.json +5 -0
- package/skills/eval-harness/promptfooconfig-go-routing.yaml +35 -0
- package/skills/eval-harness/promptfooconfig-incident-threshold.yaml +32 -0
- package/skills/eval-harness/promptfooconfig-lane-inference.yaml +33 -0
- package/skills/eval-harness/promptfooconfig-ticket-triage.yaml +34 -0
- package/skills/eval-harness/promptfooconfig-tool-selection.yaml +33 -0
- package/skills/eval-harness/prompts/go-baseline.txt +6 -0
- package/skills/eval-harness/prompts/go-skill.txt +21 -0
- package/skills/eval-harness/prompts/incident-threshold-baseline.txt +6 -0
- package/skills/eval-harness/prompts/incident-threshold-skill.txt +12 -0
- package/skills/eval-harness/prompts/lane-inference-baseline.txt +6 -0
- package/skills/eval-harness/prompts/lane-inference-skill.txt +15 -0
- package/skills/eval-harness/prompts/tool-selection-baseline.txt +19 -0
- package/skills/eval-harness/prompts/tool-selection-skill.txt +22 -0
- package/skills/eval-harness/prompts/triage-baseline.txt +7 -0
- package/skills/eval-harness/prompts/triage-skill.txt +10 -0
- package/skills/eval-harness/scripts/eval-gate.cjs +318 -0
- package/skills/eval-harness/scripts/extract-block.cjs +87 -0
- package/skills/eval-harness/scripts/gate-classification.cjs +28 -0
- package/skills/eval-harness/scripts/gen-models.sh +41 -0
- package/skills/eval-harness/scripts/gen-skill-prompt.cjs +177 -0
- package/skills/eval-harness/scripts/measure-classification.cjs +30 -0
- package/skills/eval-harness/scripts/parse-label.cjs +93 -0
- package/skills/eval-harness/scripts/verdict.cjs +132 -0
- package/skills/eval-harness/tasks/go-routing.jsonl +8 -0
- package/skills/eval-harness/tasks/incident-threshold.jsonl +7 -0
- package/skills/eval-harness/tasks/lane-inference.jsonl +7 -0
- package/skills/eval-harness/tasks/ticket-triage.jsonl +6 -0
- package/skills/eval-harness/tasks/tool-selection.jsonl +15 -0
- package/skills/eval-harness/test/eval-gate.test.sh +132 -0
- package/skills/eval-harness/test/extract-block.test.sh +87 -0
- package/skills/eval-harness/test/gate-classification.test.sh +77 -0
- package/skills/eval-harness/test/gen-models.test.sh +75 -0
- package/skills/eval-harness/test/measure-classification.test.sh +74 -0
- package/skills/eval-harness/test/parse-label.test.sh +129 -0
- package/skills/eval-harness/test/registry-completeness.test.sh +109 -0
- package/skills/eval-harness/test/verdict.test.sh +123 -0
- package/skills/every-style-editor/SKILL.md +142 -0
- package/skills/every-style-editor/references/EVERY_WRITE_STYLE.md +529 -0
- package/skills/feature-tweet/SKILL.md +199 -0
- package/skills/feature-video/SKILL.md +412 -0
- package/skills/feature-video/scripts/check_deps.sh +281 -0
- package/skills/file-todos/SKILL.md +267 -0
- package/skills/file-todos/assets/todo-template.md +166 -0
- package/skills/fix-issue/SKILL.md +278 -0
- package/skills/fix-issue/references/agent-authored-exclusion.md +120 -0
- package/skills/fix-issue/references/exclude-label-jq-snippet.md +97 -0
- package/skills/flag-bootstrap/SETUP.md +142 -0
- package/skills/flag-create/SKILL.md +145 -0
- package/skills/flag-create/scripts/create.sh +273 -0
- package/skills/flag-delete/SKILL.md +167 -0
- package/skills/flag-delete/scripts/delete.sh +288 -0
- package/skills/flag-list/SKILL.md +99 -0
- package/skills/flag-list/scripts/list.sh +275 -0
- package/skills/flag-set-role/SKILL.md +229 -0
- package/skills/flag-set-role/scripts/flip.sh +774 -0
- package/skills/frontend-anti-slop/SKILL.md +106 -0
- package/skills/frontend-anti-slop/references/anti-patterns.md +199 -0
- package/skills/frontend-anti-slop/references/slop-rules.md +65 -0
- package/skills/frontend-anti-slop/scripts/tier1-scan.ts +525 -0
- package/skills/frontend-design/SKILL.md +77 -0
- package/skills/gdpr-gate/NOTICE +136 -0
- package/skills/gdpr-gate/SKILL.md +341 -0
- package/skills/gdpr-gate/references/fields.md +160 -0
- package/skills/gdpr-gate/references/layers/api-layer.md +355 -0
- package/skills/gdpr-gate/references/layers/auth-sessions.md +290 -0
- package/skills/gdpr-gate/references/layers/data-in-transit.md +331 -0
- package/skills/gdpr-gate/references/layers/data-lifecycle.md +341 -0
- package/skills/gdpr-gate/references/layers/frontend.md +249 -0
- package/skills/gdpr-gate/references/layers/testing-seeding.md +256 -0
- package/skills/gdpr-gate/references/leakage-vectors.md +248 -0
- package/skills/gdpr-gate/references/legacy/legal-consent-v1-prose.md +48 -0
- package/skills/gdpr-gate/references/legal-consent.md +140 -0
- package/skills/gdpr-gate/references/non-negotiables.md +60 -0
- package/skills/gdpr-gate/scripts/gdpr-gate.sh +271 -0
- package/skills/gdpr-gate/scripts/notice-frontmatter.sh +337 -0
- package/skills/gdpr-gate/scripts/path-denylist.txt +39 -0
- package/skills/gdpr-gate/scripts/repo-scan.sh +158 -0
- package/skills/gdpr-gate/scripts/vendor-drift-classify.sh +120 -0
- package/skills/gdpr-gate/scripts/vendor-pin-integrity.sh +237 -0
- package/skills/gemini-imagegen/SKILL.md +283 -0
- package/skills/gemini-imagegen/requirements.txt +5 -0
- package/skills/gemini-imagegen/scripts/_error_handling.py +146 -0
- package/skills/gemini-imagegen/scripts/compose_images.py +150 -0
- package/skills/gemini-imagegen/scripts/edit_image.py +137 -0
- package/skills/gemini-imagegen/scripts/gemini_images.py +256 -0
- package/skills/gemini-imagegen/scripts/generate_image.py +147 -0
- package/skills/gemini-imagegen/scripts/multi_turn_chat.py +223 -0
- package/skills/gemini-imagegen/scripts/test_error_handling.py +179 -0
- package/skills/git-worktree/SKILL.md +534 -0
- package/skills/git-worktree/scripts/git-repo-readiness-diag.sh +98 -0
- package/skills/git-worktree/scripts/worktree-manager.sh +4773 -0
- package/skills/git-worktree/test/create-from-origin-main.test.sh +116 -0
- package/skills/git-worktree/test/lease-protects-active.test.sh +1056 -0
- package/skills/git-worktree/test/no-repo-fail-loud.test.sh +88 -0
- package/skills/git-worktree/test/orphan-reaper-honest-count.test.sh +379 -0
- package/skills/git-worktree/test/reap-archive-persistence.test.sh +725 -0
- package/skills/git-worktree/test/stale-lock-sweep.test.sh +176 -0
- package/skills/go/SKILL.md +54 -0
- package/skills/growth/SKILL.md +164 -0
- package/skills/harvest-debt/SKILL.md +78 -0
- package/skills/harvest-debt/scripts/harvest-debt.sh +114 -0
- package/skills/heal-skill/SKILL.md +173 -0
- package/skills/help/SKILL.md +46 -0
- package/skills/incident/NOTICE +39 -0
- package/skills/incident/SKILL.md +395 -0
- package/skills/incident/scripts/dry-run.sh +448 -0
- package/skills/incident/scripts/redact-engine.py +412 -0
- package/skills/incident/scripts/redact-sentinel.sh +44 -0
- package/skills/incident/templates/pir.md +139 -0
- package/skills/incident/test/fixtures/dry-run-incident.json +26 -0
- package/skills/incident/test/fixtures/dry-run-secret-leak.json +26 -0
- package/skills/incident/test/fixtures/legacy-bash-scanner.sh +82 -0
- package/skills/incident/test/fixtures/positive-corpus.md +87 -0
- package/skills/incident/test/redact-sentinel.test.sh +1420 -0
- package/skills/invoice/SKILL.md +206 -0
- package/skills/kb-glossary/SKILL.md +71 -0
- package/skills/kb-glossary/references/glossary-format.md +111 -0
- package/skills/kb-glossary/references/rejected-request-register.md +115 -0
- package/skills/kb-search/SKILL.md +276 -0
- package/skills/kb-search/scripts/kb-search-cache.sh +123 -0
- package/skills/legal-audit/SKILL.md +161 -0
- package/skills/legal-generate/NOTICE +242 -0
- package/skills/legal-generate/SKILL.md +244 -0
- package/skills/legal-generate/references/templates/advisor-agreement/template.md +12 -0
- package/skills/legal-generate/references/templates/business-associate-agreement/template.md +112 -0
- package/skills/legal-generate/references/templates/cookie-notice/template.md +82 -0
- package/skills/legal-generate/references/templates/dpa-global/template.md +439 -0
- package/skills/legal-generate/references/templates/dpa-us/template.md +222 -0
- package/skills/legal-generate/references/templates/employee-offer-letter/template.md +75 -0
- package/skills/legal-generate/references/templates/master-services-agreement/template.md +252 -0
- package/skills/legal-generate/references/templates/mutual-nda/template.md +66 -0
- package/skills/legal-generate/references/templates/one-way-nda/template.md +38 -0
- package/skills/legal-generate/references/templates/privacy-policy-gdpr/template.md +427 -0
- package/skills/legal-generate/references/templates/privacy-policy-us/template.md +313 -0
- package/skills/legal-generate/references/templates/terms-of-use/template.md +75 -0
- package/skills/legal-generate/scripts/strip-vendor-credit.sh +96 -0
- package/skills/linear-fetch/SKILL.md +247 -0
- package/skills/linear-fetch/scripts/assert-no-linear-telemetry.sh +66 -0
- package/skills/linear-fetch/scripts/redact-linear-urls.sh +51 -0
- package/skills/linear-fetch/scripts/render-caller-template.sh +36 -0
- package/skills/linear-fetch/test/assert-no-linear-telemetry.test.sh +113 -0
- package/skills/linear-fetch/test/parity.test.sh +112 -0
- package/skills/linear-fetch/test/persist-safe-integration.test.sh +191 -0
- package/skills/linear-fetch/test/redact-linear-urls.test.sh +226 -0
- package/skills/merge-pr/SKILL.md +670 -0
- package/skills/model-launch-review/SKILL.md +255 -0
- package/skills/model-launch-review/scripts/audit-models.sh +501 -0
- package/skills/one-shot/SKILL.md +316 -0
- package/skills/one-shot/references/token-discipline.md +74 -0
- package/skills/operator-bootstrap/SKILL.md +412 -0
- package/skills/operator-bootstrap/template.sh +439 -0
- package/skills/operator-digest/SKILL.md +287 -0
- package/skills/operator-digest/assets/operator-digest.workflow.yml +175 -0
- package/skills/operator-digest/scripts/digest-scrub.sh +119 -0
- package/skills/operator-digest/scripts/provision-operator-digest-repo.sh +147 -0
- package/skills/operator-rephrase/SKILL.md +98 -0
- package/skills/pencil-setup/SKILL.md +201 -0
- package/skills/pencil-setup/scripts/check_deps.sh +556 -0
- package/skills/pencil-setup/scripts/copy_adapter.sh +80 -0
- package/skills/pencil-setup/scripts/package-lock.json +1172 -0
- package/skills/pencil-setup/scripts/package.json +14 -0
- package/skills/pencil-setup/scripts/pencil-error-enrichment.mjs +21 -0
- package/skills/pencil-setup/scripts/pencil-mcp-adapter.mjs +733 -0
- package/skills/pencil-setup/scripts/pencil-response-classify.mjs +38 -0
- package/skills/pencil-setup/scripts/pencil-save-gate.mjs +26 -0
- package/skills/pencil-setup/scripts/sanitize-filename.mjs +25 -0
- package/skills/plan/SKILL.md +1140 -0
- package/skills/plan/references/differential-migration-testing.md +185 -0
- package/skills/plan/references/plan-community-discovery.md +42 -0
- package/skills/plan/references/plan-founder-check.md +137 -0
- package/skills/plan/references/plan-functional-overlap.md +25 -0
- package/skills/plan/references/plan-host-fanout.md +51 -0
- package/skills/plan/references/plan-issue-templates.md +779 -0
- package/skills/plan/references/plan-network-outage-checklist.md +131 -0
- package/skills/plan/references/plan-scope-check.md +126 -0
- package/skills/plan/references/plan-sharp-edges.md +331 -0
- package/skills/plan/references/plan-signoff-lifecycle.md +12 -0
- package/skills/plan/references/webapp-cwv-observability.md +143 -0
- package/skills/plan-review/SKILL.md +91 -0
- package/skills/plan-review/lib/named-panel.mjs +58 -0
- package/skills/plan-review/workflows/plan-review.workflow.js +477 -0
- package/skills/postmerge/SKILL.md +642 -0
- package/skills/postmerge/references/deploy-status-debugging.md +141 -0
- package/skills/postmerge/references/graceful-degradation.md +20 -0
- package/skills/postmerge/references/sentry-error-count-delta.md +137 -0
- package/skills/preflight/SKILL.md +1553 -0
- package/skills/preflight/references/check-13-founder-check.md +286 -0
- package/skills/preflight/scripts/founder-check.py +1640 -0
- package/skills/preflight/scripts/parse-form-a.awk +107 -0
- package/skills/preflight/scripts/probe-verb-gate.sh +108 -0
- package/skills/product-roadmap/SKILL.md +357 -0
- package/skills/product-roadmap/scripts/roadmap-reconcile.sh +327 -0
- package/skills/provision-cloudflare/SKILL.md +67 -0
- package/skills/provision-cloudflare/scripts/provision-cloudflare.sh +271 -0
- package/skills/provision-doppler/SKILL.md +58 -0
- package/skills/provision-doppler/scripts/provision-doppler.sh +358 -0
- package/skills/provision-github/SKILL.md +59 -0
- package/skills/provision-github/scripts/provision-github.sh +300 -0
- package/skills/provision-hetzner/SKILL.md +76 -0
- package/skills/provision-hetzner/scripts/provision-hetzner.sh +262 -0
- package/skills/provision-hetzner/test/fixture/knowledge-base/legal/tenant-dpa-register.md +26 -0
- package/skills/provision-hetzner/test/fixture/provision-hetzner-dry-run.golden +34 -0
- package/skills/provision-hetzner/test/provision-hetzner-characterization.test.sh +227 -0
- package/skills/qa/SKILL.md +263 -0
- package/skills/qa/references/browser-preflight.md +22 -0
- package/skills/questionnaire-generate/SKILL.md +328 -0
- package/skills/questionnaire-generate/references/questionnaire.template +60 -0
- package/skills/rclone/SKILL.md +162 -0
- package/skills/rclone/scripts/check_setup.sh +63 -0
- package/skills/release-announce/SKILL.md +65 -0
- package/skills/release-docs/SKILL.md +92 -0
- package/skills/reproduce-bug/SKILL.md +358 -0
- package/skills/resolve-debt/SKILL.md +85 -0
- package/skills/resolve-debt/scripts/resolve-debt.py +584 -0
- package/skills/resolve-parallel/SKILL.md +45 -0
- package/skills/resolve-parallel/workflows/resolve-parallel.workflow.js +415 -0
- package/skills/resolve-pr-parallel/SKILL.md +68 -0
- package/skills/resolve-pr-parallel/workflows/resolve-pr-parallel.workflow.js +419 -0
- package/skills/resolve-todo-parallel/SKILL.md +57 -0
- package/skills/resolve-todo-parallel/workflows/resolve-todo-parallel.workflow.js +398 -0
- package/skills/review/SKILL.md +1620 -0
- package/skills/review/references/anti-slop-scanner-hook.md +40 -0
- package/skills/review/references/defect-classes-migrations.md +9 -0
- package/skills/review/references/generated-input-oracle-surfaces.md +15 -0
- package/skills/review/references/review-e2e-testing.md +116 -0
- package/skills/review/references/review-evidence-comment.md +36 -0
- package/skills/review/references/review-todo-structure.md +165 -0
- package/skills/review/references/risk-tier-and-fix-rounds.md +97 -0
- package/skills/review/references/semgrep-custom-rules.yaml +174 -0
- package/skills/review/references/ultrathink-phases.md +98 -0
- package/skills/review/references/wfs.md +6 -0
- package/skills/review/scripts/emit-review-trailer.sh +499 -0
- package/skills/review/scripts/ensure-semgrep.sh +99 -0
- package/skills/review/scripts/fix-round-seats.sh +197 -0
- package/skills/review/test/emit-review-trailer.test.sh +387 -0
- package/skills/review/test/ensure-semgrep.test.sh +111 -0
- package/skills/review/test/fix-round-seats.test.sh +237 -0
- package/skills/review/workflows/README.md +147 -0
- package/skills/review/workflows/review.workflow.js +667 -0
- package/skills/schedule/SKILL.md +796 -0
- package/skills/seo-aeo/SKILL.md +139 -0
- package/skills/seo-aeo/scripts/validate-csp.sh +233 -0
- package/skills/seo-aeo/scripts/validate-seo.sh +262 -0
- package/skills/ship/SKILL.md +3023 -0
- package/skills/ship/references/adr-ordinal-collision.md +47 -0
- package/skills/ship/references/affected-gate-contract.md +115 -0
- package/skills/ship/references/ci-run-diagnosis.md +29 -0
- package/skills/ship/references/ci-workflow-authoring.md +68 -0
- package/skills/ship/references/cleanup-merged-archival.md +39 -0
- package/skills/ship/references/counsel-review-clo-attestation.md +38 -0
- package/skills/ship/references/cto-ruling-armed-push.md +5 -0
- package/skills/ship/references/decision-challenges-render.md +71 -0
- package/skills/ship/references/delegated-act-authoring-form.md +7 -0
- package/skills/ship/references/detached-battery-verdict.md +13 -0
- package/skills/ship/references/epic-close-sweep.md +62 -0
- package/skills/ship/references/feature-tweet-draft.md +42 -0
- package/skills/ship/references/followthrough-issue-body-template.md +47 -0
- package/skills/ship/references/followthrough-stub-template.sh +92 -0
- package/skills/ship/references/merge-queue-dequeue.md +39 -0
- package/skills/ship/references/operator-holds.md +179 -0
- package/skills/ship/references/pipeline-tally-render.md +43 -0
- package/skills/ship/references/pr-overlap.md +153 -0
- package/skills/ship/references/queue-mode.md +7 -0
- package/skills/ship/references/ready-run-wait.md +36 -0
- package/skills/ship/references/red-on-main-quarantine.md +110 -0
- package/skills/ship/references/register-update-pr-pattern.md +88 -0
- package/skills/ship/references/settle-then-admin-merge.md +130 -0
- package/skills/ship/references/supabase-column-probe.md +13 -0
- package/skills/ship/scripts/auto-close-scan.sh +76 -0
- package/skills/ship/scripts/battery-owed.sh +403 -0
- package/skills/ship/scripts/hold-gate-eval.sh +410 -0
- package/skills/ship/scripts/net-issue-flow.sh +665 -0
- package/skills/ship/scripts/pr-overlap-preflight.sh +483 -0
- package/skills/ship/scripts/ship-pir-action-items-gate.sh +246 -0
- package/skills/ship/scripts/technical-ruling-gate.sh +444 -0
- package/skills/skill-creator/SKILL.md +299 -0
- package/skills/skill-creator/references/api-security.md +248 -0
- package/skills/skill-creator/references/authoring-levers.md +110 -0
- package/skills/skill-creator/references/be-clear-and-direct.md +587 -0
- package/skills/skill-creator/references/best-practices.md +431 -0
- package/skills/skill-creator/references/common-patterns.md +639 -0
- package/skills/skill-creator/references/core-principles.md +193 -0
- package/skills/skill-creator/references/executable-code.md +188 -0
- package/skills/skill-creator/references/iteration-and-testing.md +509 -0
- package/skills/skill-creator/references/official-spec.md +193 -0
- package/skills/skill-creator/references/recommended-structure.md +180 -0
- package/skills/skill-creator/references/skill-structure.md +396 -0
- package/skills/skill-creator/references/using-scripts.md +122 -0
- package/skills/skill-creator/references/using-templates.md +120 -0
- package/skills/skill-creator/references/workflows-and-validation.md +541 -0
- package/skills/skill-creator/scripts/init_skill.py +322 -0
- package/skills/skill-creator/scripts/package_skill.py +110 -0
- package/skills/skill-creator/scripts/quick_validate.py +64 -0
- package/skills/skill-creator/templates/router-skill.md +73 -0
- package/skills/skill-creator/templates/simple-skill.md +34 -0
- package/skills/skill-creator/workflows/add-reference.md +96 -0
- package/skills/skill-creator/workflows/add-script.md +104 -0
- package/skills/skill-creator/workflows/add-template.md +83 -0
- package/skills/skill-creator/workflows/add-workflow.md +128 -0
- package/skills/skill-creator/workflows/audit-skill.md +159 -0
- package/skills/skill-creator/workflows/create-domain-expertise-skill.md +623 -0
- package/skills/skill-creator/workflows/create-new-skill.md +207 -0
- package/skills/skill-creator/workflows/get-guidance.md +134 -0
- package/skills/skill-creator/workflows/upgrade-to-router.md +170 -0
- package/skills/skill-creator/workflows/verify-skill.md +226 -0
- package/skills/skill-security-scan/SKILL.md +145 -0
- package/skills/skill-security-scan/references/disclaimer.md +21 -0
- package/skills/skill-security-scan/references/first-party-allowlist.yaml +38 -0
- package/skills/skill-security-scan/references/override-artifact-schema.json +68 -0
- package/skills/skill-security-scan/references/override-mechanism.md +171 -0
- package/skills/skill-security-scan/references/redirect-domains.yaml +27 -0
- package/skills/skill-security-scan/references/regex-patterns.md +136 -0
- package/skills/skill-security-scan/references/rules/code-exec.yaml +70 -0
- package/skills/skill-security-scan/references/rules/filesystem-boundary.yaml +29 -0
- package/skills/skill-security-scan/references/rules/manifest.yaml +44 -0
- package/skills/skill-security-scan/references/rules/supply-chain.yaml +36 -0
- package/skills/skill-security-scan/references/scan-meta-schema.json +63 -0
- package/skills/skill-security-scan/references/test-fixtures/clean-soleur-style.skill.md +23 -0
- package/skills/skill-security-scan/references/test-fixtures/clean-third-party.skill.md +26 -0
- package/skills/skill-security-scan/references/test-fixtures/malicious-codeexec.skill.md +23 -0
- package/skills/skill-security-scan/references/test-fixtures/malicious-curl-pipe-bash.skill.md +69 -0
- package/skills/skill-security-scan/references/test-fixtures/malicious-prompt-injection.skill.md +17 -0
- package/skills/skill-security-scan/references/test-fixtures/malicious-telemetry-beacon.skill.md +23 -0
- package/skills/skill-security-scan/references/typosquat-targets.yaml +65 -0
- package/skills/skill-security-scan/scripts/check-codeexec.sh +41 -0
- package/skills/skill-security-scan/scripts/check-filesystem-boundary.sh +19 -0
- package/skills/skill-security-scan/scripts/check-prompt-injection.sh +95 -0
- package/skills/skill-security-scan/scripts/check-supply-chain.sh +219 -0
- package/skills/skill-security-scan/scripts/check-telemetry-surface.sh +126 -0
- package/skills/skill-security-scan/scripts/lib.sh +197 -0
- package/skills/skill-security-scan/scripts/parse-override.sh +231 -0
- package/skills/skill-security-scan/scripts/run-scan.sh +342 -0
- package/skills/skill-security-scan/scripts/run-self-test.sh +95 -0
- package/skills/skill-security-scan/test/argv-ceiling.test.sh +180 -0
- package/skills/skill-security-scan/test/meta-dir-reap.test.sh +411 -0
- package/skills/skill-security-scan/test/parse-override.test.sh +607 -0
- package/skills/skill-security-scan/test/redact-pii-ghs-shape.test.sh +251 -0
- package/skills/social-distribute/SKILL.md +485 -0
- package/skills/spec-templates/SKILL.md +274 -0
- package/skills/sync/SKILL.md +49 -0
- package/skills/test-browser/SKILL.md +464 -0
- package/skills/test-browser/references/feature-map.md +161 -0
- package/skills/test-fix-loop/SKILL.md +159 -0
- package/skills/test-fix-loop/references/determinism-checklist.md +154 -0
- package/skills/triage/SKILL.md +402 -0
- package/skills/trigger-cron/SKILL.md +136 -0
- package/skills/trigger-cron/scripts/trigger.sh +198 -0
- package/skills/user-set-role/SKILL.md +147 -0
- package/skills/user-set-role/scripts/set-role.sh +218 -0
- package/skills/user-story-writer/SKILL.md +77 -0
- package/skills/ux-audit/SKILL.md +251 -0
- package/skills/ux-audit/references/finding.schema.json +62 -0
- package/skills/ux-audit/references/route-list.yaml +95 -0
- package/skills/ux-audit/scripts/bot-fixture.ts +270 -0
- package/skills/ux-audit/scripts/bot-signin.ts +135 -0
- package/skills/ux-audit/scripts/dedup-hash.ts +46 -0
- package/skills/verification-scaffold/SKILL.md +73 -0
- package/skills/verification-scaffold/references/gitleaks.toml.template +13 -0
- package/skills/verification-scaffold/references/guardrail-audit.md +156 -0
- package/skills/verification-scaffold/references/guards/block-stash-hook.sh.template +72 -0
- package/skills/verification-scaffold/references/guards/commit-on-main-hook.sh.template +82 -0
- package/skills/verification-scaffold/references/guards/orphan-test-check.sh.template +102 -0
- package/skills/verification-scaffold/references/guards/precommit-guard.sh.template +115 -0
- package/skills/verification-scaffold/references/guards/secret-scan-hook.sh.template +176 -0
- package/skills/verification-scaffold/references/guards/verification-gates.yml.template +49 -0
- package/skills/verification-scaffold/references/guards/wrapper-boundary.sh.template +47 -0
- package/skills/verification-scaffold/references/guards.tsv +21 -0
- package/skills/verification-scaffold/references/verification-readme.template +55 -0
- package/skills/verification-scaffold/scripts/verification-scaffold.sh +785 -0
- package/skills/verification-scaffold/test/bite-proof.test.sh +159 -0
- package/skills/verification-scaffold/test/generator.test.sh +319 -0
- package/skills/verification-scaffold/test/manifest.test.sh +144 -0
- package/skills/work/SKILL.md +1480 -0
- package/skills/work/references/end-of-work-resume.md +7 -0
- package/skills/work/references/hook-test-main-cwd.md +24 -0
- package/skills/work/references/key-principles.md +83 -0
- package/skills/work/references/property-testing.md +122 -0
- package/skills/work/references/sql-security-definer-rpc-scaffold.sql +78 -0
- package/skills/work/references/work-agent-teams.md +97 -0
- package/skills/work/references/work-lifecycle-parallel.md +147 -0
- package/skills/work/references/work-lockfile-bumps.md +97 -0
- package/skills/work/references/work-scratch-sandboxes.md +212 -0
- package/skills/work/references/work-subagent-fanout.md +61 -0
- package/skills/work/references/work-test-harness-sharp-edges.md +73 -0
- package/skills/xcode-test/SKILL.md +360 -0
|
@@ -0,0 +1,725 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# 2026-09-28 reproducer for #9127: cleanup_merged_worktrees archives KB
|
|
3
|
+
# artifacts with plain `mv`. Where the artifact is TRACKED (a non-bare clone
|
|
4
|
+
# parked on main, a feature-branch checkout, or a bare root's HEAD-materialized
|
|
5
|
+
# mirror) the move has no persistence owner: nothing commits it, and the
|
|
6
|
+
# SOLEUR-GUARD-MAINRESET `git reset --hard HEAD` — or sync_bare_files'
|
|
7
|
+
# checkout-index mirroring — restores the tracked half while the untracked
|
|
8
|
+
# archive copy persists. Result: a live+archive twin ("stranded spec").
|
|
9
|
+
#
|
|
10
|
+
# The fix (ADR-258): every reap archive move persists via the checkout's own
|
|
11
|
+
# commit path, or is not made at all.
|
|
12
|
+
# tracked + committable (feature branch) -> `git mv` + a pathspec-scoped
|
|
13
|
+
# `chore(archive-kb)` commit on the current branch (SOLEUR_REAP_ARCHIVE_COMMITTED)
|
|
14
|
+
# tracked + non-committable -> no move, SOLEUR_REAP_ARCHIVE_DEFERRED
|
|
15
|
+
# reason=<main-checkout|detached|unborn|merge-in-progress|bare|
|
|
16
|
+
# git-mv-failed|outside-git-root|unsafe-destination>
|
|
17
|
+
# untracked -> plain `mv`, unchanged (no resurrection mechanism applies)
|
|
18
|
+
#
|
|
19
|
+
# The existing sibling suites cannot see this class: their fixtures are
|
|
20
|
+
# untracked files, where `mv` is tracking-agnostic. Every "tracked" fixture
|
|
21
|
+
# below asserts its tracked-ness BEFORE the reap (guard-matrix row 6) so a
|
|
22
|
+
# neutered fixture fails loud instead of passing vacuously.
|
|
23
|
+
#
|
|
24
|
+
# Plan: knowledge-base/project/plans/archive/20261013-051752-2026-09-28-fix-reaper-archive-tracked-kb-persistence-plan.md
|
|
25
|
+
# Issue: https://github.com/jikig-ai/soleur/issues/9127
|
|
26
|
+
#
|
|
27
|
+
# Run via: bash plugins/soleur/skills/git-worktree/test/reap-archive-persistence.test.sh
|
|
28
|
+
|
|
29
|
+
set -uo pipefail
|
|
30
|
+
|
|
31
|
+
# Git-location tripwire (#7833). These suites drive worktree-manager.sh, which runs
|
|
32
|
+
# `git worktree remove`, `git branch -D` and `git reset --hard` -- the highest-damage git writes
|
|
33
|
+
# in the corpus. An inherited GIT_DIR aims all of them at the developer's real repository, so
|
|
34
|
+
# this file aborts rather than proceeding. Inline rather than sourcing test-helpers.sh, which
|
|
35
|
+
# would also import an assertion framework these suites do not use.
|
|
36
|
+
for _v in GIT_DIR GIT_WORK_TREE GIT_INDEX_FILE GIT_COMMON_DIR GIT_OBJECT_DIRECTORY \
|
|
37
|
+
GIT_ALTERNATE_OBJECT_DIRECTORIES GIT_NAMESPACE GIT_TEMPLATE_DIR GIT_EXEC_PATH; do
|
|
38
|
+
if [[ -n "${!_v:-}" && "${SOLEUR_GIT_TRIPWIRE_ALLOW:-0}" != "1" ]]; then
|
|
39
|
+
printf 'FATAL: %s started with an inherited git-location environment (%s=%s).\n' \
|
|
40
|
+
"${BASH_SOURCE[0]}" "$_v" "${!_v}" >&2
|
|
41
|
+
printf 'Fix the ENTRY POINT: unset %s && <runner>\n' "$_v" >&2
|
|
42
|
+
exit 97
|
|
43
|
+
fi
|
|
44
|
+
done
|
|
45
|
+
unset _v
|
|
46
|
+
|
|
47
|
+
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../../.." && pwd)"
|
|
48
|
+
WM="$REPO_ROOT/plugins/soleur/skills/git-worktree/scripts/worktree-manager.sh"
|
|
49
|
+
|
|
50
|
+
PASS=0; FAIL=0
|
|
51
|
+
fail() { echo " FAIL: $1"; FAIL=$((FAIL+1)); }
|
|
52
|
+
pass() { echo " pass: $1"; PASS=$((PASS+1)); }
|
|
53
|
+
|
|
54
|
+
TMP=$(mktemp -d) || { echo "FATAL: mktemp -d failed — refusing to run with an empty \$TMP, every fixture path would resolve against /" >&2; exit 2; }
|
|
55
|
+
trap 'rm -rf "$TMP"' EXIT
|
|
56
|
+
|
|
57
|
+
# Resolved ONCE, with `pwd -P`: TMPDIR is routinely a symlink, and comparing an
|
|
58
|
+
# unresolved $TMP against a resolved toplevel false-FAILS every call.
|
|
59
|
+
TMP_REAL="$(cd "$TMP" && pwd -P)" || TMP_REAL=""
|
|
60
|
+
case "$TMP_REAL" in
|
|
61
|
+
/*) : ;;
|
|
62
|
+
*) echo "FATAL: could not resolve the fixture root '$TMP' to an absolute path — refusing, an empty root makes the containment check match everything" >&2
|
|
63
|
+
exit 2 ;;
|
|
64
|
+
esac
|
|
65
|
+
readonly TMP_REAL
|
|
66
|
+
|
|
67
|
+
# cd into a NON-BARE fixture, or refuse (see lease-protects-active.test.sh for
|
|
68
|
+
# the full rationale: a missing/absent fixture dir leaves git walking up to a
|
|
69
|
+
# LIVE repository).
|
|
70
|
+
cdx() {
|
|
71
|
+
local target="$1" top
|
|
72
|
+
if ! cd "$target" 2>/dev/null; then
|
|
73
|
+
printf ' FAIL: fixture directory absent: %s\n' "$target" >&2
|
|
74
|
+
printf ' refusing to run fixture commands in %s — that is a LIVE repository.\n' "$PWD" >&2
|
|
75
|
+
: > "$TMP/.cdx-failed"
|
|
76
|
+
exit 90
|
|
77
|
+
fi
|
|
78
|
+
top="$(git rev-parse --show-toplevel 2>/dev/null)" || top=""
|
|
79
|
+
case "${top:-<none>}" in
|
|
80
|
+
"$TMP_REAL"|"$TMP_REAL"/*) return 0 ;;
|
|
81
|
+
esac
|
|
82
|
+
printf ' FAIL: %s exists, but its git toplevel is %s\n' "$target" "${top:-<not a git repository>}" >&2
|
|
83
|
+
printf ' which is OUTSIDE the fixture root %s — refusing, git would write to that repository.\n' "$TMP_REAL" >&2
|
|
84
|
+
: > "$TMP/.cdx-failed"
|
|
85
|
+
exit 90
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
# cd into a BARE fixture, or refuse. A bare repo has no toplevel, so cdx cannot
|
|
89
|
+
# guard it; the containment property is identical (resolved path inside $TMP)
|
|
90
|
+
# plus a positive bare check so a non-bare dir can never slip this arm.
|
|
91
|
+
cdb() {
|
|
92
|
+
local target="$1" resolved
|
|
93
|
+
if ! cd "$target" 2>/dev/null; then
|
|
94
|
+
printf ' FAIL: fixture directory absent: %s\n' "$target" >&2
|
|
95
|
+
printf ' refusing to run fixture commands in %s — that is a LIVE repository.\n' "$PWD" >&2
|
|
96
|
+
: > "$TMP/.cdx-failed"
|
|
97
|
+
exit 90
|
|
98
|
+
fi
|
|
99
|
+
resolved="$(pwd -P)"
|
|
100
|
+
case "$resolved" in
|
|
101
|
+
"$TMP_REAL"|"$TMP_REAL"/*) ;;
|
|
102
|
+
*) printf ' FAIL: %s resolved to %s, OUTSIDE the fixture root %s\n' "$target" "$resolved" "$TMP_REAL" >&2
|
|
103
|
+
: > "$TMP/.cdx-failed"
|
|
104
|
+
exit 90 ;;
|
|
105
|
+
esac
|
|
106
|
+
if [[ "$(git rev-parse --is-bare-repository 2>/dev/null)" != "true" ]]; then
|
|
107
|
+
printf ' FAIL: %s is not a bare repository — cdb is the bare-fixture guard; use cdx\n' "$target" >&2
|
|
108
|
+
: > "$TMP/.cdx-failed"
|
|
109
|
+
exit 90
|
|
110
|
+
fi
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
# Bare-`cd "` self-check — same construction as lease-protects-active.test.sh:
|
|
114
|
+
# strip comments, join continuations, flag any `cd "` whose logical line is not
|
|
115
|
+
# guarded by &&/||/if-while-until or routed through cdx/cdb.
|
|
116
|
+
_bare_cd="$(awk '
|
|
117
|
+
BEGIN { start_ln = 1 }
|
|
118
|
+
{
|
|
119
|
+
l = $0
|
|
120
|
+
sub(/(^|[[:space:]])#.*$/, "", l)
|
|
121
|
+
line = line l
|
|
122
|
+
if (sub(/\\[[:space:]]*$/, " ", line)) next
|
|
123
|
+
if (line ~ /(^|[^[:alnum:]_])cd "/ \
|
|
124
|
+
&& line !~ /&&/ && line !~ /\|\|/ \
|
|
125
|
+
&& line !~ /(^|[[:space:]])(if|while|until)[[:space:]]+!?[[:space:]]*cd[[:space:]]"/ \
|
|
126
|
+
&& line !~ /(^|[^[:alnum:]_])(cdx|cdb)[[:space:]]/) print start_ln ": " line
|
|
127
|
+
line = ""; start_ln = NR + 1
|
|
128
|
+
}
|
|
129
|
+
' "${BASH_SOURCE[0]}")"
|
|
130
|
+
if [[ -n "$_bare_cd" ]]; then
|
|
131
|
+
printf ' FAIL: unguarded cd site(s) in this suite — every fixture cd must go through cdx()/cdb():\n' >&2
|
|
132
|
+
printf '%s\n' "$_bare_cd" >&2
|
|
133
|
+
printf ' A bare cd here runs git in the CALLER CWD when the fixture is missing.\n' >&2
|
|
134
|
+
exit 1
|
|
135
|
+
fi
|
|
136
|
+
|
|
137
|
+
# ---------------------------------------------------------------------------
|
|
138
|
+
# Fixture helpers
|
|
139
|
+
# ---------------------------------------------------------------------------
|
|
140
|
+
|
|
141
|
+
# The body below is the CANONICAL copy, asserted byte-for-byte against every other copy by
|
|
142
|
+
# plugins/soleur/test/fixture-dir-operand-assert.test.sh. Do not reword it in one file only. #7652
|
|
143
|
+
assert_fixture_dir() {
|
|
144
|
+
case "${1-}" in
|
|
145
|
+
"") printf 'FATAL: fixture dir is EMPTY; git -C "" would operate on %s\n' "$PWD" >&2; exit 2 ;;
|
|
146
|
+
*/../*|*/..) printf 'FATAL: fixture dir %s contains ..; refusing\n' "$1" >&2; exit 2 ;;
|
|
147
|
+
/proc/*|/sys/*|/dev/*) printf 'FATAL: fixture dir %s is a synthetic-fs path; refusing\n' "$1" >&2; exit 2 ;;
|
|
148
|
+
/|//|/.) printf 'FATAL: fixture dir resolves to the filesystem root; refusing\n' >&2; exit 2 ;;
|
|
149
|
+
/*) : ;;
|
|
150
|
+
*) printf 'FATAL: fixture dir %s is RELATIVE; refusing\n' "$1" >&2; exit 2 ;;
|
|
151
|
+
esac
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
mk_lease_root() {
|
|
155
|
+
local d="$1"
|
|
156
|
+
assert_fixture_dir "$d"
|
|
157
|
+
mkdir -p "$d/leases" "$d/locks" "$d/logs" || return 1
|
|
158
|
+
# Pre-stamp the #7409 first-run arming hold: without it the reaper reports
|
|
159
|
+
# rather than reaps on the first armed run and every assertion below would
|
|
160
|
+
# pass for the wrong reason.
|
|
161
|
+
: > "$d/reaper-armed" || return 1
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
# Build <bare> + <clone> where merged branch feat-victim carries TRACKED kb
|
|
165
|
+
# artifacts: a plan file (always) and the spec dir only when mode=tracked
|
|
166
|
+
# (mode=untracked writes the spec dir post-merge, never committed).
|
|
167
|
+
build_clone() {
|
|
168
|
+
local bare="$1" clone="$2" spec_mode="$3"
|
|
169
|
+
git init --bare -b main "$bare" >/dev/null || return 1
|
|
170
|
+
git clone "$bare" "$clone" >/dev/null 2>&1 || return 1
|
|
171
|
+
( set -e
|
|
172
|
+
cdx "$clone"
|
|
173
|
+
git config user.email t@t
|
|
174
|
+
git config user.name t
|
|
175
|
+
git config commit.gpgsign false
|
|
176
|
+
git commit --allow-empty -m seed >/dev/null
|
|
177
|
+
git checkout -b feat-victim >/dev/null 2>&1
|
|
178
|
+
mkdir -p knowledge-base/project/plans
|
|
179
|
+
echo plan > "knowledge-base/project/plans/2026-01-01-feat-victim-plan.md"
|
|
180
|
+
if [[ "$spec_mode" == tracked ]]; then
|
|
181
|
+
mkdir -p knowledge-base/project/specs/feat-victim
|
|
182
|
+
echo spec > knowledge-base/project/specs/feat-victim/spec.md
|
|
183
|
+
fi
|
|
184
|
+
git add knowledge-base
|
|
185
|
+
# Backdated past the reaper's <10-minute recent-commit grace so the branch
|
|
186
|
+
# is a real reap candidate, not a grace-skipped one (vacuous-green guard).
|
|
187
|
+
GIT_COMMITTER_DATE="2025-01-01T00:00:00Z" \
|
|
188
|
+
git commit --date "2025-01-01T00:00:00Z" -m "victim kb artifacts" >/dev/null
|
|
189
|
+
git checkout main >/dev/null 2>&1
|
|
190
|
+
git merge --no-ff -m "merge feat-victim" feat-victim >/dev/null 2>&1
|
|
191
|
+
if [[ "$spec_mode" == untracked ]]; then
|
|
192
|
+
mkdir -p knowledge-base/project/specs/feat-victim
|
|
193
|
+
echo spec > knowledge-base/project/specs/feat-victim/spec.md
|
|
194
|
+
fi
|
|
195
|
+
git push origin main feat-victim >/dev/null 2>&1
|
|
196
|
+
)
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
# Run cleanup-merged inside fixture <dir> (non-bare via cdx); marker stream to
|
|
200
|
+
# <out>. rc is swallowed — every assertion keys on markers/disk state, and
|
|
201
|
+
# cleanup-merged returns 0 for most internal failures by design.
|
|
202
|
+
run_cleanup() {
|
|
203
|
+
local dir="$1" out="$2"; shift 2
|
|
204
|
+
assert_fixture_dir "$dir"; assert_fixture_dir "$out"
|
|
205
|
+
( cdx "$dir"
|
|
206
|
+
env "$@" SOLEUR_SESSION_STATE_ROOT="$LEASE_ROOT" bash "$WM" cleanup-merged
|
|
207
|
+
) >"$out" 2>&1 || true
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
run_cleanup_bare() {
|
|
211
|
+
local dir="$1" out="$2"; shift 2
|
|
212
|
+
assert_fixture_dir "$dir"; assert_fixture_dir "$out"
|
|
213
|
+
( cdb "$dir"
|
|
214
|
+
env "$@" SOLEUR_SESSION_STATE_ROOT="$LEASE_ROOT" bash "$WM" cleanup-merged
|
|
215
|
+
) >"$out" 2>&1 || true
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
is_tracked() { git -C "$1" ls-files --error-unmatch -- "$2" >/dev/null 2>&1; }
|
|
219
|
+
|
|
220
|
+
spec_live() { [[ -e "$1/knowledge-base/project/specs/feat-victim" ]]; }
|
|
221
|
+
spec_arch() { grep -q 'feat-victim' < <(ls "$1/knowledge-base/project/specs/archive/" 2>/dev/null); }
|
|
222
|
+
plan_live() { [[ -f "$1/knowledge-base/project/plans/2026-01-01-feat-victim-plan.md" ]]; }
|
|
223
|
+
plan_arch() { grep -q 'feat-victim' < <(ls "$1/knowledge-base/project/plans/archive/" 2>/dev/null); }
|
|
224
|
+
|
|
225
|
+
# ===========================================================================
|
|
226
|
+
# FIXTURE A — non-bare clone on `main`, TRACKED spec dir + plan file.
|
|
227
|
+
# The defect surface: today's plain `mv` + same-run/next-run `reset --hard`
|
|
228
|
+
# manufactures the twin. Expect: no move at all, DEFERRED reason=main-checkout.
|
|
229
|
+
# ===========================================================================
|
|
230
|
+
LEASE_ROOT="$TMP/lease-a"; mk_lease_root "$LEASE_ROOT"
|
|
231
|
+
BARE_A="$TMP/a-origin.git"; CLONE_A="$TMP/a-clone"
|
|
232
|
+
build_clone "$BARE_A" "$CLONE_A" tracked
|
|
233
|
+
|
|
234
|
+
# Precondition (guard-matrix row 6): the "tracked" fixture is really tracked.
|
|
235
|
+
if is_tracked "$CLONE_A" knowledge-base/project/specs/feat-victim/spec.md \
|
|
236
|
+
&& is_tracked "$CLONE_A" knowledge-base/project/plans/2026-01-01-feat-victim-plan.md; then
|
|
237
|
+
pass "A precondition: spec dir + plan file are tracked on main"
|
|
238
|
+
else
|
|
239
|
+
fail "A precondition: 'tracked' fixture is really untracked — the suite cannot see the class it tests"
|
|
240
|
+
fi
|
|
241
|
+
if [[ "$(git -C "$CLONE_A" rev-parse --abbrev-ref HEAD)" == "main" ]]; then
|
|
242
|
+
pass "A precondition: checkout is on main"
|
|
243
|
+
else
|
|
244
|
+
fail "A precondition: checkout is not on main"
|
|
245
|
+
fi
|
|
246
|
+
|
|
247
|
+
OUT_A="$TMP/a-out.txt"
|
|
248
|
+
run_cleanup "$CLONE_A" "$OUT_A"
|
|
249
|
+
|
|
250
|
+
if grep -q 'SOLEUR_REAP_ARCHIVE_DEFERRED .*reason=main-checkout' "$OUT_A"; then
|
|
251
|
+
pass "A: tracked reap archive on main emits SOLEUR_REAP_ARCHIVE_DEFERRED reason=main-checkout"
|
|
252
|
+
else
|
|
253
|
+
fail "A: no DEFERRED/main-checkout marker (output: $(grep -c 'SOLEUR_' "$OUT_A") SOLEUR lines)"
|
|
254
|
+
fi
|
|
255
|
+
if spec_live "$CLONE_A"; then
|
|
256
|
+
pass "A: live spec dir still on disk after reap on main"
|
|
257
|
+
else
|
|
258
|
+
fail "A: live spec dir was moved on main (non-committable checkout must not move tracked artifacts)"
|
|
259
|
+
fi
|
|
260
|
+
if is_tracked "$CLONE_A" knowledge-base/project/specs/feat-victim/spec.md; then
|
|
261
|
+
pass "A: spec file still tracked after reap on main"
|
|
262
|
+
else
|
|
263
|
+
fail "A: spec file lost index tracking on main"
|
|
264
|
+
fi
|
|
265
|
+
if spec_arch "$CLONE_A"; then
|
|
266
|
+
fail "A: archive copy of spec dir was created on main — the twin mechanism"
|
|
267
|
+
else
|
|
268
|
+
pass "A: no spec archive copy created on main"
|
|
269
|
+
fi
|
|
270
|
+
if plan_live "$CLONE_A" && ! plan_arch "$CLONE_A"; then
|
|
271
|
+
pass "A: tracked plan file deferred too (live kept, no archive copy)"
|
|
272
|
+
else
|
|
273
|
+
fail "A: tracked plan file was moved on main"
|
|
274
|
+
fi
|
|
275
|
+
if [[ -z "$(git -C "$CLONE_A" status --porcelain 2>/dev/null)" ]]; then
|
|
276
|
+
pass "A: worktree clean after deferred reap"
|
|
277
|
+
else
|
|
278
|
+
fail "A: worktree dirty after deferred reap: $(git -C "$CLONE_A" status --porcelain | head -3)"
|
|
279
|
+
fi
|
|
280
|
+
if ! grep -q 'chore(archive-kb)' < <(git -C "$CLONE_A" log --oneline -5 --format=%s); then
|
|
281
|
+
pass "A: no commit landed on main"
|
|
282
|
+
else
|
|
283
|
+
fail "A: a chore(archive-kb) commit landed on main — commits to main are prohibited"
|
|
284
|
+
fi
|
|
285
|
+
|
|
286
|
+
# Regression arm: same-run reset AND a second cleanup+reset pair (next-session).
|
|
287
|
+
git -C "$CLONE_A" reset --hard HEAD >/dev/null 2>&1
|
|
288
|
+
if spec_live "$CLONE_A" && ! spec_arch "$CLONE_A"; then
|
|
289
|
+
pass "A: same-run reset --hard produces no live+archive twin"
|
|
290
|
+
else
|
|
291
|
+
fail "A: reset --hard resurrected the twin (live+archive both present)"
|
|
292
|
+
fi
|
|
293
|
+
OUT_A2="$TMP/a2-out.txt"
|
|
294
|
+
run_cleanup "$CLONE_A" "$OUT_A2"
|
|
295
|
+
git -C "$CLONE_A" reset --hard HEAD >/dev/null 2>&1
|
|
296
|
+
if spec_live "$CLONE_A" && ! spec_arch "$CLONE_A"; then
|
|
297
|
+
pass "A: next-session cleanup+reset still produces no twin"
|
|
298
|
+
else
|
|
299
|
+
fail "A: a second cleanup/reset cycle manufactured the twin"
|
|
300
|
+
fi
|
|
301
|
+
|
|
302
|
+
# ===========================================================================
|
|
303
|
+
# FIXTURE B — clone on a FEATURE branch, tracked artifacts for a merged OTHER
|
|
304
|
+
# branch. Expect: git mv + pathspec-scoped chore(archive-kb) commit; a
|
|
305
|
+
# pre-staged unrelated file is never swept (AC5); an untracked brainstorm file
|
|
306
|
+
# in the same batch still plain-mv's (mixed batch, per-file classification).
|
|
307
|
+
# ===========================================================================
|
|
308
|
+
LEASE_ROOT="$TMP/lease-b"; mk_lease_root "$LEASE_ROOT"
|
|
309
|
+
BARE_B="$TMP/b-origin.git"; CLONE_B="$TMP/b-clone"
|
|
310
|
+
build_clone "$BARE_B" "$CLONE_B" tracked
|
|
311
|
+
|
|
312
|
+
( set -e
|
|
313
|
+
cdx "$CLONE_B"
|
|
314
|
+
git checkout -b feat-actor >/dev/null 2>&1
|
|
315
|
+
echo unrelated > staged.txt
|
|
316
|
+
git add staged.txt
|
|
317
|
+
mkdir -p knowledge-base/project/brainstorms
|
|
318
|
+
echo brainstorm > "knowledge-base/project/brainstorms/2026-01-01-feat-victim-brainstorm.md"
|
|
319
|
+
)
|
|
320
|
+
|
|
321
|
+
OUT_B="$TMP/b-out.txt"
|
|
322
|
+
run_cleanup "$CLONE_B" "$OUT_B"
|
|
323
|
+
|
|
324
|
+
if grep -q 'SOLEUR_REAP_ARCHIVE_COMMITTED' "$OUT_B"; then
|
|
325
|
+
pass "B: committable checkout emits SOLEUR_REAP_ARCHIVE_COMMITTED"
|
|
326
|
+
else
|
|
327
|
+
fail "B: no COMMITTED marker on a feature-branch reap (output: $(grep 'SOLEUR_' "$OUT_B" | head -5))"
|
|
328
|
+
fi
|
|
329
|
+
|
|
330
|
+
ARCH_COMMIT="$(git -C "$CLONE_B" log -1 --format=%s feat-actor 2>/dev/null)"
|
|
331
|
+
if [[ "$ARCH_COMMIT" == "chore(archive-kb): persist reap archive for feat-victim" ]]; then
|
|
332
|
+
pass "B: scoped chore(archive-kb) commit is the feat-actor tip"
|
|
333
|
+
else
|
|
334
|
+
fail "B: feat-actor tip is '$ARCH_COMMIT', not the archive commit"
|
|
335
|
+
fi
|
|
336
|
+
|
|
337
|
+
if grep -q '^R100' < <(git -C "$CLONE_B" show --name-status --format= feat-actor); then
|
|
338
|
+
pass "B: commit records R100 renames (git mv, not add+delete)"
|
|
339
|
+
else
|
|
340
|
+
fail "B: no R100 rename in the archive commit — the move was not `git mv`"
|
|
341
|
+
fi
|
|
342
|
+
|
|
343
|
+
# The commit's touched-path set equals EXACTLY the archive-move set.
|
|
344
|
+
# `git show --name-only` on a rename commit lists the DESTINATION paths
|
|
345
|
+
# (sources appear only via --name-status, asserted above as R100).
|
|
346
|
+
COMMIT_PATHS="$(git -C "$CLONE_B" show --name-only --format= feat-actor | LC_ALL=C sort)"
|
|
347
|
+
COMMIT_PATH_COUNT="$(printf '%s\n' "$COMMIT_PATHS" | grep -c .)"
|
|
348
|
+
BAD_PATHS="$(printf '%s\n' "$COMMIT_PATHS" | grep -vcE '^knowledge-base/project/(specs|plans)/archive/.*feat-victim' || true)"
|
|
349
|
+
if [[ "$COMMIT_PATH_COUNT" -eq 2 && "$BAD_PATHS" -eq 0 ]] \
|
|
350
|
+
&& grep -q 'specs/archive/.*feat-victim' <<<"$COMMIT_PATHS" \
|
|
351
|
+
&& grep -q 'plans/archive/.*feat-victim' <<<"$COMMIT_PATHS"; then
|
|
352
|
+
pass "B: commit path-set is exactly the archive-move set (no staged.txt, no untracked brainstorm)"
|
|
353
|
+
else
|
|
354
|
+
fail "B: commit path-set wrong: $(printf '%s' "$COMMIT_PATHS" | head -8)"
|
|
355
|
+
fi
|
|
356
|
+
|
|
357
|
+
if [[ "$(git -C "$CLONE_B" diff --cached --name-only)" == "staged.txt" ]]; then
|
|
358
|
+
pass "B: pre-staged unrelated file still staged-and-uncommitted (AC5)"
|
|
359
|
+
else
|
|
360
|
+
fail "B: staged.txt was swept or lost: index now '$(git -C "$CLONE_B" diff --cached --name-only | head -3)'"
|
|
361
|
+
fi
|
|
362
|
+
|
|
363
|
+
if [[ ! -e "$CLONE_B/knowledge-base/project/specs/feat-victim" ]] && spec_arch "$CLONE_B"; then
|
|
364
|
+
pass "B: tracked spec dir moved live->archive via git mv"
|
|
365
|
+
else
|
|
366
|
+
fail "B: spec dir did not reach archive/ on a committable checkout"
|
|
367
|
+
fi
|
|
368
|
+
|
|
369
|
+
# The untracked brainstorm file in the SAME batch plain-mv'd (per-file probe).
|
|
370
|
+
if grep -q 'feat-victim' < <(ls "$CLONE_B/knowledge-base/project/brainstorms/archive/" 2>/dev/null) \
|
|
371
|
+
&& ! is_tracked "$CLONE_B" "$(cd "$CLONE_B" 2>/dev/null && cd knowledge-base/project/brainstorms/archive 2>/dev/null && ls | grep feat-victim | head -1 | sed 's|^|knowledge-base/project/brainstorms/archive/|')"; then
|
|
372
|
+
pass "B: untracked brainstorm file plain-mv'd in the same reap (mixed batch)"
|
|
373
|
+
else
|
|
374
|
+
fail "B: untracked brainstorm file missing from archive or wrongly committed"
|
|
375
|
+
fi
|
|
376
|
+
|
|
377
|
+
# ===========================================================================
|
|
378
|
+
# FIXTURE C — untracked spec dir on `main`. Plain `mv` is a contract-permitted
|
|
379
|
+
# variant (guard-matrix row 7): untracked files cannot resurrect.
|
|
380
|
+
# ===========================================================================
|
|
381
|
+
LEASE_ROOT="$TMP/lease-c"; mk_lease_root "$LEASE_ROOT"
|
|
382
|
+
BARE_C="$TMP/c-origin.git"; CLONE_C="$TMP/c-clone"
|
|
383
|
+
build_clone "$BARE_C" "$CLONE_C" untracked
|
|
384
|
+
|
|
385
|
+
if spec_live "$CLONE_C" && ! is_tracked "$CLONE_C" knowledge-base/project/specs/feat-victim/spec.md; then
|
|
386
|
+
pass "C precondition: spec dir present and untracked on main"
|
|
387
|
+
else
|
|
388
|
+
fail "C precondition: untracked fixture is tracked or absent — vacuous fixture"
|
|
389
|
+
fi
|
|
390
|
+
|
|
391
|
+
OUT_C="$TMP/c-out.txt"
|
|
392
|
+
run_cleanup "$CLONE_C" "$OUT_C"
|
|
393
|
+
|
|
394
|
+
if spec_arch "$CLONE_C" && ! spec_live "$CLONE_C"; then
|
|
395
|
+
pass "C: untracked spec dir still archives via plain mv on main"
|
|
396
|
+
else
|
|
397
|
+
fail "C: untracked spec dir did not reach archive/ (plain-mv arm regressed)"
|
|
398
|
+
fi
|
|
399
|
+
if ! grep -q 'chore(archive-kb)' < <(git -C "$CLONE_C" log --oneline -5 --format=%s); then
|
|
400
|
+
pass "C: untracked move produced no commit on main"
|
|
401
|
+
else
|
|
402
|
+
fail "C: a commit landed on main for an untracked move"
|
|
403
|
+
fi
|
|
404
|
+
if plan_live "$CLONE_C" && ! plan_arch "$CLONE_C"; then
|
|
405
|
+
pass "C: TRACKED plan file in the same reap was still deferred (per-file probe)"
|
|
406
|
+
else
|
|
407
|
+
fail "C: tracked plan file moved on main — per-file classification failed"
|
|
408
|
+
fi
|
|
409
|
+
|
|
410
|
+
# ===========================================================================
|
|
411
|
+
# FIXTURE D — bare repo whose HEAD tracks the spec path (stale on-disk
|
|
412
|
+
# mirror). Expect DEFERRED reason=bare and zero disk churn of the mirror:
|
|
413
|
+
# sync_bare_files would only re-materialize a moved file anyway.
|
|
414
|
+
# ===========================================================================
|
|
415
|
+
LEASE_ROOT="$TMP/lease-d"; mk_lease_root "$LEASE_ROOT"
|
|
416
|
+
BARE_D="$TMP/d-bare.git"
|
|
417
|
+
git init --bare -b main "$BARE_D" >/dev/null
|
|
418
|
+
SEED_D="$TMP/d-seed"
|
|
419
|
+
git clone "$BARE_D" "$SEED_D" >/dev/null 2>&1
|
|
420
|
+
( set -e
|
|
421
|
+
cdx "$SEED_D"
|
|
422
|
+
git -c user.email=t@t -c user.name=t commit --allow-empty -m seed >/dev/null
|
|
423
|
+
git checkout -b feat-victim >/dev/null 2>&1
|
|
424
|
+
mkdir -p knowledge-base/project/specs/feat-victim
|
|
425
|
+
echo spec > knowledge-base/project/specs/feat-victim/spec.md
|
|
426
|
+
git add knowledge-base
|
|
427
|
+
GIT_COMMITTER_DATE="2025-01-01T00:00:00Z" \
|
|
428
|
+
git -c user.email=t@t -c user.name=t commit --date "2025-01-01T00:00:00Z" -m "victim kb artifacts" >/dev/null
|
|
429
|
+
git push origin feat-victim main >/dev/null 2>&1
|
|
430
|
+
)
|
|
431
|
+
# feat-victim tip IS main's tip => 'git branch --merged main' lists it.
|
|
432
|
+
git -C "$BARE_D" update-ref refs/heads/main "$(git -C "$BARE_D" rev-parse refs/heads/feat-victim)"
|
|
433
|
+
# cleanup-merged fetches origin — give the bare repo a working (self) remote.
|
|
434
|
+
git -C "$BARE_D" remote add origin "$BARE_D"
|
|
435
|
+
# The stale on-disk mirror: HEAD-tracked content parked at the live path.
|
|
436
|
+
mkdir -p "$BARE_D/knowledge-base/project/specs/feat-victim"
|
|
437
|
+
echo spec > "$BARE_D/knowledge-base/project/specs/feat-victim/spec.md"
|
|
438
|
+
|
|
439
|
+
# Precondition: the mirror path IS tracked in HEAD on the bare repo.
|
|
440
|
+
if [[ -n "$(git -C "$BARE_D" ls-tree -r HEAD --name-only -- knowledge-base/project/specs/feat-victim)" ]]; then
|
|
441
|
+
pass "D precondition: mirror path is HEAD-tracked on the bare repo"
|
|
442
|
+
else
|
|
443
|
+
fail "D precondition: mirror path not in HEAD — vacuous fixture"
|
|
444
|
+
fi
|
|
445
|
+
|
|
446
|
+
OUT_D="$TMP/d-out.txt"
|
|
447
|
+
run_cleanup_bare "$BARE_D" "$OUT_D"
|
|
448
|
+
|
|
449
|
+
if grep -q 'SOLEUR_REAP_ARCHIVE_DEFERRED .*reason=bare' "$OUT_D"; then
|
|
450
|
+
pass "D: bare-root reap emits DEFERRED reason=bare"
|
|
451
|
+
else
|
|
452
|
+
fail "D: no DEFERRED/bare marker (output: $(grep 'SOLEUR_' "$OUT_D" | head -5))"
|
|
453
|
+
fi
|
|
454
|
+
if spec_live "$BARE_D"; then
|
|
455
|
+
pass "D: bare-root mirror left in place"
|
|
456
|
+
else
|
|
457
|
+
fail "D: bare-root mirror was churned (moved) — sync_bare_files would re-materialize it"
|
|
458
|
+
fi
|
|
459
|
+
if spec_arch "$BARE_D"; then
|
|
460
|
+
fail "D: an archive copy was produced on the bare root — the mirror-twin mechanism"
|
|
461
|
+
else
|
|
462
|
+
pass "D: no archive copy produced on the bare root"
|
|
463
|
+
fi
|
|
464
|
+
|
|
465
|
+
# ===========================================================================
|
|
466
|
+
# FIXTURE E — feature-branch checkout where `git commit` fails (no resolvable
|
|
467
|
+
# identity). Expect STAGED: the staged rename payload persists so the session's
|
|
468
|
+
# own commits carry it.
|
|
469
|
+
# ===========================================================================
|
|
470
|
+
LEASE_ROOT="$TMP/lease-e"; mk_lease_root "$LEASE_ROOT"
|
|
471
|
+
BARE_E="$TMP/e-origin.git"; CLONE_E="$TMP/e-clone"
|
|
472
|
+
build_clone "$BARE_E" "$CLONE_E" tracked
|
|
473
|
+
|
|
474
|
+
( set -e
|
|
475
|
+
cdx "$CLONE_E"
|
|
476
|
+
# No local identity, and force failure if one is still resolved: the reap's
|
|
477
|
+
# chore commit must fail deterministically on ANY host.
|
|
478
|
+
git config --unset user.email 2>/dev/null || true
|
|
479
|
+
git config --unset user.name 2>/dev/null || true
|
|
480
|
+
git config user.useConfigOnly true
|
|
481
|
+
git checkout -b feat-actor >/dev/null 2>&1
|
|
482
|
+
)
|
|
483
|
+
mkdir -p "$TMP/nohome" # empty HOME + XDG_CONFIG_HOME => no --global identity either
|
|
484
|
+
# (git reads $XDG_CONFIG_HOME/git/config for global config; HOME alone is not enough)
|
|
485
|
+
|
|
486
|
+
OUT_E="$TMP/e-out.txt"
|
|
487
|
+
run_cleanup "$CLONE_E" "$OUT_E" "HOME=$TMP/nohome" "XDG_CONFIG_HOME=$TMP/nohome" "GIT_CONFIG_NOSYSTEM=1"
|
|
488
|
+
|
|
489
|
+
if grep -q 'SOLEUR_REAP_ARCHIVE_STAGED' "$OUT_E"; then
|
|
490
|
+
pass "E: commit failure emits SOLEUR_REAP_ARCHIVE_STAGED"
|
|
491
|
+
else
|
|
492
|
+
fail "E: no STAGED marker on commit failure (output: $(grep 'SOLEUR_' "$OUT_E" | head -5))"
|
|
493
|
+
fi
|
|
494
|
+
if ! grep -q 'chore(archive-kb)' < <(git -C "$CLONE_E" log --oneline -5 --format=%s feat-actor); then
|
|
495
|
+
pass "E: no archive commit landed when commit failed"
|
|
496
|
+
else
|
|
497
|
+
fail "E: chore commit landed despite the forced identity failure"
|
|
498
|
+
fi
|
|
499
|
+
if grep -qE '^R100|^A' < <(git -C "$CLONE_E" diff --cached --name-status); then
|
|
500
|
+
pass "E: staged rename payload survives in the index for the session to carry"
|
|
501
|
+
else
|
|
502
|
+
fail "E: archive move vanished instead of staying staged"
|
|
503
|
+
fi
|
|
504
|
+
|
|
505
|
+
# ===========================================================================
|
|
506
|
+
# FIXTURE F — detached HEAD. AC2 names detached; the HEAD arm must defer.
|
|
507
|
+
# ===========================================================================
|
|
508
|
+
LEASE_ROOT="$TMP/lease-f"; mk_lease_root "$LEASE_ROOT"
|
|
509
|
+
BARE_F="$TMP/f-origin.git"; CLONE_F="$TMP/f-clone"
|
|
510
|
+
build_clone "$BARE_F" "$CLONE_F" tracked
|
|
511
|
+
|
|
512
|
+
( set -e
|
|
513
|
+
cdx "$CLONE_F"
|
|
514
|
+
git checkout --detach HEAD >/dev/null 2>&1
|
|
515
|
+
)
|
|
516
|
+
|
|
517
|
+
if [[ "$(git -C "$CLONE_F" rev-parse --abbrev-ref HEAD)" == "HEAD" ]]; then
|
|
518
|
+
pass "F precondition: checkout is detached"
|
|
519
|
+
else
|
|
520
|
+
fail "F precondition: checkout is not detached"
|
|
521
|
+
fi
|
|
522
|
+
|
|
523
|
+
OUT_F="$TMP/f-out.txt"
|
|
524
|
+
run_cleanup "$CLONE_F" "$OUT_F"
|
|
525
|
+
|
|
526
|
+
if grep -q 'SOLEUR_REAP_ARCHIVE_DEFERRED .*reason=detached' "$OUT_F"; then
|
|
527
|
+
pass "F: detached checkout emits DEFERRED reason=detached"
|
|
528
|
+
else
|
|
529
|
+
fail "F: no DEFERRED/detached marker (output: $(grep 'SOLEUR_' "$OUT_F" | head -5))"
|
|
530
|
+
fi
|
|
531
|
+
if spec_live "$CLONE_F" && ! spec_arch "$CLONE_F"; then
|
|
532
|
+
pass "F: tracked spec dir left live on a detached HEAD"
|
|
533
|
+
else
|
|
534
|
+
fail "F: tracked spec dir moved on a detached HEAD"
|
|
535
|
+
fi
|
|
536
|
+
|
|
537
|
+
# ===========================================================================
|
|
538
|
+
# FIXTURE G — committable checkout where `git mv` fails (specs/ parent made
|
|
539
|
+
# read-only). Expect: DEFERRED reason=git-mv-failed for the spec, the tracked
|
|
540
|
+
# plan still commits, and no marker-free partial move.
|
|
541
|
+
# ===========================================================================
|
|
542
|
+
LEASE_ROOT="$TMP/lease-g"; mk_lease_root "$LEASE_ROOT"
|
|
543
|
+
BARE_G="$TMP/g-origin.git"; CLONE_G="$TMP/g-clone"
|
|
544
|
+
build_clone "$BARE_G" "$CLONE_G" tracked
|
|
545
|
+
|
|
546
|
+
( set -e
|
|
547
|
+
cdx "$CLONE_G"
|
|
548
|
+
git checkout -b feat-actor >/dev/null 2>&1
|
|
549
|
+
# git mv needs write perms on the destination's parent chain; a read-only
|
|
550
|
+
# specs/ fails every spec move deterministically on any host.
|
|
551
|
+
chmod a-w knowledge-base/project/specs
|
|
552
|
+
)
|
|
553
|
+
|
|
554
|
+
OUT_G="$TMP/g-out.txt"
|
|
555
|
+
run_cleanup "$CLONE_G" "$OUT_G"
|
|
556
|
+
# Restore perms before assertions (and so the EXIT trap's rm -rf can clean up).
|
|
557
|
+
chmod -R u+w "$CLONE_G" 2>/dev/null || true
|
|
558
|
+
|
|
559
|
+
# One failure of fixture G was seen under shard contention with at most five marker
|
|
560
|
+
# lines on its first arm and nothing on the other two (cause unproven, #7376 class). $OUT_G
|
|
561
|
+
# lives under $TMP and the EXIT trap deletes it, so inline everything a reader
|
|
562
|
+
# needs to tell a STAGED outcome from a COMMITTED one from a hook failure,
|
|
563
|
+
# flattened to one line.
|
|
564
|
+
g_diag() {
|
|
565
|
+
local markers tailout status log
|
|
566
|
+
markers="$(grep 'SOLEUR_' "$OUT_G" 2>/dev/null | tr '\n' '|')"
|
|
567
|
+
tailout="$(tail -20 "$OUT_G" 2>/dev/null | tr '\n' '|')"
|
|
568
|
+
status="$(git --no-optional-locks -C "$CLONE_G" status --short 2>&1 | tr '\n' '|')"
|
|
569
|
+
log="$(git -C "$CLONE_G" log --oneline -5 feat-actor 2>&1 | tr '\n' '|')"
|
|
570
|
+
printf 'markers=[%s] tail20=[%s] status=[%s] log=[%s]' "$markers" "$tailout" "$status" "$log"
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
if grep -q 'SOLEUR_REAP_ARCHIVE_DEFERRED .*reason=git-mv-failed' "$OUT_G"; then
|
|
574
|
+
pass "G: failed git mv emits DEFERRED reason=git-mv-failed (not a silent warn)"
|
|
575
|
+
else
|
|
576
|
+
fail "G: no git-mv-failed marker ($(g_diag))"
|
|
577
|
+
fi
|
|
578
|
+
if spec_live "$CLONE_G" && ! spec_arch "$CLONE_G"; then
|
|
579
|
+
pass "G: failed git mv left the spec dir live (no partial move, no plain-mv fallback)"
|
|
580
|
+
else
|
|
581
|
+
fail "G: spec dir moved/archived despite the failed git mv ($(g_diag))"
|
|
582
|
+
fi
|
|
583
|
+
# The tracked plan file DID move (plans/ stayed writable) — its commit proves
|
|
584
|
+
# the mv-failure arm did not abort the reap loop mid-batch.
|
|
585
|
+
if grep -q 'chore(archive-kb)' < <(git -C "$CLONE_G" log --oneline -3 --format=%s feat-actor); then
|
|
586
|
+
pass "G: tracked plan still committed — failed spec move did not abort the reap"
|
|
587
|
+
else
|
|
588
|
+
fail "G: plan archive commit missing — the mv failure aborted the run ($(g_diag))"
|
|
589
|
+
fi
|
|
590
|
+
# The diagnostic only runs inside the three failure arms above, so nothing else
|
|
591
|
+
# exercises it: pin that it still emits every field a reader needs.
|
|
592
|
+
G_DIAG_OUT="$(g_diag)"
|
|
593
|
+
if [[ "$G_DIAG_OUT" == *"markers=["*"SOLEUR_"*"] tail20=["*"] status=["*"] log=["*"]" ]]; then
|
|
594
|
+
pass "G: failure diagnostic carries SOLEUR_ markers, tail20, status and log"
|
|
595
|
+
else
|
|
596
|
+
fail "G: failure diagnostic is missing a field: $G_DIAG_OUT"
|
|
597
|
+
fi
|
|
598
|
+
|
|
599
|
+
# ===========================================================================
|
|
600
|
+
# FIXTURE H — committable branch mid-merge (MERGE_HEAD present). A scoped
|
|
601
|
+
# commit is refused by git mid-merge and the payload would fold into the
|
|
602
|
+
# operator's merge commit — defer instead.
|
|
603
|
+
# ===========================================================================
|
|
604
|
+
LEASE_ROOT="$TMP/lease-h"; mk_lease_root "$LEASE_ROOT"
|
|
605
|
+
BARE_H="$TMP/h-origin.git"; CLONE_H="$TMP/h-clone"
|
|
606
|
+
build_clone "$BARE_H" "$CLONE_H" tracked
|
|
607
|
+
|
|
608
|
+
( set -e
|
|
609
|
+
cdx "$CLONE_H"
|
|
610
|
+
git checkout -b feat-actor >/dev/null 2>&1
|
|
611
|
+
echo one > conflict.txt
|
|
612
|
+
git add conflict.txt
|
|
613
|
+
git commit -m actor-side >/dev/null
|
|
614
|
+
git checkout -b feat-side main >/dev/null 2>&1
|
|
615
|
+
echo two > conflict.txt
|
|
616
|
+
git add conflict.txt
|
|
617
|
+
git commit -m side >/dev/null
|
|
618
|
+
git checkout feat-actor >/dev/null 2>&1
|
|
619
|
+
# Conflicting merge -> MERGE_HEAD present on feat-actor.
|
|
620
|
+
git merge feat-side >/dev/null 2>&1 || true
|
|
621
|
+
)
|
|
622
|
+
|
|
623
|
+
if git -C "$CLONE_H" rev-parse -q --verify MERGE_HEAD >/dev/null 2>&1 \
|
|
624
|
+
&& [[ "$(git -C "$CLONE_H" rev-parse --abbrev-ref HEAD)" == "feat-actor" ]]; then
|
|
625
|
+
pass "H precondition: merge in progress on a feature branch"
|
|
626
|
+
else
|
|
627
|
+
fail "H precondition: merge did not produce MERGE_HEAD — vacuous fixture"
|
|
628
|
+
fi
|
|
629
|
+
|
|
630
|
+
OUT_H="$TMP/h-out.txt"
|
|
631
|
+
run_cleanup "$CLONE_H" "$OUT_H"
|
|
632
|
+
|
|
633
|
+
if grep -q 'SOLEUR_REAP_ARCHIVE_DEFERRED .*reason=merge-in-progress' "$OUT_H"; then
|
|
634
|
+
pass "H: merge-in-progress checkout emits DEFERRED reason=merge-in-progress"
|
|
635
|
+
else
|
|
636
|
+
fail "H: no merge-in-progress marker (output: $(grep 'SOLEUR_' "$OUT_H" | head -5))"
|
|
637
|
+
fi
|
|
638
|
+
if spec_live "$CLONE_H" && ! spec_arch "$CLONE_H"; then
|
|
639
|
+
pass "H: tracked spec dir left live mid-merge (payload never folds into a merge commit)"
|
|
640
|
+
else
|
|
641
|
+
fail "H: tracked spec dir moved mid-merge"
|
|
642
|
+
fi
|
|
643
|
+
if ! grep -q 'chore(archive-kb)' < <(git -C "$CLONE_H" log --oneline -3 --format=%s feat-actor); then
|
|
644
|
+
pass "H: no archive commit landed during a merge"
|
|
645
|
+
else
|
|
646
|
+
fail "H: chore commit landed mid-merge"
|
|
647
|
+
fi
|
|
648
|
+
|
|
649
|
+
# ===========================================================================
|
|
650
|
+
# FIXTURE I — branch literally named `feat-`: feature_slug strips to EMPTY,
|
|
651
|
+
# which would collapse the plans/brainstorms glob to `*` and sweep every file
|
|
652
|
+
# in the directory. The guard must refuse the batch entirely.
|
|
653
|
+
# ===========================================================================
|
|
654
|
+
LEASE_ROOT="$TMP/lease-i"; mk_lease_root "$LEASE_ROOT"
|
|
655
|
+
BARE_I="$TMP/i-origin.git"; CLONE_I="$TMP/i-clone"
|
|
656
|
+
git init --bare -b main "$BARE_I" >/dev/null
|
|
657
|
+
git clone "$BARE_I" "$CLONE_I" >/dev/null 2>&1
|
|
658
|
+
( set -e
|
|
659
|
+
cdx "$CLONE_I"
|
|
660
|
+
git config user.email t@t
|
|
661
|
+
git config user.name t
|
|
662
|
+
git config commit.gpgsign false
|
|
663
|
+
git commit --allow-empty -m seed >/dev/null
|
|
664
|
+
git checkout -b 'feat-' >/dev/null 2>&1
|
|
665
|
+
mkdir -p knowledge-base/project/plans
|
|
666
|
+
echo p > "knowledge-base/project/plans/2026-01-01-feat--plan.md"
|
|
667
|
+
echo u > "knowledge-base/project/plans/2026-02-02-unrelated-plan.md"
|
|
668
|
+
git add knowledge-base
|
|
669
|
+
GIT_COMMITTER_DATE="2025-01-01T00:00:00Z" \
|
|
670
|
+
git commit --date "2025-01-01T00:00:00Z" -m "kb artifacts" >/dev/null
|
|
671
|
+
git checkout main >/dev/null 2>&1
|
|
672
|
+
git merge --no-ff -m "merge feat-" 'feat-' >/dev/null 2>&1
|
|
673
|
+
git push origin main 'feat-' >/dev/null 2>&1
|
|
674
|
+
git checkout -b feat-actor >/dev/null 2>&1
|
|
675
|
+
)
|
|
676
|
+
|
|
677
|
+
OUT_I="$TMP/i-out.txt"
|
|
678
|
+
run_cleanup "$CLONE_I" "$OUT_I"
|
|
679
|
+
|
|
680
|
+
if [[ -f "$CLONE_I/knowledge-base/project/plans/2026-02-02-unrelated-plan.md" ]]; then
|
|
681
|
+
pass "I: unrelated plan file survived — empty slug did not sweep the directory"
|
|
682
|
+
else
|
|
683
|
+
fail "I: unrelated plan file was swept (empty-slug glob collapse)"
|
|
684
|
+
fi
|
|
685
|
+
if [[ -f "$CLONE_I/knowledge-base/project/plans/2026-01-01-feat--plan.md" ]]; then
|
|
686
|
+
pass "I: the feat- plan file stayed live too (empty slug refuses the batch)"
|
|
687
|
+
else
|
|
688
|
+
fail "I: feat- plan file moved — the guard should refuse, not partially move"
|
|
689
|
+
fi
|
|
690
|
+
if ! grep -q 'chore(archive-kb)' < <(git -C "$CLONE_I" log --oneline -3 --format=%s feat-actor); then
|
|
691
|
+
pass "I: no archive commit produced for an empty feature slug"
|
|
692
|
+
else
|
|
693
|
+
fail "I: a chore commit landed for the empty-slug sweep"
|
|
694
|
+
fi
|
|
695
|
+
|
|
696
|
+
# ===========================================================================
|
|
697
|
+
# Census (guard-matrix row 5): every KB archive move routes through
|
|
698
|
+
# reap_archive_persist. Extract the two caller regions and the helper body;
|
|
699
|
+
# a bare `mv`/`git mv` in a caller region is the defect class reborn.
|
|
700
|
+
# ===========================================================================
|
|
701
|
+
_arch_body="$(awk '/^archive_kb_files\(\) \{/,/^\}/' "$WM")"
|
|
702
|
+
_spec_block="$(awk '/Archive spec directory/,/Extract feature slug/' "$WM")"
|
|
703
|
+
_helper_body="$(awk '/^reap_archive_persist\(\) \{/,/^\}/' "$WM")"
|
|
704
|
+
|
|
705
|
+
_mv_cmds() { grep -vE '^[[:space:]]*#' | grep -cE '\b(git[[:space:]]+)?mv[[:space:]]' || true; }
|
|
706
|
+
|
|
707
|
+
if grep -q 'reap_archive_persist' <<<"$_arch_body" && [[ "$(printf '%s\n' "$_arch_body" | _mv_cmds)" -eq 0 ]]; then
|
|
708
|
+
pass "census: archive_kb_files routes through reap_archive_persist, no bare mv"
|
|
709
|
+
else
|
|
710
|
+
fail "census: archive_kb_files moves artifacts without the helper"
|
|
711
|
+
fi
|
|
712
|
+
if grep -q 'reap_archive_persist' <<<"$_spec_block" && [[ "$(printf '%s\n' "$_spec_block" | _mv_cmds)" -eq 0 ]]; then
|
|
713
|
+
pass "census: spec-dir block routes through reap_archive_persist, no bare mv"
|
|
714
|
+
else
|
|
715
|
+
fail "census: spec-dir block moves artifacts without the helper"
|
|
716
|
+
fi
|
|
717
|
+
if grep -q 'git -C "$GIT_ROOT" mv -- ' <<<"$_helper_body" && grep -qE '(^|[^[:alnum:]_])mv -- "\$src"' <<<"$_helper_body"; then
|
|
718
|
+
pass "census: the helper owns both move arms (git mv + plain mv)"
|
|
719
|
+
else
|
|
720
|
+
fail "census: reap_archive_persist does not own both move arms"
|
|
721
|
+
fi
|
|
722
|
+
|
|
723
|
+
echo ""
|
|
724
|
+
echo "=== $PASS passed, $FAIL failed ==="
|
|
725
|
+
[[ "$FAIL" -eq 0 ]]
|