autonomous-coding-toolkit 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +22 -0
- package/.claude-plugin/plugin.json +13 -0
- package/LICENSE +21 -0
- package/Makefile +21 -0
- package/README.md +140 -0
- package/SECURITY.md +28 -0
- package/agents/bash-expert.md +113 -0
- package/agents/dependency-auditor.md +138 -0
- package/agents/integration-tester.md +120 -0
- package/agents/lesson-scanner.md +149 -0
- package/agents/python-expert.md +179 -0
- package/agents/service-monitor.md +141 -0
- package/agents/shell-expert.md +147 -0
- package/benchmarks/runner.sh +147 -0
- package/benchmarks/tasks/01-rest-endpoint/rubric.sh +29 -0
- package/benchmarks/tasks/01-rest-endpoint/task.md +17 -0
- package/benchmarks/tasks/02-refactor-module/task.md +8 -0
- package/benchmarks/tasks/03-fix-integration-bug/task.md +8 -0
- package/benchmarks/tasks/04-add-test-coverage/task.md +8 -0
- package/benchmarks/tasks/05-multi-file-feature/task.md +8 -0
- package/bin/act.js +238 -0
- package/commands/autocode.md +6 -0
- package/commands/cancel-ralph.md +18 -0
- package/commands/code-factory.md +53 -0
- package/commands/create-prd.md +55 -0
- package/commands/ralph-loop.md +18 -0
- package/commands/run-plan.md +117 -0
- package/commands/submit-lesson.md +122 -0
- package/docs/ARCHITECTURE.md +630 -0
- package/docs/CONTRIBUTING.md +125 -0
- package/docs/lessons/0001-bare-exception-swallowing.md +34 -0
- package/docs/lessons/0002-async-def-without-await.md +28 -0
- package/docs/lessons/0003-create-task-without-callback.md +28 -0
- package/docs/lessons/0004-hardcoded-test-counts.md +28 -0
- package/docs/lessons/0005-sqlite-without-closing.md +33 -0
- package/docs/lessons/0006-venv-pip-path.md +27 -0
- package/docs/lessons/0007-runner-state-self-rejection.md +35 -0
- package/docs/lessons/0008-quality-gate-blind-spot.md +33 -0
- package/docs/lessons/0009-parser-overcount-empty-batches.md +36 -0
- package/docs/lessons/0010-local-outside-function-bash.md +33 -0
- package/docs/lessons/0011-batch-tests-for-unimplemented-code.md +36 -0
- package/docs/lessons/0012-api-markdown-unescaped-chars.md +33 -0
- package/docs/lessons/0013-export-prefix-env-parsing.md +33 -0
- package/docs/lessons/0014-decorator-registry-import-side-effect.md +43 -0
- package/docs/lessons/0015-frontend-backend-schema-drift.md +43 -0
- package/docs/lessons/0016-event-driven-cold-start-seeding.md +44 -0
- package/docs/lessons/0017-copy-paste-logic-diverges.md +43 -0
- package/docs/lessons/0018-layer-passes-pipeline-broken.md +45 -0
- package/docs/lessons/0019-systemd-envfile-ignores-export.md +41 -0
- package/docs/lessons/0020-persist-state-incrementally.md +44 -0
- package/docs/lessons/0021-dual-axis-testing.md +48 -0
- package/docs/lessons/0022-jsx-factory-shadowing.md +43 -0
- package/docs/lessons/0023-static-analysis-spiral.md +51 -0
- package/docs/lessons/0024-shared-pipeline-implementation.md +55 -0
- package/docs/lessons/0025-defense-in-depth-all-entry-points.md +65 -0
- package/docs/lessons/0026-linter-no-rules-false-enforcement.md +54 -0
- package/docs/lessons/0027-jsx-silent-prop-drop.md +64 -0
- package/docs/lessons/0028-no-infrastructure-in-client-code.md +49 -0
- package/docs/lessons/0029-never-write-secrets-to-files.md +61 -0
- package/docs/lessons/0030-cache-merge-not-replace.md +62 -0
- package/docs/lessons/0031-verify-units-at-boundaries.md +66 -0
- package/docs/lessons/0032-module-lifecycle-subscribe-unsubscribe.md +89 -0
- package/docs/lessons/0033-async-iteration-mutable-snapshot.md +72 -0
- package/docs/lessons/0034-caller-missing-await-silent-discard.md +65 -0
- package/docs/lessons/0035-duplicate-registration-silent-overwrite.md +85 -0
- package/docs/lessons/0036-websocket-dirty-disconnect.md +33 -0
- package/docs/lessons/0037-parallel-agents-worktree-corruption.md +31 -0
- package/docs/lessons/0038-subscribe-no-stored-ref.md +36 -0
- package/docs/lessons/0039-fallback-or-default-hides-bugs.md +34 -0
- package/docs/lessons/0040-event-firehose-filter-first.md +36 -0
- package/docs/lessons/0041-ambiguous-base-dir-path-nesting.md +32 -0
- package/docs/lessons/0042-spec-compliance-insufficient.md +36 -0
- package/docs/lessons/0043-exact-count-extensible-collections.md +32 -0
- package/docs/lessons/0044-relative-file-deps-worktree.md +39 -0
- package/docs/lessons/0045-iterative-design-improvement.md +33 -0
- package/docs/lessons/0046-plan-assertion-math-bugs.md +38 -0
- package/docs/lessons/0047-pytest-single-threaded-default.md +37 -0
- package/docs/lessons/0048-integration-wiring-batch.md +40 -0
- package/docs/lessons/0049-ab-verification.md +41 -0
- package/docs/lessons/0050-editing-sourced-files-during-execution.md +33 -0
- package/docs/lessons/0051-infrastructure-fixes-cant-self-heal.md +30 -0
- package/docs/lessons/0052-uncommitted-changes-poison-quality-gates.md +31 -0
- package/docs/lessons/0053-jq-compact-flag-inconsistency.md +31 -0
- package/docs/lessons/0054-parser-matches-inside-code-blocks.md +30 -0
- package/docs/lessons/0055-agents-compensate-for-garbled-prompts.md +31 -0
- package/docs/lessons/0056-grep-count-exit-code-on-zero.md +42 -0
- package/docs/lessons/0057-new-artifacts-break-git-clean-gates.md +42 -0
- package/docs/lessons/0058-dead-config-keys-never-consumed.md +49 -0
- package/docs/lessons/0059-contract-test-shared-structures.md +53 -0
- package/docs/lessons/0060-set-e-silent-death-in-runners.md +53 -0
- package/docs/lessons/0061-context-injection-dirty-state.md +50 -0
- package/docs/lessons/0062-sibling-bug-neighborhood-scan.md +29 -0
- package/docs/lessons/0063-one-flag-two-lifetimes.md +31 -0
- package/docs/lessons/0064-test-passes-wrong-reason.md +31 -0
- package/docs/lessons/0065-pipefail-grep-count-double-output.md +39 -0
- package/docs/lessons/0066-local-keyword-outside-function.md +37 -0
- package/docs/lessons/0067-stdin-hang-non-interactive-shell.md +36 -0
- package/docs/lessons/0068-agent-builds-wrong-thing-correctly.md +31 -0
- package/docs/lessons/0069-plan-quality-dominates-execution.md +30 -0
- package/docs/lessons/0070-spec-echo-back-prevents-drift.md +31 -0
- package/docs/lessons/0071-positive-instructions-outperform-negative.md +30 -0
- package/docs/lessons/0072-lost-in-the-middle-context-placement.md +30 -0
- package/docs/lessons/0073-unscoped-lessons-cause-false-positives.md +30 -0
- package/docs/lessons/0074-stale-context-injection-wrong-batch.md +32 -0
- package/docs/lessons/0075-research-artifacts-must-persist.md +32 -0
- package/docs/lessons/0076-wrong-decomposition-contaminates-downstream.md +30 -0
- package/docs/lessons/0077-cherry-pick-merges-need-manual-resolution.md +30 -0
- package/docs/lessons/0078-static-review-without-live-test.md +30 -0
- package/docs/lessons/0079-integration-wiring-batch-required.md +32 -0
- package/docs/lessons/FRAMEWORK.md +161 -0
- package/docs/lessons/SUMMARY.md +201 -0
- package/docs/lessons/TEMPLATE.md +85 -0
- package/docs/plans/2026-02-21-code-factory-v2-design.md +204 -0
- package/docs/plans/2026-02-21-code-factory-v2-implementation-plan.md +2189 -0
- package/docs/plans/2026-02-21-code-factory-v2-phase4-design.md +537 -0
- package/docs/plans/2026-02-21-code-factory-v2-phase4-implementation-plan.md +2012 -0
- package/docs/plans/2026-02-21-hardening-pass-design.md +108 -0
- package/docs/plans/2026-02-21-hardening-pass-plan.md +1378 -0
- package/docs/plans/2026-02-21-mab-research-report.md +406 -0
- package/docs/plans/2026-02-21-marketplace-restructure-design.md +240 -0
- package/docs/plans/2026-02-21-marketplace-restructure-plan.md +832 -0
- package/docs/plans/2026-02-21-phase4-completion-plan.md +697 -0
- package/docs/plans/2026-02-21-validator-suite-design.md +148 -0
- package/docs/plans/2026-02-21-validator-suite-plan.md +540 -0
- package/docs/plans/2026-02-22-mab-research-round2.md +556 -0
- package/docs/plans/2026-02-22-mab-run-design.md +462 -0
- package/docs/plans/2026-02-22-mab-run-plan.md +2046 -0
- package/docs/plans/2026-02-22-operations-design-methodology-research.md +681 -0
- package/docs/plans/2026-02-22-research-agent-failure-taxonomy.md +532 -0
- package/docs/plans/2026-02-22-research-code-guideline-policies.md +886 -0
- package/docs/plans/2026-02-22-research-codebase-audit-refactoring.md +908 -0
- package/docs/plans/2026-02-22-research-coding-standards-documentation.md +541 -0
- package/docs/plans/2026-02-22-research-competitive-landscape.md +687 -0
- package/docs/plans/2026-02-22-research-comprehensive-testing.md +1076 -0
- package/docs/plans/2026-02-22-research-context-utilization.md +459 -0
- package/docs/plans/2026-02-22-research-cost-quality-tradeoff.md +548 -0
- package/docs/plans/2026-02-22-research-lesson-transferability.md +508 -0
- package/docs/plans/2026-02-22-research-multi-agent-coordination.md +312 -0
- package/docs/plans/2026-02-22-research-phase-integration.md +602 -0
- package/docs/plans/2026-02-22-research-plan-quality.md +428 -0
- package/docs/plans/2026-02-22-research-prompt-engineering.md +558 -0
- package/docs/plans/2026-02-22-research-unconventional-perspectives.md +528 -0
- package/docs/plans/2026-02-22-research-user-adoption.md +638 -0
- package/docs/plans/2026-02-22-research-verification-effectiveness.md +433 -0
- package/docs/plans/2026-02-23-agent-suite-design.md +299 -0
- package/docs/plans/2026-02-23-agent-suite-plan.md +578 -0
- package/docs/plans/2026-02-23-phase3-cost-infrastructure-design.md +148 -0
- package/docs/plans/2026-02-23-phase3-cost-infrastructure-plan.md +1062 -0
- package/docs/plans/2026-02-23-research-bash-expert-agent.md +543 -0
- package/docs/plans/2026-02-23-research-dependency-auditor-agent.md +564 -0
- package/docs/plans/2026-02-23-research-improving-existing-agents.md +503 -0
- package/docs/plans/2026-02-23-research-integration-tester-agent.md +454 -0
- package/docs/plans/2026-02-23-research-python-expert-agent.md +429 -0
- package/docs/plans/2026-02-23-research-service-monitor-agent.md +425 -0
- package/docs/plans/2026-02-23-research-shell-expert-agent.md +533 -0
- package/docs/plans/2026-02-23-roadmap-to-completion.md +530 -0
- package/docs/plans/2026-02-24-headless-module-split-design.md +98 -0
- package/docs/plans/2026-02-24-headless-module-split.md +443 -0
- package/docs/plans/2026-02-24-lesson-scope-metadata-design.md +228 -0
- package/docs/plans/2026-02-24-lesson-scope-metadata-plan.md +968 -0
- package/docs/plans/2026-02-24-npm-packaging-design.md +841 -0
- package/docs/plans/2026-02-24-npm-packaging-plan.md +1965 -0
- package/docs/plans/audit-findings.md +186 -0
- package/docs/telegram-notification-format.md +98 -0
- package/examples/example-plan.md +51 -0
- package/examples/example-prd.json +72 -0
- package/examples/example-roadmap.md +33 -0
- package/examples/quickstart-plan.md +63 -0
- package/hooks/hooks.json +26 -0
- package/hooks/setup-symlinks.sh +48 -0
- package/hooks/stop-hook.sh +135 -0
- package/package.json +47 -0
- package/policies/bash.md +71 -0
- package/policies/python.md +71 -0
- package/policies/testing.md +61 -0
- package/policies/universal.md +60 -0
- package/scripts/analyze-report.sh +97 -0
- package/scripts/architecture-map.sh +145 -0
- package/scripts/auto-compound.sh +273 -0
- package/scripts/batch-audit.sh +42 -0
- package/scripts/batch-test.sh +101 -0
- package/scripts/entropy-audit.sh +221 -0
- package/scripts/failure-digest.sh +51 -0
- package/scripts/generate-ast-rules.sh +96 -0
- package/scripts/init.sh +112 -0
- package/scripts/lesson-check.sh +428 -0
- package/scripts/lib/common.sh +61 -0
- package/scripts/lib/cost-tracking.sh +153 -0
- package/scripts/lib/ollama.sh +60 -0
- package/scripts/lib/progress-writer.sh +128 -0
- package/scripts/lib/run-plan-context.sh +215 -0
- package/scripts/lib/run-plan-echo-back.sh +231 -0
- package/scripts/lib/run-plan-headless.sh +396 -0
- package/scripts/lib/run-plan-notify.sh +57 -0
- package/scripts/lib/run-plan-parser.sh +81 -0
- package/scripts/lib/run-plan-prompt.sh +215 -0
- package/scripts/lib/run-plan-quality-gate.sh +132 -0
- package/scripts/lib/run-plan-routing.sh +315 -0
- package/scripts/lib/run-plan-sampling.sh +170 -0
- package/scripts/lib/run-plan-scoring.sh +146 -0
- package/scripts/lib/run-plan-state.sh +142 -0
- package/scripts/lib/run-plan-team.sh +199 -0
- package/scripts/lib/telegram.sh +54 -0
- package/scripts/lib/thompson-sampling.sh +176 -0
- package/scripts/license-check.sh +74 -0
- package/scripts/mab-run.sh +575 -0
- package/scripts/module-size-check.sh +146 -0
- package/scripts/patterns/async-no-await.yml +5 -0
- package/scripts/patterns/bare-except.yml +6 -0
- package/scripts/patterns/empty-catch.yml +6 -0
- package/scripts/patterns/hardcoded-localhost.yml +9 -0
- package/scripts/patterns/retry-loop-no-backoff.yml +12 -0
- package/scripts/pipeline-status.sh +197 -0
- package/scripts/policy-check.sh +226 -0
- package/scripts/prior-art-search.sh +133 -0
- package/scripts/promote-mab-lessons.sh +126 -0
- package/scripts/prompts/agent-a-superpowers.md +29 -0
- package/scripts/prompts/agent-b-ralph.md +29 -0
- package/scripts/prompts/judge-agent.md +61 -0
- package/scripts/prompts/planner-agent.md +44 -0
- package/scripts/pull-community-lessons.sh +90 -0
- package/scripts/quality-gate.sh +266 -0
- package/scripts/research-gate.sh +90 -0
- package/scripts/run-plan.sh +329 -0
- package/scripts/scope-infer.sh +159 -0
- package/scripts/setup-ralph-loop.sh +155 -0
- package/scripts/telemetry.sh +230 -0
- package/scripts/tests/run-all-tests.sh +52 -0
- package/scripts/tests/test-act-cli.sh +46 -0
- package/scripts/tests/test-agents-md.sh +87 -0
- package/scripts/tests/test-analyze-report.sh +114 -0
- package/scripts/tests/test-architecture-map.sh +89 -0
- package/scripts/tests/test-auto-compound.sh +169 -0
- package/scripts/tests/test-batch-test.sh +65 -0
- package/scripts/tests/test-benchmark-runner.sh +25 -0
- package/scripts/tests/test-common.sh +168 -0
- package/scripts/tests/test-cost-tracking.sh +158 -0
- package/scripts/tests/test-echo-back.sh +180 -0
- package/scripts/tests/test-entropy-audit.sh +146 -0
- package/scripts/tests/test-failure-digest.sh +66 -0
- package/scripts/tests/test-generate-ast-rules.sh +145 -0
- package/scripts/tests/test-helpers.sh +82 -0
- package/scripts/tests/test-init.sh +47 -0
- package/scripts/tests/test-lesson-check.sh +278 -0
- package/scripts/tests/test-lesson-local.sh +55 -0
- package/scripts/tests/test-license-check.sh +109 -0
- package/scripts/tests/test-mab-run.sh +182 -0
- package/scripts/tests/test-ollama-lib.sh +49 -0
- package/scripts/tests/test-ollama.sh +60 -0
- package/scripts/tests/test-pipeline-status.sh +198 -0
- package/scripts/tests/test-policy-check.sh +124 -0
- package/scripts/tests/test-prior-art-search.sh +96 -0
- package/scripts/tests/test-progress-writer.sh +140 -0
- package/scripts/tests/test-promote-mab-lessons.sh +110 -0
- package/scripts/tests/test-pull-community-lessons.sh +149 -0
- package/scripts/tests/test-quality-gate.sh +241 -0
- package/scripts/tests/test-research-gate.sh +132 -0
- package/scripts/tests/test-run-plan-cli.sh +86 -0
- package/scripts/tests/test-run-plan-context.sh +305 -0
- package/scripts/tests/test-run-plan-e2e.sh +153 -0
- package/scripts/tests/test-run-plan-headless.sh +424 -0
- package/scripts/tests/test-run-plan-notify.sh +124 -0
- package/scripts/tests/test-run-plan-parser.sh +217 -0
- package/scripts/tests/test-run-plan-prompt.sh +254 -0
- package/scripts/tests/test-run-plan-quality-gate.sh +222 -0
- package/scripts/tests/test-run-plan-routing.sh +178 -0
- package/scripts/tests/test-run-plan-scoring.sh +148 -0
- package/scripts/tests/test-run-plan-state.sh +261 -0
- package/scripts/tests/test-run-plan-team.sh +157 -0
- package/scripts/tests/test-scope-infer.sh +150 -0
- package/scripts/tests/test-setup-ralph-loop.sh +63 -0
- package/scripts/tests/test-telegram-env.sh +38 -0
- package/scripts/tests/test-telegram.sh +121 -0
- package/scripts/tests/test-telemetry.sh +46 -0
- package/scripts/tests/test-thompson-sampling.sh +139 -0
- package/scripts/tests/test-validate-all.sh +60 -0
- package/scripts/tests/test-validate-commands.sh +89 -0
- package/scripts/tests/test-validate-hooks.sh +98 -0
- package/scripts/tests/test-validate-lessons.sh +150 -0
- package/scripts/tests/test-validate-plan-quality.sh +235 -0
- package/scripts/tests/test-validate-plans.sh +187 -0
- package/scripts/tests/test-validate-plugin.sh +106 -0
- package/scripts/tests/test-validate-prd.sh +184 -0
- package/scripts/tests/test-validate-skills.sh +134 -0
- package/scripts/validate-all.sh +57 -0
- package/scripts/validate-commands.sh +67 -0
- package/scripts/validate-hooks.sh +89 -0
- package/scripts/validate-lessons.sh +98 -0
- package/scripts/validate-plan-quality.sh +369 -0
- package/scripts/validate-plans.sh +120 -0
- package/scripts/validate-plugin.sh +86 -0
- package/scripts/validate-policies.sh +42 -0
- package/scripts/validate-prd.sh +118 -0
- package/scripts/validate-skills.sh +96 -0
- package/skills/autocode/SKILL.md +285 -0
- package/skills/autocode/ab-verification.md +51 -0
- package/skills/autocode/code-quality-standards.md +37 -0
- package/skills/autocode/competitive-mode.md +364 -0
- package/skills/brainstorming/SKILL.md +97 -0
- package/skills/capture-lesson/SKILL.md +187 -0
- package/skills/check-lessons/SKILL.md +116 -0
- package/skills/dispatching-parallel-agents/SKILL.md +110 -0
- package/skills/executing-plans/SKILL.md +85 -0
- package/skills/finishing-a-development-branch/SKILL.md +201 -0
- package/skills/receiving-code-review/SKILL.md +72 -0
- package/skills/requesting-code-review/SKILL.md +59 -0
- package/skills/requesting-code-review/code-reviewer.md +82 -0
- package/skills/research/SKILL.md +145 -0
- package/skills/roadmap/SKILL.md +115 -0
- package/skills/subagent-driven-development/SKILL.md +98 -0
- package/skills/subagent-driven-development/code-quality-reviewer-prompt.md +18 -0
- package/skills/subagent-driven-development/implementer-prompt.md +73 -0
- package/skills/subagent-driven-development/spec-reviewer-prompt.md +57 -0
- package/skills/systematic-debugging/SKILL.md +134 -0
- package/skills/systematic-debugging/condition-based-waiting.md +64 -0
- package/skills/systematic-debugging/defense-in-depth.md +32 -0
- package/skills/systematic-debugging/root-cause-tracing.md +55 -0
- package/skills/test-driven-development/SKILL.md +167 -0
- package/skills/using-git-worktrees/SKILL.md +219 -0
- package/skills/using-superpowers/SKILL.md +54 -0
- package/skills/verification-before-completion/SKILL.md +140 -0
- package/skills/verify/SKILL.md +82 -0
- package/skills/writing-plans/SKILL.md +128 -0
- package/skills/writing-skills/SKILL.md +93 -0
|
@@ -0,0 +1,575 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# mab-run.sh — MAB orchestrator: worktrees, competing agents, judge, merge
|
|
3
|
+
#
|
|
4
|
+
# Usage:
|
|
5
|
+
# mab-run.sh --plan <file> --batch <N> --work-unit <desc> --worktree <dir> [options]
|
|
6
|
+
# mab-run.sh --init-data --worktree <dir>
|
|
7
|
+
# mab-run.sh --help
|
|
8
|
+
#
|
|
9
|
+
# Options:
|
|
10
|
+
# --plan <file> Implementation plan file
|
|
11
|
+
# --batch <N> Batch number to execute
|
|
12
|
+
# --work-unit <desc> Work unit description
|
|
13
|
+
# --worktree <dir> Base worktree directory
|
|
14
|
+
# --dry-run Show planned actions without executing
|
|
15
|
+
# --init-data Initialize strategy-perf.json and mab-lessons.json
|
|
16
|
+
# --prd <file> PRD file path (optional)
|
|
17
|
+
# --quality-gate <cmd> Quality gate command
|
|
18
|
+
# -h, --help Show this help
|
|
19
|
+
set -euo pipefail
|
|
20
|
+
|
|
21
|
+
SCRIPT_DIR="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" && pwd)"
|
|
22
|
+
|
|
23
|
+
# Source dependencies
|
|
24
|
+
source "$SCRIPT_DIR/lib/thompson-sampling.sh"
|
|
25
|
+
if [[ -f "$SCRIPT_DIR/lib/run-plan-scoring.sh" ]]; then
|
|
26
|
+
source "$SCRIPT_DIR/lib/run-plan-scoring.sh"
|
|
27
|
+
fi
|
|
28
|
+
if [[ -f "$SCRIPT_DIR/lib/run-plan-state.sh" ]]; then
|
|
29
|
+
source "$SCRIPT_DIR/lib/run-plan-state.sh"
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
# --- Defaults ---
|
|
33
|
+
MAB_PLAN=""
|
|
34
|
+
MAB_BATCH=""
|
|
35
|
+
MAB_WORK_UNIT=""
|
|
36
|
+
MAB_WORKTREE=""
|
|
37
|
+
MAB_DRY_RUN=false
|
|
38
|
+
MAB_INIT_DATA=false
|
|
39
|
+
MAB_PRD=""
|
|
40
|
+
MAB_QUALITY_GATE="scripts/quality-gate.sh --project-root ."
|
|
41
|
+
MAB_SOURCE_ONLY=false
|
|
42
|
+
|
|
43
|
+
# --- Usage ---
|
|
44
|
+
mab_usage() {
|
|
45
|
+
cat <<'USAGE'
|
|
46
|
+
mab-run.sh — MAB orchestrator for competing agent strategies
|
|
47
|
+
|
|
48
|
+
Usage:
|
|
49
|
+
mab-run.sh --plan <file> --batch <N> --work-unit <desc> --worktree <dir> [options]
|
|
50
|
+
mab-run.sh --init-data --worktree <dir>
|
|
51
|
+
|
|
52
|
+
Runs two agents (superpowers + ralph) in parallel worktrees on the same work
|
|
53
|
+
unit. A judge agent evaluates both outputs. Quality gate override: if only one
|
|
54
|
+
agent passes, that agent wins regardless of judge verdict.
|
|
55
|
+
|
|
56
|
+
Options:
|
|
57
|
+
--plan <file> Implementation plan file
|
|
58
|
+
--batch <N> Batch number to execute
|
|
59
|
+
--work-unit <desc> Work unit description
|
|
60
|
+
--worktree <dir> Base worktree directory
|
|
61
|
+
--dry-run Show planned actions without executing
|
|
62
|
+
--init-data Initialize strategy-perf.json and mab-lessons.json
|
|
63
|
+
--prd <file> PRD file path (optional)
|
|
64
|
+
--quality-gate <cmd> Quality gate command
|
|
65
|
+
-h, --help Show this help
|
|
66
|
+
USAGE
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
# --- Argument parsing ---
|
|
70
|
+
parse_mab_args() {
|
|
71
|
+
while [[ $# -gt 0 ]]; do
|
|
72
|
+
case "$1" in
|
|
73
|
+
--source-only)
|
|
74
|
+
MAB_SOURCE_ONLY=true; shift ;;
|
|
75
|
+
-h|--help)
|
|
76
|
+
mab_usage; exit 0 ;;
|
|
77
|
+
--plan)
|
|
78
|
+
MAB_PLAN="$2"; shift 2 ;;
|
|
79
|
+
--batch)
|
|
80
|
+
MAB_BATCH="$2"; shift 2 ;;
|
|
81
|
+
--work-unit)
|
|
82
|
+
MAB_WORK_UNIT="$2"; shift 2 ;;
|
|
83
|
+
--worktree)
|
|
84
|
+
MAB_WORKTREE="$2"; shift 2 ;;
|
|
85
|
+
--dry-run)
|
|
86
|
+
MAB_DRY_RUN=true; shift ;;
|
|
87
|
+
--init-data)
|
|
88
|
+
MAB_INIT_DATA=true; shift ;;
|
|
89
|
+
--prd)
|
|
90
|
+
MAB_PRD="$2"; shift 2 ;;
|
|
91
|
+
--quality-gate)
|
|
92
|
+
MAB_QUALITY_GATE="$2"; shift 2 ;;
|
|
93
|
+
*)
|
|
94
|
+
echo "ERROR: Unknown option: $1" >&2
|
|
95
|
+
mab_usage >&2
|
|
96
|
+
exit 1 ;;
|
|
97
|
+
esac
|
|
98
|
+
done
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
# --- Validation ---
|
|
102
|
+
validate_mab_args() {
|
|
103
|
+
if [[ "$MAB_INIT_DATA" == true ]]; then
|
|
104
|
+
if [[ -z "$MAB_WORKTREE" ]]; then
|
|
105
|
+
echo "ERROR: --init-data requires --worktree" >&2
|
|
106
|
+
exit 1
|
|
107
|
+
fi
|
|
108
|
+
return
|
|
109
|
+
fi
|
|
110
|
+
|
|
111
|
+
if [[ -z "$MAB_PLAN" || ! -f "$MAB_PLAN" ]]; then
|
|
112
|
+
echo "ERROR: --plan file required and must exist" >&2
|
|
113
|
+
exit 1
|
|
114
|
+
fi
|
|
115
|
+
|
|
116
|
+
if [[ -z "$MAB_BATCH" ]]; then
|
|
117
|
+
echo "ERROR: --batch required" >&2
|
|
118
|
+
exit 1
|
|
119
|
+
fi
|
|
120
|
+
|
|
121
|
+
# Validate batch is numeric
|
|
122
|
+
if ! [[ "$MAB_BATCH" =~ ^[0-9]+$ ]]; then
|
|
123
|
+
echo "ERROR: --batch must be a number (got: $MAB_BATCH)" >&2
|
|
124
|
+
exit 1
|
|
125
|
+
fi
|
|
126
|
+
|
|
127
|
+
if [[ -z "$MAB_WORK_UNIT" ]]; then
|
|
128
|
+
echo "ERROR: --work-unit required" >&2
|
|
129
|
+
exit 1
|
|
130
|
+
fi
|
|
131
|
+
|
|
132
|
+
if [[ -z "$MAB_WORKTREE" ]]; then
|
|
133
|
+
echo "ERROR: --worktree required" >&2
|
|
134
|
+
exit 1
|
|
135
|
+
fi
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
# --- Template substitution ---
|
|
139
|
+
# Replaces {PLACEHOLDER} tokens in a prompt template with actual values.
|
|
140
|
+
#
|
|
141
|
+
# Args: <template> <work_unit> <prd_path> <arch_map_path> <mab_lessons> <quality_gate_cmd>
|
|
142
|
+
# Output: substituted string
|
|
143
|
+
assemble_agent_prompt() {
|
|
144
|
+
local template="$1"
|
|
145
|
+
local work_unit="$2"
|
|
146
|
+
local prd_path="${3:-}"
|
|
147
|
+
local arch_map_path="${4:-}"
|
|
148
|
+
local mab_lessons="${5:-}"
|
|
149
|
+
local quality_gate_cmd="${6:-}"
|
|
150
|
+
|
|
151
|
+
local result="$template"
|
|
152
|
+
result="${result//\{WORK_UNIT_DESCRIPTION\}/$work_unit}"
|
|
153
|
+
result="${result//\{PRD_PATH\}/$prd_path}"
|
|
154
|
+
result="${result//\{ARCH_MAP_PATH\}/$arch_map_path}"
|
|
155
|
+
result="${result//\{MAB_LESSONS\}/$mab_lessons}"
|
|
156
|
+
result="${result//\{QUALITY_GATE_CMD\}/$quality_gate_cmd}"
|
|
157
|
+
|
|
158
|
+
echo "$result"
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
# --- Gate override logic ---
|
|
162
|
+
# If only one agent passes the quality gate, that agent wins regardless of judge.
|
|
163
|
+
#
|
|
164
|
+
# Args: <gate_a_exit> <gate_b_exit> <judge_winner>
|
|
165
|
+
# Output: "agent-a" | "agent-b" | "none" | <judge_winner>
|
|
166
|
+
select_winner_with_gate_override() {
|
|
167
|
+
local gate_a="$1" gate_b="$2" judge_winner="$3"
|
|
168
|
+
|
|
169
|
+
local a_passed=false b_passed=false
|
|
170
|
+
[[ "$gate_a" -eq 0 ]] && a_passed=true
|
|
171
|
+
[[ "$gate_b" -eq 0 ]] && b_passed=true
|
|
172
|
+
|
|
173
|
+
if [[ "$a_passed" == true && "$b_passed" == false ]]; then
|
|
174
|
+
echo "agent-a"
|
|
175
|
+
elif [[ "$a_passed" == false && "$b_passed" == true ]]; then
|
|
176
|
+
echo "agent-b"
|
|
177
|
+
elif [[ "$a_passed" == false && "$b_passed" == false ]]; then
|
|
178
|
+
echo "none"
|
|
179
|
+
else
|
|
180
|
+
# Both passed — use judge verdict
|
|
181
|
+
echo "$judge_winner"
|
|
182
|
+
fi
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
# --- Create MAB worktrees ---
|
|
186
|
+
create_mab_worktrees() {
|
|
187
|
+
local base_worktree="$1" batch="$2"
|
|
188
|
+
local branch_a="mab-agent-a-batch-${batch}"
|
|
189
|
+
local branch_b="mab-agent-b-batch-${batch}"
|
|
190
|
+
local wt_a="$base_worktree/.mab-worktrees/agent-a"
|
|
191
|
+
local wt_b="$base_worktree/.mab-worktrees/agent-b"
|
|
192
|
+
|
|
193
|
+
mkdir -p "$base_worktree/.mab-worktrees"
|
|
194
|
+
|
|
195
|
+
# Clean up any leftover worktrees from previous runs
|
|
196
|
+
git -C "$base_worktree" worktree remove "$wt_a" --force 2>/dev/null || true
|
|
197
|
+
git -C "$base_worktree" worktree remove "$wt_b" --force 2>/dev/null || true
|
|
198
|
+
git -C "$base_worktree" branch -D "$branch_a" 2>/dev/null || true
|
|
199
|
+
git -C "$base_worktree" branch -D "$branch_b" 2>/dev/null || true
|
|
200
|
+
|
|
201
|
+
git -C "$base_worktree" worktree add "$wt_a" -b "$branch_a" HEAD 2>/dev/null
|
|
202
|
+
git -C "$base_worktree" worktree add "$wt_b" -b "$branch_b" HEAD 2>/dev/null
|
|
203
|
+
|
|
204
|
+
echo "$wt_a $wt_b"
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
# --- Run agents in parallel ---
|
|
208
|
+
run_agents_parallel() {
|
|
209
|
+
local wt_a="$1" wt_b="$2" prompt_a="$3" prompt_b="$4"
|
|
210
|
+
local log_a="$MAB_WORKTREE/logs/mab-batch-${MAB_BATCH}-agent-a.log"
|
|
211
|
+
local log_b="$MAB_WORKTREE/logs/mab-batch-${MAB_BATCH}-agent-b.log"
|
|
212
|
+
|
|
213
|
+
mkdir -p "$MAB_WORKTREE/logs"
|
|
214
|
+
|
|
215
|
+
echo " Running Agent A (superpowers) in $wt_a..."
|
|
216
|
+
(cd "$wt_a" && CLAUDECODE='' claude -p "$prompt_a" \
|
|
217
|
+
--allowedTools "Bash,Read,Write,Edit,Grep,Glob" \
|
|
218
|
+
--permission-mode bypassPermissions \
|
|
219
|
+
> "$log_a" 2>&1) &
|
|
220
|
+
local pid_a=$!
|
|
221
|
+
|
|
222
|
+
echo " Running Agent B (ralph) in $wt_b..."
|
|
223
|
+
(cd "$wt_b" && CLAUDECODE='' claude -p "$prompt_b" \
|
|
224
|
+
--allowedTools "Bash,Read,Write,Edit,Grep,Glob" \
|
|
225
|
+
--permission-mode bypassPermissions \
|
|
226
|
+
> "$log_b" 2>&1) &
|
|
227
|
+
local pid_b=$!
|
|
228
|
+
|
|
229
|
+
# Kill children on interrupt, clean up worktrees
|
|
230
|
+
trap 'kill "$pid_a" "$pid_b" 2>/dev/null; wait "$pid_a" "$pid_b" 2>/dev/null; echo "MAB agents interrupted" >&2' INT TERM
|
|
231
|
+
|
|
232
|
+
# Wait for both
|
|
233
|
+
local exit_a=0 exit_b=0
|
|
234
|
+
wait $pid_a || exit_a=$?
|
|
235
|
+
wait $pid_b || exit_b=$?
|
|
236
|
+
|
|
237
|
+
# Clear the interrupt trap
|
|
238
|
+
trap - INT TERM
|
|
239
|
+
|
|
240
|
+
echo " Agent A exited: $exit_a | Agent B exited: $exit_b"
|
|
241
|
+
echo "$exit_a $exit_b"
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
# --- Run quality gate on an agent worktree ---
|
|
245
|
+
run_gate_on_agent() {
|
|
246
|
+
local agent_wt="$1" agent_name="$2"
|
|
247
|
+
local gate_exit=0
|
|
248
|
+
(cd "$agent_wt" && bash -c "$MAB_QUALITY_GATE") > "$MAB_WORKTREE/logs/mab-gate-${agent_name}.log" 2>&1 || gate_exit=$?
|
|
249
|
+
echo " Gate $agent_name: exit=$gate_exit"
|
|
250
|
+
return $gate_exit
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
# --- Invoke judge ---
|
|
254
|
+
invoke_judge() {
|
|
255
|
+
local wt_a="$1" wt_b="$2" gate_a_log="$3" gate_b_log="$4"
|
|
256
|
+
local judge_template
|
|
257
|
+
judge_template=$(cat "$SCRIPT_DIR/prompts/judge-agent.md")
|
|
258
|
+
|
|
259
|
+
local diff_a diff_b gate_a_text gate_b_text
|
|
260
|
+
diff_a=$(cd "$wt_a" && git diff HEAD 2>/dev/null | head -500) || diff_a="(no diff)"
|
|
261
|
+
diff_b=$(cd "$wt_b" && git diff HEAD 2>/dev/null | head -500) || diff_b="(no diff)"
|
|
262
|
+
gate_a_text=$(cat "$gate_a_log" 2>/dev/null | tail -50 || echo "(no gate output)")
|
|
263
|
+
gate_b_text=$(cat "$gate_b_log" 2>/dev/null | tail -50 || echo "(no gate output)")
|
|
264
|
+
|
|
265
|
+
local design_doc=""
|
|
266
|
+
if [[ -n "$MAB_PLAN" && -f "$MAB_PLAN" ]]; then
|
|
267
|
+
design_doc=$(head -100 "$MAB_PLAN")
|
|
268
|
+
fi
|
|
269
|
+
|
|
270
|
+
local judge_prompt="$judge_template"
|
|
271
|
+
judge_prompt="${judge_prompt//\{WORK_UNIT_DESCRIPTION\}/$MAB_WORK_UNIT}"
|
|
272
|
+
judge_prompt="${judge_prompt//\{DIFF_A\}/$diff_a}"
|
|
273
|
+
judge_prompt="${judge_prompt//\{DIFF_B\}/$diff_b}"
|
|
274
|
+
judge_prompt="${judge_prompt//\{GATE_A\}/$gate_a_text}"
|
|
275
|
+
judge_prompt="${judge_prompt//\{GATE_B\}/$gate_b_text}"
|
|
276
|
+
judge_prompt="${judge_prompt//\{DESIGN_DOC\}/$design_doc}"
|
|
277
|
+
|
|
278
|
+
local judge_output
|
|
279
|
+
local judge_exit=0
|
|
280
|
+
judge_output=$(CLAUDECODE='' claude -p "$judge_prompt" \
|
|
281
|
+
--allowedTools "" \
|
|
282
|
+
--permission-mode bypassPermissions \
|
|
283
|
+
2>"$MAB_WORKTREE/logs/mab-judge-stderr.log") || judge_exit=$?
|
|
284
|
+
if [[ $judge_exit -ne 0 ]]; then
|
|
285
|
+
echo "WARNING: judge failed (exit $judge_exit), defaulting to tie" >&2
|
|
286
|
+
fi
|
|
287
|
+
|
|
288
|
+
echo "$judge_output" > "$MAB_WORKTREE/logs/mab-judge-output.log"
|
|
289
|
+
|
|
290
|
+
# Parse winner from judge output
|
|
291
|
+
local winner
|
|
292
|
+
winner=$(echo "$judge_output" | grep -oE 'WINNER:\s*(agent-[ab]|tie)' | sed 's/WINNER:\s*//' | head -1 || echo "tie")
|
|
293
|
+
winner="${winner:-tie}"
|
|
294
|
+
|
|
295
|
+
# Parse lesson
|
|
296
|
+
local lesson
|
|
297
|
+
lesson=$(echo "$judge_output" | grep -oE 'LESSON:\s*.*' | sed 's/LESSON:\s*//' | head -1 || echo "")
|
|
298
|
+
|
|
299
|
+
echo "$winner|$lesson"
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
# --- Human calibration prompt ---
|
|
303
|
+
prompt_human_calibration() {
|
|
304
|
+
local winner="$1" perf_file="$2"
|
|
305
|
+
|
|
306
|
+
local cal_count cal_complete
|
|
307
|
+
cal_count=$(jq -r '.calibration_count // 0' "$perf_file" 2>/dev/null || echo "0")
|
|
308
|
+
cal_complete=$(jq -r '.calibration_complete // false' "$perf_file" 2>/dev/null || echo "false")
|
|
309
|
+
|
|
310
|
+
if [[ "$cal_complete" == "true" ]]; then
|
|
311
|
+
echo "$winner"
|
|
312
|
+
return
|
|
313
|
+
fi
|
|
314
|
+
|
|
315
|
+
# Only prompt if stdin is a tty
|
|
316
|
+
if [[ -t 0 ]]; then
|
|
317
|
+
echo ""
|
|
318
|
+
echo " [CALIBRATION $((cal_count + 1))/10] Judge picked: $winner"
|
|
319
|
+
echo " [y] Accept [a] Override → agent-a [b] Override → agent-b [n] Skip"
|
|
320
|
+
read -r -p " Choice: " choice < /dev/tty
|
|
321
|
+
case "$choice" in
|
|
322
|
+
y|Y) ;; # Accept judge verdict
|
|
323
|
+
a|A) winner="agent-a" ;;
|
|
324
|
+
b|B) winner="agent-b" ;;
|
|
325
|
+
n|N) winner="none" ;;
|
|
326
|
+
esac
|
|
327
|
+
else
|
|
328
|
+
echo " [CALIBRATION] headless-auto-approved: $winner"
|
|
329
|
+
fi
|
|
330
|
+
|
|
331
|
+
# Increment calibration count
|
|
332
|
+
local tmp
|
|
333
|
+
tmp=$(mktemp)
|
|
334
|
+
local new_count=$((cal_count + 1))
|
|
335
|
+
if [[ "$new_count" -ge 10 ]]; then
|
|
336
|
+
jq ".calibration_count = $new_count | .calibration_complete = true" "$perf_file" > "$tmp" && mv "$tmp" "$perf_file"
|
|
337
|
+
else
|
|
338
|
+
jq ".calibration_count = $new_count" "$perf_file" > "$tmp" && mv "$tmp" "$perf_file"
|
|
339
|
+
fi
|
|
340
|
+
|
|
341
|
+
echo "$winner"
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
# --- Merge winner branch ---
|
|
345
|
+
merge_winner() {
|
|
346
|
+
local winner="$1" wt_a="$2" wt_b="$3"
|
|
347
|
+
|
|
348
|
+
local winner_wt
|
|
349
|
+
if [[ "$winner" == "agent-a" ]]; then
|
|
350
|
+
winner_wt="$wt_a"
|
|
351
|
+
elif [[ "$winner" == "agent-b" ]]; then
|
|
352
|
+
winner_wt="$wt_b"
|
|
353
|
+
else
|
|
354
|
+
echo "ERROR: merge_winner called with unexpected winner='$winner'" >&2
|
|
355
|
+
return 1
|
|
356
|
+
fi
|
|
357
|
+
|
|
358
|
+
# Commit winner's changes in their worktree
|
|
359
|
+
(cd "$winner_wt" && git add -u && git commit -m "mab: $winner batch $MAB_BATCH — $MAB_WORK_UNIT" --allow-empty 2>/dev/null) || true
|
|
360
|
+
|
|
361
|
+
# Cherry-pick into base worktree
|
|
362
|
+
local winner_commit
|
|
363
|
+
winner_commit=$(cd "$winner_wt" && git rev-parse HEAD)
|
|
364
|
+
|
|
365
|
+
(cd "$MAB_WORKTREE" && git cherry-pick "$winner_commit" --no-edit 2>/dev/null) || {
|
|
366
|
+
echo "WARNING: Cherry-pick failed, attempting manual merge" >&2
|
|
367
|
+
(cd "$MAB_WORKTREE" && git cherry-pick --abort 2>/dev/null || true)
|
|
368
|
+
# Fallback: copy files from winner worktree
|
|
369
|
+
(cd "$winner_wt" && git diff HEAD~1 --name-only 2>/dev/null | while IFS= read -r f; do
|
|
370
|
+
mkdir -p "$MAB_WORKTREE/$(dirname "$f")"
|
|
371
|
+
cp "$winner_wt/$f" "$MAB_WORKTREE/$f" 2>/dev/null || true
|
|
372
|
+
done)
|
|
373
|
+
(cd "$MAB_WORKTREE" && git add -u && git commit -m "mab: $winner batch $MAB_BATCH (manual merge)" --allow-empty 2>/dev/null) || true
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
# --- Update MAB data files ---
|
|
378
|
+
update_mab_data() {
|
|
379
|
+
local winner="$1" lesson="$2" batch_type="$3"
|
|
380
|
+
local perf_file="$MAB_WORKTREE/logs/strategy-perf.json"
|
|
381
|
+
local lessons_file="$MAB_WORKTREE/logs/mab-lessons.json"
|
|
382
|
+
|
|
383
|
+
# Update strategy performance
|
|
384
|
+
local winner_strategy
|
|
385
|
+
if [[ "$winner" == "agent-a" ]]; then
|
|
386
|
+
winner_strategy="superpowers"
|
|
387
|
+
else
|
|
388
|
+
winner_strategy="ralph"
|
|
389
|
+
fi
|
|
390
|
+
update_strategy_perf "$perf_file" "$batch_type" "$winner_strategy"
|
|
391
|
+
|
|
392
|
+
# Record lesson if present
|
|
393
|
+
if [[ -n "$lesson" ]]; then
|
|
394
|
+
if [[ ! -f "$lessons_file" ]]; then
|
|
395
|
+
echo "[]" > "$lessons_file"
|
|
396
|
+
fi
|
|
397
|
+
|
|
398
|
+
local tmp
|
|
399
|
+
tmp=$(mktemp)
|
|
400
|
+
jq --arg p "$lesson" --arg ctx "$batch_type" --arg w "$winner_strategy" '
|
|
401
|
+
# Check if pattern already exists
|
|
402
|
+
if [.[] | select(.pattern == $p)] | length > 0 then
|
|
403
|
+
[.[] | if .pattern == $p then .occurrences += 1 | .last_seen = (now | tostring) else . end]
|
|
404
|
+
else
|
|
405
|
+
. + [{"pattern": $p, "context": $ctx, "winner": $w, "occurrences": 1, "last_seen": (now | tostring), "promoted": false}]
|
|
406
|
+
end
|
|
407
|
+
' "$lessons_file" > "$tmp" && mv "$tmp" "$lessons_file"
|
|
408
|
+
fi
|
|
409
|
+
|
|
410
|
+
# Log the run
|
|
411
|
+
local run_log="$MAB_WORKTREE/logs/mab-runs.log"
|
|
412
|
+
echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] batch=$MAB_BATCH type=$batch_type winner=$winner lesson=\"$lesson\"" >> "$run_log"
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
# --- Cleanup worktrees ---
|
|
416
|
+
cleanup_mab_worktrees() {
|
|
417
|
+
local base_worktree="$1" batch="$2"
|
|
418
|
+
local branch_a="mab-agent-a-batch-${batch}"
|
|
419
|
+
local branch_b="mab-agent-b-batch-${batch}"
|
|
420
|
+
local wt_a="$base_worktree/.mab-worktrees/agent-a"
|
|
421
|
+
local wt_b="$base_worktree/.mab-worktrees/agent-b"
|
|
422
|
+
|
|
423
|
+
git -C "$base_worktree" worktree remove "$wt_a" --force 2>/dev/null || true
|
|
424
|
+
git -C "$base_worktree" worktree remove "$wt_b" --force 2>/dev/null || true
|
|
425
|
+
git -C "$base_worktree" branch -D "$branch_a" 2>/dev/null || true
|
|
426
|
+
git -C "$base_worktree" branch -D "$branch_b" 2>/dev/null || true
|
|
427
|
+
rm -rf "$base_worktree/.mab-worktrees" 2>/dev/null || true
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
# --- Main orchestration ---
|
|
431
|
+
run_mab() {
|
|
432
|
+
local perf_file="$MAB_WORKTREE/logs/strategy-perf.json"
|
|
433
|
+
[[ ! -f "$perf_file" ]] && init_strategy_perf "$perf_file"
|
|
434
|
+
|
|
435
|
+
local lessons_file="$MAB_WORKTREE/logs/mab-lessons.json"
|
|
436
|
+
[[ ! -f "$lessons_file" ]] && echo "[]" > "$lessons_file"
|
|
437
|
+
|
|
438
|
+
echo ""
|
|
439
|
+
echo "╔══════════════════════════════════════════════════════╗"
|
|
440
|
+
echo "║ MAB Run — Batch $MAB_BATCH"
|
|
441
|
+
echo "║ Work: $MAB_WORK_UNIT"
|
|
442
|
+
echo "╚══════════════════════════════════════════════════════╝"
|
|
443
|
+
|
|
444
|
+
if [[ "$MAB_DRY_RUN" == true ]]; then
|
|
445
|
+
echo ""
|
|
446
|
+
echo "=== DRY RUN ==="
|
|
447
|
+
echo " Plan: $MAB_PLAN"
|
|
448
|
+
echo " Batch: $MAB_BATCH"
|
|
449
|
+
echo " Work unit: $MAB_WORK_UNIT"
|
|
450
|
+
echo " Worktree: $MAB_WORKTREE"
|
|
451
|
+
echo " Quality gate: $MAB_QUALITY_GATE"
|
|
452
|
+
echo ""
|
|
453
|
+
echo " Would create worktrees:"
|
|
454
|
+
echo " agent-a: $MAB_WORKTREE/.mab-worktrees/agent-a"
|
|
455
|
+
echo " agent-b: $MAB_WORKTREE/.mab-worktrees/agent-b"
|
|
456
|
+
echo ""
|
|
457
|
+
echo " Would run agents in parallel, invoke judge, merge winner."
|
|
458
|
+
echo "=== END DRY RUN ==="
|
|
459
|
+
return 0
|
|
460
|
+
fi
|
|
461
|
+
|
|
462
|
+
# Load MAB lessons for injection
|
|
463
|
+
local mab_lessons_text=""
|
|
464
|
+
if [[ -f "$lessons_file" ]]; then
|
|
465
|
+
mab_lessons_text=$(jq -r '
|
|
466
|
+
sort_by(-.occurrences // 0) | .[0:5] | .[] |
|
|
467
|
+
"- \(.pattern) (\(.context // "general")): winner=\(.winner // "unknown")"
|
|
468
|
+
' "$lessons_file" 2>/dev/null || echo "No lessons yet.")
|
|
469
|
+
fi
|
|
470
|
+
[[ -z "$mab_lessons_text" ]] && mab_lessons_text="No lessons yet."
|
|
471
|
+
|
|
472
|
+
# Resolve paths
|
|
473
|
+
local prd_path="${MAB_PRD:-tasks/prd.json}"
|
|
474
|
+
local arch_map_path="docs/ARCHITECTURE-MAP.json"
|
|
475
|
+
|
|
476
|
+
# Assemble prompts
|
|
477
|
+
local prompt_a_template prompt_b_template
|
|
478
|
+
prompt_a_template=$(cat "$SCRIPT_DIR/prompts/agent-a-superpowers.md")
|
|
479
|
+
prompt_b_template=$(cat "$SCRIPT_DIR/prompts/agent-b-ralph.md")
|
|
480
|
+
|
|
481
|
+
local prompt_a prompt_b
|
|
482
|
+
prompt_a=$(assemble_agent_prompt "$prompt_a_template" "$MAB_WORK_UNIT" "$prd_path" "$arch_map_path" "$mab_lessons_text" "$MAB_QUALITY_GATE")
|
|
483
|
+
prompt_b=$(assemble_agent_prompt "$prompt_b_template" "$MAB_WORK_UNIT" "$prd_path" "$arch_map_path" "$mab_lessons_text" "$MAB_QUALITY_GATE")
|
|
484
|
+
|
|
485
|
+
# Create worktrees
|
|
486
|
+
echo ""
|
|
487
|
+
echo "--- Creating worktrees ---"
|
|
488
|
+
local worktrees
|
|
489
|
+
worktrees=$(create_mab_worktrees "$MAB_WORKTREE" "$MAB_BATCH")
|
|
490
|
+
local wt_a wt_b
|
|
491
|
+
wt_a=$(echo "$worktrees" | awk '{print $1}')
|
|
492
|
+
wt_b=$(echo "$worktrees" | awk '{print $2}')
|
|
493
|
+
echo " Agent A: $wt_a"
|
|
494
|
+
echo " Agent B: $wt_b"
|
|
495
|
+
|
|
496
|
+
# Run agents in parallel
|
|
497
|
+
echo ""
|
|
498
|
+
echo "--- Running agents ---"
|
|
499
|
+
run_agents_parallel "$wt_a" "$wt_b" "$prompt_a" "$prompt_b" || true
|
|
500
|
+
|
|
501
|
+
# Run quality gates
|
|
502
|
+
echo ""
|
|
503
|
+
echo "--- Quality gates ---"
|
|
504
|
+
# Capture gate exit codes without disabling set -e inside functions (SC2310)
|
|
505
|
+
local gate_a gate_b
|
|
506
|
+
set +e; run_gate_on_agent "$wt_a" "agent-a"; gate_a=$?; set -e
|
|
507
|
+
set +e; run_gate_on_agent "$wt_b" "agent-b"; gate_b=$?; set -e
|
|
508
|
+
|
|
509
|
+
# Invoke judge (only if both agents ran)
|
|
510
|
+
echo ""
|
|
511
|
+
echo "--- Judge evaluation ---"
|
|
512
|
+
local judge_result judge_winner judge_lesson
|
|
513
|
+
judge_result=$(invoke_judge "$wt_a" "$wt_b" \
|
|
514
|
+
"$MAB_WORKTREE/logs/mab-gate-agent-a.log" \
|
|
515
|
+
"$MAB_WORKTREE/logs/mab-gate-agent-b.log")
|
|
516
|
+
judge_winner=$(echo "$judge_result" | cut -d'|' -f1)
|
|
517
|
+
judge_lesson=$(echo "$judge_result" | cut -d'|' -f2-)
|
|
518
|
+
echo " Judge verdict: $judge_winner"
|
|
519
|
+
|
|
520
|
+
# Apply gate override
|
|
521
|
+
local final_winner
|
|
522
|
+
final_winner=$(select_winner_with_gate_override "$gate_a" "$gate_b" "$judge_winner")
|
|
523
|
+
echo " Final winner: $final_winner (gate override applied)"
|
|
524
|
+
|
|
525
|
+
# Human calibration
|
|
526
|
+
final_winner=$(prompt_human_calibration "$final_winner" "$perf_file")
|
|
527
|
+
|
|
528
|
+
if [[ "$final_winner" == "none" || "$final_winner" == "tie" ]]; then
|
|
529
|
+
echo " No winner — both agents failed or tie with no override."
|
|
530
|
+
cleanup_mab_worktrees "$MAB_WORKTREE" "$MAB_BATCH"
|
|
531
|
+
return 1
|
|
532
|
+
fi
|
|
533
|
+
|
|
534
|
+
# Merge winner
|
|
535
|
+
echo ""
|
|
536
|
+
echo "--- Merging winner ($final_winner) ---"
|
|
537
|
+
merge_winner "$final_winner" "$wt_a" "$wt_b"
|
|
538
|
+
|
|
539
|
+
# Classify batch type for data recording
|
|
540
|
+
local batch_type="unknown"
|
|
541
|
+
if type classify_batch_type &>/dev/null && [[ -n "$MAB_PLAN" ]]; then
|
|
542
|
+
batch_type=$(classify_batch_type "$MAB_PLAN" "$MAB_BATCH" 2>/dev/null || echo "unknown")
|
|
543
|
+
fi
|
|
544
|
+
|
|
545
|
+
# Update data
|
|
546
|
+
update_mab_data "$final_winner" "$judge_lesson" "$batch_type"
|
|
547
|
+
|
|
548
|
+
# Cleanup
|
|
549
|
+
echo ""
|
|
550
|
+
echo "--- Cleanup ---"
|
|
551
|
+
cleanup_mab_worktrees "$MAB_WORKTREE" "$MAB_BATCH"
|
|
552
|
+
|
|
553
|
+
echo ""
|
|
554
|
+
echo "MAB batch $MAB_BATCH complete. Winner: $final_winner"
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
# --- Entry point ---
|
|
558
|
+
parse_mab_args "$@"
|
|
559
|
+
|
|
560
|
+
# --source-only: export functions for testing, don't execute
|
|
561
|
+
if [[ "$MAB_SOURCE_ONLY" == true ]]; then
|
|
562
|
+
return 0 2>/dev/null || exit 0
|
|
563
|
+
fi
|
|
564
|
+
|
|
565
|
+
validate_mab_args
|
|
566
|
+
|
|
567
|
+
if [[ "$MAB_INIT_DATA" == true ]]; then
|
|
568
|
+
mkdir -p "$MAB_WORKTREE/logs"
|
|
569
|
+
init_strategy_perf "$MAB_WORKTREE/logs/strategy-perf.json"
|
|
570
|
+
echo "[]" > "$MAB_WORKTREE/logs/mab-lessons.json"
|
|
571
|
+
echo "Initialized MAB data files in $MAB_WORKTREE/logs/"
|
|
572
|
+
exit 0
|
|
573
|
+
fi
|
|
574
|
+
|
|
575
|
+
run_mab
|