openlanes 3.0.1 → 3.1.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.
- checksums.yaml +4 -4
- data/Brewfile +42 -0
- data/agents/bb8-resolver.md +49 -0
- data/agents/c3po-operator.md +4 -0
- data/agents/chewie-verifier.md +85 -0
- data/agents/hansolo-reviewer.md +20 -15
- data/agents/lando-broker.md +81 -19
- data/agents/leah-researcher.md +6 -6
- data/agents/luke-backend.md +41 -20
- data/agents/{palpatine-planner.md → luthen-rael-planner.md} +15 -13
- data/agents/palpatine-risk-assessor.md +112 -0
- data/agents/r2d2-mechanic.md +5 -1
- data/agents/rey-frontend.md +38 -19
- data/agents/yoda-writer.md +7 -7
- data/evals/cases/chewie-verifier/verify-medium/fail/plan/plan.md +7 -0
- data/evals/cases/chewie-verifier/verify-medium/fail/plan/pull-requests.md +10 -0
- data/evals/cases/chewie-verifier/verify-medium/fail/plan/spec.md +5 -0
- data/evals/cases/chewie-verifier/verify-medium/fail/plan/verification/1/final.png +0 -0
- data/evals/cases/chewie-verifier/verify-medium/fail/plan/verification/1/report.md +7 -0
- data/evals/cases/chewie-verifier/verify-medium/fail/repo/bin/greet +1 -0
- data/evals/cases/chewie-verifier/verify-medium/fail/run.json +1 -0
- data/evals/cases/chewie-verifier/verify-medium/pass/plan/plan.md +7 -0
- data/evals/cases/chewie-verifier/verify-medium/pass/plan/pull-requests.md +10 -0
- data/evals/cases/chewie-verifier/verify-medium/pass/plan/spec.md +5 -0
- data/evals/cases/chewie-verifier/verify-medium/pass/plan/verification/1/final.png +0 -0
- data/evals/cases/chewie-verifier/verify-medium/pass/plan/verification/1/report.md +14 -0
- data/evals/cases/chewie-verifier/verify-medium/pass/plan/verification/1/step-01.png +0 -0
- data/evals/cases/chewie-verifier/verify-medium/pass/repo/bin/greet +1 -0
- data/evals/cases/chewie-verifier/verify-medium/pass/run.json +1 -0
- data/evals/cases/chewie-verifier/verify-medium.yml +48 -0
- data/evals/cases/hansolo-reviewer/coverage-minimum/fail/plan/implementation-plan.md +5 -0
- data/evals/cases/hansolo-reviewer/coverage-minimum/fail/plan/plan.md +3 -0
- data/evals/cases/hansolo-reviewer/coverage-minimum/fail/plan/pull-requests.md +12 -0
- data/evals/cases/hansolo-reviewer/coverage-minimum/fail/plan/spec.md +5 -0
- data/evals/cases/hansolo-reviewer/coverage-minimum/fail/repo/lib/cart.rb +10 -0
- data/evals/cases/hansolo-reviewer/coverage-minimum/fail/repo/spec/cart_spec.rb +9 -0
- data/evals/cases/hansolo-reviewer/coverage-minimum/fail/run.json +1 -0
- data/evals/cases/hansolo-reviewer/coverage-minimum/pass/plan/implementation-plan.md +5 -0
- data/evals/cases/hansolo-reviewer/coverage-minimum/pass/plan/plan.md +3 -0
- data/evals/cases/hansolo-reviewer/coverage-minimum/pass/plan/pull-requests.md +15 -0
- data/evals/cases/hansolo-reviewer/coverage-minimum/pass/plan/spec.md +5 -0
- data/evals/cases/hansolo-reviewer/coverage-minimum/pass/repo/lib/cart.rb +10 -0
- data/evals/cases/hansolo-reviewer/coverage-minimum/pass/repo/spec/cart_spec.rb +9 -0
- data/evals/cases/hansolo-reviewer/coverage-minimum/pass/run.json +1 -0
- data/evals/cases/hansolo-reviewer/coverage-minimum.yml +76 -0
- data/evals/cases/luthen-rael-planner/plan-deep/fail/plan/plan.md +8 -0
- data/evals/cases/{palpatine-planner → luthen-rael-planner}/plan-deep/pass/plan/plan.md +2 -2
- data/evals/cases/{palpatine-planner → luthen-rael-planner}/plan-deep.yml +1 -1
- data/evals/cases/luthen-rael-planner/plan-fast/fail/plan/plan.md +12 -0
- data/evals/cases/{palpatine-planner → luthen-rael-planner}/plan-fast/pass/plan/plan.md +2 -2
- data/evals/cases/{palpatine-planner → luthen-rael-planner}/plan-fast.yml +1 -1
- data/evals/cases/palpatine-risk-assessor/risk-medium/fail/plan/plan.md +20 -0
- data/evals/cases/palpatine-risk-assessor/risk-medium/fail/plan/pull-requests.md +5 -0
- data/evals/cases/palpatine-risk-assessor/risk-medium/fail/plan/spec.md +5 -0
- data/evals/cases/palpatine-risk-assessor/risk-medium/fail/repo/db/migrate/20261020120000_drop_legacy_email.rb +5 -0
- data/evals/cases/palpatine-risk-assessor/risk-medium/fail/run.json +1 -0
- data/evals/cases/palpatine-risk-assessor/risk-medium/pass/plan/plan.md +25 -0
- data/evals/cases/palpatine-risk-assessor/risk-medium/pass/plan/pull-requests.md +5 -0
- data/evals/cases/palpatine-risk-assessor/risk-medium/pass/plan/spec.md +5 -0
- data/evals/cases/palpatine-risk-assessor/risk-medium/pass/repo/db/migrate/20261020120000_drop_legacy_email.rb +5 -0
- data/evals/cases/palpatine-risk-assessor/risk-medium/pass/run.json +1 -0
- data/evals/cases/palpatine-risk-assessor/risk-medium.yml +47 -0
- data/evals/cases/yoda-writer/spec-medium/pass/plan/spec.md +1 -1
- data/lib/openlanes/adapters/base.rb +18 -4
- data/lib/openlanes/adapters/capabilities.rb +29 -0
- data/lib/openlanes/adapters/claude.rb +14 -11
- data/lib/openlanes/adapters/codex.rb +9 -0
- data/lib/openlanes/adapters/pi.rb +10 -0
- data/lib/openlanes/adapters/stream.rb +145 -1
- data/lib/openlanes/adapters.rb +7 -0
- data/lib/openlanes/agents/agent.rb +4 -3
- data/lib/openlanes/agents/roster.rb +14 -2
- data/lib/openlanes/agents/routing.rb +43 -3
- data/lib/openlanes/apps/definition.rb +152 -0
- data/lib/openlanes/apps/framing.rb +114 -0
- data/lib/openlanes/apps/listing.rb +60 -0
- data/lib/openlanes/apps/ports.rb +168 -0
- data/lib/openlanes/apps/probe.rb +63 -0
- data/lib/openlanes/apps/process_spec.rb +39 -0
- data/lib/openlanes/apps/runner.rb +174 -0
- data/lib/openlanes/apps/status.rb +62 -0
- data/lib/openlanes/apps/supervisor.rb +277 -0
- data/lib/openlanes/apps/watcher.rb +50 -0
- data/lib/openlanes/apps.rb +41 -0
- data/lib/openlanes/cli/api/api.rb +10 -0
- data/lib/openlanes/cli/api/subcommands/docs.rb +63 -0
- data/lib/openlanes/cli/app/app.rb +31 -0
- data/lib/openlanes/cli/app/subcommands/start.rb +114 -0
- data/lib/openlanes/cli/app/subcommands/status.rb +38 -0
- data/lib/openlanes/cli/app/subcommands/stop.rb +44 -0
- data/lib/openlanes/cli/base.rb +89 -16
- data/lib/openlanes/cli/coverage/coverage.rb +68 -0
- data/lib/openlanes/cli/create/create.rb +11 -265
- data/lib/openlanes/cli/eval/eval.rb +4 -1
- data/lib/openlanes/cli/init/init.rb +39 -2
- data/lib/openlanes/cli/linear/subcommands/import.rb +1 -1
- data/lib/openlanes/cli/linear/subcommands/projects.rb +1 -1
- data/lib/openlanes/cli/list_plans/list_plans.rb +8 -2
- data/lib/openlanes/cli/mail/subcommands/ack.rb +52 -0
- data/lib/openlanes/cli/mail/subcommands/render.rb +31 -0
- data/lib/openlanes/cli/mail/subcommands/send.rb +26 -0
- data/lib/openlanes/cli/resync/subcommands/dirs.rb +53 -12
- data/lib/openlanes/cli/resync/subcommands/prs.rb +8 -69
- data/lib/openlanes/cli/review/review.rb +72 -0
- data/lib/openlanes/cli/run/run.rb +22 -486
- data/lib/openlanes/cli/setup/setup.rb +51 -0
- data/lib/openlanes/cli/start/start.rb +7 -51
- data/lib/openlanes/cli/state/state.rb +1 -1
- data/lib/openlanes/cli/state/subcommands/resume.rb +61 -0
- data/lib/openlanes/cli/state/subcommands/sign.rb +1 -1
- data/lib/openlanes/cli/unblock/unblock.rb +11 -205
- data/lib/openlanes/cli/web/web.rb +84 -8
- data/lib/openlanes/cli/worktree/worktree.rb +1 -1
- data/lib/openlanes/cli/worktree/worktree_prune.rb +77 -0
- data/lib/openlanes/cli.rb +37 -2
- data/lib/openlanes/coverage/cobertura.rb +49 -0
- data/lib/openlanes/coverage/config.rb +194 -0
- data/lib/openlanes/coverage/istanbul.rb +31 -0
- data/lib/openlanes/coverage/lcov.rb +38 -0
- data/lib/openlanes/coverage/report.rb +71 -0
- data/lib/openlanes/coverage/simplecov.rb +70 -0
- data/lib/openlanes/coverage.rb +33 -0
- data/lib/openlanes/engine/agent_locks.rb +231 -0
- data/lib/openlanes/engine/arbitration.rb +25 -0
- data/lib/openlanes/engine/board.rb +36 -5
- data/lib/openlanes/engine/conversions.rb +160 -0
- data/lib/openlanes/engine/coverage_gate.rb +217 -0
- data/lib/openlanes/engine/dispatcher.rb +1175 -117
- data/lib/openlanes/engine/event_journal/replay.rb +96 -0
- data/lib/openlanes/engine/event_journal.rb +148 -0
- data/lib/openlanes/engine/extensions.rb +271 -0
- data/lib/openlanes/engine/merging.rb +459 -0
- data/lib/openlanes/engine/narrator.rb +6 -6
- data/lib/openlanes/engine/plan_locks.rb +114 -0
- data/lib/openlanes/engine/pr_outcomes.rb +161 -0
- data/lib/openlanes/engine/pr_watch.rb +83 -0
- data/lib/openlanes/engine/progress_log.rb +12 -120
- data/lib/openlanes/engine/quality_question.rb +125 -0
- data/lib/openlanes/engine/rebase.rb +200 -0
- data/lib/openlanes/engine/run_workflow.rb +776 -0
- data/lib/openlanes/engine/runner.rb +186 -15
- data/lib/openlanes/engine/start_workflow.rb +77 -0
- data/lib/openlanes/engine/state_file.rb +101 -34
- data/lib/openlanes/engine/tally.rb +1 -1
- data/lib/openlanes/engine/verification/app_session.rb +104 -0
- data/lib/openlanes/engine/verification/driver.rb +314 -0
- data/lib/openlanes/engine/verification/outcome.rb +516 -0
- data/lib/openlanes/engine/verification/report.rb +95 -0
- data/lib/openlanes/engine/verification/round.rb +100 -0
- data/lib/openlanes/engine/verification/screenshots.rb +120 -0
- data/lib/openlanes/engine/verification.rb +57 -0
- data/lib/openlanes/engine.rb +30 -1
- data/lib/openlanes/execution/boundary.rb +212 -0
- data/lib/openlanes/execution/child.rb +4 -2
- data/lib/openlanes/execution/clock.rb +36 -6
- data/lib/openlanes/execution/control.rb +32 -0
- data/lib/openlanes/execution/executor.rb +114 -35
- data/lib/openlanes/execution/process_start.rb +63 -0
- data/lib/openlanes/execution/prompt.rb +223 -34
- data/lib/openlanes/execution/transcript.rb +159 -8
- data/lib/openlanes/execution.rb +21 -0
- data/lib/openlanes/lifecycle/adoption.rb +25 -8
- data/lib/openlanes/lifecycle/aging.rb +166 -0
- data/lib/openlanes/lifecycle/allocator.rb +216 -0
- data/lib/openlanes/lifecycle/brief.rb +32 -2
- data/lib/openlanes/lifecycle/completion.rb +12 -6
- data/lib/openlanes/lifecycle/create_workflow.rb +272 -0
- data/lib/openlanes/lifecycle/creator.rb +17 -13
- data/lib/openlanes/lifecycle/lanes.rb +1 -1
- data/lib/openlanes/lifecycle/resync.rb +170 -42
- data/lib/openlanes/lifecycle/unblock_workflow.rb +234 -0
- data/lib/openlanes/lifecycle/unblocker.rb +76 -2
- data/lib/openlanes/lifecycle.rb +37 -1
- data/lib/openlanes/linear/mapping.rb +4 -1
- data/lib/openlanes/linear/unit.rb +1 -1
- data/lib/openlanes/live/chat.rb +60 -11
- data/lib/openlanes/live/choice_converter.rb +166 -0
- data/lib/openlanes/live/choice_judge.rb +109 -0
- data/lib/openlanes/live/claims.rb +9 -1
- data/lib/openlanes/live/command.rb +13 -10
- data/lib/openlanes/live/commands.rb +217 -30
- data/lib/openlanes/live/copilot/slash.rb +82 -0
- data/lib/openlanes/live/copilot.rb +38 -4
- data/lib/openlanes/live/event_bus/base.rb +52 -0
- data/lib/openlanes/live/event_bus/memory_bus.rb +14 -0
- data/lib/openlanes/live/event_bus/redis_bus.rb +10 -0
- data/lib/openlanes/live/event_bus/transaction.rb +27 -0
- data/lib/openlanes/live/event_bus.rb +29 -0
- data/lib/openlanes/live/interviewer.rb +146 -0
- data/lib/openlanes/live/keys.rb +56 -0
- data/lib/openlanes/live/mail.rb +143 -0
- data/lib/openlanes/live/memory_store.rb +12 -1
- data/lib/openlanes/live/news.rb +61 -0
- data/lib/openlanes/live/node.rb +20 -0
- data/lib/openlanes/live/outage.rb +225 -0
- data/lib/openlanes/live/outage_report.rb +89 -0
- data/lib/openlanes/live/publisher.rb +42 -2
- data/lib/openlanes/live/run_record.rb +39 -1
- data/lib/openlanes/live/run_state.rb +19 -2
- data/lib/openlanes/live/session.rb +31 -3
- data/lib/openlanes/live/snapshot.rb +103 -42
- data/lib/openlanes/live/stations.rb +4 -4
- data/lib/openlanes/live/store.rb +18 -1
- data/lib/openlanes/live/subscriber.rb +22 -2
- data/lib/openlanes/live.rb +66 -1
- data/lib/openlanes/plans/blocked_file.rb +117 -0
- data/lib/openlanes/plans/choices.rb +228 -0
- data/lib/openlanes/plans/dependencies.rb +304 -0
- data/lib/openlanes/plans/feature.rb +75 -16
- data/lib/openlanes/plans/journal.rb +169 -0
- data/lib/openlanes/plans/last_known_state.rb +82 -0
- data/lib/openlanes/plans/lock.rb +171 -0
- data/lib/openlanes/plans/mailbox.rb +145 -4
- data/lib/openlanes/plans/plan_state.rb +590 -9
- data/lib/openlanes/plans/pull_request_machine.rb +163 -0
- data/lib/openlanes/plans/review_label.rb +139 -0
- data/lib/openlanes/plans/spec.rb +239 -3
- data/lib/openlanes/plans/state_machine.rb +63 -30
- data/lib/openlanes/plans/status.rb +60 -11
- data/lib/openlanes/plans/subject.rb +4 -0
- data/lib/openlanes/plans/tree.rb +101 -10
- data/lib/openlanes/plans/verdict.rb +124 -0
- data/lib/openlanes/plans.rb +19 -0
- data/lib/openlanes/presentation/api_docs.rb +76 -0
- data/lib/openlanes/presentation/documentation.rb +105 -12
- data/lib/openlanes/presentation/pr_changes.rb +90 -0
- data/lib/openlanes/presentation/reporter.rb +64 -5
- data/lib/openlanes/presentation.rb +20 -1
- data/lib/openlanes/setup/check.rb +16 -0
- data/lib/openlanes/setup/machine.rb +179 -0
- data/lib/openlanes/setup.rb +34 -0
- data/lib/openlanes/support/clock.rb +57 -0
- data/lib/openlanes/support/config.rb +318 -6
- data/lib/openlanes/support/log.rb +206 -0
- data/lib/openlanes/support/refusal.rb +15 -0
- data/lib/openlanes/support/runtime.rb +61 -0
- data/lib/openlanes/support/spawner.rb +51 -0
- data/lib/openlanes/support/ui.rb +39 -24
- data/lib/openlanes/vcs/ci_gate.rb +31 -0
- data/lib/openlanes/vcs/github.rb +362 -12
- data/lib/openlanes/vcs/label_migration.rb +132 -0
- data/lib/openlanes/vcs/label_sync.rb +75 -0
- data/lib/openlanes/vcs/publisher.rb +226 -8
- data/lib/openlanes/vcs/refresh.rb +337 -0
- data/lib/openlanes/vcs/rename_date.rb +83 -0
- data/lib/openlanes/vcs/review.rb +66 -0
- data/lib/openlanes/vcs/worktree.rb +167 -6
- data/lib/openlanes/vcs.rb +18 -0
- data/lib/openlanes/version.rb +1 -1
- data/lib/openlanes/web/admin_auth.rb +104 -0
- data/lib/openlanes/web/app.rb +115 -16
- data/lib/openlanes/web/context.rb +15 -9
- data/lib/openlanes/web/demo.rb +29 -14
- data/lib/openlanes/web/demo_board.rb +63 -5
- data/lib/openlanes/web/events.rb +86 -7
- data/lib/openlanes/web/launcher.rb +69 -7
- data/lib/openlanes/web/listen.rb +133 -0
- data/lib/openlanes/web/plan_files.rb +136 -0
- data/lib/openlanes/web/request_log.rb +108 -0
- data/lib/openlanes/web/server.rb +29 -10
- data/lib/openlanes/web.rb +6 -4
- data/lib/openlanes.rb +45 -7
- data/openlanes.gemspec +9 -4
- data/schemas/journal-event.schema.json +72 -0
- data/schemas/plan-state.schema.json +163 -2
- data/skills/openlanes/SKILL.md +2 -2
- data/skills/openlanes-documents/SKILL.md +4 -4
- data/skills/openlanes-documents/references/blocked-template.md +2 -2
- data/skills/openlanes-documents/references/closing-templates.md +1 -1
- data/skills/openlanes-documents/references/plan-template.md +12 -4
- data/skills/openlanes-documents/references/retroactive-spec.md +1 -1
- data/skills/openlanes-run/SKILL.md +5 -5
- data/skills/openlanes-spec/SKILL.md +1 -1
- data/skills/openlanes-status/SKILL.md +1 -1
- data/web/dist/assets/{index-BFPI-zXI.js → index-690ayLS4.js} +2 -2
- data/web/dist/assets/index-6ZmW4slI.js +199 -0
- data/web/dist/assets/{index-bpsFIpXE.js → index-B5KzlXp1.js} +2 -2
- data/web/dist/assets/{index-DtA46i32.js → index-BAo_v9bU.js} +2 -2
- data/web/dist/assets/{index-CnJfB0l2.js → index-BDm7g-xG.js} +2 -2
- data/web/dist/assets/{index-DXgeajd6.js → index-BFH9bC7v.js} +2 -2
- data/web/dist/assets/{index-DH0gDlee.js → index-BVHPV7z4.js} +2 -2
- data/web/dist/assets/{index-DaSjQ-H4.js → index-B_CPqjnA.js} +2 -2
- data/web/dist/assets/{index-Dbxvk-EC.js → index-BhwBH5ct.js} +2 -2
- data/web/dist/assets/{index-6MZkmh3k.js → index-Bq5AdwEt.js} +2 -2
- data/web/dist/assets/{index-B5CKJPm-.js → index-CAW6ClM2.js} +2 -2
- data/web/dist/assets/index-Cp86u27u.css +1 -0
- data/web/dist/assets/{index-CnvkZu5Y.js → index-Culm4pMO.js} +2 -2
- data/web/dist/assets/{index-IqD8mBos.js → index-DElDJfp1.js} +2 -2
- data/web/dist/assets/{index-C3zc4gFe.js → index-Dja7osNW.js} +2 -2
- data/web/dist/assets/{index-C2jwoWVV.js → index-DjhU3FzU.js} +2 -2
- data/web/dist/assets/{index-pvJi-JJO.js → index-Dutbxj4o.js} +2 -2
- data/web/dist/assets/{index-BF6QYroq.js → index-RkDhPMDt.js} +2 -2
- data/web/dist/assets/{index-DbueqOK5.js → index-_mptZjlC.js} +2 -2
- data/web/dist/index.html +2 -2
- data/web/src/api/fixtures/board.json +203 -28
- metadata +1053 -889
- data/bin/factory-e2e +0 -157
- data/bin/plan-number +0 -164
- data/bin/setup +0 -26
- data/evals/cases/palpatine-planner/plan-deep/fail/plan/plan.md +0 -8
- data/evals/cases/palpatine-planner/plan-fast/fail/plan/plan.md +0 -12
- data/web/dist/assets/index-BYJCWlk0.js +0 -198
- data/web/dist/assets/index-CjInBi5X.css +0 -1
- /data/evals/cases/{palpatine-planner → luthen-rael-planner}/plan-deep/fail/plan/plan-backend.md +0 -0
- /data/evals/cases/{palpatine-planner → luthen-rael-planner}/plan-deep/fail/plan/spec.md +0 -0
- /data/evals/cases/{palpatine-planner → luthen-rael-planner}/plan-deep/fail/run.json +0 -0
- /data/evals/cases/{palpatine-planner → luthen-rael-planner}/plan-deep/pass/plan/plan-backend.md +0 -0
- /data/evals/cases/{palpatine-planner → luthen-rael-planner}/plan-deep/pass/plan/plan-frontend.md +0 -0
- /data/evals/cases/{palpatine-planner → luthen-rael-planner}/plan-deep/pass/plan/spec.md +0 -0
- /data/evals/cases/{palpatine-planner → luthen-rael-planner}/plan-deep/pass/run.json +0 -0
- /data/evals/cases/{palpatine-planner → luthen-rael-planner}/plan-fast/fail/plan/plan-backend.md +0 -0
- /data/evals/cases/{palpatine-planner → luthen-rael-planner}/plan-fast/fail/plan/plan-frontend.md +0 -0
- /data/evals/cases/{palpatine-planner → luthen-rael-planner}/plan-fast/fail/plan/spec.md +0 -0
- /data/evals/cases/{palpatine-planner → luthen-rael-planner}/plan-fast/fail/run.json +0 -0
- /data/evals/cases/{palpatine-planner → luthen-rael-planner}/plan-fast/pass/plan/plan-backend.md +0 -0
- /data/evals/cases/{palpatine-planner → luthen-rael-planner}/plan-fast/pass/plan/plan-frontend.md +0 -0
- /data/evals/cases/{palpatine-planner → luthen-rael-planner}/plan-fast/pass/plan/spec.md +0 -0
- /data/evals/cases/{palpatine-planner → luthen-rael-planner}/plan-fast/pass/run.json +0 -0
- /data/exe/{depot → ol} +0 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: palpatine-risk-assessor
|
|
3
|
+
description: Weighs each ready-to-merge pull request of a completed plan and rules auto (the engine may merge it unattended) or manual (a person merges it).
|
|
4
|
+
handles: [completed]
|
|
5
|
+
advances_to: approved
|
|
6
|
+
model: opus
|
|
7
|
+
effort: high
|
|
8
|
+
timeout: 600
|
|
9
|
+
ledger: [plan.md]
|
|
10
|
+
phase: completion
|
|
11
|
+
lanes: [full, plan, quick]
|
|
12
|
+
allowed_tools: [Read, Grep, Glob, Bash, Edit, Write, Skill]
|
|
13
|
+
writes: [plan.md]
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
The plan is 🏁 Completed: every one of its open pull requests is labelled `ready-to-merge`. For each of them you decide whether it can merge and deploy with nobody watching. CI is green, end-to-end tests passed, and reviewers signed off. Your job is not to find bugs. Your job is to answer two questions: if this change is wrong, how bad is it and how fast can we undo it? And how much should we trust the evidence that it is right?
|
|
17
|
+
|
|
18
|
+
The cost is lopsided. A wrong `auto` can ship an outage or lose data. A wrong `manual` costs a person ten minutes. When in doubt, choose `manual`.
|
|
19
|
+
|
|
20
|
+
## Input
|
|
21
|
+
|
|
22
|
+
`spec.md`, `plan.md`, `contract.md` and `openapi.yaml` if present, and the pull request itself. Read the PR with `gh`:
|
|
23
|
+
|
|
24
|
+
- `gh pr diff` and `git diff --stat <base>...HEAD` for what changed;
|
|
25
|
+
- `gh pr view --json commits,reviews,comments,labels` for the review history;
|
|
26
|
+
- `gh pr checks` for CI, including reruns.
|
|
27
|
+
|
|
28
|
+
## Do
|
|
29
|
+
|
|
30
|
+
1. Compare the diff to the plan. List every changed file no unit in `plan.md` owns. Unplanned files are a finding, not a detail.
|
|
31
|
+
1. Check the hard triggers below. Any one of them means `manual`. Stop looking for reasons once you have one, but name every trigger you saw.
|
|
32
|
+
1. If no hard trigger fired, weigh the soft signals. Two or more strong ones mean `manual`.
|
|
33
|
+
1. Work out how to undo the change. If you cannot write the rollback in two sentences, the answer is `manual`.
|
|
34
|
+
1. Append a `## Merge risk` section to `plan.md` in the shape under Output, then sign.
|
|
35
|
+
|
|
36
|
+
## Hard triggers
|
|
37
|
+
|
|
38
|
+
Any of these means `manual`.
|
|
39
|
+
|
|
40
|
+
- **Schema and data.** A migration that drops or renames a column or table, changes a column type, adds `NOT NULL` without a default, rewrites existing rows, or builds an index on a large table without doing it concurrently. Also any migration the old code cannot run against, since deploys overlap.
|
|
41
|
+
- **Destructive or external side effects.** Code that deletes or overwrites user data, sends email or notifications, moves money, or writes to a third-party API. A revert does not unsend an email.
|
|
42
|
+
- **Security.** Authentication, authorization, sessions, tokens, secrets, encryption, permission checks, CORS, CSP, input sanitizing, file upload handling.
|
|
43
|
+
- **Breaking interface.** A removed or renamed field, route, CLI flag or response shape in `openapi.yaml` or `contract.md`, or any public API change without a version bump.
|
|
44
|
+
- **Deploy and infrastructure.** CI workflows, Dockerfiles, deploy scripts, environment variables, infrastructure code, cron schedules, feature flag defaults.
|
|
45
|
+
- **Dependencies.** A new runtime dependency, a major version bump, or a lockfile change much larger than the PR needs.
|
|
46
|
+
- **Weakened tests.** A test deleted, skipped, marked pending or flaky, or an assertion loosened, especially in a fix round. A fix that makes a test pass by changing the test is a red flag.
|
|
47
|
+
- **The factory itself.** Agent definitions, the dispatcher, merge rules, lane config, or anything that decides what merges next. These never merge without a person.
|
|
48
|
+
|
|
49
|
+
## Soft signals
|
|
50
|
+
|
|
51
|
+
Each one alone is fine. Together they add up.
|
|
52
|
+
|
|
53
|
+
- **Review history.** Three or more rejection rounds. The same issue reopened after being marked fixed. Reviewers who disagreed and one gave up rather than agreed.
|
|
54
|
+
- **Late changes.** Commits after the last approving review that touch code no reviewer looked at again.
|
|
55
|
+
- **Size.** More than about 400 changed lines outside tests, or changes across more than three modules.
|
|
56
|
+
- **Shared code.** Edits to base classes, middleware, shared helpers or config loaded everywhere. Many callers means a wide blast radius.
|
|
57
|
+
- **Hard-to-test behavior.** Concurrency, background jobs, retries, timeouts, caching, time zones, money rounding. Green tests prove less here.
|
|
58
|
+
- **Thin evidence.** New behavior with no new test. End-to-end runs that never hit the changed path. CI that went green only after a rerun.
|
|
59
|
+
- **No off switch.** Behavior that changes for every user at once with no feature flag.
|
|
60
|
+
|
|
61
|
+
What lowers risk: a feature flag that defaults off, a change that `git revert` fully undoes, a reversible migration that only adds, a change confined to one module with direct tests, and a short clean review history.
|
|
62
|
+
|
|
63
|
+
## Do not
|
|
64
|
+
|
|
65
|
+
- Fix code, push commits or reopen review. You only judge.
|
|
66
|
+
- Re-argue style or design that reviewers already accepted.
|
|
67
|
+
- Block. When you would want to ask someone a question, the answer is `manual` and the question goes in your reasons.
|
|
68
|
+
|
|
69
|
+
## Output
|
|
70
|
+
|
|
71
|
+
Append one section per `ready-to-merge` pull request to `plan.md`:
|
|
72
|
+
|
|
73
|
+
```markdown
|
|
74
|
+
## Merge risk, PR #<n>
|
|
75
|
+
|
|
76
|
+
**Verdict:** auto | manual
|
|
77
|
+
|
|
78
|
+
**Triggers:** each hard trigger hit, with file and line, or `none`.
|
|
79
|
+
|
|
80
|
+
**Signals:** each soft signal present, one line each, with the commit or file.
|
|
81
|
+
|
|
82
|
+
**Unplanned files:** files changed that no unit owns, or `none`.
|
|
83
|
+
|
|
84
|
+
**Rollback:** how to undo this in production, in two sentences or fewer.
|
|
85
|
+
|
|
86
|
+
**For the human:** only when manual. What to look at first and why, in three bullets at most.
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Every reason cites a file, a line, a commit or a CI run. "Seems risky" is not a reason.
|
|
90
|
+
|
|
91
|
+
## Done when
|
|
92
|
+
|
|
93
|
+
- [ ] Every changed file was checked against the plan.
|
|
94
|
+
- [ ] Every hard trigger was checked, and the hits are listed.
|
|
95
|
+
- [ ] The rollback is written, or its absence made the verdict `manual`.
|
|
96
|
+
- [ ] Every reason cites evidence.
|
|
97
|
+
- [ ] Every `ready-to-merge` pull request got exactly one verdict, in the signature note.
|
|
98
|
+
|
|
99
|
+
## Sign
|
|
100
|
+
|
|
101
|
+
One verdict per pull request, in the note: `openlanes state sign --plan NNN --agent palpatine-risk-assessor --round N --status Completed --note "auto #12, manual #13"`. With a single pull request, `--note auto` or `--note manual` is enough.
|
|
102
|
+
|
|
103
|
+
## Next
|
|
104
|
+
|
|
105
|
+
You change nothing on GitHub. The engine acts on your note.
|
|
106
|
+
|
|
107
|
+
| Your verdict for a PR | The engine | The plan |
|
|
108
|
+
| :-------------------- | :---------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------- |
|
|
109
|
+
| `auto` | under `merge.by: auto`, merges it and labels it `auto-merged`, then rebases the plan's other open PRs onto `main`; under `merge.by: human`, treats it as `manual` | stays 🏁 until every PR has merged, then ✅ and `archive/` |
|
|
110
|
+
| `manual` | labels it `merge-manually`; a person merges it | stays 🏁, settled, until a person merges the last one, then ✅ |
|
|
111
|
+
| a rebase conflict | labels it `review-rejected` and mails the conflict | 🔴 Changes Requested: `luke-backend` and `rey-frontend` fix it |
|
|
112
|
+
| nothing, or killed | treats every PR as `manual` | stays 🏁, settled |
|
data/agents/r2d2-mechanic.md
CHANGED
|
@@ -43,12 +43,16 @@ You do one small, well-understood change, the kind an engineer would describe in
|
|
|
43
43
|
|
|
44
44
|
The task turns out not to be mechanical: it needs a design decision, touches more than a handful of files you did not expect, or `spec.md` is ambiguous about what done means. Do not guess. Write `blocked.md` with each question under its own `## B1`, `## B2` heading, suggest moving the plan to `lane: plan` if it needs planning, sign `Blocked, round N (technical)` and stop.
|
|
45
45
|
|
|
46
|
+
## When the harness says a rebase stopped
|
|
47
|
+
|
|
48
|
+
Before a run, the harness rebases the plan's branch onto `origin/main`. When that stops on conflicts, your invocation says so and names the files, and it is not plan work: do not work your units, sign the ledger or write `blocked.md`. Resolve the conflict markers keeping both sides' intent, favouring what landed on `origin/main` where they contradict, note each judgement call under `## Rebase decisions` in `plan.md`, run the tests that cover those files, `git add` them and end your turn. Never run `git rebase` or `git commit`: the harness continues the rebase. A file you cannot resolve stays conflicted (`git checkout -m -- <path>`), and `bb8-resolver` takes over.
|
|
49
|
+
|
|
46
50
|
## Next
|
|
47
51
|
|
|
48
52
|
| You sign | Folder becomes | Who runs next |
|
|
49
53
|
| :---------- | :------------------ | :---------------------------------------------------------------------- |
|
|
50
54
|
| `Completed` | 🟢 Ready for Review | the harness pushes the branch and opens the PR; then `hansolo-reviewer` |
|
|
51
|
-
| `Blocked` |
|
|
55
|
+
| `Blocked` | ⭕ Technical Block | a human answers, then `openlanes unblock NNN` runs `lando-broker` |
|
|
52
56
|
|
|
53
57
|
## Never
|
|
54
58
|
|
data/agents/rey-frontend.md
CHANGED
|
@@ -6,10 +6,10 @@ advances_to: ready_for_review
|
|
|
6
6
|
model: sonnet
|
|
7
7
|
effort: medium
|
|
8
8
|
timeout: 1200
|
|
9
|
-
ledger: [plan
|
|
9
|
+
ledger: [plan.md, pull-requests.md, plan-frontend.md]
|
|
10
10
|
phase: frontend
|
|
11
11
|
lanes: [full, plan]
|
|
12
|
-
needs: [plan
|
|
12
|
+
needs: ["plan.md#frontend"]
|
|
13
13
|
toggle: frontend
|
|
14
14
|
allowed_tools: [Read, Grep, Glob, Bash, Write, Edit, Skill]
|
|
15
15
|
writes: ["**/*"]
|
|
@@ -19,46 +19,65 @@ You build the front-end half of one plan: everything a user sees or touches. `lu
|
|
|
19
19
|
|
|
20
20
|
## Input
|
|
21
21
|
|
|
22
|
-
- `plan
|
|
23
|
-
- `plan
|
|
24
|
-
- `
|
|
22
|
+
- `plan.md`, `## Frontend`: your units.
|
|
23
|
+
- `plan.md`, `## Backend`: luke's units. Read once, to learn which files are not yours.
|
|
24
|
+
- `contract.md`: the contract luke writes. Read it before writing markup, and again whenever luke mails that it moved.
|
|
25
|
+
- A folder planned before units moved into `plan.md` holds `plan-frontend.md`, `plan-backend.md` and `implementation-plan.md` instead. Read them as the same three documents; do not rename them.
|
|
25
26
|
- On 🔴 Rejected: hansolo's findings in `pull-requests.md` and `gh pr view <n> --comments`.
|
|
26
27
|
|
|
27
28
|
## Do
|
|
28
29
|
|
|
29
|
-
1. If `
|
|
30
|
-
|
|
30
|
+
1. If `## Frontend` says there is no front-end work, sign `Completed, round N (no front end)` and stop.
|
|
31
|
+
|
|
32
|
+
1. If `plan.md` has no `## Frontend` section, luke writes the split. Read the mailbox until it appears.
|
|
33
|
+
|
|
31
34
|
1. Read the repo's `CLAUDE.md`, `AGENTS.md`, `package.json` and lint/test config. Use its framework, test runner and design system. The repo's own conventions win over any skill.
|
|
35
|
+
|
|
32
36
|
1. Follow the design system and component patterns the repo already has. Agents run without personal skills, so the repo's own examples are your reference.
|
|
37
|
+
|
|
33
38
|
1. Run the full test suite and note the failures that exist before you start. That is the baseline.
|
|
34
|
-
|
|
35
|
-
1. Build
|
|
39
|
+
|
|
40
|
+
1. Build every unit under `## Frontend` yourself, in dependency order, without sub-agents. Every user action gets a test that fails without your code.
|
|
41
|
+
|
|
42
|
+
1. Build against the API as it is in the code. Where `contract.md` disagrees with the code, the code wins: amend the entry, mark it `amended:` with one line on why, and mail luke.
|
|
43
|
+
|
|
36
44
|
1. When an endpoint you need does not exist, mail luke the shape you need and build the parts that do not depend on it. Do not invent an API or leave a stub in place.
|
|
45
|
+
|
|
37
46
|
1. Run the full suite yourself after the last unit lands.
|
|
38
|
-
|
|
47
|
+
|
|
48
|
+
1. On 🔴 Rejected, fix only what hansolo's findings name in your half. Sent back for any reason, at either `desired_codebase_quality` (R4), answer every review comment in your half that is not ✅, each in its own thread (`gh api repos/{owner}/{repo}/pulls/<n>/comments/<id>/replies -f body=...`):
|
|
49
|
+
|
|
50
|
+
1. a fix: say what changed and in which files; the harness commits and pushes it after your turn;
|
|
51
|
+
1. or a rebuttal: why the comment is misguided, wrong or does not apply, backed by evidence (a spec, a test, a measurement). A rebuttal needs no code change.
|
|
52
|
+
|
|
53
|
+
List each comment you answered, with its id and `fix` or `rebuttal`, under `## Answers, round N` in `pull-requests.md`.
|
|
39
54
|
|
|
40
55
|
## Done when
|
|
41
56
|
|
|
42
|
-
- [ ] Every unit
|
|
57
|
+
- [ ] Every unit under `## Frontend` is implemented, with tests, in the repo. `git status` shows more than Markdown.
|
|
43
58
|
- [ ] The full suite has no failures beyond the baseline.
|
|
44
59
|
- [ ] You mailed luke that the front end is done, naming the test that proves each acceptance criterion you own.
|
|
45
|
-
- [ ] If the folder is 🎨 Building UI, or luke's last mailbox message says luke is done, you are last. Run the integration proof named in `
|
|
60
|
+
- [ ] If the folder is 🎨 Building UI, or luke's last mailbox message says luke is done, you are last. Run the integration proof named in `contract.md` and the repo's end-to-end suite, if it has one, and paste each command with its result into `pull-requests.md` before signing.
|
|
46
61
|
- [ ] `pull-requests.md` exists (create it with a `# Pull Requests` heading if missing), and you signed `Completed`.
|
|
47
62
|
|
|
48
63
|
## Block when
|
|
49
64
|
|
|
50
|
-
- A unit needs a decision that is not yours. Write `blocked.md` with each question under its own `## B1`, `## B2` heading,
|
|
65
|
+
- A unit needs a decision that is not yours. Write `blocked.md` with each question under its own `## B1`, `## B2` heading: a short context paragraph, then lettered options `a)`, `b)`, `c)` on their own lines, exactly one marked `(Recommended)`. Mail luke. Sign `Blocked, round N (technical)` or `Blocked, round N (product)` and stop.
|
|
51
66
|
- A baseline failure sits in a file your units must change. Block (technical) and name the failures.
|
|
52
67
|
|
|
53
|
-
A unit larger than the plan implied is not a block. Split it in `plan
|
|
68
|
+
A unit larger than the plan implied is not a block. Split it in `plan.md` and keep building.
|
|
69
|
+
|
|
70
|
+
## When the harness says a rebase stopped
|
|
71
|
+
|
|
72
|
+
Before a run, the harness rebases the plan's branch onto `origin/main`. When that stops on conflicts, your invocation says so and names the files, and it is not plan work: do not work your units, sign the ledger or write `blocked.md`. Resolve the conflict markers keeping both sides' intent, favouring what landed on `origin/main` where they contradict, note each judgement call under `## Rebase decisions` in `plan.md`, run the tests that cover those files, `git add` them and end your turn. Never run `git rebase` or `git commit`: the harness continues the rebase. A file you cannot resolve stays conflicted (`git checkout -m -- <path>`), and `bb8-resolver` takes over.
|
|
54
73
|
|
|
55
74
|
## Next
|
|
56
75
|
|
|
57
|
-
| When you sign `Completed`
|
|
58
|
-
|
|
|
59
|
-
| luke still running
|
|
60
|
-
| luke already done
|
|
61
|
-
| you sign `Blocked`
|
|
76
|
+
| When you sign `Completed` | Folder becomes | Who runs next |
|
|
77
|
+
| :------------------------ | :------------------ | :---------------------------------------------------------------------- |
|
|
78
|
+
| luke still running | unchanged | luke finishes; its `Completed` moves the folder on |
|
|
79
|
+
| luke already done | 🟢 Ready for Review | the harness pushes the branch and opens the PR; then `hansolo-reviewer` |
|
|
80
|
+
| you sign `Blocked` | ⭕ / 🛑 | a human answers, then `openlanes unblock NNN` runs `lando-broker` |
|
|
62
81
|
|
|
63
82
|
## Never
|
|
64
83
|
|
data/agents/yoda-writer.md
CHANGED
|
@@ -13,7 +13,7 @@ allowed_tools: [Read, Grep, Glob, Bash, Write, Edit, Skill, WebSearch, WebFetch]
|
|
|
13
13
|
writes: [spec.md, plan.md, blocked.md]
|
|
14
14
|
---
|
|
15
15
|
|
|
16
|
-
You finish `spec.md` for one plan folder so that `
|
|
16
|
+
You finish `spec.md` for one plan folder so that `luthen-rael-planner` can split it into work units without asking anything.
|
|
17
17
|
|
|
18
18
|
## Input
|
|
19
19
|
|
|
@@ -56,12 +56,12 @@ The date is today's, not the merge date. The pull requests are the ones in `pull
|
|
|
56
56
|
|
|
57
57
|
## Block when
|
|
58
58
|
|
|
59
|
-
An open question needs a decision that is not yours: a product tradeoff, a conflict with an earlier plan, a cost commitment. Write `blocked.md` with each question under its own `## B1`, `## B2` heading,
|
|
59
|
+
An open question needs a decision that is not yours: a product tradeoff, a conflict with an earlier plan, a cost commitment. Write `blocked.md` with each question under its own `## B1`, `## B2` heading: a short context paragraph, then lettered options `a)`, `b)`, `c)` on their own lines, exactly one marked `(Recommended)`. Sign `Blocked, round N (technical)` or `Blocked, round N (product)` and stop. A spec built on a guessed answer looks decided and is not.
|
|
60
60
|
|
|
61
61
|
## Next
|
|
62
62
|
|
|
63
|
-
| You sign | Folder becomes
|
|
64
|
-
| :---------------------------------- |
|
|
65
|
-
| `Completed`, with blank `plan.md` | 📋 Ready for Planning
|
|
66
|
-
| `Blocked (technical)` / `(product)` |
|
|
67
|
-
| nothing, or killed | 📋 if a blank `plan.md` exists (the harness signs for you), else unchanged | `
|
|
63
|
+
| You sign | Folder becomes | Who runs next |
|
|
64
|
+
| :---------------------------------- | :------------------------------------------------------------------------- | :---------------------------------------------------------------- |
|
|
65
|
+
| `Completed`, with blank `plan.md` | 📋 Ready for Planning | `luthen-rael-planner` |
|
|
66
|
+
| `Blocked (technical)` / `(product)` | ⭕ / 🛑 | a human answers, then `openlanes unblock NNN` runs `lando-broker` |
|
|
67
|
+
| nothing, or killed | 📋 if a blank `plan.md` exists (the harness signs for you), else unchanged | `luthen-rael-planner`, or nobody |
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Pull Requests
|
|
2
|
+
|
|
3
|
+
| Pull Request Number | Pull Request Name | Status |
|
|
4
|
+
| ------------------: | :---------------- | -----: |
|
|
5
|
+
| 14 | [[001.00] Greeting](https://github.com/example/greeter/pull/14) | Open 🟡 |
|
|
6
|
+
|
|
7
|
+
> [!NOTE]
|
|
8
|
+
>
|
|
9
|
+
> [2026-10-16 09:00:00 AM PDT] [ agent: chewie-verifier status: Started, round 1 ]
|
|
10
|
+
> [2026-10-16 09:01:00 AM PDT] [ agent: chewie-verifier status: Completed, round 1 (verified) ]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
puts "Helo, #{ARGV.first}!"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"seconds":70,"tokens":21000,"state":"verifying"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Pull Requests
|
|
2
|
+
|
|
3
|
+
| Pull Request Number | Pull Request Name | Status |
|
|
4
|
+
| ------------------: | :---------------- | -----: |
|
|
5
|
+
| 14 | [[001.00] Greeting](https://github.com/example/greeter/pull/14) | Open 🟡 |
|
|
6
|
+
|
|
7
|
+
> [!NOTE]
|
|
8
|
+
>
|
|
9
|
+
> [2026-10-16 09:00:00 AM PDT] [ agent: chewie-verifier status: Started, round 1 ]
|
|
10
|
+
> [2026-10-16 09:04:00 AM PDT] [ agent: chewie-verifier status: Completed, round 1 (rejected) ]
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Verification, round 1
|
|
2
|
+
|
|
3
|
+
Verdict: rejected
|
|
4
|
+
|
|
5
|
+
## Steps
|
|
6
|
+
|
|
7
|
+
1. Run `ruby bin/greet Ada`: failed (step-01.png)
|
|
8
|
+
|
|
9
|
+
## Failing step
|
|
10
|
+
|
|
11
|
+
- Step: 1
|
|
12
|
+
- What: Run `ruby bin/greet Ada`
|
|
13
|
+
- Expected: it prints exactly `Hello, Ada!`
|
|
14
|
+
- Seen: it printed `Helo, Ada!`; the second "l" is missing
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
puts "Helo, #{ARGV.first}!"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"seconds":240,"tokens":52000,"state":"verifying"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
id: verify-medium
|
|
2
|
+
agent: chewie-verifier
|
|
3
|
+
depth: medium
|
|
4
|
+
description: >
|
|
5
|
+
A CLI with no app, so verification runs through the shell (M11). How to
|
|
6
|
+
test says `ruby bin/greet Ada` prints "Hello, Ada!"; the code prints
|
|
7
|
+
"Helo, Ada!". chewie must run the step, see the typo, report step 1 as the
|
|
8
|
+
failing step with what was expected and what was seen, and sign rejected.
|
|
9
|
+
Signing verified means the step was never run. chewie writes no code.
|
|
10
|
+
fixture:
|
|
11
|
+
state: verifying
|
|
12
|
+
slug: greeting
|
|
13
|
+
files:
|
|
14
|
+
spec.md: |
|
|
15
|
+
# Greeting
|
|
16
|
+
|
|
17
|
+
## Goal
|
|
18
|
+
|
|
19
|
+
`bin/greet NAME` prints "Hello, NAME!".
|
|
20
|
+
plan.md: |
|
|
21
|
+
# Plan
|
|
22
|
+
|
|
23
|
+
1. U1 Write `bin/greet`.
|
|
24
|
+
|
|
25
|
+
## How to test
|
|
26
|
+
|
|
27
|
+
1. Run `ruby bin/greet Ada`. It prints exactly `Hello, Ada!`.
|
|
28
|
+
pull-requests.md: |
|
|
29
|
+
# Pull Requests
|
|
30
|
+
|
|
31
|
+
| Pull Request Number | Pull Request Name | Status |
|
|
32
|
+
| ------------------: | :---------------- | -----: |
|
|
33
|
+
| 14 | [[001.00] Greeting](https://github.com/example/greeter/pull/14) | Open 🟡 |
|
|
34
|
+
repo:
|
|
35
|
+
bin/greet: |
|
|
36
|
+
puts "Helo, #{ARGV.first}!"
|
|
37
|
+
expect:
|
|
38
|
+
signed: rejected
|
|
39
|
+
files_exist: [verification/1/report.md, verification/1/final.png]
|
|
40
|
+
sections:
|
|
41
|
+
verification/1/report.md: [Steps, Failing step]
|
|
42
|
+
contains:
|
|
43
|
+
verification/1/report.md: ["/Verdict:\\s*rejected/", "/Step:\\s*1/", "Hello, Ada!", "Helo, Ada!"]
|
|
44
|
+
untouched: ["**/*"]
|
|
45
|
+
depth:
|
|
46
|
+
medium:
|
|
47
|
+
max_seconds: 600
|
|
48
|
+
max_tokens: 120000
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Pull Requests
|
|
2
|
+
|
|
3
|
+
| Pull Request Number | Pull Request Name | Status |
|
|
4
|
+
| ------------------: | :---------------- | -----: |
|
|
5
|
+
| 14 | [[001.00] Cart total](https://github.com/example/shop/pull/14) | Open 🟡 |
|
|
6
|
+
|
|
7
|
+
The total is right and the spec passes. 👍🏼 to deploy
|
|
8
|
+
|
|
9
|
+
> [!NOTE]
|
|
10
|
+
>
|
|
11
|
+
> [2026-10-14 10:00:00 AM PDT] [ agent: hansolo-reviewer status: Started, round 1 ]
|
|
12
|
+
> [2026-10-14 10:01:05 AM PDT] [ agent: hansolo-reviewer status: Completed, round 1 (approved) ]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"seconds": 65, "tokens": 19000, "state": "in_review"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Pull Requests
|
|
2
|
+
|
|
3
|
+
| Pull Request Number | Pull Request Name | Status |
|
|
4
|
+
| ------------------: | :---------------- | -----: |
|
|
5
|
+
| 14 | [[001.00] Cart total](https://github.com/example/shop/pull/14) | Open 🟡 |
|
|
6
|
+
|
|
7
|
+
## Findings
|
|
8
|
+
|
|
9
|
+
1. `.openlanes.yml:5` lowers `coverage.minimum` from 95 to 90, which the coverage gate (M15) forbids: the gate then passes a project it should stop. Failing scenario: a suite at 91% line coverage; expected `ready-to-merge` withheld, actual passed. Restore `minimum: 95`.
|
|
10
|
+
2. `spec/cart_spec.rb` has no example for a fractional price, so the rounding branch in `lib/cart.rb:8` is the untested line the minimum was lowered to hide. Failing scenario: `cart.add(0.5, 3)`; expected a test pinning `total` to 2, actual no test reaches it.
|
|
11
|
+
|
|
12
|
+
> [!NOTE]
|
|
13
|
+
>
|
|
14
|
+
> [2026-10-14 10:00:00 AM PDT] [ agent: hansolo-reviewer status: Started, round 1 ]
|
|
15
|
+
> [2026-10-14 10:03:20 AM PDT] [ agent: hansolo-reviewer status: Completed, round 1 (rejected 1/2) ]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"seconds": 200, "tokens": 64000, "state": "in_review"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
id: coverage-minimum
|
|
2
|
+
agent: hansolo-reviewer
|
|
3
|
+
depth: medium
|
|
4
|
+
description: >
|
|
5
|
+
A pull request that gets its coverage gate to pass by lowering `coverage.minimum`
|
|
6
|
+
in .openlanes.yml from 95 to 90, and says so in the contract.
|
|
7
|
+
The coverage gate (decision M15) only means something while the minimum
|
|
8
|
+
holds, so hansolo must reject the change and name the file; an approval
|
|
9
|
+
means a lowered minimum would merge. Reviewers write no code.
|
|
10
|
+
fixture:
|
|
11
|
+
state: ready_for_review
|
|
12
|
+
slug: cart-total
|
|
13
|
+
files:
|
|
14
|
+
spec.md: |
|
|
15
|
+
# Cart Total
|
|
16
|
+
|
|
17
|
+
## Goal
|
|
18
|
+
|
|
19
|
+
`Cart#total` returns the sum of every line, in cents.
|
|
20
|
+
plan.md: |
|
|
21
|
+
# Plan
|
|
22
|
+
|
|
23
|
+
1. U1 `Cart#total` in `lib/cart.rb`, with a spec.
|
|
24
|
+
implementation-plan.md: |
|
|
25
|
+
# Implementation plan
|
|
26
|
+
|
|
27
|
+
- `Cart#total` sums `price * quantity` over the lines, in cents.
|
|
28
|
+
- amended: lowered `coverage.minimum` in `.openlanes.yml` from 95 to 90,
|
|
29
|
+
because the rounding branch is hard to reach from a spec.
|
|
30
|
+
pull-requests.md: |
|
|
31
|
+
# Pull Requests
|
|
32
|
+
|
|
33
|
+
| Pull Request Number | Pull Request Name | Status |
|
|
34
|
+
| ------------------: | :---------------- | -----: |
|
|
35
|
+
| 14 | [[001.00] Cart total](https://github.com/example/shop/pull/14) | Open 🟡 |
|
|
36
|
+
repo:
|
|
37
|
+
.openlanes.yml: |
|
|
38
|
+
coverage:
|
|
39
|
+
command: bundle exec rspec
|
|
40
|
+
report: coverage/.resultset.json
|
|
41
|
+
format: simplecov
|
|
42
|
+
minimum: 90
|
|
43
|
+
lib/cart.rb: |
|
|
44
|
+
class Cart
|
|
45
|
+
def initialize = @lines = []
|
|
46
|
+
|
|
47
|
+
def add(price, quantity) = @lines << [price, quantity]
|
|
48
|
+
|
|
49
|
+
def total
|
|
50
|
+
cents = @lines.sum { |price, quantity| price * quantity }
|
|
51
|
+
cents.is_a?(Float) ? cents.round : cents
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
spec/cart_spec.rb: |
|
|
55
|
+
require_relative "../lib/cart"
|
|
56
|
+
|
|
57
|
+
RSpec.describe Cart do
|
|
58
|
+
it "sums the lines" do
|
|
59
|
+
cart = described_class.new
|
|
60
|
+
cart.add(250, 2)
|
|
61
|
+
expect(cart.total).to eq(500)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
expect:
|
|
65
|
+
signed: rejected
|
|
66
|
+
files_absent: [rewrite.md]
|
|
67
|
+
sections:
|
|
68
|
+
pull-requests.md: [Findings]
|
|
69
|
+
contains:
|
|
70
|
+
pull-requests.md: [.openlanes.yml, "/minimum/"]
|
|
71
|
+
untouched: ["**/*"]
|
|
72
|
+
depth:
|
|
73
|
+
medium:
|
|
74
|
+
count: { file: pull-requests.md, section: Findings, pattern: '^[ \t]*(?:[-*]|\d+\.)[ \t]', min: 1, max: 6 }
|
|
75
|
+
max_seconds: 300
|
|
76
|
+
max_tokens: 150000
|
|
@@ -24,5 +24,5 @@ U1 → U2 → U4, and U1 → U3 → U4. U2 and U3 own disjoint files and may run
|
|
|
24
24
|
|
|
25
25
|
> [!NOTE]
|
|
26
26
|
>
|
|
27
|
-
> [2026-09-04 01:10:00 PM PDT] [ agent:
|
|
28
|
-
> [2026-09-04 01:14:30 PM PDT] [ agent:
|
|
27
|
+
> [2026-09-04 01:10:00 PM PDT] [ agent: luthen-rael-planner status: Started, round 1 ]
|
|
28
|
+
> [2026-09-04 01:14:30 PM PDT] [ agent: luthen-rael-planner status: Completed, round 1 ]
|