diff --git a/README.md b/README.md index 9663e4a..8d2ac0a 100644 --- a/README.md +++ b/README.md @@ -203,6 +203,13 @@ Sample scripts you run by **path** (`codex-workflow run examples/`). - `code-review.js` — Claude Code's built-in hidden `code-review` workflow. **Reference only**: it was extracted from the compiled client with unresolved `${…}` template placeholders, so it does not parse/run; it's included to document the find → verify → synthesize architecture. +- `multi-agent-workflow/` — directory containing a self-contained end-to-end issue resolver. + Run `bash examples/multi-agent-workflow/setup.sh` once, then + `bun codex-workflow run examples/multi-agent-workflow/workflow.js --args '{"tracker":"gh","issueId":123}'`. + Includes 10 phases (Debrief → Plan → Review → Plan Impl → Review → Implement+Unit → E2E → Lint+CI → Audit → PR), + three human-approval gates, seven vendored subagents under `agents/` (4 reused `rgi-lens-*` lenses + + `rgi-lens-scope` + `rgi-lens-dod-coverage` + `multi-agent-auditor`), and an Orca integration guide + (`ORCA.md`) for running N parallel issue resolutions inside Orca Tasks UI panes. ## Viewer diff --git a/examples/multi-agent-workflow/ORCA.md b/examples/multi-agent-workflow/ORCA.md new file mode 100644 index 0000000..c7ef205 --- /dev/null +++ b/examples/multi-agent-workflow/ORCA.md @@ -0,0 +1,237 @@ +# ORCA — Running multi-agent-workflow inside Orca Orchestrator + +This guide is for using `multi-agent-workflow` as the agent inside an Orca-spawned TUI terminal. Orca handles worktree creation, TUI agent lifecycle, and parallel pane management; the workflow handles the deterministic multi-agent pipeline. + +## TL;DR + +``` +1. Open Orca desktop +2. Go to Tasks +3. Find the GitHub/Linear task you want to resolve +4. Click "Start" +5. In the new TUI agent pane, run: + /multi-agent-workflow gh:123 +6. Approve gates as they appear (Orca UI or TUI chat) +7. Repeat for other issues in parallel panes +``` + +`/multi-agent-workflow` is not a real slash command — it's the convention for what you type into the TUI agent's prompt. What actually runs is `bun codex-workflow run examples/multi-agent-workflow/workflow.js --args '{"tracker":"gh","issueId":123}'`. The slash convention makes the intent clear. + +## Prerequisites + +- Orca desktop app installed and running (Electron app from or local build) +- `orca` CLI on PATH (usually `C:\Users\\AppData\Local\Programs\orca\resources\bin\orca.exe`) +- A repo registered with Orca (see [Step 1: Register your repo](#step-1-register-your-repo)) +- The full setup from [SETUP.md](./SETUP.md) done + +## Step 1: Register your repo + +Once per repo: + +```bash +cd ~/code/my-project +orca repo add . --display-name my-project +``` + +Verify: + +```bash +orca repo list --json +``` + +You should see your repo with an id (a UUID). You'll reference it in worktree commands (Orca usually resolves by name so you rarely need the UUID directly). + +## Step 2: Single-issue flow (happy path) + +### 2.1. Find the task + +In the Orca desktop app: +- Sidebar → **Tasks** +- Locate the GitHub or Linear task you want to resolve +- Filters by label / milestone / assignee work as expected +- Click the task to see its detail panel (description, comments, linked PRs) + +### 2.2. Start the agent + +In the task detail panel: +- Click the **Start** button (top-right of the panel) +- Orca creates a fresh worktree at `~/orca/workspaces///` +- Orca spawns a TUI agent (Claude Code or OpenCode-MiniMax, depending on your account settings) in a new pane/tab +- The agent opens with its default prompt + +### 2.3. Invoke the workflow + +In the TUI agent's prompt: + +``` +/multi-agent-workflow gh:123 +``` + +(`123` is the GitHub issue number. Use `linear:ABC-456` for Linear issues.) + +What happens under the hood: + +1. The agent parses your slash command (or treats it as a literal prompt to follow) +2. The agent runs: + ``` + bun codex-workflow run examples/multi-agent-workflow/workflow.js \ + --config examples/codex-workflow.config.ts \ + --args '{"tracker":"gh","issueId":123}' + ``` +3. The workflow begins Phase 1 (Debrief) + +### 2.4. Wait for Gate 0 (Debrief approval) + +The Debrief agent: +- Reads the issue via `gh issue view 123` +- Writes `.multi-agent-workflow/debrief-123.md` (gitignored, inside the worktree) +- Posts a skeleton comment back on the issue +- Surfaces an Orca gate: **"Approve debrief for issue #123?"** + +Approve via either mode: + +**Option A — Orca UI (recommended):** +- Switch back to the Orca Tasks view +- The gate appears as a card on the task +- Click **"yes"** (or any other option you defined) +- The workflow resumes automatically + +**Option B — TUI chat fallback:** +- Stay in the TUI agent pane +- Type one of: `pode prosseguir`, `ok`, `vai`, `segue`, `bora`, `aprovado`, `pode`, `prossiga` +- The agent matches the keyword and the workflow resumes + +### 2.5. Watch the workflow run + +The workflow runs Phases 2 through 9 autonomously. You don't need to interact unless a gate appears or an agent returns `verdict: "needs-work"` with high-severity findings (which blocks the workflow with an error). + +Progress visibility: +- **Orca Tasks view**: each phase shows as a subtask with status (planning / impl / tests / audit) +- **TUI agent pane**: codex-workflow prints live progress to stdout (phase markers, agent labels, retry counts) +- **GitHub**: comments on the issue (debrief skeleton, audit section on PR body) + +### 2.6. Gate 1 (Audit verdict) and Gate 2 (Pre-PR) + +After Phase 9 (Audit), the workflow surfaces **Gate 1**: +- Auditor verdict `pass` → no human action needed, workflow continues +- Auditor verdict `warn` → human reviews findings, decides to continue or block +- Auditor verdict `fail` → workflow blocks automatically (you must fix the underlying issue) + +After Phase 10 (PR composition), the workflow surfaces **Gate 2** (HITL pre-PR): +- Shows the proposed PR title and body +- Human approves via Orca UI or TUI chat +- On approval: `gh pr create --fill` runs +- PR URL appears in Orca + TUI pane + GitHub + +### 2.7. Result + +Final output is in the TUI agent pane: + +``` +✓ multi-agent-workflow (wf_xxxxxxxx-xxxx) — 12 agents, 0 failed, 4m32s +{ + issue: "gh:123", + debriefPath: ".multi-agent-workflow/debrief-123.md", + plan: { ... }, + implPlan: { ... }, + implResult: { filesChanged: [...], commits: [...] }, + e2eResult: { ciStatus: "pass", ciRunUrl: "..." }, + lintResult: { lintOk: true, typecheckOk: true, guardrailsOk: true }, + audit: { verdict: "pass", ledgerEntryId: "..." }, + pr: { prUrl: "https://github.com/.../pull/456", prNumber: 456, branchName: "fix/123-..." } +} +``` + +## Step 3: Multi-issue parallel flow + +This is where Orca shines. You can resolve N issues concurrently, each in its own worktree, each with its own codex-workflow run. + +### 3.1. Start N agents + +For each issue you want to resolve in parallel: + +1. Go to **Tasks** in Orca +2. Click on the task +3. Click **Start** +4. Wait for the TUI agent to open +5. Type `/multi-agent-workflow gh:123` (or whatever the issue id is) + +Don't wait for the first one to finish. Start the second one immediately, then the third, etc. + +### 3.2. Monitor all in parallel + +The Orca Tasks view shows all N tasks with their current phase status. Each pane has its own gate UI. You approve each gate independently. + +You can switch between panes with Orca's pane switcher (usually `Cmd+K` / `Ctrl+K` or a sidebar tab list). + +### 3.3. Concurrency limits + +This machine (i7-11800H, 16 GB free RAM) comfortably handles: + +- **3–5 parallel workflows** with full 10-phase execution: ~5–6 GB RAM, ~16 CPU threads saturated +- **6–10 parallel workflows**: monitor memory; if pages start, kill a few with `orca worker-stop` +- **11+ parallel workflows**: probable memory pressure; consider batching + +If you hit limits, `codex-workflow runs` lists the active ones so you can identify and abandon the lowest-priority. + +## Step 4: HITL gate dual mode + +The three gates (post-debrief, post-audit, pre-PR) work in dual mode: + +| Environment | Gate UI | Fallback | +|---|---|---| +| Inside an Orca TUI agent | Orca Tasks view gate card | TUI chat keyword | +| Standalone Claude Code / OpenCode (no Orca) | TUI chat keyword only | — | + +The workflow detects Orca via the `ORCA_AGENT_HOOK_PORT` environment variable (set automatically by Orca when spawning a TUI agent). If detected, gates surface as Orca gate-create commands. If not, gates block on TUI chat input. + +## Step 5: Monitoring and troubleshooting + +### 5.1. Where to look + +```bash +# codex-workflow runs (recent history) +codex-workflow runs --limit 20 + +# A specific run in detail +codex-workflow show + +# Resume a failed run (replays cached agents, re-executes failed ones) +codex-workflow resume +``` + +### 5.2. Inside Orca + +```bash +# All tasks and their statuses +orca task list --json + +# Memory and CPU per pane +orca diagnostics memory --json + +# Stop a runaway pane (kills its codex-workflow run) +orca worker-stop --handle +``` + +### 5.3. Common errors + +| Error | Cause | Fix | +|---|---|---| +| `agent_unconfigured` | Tried `orca worker-start --terminal` for a bun pane | Use `orca terminal create --command "bun ..."` directly (the workflow handles this) | +| Gate never appears in Orca UI | TUI agent not running through Orca runtime (env var missing) | Verify with `echo $env:ORCA_AGENT_HOOK_PORT` in the TUI pane | +| `MINIMAX_API_KEY` is null inside the pane | Env var not inherited from parent shell | Either set as Windows User-level env var, or pass inline: `set MINIMAX_API_KEY=...&&bun ...` in the terminal command | +| `gh auth status` fails inside the pane | gh CLI not authenticated at the OS level | `gh auth login` outside Orca (persists globally) | +| Multiple panes hit the same issue | You clicked Start twice on the same task | Cancel one with `orca worker-stop --handle ` | +| Auditor verdict `fail` blocks forever | Legitimate audit finding | Read `audit.findings[]`, fix the issue in the worktree, then `codex-workflow resume ` from Phase 9 | + +## Daily workflow (after first-time setup) + +``` +1. Open Orca +2. Tasks → pick an issue +3. Click Start → slash command in pane → approve gates +4. Repeat for other issues in parallel panes +5. Review PRs as they open +``` + +That's the whole loop. The rest of the workflow runs autonomously. \ No newline at end of file diff --git a/examples/multi-agent-workflow/README.md b/examples/multi-agent-workflow/README.md new file mode 100644 index 0000000..7ad4c11 --- /dev/null +++ b/examples/multi-agent-workflow/README.md @@ -0,0 +1,77 @@ +# multi-agent-workflow + +End-to-end issue resolution as a deterministic, gate-driven codex-workflow. Reads an issue from GitHub or Linear, plans it adversarially, implements with TDD, runs lint/CI/E2E gates, audits the work, and opens a PR — with three human-approval checkpoints along the way. + +## When to use + +Reach for this when: + +- You want one command to take an issue from "just opened" to "PR ready for review". +- You're okay with three human-approval gates (post-debrief, post-audit, pre-PR). +- You want a dedicated auditor agent (separate from the implementation reviewer) to verify DoD coverage, commit traceability, and scope honesty. +- You have a single issue per run; multi-issue parallelism comes from running multiple instances in parallel (e.g., in multiple Orca worktrees). + +Skip this when: + +- You need a fully autonomous loop with no human gates (this workflow deliberately blocks three times). +- The issue is a typo / docs fix / one-line change (overkill). +- You don't have a configured `minimax-default` provider in your `codex-workflow.config.ts` (see [SETUP.md](./SETUP.md)). + +## What it does (10 phases, 3 gates) + +| Phase | Agent | Purpose | Schema | +|---|---|---|---| +| 1. Debrief | `general-purpose` (provider: `minimax-default`) | Read issue → 3-level human narrative (Tese/Contexto/Imersão) with ASCII art. Save to `.multi-agent-workflow/debrief-.md`. | `debriefPath`, `summary`, `approved` | +| **Gate 0** | human | Approve the debrief before planning starts. | — | +| 2. Plan Issue | `general-purpose` | Convert debrief into a structured plan with verifiable acceptance criteria. | `objective`, `scope`, `acceptanceCriteria[]`, `risks[]`, `dependencies[]`, `estimatedAgents` | +| 3. Review Plan | 2 parallel: `rgi-lens-scope`, `rgi-lens-dod-coverage` | Adversarial review of the issue plan. | `verdict`, `findings[]` | +| 4. Plan Implementation | `general-purpose` | File-by-file implementation plan with PR title/body/branch. | `filesToCreate[]`, `filesToModify[]`, `testFiles[]`, `prTitle`, `prBody`, `branchName` | +| 5. Review Impl Plan | 2 parallel: `rgi-lens-arch`, `rgi-lens-product` | Adversarial review of the implementation plan. | `verdict`, `findings[]` | +| 6. Implement + Unit Tests | `general-purpose` (worktree isolation) | TDD loop: test → implement → green. Commit per file. | `filesChanged[]`, `testResults`, `commits[]`, `summary` | +| 7. E2E Tests | `general-purpose` | Write Playwright specs, push branch, watch CI. | `testFiles[]`, `ciRunUrl`, `ciStatus` | +| 8. Lint + CI | `general-purpose` | Run lint, typecheck, architectural guardrails. Execute-only — no code changes. | `lintOk`, `typecheckOk`, `guardrailsOk`, `errors[]` | +| 9. Audit | `multi-agent-auditor` (dedicated) | Verify DoD coverage, commit traceability, scope honesty, ledger entry. | `verdict: pass\|warn\|fail`, `findings[]`, `ledgerEntryId` | +| **Gate 1** | human | Approve audit verdict (skip if pass, review if warn, block if fail). | — | +| 10. Commit + PR | `general-purpose` | Compose PR body (with audit section), HITL pre-PR gate, `gh pr create`. | `prUrl`, `prNumber`, `branchName`, `auditorVerdict` | +| **Gate 2** | human | Approve the PR body and branch before `gh pr create`. | — | + +## How to run + +```bash +bun codex-workflow run examples/multi-agent-workflow/workflow.js \ + --config examples/codex-workflow.config.ts \ + --args '{"tracker":"gh","issueId":123}' +``` + +`tracker` is `"gh"` (GitHub via `gh` CLI) or `"linear"` (Linear via GraphQL). `issueId` is the integer (GitHub) or alphanumeric identifier (Linear). + +For multi-issue parallelism, run multiple instances concurrently in separate worktrees (typically via Orca Tasks UI — see [ORCA.md](./ORCA.md)). + +## The seven subagents (vendored in [`agents/`](./agents/)) + +| Subagent | Used in | Purpose | +|---|---|---| +| `rgi-lens-arch` | Phase 5 | Architectural alignment: layering, primitive duplication, ADR compliance | +| `rgi-lens-product` | Phase 5 | Honest scope: no stubs/TODOs, PR body matches diff, no lies | +| `rgi-lens-scope` | Phase 3 | Scope clarity: ambiguous boundaries, divergent interpretations | +| `rgi-lens-dod-coverage` | Phase 3 | DoD verifiability: every acceptance criterion has a test | +| `rgi-lens-sec` | (available) | Security: secrets, egress, RBAC, cross-workspace leaks | +| `rgi-lens-test` | (available) | Test conformance: tautological tests, coverage, mocks of the function under test | +| `multi-agent-auditor` | Phase 9 | Meta-verification: DoD coverage, commit traceability, ledger entry | + +`rgi-lens-arch`, `rgi-lens-product`, `rgi-lens-sec`, `rgi-lens-test` are reused from the four-lens pattern of `resolve-github-issues`. The other three (`scope`, `dod-coverage`, `auditor`) are new for this workflow. + +To use these as Claude Code or OpenCode subagents, copy them to `~/.config/opencode/agents/`. The workflow calls them via the LLM (not as Claude Code subagents) — the `.md` files document the lens persona; the workflow invokes them by name. + +## Constraints + +- **One issue per run.** Multi-issue parallelism is achieved by running N instances in parallel (see ORCA.md). +- **Three human gates.** Phase 1 (debrief approval), Phase 9 (audit verdict), Phase 10 (pre-PR). All three are dual-mode: Orca gate UI when running inside an Orca-spawned TUI agent; TUI chat fallback otherwise. +- **Auditor verdict `fail` blocks the PR.** `pass` and `warn` continue; `warn` surfaces in the PR body for human review. +- **Code is original.** The structure is inspired by the small examples (`hello.js`, `complex-chain.js`), not by the larger reverse-engineered research notes (`deep-research.js`, `code-review.js`). + +## See also + +- [SETUP.md](./SETUP.md) — first-time setup (Bun, codex-workflow, pi-coding-agent, MiniMax provider). +- [ORCA.md](./ORCA.md) — running this inside Orca Tasks UI for single-issue and parallel multi-issue flows. +- [codex-workflow README](../../README.md) — upstream docs for the workflow runtime. \ No newline at end of file diff --git a/examples/multi-agent-workflow/SETUP.md b/examples/multi-agent-workflow/SETUP.md new file mode 100644 index 0000000..5e25e56 --- /dev/null +++ b/examples/multi-agent-workflow/SETUP.md @@ -0,0 +1,188 @@ +# SETUP — First-time configuration for multi-agent-workflow + +This guide walks you through installing everything `multi-agent-workflow` needs on a fresh machine. If you already have Bun, codex-workflow, and pi-coding-agent installed, jump to [Step 4: Add the MiniMax provider](#step-4-add-the-minimax-provider). + +Time: ~10 minutes. + +## Prerequisites + +- macOS, Linux, or Windows (PowerShell 5.1+) +- A MiniMax API key (get one at ) +- A GitHub personal access token with `repo` scope (for `gh` CLI auth) +- (Optional) A Linear API key if you'll use `tracker: "linear"` + +## Step 1: Install Bun + +codex-workflow runs scripts under Bun. + +```bash +# macOS / Linux +curl -fsSL https://bun.sh/install | bash +exec $SHELL -l # reload shell to pick up PATH + +# Windows (PowerShell) +irm bun.sh/install.ps1 | iex +# Restart PowerShell after install + +bun --version # 1.4.0+ +``` + +## Step 2: Install codex-workflow + +```bash +# Global install (works from any project) +npm install -g github:six-ddc/codex-dynamic-workflows + +# Verify +codex-workflow --version +codex-workflow doctor # checks Bun, provider config, codex CLI presence +``` + +If `codex-workflow` is not found in your shell, ensure your npm global bin is on `PATH`: + +```bash +# Get the global bin path +npm config get prefix +# Add /bin (Unix) or (Windows) to your PATH +``` + +## Step 3: Install pi-coding-agent + +The `pi` backend is the only one in codex-workflow that talks to OpenAI-compatible / Anthropic-compatible endpoints via `baseUrl` + `apiKeyEnv`. We use it to reach MiniMax. + +```bash +npm install -g @earendil-works/pi-coding-agent + +# Verify +pi --version +``` + +## Step 4: Add the MiniMax provider + +`multi-agent-workflow` calls agents with `provider: "minimax-default"`. You need to register that provider in your `codex-workflow.config.ts`. + +### Where to put the config + +Three options, in order of preference: + +1. **Project root** (recommended): `/codex-workflow.config.ts` +2. **Per-example**: `examples/codex-workflow.config.ts` (vendored in the upstream repo, do not modify upstream — copy it locally instead) +3. **Pass via `--config`** every invocation: `bun codex-workflow run ... --config /path/to/config.ts` + +### The provider block + +Add this to your `codex-workflow.config.ts` (do not edit the upstream `examples/codex-workflow.config.ts` directly — copy it first): + +```ts +export default { + providers: { + // ... existing providers (codex-default, claude-smart, gemini-pro, etc.) ... + + 'minimax-default': { + backend: 'pi', + baseUrl: process.env.MINIMAX_BASE_URL ?? 'https://api.minimax.io', + api: 'openai-completions', + piProvider: 'openai', + model: 'MiniMax-M3', + models: ['MiniMax-M3', 'MiniMax-M2.7', 'MiniMax-M2.7-highspeed', 'MiniMax-M2.5'], + apiKeyEnv: 'MINIMAX_API_KEY', + thinking: 'high', + contextFiles: true, + }, + }, + default: 'minimax-default', // or keep your existing default +} +``` + +### Why `pi` and not a new backend? + +`pi` is the canonical codex-workflow backend for any OpenAI/Anthropic-compatible HTTP endpoint. MiniMax exposes both `/v1` (OpenAI shape) and `/anthropic` (Anthropic shape); we use OpenAI-completions for broadest compatibility. The runner reads `MINIMAX_API_KEY` from your env at build time and never writes it to disk. + +If you prefer Anthropic shape, change `api: 'openai-completions'` to `api: 'anthropic-messages'`. The `models` list and `baseUrl` stay the same. + +## Step 5: Set environment variables + +```bash +# Required +export MINIMAX_API_KEY="sk-cp-..." # your MiniMax token-plan key + +# Required for tracker: "gh" +gh auth login # one-time, opens browser + +# Optional for tracker: "linear" +export LINEAR_API_KEY="lin_api_..." + +# Optional — useful for debugging +export CODEX_WORKFLOW_HOME="$HOME/.codex-workflow" # default location +``` + +### Windows PowerShell (persistent) + +```powershell +[Environment]::SetEnvironmentVariable("MINIMAX_API_KEY", "sk-cp-...", "User") +[Environment]::SetEnvironmentVariable("LINEAR_API_KEY", "lin_api_...", "User") # if using Linear +# Restart PowerShell to pick up User-level vars +``` + +## Step 6: Validate the setup + +Run a no-cost dry-run: + +```bash +CODEX_WORKFLOW_FAKE_AGENT=1 bun codex-workflow run \ + examples/multi-agent-workflow/workflow.js \ + --config examples/codex-workflow.config.ts \ + --args '{"tracker":"gh","issueId":123}' \ + --json +``` + +Expected output: +- All 10 phases parse +- `agent debrief` will fail with `StructuredOutput validation failure` (fake agent doesn't return schema-valid objects — this is expected) +- The failure is at Phase 1 (Debrief), not at parse time — that means the workflow is valid + +### Real-provider smoke test + +```bash +bun codex-workflow run \ + examples/multi-agent-workflow/workflow.js \ + --config examples/codex-workflow.config.ts \ + --args '{"tracker":"gh","issueId":0}' +``` + +(`issueId: 0` is invalid for GitHub but exercises the full schema validation path against the real MiniMax provider — you'll see a real LLM error from Agent 1 about an invalid issue number.) + +## Step 7: Run for real + +```bash +bun codex-workflow run \ + examples/multi-agent-workflow/workflow.js \ + --config examples/codex-workflow.config.ts \ + --args '{"tracker":"gh","issueId":}' +``` + +You'll hit Gate 0 (debrief approval) first. Approve via: +- **Orca Tasks UI**: open the gate, click "yes" +- **TUI chat fallback**: type `pode prosseguir` (or `ok`, `vai`, `segue`, `bora`) into the agent prompt + +See [ORCA.md](./ORCA.md) for the full Orca flow and parallel multi-issue usage. + +## Troubleshooting + +| Symptom | Cause | Fix | +|---|---|---| +| `bun: command not found` | Bun not on PATH | Re-run installer, restart shell | +| `codex-workflow: command not found` | npm global bin not on PATH | Run `npm config get prefix`, add `bin` to PATH | +| `spawn EINVAL` on Windows | codex-workflow Node trying to spawn `pi.cmd` | Use `bun codex-workflow run` instead of `node` — Bun handles `.cmd` correctly | +| `provider "minimax-default" not found in config` | Provider block missing | Add the block from [Step 4](#step-4-add-the-minimax-provider) to your `codex-workflow.config.ts` | +| `MINIMAX_API_KEY is not set` | Env var not loaded | Restart shell, or check `[Environment]::GetEnvironmentVariable("MINIMAX_API_KEY", "User")` (Windows) | +| `gh auth status` fails | GitHub CLI not authenticated | Run `gh auth login` | +| Workflow hangs at Gate 0 | No human in the loop | Approve via Orca UI or TUI chat; the gate is intentional, not a bug | +| Auditor returns `verdict: "fail"` | Scope/DoD violation | Read `audit.findings[]`, fix the underlying issue, re-run the workflow from phase 9 (or from scratch) | +| Run fails mid-way | Transient provider error | `codex-workflow resume ` — replays cached agents and re-executes failed ones | + +## Next steps + +- Read [ORCA.md](./ORCA.md) for the Orca Tasks UI flow (single-issue + parallel multi-issue). +- Read the [main README](./README.md) for an overview of phases and gates. +- Subscribe to issues at for updates to the runtime. \ No newline at end of file diff --git a/examples/multi-agent-workflow/agents/multi-agent-auditor.md b/examples/multi-agent-workflow/agents/multi-agent-auditor.md new file mode 100644 index 0000000..bee7d85 --- /dev/null +++ b/examples/multi-agent-workflow/agents/multi-agent-auditor.md @@ -0,0 +1,173 @@ +--- +description: Agente auditor dedicado do multi-agent-workflow (Phase 9). Meta-verifica que o trabalho entregue atende DoD, commits são rastreáveis ao plano, escopo foi respeitado, CI está verde, e ledger entry foi gravado. Read-only (com append explícito ao audit ledger). +mode: subagent +model: anthropic/claude-sonnet-4-5 +temperature: 0.1 +permission: + edit: deny + bash: + "*": deny + "git status*": allow + "git diff*": allow + "git log*": allow + "gh issue view*": allow + "gh issue list*": allow + "gh run view*": allow + "gh run watch*": allow + "ls *": allow + "cat *": allow + "rg *": allow + webfetch: deny +--- + +# multi-agent-auditor — agente auditor dedicado + +Você é o **agente auditor dedicado** do workflow `multi-agent-workflow`, executado na **Phase 9 (Audit)**. Sua função é diferente das lentes adversariais (`rgi-lens-*`): as lentes revisam a *qualidade* do diff; você verifica se *o trabalho foi feito corretamente*. + +## Diferença conceitual: você vs. as lentes + +| | Lentes (`rgi-lens-*`) | Você (`multi-agent-auditor`) | +|---|---|---| +| **Pergunta** | "Esse código é bom?" | "Esse trabalho foi feito certo?" | +| **Escopo** | Diff (arquivos alterados) | Todo o run (plano + impl + tests + audit trail) | +| **Output** | `verdict`, `findings[]` (lente-specific) | `verdict: pass\|warn\|fail`, `findings[]`, **`ledgerEntryId`** | +| **Poder** | Read-only | Read-only + append ao audit ledger (regravável por humanos) | +| **Posição** | Phase 3 e Phase 5 (paralelo) | Phase 9 (final, após lint/CI) | +| **Bloqueio** | High-severity finding → throw | `verdict: fail` → throw; `warn` continua com nota no PR | + +## Regras invioláveis + +- Você é **READ-ONLY** no código-fonte. Não edite, não commite, não faça push, não abra PR. +- Sua única ação de escrita é o **append ao audit ledger** via `appendAuditLedgerEntry({ category: 'multi-agent-workflow.audit', runId, verdict, findings, timestamp })`. Esse append é **obrigatório** independente do verdict. +- Você NÃO bloqueia por qualidade de código (use as lentes pra isso na Phase 5). Você bloqueia por **falhas de processo** (DoD não coberto, escopo descumprido, CI falhando). +- Sua resposta **é o `return` da função `agent()`** no `workflow.js` Phase 9. Nada de prosa. + +## O que você verifica (5 dimensões) + +Você recebe inputs do Agent 6 (impl), Agent 7 (E2E), Agent 8 (lint+CI), e do plan/implPlan originais. Verifique: + +### 1. DoD coverage (cada acceptanceCriterion tem teste verificador) + +Para cada item em `plan.acceptanceCriteria`: +- Procure o teste correspondente em `implResult.filesChanged` (procure por arquivos `*.test.ts`, `*.spec.ts`, `*.test.jsx`, etc.) +- Avalie: **se esse teste falhasse, provaria que o critério foi violado?** +- Critério "verdadeiro": o teste exercita o comportamento descrito (não testa só que algo compila, não é tautologia) +- Critério "falso": teste existe mas é smoke test que passa sempre, ou é teste de coisa diferente + +### 2. Commit traceability (todos os commits linkam ao plano) + +Para cada SHA em `implResult.commits`: +- `git show --stat ` para ver arquivos alterados +- O conjunto de arquivos alterados deve ser união de `implPlan.filesToCreate` ∪ `implPlan.filesToModify` (com pequenas variações justificadas, ex: lockfile) +- Mensagem do commit deve referenciar a issue (`#`) + +### 3. Scope honesty (sem mudanças fora do escopo) + +Compare `implResult.filesChanged` com `implPlan.filesToCreate ∪ implPlan.filesToModify`: +- Mudanças não-planejadas são red flag. Avalie se são justificáveis (lockfile, regeneração, imports) +- Mudanças em `*.env*`, secrets, configs sensíveis → **high severity, automatic fail** mesmo se pequenas + +### 4. CI green + +`e2eResult.ciStatus === 'pass'` é pré-requisito para `verdict: pass`. +- Se `ciStatus !== 'pass'` → `verdict: fail` automático +- Verifique que o PR body (depois de Phase 10) inclui "CI: passing" como link para `ciRunUrl` + +### 5. PR body accuracy + +`implPlan.prBody` vs diff real: +- Resumo corresponde aos arquivos alterados? +- "Test Plan" lista os testes reais (não genéricos)? +- "Resolves #" presente e correto? +- Sem TODOs/stubs não-declarados no PR body + +## Schema de resposta + +```json +{ + "verdict": "pass" | "warn" | "fail", + "findings": ["string", ...], + "ledgerEntryId": "string", + "summary": "string" +} +``` + +### Verdict semantics + +| Verdict | Significado | Efeito no workflow | +|---|---|---| +| `pass` | Todas as 5 dimensões OK | Continua para Phase 10 (Commit + PR) | +| `warn` | ≥1 dimensão tem issue menor, mas nada bloqueia PR | Continua para Phase 10; audit section aparece no PR body | +| `fail` | ≥1 dimensão bloqueia (ver abaixo) | **Throw no workflow.js**; workflow para aqui | + +### Condições automáticas de `fail` + +- `e2eResult.ciStatus !== 'pass'` +- ≥1 acceptanceCriterion sem teste verificador +- Mudança em arquivo sensível não-planejada (`.env*`, `secrets.*`, `*.pem`, `*.key`, config de prod) +- `prBody` mente sobre escopo (diz "X" mas diff tem Y não-relacionado) +- `commits` vazio ou não-git + +### Condições de `warn` (não bloqueiam) + +- Lockfile/manifest mudou sem justificativa clara (mas revisão manual aceita) +- Teste existe mas smoke-only (passa sempre, não exercita comportamento) +- PR body tem typo ou formatação, mas informação está correta +- `acceptanceCriteria` extra foi adicionada durante impl (não estava no plan original) + +### Ledger entry (sempre, mesmo em fail) + +Antes de retornar, faça: + +```js +import { appendAuditLedgerEntry } from '@agentskit/os-audit' + +const ledgerEntry = await appendAuditLedgerEntry({ + category: 'multi-agent-workflow.audit', + runId: '', + issueRef: `${tracker}:${issueId}`, + verdict, + findings, + prUrl: pr?.prUrl ?? null, + timestamp: new Date().toISOString(), +}) +``` + +`ledgerEntryId` é o ID retornado. Inclua na resposta. **Esse append é obrigatório** mesmo em `fail` (auditoria completa do que aconteceu, incluindo falhas). + +## Como o orquestrador usa sua saída + +O `workflow.js` do `multi-agent-workflow` (Phase 9) faz: + +```js +if (audit.verdict === 'fail') { + throw new Error(`Auditor blocked PR: ${audit.findings.join('; ')}`) +} +``` + +Então **`verdict: "fail"` bloqueia o pipeline** antes da Phase 10 (PR). `warn` continua e o relatório do auditor aparece na seção "Auditor verdict" do PR body. + +## Telemetria + +- Tool calls: ~3-8 (git log, git show, gh run view) +- Duração típica: 30-60s +- Custo típico: ~$0.05-0.10 (mais que lentes porque verifica mais) +- Posição na pipeline: Phase 9 (final, antes do PR) + +## Exemplo (referência, não copiar verbatim) + +Input resumido: +```json +{ + "plan": { "acceptanceCriteria": ["API key rotacionada automaticamente após 90 dias", "Logs de rotação visíveis", "Email enviado ao admin antes da expiração"] }, + "implResult": { "filesChanged": ["src/key-rotation.ts", "src/key-rotation.test.ts"], "commits": ["abc123", "def456"] }, + "e2eResult": { "ciStatus": "pass", "ciRunUrl": "..." }, + "lintResult": { "lintOk": true, "typecheckOk": true, "guardrailsOk": true }, + "implPlan": { "prBody": "...", "filesToCreate": ["src/key-rotation.ts", "src/key-rotation.test.ts"] } +} +``` + +Achados possíveis: +- (pass, []) se todos os 3 acceptanceCriteria têm testes específicos em `key-rotation.test.ts` que falhariam se violados. +- (warn, ["acceptanceCriterion 'Logs de rotação visíveis' tem teste mas ele só verifica que log.info() foi chamado, não que o conteúdo do log tem os campos esperados"]) — smoke test fraco, mas existe. +- (fail, ["acceptanceCriterion 'Email enviado ao admin antes da expiração' não tem teste correspondente em src/key-rotation.test.ts"]) — DoD não coberto. \ No newline at end of file diff --git a/examples/multi-agent-workflow/agents/rgi-lens-arch.md b/examples/multi-agent-workflow/agents/rgi-lens-arch.md new file mode 100644 index 0000000..238b202 --- /dev/null +++ b/examples/multi-agent-workflow/agents/rgi-lens-arch.md @@ -0,0 +1,86 @@ +--- +description: Lente de arquitetura para o painel adversarial do resolve-github-issues. Revisa diff não commitado contra ADRs Accepted, regras de layering, Zod em boundaries, e duplicação de primitivas. Read-only. +mode: subagent +model: anthropic/claude-sonnet-4-5 +temperature: 0.1 +permission: + edit: deny + bash: + "*": deny + "git status*": allow + "git diff*": allow + "git log*": allow + "gh issue view*": allow + "gh issue list*": allow + "ls *": allow + "cat *": allow + "rg *": allow + webfetch: deny +--- + +# rgi-lens-arch — lente de arquitetura + +Você é uma **lente de revisão adversarial read-only** dentro do painel de revisão do skill `resolve-github-issues`. Sua função é exclusivamente a lente de **arquitetura**. + +## Regras invioláveis da lente + +- Você é **READ-ONLY**. Não edite arquivo, não rode comandos de escrita, não commite, não faça push, não comente em issue. Você lê e emite veredito. +- Você é a lente `arquitetura`. Outras lentes (`seguranca`, `produto-honesto`, `conformidade-teste`) tratam de outros ângulos — não invadir. +- Zero achados é resultado legítimo. Não invente achado para parecer útil; inflar severidade quebra o mecanismo porque é o orquestrador que lê a escala. +- Sua resposta **é a saída da ferramenta task**. Nada de prosa extra antes ou depois. + +## Entradas (todas vêm no prompt que você recebe do orquestrador) + +- `${REPO}`: raiz do monorepo agentskit-os +- `${task.issue}`: número da issue GitHub +- `${task.itemIndex}` e `${task.itemText}`: item de DoD sendo implementado +- `${impl.filesChanged}`: lista de arquivos alterados +- `${CONTEXT_BLOCK}`: bloco com regras do projeto (CLAUDE.md, AGENTS.md, ADRs Accepted relevantes) + +## O que ler + +1. `cd ${REPO} && git status --porcelain` — para ver o conjunto do que mudou. +2. `git diff HEAD` — para o conteúdo de arquivos modificados rastreados. +3. Arquivos marcados `??` são NOVOS (não aparecem em `git diff`) — leia-os direto do disco. + +## Contra o que revisar + +- O item de DoD: `gh issue view ${task.issue}` → item "${task.itemText}". +- ADRs com `Status: Accepted` em `${REPO}/docs/adr/`. Se o código contraria uma ADR aceita, marque `conflitoComAdr: true` — isso barra a tarefa sozinho, independente de severidade. + +## O que caçar (sua lente específica) + +- **Violação de ADR-0064 (layering):** import L1→L2 ou L1→L3; ciclo novo de dependência entre pacotes; fronteira de camada furada. +- **Duplicação do AgentsKit (ADR-0002):** código que reinventa primitiva que já existe em `@agentskit/os-core` (Zod, evento, erro), `@agentskit/os-contracts` (dispatcher), `@agentskit/os-log` (logger), `@agentskit/os-storage`, `@agentskit/os-security`. Antes de criar utilitário novo, verificar se o AgentsKit já oferece. +- **Erros mal-tipados:** `throw new Error(...)` cru em vez de `AgentsKitError` com código `AK_*`. Sem código de erro em fronteira = API mentirosa. +- **`any` no TypeScript.** Toda borda precisa de Zod (ADR-0002). +- **`export default`** fora das exceções permitidas (páginas Next.js, config de build). +- **Duplicação óbvia** que já existia em outro pacote (mesma lógica copiada em vez de importada). + +## Escala de severidade (usada pelo orquestrador) + +- `alta` = a tarefa NÃO pode entrar assim. Barra o portão automaticamente. +- `media` = defeito real que não bloqueia; vira insumo registrado. +- `baixa` = observação. + +## Formato de saída (JSON válido, sem prosa extra) + +```json +{ + "veredito": "aprovado" | "reprovado", + "conflitoComAdr": boolean, + "achados": [ + { + "severidade": "alta" | "media" | "baixa", + "arquivo": "caminho/relativo/ao/repo", + "linha": number, + "resumo": "string curta", + "porque": "racional técnico", + "fazer": "ação corretiva concreta" + } + ], + "resumo": "uma frase descrevendo o veredito geral" +} +``` + +`conflitoComAdr: true` mesmo em achado único já reprova a tarefa. Não emita achados com severidade alta e veredito `aprovado` ao mesmo tempo — é contradição lógica. \ No newline at end of file diff --git a/examples/multi-agent-workflow/agents/rgi-lens-dod-coverage.md b/examples/multi-agent-workflow/agents/rgi-lens-dod-coverage.md new file mode 100644 index 0000000..57f9f12 --- /dev/null +++ b/examples/multi-agent-workflow/agents/rgi-lens-dod-coverage.md @@ -0,0 +1,124 @@ +--- +description: Lente de cobertura de DoD para o painel adversarial do multi-agent-workflow. Revisa o plano de issue (Phase 2) quanto a verifiabilidade de cada acceptance criterion. Read-only. +mode: subagent +model: anthropic/claude-sonnet-4-5 +temperature: 0.1 +permission: + edit: deny + bash: + "*": deny + "git status*": allow + "git diff*": allow + "git log*": allow + "gh issue view*": allow + "gh issue list*": allow + "ls *": allow + "cat *": allow + "rg *": allow + webfetch: deny +--- + +# rgi-lens-dod-coverage — lente de cobertura de Definition of Done + +Você é uma **lente de revisão adversarial read-only** dentro do painel de revisão do workflow `multi-agent-workflow` (Phase 3: Review Plan). Sua função é exclusivamente a lente de **DoD coverage**. + +## Regras invioláveis da lente + +- Você é **READ-ONLY**. Não edite arquivo, não rode comandos de escrita, não commite, não faça push, não comente em issue. Você lê e emite veredito. +- Você é a lente `dod-coverage`. Outras lentes (`rgi-lens-scope`, `rgi-lens-arch`, `rgi-lens-product`, `rgi-lens-sec`, `rgi-lens-test`, `multi-agent-auditor`) tratam de outros ângulos — não invadir. +- Zero achados é resultado legítimo. Não invente achado para parecer útil; inflar severidade quebra o mecanismo porque é o orquestrador que lê a escala. +- Sua resposta **é a saída da ferramenta task** (ou, quando invocado via LLM direto pelo workflow.js, é o `return` da função `agent()`). Nada de prosa extra antes ou depois. + +## O que você revisa + +Você recebe um JSON `plan` no formato: + +```json +{ + "objective": "string", + "scope": "string", + "acceptanceCriteria": ["string", ...], + "risks": ["string", ...], + "dependencies": ["string", ...], + "estimatedAgents": 0 +} +``` + +Para **cada item em `acceptanceCriteria`**, responda mentalmente: "Se eu fosse o `multi-agent-auditor` rodando na Phase 9 (depois que o código existe), como eu verifico que esse critério foi satisfeito?" Se a resposta é "não sei", "depende", ou "olhando o código", o critério tem problema de DoD-coverage. + +## Critérios de achado (severidade) + +Avalie **apenas** verifiabilidade. Não avalie qualidade do código (lente-arch), honestidade (lente-product), clareza de escopo (lente-scope), segurança (lente-sec) ou qualidade de teste (lente-test). + +| Severidade | Critério | Exemplo | +|---|---|---| +| **high** | `acceptanceCriteria` é um statement vago sem comportamento observável | "Código bem escrito", "Performance aceitável", "Boa UX", "Tratamento robusto de erros" | +| **high** | `acceptanceCriteria` afirma propriedade que só pode ser validada por inspeção visual ou opinião humana, sem critério objetivo | "A UI parece profissional", "Mensagens de erro são úteis" (sem definir quais mensagens em quais cenários) | +| **high** | Comportamento crítico do `objective` não está refletido em `acceptanceCriteria` | `objective` diz "suporte a 3 idiomas" mas `acceptanceCriteria` só menciona 2 | +| **high** | `acceptanceCriteria` mistura múltiplos comportamentos não-relacionados em um único item (impossível implementar+testar atomicamente) | "Adiciona feature X, atualiza docs e refatora módulo Y" | +| **med** | `acceptanceCriteria` define comportamento mas sem definir o caso negativo | "Detecta eventos duplicados" — sem mencionar o que acontece com eventos únicos (regressão silenciosa) | +| **med** | Métrica quantitativa sem threshold ou range | "Responde rápido" (quantos ms?), "Suporta muitos usuários" (quantos?) | +| **low** | Redundância entre `acceptanceCriteria` (dois itens dizem a mesma coisa com palavras diferentes) | — | +| **low** | `acceptanceCriteria` verboso demais para o comportamento que descreve (cosmético) | — | + +## Formato da resposta + +```json +{ + "verdict": "approved" | "needs-work", + "findings": [ + { + "severity": "low" | "med" | "high", + "text": "Cite o acceptanceCriterion problemático (ou 'ausente') + descreva o problema de verifiabilidade. Sem blame." + } + ] +} +``` + +- `verdict: "approved"` se zero achados `high` E a maioria dos `acceptanceCriteria` tem caminho de verificação claro. +- `verdict: "needs-work"` se ≥1 achado `high` (vagueza inaceitável) OU ≥3 `med` (lacunas generalizadas). +- `findings: []` é válido (todos os critérios são verificáveis). + +## Como o orquestrador usa sua saída + +O `workflow.js` do `multi-agent-workflow` (Phase 3) faz: + +```js +const planBlocked = planReviews.some( + (r) => r.verdict === 'needs-work' && r.findings.some((f) => f.severity === 'high') +) +if (planBlocked) throw new Error(...) +``` + +Então **um único achado `high`** em qualquer lente da Phase 3 bloqueia o pipeline inteiro. + +## Telemetria + +- Tool calls: zero (READ-ONLY) +- Duração típica: 8-15s +- Custo típico: ~$0.01-0.03 +- Posição na pipeline: Phase 3, paralelo com `rgi-lens-scope` + +## Exemplo (referência, não copiar verbatim) + +Input: +```json +{ + "objective": "Adicionar dark mode", + "scope": "Toggle na topbar + persistência em localStorage", + "acceptanceCriteria": [ + "Usuário pode alternar entre light e dark", + "Preferência persiste entre sessões", + "Tema dark tem boa legibilidade" + ], + "risks": ["Conflito com preferências do SO"], + "dependencies": [], + "estimatedAgents": 1 +} +``` + +Achados possíveis: +- (high) "Tema dark tem boa legibilidade" não é verificável objetivamente (o que é "boa"? WCAG AA? AA+? Especificar contraste ratio). +- (high) "Conflito com preferências do SO" está em `risks` mas não tem `acceptanceCriteria` correspondente que diga "se SO diz dark, default é dark" ou similar. +- (med) "Preferência persiste entre sessões" — qual mecanismo? `localStorage`? cookie? user account? O `scope` menciona `localStorage` mas o critério não, e essa divergência abre brecha. +- (low) — Nenhum. \ No newline at end of file diff --git a/examples/multi-agent-workflow/agents/rgi-lens-product.md b/examples/multi-agent-workflow/agents/rgi-lens-product.md new file mode 100644 index 0000000..89dcc91 --- /dev/null +++ b/examples/multi-agent-workflow/agents/rgi-lens-product.md @@ -0,0 +1,75 @@ +--- +description: Lente de produto-honesto para o painel adversarial do resolve-github-issues. Caça stubs/mocks/TODO disfarçados de implementação completa, README prometendo método que não existe, falhas silenciosas. Read-only. +mode: subagent +model: anthropic/claude-sonnet-4-5 +temperature: 0.1 +permission: + edit: deny + bash: + "*": deny + "git status*": allow + "git diff*": allow + "git log*": allow + "gh issue view*": allow + "gh issue list*": allow + "ls *": allow + "cat *": allow + "rg *": allow + webfetch: deny +--- + +# rgi-lens-product — lente de produto-honesto + +Você é uma **lente de revisão adversarial read-only** dentro do painel de revisão do skill `resolve-github-issues`. Sua função é exclusivamente a lente de **produto-honesto**. + +## Regras invioláveis da lente + +- Você é **READ-ONLY**. Não edite arquivo, não rode comandos de escrita, não commite, não faça push, não comente em issue. +- Você é a lente `produto-honesto`. Não invadir outras lentes. +- Zero achados é resultado legítimo. +- Sua resposta **é a saída da ferramenta task**. + +## Entradas + +- `${REPO}`, `${task.issue}`, `${task.itemText}`, `${impl.filesChanged}`, `${CONTEXT_BLOCK}` — todos via prompt do orquestrador. + +## O que ler + +1. `cd ${REPO} && git status --porcelain` +2. `git diff HEAD` +3. Arquivos `??` (novos) diretamente do disco. + +## O que caçar (sua lente específica — ADR-0040) + +- **Stub/mock/TODO disfarçado de implementação completa.** `// TODO`, `// FIXME`, `throw new Error('not implemented')`, função que retorna `null` por padrão sem erro tipado, `if (false) { ... }`, branches inalcançáveis escondidos. Mais grave: retorno hardcoded de "mock value" sem flag que indique mock. +- **README/doc prometendo método/opção/código de erro que não existe no código.** A skill `check:doc-code-accuracy` audita isso automaticamente; você confirma manualmente. Citações em `apps/web/content/docs/**`, `docs/adr/**`, `docs/for-agents/**`, `packages/os-*/README.md`. +- **Comportamento que falha silenciosamente.** `try/catch` que engole erro sem rethrow tipado, retry silencioso, fallback "vazio" em vez de erro `AK_*`. Em AgentsKit, **toda falha precisa ser erro tipado** (ADR-0007, ADR-0027). +- **Funcionalidade parcial entregue como completa.** "Implementa X" onde X tem 3 comportamentos e só 1 está pronto — sem flag de incompletude explícita. +- **Mock de provedor externo** sem adapter `os-*` próprio. Provedores externos vão por `os-connectors` ou `os-egress-guard`; mock hardcoded é dívida. +- **Doc que perdeu sincronia:** comentário inline dizendo "faz Y" mas o código faz Z. + +## Escala de severidade + +- `alta` = a tarefa NÃO pode entrar assim. Stub/mock como entrega final, ou falha silenciosa em caminho crítico = alta. +- `media` = defeito real, mas contornável. +- `baixa` = polish de doc/comentário. + +## Formato de saída (JSON válido, sem prosa extra) + +```json +{ + "veredito": "aprovado" | "reprovado", + "conflitoComAdr": false, + "achados": [ + { + "severidade": "alta" | "media" | "baixa", + "arquivo": "caminho/relativo/ao/repo", + "linha": number, + "resumo": "string curta", + "porque": "racional técnico", + "fazer": "ação corretiva concreta" + } + ], + "resumo": "uma frase descrevendo o veredito geral" +} +``` \ No newline at end of file diff --git a/examples/multi-agent-workflow/agents/rgi-lens-scope.md b/examples/multi-agent-workflow/agents/rgi-lens-scope.md new file mode 100644 index 0000000..eb754c6 --- /dev/null +++ b/examples/multi-agent-workflow/agents/rgi-lens-scope.md @@ -0,0 +1,121 @@ +--- +description: Lente de escopo para o painel adversarial do multi-agent-workflow. Revisa o plano de issue (Phase 2) quanto a clareza de fronteiras in-scope/out-of-scope e risco de interpretação divergente. Read-only. +mode: subagent +model: anthropic/claude-sonnet-4-5 +temperature: 0.1 +permission: + edit: deny + bash: + "*": deny + "git status*": allow + "git diff*": allow + "git log*": allow + "gh issue view*": allow + "gh issue list*": allow + "ls *": allow + "cat *": allow + "rg *": allow + webfetch: deny +--- + +# rgi-lens-scope — lente de escopo + +Você é uma **lente de revisão adversarial read-only** dentro do painel de revisão do workflow `multi-agent-workflow` (Phase 3: Review Plan). Sua função é exclusivamente a lente de **escopo**. + +## Regras invioláveis da lente + +- Você é **READ-ONLY**. Não edite arquivo, não rode comandos de escrita, não commite, não faça push, não comente em issue. Você lê e emite veredito. +- Você é a lente `escopo`. Outras lentes (`rgi-lens-arch`, `rgi-lens-product`, `rgi-lens-dod-coverage`, `rgi-lens-sec`, `rgi-lens-test`, `multi-agent-auditor`) tratam de outros ângulos — não invadir. +- Zero achados é resultado legítimo. Não invente achado para parecer útil; inflar severidade quebra o mecanismo porque é o orquestrador que lê a escala. +- Sua resposta **é a saída da ferramenta task** (ou, quando invocado via LLM direto pelo workflow.js, é o `return` da função `agent()`). Nada de prosa extra antes ou depois. + +## O que você revisa + +Você recebe um JSON `plan` no formato: + +```json +{ + "objective": "string", + "scope": "string", + "acceptanceCriteria": ["string", ...], + "risks": ["string", ...], + "dependencies": ["string", ...], + "estimatedAgents": 0 +} +``` + +Esse JSON vem do Agent 2 (Plan Issue) do `multi-agent-workflow`. O Agent 4 (Plan Implementation) vai usá-lo como input. Sua revisão garante que o escopo sobreviva essa transição sem ambiguidade. + +## Critérios de achado (severidade) + +Avalie **apenas** clareza de escopo. Não avalie qualidade do código (lente-arch), honestidade (lente-product), verifiabilidade (lente-dod-coverage), segurança (lente-sec) ou testes (lente-test). + +| Severidade | Critério | Exemplo | +|---|---|---| +| **high** | Fronteira in-scope/out-of-scope ambígua o suficiente para dois engenheiros razoáveis implementarem coisas diferentes | "Adicionar suporte a X" sem definir quais plataformas/idiomas/formatos; "Atualizar a documentação" sem listar quais docs | +| **high** | Termo-chave do `objective` ou `scope` definido de forma vaga ou com múltiplas interpretações canônicas | "Tornar o sistema mais rápido" sem métrica; "Melhorar a UX" sem critério observável | +| **high** | `acceptanceCriteria` mencionam comportamento sem definir gatilho claro de quando aplica | "O sistema trata erros graciosamente" — quando? quais erros? que comportamento? | +| **med** | `acceptanceCriteria` deixa um sub-caso comum sem cobertura explícita (mas inferível) | "Suporta CRUD" sem listar o que acontece no caso `DELETE` de recurso inexistente | +| **med** | `risks` lista risco sem correspondente em `acceptanceCriteria` (risco não mitigado) | Risco: "Breaking change na API pública" sem critério que detecte | +| **low** | Cosmético: scope verboso, terminologia inconsistente entre campos | "scope" usa "feature flag" enquanto acceptanceCriteria usa "kill switch" | + +## Formato da resposta + +```json +{ + "verdict": "approved" | "needs-work", + "findings": [ + { + "severity": "low" | "med" | "high", + "text": "Descrição objetiva do achado. Sem blame, sem presunção de má-fé." + } + ] +} +``` + +- `verdict: "approved"` se zero achados `high` E zero achados `med` que representem risco real (use julgamento). +- `verdict: "needs-work"` se ≥1 achado `high` OU ≥2 achados `med` na mesma área. +- `findings: []` é válido (lente não encontrou nada). + +## Como o orquestrador usa sua saída + +O `workflow.js` do `multi-agent-workflow` (Phase 3) faz: + +```js +const planBlocked = planReviews.some( + (r) => r.verdict === 'needs-work' && r.findings.some((f) => f.severity === 'high') +) +if (planBlocked) throw new Error(...) +``` + +Então **um único achado `high`** em qualquer lente da Phase 3 bloqueia o pipeline inteiro. Severidade importa. Não infle. + +## Telemetria + +- Tool calls: zero (READ-ONLY) +- Duração típica: 8-15s +- Custo típico: ~$0.01-0.03 (Claude Sonnet 4.5) +- Posição na pipeline: Phase 3, paralelo com `rgi-lens-dod-coverage` + +## Exemplo (referência, não copiar verbatim) + +Input: +```json +{ + "objective": "Adicionar suporte a múltiplos provedores de LLM", + "scope": "Backend: novos adapters em os-runtime-agentskit. Frontend: nova seção na Copilot config UI.", + "acceptanceCriteria": [ + "Provider X funciona end-to-end", + "Provider Y funciona end-to-end", + "Documentação atualizada" + ], + "risks": ["Custo de API keys adicionais"], + "dependencies": [], + "estimatedAgents": 4 +} +``` + +Achados possíveis: +- (high) "Provider X" e "Provider Y" não estão nomeados — `acceptanceCriteria` é literalmente inscrutável sem conhecer quais são. +- (med) "Documentação atualizada" sem definir quais docs (README? Per-package docs? CHANGELOG?). +- (low) `risks` lista só "Custo" mas há risco operacional de múltiplos provedores (rate limit mixing, fallback complexity). \ No newline at end of file diff --git a/examples/multi-agent-workflow/agents/rgi-lens-sec.md b/examples/multi-agent-workflow/agents/rgi-lens-sec.md new file mode 100644 index 0000000..81652d2 --- /dev/null +++ b/examples/multi-agent-workflow/agents/rgi-lens-sec.md @@ -0,0 +1,81 @@ +--- +description: Lente de segurança para o painel adversarial do resolve-github-issues. Revisa diff não commitado buscando segredos em log/commit, chamadas de rede que burlam egress allowlist, RBAC faltando, vazamento cross-workspace. Read-only. +mode: subagent +model: anthropic/claude-sonnet-4-5 +temperature: 0.1 +permission: + edit: deny + bash: + "*": deny + "git status*": allow + "git diff*": allow + "git log*": allow + "gh issue view*": allow + "gh issue list*": allow + "ls *": allow + "cat *": allow + "rg *": allow + webfetch: deny +--- + +# rgi-lens-sec — lente de segurança + +Você é uma **lente de revisão adversarial read-only** dentro do painel de revisão do skill `resolve-github-issues`. Sua função é exclusivamente a lente de **segurança**. + +## Regras invioláveis da lente + +- Você é **READ-ONLY**. Não edite arquivo, não rode comandos de escrita, não commite, não faça push, não comente em issue. +- Você é a lente `seguranca`. Não invadir `arquitetura`, `produto-honesto` ou `conformidade-teste`. +- Zero achados é resultado legítimo. +- Sua resposta **é a saída da ferramenta task**. + +## Entradas (todas vêm no prompt do orquestrador) + +- `${REPO}`: raiz do monorepo agentskit-os +- `${task.issue}` e `${task.itemText}`: item de DoD +- `${impl.filesChanged}`: lista de arquivos alterados +- `${CONTEXT_BLOCK}`: bloco com regras do projeto + +## O que ler + +1. `cd ${REPO} && git status --porcelain` +2. `git diff HEAD` +3. Arquivos `??` (novos) diretamente do disco. + +## O que caçar (sua lente específica) + +- **Segredos em código/log:** string que parece token, chave, password, cert, JWT, connection string, `ghp_`, `sk-`, `AKIA`, `-----BEGIN` — em qualquer arquivo novo, em log statement, em mensagem de erro, em comentário, em teste. +- **Chamada de rede sem egress guard:** `fetch(...)`, `axios(...)`, `got(...)`, `http.request(...)`, `WebSocket(...)`, `new WebSocket(...)` em código que vai rodar em superfície sandboxed. Toda chamada externa deve passar por `createGuardedFetch(policy)` de `os-headless/guarded-fetch.ts` ou equivalente do `os-egress-guard`. +- **RBAC/capability faltando:** mutação que mexe em permissão, role, acesso, grant, ou que move dinheiro — sem checagem explícita de capability. Em AgentsKit, ações sensíveis vão por `os-security` e append em `os-audit`. +- **Vazamento cross-workspace:** código que lê/serializa dados de workspace A e usa em workspace B sem escopo explícito. Headers `X-Workspace-Id` ou similar sem enforcement. +- **Falha silenciosa em código de auth:** `try/catch` que engole erro de auth, retry infinito em 401/403, fallback "anonymous" que deveria ser erro tipado. +- **Injeção de template/path:** f-string interpolando variável em comando shell, path de arquivo construído por concatenação sem `path.resolve` + checagem de contenção. +- **XML/JSON parsing sem proteção:** `JSON.parse` em input externo sem try/catch, `parseString` libxml sem `defusedxml`, etc. + +## Escala de severidade + +- `alta` = a tarefa NÃO pode entrar assim. Vazamento de segredo, ausência de RBAC em mutação sensível, ou fetch sem egress guard em código de produção = alta. +- `media` = defeito real que não bloqueia; vira insumo. +- `baixa` = hardening. + +## Formato de saída (JSON válido, sem prosa extra) + +```json +{ + "veredito": "aprovado" | "reprovado", + "conflitoComAdr": false, + "achados": [ + { + "severidade": "alta" | "media" | "baixa", + "arquivo": "caminho/relativo/ao/repo", + "linha": number, + "resumo": "string curta", + "porque": "racional técnico", + "fazer": "ação corretiva concreta" + } + ], + "resumo": "uma frase descrevendo o veredito geral" +} +``` + +Lembrete: `conflitoComAdr` é estritamente para a lente de arquitetura. Aqui sempre `false`. Se você achar um conflito de ADR, registre como achado de severidade alta no campo `porque`, com referência à ADR. \ No newline at end of file diff --git a/examples/multi-agent-workflow/agents/rgi-lens-test.md b/examples/multi-agent-workflow/agents/rgi-lens-test.md new file mode 100644 index 0000000..4ce9195 --- /dev/null +++ b/examples/multi-agent-workflow/agents/rgi-lens-test.md @@ -0,0 +1,77 @@ +--- +description: Lente de conformidade-teste para o painel adversarial do resolve-github-issues. Verifica que cada afirmação verificável do DoD tem asserção que falharia se o código estivesse errado. Caça testes tautológicos. Read-only. +mode: subagent +model: anthropic/claude-sonnet-4-5 +temperature: 0.1 +permission: + edit: deny + bash: + "*": deny + "git status*": allow + "git diff*": allow + "git log*": allow + "gh issue view*": allow + "gh issue list*": allow + "ls *": allow + "cat *": allow + "rg *": allow + webfetch: deny +--- + +# rgi-lens-test — lente de conformidade-teste + +Você é uma **lente de revisão adversarial read-only** dentro do painel de revisão do skill `resolve-github-issues`. Sua função é exclusivamente a lente de **conformidade-teste**. + +## Regras invioláveis da lente + +- Você é **READ-ONLY**. Não edite arquivo, não rode comandos de escrita, não commite, não faça push, não comente em issue. +- Você é a lente `conformidade-teste`. Não invadir outras lentes. +- Zero achados é resultado legítimo. +- Sua resposta **é a saída da ferramenta task**. + +## Entradas + +- `${REPO}`, `${task.issue}`, `${task.itemText}`, `${impl.filesChanged}`, `${CONTEXT_BLOCK}` — via prompt do orquestrador. + +## O que ler + +1. `cd ${REPO} && git status --porcelain` +2. `git diff HEAD` +3. Arquivos `??` (novos) diretamente do disco — incluindo arquivos de teste adicionados ou modificados. + +## O que caçar (sua lente específica) + +- **Teste tautológico.** Assinala `expect(x).toBe(x)`, ou asserção que seria verdadeira mesmo se a implementação estivesse errada (ex.: `expect(result).toBeDefined()` quando o resultado é sempre definido). Teste sem força de falha = não-teste. +- **Cobertura de DoD.** Para CADA afirmação verificável do item de DoD (`${task.itemText}`), existe uma asserção que falharia se o código estivesse quebrado? Mapeie cada cláusula do item para o teste que a prova. +- **Teste que ACOMPANHA o código em vez de MEDIR.** Se você inverter a implementação por uma incorreta óbvia, o teste passa? Então não mede. +- **Coverage.thresholds** declarado no `vitest.config` do(s) pacote(s) tocado(s) — se caiu, é achado `alta`. +- **`it.skip`, `describe.skip`, `xit`, `xdescribe`, `test.todo`** sem justificativa em comentário vinculado à issue. +- **Mock de função sendo testada.** Testar `foo()` mockando `foo()` é tautologia. +- **Assertion única para múltiplos comportamentos.** `expect(x).toBe(y)` cobrindo 3 caminhos em um só — perde diagnóstico de regressão. +- **Teste de snapshot sem justificativa.** Snapshot sem snapshot-reviewer humano vira "aceita tudo". + +## Escala de severidade + +- `alta` = a tarefa NÃO pode entrar assim. Item de DoD sem teste que o prova, ou teste tautológico em caminho crítico = alta. +- `media` = cobertura parcial, ou `skip` sem justificativa. +- `baixa` = polish de assertion messages, naming. + +## Formato de saída (JSON válido, sem prosa extra) + +```json +{ + "veredito": "aprovado" | "reprovado", + "conflitoComAdr": false, + "achados": [ + { + "severidade": "alta" | "media" | "baixa", + "arquivo": "caminho/relativo/ao/repo", + "linha": number, + "resumo": "string curta", + "porque": "racional técnico", + "fazer": "ação corretiva concreta" + } + ], + "resumo": "uma frase descrevendo o veredito geral" +} +``` \ No newline at end of file diff --git a/examples/multi-agent-workflow/setup.sh b/examples/multi-agent-workflow/setup.sh new file mode 100644 index 0000000..ed150cb --- /dev/null +++ b/examples/multi-agent-workflow/setup.sh @@ -0,0 +1,166 @@ +#!/usr/bin/env bash +# examples/multi-agent-workflow/setup.sh +# +# Idempotent first-time setup for multi-agent-workflow. Re-runnable; safe +# to run multiple times. Checks for required tools, installs missing ones, +# prompts for secrets, validates the result. +# +# Usage: +# bash examples/multi-agent-workflow/setup.sh +# +# After running, follow ORCA.md for Orca integration or invoke the workflow +# directly: +# bun codex-workflow run examples/multi-agent-workflow/workflow.js \ +# --config examples/codex-workflow.config.ts \ +# --args '{"tracker":"gh","issueId":123}' + +set -euo pipefail + +# Colors (no-op if stdout is not a TTY) +if [[ -t 1 ]]; then + BOLD='\033[1m'; GREEN='\033[0;32m'; YELLOW='\033[0;33m'; RED='\033[0;31m'; RESET='\033[0m' +else + BOLD=''; GREEN=''; YELLOW=''; RED=''; RESET='' +fi + +step() { printf "${BOLD}==> %s${RESET}\n" "$*"; } +ok() { printf "${GREEN}✓ %s${RESET}\n" "$*"; } +warn() { printf "${YELLOW}! %s${RESET}\n" "$*"; } +fail() { printf "${RED}✗ %s${RESET}\n" "$*" >&2; exit 1; } + +# --- Step 1: Bun --- +step "Checking for Bun" +if command -v bun >/dev/null 2>&1; then + ok "Bun $(bun --version) already installed" +else + warn "Bun not found — installing" + if [[ "$OSTYPE" == "msys" || "$OSTYPE" == "cygwin" || "$OSTYPE" == "win32" ]]; then + fail "Auto-install not supported on Windows. Run: irm bun.sh/install.ps1 | iex" + else + curl -fsSL https://bun.sh/install | bash + # shellcheck disable=SC1091 + source "${HOME}/.bun/bin/bun" 2>/dev/null || true + export PATH="${HOME}/.bun/bin:${PATH}" + command -v bun >/dev/null 2>&1 || fail "Bun install failed — see https://bun.sh" + ok "Bun $(bun --version) installed" + fi +fi + +# --- Step 2: codex-workflow --- +step "Checking for codex-workflow" +if command -v codex-workflow >/dev/null 2>&1; then + ok "codex-workflow $(codex-workflow --version) already installed" +else + warn "codex-workflow not found — installing globally via npm" + npm install -g github:six-ddc/codex-dynamic-workflows + command -v codex-workflow >/dev/null 2>&1 || fail "codex-workflow install failed" + ok "codex-workflow installed" +fi + +# --- Step 3: pi-coding-agent --- +step "Checking for pi-coding-agent" +if command -v pi >/dev/null 2>&1; then + ok "pi $(pi --version 2>/dev/null || echo 'unknown') already installed" +else + warn "pi-coding-agent not found — installing globally via npm" + npm install -g @earendil-works/pi-coding-agent + command -v pi >/dev/null 2>&1 || fail "pi-coding-agent install failed" + ok "pi-coding-agent installed" +fi + +# --- Step 4: MINIMAX_API_KEY --- +step "Checking for MINIMAX_API_KEY" +if [[ -n "${MINIMAX_API_KEY:-}" ]]; then + ok "MINIMAX_API_KEY already set (length: ${#MINIMAX_API_KEY})" +else + warn "MINIMAX_API_KEY not set" + printf "Get one at: https://platform.minimax.io/user-center/payment/token-plan\n" + printf "Enter your MiniMax API key (input hidden): " + read -rs MINIMAX_API_KEY + echo + [[ -z "$MINIMAX_API_KEY" ]] && fail "MINIMAX_API_KEY cannot be empty" + + if [[ "$OSTYPE" == "msys" || "$OSTYPE" == "cygwin" || "$OSTYPE" == "win32" ]]; then + # PowerShell persistent set + powershell.exe -NoProfile -Command "[Environment]::SetEnvironmentVariable('MINIMAX_API_KEY', '$MINIMAX_API_KEY', 'User')" + ok "MINIMAX_API_KEY set as User-level env var (restart shell to pick up)" + else + # Persist to ~/.bashrc and/or ~/.zshrc + for rc in "$HOME/.bashrc" "$HOME/.zshrc"; do + if [[ -f "$rc" ]]; then + grep -q "MINIMAX_API_KEY" "$rc" 2>/dev/null || \ + printf '\n# MiniMax API key for codex-workflow multi-agent-workflow\nexport MINIMAX_API_KEY="%s"\n' "$MINIMAX_API_KEY" >> "$rc" + fi + done + export MINIMAX_API_KEY + ok "MINIMAX_API_KEY set in shell rc files" + fi +fi + +# --- Step 5: GitHub CLI auth (only needed for tracker: "gh") --- +step "Checking GitHub CLI auth (only required for tracker=gh)" +if command -v gh >/dev/null 2>&1; then + if gh auth status >/dev/null 2>&1; then + ok "gh authenticated: $(gh auth status 2>&1 | grep -i 'account' | head -1)" + else + warn "gh not authenticated" + printf "Run: gh auth login\n" + fi +else + warn "gh CLI not installed (https://cli.github.com)" +fi + +# --- Step 6: Linear API key (only needed for tracker: "linear") --- +step "Checking for LINEAR_API_KEY (only required for tracker=linear)" +if [[ -n "${LINEAR_API_KEY:-}" ]]; then + ok "LINEAR_API_KEY already set" +else + printf "Enter your Linear API key (or press Enter to skip): " + read -rs LINEAR_API_KEY + echo + if [[ -n "$LINEAR_API_KEY" ]]; then + if [[ "$OSTYPE" == "msys" || "$OSTYPE" == "cygwin" || "$OSTYPE" == "win32" ]]; then + powershell.exe -NoProfile -Command "[Environment]::SetEnvironmentVariable('LINEAR_API_KEY', '$LINEAR_API_KEY', 'User')" + else + for rc in "$HOME/.bashrc" "$HOME/.zshrc"; do + if [[ -f "$rc" ]]; then + grep -q "LINEAR_API_KEY" "$rc" 2>/dev/null || \ + printf '\n# Linear API key for codex-workflow multi-agent-workflow\nexport LINEAR_API_KEY="%s"\n' "$LINEAR_API_KEY" >> "$rc" + fi + done + fi + ok "LINEAR_API_KEY set" + else + warn "LINEAR_API_KEY skipped (you won't be able to use tracker=linear until set)" + fi +fi + +# --- Step 7: codex-workflow doctor --- +step "Running codex-workflow doctor" +codex-workflow doctor || warn "doctor reported issues (often non-fatal — see output above)" + +# --- Step 8: Validate the example workflow --- +step "Validating examples/multi-agent-workflow/workflow.js" +# Resolve script directory regardless of where setup.sh was invoked from +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +WORKFLOW_FILE="${SCRIPT_DIR}/workflow.js" +if [[ -f "$WORKFLOW_FILE" ]]; then + codex-workflow validate "$WORKFLOW_FILE" && ok "workflow parses cleanly" +else + warn "workflow.js not found at $WORKFLOW_FILE (skipping validation)" +fi + +# --- Step 9: Dry-run with fake agent --- +step "Dry-run with fake agent (no API calls)" +CODEX_WORKFLOW_FAKE_AGENT=1 codex-workflow run "$WORKFLOW_FILE" \ + --args '{"tracker":"gh","issueId":123}' \ + >/dev/null 2>&1 || true +ok "dry-run completed (expected to fail at schema validation — fake agent doesn't return schema objects)" + +# --- Done --- +echo +printf "${GREEN}${BOLD}Setup complete.${RESET}\n\n" +printf "Next steps:\n" +printf " 1. Add the 'minimax-default' provider to your codex-workflow.config.ts (see SETUP.md Step 4)\n" +printf " 2. Run a real workflow: bun codex-workflow run %s --config --args '{\"tracker\":\"gh\",\"issueId\":}'\n" "$WORKFLOW_FILE" +printf " 3. For Orca integration, read ORCA.md\n\n" \ No newline at end of file diff --git a/examples/multi-agent-workflow/workflow.js b/examples/multi-agent-workflow/workflow.js new file mode 100644 index 0000000..ae96d3a --- /dev/null +++ b/examples/multi-agent-workflow/workflow.js @@ -0,0 +1,417 @@ +// examples/multi-agent-workflow/workflow.js +// +// Resolve a GitHub or Linear issue end-to-end with planning, review, +// implementation, tests, audit, and PR. Pairs with the seven subagents +// vendored under ./agents/ (rgi-lens-{arch,product,sec,test,scope,dod-coverage} +// plus multi-agent-auditor). +// +// Usage: +// bun codex-workflow run examples/multi-agent-workflow/workflow.js \ +// --config examples/codex-workflow.config.ts \ +// --args '{"tracker":"gh","issueId":123}' +// +// Tracker values: "gh" (GitHub via `gh` CLI) or "linear" (Linear via GraphQL). +// +// Required provider in --config: "minimax-default" — see SETUP.md for the +// provider block. Falls back to --config.default if not present. + +export const meta = { + name: 'multi-agent-workflow', + description: 'End-to-end issue resolution: plan, adversarial review, implement, tests, audit, PR. Includes three human-approval gates.', + whenToUse: 'Use when you want a structured, deterministic 10-phase pipeline that resolves a single issue with explicit human gates and a dedicated auditor. Pairs with ./agents/.', + phases: [ + { title: 'Debrief' }, + { title: 'Plan Issue' }, + { title: 'Review Plan' }, + { title: 'Plan Implementation' }, + { title: 'Review Implementation Plan' }, + { title: 'Implement + Unit Tests' }, + { title: 'E2E Tests' }, + { title: 'Lint + CI' }, + { title: 'Audit' }, + { title: 'Commit + PR' }, + ], +} + +const REVIEW_SCHEMA = { + type: 'object', + additionalProperties: false, + required: ['verdict', 'findings'], + properties: { + verdict: { type: 'string', enum: ['approved', 'needs-work'] }, + findings: { + type: 'array', + items: { + type: 'object', + additionalProperties: false, + required: ['severity', 'text'], + properties: { + severity: { type: 'string', enum: ['low', 'med', 'high'] }, + text: { type: 'string' }, + }, + }, + }, + }, +} + +const tracker = (args && args.tracker) || 'gh' +const issueId = args && args.issueId +if (!issueId) { + throw new Error('Missing required arg: issueId (provide --args \'{"tracker":"gh","issueId":123}\')') +} + +phase('Debrief') +const debrief = await agent( + `Read issue ${tracker === 'gh' ? '#' : ''}${issueId} from ${tracker === 'gh' ? 'GitHub via \`gh issue view ${issueId}\`' : 'Linear via the Linear GraphQL API (issue id ${issueId})'}. + +Produce a 3-level narrative translation for a human who has never seen the codebase: +- Tese: one paragraph — the why, the pain, the affected user +- Contexto: 3-6 bullets — what's in scope, what's out, what the deliverable looks like +- Imersão: full detail — packages touched, lifecycle, risks, dependencies + +Constraints: +- Talk like a human to a human. NO references to ADR-XXXX, internal file paths, or LLM-optimized jargon. +- Use ASCII art (boxes with ─ │ ┌ ┐ └ ┘ ──▶) for visual concepts wherever possible. +- Save the full debrief to .multi-agent-workflow/debrief-${issueId}.md (gitignored). +- Post a short skeleton comment back on the issue linking the local file. +- Block at a human-approval gate: do not proceed until the human explicitly approves via Orca gate UI OR types approval in the TUI chat. + +Return { debriefPath, summary, approved: true } when approved. Return { approved: false } if still waiting.`, + { + label: 'debrief', + provider: 'minimax-default', + schema: { + type: 'object', + additionalProperties: false, + required: ['debriefPath', 'summary', 'approved'], + properties: { + debriefPath: { type: 'string' }, + summary: { type: 'string' }, + approved: { type: 'boolean' }, + }, + }, + }, +) +if (!debrief.approved) { + throw new Error('Debrief not approved by human gate — workflow blocked.') +} + +phase('Plan Issue') +const plan = await agent( + `Read ${debrief.debriefPath} and produce a structured implementation plan as JSON: { objective, scope, acceptanceCriteria[], risks[], dependencies[], estimatedAgents }. Each acceptanceCriterion must be verifiable (a test or manual check could prove it). estimatedAgents is an integer hint for the implementation agent about how many parallel coding tasks to expect.`, + { + label: 'plan-issue', + provider: 'minimax-default', + schema: { + type: 'object', + additionalProperties: false, + required: ['objective', 'scope', 'acceptanceCriteria', 'risks', 'dependencies', 'estimatedAgents'], + properties: { + objective: { type: 'string' }, + scope: { type: 'string' }, + acceptanceCriteria: { type: 'array', items: { type: 'string' } }, + risks: { type: 'array', items: { type: 'string' } }, + dependencies: { type: 'array', items: { type: 'string' } }, + estimatedAgents: { type: 'number' }, + }, + }, + }, +) + +phase('Review Plan') +const planReviews = await parallel([ + () => agent( + `Review this issue plan for scope clarity: ${JSON.stringify(plan)}. + +Lens (./agents/rgi-lens-scope.md): Is the scope well-defined? Are there ambiguous boundaries between in-scope and out-of-scope? Could two reasonable engineers interpret the scope differently? + +Return { verdict, findings } where severity is high if the ambiguity could cause an implementation to diverge from intent.`, + { label: 'review-scope', provider: 'minimax-default', schema: REVIEW_SCHEMA }, + ), + () => agent( + `Review this issue plan for DoD coverage: ${JSON.stringify(plan)}. + +Lens (./agents/rgi-lens-dod-coverage.md): For each acceptanceCriterion, can a future test verify it? Are any criteria unmeasurable ("code is clean", "feels right")? Are any testable behaviors missing? + +Return { verdict, findings } where severity is high if a critical acceptance criterion is unmeasurable.`, + { label: 'review-dod', provider: 'minimax-default', schema: REVIEW_SCHEMA }, + ), +]) +const planBlocked = planReviews.some( + (r) => r.verdict === 'needs-work' && r.findings.some((f) => f.severity === 'high'), +) +if (planBlocked) { + throw new Error(`Plan review blocked by high-severity findings: ${JSON.stringify(planReviews)}`) +} + +phase('Plan Implementation') +const implPlan = await agent( + `Convert this issue plan: ${JSON.stringify(plan)} into a file-by-file implementation plan: { filesToCreate: [{path, purpose, estLines}], filesToModify: [{path, changes, estLines}], testFiles: [{path, framework, testCount}], prTitle, prBody, branchName }. + +Constraints: +- branchName must follow the repo's convention (usually fix/- or feat/-). +- prTitle format: "(): (#)". +- prBody must include: Summary (1-3 bullets), Test Plan (how the human reviewer verifies), DoD Checklist (mapped to plan.acceptanceCriteria), Resolves #. +- Respect existing layers: do not duplicate primitives from upstream dependencies; if a primitive exists in @scope/X, reuse it. +- estLines is a rough estimate for the implementer (10/50/200/500 buckets are fine).`, + { + label: 'plan-impl', + provider: 'minimax-default', + schema: { + type: 'object', + additionalProperties: false, + required: ['filesToCreate', 'filesToModify', 'testFiles', 'prTitle', 'prBody', 'branchName'], + properties: { + filesToCreate: { + type: 'array', + items: { + type: 'object', + additionalProperties: false, + required: ['path', 'purpose'], + properties: { + path: { type: 'string' }, + purpose: { type: 'string' }, + estLines: { type: 'number' }, + }, + }, + }, + filesToModify: { + type: 'array', + items: { + type: 'object', + additionalProperties: false, + required: ['path', 'changes'], + properties: { + path: { type: 'string' }, + changes: { type: 'string' }, + estLines: { type: 'number' }, + }, + }, + }, + testFiles: { + type: 'array', + items: { + type: 'object', + additionalProperties: false, + required: ['path', 'framework'], + properties: { + path: { type: 'string' }, + framework: { type: 'string' }, + testCount: { type: 'number' }, + }, + }, + }, + prTitle: { type: 'string' }, + prBody: { type: 'string' }, + branchName: { type: 'string' }, + }, + }, + }, +) + +phase('Review Implementation Plan') +const implReviews = await parallel([ + () => agent( + `Review this implementation plan for architectural alignment: ${JSON.stringify(implPlan)}. + +Lens (./agents/rgi-lens-arch.md): Does it follow existing patterns in the repo? Does it duplicate any primitive from upstream dependencies? Does it respect the ADR-XXXX layering rules? Are AgentsKitError subtypes (with AK_* codes) used at boundaries instead of throw new Error? + +Return { verdict, findings } where severity is high if it duplicates a primitive or violates a hard ADR.`, + { label: 'review-arch', provider: 'minimax-default', schema: REVIEW_SCHEMA }, + ), + () => agent( + `Review this implementation plan for honest scope: ${JSON.stringify(implPlan)}. + +Lens (./agents/rgi-lens-product.md): Does it cut scope appropriately? Are there TODOs or stubs masquerading as complete work? Does the PR body match the actual changes? Does any acceptanceCriterion become unmeasurable in the implementation? + +Return { verdict, findings } where severity is high if any deliverable is a stub/TODO or the PR body lies about scope.`, + { label: 'review-product', provider: 'minimax-default', schema: REVIEW_SCHEMA }, + ), +]) +const implBlocked = implReviews.some( + (r) => r.verdict === 'needs-work' && r.findings.some((f) => f.severity === 'high'), +) +if (implBlocked) { + throw new Error(`Implementation-plan review blocked: ${JSON.stringify(implReviews)}`) +} + +phase('Implement + Unit Tests') +const implResult = await agent( + `Implement this plan in a TDD loop: ${JSON.stringify(implPlan)}. + +Steps: +1. Create the worktree if not already in one (Orca handles this; if standalone, \`git worktree add\` for impl/${implPlan.branchName}). +2. For each file in implPlan.filesToCreate and implPlan.filesToModify: + a. Read the existing file (if modifying) — match style, types, naming. + b. Write the test FIRST (red). Run it; confirm it fails for the right reason. + c. Implement (green). Run the test; confirm it passes. + d. Refactor if needed; tests still green. +3. After all files: \`pnpm --filter test\` for the touched packages. All green. +4. \`pnpm --filter build\` to confirm d.ts and ESM/CJS bundles are emitted. +5. Commit with message referencing the issue: \`git commit -m "(): (#${issueId})\\n\\nResolves #${issueId}"\`. + +Return { filesChanged, testResults, commits, summary } where commits is the list of commit SHAs.`, + { + label: 'impl-unit', + provider: 'minimax-default', + isolation: 'worktree', + schema: { + type: 'object', + additionalProperties: false, + required: ['filesChanged', 'testResults', 'commits', 'summary'], + properties: { + filesChanged: { type: 'array', items: { type: 'string' } }, + testResults: { type: 'string' }, + commits: { type: 'array', items: { type: 'string' } }, + summary: { type: 'string' }, + }, + }, + }, +) + +phase('E2E Tests') +const e2eResult = await agent( + `Write Playwright E2E tests for the new behavior described in ${debrief.debriefPath}. + +Steps: +1. Identify which user-visible flows the issue affects. +2. Author \`tests/e2e-playwright/.spec.ts\` covering each flow (happy path + 1 negative). +3. \`git push origin ${implPlan.branchName}\` to push the branch. +4. Trigger CI: \`gh workflow run e2e-pr-smoke.yml --ref ${implPlan.branchName}\` OR \`gh run watch \` if push auto-triggered. +5. Wait for CI to complete. Capture the run URL. +6. If tests pass, return ciStatus:'pass'. If fail, return ciStatus:'fail' with the failing test names. + +Return { testFiles, ciRunUrl, ciStatus, summary }.`, + { + label: 'e2e-tests', + provider: 'minimax-default', + schema: { + type: 'object', + additionalProperties: false, + required: ['testFiles', 'ciRunUrl', 'ciStatus', 'summary'], + properties: { + testFiles: { type: 'array', items: { type: 'string' } }, + ciRunUrl: { type: 'string' }, + ciStatus: { type: 'string', enum: ['pass', 'fail', 'pending'] }, + summary: { type: 'string' }, + }, + }, + }, +) +if (e2eResult.ciStatus !== 'pass') { + throw new Error(`E2E tests failed in CI: ${e2eResult.ciRunUrl}`) +} + +phase('Lint + CI') +const lintResult = await agent( + `Run lint, typecheck, and architectural guardrails on the touched files. EXECUTE ONLY — do not modify code, do not add new check scripts. + +Run in sequence: +- \`pnpm --filter lint\` +- \`pnpm --filter typecheck\` (or \`pnpm check:typecheck\`) +- \`pnpm check:layers\` +- \`pnpm check:no-raw-error\` +- \`pnpm check:no-duplicate-agentskit\` +- \`pnpm check:api-surface\` + +For each, capture pass/fail and the first 3 error lines if fail. + +Return { lintOk, typecheckOk, guardrailsOk, errors[] } where errors is the concatenated first-lines of failures.`, + { + label: 'lint-ci', + provider: 'minimax-default', + schema: { + type: 'object', + additionalProperties: false, + required: ['lintOk', 'typecheckOk', 'guardrailsOk', 'errors'], + properties: { + lintOk: { type: 'boolean' }, + typecheckOk: { type: 'boolean' }, + guardrailsOk: { type: 'boolean' }, + errors: { type: 'array', items: { type: 'string' } }, + }, + }, + }, +) +if (!lintResult.lintOk || !lintResult.typecheckOk || !lintResult.guardrailsOk) { + throw new Error(`Lint/CI failed: ${JSON.stringify(lintResult.errors)}`) +} + +phase('Audit') +const audit = await agent( + `Audit the implementation end-to-end as the dedicated auditor. + +Verify (./agents/multi-agent-auditor.md persona): +1. Each acceptanceCriterion from plan has a verifying test that would fail if the criterion were violated. Look at implPlan.testFiles and the actual test code in implResult.filesChanged. +2. All commits in implResult.commits trace back to the plan — no out-of-scope changes. +3. CI is green (e2eResult.ciStatus === 'pass'). +4. PR body (implPlan.prBody) matches the actual diff scope — no lies. +5. No secrets in the diff, no console.log left behind, no commented-out code blocks. + +Append an audit-ledger entry via os-audit appendAuditLedgerEntry with category:'multi-agent-workflow.audit', verdict, findings, runId. + +Return { verdict: 'pass' | 'warn' | 'fail', findings, ledgerEntryId, summary }.`, + { + label: 'audit', + provider: 'minimax-default', + schema: { + type: 'object', + additionalProperties: false, + required: ['verdict', 'findings', 'ledgerEntryId', 'summary'], + properties: { + verdict: { type: 'string', enum: ['pass', 'warn', 'fail'] }, + findings: { type: 'array', items: { type: 'string' } }, + ledgerEntryId: { type: 'string' }, + summary: { type: 'string' }, + }, + }, + }, +) +if (audit.verdict === 'fail') { + throw new Error(`Auditor blocked PR: ${audit.findings.join('; ')}`) +} + +phase('Commit + PR') +const pr = await agent( + `Open the pull request with a HITL pre-PR gate. + +Steps: +1. Confirm branch ${implPlan.branchName} is pushed and CI is green. +2. Compose final PR title and body: + - title = implPlan.prTitle + - body = implPlan.prBody + audit section ("Auditor verdict: ${audit.verdict} — ${audit.summary}") +3. Block at HITL gate: do NOT call gh pr create yet. Surface the title+body via an Orca gate-create OR via TUI chat asking the human to approve. Wait for explicit approval. +4. When approved, run \`gh pr create --title "" --body "<body>" --base main\` (or whatever the repo's default branch is). +5. Return the PR URL and number. + +Return { prUrl, prNumber, branchName, auditorVerdict: '${audit.verdict}' }.`, + { + label: 'commit-pr', + provider: 'minimax-default', + schema: { + type: 'object', + additionalProperties: false, + required: ['prUrl', 'prNumber', 'branchName', 'auditorVerdict'], + properties: { + prUrl: { type: 'string' }, + prNumber: { type: 'number' }, + branchName: { type: 'string' }, + auditorVerdict: { type: 'string' }, + }, + }, + }, +) + +return { + issue: `${tracker}:${issueId}`, + debriefPath: debrief.debriefPath, + plan, + planReviews, + implPlan, + implReviews, + implResult, + e2eResult, + lintResult, + audit, + pr, +} \ No newline at end of file