agent-bober 0.12.0 → 0.17.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 +20 -0
- package/.claude-plugin/plugin.json +2 -2
- package/CHANGELOG.md +243 -0
- package/README.md +238 -5
- package/agents/bober-architect.md +72 -0
- package/agents/bober-code-reviewer.md +238 -0
- package/agents/bober-curator.md +49 -0
- package/agents/bober-deployer.md +267 -0
- package/agents/bober-diagnoser.md +289 -0
- package/agents/bober-documenter.md +129 -0
- package/agents/bober-evaluator.md +135 -1
- package/agents/bober-generator.md +80 -3
- package/agents/bober-planner.md +47 -1
- package/agents/bober-postmortemer.md +185 -0
- package/agents/bober-researcher.md +38 -0
- package/dist/cli/commands/approve.d.ts +17 -0
- package/dist/cli/commands/approve.d.ts.map +1 -0
- package/dist/cli/commands/approve.js +64 -0
- package/dist/cli/commands/approve.js.map +1 -0
- package/dist/cli/commands/audit-show.d.ts +14 -0
- package/dist/cli/commands/audit-show.d.ts.map +1 -0
- package/dist/cli/commands/audit-show.js +85 -0
- package/dist/cli/commands/audit-show.js.map +1 -0
- package/dist/cli/commands/config.d.ts +10 -0
- package/dist/cli/commands/config.d.ts.map +1 -0
- package/dist/cli/commands/config.js +73 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/graph.d.ts +8 -0
- package/dist/cli/commands/graph.d.ts.map +1 -0
- package/dist/cli/commands/graph.js +219 -0
- package/dist/cli/commands/graph.js.map +1 -0
- package/dist/cli/commands/impact.d.ts +19 -0
- package/dist/cli/commands/impact.d.ts.map +1 -0
- package/dist/cli/commands/impact.js +191 -0
- package/dist/cli/commands/impact.js.map +1 -0
- package/dist/cli/commands/incident.d.ts +19 -0
- package/dist/cli/commands/incident.d.ts.map +1 -0
- package/dist/cli/commands/incident.js +324 -0
- package/dist/cli/commands/incident.js.map +1 -0
- package/dist/cli/commands/init.js +40 -1
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/list-approvals.d.ts +16 -0
- package/dist/cli/commands/list-approvals.d.ts.map +1 -0
- package/dist/cli/commands/list-approvals.js +57 -0
- package/dist/cli/commands/list-approvals.js.map +1 -0
- package/dist/cli/commands/memory.d.ts +14 -0
- package/dist/cli/commands/memory.d.ts.map +1 -0
- package/dist/cli/commands/memory.js +132 -0
- package/dist/cli/commands/memory.js.map +1 -0
- package/dist/cli/commands/onboard.d.ts +3 -0
- package/dist/cli/commands/onboard.d.ts.map +1 -0
- package/dist/cli/commands/onboard.js +190 -0
- package/dist/cli/commands/onboard.js.map +1 -0
- package/dist/cli/commands/playbook.d.ts +17 -0
- package/dist/cli/commands/playbook.d.ts.map +1 -0
- package/dist/cli/commands/playbook.js +123 -0
- package/dist/cli/commands/playbook.js.map +1 -0
- package/dist/cli/commands/postmortem.d.ts +12 -0
- package/dist/cli/commands/postmortem.d.ts.map +1 -0
- package/dist/cli/commands/postmortem.js +67 -0
- package/dist/cli/commands/postmortem.js.map +1 -0
- package/dist/cli/commands/reject.d.ts +17 -0
- package/dist/cli/commands/reject.d.ts.map +1 -0
- package/dist/cli/commands/reject.js +52 -0
- package/dist/cli/commands/reject.js.map +1 -0
- package/dist/cli/commands/rollback.d.ts +21 -0
- package/dist/cli/commands/rollback.d.ts.map +1 -0
- package/dist/cli/commands/rollback.js +90 -0
- package/dist/cli/commands/rollback.js.map +1 -0
- package/dist/cli/commands/run.d.ts +9 -0
- package/dist/cli/commands/run.d.ts.map +1 -1
- package/dist/cli/commands/run.js +29 -0
- package/dist/cli/commands/run.js.map +1 -1
- package/dist/cli/commands/telemetry.d.ts +16 -0
- package/dist/cli/commands/telemetry.d.ts.map +1 -0
- package/dist/cli/commands/telemetry.js +152 -0
- package/dist/cli/commands/telemetry.js.map +1 -0
- package/dist/cli/commands/worktree.d.ts +12 -0
- package/dist/cli/commands/worktree.d.ts.map +1 -0
- package/dist/cli/commands/worktree.js +57 -0
- package/dist/cli/commands/worktree.js.map +1 -0
- package/dist/cli/index.js +56 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +41 -3
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/index.d.ts +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +4 -0
- package/dist/config/index.js.map +1 -1
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +25 -1
- package/dist/config/loader.js.map +1 -1
- package/dist/config/role-providers.d.ts +29 -0
- package/dist/config/role-providers.d.ts.map +1 -0
- package/dist/config/role-providers.js +115 -0
- package/dist/config/role-providers.js.map +1 -0
- package/dist/config/schema.d.ts +1350 -61
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +189 -0
- package/dist/config/schema.js.map +1 -1
- package/dist/contracts/eval-result.d.ts +112 -56
- package/dist/contracts/eval-result.d.ts.map +1 -1
- package/dist/contracts/eval-result.js +3 -0
- package/dist/contracts/eval-result.js.map +1 -1
- package/dist/contracts/sprint-contract.d.ts +30 -30
- package/dist/fleet/aggregator.d.ts +5 -0
- package/dist/fleet/aggregator.d.ts.map +1 -0
- package/dist/fleet/aggregator.js +39 -0
- package/dist/fleet/aggregator.js.map +1 -0
- package/dist/fleet/child-config.d.ts +12 -0
- package/dist/fleet/child-config.d.ts.map +1 -0
- package/dist/fleet/child-config.js +38 -0
- package/dist/fleet/child-config.js.map +1 -0
- package/dist/fleet/coordinator.d.ts +25 -0
- package/dist/fleet/coordinator.d.ts.map +1 -0
- package/dist/fleet/coordinator.js +40 -0
- package/dist/fleet/coordinator.js.map +1 -0
- package/dist/fleet/index.d.ts +40 -0
- package/dist/fleet/index.d.ts.map +1 -0
- package/dist/fleet/index.js +117 -0
- package/dist/fleet/index.js.map +1 -0
- package/dist/fleet/manifest.d.ts +51 -0
- package/dist/fleet/manifest.d.ts.map +1 -0
- package/dist/fleet/manifest.js +32 -0
- package/dist/fleet/manifest.js.map +1 -0
- package/dist/fleet/reporter.d.ts +32 -0
- package/dist/fleet/reporter.d.ts.map +1 -0
- package/dist/fleet/reporter.js +71 -0
- package/dist/fleet/reporter.js.map +1 -0
- package/dist/fleet/runner.d.ts +48 -0
- package/dist/fleet/runner.d.ts.map +1 -0
- package/dist/fleet/runner.js +104 -0
- package/dist/fleet/runner.js.map +1 -0
- package/dist/fleet/scaffolder.d.ts +12 -0
- package/dist/fleet/scaffolder.d.ts.map +1 -0
- package/dist/fleet/scaffolder.js +82 -0
- package/dist/fleet/scaffolder.js.map +1 -0
- package/dist/fleet/types.d.ts +21 -0
- package/dist/fleet/types.d.ts.map +1 -0
- package/dist/fleet/types.js +2 -0
- package/dist/fleet/types.js.map +1 -0
- package/dist/graph/artifact-store.d.ts +14 -0
- package/dist/graph/artifact-store.d.ts.map +1 -0
- package/dist/graph/artifact-store.js +100 -0
- package/dist/graph/artifact-store.js.map +1 -0
- package/dist/graph/cli.d.ts +53 -0
- package/dist/graph/cli.d.ts.map +1 -0
- package/dist/graph/cli.js +181 -0
- package/dist/graph/cli.js.map +1 -0
- package/dist/graph/client.d.ts +64 -0
- package/dist/graph/client.d.ts.map +1 -0
- package/dist/graph/client.js +216 -0
- package/dist/graph/client.js.map +1 -0
- package/dist/graph/fallback.d.ts +13 -0
- package/dist/graph/fallback.d.ts.map +1 -0
- package/dist/graph/fallback.js +57 -0
- package/dist/graph/fallback.js.map +1 -0
- package/dist/graph/hook-handler.d.ts +50 -0
- package/dist/graph/hook-handler.d.ts.map +1 -0
- package/dist/graph/hook-handler.js +217 -0
- package/dist/graph/hook-handler.js.map +1 -0
- package/dist/graph/incidents.d.ts +59 -0
- package/dist/graph/incidents.d.ts.map +1 -0
- package/dist/graph/incidents.js +22 -0
- package/dist/graph/incidents.js.map +1 -0
- package/dist/graph/mcp-client.d.ts +51 -0
- package/dist/graph/mcp-client.d.ts.map +1 -0
- package/dist/graph/mcp-client.js +285 -0
- package/dist/graph/mcp-client.js.map +1 -0
- package/dist/graph/onboarding-composer.d.ts +30 -0
- package/dist/graph/onboarding-composer.d.ts.map +1 -0
- package/dist/graph/onboarding-composer.js +275 -0
- package/dist/graph/onboarding-composer.js.map +1 -0
- package/dist/graph/pipeline-lifecycle.d.ts +95 -0
- package/dist/graph/pipeline-lifecycle.d.ts.map +1 -0
- package/dist/graph/pipeline-lifecycle.js +341 -0
- package/dist/graph/pipeline-lifecycle.js.map +1 -0
- package/dist/graph/preflight-budgets.d.ts +52 -0
- package/dist/graph/preflight-budgets.d.ts.map +1 -0
- package/dist/graph/preflight-budgets.js +78 -0
- package/dist/graph/preflight-budgets.js.map +1 -0
- package/dist/graph/preflight-injector.d.ts +130 -0
- package/dist/graph/preflight-injector.d.ts.map +1 -0
- package/dist/graph/preflight-injector.js +618 -0
- package/dist/graph/preflight-injector.js.map +1 -0
- package/dist/graph/prereq.d.ts +12 -0
- package/dist/graph/prereq.d.ts.map +1 -0
- package/dist/graph/prereq.js +61 -0
- package/dist/graph/prereq.js.map +1 -0
- package/dist/graph/prompts.d.ts +42 -0
- package/dist/graph/prompts.d.ts.map +1 -0
- package/dist/graph/prompts.js +80 -0
- package/dist/graph/prompts.js.map +1 -0
- package/dist/graph/sandbox.d.ts +19 -0
- package/dist/graph/sandbox.d.ts.map +1 -0
- package/dist/graph/sandbox.js +25 -0
- package/dist/graph/sandbox.js.map +1 -0
- package/dist/graph/token-usage.d.ts +21 -0
- package/dist/graph/token-usage.d.ts.map +1 -0
- package/dist/graph/token-usage.js +22 -0
- package/dist/graph/token-usage.js.map +1 -0
- package/dist/graph/types.d.ts +129 -0
- package/dist/graph/types.d.ts.map +1 -0
- package/dist/graph/types.js +12 -0
- package/dist/graph/types.js.map +1 -0
- package/dist/incident/orchestrator.d.ts +168 -0
- package/dist/incident/orchestrator.d.ts.map +1 -0
- package/dist/incident/orchestrator.js +279 -0
- package/dist/incident/orchestrator.js.map +1 -0
- package/dist/incident/playbook-search.d.ts +67 -0
- package/dist/incident/playbook-search.d.ts.map +1 -0
- package/dist/incident/playbook-search.js +288 -0
- package/dist/incident/playbook-search.js.map +1 -0
- package/dist/incident/postmortem.d.ts +44 -0
- package/dist/incident/postmortem.d.ts.map +1 -0
- package/dist/incident/postmortem.js +486 -0
- package/dist/incident/postmortem.js.map +1 -0
- package/dist/incident/resolution-verify.d.ts +186 -0
- package/dist/incident/resolution-verify.d.ts.map +1 -0
- package/dist/incident/resolution-verify.js +210 -0
- package/dist/incident/resolution-verify.js.map +1 -0
- package/dist/incident/rollback.d.ts +137 -0
- package/dist/incident/rollback.d.ts.map +1 -0
- package/dist/incident/rollback.js +328 -0
- package/dist/incident/rollback.js.map +1 -0
- package/dist/incident/timeline.d.ts +147 -0
- package/dist/incident/timeline.d.ts.map +1 -0
- package/dist/incident/timeline.js +452 -0
- package/dist/incident/timeline.js.map +1 -0
- package/dist/incident/types.d.ts +335 -0
- package/dist/incident/types.d.ts.map +1 -0
- package/dist/incident/types.js +158 -0
- package/dist/incident/types.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/event-stream.d.ts +46 -0
- package/dist/mcp/event-stream.d.ts.map +1 -0
- package/dist/mcp/event-stream.js +421 -0
- package/dist/mcp/event-stream.js.map +1 -0
- package/dist/mcp/external-client.d.ts +38 -0
- package/dist/mcp/external-client.d.ts.map +1 -0
- package/dist/mcp/external-client.js +121 -0
- package/dist/mcp/external-client.js.map +1 -0
- package/dist/mcp/run-manager.d.ts +74 -9
- package/dist/mcp/run-manager.d.ts.map +1 -1
- package/dist/mcp/run-manager.js +127 -31
- package/dist/mcp/run-manager.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +56 -0
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools/abort-run.d.ts +2 -0
- package/dist/mcp/tools/abort-run.d.ts.map +1 -0
- package/dist/mcp/tools/abort-run.js +62 -0
- package/dist/mcp/tools/abort-run.js.map +1 -0
- package/dist/mcp/tools/anchor.js +1 -1
- package/dist/mcp/tools/anchor.js.map +1 -1
- package/dist/mcp/tools/approve-checkpoint.d.ts +2 -0
- package/dist/mcp/tools/approve-checkpoint.d.ts.map +1 -0
- package/dist/mcp/tools/approve-checkpoint.js +70 -0
- package/dist/mcp/tools/approve-checkpoint.js.map +1 -0
- package/dist/mcp/tools/brownfield.js +1 -1
- package/dist/mcp/tools/brownfield.js.map +1 -1
- package/dist/mcp/tools/get-project-state.d.ts +2 -0
- package/dist/mcp/tools/get-project-state.d.ts.map +1 -0
- package/dist/mcp/tools/get-project-state.js +107 -0
- package/dist/mcp/tools/get-project-state.js.map +1 -0
- package/dist/mcp/tools/get-run-status.d.ts +2 -0
- package/dist/mcp/tools/get-run-status.d.ts.map +1 -0
- package/dist/mcp/tools/get-run-status.js +40 -0
- package/dist/mcp/tools/get-run-status.js.map +1 -0
- package/dist/mcp/tools/graph-schemas.d.ts +100 -0
- package/dist/mcp/tools/graph-schemas.d.ts.map +1 -0
- package/dist/mcp/tools/graph-schemas.js +39 -0
- package/dist/mcp/tools/graph-schemas.js.map +1 -0
- package/dist/mcp/tools/graph.d.ts +19 -0
- package/dist/mcp/tools/graph.d.ts.map +1 -0
- package/dist/mcp/tools/graph.js +263 -0
- package/dist/mcp/tools/graph.js.map +1 -0
- package/dist/mcp/tools/incident.d.ts +2 -0
- package/dist/mcp/tools/incident.d.ts.map +1 -0
- package/dist/mcp/tools/incident.js +246 -0
- package/dist/mcp/tools/incident.js.map +1 -0
- package/dist/mcp/tools/index.d.ts +38 -18
- package/dist/mcp/tools/index.d.ts.map +1 -1
- package/dist/mcp/tools/index.js +74 -18
- package/dist/mcp/tools/index.js.map +1 -1
- package/dist/mcp/tools/init.d.ts.map +1 -1
- package/dist/mcp/tools/init.js +2 -0
- package/dist/mcp/tools/init.js.map +1 -1
- package/dist/mcp/tools/list-active-runs.d.ts +2 -0
- package/dist/mcp/tools/list-active-runs.d.ts.map +1 -0
- package/dist/mcp/tools/list-active-runs.js +35 -0
- package/dist/mcp/tools/list-active-runs.js.map +1 -0
- package/dist/mcp/tools/list-pending-approvals.d.ts +2 -0
- package/dist/mcp/tools/list-pending-approvals.d.ts.map +1 -0
- package/dist/mcp/tools/list-pending-approvals.js +40 -0
- package/dist/mcp/tools/list-pending-approvals.js.map +1 -0
- package/dist/mcp/tools/list-projects.d.ts +2 -0
- package/dist/mcp/tools/list-projects.d.ts.map +1 -0
- package/dist/mcp/tools/list-projects.js +101 -0
- package/dist/mcp/tools/list-projects.js.map +1 -0
- package/dist/mcp/tools/list-specs.d.ts +2 -0
- package/dist/mcp/tools/list-specs.d.ts.map +1 -0
- package/dist/mcp/tools/list-specs.js +48 -0
- package/dist/mcp/tools/list-specs.js.map +1 -0
- package/dist/mcp/tools/playbook.d.ts +2 -0
- package/dist/mcp/tools/playbook.d.ts.map +1 -0
- package/dist/mcp/tools/playbook.js +104 -0
- package/dist/mcp/tools/playbook.js.map +1 -0
- package/dist/mcp/tools/postmortem.d.ts +2 -0
- package/dist/mcp/tools/postmortem.d.ts.map +1 -0
- package/dist/mcp/tools/postmortem.js +75 -0
- package/dist/mcp/tools/postmortem.js.map +1 -0
- package/dist/mcp/tools/react.js +1 -1
- package/dist/mcp/tools/react.js.map +1 -1
- package/dist/mcp/tools/reject-checkpoint.d.ts +2 -0
- package/dist/mcp/tools/reject-checkpoint.d.ts.map +1 -0
- package/dist/mcp/tools/reject-checkpoint.js +79 -0
- package/dist/mcp/tools/reject-checkpoint.js.map +1 -0
- package/dist/mcp/tools/rollback.d.ts +2 -0
- package/dist/mcp/tools/rollback.d.ts.map +1 -0
- package/dist/mcp/tools/rollback.js +78 -0
- package/dist/mcp/tools/rollback.js.map +1 -0
- package/dist/mcp/tools/run-in-worktree.d.ts +2 -0
- package/dist/mcp/tools/run-in-worktree.d.ts.map +1 -0
- package/dist/mcp/tools/run-in-worktree.js +90 -0
- package/dist/mcp/tools/run-in-worktree.js.map +1 -0
- package/dist/mcp/tools/run.js +1 -1
- package/dist/mcp/tools/run.js.map +1 -1
- package/dist/mcp/tools/solidity.js +1 -1
- package/dist/mcp/tools/solidity.js.map +1 -1
- package/dist/mcp/tools/status.d.ts.map +1 -1
- package/dist/mcp/tools/status.js +11 -0
- package/dist/mcp/tools/status.js.map +1 -1
- package/dist/mcp/tools/subscribe-events.d.ts +2 -0
- package/dist/mcp/tools/subscribe-events.d.ts.map +1 -0
- package/dist/mcp/tools/subscribe-events.js +48 -0
- package/dist/mcp/tools/subscribe-events.js.map +1 -0
- package/dist/mcp/tools/unsubscribe-events.d.ts +2 -0
- package/dist/mcp/tools/unsubscribe-events.d.ts.map +1 -0
- package/dist/mcp/tools/unsubscribe-events.js +45 -0
- package/dist/mcp/tools/unsubscribe-events.js.map +1 -0
- package/dist/orchestrator/agent-loader.d.ts +16 -0
- package/dist/orchestrator/agent-loader.d.ts.map +1 -1
- package/dist/orchestrator/agent-loader.js +30 -0
- package/dist/orchestrator/agent-loader.js.map +1 -1
- package/dist/orchestrator/agentic-loop.d.ts +51 -0
- package/dist/orchestrator/agentic-loop.d.ts.map +1 -1
- package/dist/orchestrator/agentic-loop.js +123 -4
- package/dist/orchestrator/agentic-loop.js.map +1 -1
- package/dist/orchestrator/arch-lenses.d.ts +7 -0
- package/dist/orchestrator/arch-lenses.d.ts.map +1 -0
- package/dist/orchestrator/arch-lenses.js +22 -0
- package/dist/orchestrator/arch-lenses.js.map +1 -0
- package/dist/orchestrator/architect-agent.d.ts +16 -0
- package/dist/orchestrator/architect-agent.d.ts.map +1 -1
- package/dist/orchestrator/architect-agent.js +546 -9
- package/dist/orchestrator/architect-agent.js.map +1 -1
- package/dist/orchestrator/checkpoints/audit.d.ts +128 -0
- package/dist/orchestrator/checkpoints/audit.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/audit.js +272 -0
- package/dist/orchestrator/checkpoints/audit.js.map +1 -0
- package/dist/orchestrator/checkpoints/feedback-router.d.ts +213 -0
- package/dist/orchestrator/checkpoints/feedback-router.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/feedback-router.js +438 -0
- package/dist/orchestrator/checkpoints/feedback-router.js.map +1 -0
- package/dist/orchestrator/checkpoints/index.d.ts +11 -0
- package/dist/orchestrator/checkpoints/index.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/index.js +12 -0
- package/dist/orchestrator/checkpoints/index.js.map +1 -0
- package/dist/orchestrator/checkpoints/mechanisms/cli.d.ts +35 -0
- package/dist/orchestrator/checkpoints/mechanisms/cli.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/mechanisms/cli.js +153 -0
- package/dist/orchestrator/checkpoints/mechanisms/cli.js.map +1 -0
- package/dist/orchestrator/checkpoints/mechanisms/disk.d.ts +34 -0
- package/dist/orchestrator/checkpoints/mechanisms/disk.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/mechanisms/disk.js +139 -0
- package/dist/orchestrator/checkpoints/mechanisms/disk.js.map +1 -0
- package/dist/orchestrator/checkpoints/mechanisms/pr.d.ts +141 -0
- package/dist/orchestrator/checkpoints/mechanisms/pr.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/mechanisms/pr.js +445 -0
- package/dist/orchestrator/checkpoints/mechanisms/pr.js.map +1 -0
- package/dist/orchestrator/checkpoints/noop.d.ts +12 -0
- package/dist/orchestrator/checkpoints/noop.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/noop.js +13 -0
- package/dist/orchestrator/checkpoints/noop.js.map +1 -0
- package/dist/orchestrator/checkpoints/registry.d.ts +48 -0
- package/dist/orchestrator/checkpoints/registry.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/registry.js +89 -0
- package/dist/orchestrator/checkpoints/registry.js.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/_util.d.ts +50 -0
- package/dist/orchestrator/checkpoints/renderers/_util.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/_util.js +137 -0
- package/dist/orchestrator/checkpoints/renderers/_util.js.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/code-review.d.ts +15 -0
- package/dist/orchestrator/checkpoints/renderers/code-review.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/code-review.js +66 -0
- package/dist/orchestrator/checkpoints/renderers/code-review.js.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/curator-briefing.d.ts +15 -0
- package/dist/orchestrator/checkpoints/renderers/curator-briefing.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/curator-briefing.js +40 -0
- package/dist/orchestrator/checkpoints/renderers/curator-briefing.js.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/eval-result.d.ts +15 -0
- package/dist/orchestrator/checkpoints/renderers/eval-result.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/eval-result.js +54 -0
- package/dist/orchestrator/checkpoints/renderers/eval-result.js.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/generator-diff.d.ts +49 -0
- package/dist/orchestrator/checkpoints/renderers/generator-diff.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/generator-diff.js +154 -0
- package/dist/orchestrator/checkpoints/renderers/generator-diff.js.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/pipeline-summary.d.ts +15 -0
- package/dist/orchestrator/checkpoints/renderers/pipeline-summary.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/pipeline-summary.js +59 -0
- package/dist/orchestrator/checkpoints/renderers/pipeline-summary.js.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/plan.d.ts +15 -0
- package/dist/orchestrator/checkpoints/renderers/plan.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/plan.js +34 -0
- package/dist/orchestrator/checkpoints/renderers/plan.js.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/registry.d.ts +43 -0
- package/dist/orchestrator/checkpoints/renderers/registry.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/registry.js +83 -0
- package/dist/orchestrator/checkpoints/renderers/registry.js.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/research.d.ts +15 -0
- package/dist/orchestrator/checkpoints/renderers/research.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/research.js +39 -0
- package/dist/orchestrator/checkpoints/renderers/research.js.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/sprint-contract.d.ts +20 -0
- package/dist/orchestrator/checkpoints/renderers/sprint-contract.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/sprint-contract.js +57 -0
- package/dist/orchestrator/checkpoints/renderers/sprint-contract.js.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/sprint-summary.d.ts +15 -0
- package/dist/orchestrator/checkpoints/renderers/sprint-summary.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/renderers/sprint-summary.js +38 -0
- package/dist/orchestrator/checkpoints/renderers/sprint-summary.js.map +1 -0
- package/dist/orchestrator/checkpoints/sites.d.ts +22 -0
- package/dist/orchestrator/checkpoints/sites.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/sites.js +57 -0
- package/dist/orchestrator/checkpoints/sites.js.map +1 -0
- package/dist/orchestrator/checkpoints/types.d.ts +51 -0
- package/dist/orchestrator/checkpoints/types.d.ts.map +1 -0
- package/dist/orchestrator/checkpoints/types.js +9 -0
- package/dist/orchestrator/checkpoints/types.js.map +1 -0
- package/dist/orchestrator/code-reviewer-agent.d.ts +50 -0
- package/dist/orchestrator/code-reviewer-agent.d.ts.map +1 -0
- package/dist/orchestrator/code-reviewer-agent.js +283 -0
- package/dist/orchestrator/code-reviewer-agent.js.map +1 -0
- package/dist/orchestrator/curator-agent.d.ts.map +1 -1
- package/dist/orchestrator/curator-agent.js +60 -9
- package/dist/orchestrator/curator-agent.js.map +1 -1
- package/dist/orchestrator/deploy/classify.d.ts +31 -0
- package/dist/orchestrator/deploy/classify.d.ts.map +1 -0
- package/dist/orchestrator/deploy/classify.js +109 -0
- package/dist/orchestrator/deploy/classify.js.map +1 -0
- package/dist/orchestrator/deploy/execute.d.ts +45 -0
- package/dist/orchestrator/deploy/execute.d.ts.map +1 -0
- package/dist/orchestrator/deploy/execute.js +146 -0
- package/dist/orchestrator/deploy/execute.js.map +1 -0
- package/dist/orchestrator/deploy/executor.d.ts +22 -0
- package/dist/orchestrator/deploy/executor.d.ts.map +1 -0
- package/dist/orchestrator/deploy/executor.js +31 -0
- package/dist/orchestrator/deploy/executor.js.map +1 -0
- package/dist/orchestrator/deploy/index.d.ts +21 -0
- package/dist/orchestrator/deploy/index.d.ts.map +1 -0
- package/dist/orchestrator/deploy/index.js +21 -0
- package/dist/orchestrator/deploy/index.js.map +1 -0
- package/dist/orchestrator/deploy/resolve.d.ts +51 -0
- package/dist/orchestrator/deploy/resolve.d.ts.map +1 -0
- package/dist/orchestrator/deploy/resolve.js +53 -0
- package/dist/orchestrator/deploy/resolve.js.map +1 -0
- package/dist/orchestrator/deploy/spawn.d.ts +60 -0
- package/dist/orchestrator/deploy/spawn.d.ts.map +1 -0
- package/dist/orchestrator/deploy/spawn.js +62 -0
- package/dist/orchestrator/deploy/spawn.js.map +1 -0
- package/dist/orchestrator/deploy/types.d.ts +98 -0
- package/dist/orchestrator/deploy/types.d.ts.map +1 -0
- package/dist/orchestrator/deploy/types.js +39 -0
- package/dist/orchestrator/deploy/types.js.map +1 -0
- package/dist/orchestrator/documenter-agent.d.ts +57 -0
- package/dist/orchestrator/documenter-agent.d.ts.map +1 -0
- package/dist/orchestrator/documenter-agent.js +195 -0
- package/dist/orchestrator/documenter-agent.js.map +1 -0
- package/dist/orchestrator/environment.d.ts +45 -0
- package/dist/orchestrator/environment.d.ts.map +1 -0
- package/dist/orchestrator/environment.js +151 -0
- package/dist/orchestrator/environment.js.map +1 -0
- package/dist/orchestrator/eval-lenses.d.ts +7 -0
- package/dist/orchestrator/eval-lenses.d.ts.map +1 -0
- package/dist/orchestrator/eval-lenses.js +19 -0
- package/dist/orchestrator/eval-lenses.js.map +1 -0
- package/dist/orchestrator/eval-persist.d.ts +25 -0
- package/dist/orchestrator/eval-persist.d.ts.map +1 -0
- package/dist/orchestrator/eval-persist.js +74 -0
- package/dist/orchestrator/eval-persist.js.map +1 -0
- package/dist/orchestrator/evaluator-agent.d.ts +23 -0
- package/dist/orchestrator/evaluator-agent.d.ts.map +1 -1
- package/dist/orchestrator/evaluator-agent.js +80 -10
- package/dist/orchestrator/evaluator-agent.js.map +1 -1
- package/dist/orchestrator/generator-agent.d.ts.map +1 -1
- package/dist/orchestrator/generator-agent.js +53 -8
- package/dist/orchestrator/generator-agent.js.map +1 -1
- package/dist/orchestrator/memory/distill.d.ts +60 -0
- package/dist/orchestrator/memory/distill.d.ts.map +1 -0
- package/dist/orchestrator/memory/distill.js +177 -0
- package/dist/orchestrator/memory/distill.js.map +1 -0
- package/dist/orchestrator/memory/eval-source.d.ts +20 -0
- package/dist/orchestrator/memory/eval-source.d.ts.map +1 -0
- package/dist/orchestrator/memory/eval-source.js +88 -0
- package/dist/orchestrator/memory/eval-source.js.map +1 -0
- package/dist/orchestrator/memory/retrieve.d.ts +45 -0
- package/dist/orchestrator/memory/retrieve.d.ts.map +1 -0
- package/dist/orchestrator/memory/retrieve.js +102 -0
- package/dist/orchestrator/memory/retrieve.js.map +1 -0
- package/dist/orchestrator/model-resolver.d.ts.map +1 -1
- package/dist/orchestrator/model-resolver.js +15 -1
- package/dist/orchestrator/model-resolver.js.map +1 -1
- package/dist/orchestrator/observability/index.d.ts +12 -0
- package/dist/orchestrator/observability/index.d.ts.map +1 -0
- package/dist/orchestrator/observability/index.js +12 -0
- package/dist/orchestrator/observability/index.js.map +1 -0
- package/dist/orchestrator/observability/merge.d.ts +73 -0
- package/dist/orchestrator/observability/merge.d.ts.map +1 -0
- package/dist/orchestrator/observability/merge.js +110 -0
- package/dist/orchestrator/observability/merge.js.map +1 -0
- package/dist/orchestrator/pipeline.d.ts +31 -0
- package/dist/orchestrator/pipeline.d.ts.map +1 -1
- package/dist/orchestrator/pipeline.js +267 -5
- package/dist/orchestrator/pipeline.js.map +1 -1
- package/dist/orchestrator/planner-agent.d.ts +22 -1
- package/dist/orchestrator/planner-agent.d.ts.map +1 -1
- package/dist/orchestrator/planner-agent.js +165 -8
- package/dist/orchestrator/planner-agent.js.map +1 -1
- package/dist/orchestrator/research-agent.d.ts.map +1 -1
- package/dist/orchestrator/research-agent.js +48 -11
- package/dist/orchestrator/research-agent.js.map +1 -1
- package/dist/orchestrator/tools/handlers.d.ts +16 -0
- package/dist/orchestrator/tools/handlers.d.ts.map +1 -1
- package/dist/orchestrator/tools/handlers.js +30 -5
- package/dist/orchestrator/tools/handlers.js.map +1 -1
- package/dist/orchestrator/tools/index.d.ts +84 -1
- package/dist/orchestrator/tools/index.d.ts.map +1 -1
- package/dist/orchestrator/tools/index.js +164 -1
- package/dist/orchestrator/tools/index.js.map +1 -1
- package/dist/orchestrator/tools/schemas.js +5 -5
- package/dist/orchestrator/tools/schemas.js.map +1 -1
- package/dist/orchestrator/workflow/args-builder.d.ts +35 -0
- package/dist/orchestrator/workflow/args-builder.d.ts.map +1 -0
- package/dist/orchestrator/workflow/args-builder.js +142 -0
- package/dist/orchestrator/workflow/args-builder.js.map +1 -0
- package/dist/orchestrator/workflow/budget.d.ts +57 -0
- package/dist/orchestrator/workflow/budget.d.ts.map +1 -0
- package/dist/orchestrator/workflow/budget.js +80 -0
- package/dist/orchestrator/workflow/budget.js.map +1 -0
- package/dist/orchestrator/workflow/conformance.d.ts +27 -0
- package/dist/orchestrator/workflow/conformance.d.ts.map +1 -0
- package/dist/orchestrator/workflow/conformance.js +111 -0
- package/dist/orchestrator/workflow/conformance.js.map +1 -0
- package/dist/orchestrator/workflow/eligibility.d.ts +8 -0
- package/dist/orchestrator/workflow/eligibility.d.ts.map +1 -0
- package/dist/orchestrator/workflow/eligibility.js +10 -0
- package/dist/orchestrator/workflow/eligibility.js.map +1 -0
- package/dist/orchestrator/workflow/engine.d.ts +10 -0
- package/dist/orchestrator/workflow/engine.d.ts.map +1 -0
- package/dist/orchestrator/workflow/engine.js +2 -0
- package/dist/orchestrator/workflow/engine.js.map +1 -0
- package/dist/orchestrator/workflow/errors.d.ts +13 -0
- package/dist/orchestrator/workflow/errors.d.ts.map +1 -0
- package/dist/orchestrator/workflow/errors.js +26 -0
- package/dist/orchestrator/workflow/errors.js.map +1 -0
- package/dist/orchestrator/workflow/flusher.d.ts +19 -0
- package/dist/orchestrator/workflow/flusher.d.ts.map +1 -0
- package/dist/orchestrator/workflow/flusher.js +81 -0
- package/dist/orchestrator/workflow/flusher.js.map +1 -0
- package/dist/orchestrator/workflow/interpreter.d.ts +48 -0
- package/dist/orchestrator/workflow/interpreter.d.ts.map +1 -0
- package/dist/orchestrator/workflow/interpreter.js +92 -0
- package/dist/orchestrator/workflow/interpreter.js.map +1 -0
- package/dist/orchestrator/workflow/pure-sprint.d.ts +65 -0
- package/dist/orchestrator/workflow/pure-sprint.d.ts.map +1 -0
- package/dist/orchestrator/workflow/pure-sprint.js +82 -0
- package/dist/orchestrator/workflow/pure-sprint.js.map +1 -0
- package/dist/orchestrator/workflow/reconciler.d.ts +15 -0
- package/dist/orchestrator/workflow/reconciler.d.ts.map +1 -0
- package/dist/orchestrator/workflow/reconciler.js +65 -0
- package/dist/orchestrator/workflow/reconciler.js.map +1 -0
- package/dist/orchestrator/workflow/resume-cursor.d.ts +10 -0
- package/dist/orchestrator/workflow/resume-cursor.d.ts.map +1 -0
- package/dist/orchestrator/workflow/resume-cursor.js +25 -0
- package/dist/orchestrator/workflow/resume-cursor.js.map +1 -0
- package/dist/orchestrator/workflow/retry.d.ts +50 -0
- package/dist/orchestrator/workflow/retry.d.ts.map +1 -0
- package/dist/orchestrator/workflow/retry.js +100 -0
- package/dist/orchestrator/workflow/retry.js.map +1 -0
- package/dist/orchestrator/workflow/scheduler.d.ts +87 -0
- package/dist/orchestrator/workflow/scheduler.d.ts.map +1 -0
- package/dist/orchestrator/workflow/scheduler.js +158 -0
- package/dist/orchestrator/workflow/scheduler.js.map +1 -0
- package/dist/orchestrator/workflow/selector.d.ts +26 -0
- package/dist/orchestrator/workflow/selector.d.ts.map +1 -0
- package/dist/orchestrator/workflow/selector.js +54 -0
- package/dist/orchestrator/workflow/selector.js.map +1 -0
- package/dist/orchestrator/workflow/synthesizer.d.ts +52 -0
- package/dist/orchestrator/workflow/synthesizer.d.ts.map +1 -0
- package/dist/orchestrator/workflow/synthesizer.js +75 -0
- package/dist/orchestrator/workflow/synthesizer.js.map +1 -0
- package/dist/orchestrator/workflow/ts-engine.d.ts +13 -0
- package/dist/orchestrator/workflow/ts-engine.d.ts.map +1 -0
- package/dist/orchestrator/workflow/ts-engine.js +14 -0
- package/dist/orchestrator/workflow/ts-engine.js.map +1 -0
- package/dist/orchestrator/workflow/types.d.ts +55 -0
- package/dist/orchestrator/workflow/types.d.ts.map +1 -0
- package/dist/orchestrator/workflow/types.js +3 -0
- package/dist/orchestrator/workflow/types.js.map +1 -0
- package/dist/orchestrator/workflow/workflow-engine.d.ts +31 -0
- package/dist/orchestrator/workflow/workflow-engine.d.ts.map +1 -0
- package/dist/orchestrator/workflow/workflow-engine.js +70 -0
- package/dist/orchestrator/workflow/workflow-engine.js.map +1 -0
- package/dist/orchestrator/worktree.d.ts +18 -0
- package/dist/orchestrator/worktree.d.ts.map +1 -0
- package/dist/orchestrator/worktree.js +129 -0
- package/dist/orchestrator/worktree.js.map +1 -0
- package/dist/providers/anthropic.d.ts +8 -1
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/anthropic.js +135 -11
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/claude-code.d.ts +44 -0
- package/dist/providers/claude-code.d.ts.map +1 -0
- package/dist/providers/claude-code.js +143 -0
- package/dist/providers/claude-code.js.map +1 -0
- package/dist/providers/factory.d.ts +16 -2
- package/dist/providers/factory.d.ts.map +1 -1
- package/dist/providers/factory.js +101 -14
- package/dist/providers/factory.js.map +1 -1
- package/dist/providers/google.d.ts.map +1 -1
- package/dist/providers/google.js +32 -3
- package/dist/providers/google.js.map +1 -1
- package/dist/providers/index.d.ts +4 -2
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +3 -1
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/openai.d.ts.map +1 -1
- package/dist/providers/openai.js +28 -3
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/preflight.d.ts +22 -0
- package/dist/providers/preflight.d.ts.map +1 -0
- package/dist/providers/preflight.js +54 -0
- package/dist/providers/preflight.js.map +1 -0
- package/dist/providers/structured.d.ts +130 -0
- package/dist/providers/structured.d.ts.map +1 -0
- package/dist/providers/structured.js +205 -0
- package/dist/providers/structured.js.map +1 -0
- package/dist/providers/types.d.ts +53 -2
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/state/approval-state.d.ts +74 -0
- package/dist/state/approval-state.d.ts.map +1 -0
- package/dist/state/approval-state.js +127 -0
- package/dist/state/approval-state.js.map +1 -0
- package/dist/state/history-rotation.d.ts +17 -0
- package/dist/state/history-rotation.d.ts.map +1 -0
- package/dist/state/history-rotation.js +84 -0
- package/dist/state/history-rotation.js.map +1 -0
- package/dist/state/history.d.ts +16 -4
- package/dist/state/history.d.ts.map +1 -1
- package/dist/state/history.js +62 -20
- package/dist/state/history.js.map +1 -1
- package/dist/state/index.d.ts +4 -1
- package/dist/state/index.d.ts.map +1 -1
- package/dist/state/index.js +5 -2
- package/dist/state/index.js.map +1 -1
- package/dist/state/memory.d.ts +60 -0
- package/dist/state/memory.d.ts.map +1 -0
- package/dist/state/memory.js +242 -0
- package/dist/state/memory.js.map +1 -0
- package/dist/state/review-state.d.ts +15 -0
- package/dist/state/review-state.d.ts.map +1 -0
- package/dist/state/review-state.js +51 -0
- package/dist/state/review-state.js.map +1 -0
- package/dist/state/run-state.d.ts +39 -0
- package/dist/state/run-state.d.ts.map +1 -0
- package/dist/state/run-state.js +101 -0
- package/dist/state/run-state.js.map +1 -0
- package/dist/telemetry/emit.d.ts +41 -0
- package/dist/telemetry/emit.d.ts.map +1 -0
- package/dist/telemetry/emit.js +65 -0
- package/dist/telemetry/emit.js.map +1 -0
- package/dist/utils/git.d.ts +27 -0
- package/dist/utils/git.d.ts.map +1 -1
- package/dist/utils/git.js +50 -0
- package/dist/utils/git.js.map +1 -1
- package/hooks/hooks.json +27 -1
- package/hooks/session-start +42 -0
- package/package.json +13 -6
- package/scripts/check-prereqs.sh +12 -0
- package/scripts/e2e-graph-smoke.sh +167 -0
- package/scripts/graph-hook.mjs +151 -0
- package/scripts/run-kpi-gate.mjs +245 -0
- package/scripts/spike-claude-code-provider.mjs +66 -0
- package/scripts/spike-deepseek.mjs +63 -0
- package/scripts/sync-skills.mjs +4 -1
- package/scripts/sync-targets.json +12 -0
- package/scripts/update-all.mjs +255 -0
- package/skills/bober.architect/SKILL.md +13 -0
- package/skills/bober.architect/references/arch-lens-panel.md +126 -0
- package/skills/bober.code-review/SKILL.md +186 -0
- package/skills/bober.debug/SKILL.md +300 -0
- package/skills/bober.deploy/SKILL.md +262 -0
- package/skills/bober.diagnose/SKILL.md +254 -0
- package/skills/bober.eval/SKILL.md +9 -0
- package/skills/bober.eval/references/lens-panel.md +115 -0
- package/skills/bober.graph/SKILL.md +85 -0
- package/skills/bober.impact/SKILL.md +101 -0
- package/skills/bober.incident/SKILL.md +245 -0
- package/skills/bober.onboard/SKILL.md +84 -0
- package/skills/bober.plan/SKILL.md +16 -0
- package/skills/bober.postmortem/SKILL.md +231 -0
- package/skills/bober.run/SKILL.md +23 -4
- package/skills/bober.run/references/lens-panel.md +115 -0
- package/skills/bober.runbook/SKILL.md +335 -0
- package/skills/bober.sprint/SKILL.md +44 -2
- package/skills/bober.sprint/references/lens-panel.md +115 -0
- package/skills/bober.using-bober/SKILL.md +133 -0
- package/skills/bober.verify/SKILL.md +143 -0
- package/skills/shared/arch-lens-panel.md +126 -0
- package/skills/shared/lens-panel.md +115 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Lens Panel — Canonical Protocol Reference
|
|
2
|
+
|
|
3
|
+
This document is the single source of truth for native panel orchestration in agent-bober.
|
|
4
|
+
It embeds the five canonical lens focus fragments verbatim from
|
|
5
|
+
`src/orchestrator/eval-lenses.ts` (the `LENS_CATALOG` literal) and documents the
|
|
6
|
+
split fan-out, majority-vote/fail-closed reconciliation, and the `lensVerdicts` output shape.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Lens Focus Fragments
|
|
11
|
+
|
|
12
|
+
The following fragments are the exact strings returned by `resolveLensFocus(lens)` for each
|
|
13
|
+
built-in lens. They MUST remain byte-for-byte identical to the corresponding entries in
|
|
14
|
+
`LENS_CATALOG` — the drift gate (`src/orchestrator/lens-panel-parity.test.ts`) enforces this.
|
|
15
|
+
|
|
16
|
+
### correctness
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
Focus on whether the implementation actually satisfies each success criterion verbatim. Check that all required behaviours exist, all edge cases are handled, and the contract's definitionOfDone is met.
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### security
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
Focus on injection vulnerabilities, authentication and authorisation gaps, secret handling, unsafe input validation, and any path traversal or privilege escalation risks.
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### regression
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
Focus on whether previously working behaviour still works after the changes. Verify that pre-existing tests pass, that no public API or config interface was broken, and that the sprint diff does not silently remove functionality.
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### quality
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
Focus on principles violations, dead code, misleading naming, smells, duplicated logic, and whether the implementation follows the project's established patterns and conventions.
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### simplicity
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
Focus exclusively on over-engineering in the production code: logic that reinvents the standard library, dependencies or hand-rolled code doing what a native platform feature already provides, abstractions with a single implementation, configuration nobody reads, dead flexibility, and code expressible in materially fewer lines. For each, name the location, what to cut, and what replaces it. Never flag tests, assertion-based self-checks, input validation at trust boundaries, error handling, security measures, or accessibility as deletable — minimalism governs production code, never the verification or safety discipline.
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
> The `simplicity` lens is the complexity-only counterpart to `quality`. `quality` asks
|
|
47
|
+
> "does this follow our patterns and is it free of smells?"; `simplicity` asks "what can be
|
|
48
|
+
> deleted, replaced by stdlib/native, or shrunk?" — and is forbidden from ever recommending the
|
|
49
|
+
> removal of a test, a validation, or a safety measure. It pairs cleanly with the evaluator's
|
|
50
|
+
> test/verification Iron Law: minimalism governs what is built, never what is verified.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Native Panel Protocol
|
|
55
|
+
|
|
56
|
+
### Split Fan-out
|
|
57
|
+
|
|
58
|
+
When the native panel is active, the orchestrator spawns evaluators in two passes:
|
|
59
|
+
|
|
60
|
+
1. **Deterministic evaluator (one instance):** runs the configured strategy suite exactly once
|
|
61
|
+
(build, typecheck, lint, unit-test, playwright, api-check, etc.). This produces the
|
|
62
|
+
deterministic verdict — objective, tool-based checks that do not depend on lens focus.
|
|
63
|
+
|
|
64
|
+
2. **Qualitative evaluators (one per configured lens):** each evaluator receives the same
|
|
65
|
+
sprint diff and context but is instructed to judge the contract's success criteria
|
|
66
|
+
exclusively through its lens focus fragment. The strategy suite is **not** re-run for
|
|
67
|
+
these evaluators — they perform qualitative assessment only, using the results already
|
|
68
|
+
collected by the deterministic evaluator as supporting context.
|
|
69
|
+
|
|
70
|
+
This split ensures strategies execute once (no duplicate CI cost) while each lens evaluates
|
|
71
|
+
the diff independently.
|
|
72
|
+
|
|
73
|
+
### Reconciliation — Majority Vote, Fail-Closed
|
|
74
|
+
|
|
75
|
+
The lens verdicts are reconciled by `reconcile()` in
|
|
76
|
+
`src/orchestrator/workflow/reconciler.ts` using the following semantics:
|
|
77
|
+
|
|
78
|
+
- **Inputs:** the array of per-lens `EvalResult` objects (`lensVerdicts`).
|
|
79
|
+
- **Require non-empty:** an empty array throws `"reconcile: lensVerdicts must be non-empty"`.
|
|
80
|
+
- **Vote count:** `passCount` = number of lenses where `passed === true`;
|
|
81
|
+
`failCount` = total − passCount.
|
|
82
|
+
- **Verdict:** `passed = passCount > failCount` (strict majority).
|
|
83
|
+
- **Fail-closed on tie:** when `passCount === failCount` the panel verdict is `false`.
|
|
84
|
+
- **Details:** union of all failing lens details, de-duplicated by `(criterion, message)` key.
|
|
85
|
+
- **Feedback:** failing lenses' feedback joined with `\n`; `"All lenses passed."` when all pass.
|
|
86
|
+
- **Summary:** `"Panel verdict: ${passCount}/${n} lenses passed"`.
|
|
87
|
+
- **Score:** `Math.round((100 * passCount) / n)`.
|
|
88
|
+
- **Evaluator tag:** `evaluator = "panel"`.
|
|
89
|
+
- **Timestamp:** echoed verbatim from the input argument (pure function, ADR-4).
|
|
90
|
+
|
|
91
|
+
### Combine
|
|
92
|
+
|
|
93
|
+
The final sprint verdict combines both passes:
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
final.passed = deterministic.passed && reconciled.passed
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Both must pass for the sprint to be accepted.
|
|
100
|
+
|
|
101
|
+
### lensVerdicts Output Shape
|
|
102
|
+
|
|
103
|
+
After reconciliation the orchestrator writes a `lensVerdicts` array into the saved
|
|
104
|
+
`EvalResult` JSON and sets `evaluator = "panel"`. The array shape is:
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
lensVerdicts: Array<{
|
|
108
|
+
lens: string; // e.g. "correctness", "security", "regression", "quality", "simplicity"
|
|
109
|
+
passed: boolean; // individual lens verdict
|
|
110
|
+
summary: string; // per-lens summary from the qualitative evaluator
|
|
111
|
+
}>
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
This field is optional and backward-compatible: eval results produced before the panel
|
|
115
|
+
feature (or by non-panel evaluators) simply omit it.
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bober-runbook
|
|
3
|
+
description: Use when executing a runbook or step-by-step recovery procedure — verify precondition before each step, execute, verify postcondition before advancing; hard gate around destructive operations
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
> Adapted from [obra/superpowers](https://github.com/obra/superpowers) — MIT License.
|
|
7
|
+
> Structural source: verification-before-completion discipline (precondition → execute → postcondition loop).
|
|
8
|
+
> Adaptations: applied to runbook step execution; explicit hard gate around steps with blastRadius='risky'; rollback cascade for postcondition failures.
|
|
9
|
+
|
|
10
|
+
# Runbook Execution Discipline
|
|
11
|
+
|
|
12
|
+
## Overview
|
|
13
|
+
|
|
14
|
+
A runbook is a contract between the author and the executor: each step asserts what must be true before it runs and what must be true after. Blindly running steps without verification turns a recovery procedure into a second incident. A step that succeeds silently while leaving the system in an unexpected state is MORE dangerous than a step that fails loudly.
|
|
15
|
+
|
|
16
|
+
**Core principle:** ALWAYS verify the precondition before executing each step, and the postcondition before advancing.
|
|
17
|
+
|
|
18
|
+
**Violating the letter of this process is violating the spirit of incident recovery.**
|
|
19
|
+
|
|
20
|
+
## The Iron Law
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
NO STEP EXECUTION WITHOUT VERIFIED PRECONDITION; NO ADVANCE WITHOUT VERIFIED POSTCONDITION
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
A runbook is a contract: each step asserts what must be true BEFORE it runs and what must be true AFTER. Executing without verifying preconditions makes the incident worse. Advancing without verifying postconditions hides failures that the next step assumes have been handled.
|
|
27
|
+
|
|
28
|
+
## When to Use
|
|
29
|
+
|
|
30
|
+
Use for ANY step-by-step operational procedure:
|
|
31
|
+
- Recovering from a production incident via a named runbook
|
|
32
|
+
- Following a disaster-recovery procedure
|
|
33
|
+
- Executing a curated playbook from `.bober/playbooks/`
|
|
34
|
+
- Rolling back a deployment via prescribed steps
|
|
35
|
+
- Running a database migration procedure
|
|
36
|
+
- Applying a pre-approved scaling policy
|
|
37
|
+
|
|
38
|
+
**Use this ESPECIALLY when:**
|
|
39
|
+
- An incident is active and seconds count (pressure makes step-skipping tempting)
|
|
40
|
+
- The runbook author is not in the room to answer questions
|
|
41
|
+
- The procedure involves destructive or stateful operations
|
|
42
|
+
- You are executing a runbook you have never run before in production
|
|
43
|
+
|
|
44
|
+
**Don't skip when:**
|
|
45
|
+
- "Everyone knows this runbook" — tribal knowledge is not a verified precondition
|
|
46
|
+
- "We ran it last week and it was fine" — system state changes; the precondition may no longer hold
|
|
47
|
+
- "The operator says skip the precondition" — the Iron Law is not advisory; get an explicit checkpoint approval if you must proceed without a check
|
|
48
|
+
|
|
49
|
+
## Runbook Parse Format
|
|
50
|
+
|
|
51
|
+
A runbook is a markdown file with YAML frontmatter and numbered step sections.
|
|
52
|
+
|
|
53
|
+
**Frontmatter:**
|
|
54
|
+
|
|
55
|
+
```yaml
|
|
56
|
+
---
|
|
57
|
+
name: <kebab-case runbook name>
|
|
58
|
+
classification: standard | emergency
|
|
59
|
+
prerequisites:
|
|
60
|
+
- <human-readable prerequisite>
|
|
61
|
+
- <another prerequisite>
|
|
62
|
+
---
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Each step section:**
|
|
66
|
+
|
|
67
|
+
- `## Step <N>: <description>` — H2 with step number and one-line description
|
|
68
|
+
- `blastRadius: safe | risky` — REQUIRED. `safe` = read-only or trivially reversible (e.g., a kubectl get, a feature flag flip back to default). `risky` = stateful, destructive, externally-observable (e.g., kubectl scale, kubectl rollout, terraform apply, db migration).
|
|
69
|
+
- `precondition-check:` — REQUIRED. A bulleted list of conditions to verify BEFORE the step runs. Each bullet is either a concrete command (e.g., `kubectl get deployment api -o json | jq .spec.replicas — value is 3`) or a human-readable check (e.g., `acknowledgement received in channel`).
|
|
70
|
+
- `execute:` — REQUIRED. A bulleted list of the actual operation. For safe steps, may be a single command. For risky steps, ALWAYS a single command (multi-command risky steps must be split into separate numbered steps so each gets its own checkpoint).
|
|
71
|
+
- `postcondition-check:` — REQUIRED. A bulleted list of conditions to verify AFTER the step runs. Same format as precondition.
|
|
72
|
+
- `rollback:` — OPTIONAL. A bulleted list of operations to run if postcondition-check fails. If omitted, postcondition failure triggers immediate escalation (see Rollback Cascade).
|
|
73
|
+
|
|
74
|
+
**Worked frontmatter + two-step example:**
|
|
75
|
+
|
|
76
|
+
~~~markdown
|
|
77
|
+
---
|
|
78
|
+
name: high-error-rate-recovery
|
|
79
|
+
classification: emergency
|
|
80
|
+
prerequisites:
|
|
81
|
+
- logged in as production-on-call
|
|
82
|
+
- error rate observable in obs__datadog
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Step 1: Confirm error rate exceeded threshold
|
|
86
|
+
blastRadius: safe
|
|
87
|
+
|
|
88
|
+
precondition-check:
|
|
89
|
+
- Read obs__datadog metric `api.error_rate`; current value > 1% for >= 5 minutes
|
|
90
|
+
|
|
91
|
+
execute:
|
|
92
|
+
- (description only) Open the runbook approver in the team channel
|
|
93
|
+
|
|
94
|
+
postcondition-check:
|
|
95
|
+
- Acknowledgement received in channel from at least one approver
|
|
96
|
+
|
|
97
|
+
## Step 2: Scale up replicas
|
|
98
|
+
blastRadius: risky # destructive — requires checkpoint approval
|
|
99
|
+
|
|
100
|
+
precondition-check:
|
|
101
|
+
- kubectl get deployment api-service -o json | jq .spec.replicas — value is 3
|
|
102
|
+
|
|
103
|
+
execute:
|
|
104
|
+
- kubectl scale deployment api-service --replicas=6
|
|
105
|
+
|
|
106
|
+
postcondition-check:
|
|
107
|
+
- kubectl get pods -l app=api-service -o json | jq '.items | map(select(.status.phase=="Running")) | length' — value is 6
|
|
108
|
+
|
|
109
|
+
rollback:
|
|
110
|
+
- kubectl scale deployment api-service --replicas=3
|
|
111
|
+
~~~
|
|
112
|
+
|
|
113
|
+
<EXTREMELY-IMPORTANT>
|
|
114
|
+
BEFORE executing the first step, you MUST parse the runbook end-to-end and verify every step has a precondition-check and a postcondition-check declared. A runbook with an undeclared precondition-check on ANY step is malformed — abort and escalate via checkpoint. Do NOT silently default to "no check" — the absence of a check is a parse-time failure, not a runtime convenience.
|
|
115
|
+
</EXTREMELY-IMPORTANT>
|
|
116
|
+
|
|
117
|
+
## Execution Discipline
|
|
118
|
+
|
|
119
|
+
For each step in the runbook, run the four-stage loop. Do not skip stages. Do not reorder.
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
FOR each step IN runbook:
|
|
123
|
+
RUN precondition-check
|
|
124
|
+
IF precondition fails: STOP, report 'precondition_failed', do not advance
|
|
125
|
+
IF step.blastRadius == 'risky':
|
|
126
|
+
INVOKE checkpoint(pre-execute) — even in autopilot mode
|
|
127
|
+
IF checkpoint rejected: STOP, abort runbook
|
|
128
|
+
EXECUTE step (command, or await human action via checkpoint if description-only)
|
|
129
|
+
RUN postcondition-check
|
|
130
|
+
IF postcondition fails:
|
|
131
|
+
IF step.rollback defined: EXECUTE rollback
|
|
132
|
+
IF rollback postcondition still fails: ESCALATE via checkpoint, STOP
|
|
133
|
+
IF rollback NOT defined: ESCALATE via checkpoint, STOP
|
|
134
|
+
ADVANCE to next step
|
|
135
|
+
MARK runbook complete; write summary entry to .bober/incidents/<id>/runbook-execution.jsonl
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**STOP conditions enumerated:**
|
|
139
|
+
|
|
140
|
+
- **Precondition fails** → STOP. Write `{status: 'precondition_failed'}` to runbook-execution.jsonl. Do NOT execute.
|
|
141
|
+
- **Risky-step checkpoint rejected** → STOP. Write `{status: 'checkpoint_rejected'}`. Do NOT execute.
|
|
142
|
+
- **Step execution errors** → STOP. Write `{status: 'execution_failed'}`. Trigger rollback if defined; otherwise escalate.
|
|
143
|
+
- **Postcondition fails AND rollback fails (or no rollback)** → STOP. Write `{status: 'rollback_failed'}` (or `{status: 'postcondition_failed_no_rollback'}`). Escalate via checkpoint.
|
|
144
|
+
|
|
145
|
+
ADVANCE happens ONLY when the postcondition-check explicitly passes. Default behavior on uncertainty is STOP, not ADVANCE.
|
|
146
|
+
|
|
147
|
+
## Hard Gate — Risky Steps
|
|
148
|
+
|
|
149
|
+
Any step with `blastRadius: 'risky'` MUST invoke the Tier 2 checkpoint mechanism before execution. This is UNCONDITIONAL:
|
|
150
|
+
|
|
151
|
+
- **`pipeline.mode='autopilot'` does NOT bypass risky-step approval.** Autopilot trades human-in-the-loop for speed on SAFE steps; the risky-step gate is the production safety floor and does not move.
|
|
152
|
+
- **`pipeline.checkpointMechanism='noop'` does NOT apply to risky steps.** When the configured mechanism is `noop` but the step is risky, the runbook executor uses the default `disk` fallback (Sprint 13's checkpoint mechanism). The gate cannot be configured away.
|
|
153
|
+
- **Multi-command bash invocations do NOT slip through the gate.** A step that wraps `kubectl scale` inside `echo 'safe' && kubectl scale ...` is classified by COMMAND content, not by step authorship. The classifier checks for state-mutating verbs in the entire command string.
|
|
154
|
+
|
|
155
|
+
The gate receives the step's classification reasoning, the proposed command, and the declared rollback. The operator can approve, reject, or modify (the modification is recorded in `changelog.jsonl` via Sprint 19's `appendChange` with the required `inverse` field).
|
|
156
|
+
|
|
157
|
+
<EXTREMELY-IMPORTANT>
|
|
158
|
+
Risky steps invoke the Tier 2 checkpoint mechanism regardless of pipeline.mode. Autopilot mode does NOT bypass risky-step approval. If `pipeline.mode='autopilot'` and `pipeline.checkpointMechanism='noop'`, the runbook executor STILL invokes a non-noop mechanism (default 'disk' fallback) for any step with `blastRadius: 'risky'`. This is the production safety guarantee — bypassing it forfeits the guarantee.
|
|
159
|
+
</EXTREMELY-IMPORTANT>
|
|
160
|
+
|
|
161
|
+
The escape hatch — `pipeline.allowAutopilotRiskyActions=true` — is documented in `skills/bober.deploy/SKILL.md` (Sprint 20) and exists for fully-automated environments (CI, batch jobs) where no human is available. Default `false`. When set to `true`, risky steps are auto-approved BUT a stern warning is logged and the `ChangeEntry` is still recorded with the required `inverse`. This is "skip the interactive approval" — NOT "skip the audit trail."
|
|
162
|
+
|
|
163
|
+
## Rollback Cascade
|
|
164
|
+
|
|
165
|
+
When a step's postcondition-check fails, the runbook executor follows a three-tier cascade. Each tier MUST be exhausted before falling to the next.
|
|
166
|
+
|
|
167
|
+
**Tier 1 — Run the declared rollback (if any).**
|
|
168
|
+
The rollback is itself a mini-step: it has an `execute` command and an implicit postcondition (the inverse of the failed step's postcondition). Run the rollback command. Then check whether the rollback's effect held — for example, if the original step scaled to 6 replicas and failed, the rollback `kubectl scale --replicas=3` is verified by `kubectl get deployment ... | jq .spec.replicas == 3`.
|
|
169
|
+
|
|
170
|
+
**Tier 2 — If rollback fails OR no rollback was declared, escalate via checkpoint.**
|
|
171
|
+
The checkpoint payload includes: the failed step number, the postcondition-check result, the rollback-attempt result (if attempted), and the current observable state. The operator (or the configured escalation handler) decides the next move — manual intervention, abort, or override.
|
|
172
|
+
|
|
173
|
+
**Tier 3 — Write the indeterminate state to the observation log and STOP the runbook.**
|
|
174
|
+
Regardless of which tier resolved (or did not resolve) the failure, append a complete record to `.bober/incidents/<id>/runbook-execution.jsonl` with `rollbackTriggered: true` (Tier 1 ran) and `status: 'rollback_failed' | 'escalated' | 'recovered_via_rollback'` as appropriate. Do NOT continue with subsequent steps — their preconditions assume the failed step's postcondition held, which it did not.
|
|
175
|
+
|
|
176
|
+
<EXTREMELY-IMPORTANT>
|
|
177
|
+
If a step's postcondition fails AND its declared rollback ALSO fails (or no rollback was declared), the runbook executor MUST escalate via the Tier 2 checkpoint mechanism — do not silently proceed, do not retry the failed step. The incident state is now indeterminate; only a human (or the configured escalation handler) can decide the next move.
|
|
178
|
+
</EXTREMELY-IMPORTANT>
|
|
179
|
+
|
|
180
|
+
## Observation Log
|
|
181
|
+
|
|
182
|
+
Every step execution writes one line to `.bober/incidents/<id>/runbook-execution.jsonl`. Sprint 19's `appendRunbookExecution` helper provides the write primitive; this skill documents the schema.
|
|
183
|
+
|
|
184
|
+
**Line shape:**
|
|
185
|
+
|
|
186
|
+
```json
|
|
187
|
+
{
|
|
188
|
+
"timestamp": "<ISO-8601, when the step completed (or failed)>",
|
|
189
|
+
"runbookName": "<frontmatter name from the runbook file>",
|
|
190
|
+
"stepNumber": "<integer, 1-indexed from the H2 ## Step N: ...>",
|
|
191
|
+
"status": "'precondition_failed' | 'checkpoint_rejected' | 'execution_failed' | 'postcondition_failed_no_rollback' | 'rollback_failed' | 'recovered_via_rollback' | 'success'",
|
|
192
|
+
"preconditionResult": "'pass' | 'fail' | 'not_run'",
|
|
193
|
+
"postconditionResult": "'pass' | 'fail' | 'not_run'",
|
|
194
|
+
"rollbackTriggered": "<boolean — true if Tier 1 of the cascade ran, false or omitted otherwise>"
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
**Worked log entries (one runbook execution, three steps):**
|
|
199
|
+
|
|
200
|
+
```jsonl
|
|
201
|
+
{"timestamp": "2026-05-24T14:10:00Z", "runbookName": "high-error-rate-recovery", "stepNumber": 1, "status": "success", "preconditionResult": "pass", "postconditionResult": "pass"}
|
|
202
|
+
{"timestamp": "2026-05-24T14:12:00Z", "runbookName": "high-error-rate-recovery", "stepNumber": 2, "status": "success", "preconditionResult": "pass", "postconditionResult": "pass"}
|
|
203
|
+
{"timestamp": "2026-05-24T14:15:00Z", "runbookName": "high-error-rate-recovery", "stepNumber": 3, "status": "recovered_via_rollback", "preconditionResult": "pass", "postconditionResult": "fail", "rollbackTriggered": true}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
The timeline.jsonl (Sprint 19) ALSO gains a corresponding line per step via Sprint 19's pattern that "every other append helper ALSO writes a corresponding timeline event." Operators get a chronological view via `cat timeline.jsonl`, and a runbook-specific view via `cat runbook-execution.jsonl`.
|
|
207
|
+
|
|
208
|
+
**Field-name lock:** The exact 7 field names above (`timestamp, runbookName, stepNumber, status, preconditionResult, postconditionResult, rollbackTriggered`) are the schema Sprint 19's writer will use. Do NOT introduce field-name variants — `step_number` vs `stepNumber`, `runbook_name` vs `runbookName` — schema drift between sprints breaks the timeline.
|
|
209
|
+
|
|
210
|
+
## Worked Example — Recovering from API Error Spike
|
|
211
|
+
|
|
212
|
+
A worked end-to-end execution of `high-error-rate-recovery` (the runbook in §Runbook Parse Format).
|
|
213
|
+
|
|
214
|
+
**Setup:** Datadog alert fires at 14:00 UTC. `api.error_rate` at 4.2%. Diagnoser (via `bober.diagnose` Phase 1-3) hypothesizes "replicas exhausted under load, scaling up will relieve pressure." `nextActions[0]` is `{action: "follow runbook high-error-rate-recovery", blastRadius: "risky", requiresApproval: true}`. Orchestrator invokes this skill.
|
|
215
|
+
|
|
216
|
+
**Step 1 — Confirm error rate exceeded threshold (`blastRadius: safe`):**
|
|
217
|
+
|
|
218
|
+
Precondition-check:
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
$ curl -s "https://datadog/api/v1/query?query=avg:api.error_rate{*}&from=now-5m" | jq .series[0].pointlist[-1][1]
|
|
222
|
+
0.042 # 4.2% > 1% threshold — PASS
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Execute (description-only): "Open the runbook approver in the team channel" — agent awaits human action via checkpoint.
|
|
226
|
+
|
|
227
|
+
Postcondition-check:
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
$ grep -c "approved" /tmp/channel-acks.log
|
|
231
|
+
1 # at least one approver — PASS
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Status: `success`. ADVANCE to Step 2.
|
|
235
|
+
|
|
236
|
+
**Step 2 — Scale up replicas (`blastRadius: risky`):**
|
|
237
|
+
|
|
238
|
+
Precondition-check:
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
$ kubectl get deployment api-service -o json | jq .spec.replicas
|
|
242
|
+
3 # matches expected — PASS
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
**Risky step — HARD GATE invoked.** Even though `pipeline.mode='autopilot'`, the checkpoint mechanism (default 'disk' fallback because configured 'noop' is overridden for risky steps) presents the action to the operator. Payload includes:
|
|
246
|
+
- Action: `kubectl scale deployment api-service --replicas=6`
|
|
247
|
+
- Classification reasoning: scale operation is stateful + externally-observable
|
|
248
|
+
- Proposed rollback: `kubectl scale deployment api-service --replicas=3`
|
|
249
|
+
|
|
250
|
+
Operator approves. Step executes.
|
|
251
|
+
|
|
252
|
+
Execute:
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
$ kubectl scale deployment api-service --replicas=6
|
|
256
|
+
deployment.apps/api-service scaled
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
Postcondition-check:
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
$ kubectl get pods -l app=api-service -o json | jq '.items | map(select(.status.phase=="Running")) | length'
|
|
263
|
+
6 # 6 pods Ready — PASS
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
Status: `success`. ADVANCE.
|
|
267
|
+
|
|
268
|
+
**Log entries written:**
|
|
269
|
+
|
|
270
|
+
```jsonl
|
|
271
|
+
{"timestamp": "2026-05-24T14:11:00Z", "runbookName": "high-error-rate-recovery", "stepNumber": 1, "status": "success", "preconditionResult": "pass", "postconditionResult": "pass"}
|
|
272
|
+
{"timestamp": "2026-05-24T14:14:00Z", "runbookName": "high-error-rate-recovery", "stepNumber": 2, "status": "success", "preconditionResult": "pass", "postconditionResult": "pass"}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
**Counter-example — rollback cascade in action.** Suppose Step 2's postcondition had returned `4` (only 4 pods Running). The runbook executor would:
|
|
276
|
+
|
|
277
|
+
1. Run rollback `kubectl scale deployment api-service --replicas=3`.
|
|
278
|
+
2. Verify rollback's effect: `kubectl get deployment api-service -o json | jq .spec.replicas == 3` → PASS.
|
|
279
|
+
3. Write `{status: "recovered_via_rollback", rollbackTriggered: true, ...}` and STOP.
|
|
280
|
+
|
|
281
|
+
If the rollback ITSELF had failed (e.g., kubectl API errored), the executor escalates via checkpoint with `{status: "rollback_failed", rollbackTriggered: true, ...}` and STOPs. The operator decides next move; the runbook does NOT continue.
|
|
282
|
+
|
|
283
|
+
## Red Flags - STOP and Follow Process
|
|
284
|
+
|
|
285
|
+
If you catch yourself thinking:
|
|
286
|
+
- "The precondition check is obvious, just run the step"
|
|
287
|
+
- "The postcondition is just a sanity check, advance anyway"
|
|
288
|
+
- "It's a small scale-up, skip the checkpoint"
|
|
289
|
+
- "The rollback should be safe to skip, the change was tiny"
|
|
290
|
+
- "Autopilot mode said skip approval"
|
|
291
|
+
- "The step failed but the next one might fix it, try advancing"
|
|
292
|
+
- "No rollback declared, that means it's safe to skip the cascade"
|
|
293
|
+
- "The runbook is in the playbook library so it must be safe"
|
|
294
|
+
- "Precondition timed out, retry without checking"
|
|
295
|
+
- Advancing to the next step without an explicit postcondition PASS result
|
|
296
|
+
- **"No time to check preconditions, the incident is live"**
|
|
297
|
+
|
|
298
|
+
**ALL of these mean: STOP. Return to the verification loop — parse, check, execute, verify.**
|
|
299
|
+
|
|
300
|
+
## Common Rationalizations
|
|
301
|
+
|
|
302
|
+
| Excuse | Reality |
|
|
303
|
+
|--------|---------|
|
|
304
|
+
| "The precondition is just paperwork, the team always runs this step without checking" | Tribal-knowledge preconditions are precisely what the runbook formalizes. Run the check — if it's always true, it costs nothing; if it's not always true, you just averted an incident. |
|
|
305
|
+
| "The postcondition can be verified later, we're behind schedule" | Postcondition deferred is postcondition skipped. The next step's precondition assumes this step's postcondition held. Defer the verification, defer the failure into a worse moment. |
|
|
306
|
+
| "Autopilot mode is explicitly opt-in for trusted runbooks" | Autopilot mode trades human-in-the-loop for speed on SAFE steps. Risky-step approval is the safety floor — autopilot does NOT bypass it. Read the Iron Law again. |
|
|
307
|
+
| "Rollback failed but the system looks fine, mark step complete" | If the rollback failed, you do not know the system state. "Looks fine" is not state knowledge. Escalate via checkpoint — the operator decides whether to mark complete or treat as undetermined. |
|
|
308
|
+
| "No rollback declared because the step is reversible by retrying" | Retry-as-rollback is acceptable ONLY when declared as the rollback. An undeclared "we'll just retry" is implicit state, not a recoverable plan. Declare the rollback at runbook-write time. |
|
|
309
|
+
| "The runbook came from the playbook library, trust the author" | Trust the discipline, not the author. The parse format and the four-stage loop apply to every runbook regardless of author. The library passed review for SHAPE, not for situation fit. |
|
|
310
|
+
| "The step is idempotent so skipping the precondition is harmless" | Idempotency is a property of the happy path. An idempotent step run against an unexpected precondition state is NOT guaranteed idempotent — the precondition defines the state the idempotency guarantee assumes. |
|
|
311
|
+
| "It worked in staging, precondition must be fine" | Staging is a hypothesis about production state, not a verification. The precondition-check runs in production, against production state, immediately before the step executes. Staging results are not portable. |
|
|
312
|
+
|
|
313
|
+
## Quick Reference
|
|
314
|
+
|
|
315
|
+
| Stage | Key Activities | Success Criteria |
|
|
316
|
+
|-------|---------------|------------------|
|
|
317
|
+
| **1. Parse** | Read frontmatter (name, classification, prerequisites); enumerate steps; verify each step has precondition-check + postcondition-check + blastRadius | Runbook is structurally valid; no undeclared checks |
|
|
318
|
+
| **2. Precondition** | Run precondition-check command (or read the condition); compare to expected state | Result matches expected; otherwise STOP |
|
|
319
|
+
| **3. Execute** | If step is risky → invoke Tier 2 checkpoint (regardless of pipeline.mode); on approval, run the step's command (or await human action) | Step ran without error |
|
|
320
|
+
| **4. Postcondition** | Run postcondition-check; if pass → advance; if fail → run rollback; if rollback also fails → escalate via checkpoint | Either step's postcondition holds OR rollback's postcondition holds OR escalation triggered |
|
|
321
|
+
|
|
322
|
+
## Related Skills
|
|
323
|
+
|
|
324
|
+
- **`bober.diagnose`** (`skills/bober.diagnose/SKILL.md`, Sprint 17) — Upstream skill. The diagnoser identifies "follow runbook X" as a next-action; that next-action is then executed under this skill's discipline. Diagnose says WHAT to do; runbook says HOW to do each step safely.
|
|
325
|
+
- **`bober.deploy`** (`skills/bober.deploy/SKILL.md`, Sprint 20) — Downstream execution wiring. `bober.deploy` is the agent-level execution discipline (action classification, checkpoint gate enforcement, ChangeEntry recording with required inverse). `bober.runbook` is the operator-level discipline for executing a step-by-step procedure; `bober.deploy` is what actually runs the risky step. Risky steps in this skill DELEGATE to `agents/bober-deployer.md` for execution.
|
|
326
|
+
- **`.bober/playbooks/`** (Sprint 25) — Library of curated runbooks (`build-failure.md`, `migration-timeout.md`, `error-spike.md`, `latency-regression.md`). Each playbook MUST conform to the parse format documented in this skill. The diagnoser invokes `searchPlaybooks(symptom)` to find a matching playbook; matched playbooks are executed under this skill's discipline.
|
|
327
|
+
- **`.bober/anti-patterns/`** — Pattern catalog. Two anti-patterns are especially common in runbook execution: **Single-Layer Validation** (`defense-in-depth.md` — postcondition skipped because step "looked successful") and **Symptom-Fix Instead of Root-Cause** (`root-cause-tracing.md` — running a recovery runbook to mask an underlying defect).
|
|
328
|
+
|
|
329
|
+
## Real-World Impact
|
|
330
|
+
|
|
331
|
+
From incident response patterns:
|
|
332
|
+
- Runbook execution with pre/post verification: regressions caught at the step boundary, not as downstream failures
|
|
333
|
+
- Runbook execution without postcondition checks: failures propagate silently, next-step preconditions assume state that no longer exists
|
|
334
|
+
- Risky steps with hard-gate enforcement: blast radius contained to the declared scope of the step
|
|
335
|
+
- Risky steps executed without approval in autopilot mode: unreviewed changes to production infrastructure with no audit trail
|
|
@@ -283,6 +283,15 @@ When done, respond with EXACTLY this JSON structure (no other text):
|
|
|
283
283
|
|
|
284
284
|
## Step 6: Spawn the Evaluator Subagent
|
|
285
285
|
|
|
286
|
+
**Panel mode (gated, off by default):** Read `config.evaluator.panel`. If `panel.enabled` is `true` AND `panel.lenses.length >= 2`, run the PANEL flow described in the inlined Lens Panel reference below (`<!-- Reference: lens-panel.md -->`):
|
|
287
|
+
- Spawn ONE bober-evaluator with **MODE:deterministic** — runs the configured strategy suite exactly once.
|
|
288
|
+
- Then spawn one bober-evaluator per lens with **MODE:lens:<name>** for each name in `panel.lenses`, bounded by `panel.maxConcurrent` concurrent spawns.
|
|
289
|
+
- Collect each lens verdict; majority-vote: `passed = passCount > failCount`, **FAIL-CLOSED on tie** (tie → false).
|
|
290
|
+
- Set `final.passed = deterministic.passed && reconciled.passed`.
|
|
291
|
+
- Save the eval-result with `evaluator: "panel"` and a `lensVerdicts: [{ lens, passed, summary }]` array.
|
|
292
|
+
|
|
293
|
+
OTHERWISE (panel disabled, or fewer than 2 lenses), spawn exactly ONE bober-evaluator with **MODE:full** exactly as described below — byte-identical to today's behaviour.
|
|
294
|
+
|
|
286
295
|
**Use the Agent tool to spawn the evaluator:**
|
|
287
296
|
|
|
288
297
|
```
|
|
@@ -368,12 +377,44 @@ Respond with EXACTLY this JSON structure (no other text):
|
|
|
368
377
|
{"event":"sprint-completed","contractId":"...","specId":"...","iteration":N,"timestamp":"..."}
|
|
369
378
|
```
|
|
370
379
|
|
|
371
|
-
4. **
|
|
380
|
+
4. **Spawn the Documenter subagent — write docs now, while the change is fresh.** The sprint is committed and marked complete; document it per-sprint instead of batching all docs into a final sprint (which goes stale and error-prone). Use the Agent tool:
|
|
381
|
+
|
|
382
|
+
```
|
|
383
|
+
Agent tool call:
|
|
384
|
+
description: "Docs for sprint <N>: <sprint title>"
|
|
385
|
+
subagent_type: bober-documenter
|
|
386
|
+
mode: auto
|
|
387
|
+
prompt: <the prompt below>
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
IMPORTANT: Use `mode: auto` or `mode: bypassPermissions` — the documenter needs write access to create/edit docs and commit them.
|
|
391
|
+
|
|
392
|
+
**Documenter prompt:**
|
|
393
|
+
```
|
|
394
|
+
You are the Bober Documenter subagent. Sprint <N> just PASSED evaluation and was marked complete. Write its documentation and update related docs while the change is fresh.
|
|
395
|
+
|
|
396
|
+
Read these from disk:
|
|
397
|
+
- SprintContract: .bober/contracts/<contractId>.json
|
|
398
|
+
- Generator report: .bober/handoffs/gen-report-<contractId>-<iteration>.json
|
|
399
|
+
- Eval result: .bober/eval-results/eval-<contractId>-<iteration>.json
|
|
400
|
+
- .bober/principles.md if it exists
|
|
401
|
+
|
|
402
|
+
Then follow your agent instructions: determine what was built from the committed diff, write the sprint record to docs/sprints/<contractId>.md, find & update related existing docs (README, ADRs, CLAUDE.md, module docs) that the change made stale, and commit ONLY the doc files separately. Do NOT modify application code or tests.
|
|
403
|
+
|
|
404
|
+
Respond with the JSON structure defined in your agent spec.
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
**After the Documenter returns:**
|
|
408
|
+
- Parse its JSON response. Note `sprintDocPath`, `relatedDocsUpdated`, and any `concerns`.
|
|
409
|
+
- If the documenter crashed or returned an error, do NOT fail the sprint — it already passed. Log `{"event":"sprint-docs-failed","contractId":"...","timestamp":"..."}` and continue. Docs can be regenerated later.
|
|
410
|
+
- If `concerns` is non-empty, surface them in the success report so the user can decide whether to act.
|
|
411
|
+
|
|
412
|
+
5. **Check if the plan is now fully complete.** Read the PlanSpec's `sprints` array to get the total count. Count how many of those contracts now have `status: "completed"`. If ALL sprints are completed (N/N):
|
|
372
413
|
- Update the PlanSpec: set `status` to `"completed"` and `completedAt` to current ISO-8601 timestamp. Save to `.bober/specs/<specId>.json`. **The `status` field MUST remain in the first 10 lines of the JSON** so future runs can skip it with a partial read.
|
|
373
414
|
- Update `.bober/progress.md` — change the plan's status line to `completed (N/N sprints)`.
|
|
374
415
|
- Log event: `{"event":"plan-completed","specId":"...","sprintsCompleted":N,"timestamp":"..."}`
|
|
375
416
|
|
|
376
|
-
|
|
417
|
+
6. **Report success to the user:**
|
|
377
418
|
```
|
|
378
419
|
=== Sprint <N> PASSED on iteration <M> ===
|
|
379
420
|
|
|
@@ -383,6 +424,7 @@ Respond with EXACTLY this JSON structure (no other text):
|
|
|
383
424
|
- <criterion 2>: PASS
|
|
384
425
|
...
|
|
385
426
|
|
|
427
|
+
Docs: <sprintDocPath> (+ <count> related docs updated)
|
|
386
428
|
Next sprint: <next sprint title> (run /bober-sprint to continue)
|
|
387
429
|
```
|
|
388
430
|
If all sprints are done, report `=== PLAN COMPLETE (N/N sprints) ===` instead of "Next sprint".
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Lens Panel — Canonical Protocol Reference
|
|
2
|
+
|
|
3
|
+
This document is the single source of truth for native panel orchestration in agent-bober.
|
|
4
|
+
It embeds the five canonical lens focus fragments verbatim from
|
|
5
|
+
`src/orchestrator/eval-lenses.ts` (the `LENS_CATALOG` literal) and documents the
|
|
6
|
+
split fan-out, majority-vote/fail-closed reconciliation, and the `lensVerdicts` output shape.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Lens Focus Fragments
|
|
11
|
+
|
|
12
|
+
The following fragments are the exact strings returned by `resolveLensFocus(lens)` for each
|
|
13
|
+
built-in lens. They MUST remain byte-for-byte identical to the corresponding entries in
|
|
14
|
+
`LENS_CATALOG` — the drift gate (`src/orchestrator/lens-panel-parity.test.ts`) enforces this.
|
|
15
|
+
|
|
16
|
+
### correctness
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
Focus on whether the implementation actually satisfies each success criterion verbatim. Check that all required behaviours exist, all edge cases are handled, and the contract's definitionOfDone is met.
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### security
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
Focus on injection vulnerabilities, authentication and authorisation gaps, secret handling, unsafe input validation, and any path traversal or privilege escalation risks.
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### regression
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
Focus on whether previously working behaviour still works after the changes. Verify that pre-existing tests pass, that no public API or config interface was broken, and that the sprint diff does not silently remove functionality.
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### quality
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
Focus on principles violations, dead code, misleading naming, smells, duplicated logic, and whether the implementation follows the project's established patterns and conventions.
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### simplicity
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
Focus exclusively on over-engineering in the production code: logic that reinvents the standard library, dependencies or hand-rolled code doing what a native platform feature already provides, abstractions with a single implementation, configuration nobody reads, dead flexibility, and code expressible in materially fewer lines. For each, name the location, what to cut, and what replaces it. Never flag tests, assertion-based self-checks, input validation at trust boundaries, error handling, security measures, or accessibility as deletable — minimalism governs production code, never the verification or safety discipline.
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
> The `simplicity` lens is the complexity-only counterpart to `quality`. `quality` asks
|
|
47
|
+
> "does this follow our patterns and is it free of smells?"; `simplicity` asks "what can be
|
|
48
|
+
> deleted, replaced by stdlib/native, or shrunk?" — and is forbidden from ever recommending the
|
|
49
|
+
> removal of a test, a validation, or a safety measure. It pairs cleanly with the evaluator's
|
|
50
|
+
> test/verification Iron Law: minimalism governs what is built, never what is verified.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Native Panel Protocol
|
|
55
|
+
|
|
56
|
+
### Split Fan-out
|
|
57
|
+
|
|
58
|
+
When the native panel is active, the orchestrator spawns evaluators in two passes:
|
|
59
|
+
|
|
60
|
+
1. **Deterministic evaluator (one instance):** runs the configured strategy suite exactly once
|
|
61
|
+
(build, typecheck, lint, unit-test, playwright, api-check, etc.). This produces the
|
|
62
|
+
deterministic verdict — objective, tool-based checks that do not depend on lens focus.
|
|
63
|
+
|
|
64
|
+
2. **Qualitative evaluators (one per configured lens):** each evaluator receives the same
|
|
65
|
+
sprint diff and context but is instructed to judge the contract's success criteria
|
|
66
|
+
exclusively through its lens focus fragment. The strategy suite is **not** re-run for
|
|
67
|
+
these evaluators — they perform qualitative assessment only, using the results already
|
|
68
|
+
collected by the deterministic evaluator as supporting context.
|
|
69
|
+
|
|
70
|
+
This split ensures strategies execute once (no duplicate CI cost) while each lens evaluates
|
|
71
|
+
the diff independently.
|
|
72
|
+
|
|
73
|
+
### Reconciliation — Majority Vote, Fail-Closed
|
|
74
|
+
|
|
75
|
+
The lens verdicts are reconciled by `reconcile()` in
|
|
76
|
+
`src/orchestrator/workflow/reconciler.ts` using the following semantics:
|
|
77
|
+
|
|
78
|
+
- **Inputs:** the array of per-lens `EvalResult` objects (`lensVerdicts`).
|
|
79
|
+
- **Require non-empty:** an empty array throws `"reconcile: lensVerdicts must be non-empty"`.
|
|
80
|
+
- **Vote count:** `passCount` = number of lenses where `passed === true`;
|
|
81
|
+
`failCount` = total − passCount.
|
|
82
|
+
- **Verdict:** `passed = passCount > failCount` (strict majority).
|
|
83
|
+
- **Fail-closed on tie:** when `passCount === failCount` the panel verdict is `false`.
|
|
84
|
+
- **Details:** union of all failing lens details, de-duplicated by `(criterion, message)` key.
|
|
85
|
+
- **Feedback:** failing lenses' feedback joined with `\n`; `"All lenses passed."` when all pass.
|
|
86
|
+
- **Summary:** `"Panel verdict: ${passCount}/${n} lenses passed"`.
|
|
87
|
+
- **Score:** `Math.round((100 * passCount) / n)`.
|
|
88
|
+
- **Evaluator tag:** `evaluator = "panel"`.
|
|
89
|
+
- **Timestamp:** echoed verbatim from the input argument (pure function, ADR-4).
|
|
90
|
+
|
|
91
|
+
### Combine
|
|
92
|
+
|
|
93
|
+
The final sprint verdict combines both passes:
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
final.passed = deterministic.passed && reconciled.passed
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Both must pass for the sprint to be accepted.
|
|
100
|
+
|
|
101
|
+
### lensVerdicts Output Shape
|
|
102
|
+
|
|
103
|
+
After reconciliation the orchestrator writes a `lensVerdicts` array into the saved
|
|
104
|
+
`EvalResult` JSON and sets `evaluator = "panel"`. The array shape is:
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
lensVerdicts: Array<{
|
|
108
|
+
lens: string; // e.g. "correctness", "security", "regression", "quality", "simplicity"
|
|
109
|
+
passed: boolean; // individual lens verdict
|
|
110
|
+
summary: string; // per-lens summary from the qualitative evaluator
|
|
111
|
+
}>
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
This field is optional and backward-compatible: eval results produced before the panel
|
|
115
|
+
feature (or by non-panel evaluators) simply omit it.
|