mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-09-14 23:22:51 +00:00
506 lines
No EOL
40 KiB
JSON
506 lines
No EOL
40 KiB
JSON
{
|
||
"title": "<proposed_plan>",
|
||
"spec": {
|
||
"run_id": "01KY7YH7RYCJ1BDVTTP96ZA4HV",
|
||
"settings": {
|
||
"project": {
|
||
"name": null,
|
||
"description": null,
|
||
"metadata": {}
|
||
},
|
||
"workflow": {
|
||
"name": null,
|
||
"description": null,
|
||
"graph": "workflow.fabro",
|
||
"metadata": {}
|
||
},
|
||
"run": {
|
||
"goal": {
|
||
"type": "inline",
|
||
"value": "<proposed_plan>\n# Shared-Checkout Parallel Execution\n\n## Summary\n\nSimplify parallel execution so every branch:\n\n- Receives an isolated context fork.\n- Executes concurrently against the same sandbox and Git checkout.\n- Creates no Git branch, worktree, checkpoint, or branch commit.\n- Always waits for every branch; remove `first_success` and `join_policy`.\n- Produces a collision-free result containing its context updates.\n\nFan-in remains an explicit join node. Without a prompt it is a no-op barrier; with a prompt it behaves like a standard prompt stage that reduces the aggregated results without selecting a branch.\n\n## Implementation Changes\n\n### Parallel execution\n\n- Remove all parallel-specific Git setup, checkpointing, committing, cleanup, and fast-forwarding.\n- Give each branch the same `Arc<dyn Sandbox>` and inherited `internal.work_dir`.\n- Retain `max_parallel`, branch-scoped contexts, IDs, hooks, and lifecycle events.\n- Preserve outgoing-edge order in the final results regardless of completion order.\n- Define the parallel outcome as:\n - `succeeded` when every branch succeeds.\n - `failed` when every branch fails.\n - `partially_succeeded` for every mixed or partial result.\n- Preserve branch ID/index when handler or task execution fails.\n- Keep the current single-node-per-branch topology.\n\n### Results and fan-in\n\nIntroduce a shared typed result:\n\n```rust\nParallelBranchResult {\n id: String,\n status: String,\n context_updates: BTreeMap<String, serde_json::Value>,\n}\n```\n\n- Store the ordered array in `parallel.results` and keep `parallel.branch_count`.\n- Include updates from successful and failed branches; never merge them into the parent context at top level.\n- Offload large leaf values using existing artifact storage while keeping `parallel.results` itself a structured array.\n- Resolve nested textual `response.*` and `command.output` blob references when building downstream prompt context.\n- Emit the same typed results through `parallel.completed` and project them into `StageProjection.parallel_results`.\n- A promptless fan-in verifies results exist and succeeds with a joined-branches note.\n- A prompted fan-in uses standard prompt execution and records `response.<fan_in_id>`, `last_response`, usage, and prompt events. It performs no ranking or selection.\n\nRemove:\n\n- Heuristic and LLM branch-selection code.\n- `parallel.fan_in.best_id`, `best_outcome`, and `best_head_sha`.\n- Per-result `head_sha` and `score`.\n- The special fan-in model-usage mode.\n- Fan-in selected-branch notes and UI.\n\n### Delete obsolete Git/worktree infrastructure\n\n- Delete the parallel-only `WorktreeSandbox`, its options/callbacks, exports, tests, and sandbox trait path helpers.\n- Remove `EngineServices`’ parallel-only `GitState` and pipeline wiring.\n- Remove now-unused branch/worktree/fast-forward Git helpers and parallel ref sanitization.\n- Remove the parallel-base-checkpoint notice code.\n- Remove the now-unemitted `git.branch`, `git.worktree.added`, and `git.worktree.removed` event variants and property types.\n- Leave the server’s independent Git checkout/worktree implementation unchanged.\n- Continue normal run-level checkpointing after the parallel node; any shared workspace changes are captured together.\n\n## Public Interfaces and Documentation\n\n- Remove `join_policy` from DOT documentation, examples, fixtures, events, and UI.\n- Add a validation error directing users to remove any `join_policy` attribute.\n- Update `parallel.started` to contain only visit and branch count.\n- Update `parallel.branch.completed` to remove `head_sha`.\n- Define `ParallelBranchResult` in OpenAPI and change `StageProjection.parallel_results` from untyped objects to that typed array; regenerate Rust and TypeScript clients.\n- Update the parallel UI to show branch status and links without commit SHAs or a join-policy badge.\n- Replace the fan-in trophy/selection UI with joined-state information and the optional standard reducer transcript.\n- Rewrite the active parallel strategy and public docs around shared-checkout concurrency:\n - Read-only behavior is best effort.\n - Concurrent writes are allowed but entirely user-managed.\n - Fabro performs no write enforcement, detection, or warnings.\n - Results are available through `parallel.results`, not a workspace `parallel_results.json`.\n - A fan-in prompt synthesizes results but never selects workspace state.\n- Remove `join_policy` from all checked-in tutorial/demo workflows and generated documentation fixtures.\n\n## Test Plan\n\n- Unit-test that every branch receives the same sandbox working directory while retaining independent contexts.\n- Verify deterministic result ordering and complete per-branch context updates, including failed branches and structured/command outputs.\n- Cover all-success, mixed, partial, all-failed, zero-branch, `max_parallel`, dry-run, and run-cancellation behavior.\n- In a temporary Git repository, run parallel branches that write distinct files and assert:\n - Both files remain in the shared checkout.\n - No `fabro/run/parallel/*` refs exist.\n - No parallel worktrees, branch commits, worktree events, or fast-forward commands occur.\n- Test promptless fan-in as a no-op join and prompted fan-in as a standard reducer that sees every branch result and emits a normal response.\n- Update event serialization, store projection, API round-trip, web parser, and renderer tests for the new typed payloads and removed fields.\n- Remove the obsolete host and Daytona parallel-Git-selection tests; retain provider-independent shared-sandbox coverage.\n- Verify with:\n - `cargo build -p fabro-api`\n - `cd lib/packages/fabro-api-client && bun run generate && bun run typecheck`\n - `cargo build --workspace`\n - `ulimit -n 4096 && cargo nextest run --workspace`\n - `cargo +nightly-2026-04-14 fmt --check --all`\n - `cargo +nightly-2026-04-14 clippy --workspace --all-targets -- -D warnings`\n - `cd apps/fabro-web && bun test && bun run typecheck && bun run build`\n - `cargo --locked dev docs check`\n\n## Assumptions and Unresolved Questions\n\n- The application is greenfield; removed fields, events, and attributes receive no compatibility layer.\n- Parallel branches remain single-node executions.\n- `max_parallel` remains supported.\n- Shared-workspace write races are explicitly the user’s responsibility.\n- No Git workspace warning or read-only enforcement will be added.\n- Unresolved questions: none.\n</proposed_plan>\n"
|
||
},
|
||
"working_dir": null,
|
||
"metadata": {},
|
||
"inputs": {},
|
||
"model": {
|
||
"provider": "openrouter",
|
||
"name": "anthropic/claude-sonnet-4-6",
|
||
"fallbacks": [],
|
||
"controls": {
|
||
"reasoning_effort": null,
|
||
"speed": null
|
||
}
|
||
},
|
||
"git": {
|
||
"author": null
|
||
},
|
||
"prepare": {
|
||
"steps": [],
|
||
"timeout_ms": 300000
|
||
},
|
||
"execution": {
|
||
"mode": "normal",
|
||
"approval": "prompt"
|
||
},
|
||
"checkpoint": {
|
||
"exclude_globs": [],
|
||
"skip_git_hooks": false,
|
||
"commit_timeout_ms": 30000
|
||
},
|
||
"clone": {
|
||
"enabled": true
|
||
},
|
||
"run_branch": {
|
||
"enabled": true,
|
||
"push": true
|
||
},
|
||
"meta_branch": {
|
||
"enabled": true,
|
||
"push": true
|
||
},
|
||
"environment": {
|
||
"id": "fabro-dev",
|
||
"provider": "daytona",
|
||
"image": {
|
||
"docker": null,
|
||
"dockerfile": {
|
||
"type": "inline",
|
||
"value": "FROM ubuntu:24.04\n\nRUN apt-get update && apt-get install -y --no-install-recommends \\\n curl git ripgrep ca-certificates build-essential pkg-config libssl-dev unzip python3 \\\n xvfb xfce4 xfce4-terminal x11vnc novnc dbus-x11 \\\n libx11-6 libxrandr2 libxext6 libxrender1 libxfixes3 libxss1 libxtst6 libxi6 \\\n && rm -rf /var/lib/apt/lists/*\n\n# Install real Chromium (not the snap stub) via xtradeb PPA\nRUN apt-get update && apt-get install -y --no-install-recommends \\\n software-properties-common curl gnupg \\\n && add-apt-repository -y ppa:xtradeb/apps \\\n && apt-get update \\\n && apt-get install -y --no-install-recommends chromium \\\n && rm -rf /var/lib/apt/lists/*\n\n# Wrapper: Chromium needs --no-sandbox when running as root in a container,\n# and --disable-dev-shm-usage avoids crashes from small /dev/shm\nRUN printf '#!/bin/bash\\nexec /usr/bin/chromium --no-sandbox --disable-dev-shm-usage \"$@\"\\n' \\\n > /usr/local/bin/chromium-wrapper \\\n && chmod +x /usr/local/bin/chromium-wrapper\n\n# Make the wrapper the default in the system .desktop file and via alternatives\nRUN sed -i 's|^Exec=.*|Exec=/usr/local/bin/chromium-wrapper %U|' \\\n /usr/share/applications/chromium.desktop \\\n && update-alternatives --install /usr/bin/x-www-browser x-www-browser \\\n /usr/local/bin/chromium-wrapper 100\n\n# Tell XFCE's exo-open that Chromium is the WebBrowser helper (system-wide)\nRUN mkdir -p /etc/xdg/xfce4 /usr/share/xfce4/helpers \\\n && printf 'WebBrowser=custom-WebBrowser\\n' > /etc/xdg/xfce4/helpers.rc \\\n && printf '[Desktop Entry]\\n\\\nVersion=1.0\\n\\\nType=X-XFCE-Helper\\n\\\nName=Chromium\\n\\\nIcon=chromium\\n\\\nX-XFCE-Category=WebBrowser\\n\\\nX-XFCE-CommandsWithParameter=/usr/local/bin/chromium-wrapper \"%%s\"\\n\\\nX-XFCE-Commands=/usr/local/bin/chromium-wrapper\\n' \\\n > /usr/share/xfce4/helpers/custom-WebBrowser.desktop\n\n# GitHub CLI\nRUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \\\n | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \\\n && echo \"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main\" \\\n | tee /etc/apt/sources.list.d/github-cli.list > /dev/null \\\n && apt-get update && apt-get install -y --no-install-recommends gh \\\n && rm -rf /var/lib/apt/lists/*\n\n# Rust\nRUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y\nENV PATH=\"/root/.cargo/bin:${PATH}\"\nRUN rustup toolchain install nightly-2026-04-14 --profile minimal --component clippy,rustfmt\nRUN cargo install cargo-nextest --locked\nENV CARGO_INCREMENTAL=0\n\n# Bun\nRUN curl -fsSL https://bun.sh/install | bash\nENV PATH=\"/root/.bun/bin:${PATH}\"\n\nWORKDIR /root\n"
|
||
}
|
||
},
|
||
"resources": {
|
||
"cpu": 8,
|
||
"memory": "16GB",
|
||
"disk": "20GB"
|
||
},
|
||
"network": {
|
||
"mode": "allow_all",
|
||
"allow": []
|
||
},
|
||
"lifecycle": {
|
||
"preserve": false,
|
||
"stop_on_terminal": true,
|
||
"auto_stop": "30m"
|
||
},
|
||
"labels": {
|
||
"repo": "fabro-sh/fabro"
|
||
},
|
||
"env": {}
|
||
},
|
||
"notifications": {
|
||
"feed": {
|
||
"enabled": true,
|
||
"provider": "slack",
|
||
"events": [
|
||
"run.started",
|
||
"run.completed",
|
||
"run.failed"
|
||
],
|
||
"slack": {
|
||
"channel": "#feed-fabro"
|
||
}
|
||
}
|
||
},
|
||
"interviews": {
|
||
"provider": null,
|
||
"slack": null
|
||
},
|
||
"agent": {
|
||
"fabro_tools": false,
|
||
"permissions": null,
|
||
"mcps": {}
|
||
},
|
||
"hooks": [],
|
||
"scm": {
|
||
"provider": null,
|
||
"owner": null,
|
||
"repository": null,
|
||
"github": null
|
||
},
|
||
"pull_request": {
|
||
"enabled": true,
|
||
"draft": false,
|
||
"auto_merge": false,
|
||
"merge_strategy": "squash"
|
||
},
|
||
"artifacts": {
|
||
"include": []
|
||
},
|
||
"integrations": {
|
||
"github": {
|
||
"permissions": {}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"graph": {
|
||
"name": "ImplementPlan",
|
||
"nodes": {
|
||
"exit": {
|
||
"id": "exit",
|
||
"attrs": {
|
||
"label": {
|
||
"String": "Exit"
|
||
},
|
||
"shape": {
|
||
"String": "Msquare"
|
||
}
|
||
}
|
||
},
|
||
"toolchain": {
|
||
"id": "toolchain",
|
||
"attrs": {
|
||
"max_retries": {
|
||
"Integer": 0
|
||
},
|
||
"label": {
|
||
"String": "Toolchain"
|
||
},
|
||
"script": {
|
||
"String": "command -v cargo >/dev/null || { curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && sudo ln -sf $HOME/.cargo/bin/* /usr/local/bin/; }; cargo --version 2>&1"
|
||
},
|
||
"shape": {
|
||
"String": "parallelogram"
|
||
}
|
||
}
|
||
},
|
||
"start": {
|
||
"id": "start",
|
||
"attrs": {
|
||
"label": {
|
||
"String": "Start"
|
||
},
|
||
"shape": {
|
||
"String": "Mdiamond"
|
||
}
|
||
}
|
||
},
|
||
"preflight_compile": {
|
||
"id": "preflight_compile",
|
||
"attrs": {
|
||
"label": {
|
||
"String": "Preflight Compile"
|
||
},
|
||
"script": {
|
||
"String": "cargo check -q --workspace 2>&1"
|
||
},
|
||
"shape": {
|
||
"String": "parallelogram"
|
||
},
|
||
"max_retries": {
|
||
"Integer": 0
|
||
}
|
||
}
|
||
},
|
||
"preflight_lint": {
|
||
"id": "preflight_lint",
|
||
"attrs": {
|
||
"label": {
|
||
"String": "Preflight Lint"
|
||
},
|
||
"shape": {
|
||
"String": "parallelogram"
|
||
},
|
||
"script": {
|
||
"String": "cargo +nightly-2026-04-14 clippy -q --workspace --all-targets -- -D warnings 2>&1"
|
||
},
|
||
"max_retries": {
|
||
"Integer": 0
|
||
}
|
||
}
|
||
},
|
||
"simplify_fable": {
|
||
"id": "simplify_fable",
|
||
"attrs": {
|
||
"prompt": {
|
||
"String": "# Simplify: Code Review and Cleanup\n\nReview all changed files for reuse, quality, and efficiency. Fix any issues found.\n\n## Phase 1: Identify Changes\n\nRun \\`git diff\\` (or \\`git diff HEAD\\` if there are staged changes) to see what changed. If there are no git changes, review the most recently modified files that the user mentioned or that you edited earlier in this conversation.\n\n## Phase 2: Launch Three Review Agents in Parallel\n\nUse the ${AGENT_TOOL_NAME} tool to launch all three agents concurrently in a single message. Pass each agent the full diff so it has the complete context.\n\n### Agent 1: Code Reuse Review\n\nFor each change:\n\n1. **Search for existing utilities and helpers** that could replace newly written code. Look for similar patterns elsewhere in the codebase — common locations are utility directories, shared modules, and files adjacent to the changed ones.\n2. **Flag any new function that duplicates existing functionality.** Suggest the existing function to use instead.\n3. **Flag any inline logic that could use an existing utility** — hand-rolled string manipulation, manual path handling, custom environment checks, ad-hoc type guards, and similar patterns are common candidates.\n\n### Agent 2: Code Quality Review\n\nReview the same changes for hacky patterns:\n\n1. **Redundant state**: state that duplicates existing state, cached values that could be derived, observers/effects that could be direct calls\n2. **Parameter sprawl**: adding new parameters to a function instead of generalizing or restructuring existing ones\n3. **Copy-paste with slight variation**: near-duplicate code blocks that should be unified with a shared abstraction\n4. **Leaky abstractions**: exposing internal details that should be encapsulated, or breaking existing abstraction boundaries\n5. **Stringly-typed code**: using raw strings where constants, enums (string unions), or branded types already exist in the codebase\n6. **Unnecessary JSX nesting**: wrapper Boxes/elements that add no layout value — check if inner component props (flexShrink, alignItems, etc.) already provide the needed behavior\n7. **Unnecessary comments**: comments explaining WHAT the code does (well-named identifiers already do that), narrating the change, or referencing the task/caller — delete; keep only non-obvious WHY (hidden constraints, subtle invariants, workarounds)\n\n### Agent 3: Efficiency Review\n\nReview the same changes for efficiency:\n\n1. **Unnecessary work**: redundant computations, repeated file reads, duplicate network/API calls, N+1 patterns\n2. **Missed concurrency**: independent operations run sequentially when they could run in parallel\n3. **Hot-path bloat**: new blocking work added to startup or per-request/per-render hot paths\n4. **Recurring no-op updates**: state/store updates inside polling loops, intervals, or event handlers that fire unconditionally — add a change-detection guard so downstream consumers aren't notified when nothing changed. Also: if a wrapper function takes an updater/reducer callback, verify it honors same-reference returns (or whatever the \"no change\" signal is) — otherwise callers' early-return no-ops are silently defeated\n5. **Unnecessary existence checks**: pre-checking file/resource existence before operating (TOCTOU anti-pattern) — operate directly and handle the error\n6. **Memory**: unbounded data structures, missing cleanup, event listener leaks\n7. **Overly broad operations**: reading entire files when only a portion is needed, loading all items when filtering for one\n\n## Phase 3: Fix Issues\n\nWait for all three agents to complete. Aggregate their findings and fix each issue directly. If a finding is a false positive or not worth addressing, note it and move on — do not argue with the finding, just skip it.\n\nWhen done, briefly summarize what was fixed (or confirm the code was already clean).\n"
|
||
},
|
||
"provider": {
|
||
"String": "openrouter"
|
||
},
|
||
"model": {
|
||
"String": "anthropic/claude-fable-5"
|
||
},
|
||
"reasoning_effort": {
|
||
"String": "xhigh"
|
||
},
|
||
"label": {
|
||
"String": "Simplify (Claude Fable 5)"
|
||
}
|
||
}
|
||
},
|
||
"fixup": {
|
||
"id": "fixup",
|
||
"attrs": {
|
||
"model": {
|
||
"String": "anthropic/claude-fable-5"
|
||
},
|
||
"prompt": {
|
||
"String": "The verify step failed. Read the build output from context and fix all format, clippy, Rust test, docs, TypeScript typecheck/test, and build failures."
|
||
},
|
||
"label": {
|
||
"String": "Fixup"
|
||
},
|
||
"reasoning_effort": {
|
||
"String": "xhigh"
|
||
},
|
||
"provider": {
|
||
"String": "openrouter"
|
||
},
|
||
"max_visits": {
|
||
"Integer": 3
|
||
}
|
||
}
|
||
},
|
||
"fix_lints": {
|
||
"id": "fix_lints",
|
||
"attrs": {
|
||
"label": {
|
||
"String": "Fix Lints"
|
||
},
|
||
"model": {
|
||
"String": "anthropic/claude-fable-5"
|
||
},
|
||
"reasoning_effort": {
|
||
"String": "xhigh"
|
||
},
|
||
"provider": {
|
||
"String": "openrouter"
|
||
},
|
||
"prompt": {
|
||
"String": "The preflight lint step failed. Read the build output from context and fix all clippy lint warnings."
|
||
},
|
||
"max_visits": {
|
||
"Integer": 3
|
||
}
|
||
}
|
||
},
|
||
"implement": {
|
||
"id": "implement",
|
||
"attrs": {
|
||
"model": {
|
||
"String": "openai/gpt-5.6-sol"
|
||
},
|
||
"prompt": {
|
||
"String": "Read the plan file referenced in the goal and implement every step. Make all the code changes described in the plan. Use red/green TDD."
|
||
},
|
||
"label": {
|
||
"String": "Implement"
|
||
},
|
||
"provider": {
|
||
"String": "openrouter"
|
||
},
|
||
"reasoning_effort": {
|
||
"String": "xhigh"
|
||
}
|
||
}
|
||
},
|
||
"verify": {
|
||
"id": "verify",
|
||
"attrs": {
|
||
"script": {
|
||
"String": "git fetch origin main 2>&1 && git merge --no-edit --no-stat origin/main 2>&1 && cargo +nightly-2026-04-14 fmt --all 2>&1 && cargo dev docs refresh 2>&1 && cargo +nightly-2026-04-14 fmt --check --all 2>&1 && { command -v rg >/dev/null 2>&1 || { echo 'rg is required for verify'; exit 127; }; } && ! rg -n 'AuthMode::Disabled|RunAuthMethod|RunSubjectProvenance|\\bActorRef\\b|\\bActorKind\\b|AuthenticatedSubject|AuthenticatedService|AuthorizeRunScoped|AuthorizeRunBlob|AuthorizeStageArtifact|AuthorizeCommandLog|auth_method\\s*==\\s*\"disabled\"' lib/crates apps lib/packages docs/public/api-reference/fabro-api.yaml 2>&1 && cargo +nightly-2026-04-14 clippy --workspace --all-targets -- -D warnings 2>&1 && cargo nextest run --workspace --status-level slow --profile ci 2>&1 && cargo dev docs check 2>&1 && bun install --frozen-lockfile 2>&1 && (cd apps/fabro-web && bun run typecheck) 2>&1 && (cd apps/fabro-web && bun run test) 2>&1 && (cd lib/packages/fabro-api-client && bun run typecheck) 2>&1 && cargo dev build -- -p fabro-cli --release 2>&1"
|
||
},
|
||
"label": {
|
||
"String": "Verify"
|
||
},
|
||
"retry_target": {
|
||
"String": "fixup"
|
||
},
|
||
"goal_gate": {
|
||
"Boolean": true
|
||
},
|
||
"shape": {
|
||
"String": "parallelogram"
|
||
}
|
||
}
|
||
},
|
||
"simplify_sol": {
|
||
"id": "simplify_sol",
|
||
"attrs": {
|
||
"provider": {
|
||
"String": "openrouter"
|
||
},
|
||
"reasoning_effort": {
|
||
"String": "max"
|
||
},
|
||
"label": {
|
||
"String": "Simplify (GPT-5.6 Sol)"
|
||
},
|
||
"prompt": {
|
||
"String": "# Simplify: Code Review and Cleanup\n\nReview all changed files for reuse, quality, and efficiency. Fix any issues found.\n\n## Phase 1: Identify Changes\n\nRun \\`git diff\\` (or \\`git diff HEAD\\` if there are staged changes) to see what changed. If there are no git changes, review the most recently modified files that the user mentioned or that you edited earlier in this conversation.\n\n## Phase 2: Launch Three Review Agents in Parallel\n\nUse the ${AGENT_TOOL_NAME} tool to launch all three agents concurrently in a single message. Pass each agent the full diff so it has the complete context.\n\n### Agent 1: Code Reuse Review\n\nFor each change:\n\n1. **Search for existing utilities and helpers** that could replace newly written code. Look for similar patterns elsewhere in the codebase — common locations are utility directories, shared modules, and files adjacent to the changed ones.\n2. **Flag any new function that duplicates existing functionality.** Suggest the existing function to use instead.\n3. **Flag any inline logic that could use an existing utility** — hand-rolled string manipulation, manual path handling, custom environment checks, ad-hoc type guards, and similar patterns are common candidates.\n\n### Agent 2: Code Quality Review\n\nReview the same changes for hacky patterns:\n\n1. **Redundant state**: state that duplicates existing state, cached values that could be derived, observers/effects that could be direct calls\n2. **Parameter sprawl**: adding new parameters to a function instead of generalizing or restructuring existing ones\n3. **Copy-paste with slight variation**: near-duplicate code blocks that should be unified with a shared abstraction\n4. **Leaky abstractions**: exposing internal details that should be encapsulated, or breaking existing abstraction boundaries\n5. **Stringly-typed code**: using raw strings where constants, enums (string unions), or branded types already exist in the codebase\n6. **Unnecessary JSX nesting**: wrapper Boxes/elements that add no layout value — check if inner component props (flexShrink, alignItems, etc.) already provide the needed behavior\n7. **Unnecessary comments**: comments explaining WHAT the code does (well-named identifiers already do that), narrating the change, or referencing the task/caller — delete; keep only non-obvious WHY (hidden constraints, subtle invariants, workarounds)\n\n### Agent 3: Efficiency Review\n\nReview the same changes for efficiency:\n\n1. **Unnecessary work**: redundant computations, repeated file reads, duplicate network/API calls, N+1 patterns\n2. **Missed concurrency**: independent operations run sequentially when they could run in parallel\n3. **Hot-path bloat**: new blocking work added to startup or per-request/per-render hot paths\n4. **Recurring no-op updates**: state/store updates inside polling loops, intervals, or event handlers that fire unconditionally — add a change-detection guard so downstream consumers aren't notified when nothing changed. Also: if a wrapper function takes an updater/reducer callback, verify it honors same-reference returns (or whatever the \"no change\" signal is) — otherwise callers' early-return no-ops are silently defeated\n5. **Unnecessary existence checks**: pre-checking file/resource existence before operating (TOCTOU anti-pattern) — operate directly and handle the error\n6. **Memory**: unbounded data structures, missing cleanup, event listener leaks\n7. **Overly broad operations**: reading entire files when only a portion is needed, loading all items when filtering for one\n\n## Phase 3: Fix Issues\n\nWait for all three agents to complete. Aggregate their findings and fix each issue directly. If a finding is a false positive or not worth addressing, note it and move on — do not argue with the finding, just skip it.\n\nWhen done, briefly summarize what was fixed (or confirm the code was already clean).\n"
|
||
},
|
||
"model": {
|
||
"String": "openai/gpt-5.6-sol"
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"edges": [
|
||
{
|
||
"from": "start",
|
||
"to": "toolchain",
|
||
"attrs": {}
|
||
},
|
||
{
|
||
"from": "toolchain",
|
||
"to": "preflight_compile",
|
||
"attrs": {
|
||
"condition": {
|
||
"String": "outcome=succeeded"
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"from": "toolchain",
|
||
"to": "exit",
|
||
"attrs": {}
|
||
},
|
||
{
|
||
"from": "preflight_compile",
|
||
"to": "preflight_lint",
|
||
"attrs": {
|
||
"condition": {
|
||
"String": "outcome=succeeded"
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"from": "preflight_compile",
|
||
"to": "exit",
|
||
"attrs": {}
|
||
},
|
||
{
|
||
"from": "preflight_lint",
|
||
"to": "implement",
|
||
"attrs": {
|
||
"condition": {
|
||
"String": "outcome=succeeded"
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"from": "preflight_lint",
|
||
"to": "fix_lints",
|
||
"attrs": {}
|
||
},
|
||
{
|
||
"from": "fix_lints",
|
||
"to": "preflight_lint",
|
||
"attrs": {}
|
||
},
|
||
{
|
||
"from": "implement",
|
||
"to": "simplify_fable",
|
||
"attrs": {}
|
||
},
|
||
{
|
||
"from": "simplify_fable",
|
||
"to": "simplify_sol",
|
||
"attrs": {}
|
||
},
|
||
{
|
||
"from": "simplify_sol",
|
||
"to": "verify",
|
||
"attrs": {}
|
||
},
|
||
{
|
||
"from": "verify",
|
||
"to": "exit",
|
||
"attrs": {
|
||
"condition": {
|
||
"String": "outcome=succeeded"
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"from": "verify",
|
||
"to": "fixup",
|
||
"attrs": {}
|
||
},
|
||
{
|
||
"from": "fixup",
|
||
"to": "verify",
|
||
"attrs": {}
|
||
}
|
||
],
|
||
"attrs": {
|
||
"rankdir": {
|
||
"String": "LR"
|
||
},
|
||
"goal": {
|
||
"String": "<proposed_plan>\n# Shared-Checkout Parallel Execution\n\n## Summary\n\nSimplify parallel execution so every branch:\n\n- Receives an isolated context fork.\n- Executes concurrently against the same sandbox and Git checkout.\n- Creates no Git branch, worktree, checkpoint, or branch commit.\n- Always waits for every branch; remove `first_success` and `join_policy`.\n- Produces a collision-free result containing its context updates.\n\nFan-in remains an explicit join node. Without a prompt it is a no-op barrier; with a prompt it behaves like a standard prompt stage that reduces the aggregated results without selecting a branch.\n\n## Implementation Changes\n\n### Parallel execution\n\n- Remove all parallel-specific Git setup, checkpointing, committing, cleanup, and fast-forwarding.\n- Give each branch the same `Arc<dyn Sandbox>` and inherited `internal.work_dir`.\n- Retain `max_parallel`, branch-scoped contexts, IDs, hooks, and lifecycle events.\n- Preserve outgoing-edge order in the final results regardless of completion order.\n- Define the parallel outcome as:\n - `succeeded` when every branch succeeds.\n - `failed` when every branch fails.\n - `partially_succeeded` for every mixed or partial result.\n- Preserve branch ID/index when handler or task execution fails.\n- Keep the current single-node-per-branch topology.\n\n### Results and fan-in\n\nIntroduce a shared typed result:\n\n```rust\nParallelBranchResult {\n id: String,\n status: String,\n context_updates: BTreeMap<String, serde_json::Value>,\n}\n```\n\n- Store the ordered array in `parallel.results` and keep `parallel.branch_count`.\n- Include updates from successful and failed branches; never merge them into the parent context at top level.\n- Offload large leaf values using existing artifact storage while keeping `parallel.results` itself a structured array.\n- Resolve nested textual `response.*` and `command.output` blob references when building downstream prompt context.\n- Emit the same typed results through `parallel.completed` and project them into `StageProjection.parallel_results`.\n- A promptless fan-in verifies results exist and succeeds with a joined-branches note.\n- A prompted fan-in uses standard prompt execution and records `response.<fan_in_id>`, `last_response`, usage, and prompt events. It performs no ranking or selection.\n\nRemove:\n\n- Heuristic and LLM branch-selection code.\n- `parallel.fan_in.best_id`, `best_outcome`, and `best_head_sha`.\n- Per-result `head_sha` and `score`.\n- The special fan-in model-usage mode.\n- Fan-in selected-branch notes and UI.\n\n### Delete obsolete Git/worktree infrastructure\n\n- Delete the parallel-only `WorktreeSandbox`, its options/callbacks, exports, tests, and sandbox trait path helpers.\n- Remove `EngineServices`’ parallel-only `GitState` and pipeline wiring.\n- Remove now-unused branch/worktree/fast-forward Git helpers and parallel ref sanitization.\n- Remove the parallel-base-checkpoint notice code.\n- Remove the now-unemitted `git.branch`, `git.worktree.added`, and `git.worktree.removed` event variants and property types.\n- Leave the server’s independent Git checkout/worktree implementation unchanged.\n- Continue normal run-level checkpointing after the parallel node; any shared workspace changes are captured together.\n\n## Public Interfaces and Documentation\n\n- Remove `join_policy` from DOT documentation, examples, fixtures, events, and UI.\n- Add a validation error directing users to remove any `join_policy` attribute.\n- Update `parallel.started` to contain only visit and branch count.\n- Update `parallel.branch.completed` to remove `head_sha`.\n- Define `ParallelBranchResult` in OpenAPI and change `StageProjection.parallel_results` from untyped objects to that typed array; regenerate Rust and TypeScript clients.\n- Update the parallel UI to show branch status and links without commit SHAs or a join-policy badge.\n- Replace the fan-in trophy/selection UI with joined-state information and the optional standard reducer transcript.\n- Rewrite the active parallel strategy and public docs around shared-checkout concurrency:\n - Read-only behavior is best effort.\n - Concurrent writes are allowed but entirely user-managed.\n - Fabro performs no write enforcement, detection, or warnings.\n - Results are available through `parallel.results`, not a workspace `parallel_results.json`.\n - A fan-in prompt synthesizes results but never selects workspace state.\n- Remove `join_policy` from all checked-in tutorial/demo workflows and generated documentation fixtures.\n\n## Test Plan\n\n- Unit-test that every branch receives the same sandbox working directory while retaining independent contexts.\n- Verify deterministic result ordering and complete per-branch context updates, including failed branches and structured/command outputs.\n- Cover all-success, mixed, partial, all-failed, zero-branch, `max_parallel`, dry-run, and run-cancellation behavior.\n- In a temporary Git repository, run parallel branches that write distinct files and assert:\n - Both files remain in the shared checkout.\n - No `fabro/run/parallel/*` refs exist.\n - No parallel worktrees, branch commits, worktree events, or fast-forward commands occur.\n- Test promptless fan-in as a no-op join and prompted fan-in as a standard reducer that sees every branch result and emits a normal response.\n- Update event serialization, store projection, API round-trip, web parser, and renderer tests for the new typed payloads and removed fields.\n- Remove the obsolete host and Daytona parallel-Git-selection tests; retain provider-independent shared-sandbox coverage.\n- Verify with:\n - `cargo build -p fabro-api`\n - `cd lib/packages/fabro-api-client && bun run generate && bun run typecheck`\n - `cargo build --workspace`\n - `ulimit -n 4096 && cargo nextest run --workspace`\n - `cargo +nightly-2026-04-14 fmt --check --all`\n - `cargo +nightly-2026-04-14 clippy --workspace --all-targets -- -D warnings`\n - `cd apps/fabro-web && bun test && bun run typecheck && bun run build`\n - `cargo --locked dev docs check`\n\n## Assumptions and Unresolved Questions\n\n- The application is greenfield; removed fields, events, and attributes receive no compatibility layer.\n- Parallel branches remain single-node executions.\n- `max_parallel` remains supported.\n- Shared-workspace write races are explicitly the user’s responsibility.\n- No Git workspace warning or read-only enforcement will be added.\n- Unresolved questions: none.\n</proposed_plan>\n"
|
||
}
|
||
}
|
||
},
|
||
"graph_source": "digraph ImplementPlan {\n graph [goal=\"Implement and simplify\"]\n rankdir=LR\n\n start [shape=Mdiamond, label=\"Start\"]\n exit [shape=Msquare, label=\"Exit\"]\n\n toolchain [label=\"Toolchain\", shape=parallelogram, script=\"command -v cargo >/dev/null || { curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && sudo ln -sf $HOME/.cargo/bin/* /usr/local/bin/; }; cargo --version 2>&1\", max_retries=0]\n preflight_compile [label=\"Preflight Compile\", shape=parallelogram, script=\"cargo check -q --workspace 2>&1\", max_retries=0]\n preflight_lint [label=\"Preflight Lint\", shape=parallelogram, script=\"cargo +nightly-2026-04-14 clippy -q --workspace --all-targets -- -D warnings 2>&1\", max_retries=0]\n fix_lints [label=\"Fix Lints\", prompt=\"The preflight lint step failed. Read the build output from context and fix all clippy lint warnings.\", model=\"anthropic/claude-fable-5\", provider=\"openrouter\", reasoning_effort=\"xhigh\", max_visits=3]\n implement [label=\"Implement\", prompt=\"Read the plan file referenced in the goal and implement every step. Make all the code changes described in the plan. Use red/green TDD.\", model=\"openai/gpt-5.6-sol\", provider=\"openrouter\", reasoning_effort=\"xhigh\"]\n simplify_fable [label=\"Simplify (Claude Fable 5)\", prompt=\"@prompts/simplify.md\", model=\"anthropic/claude-fable-5\", provider=\"openrouter\", reasoning_effort=\"xhigh\"]\n simplify_sol [label=\"Simplify (GPT-5.6 Sol)\", prompt=\"@prompts/simplify.md\", model=\"openai/gpt-5.6-sol\", provider=\"openrouter\", reasoning_effort=\"max\"]\n verify [label=\"Verify\", shape=parallelogram, script=\"git fetch origin main 2>&1 && git merge --no-edit --no-stat origin/main 2>&1 && cargo +nightly-2026-04-14 fmt --all 2>&1 && cargo dev docs refresh 2>&1 && cargo +nightly-2026-04-14 fmt --check --all 2>&1 && { command -v rg >/dev/null 2>&1 || { echo 'rg is required for verify'; exit 127; }; } && ! rg -n 'AuthMode::Disabled|RunAuthMethod|RunSubjectProvenance|\\bActorRef\\b|\\bActorKind\\b|AuthenticatedSubject|AuthenticatedService|AuthorizeRunScoped|AuthorizeRunBlob|AuthorizeStageArtifact|AuthorizeCommandLog|auth_method\\s*==\\s*\\\"disabled\\\"' lib/crates apps lib/packages docs/public/api-reference/fabro-api.yaml 2>&1 && cargo +nightly-2026-04-14 clippy --workspace --all-targets -- -D warnings 2>&1 && cargo nextest run --workspace --status-level slow --profile ci 2>&1 && cargo dev docs check 2>&1 && bun install --frozen-lockfile 2>&1 && (cd apps/fabro-web && bun run typecheck) 2>&1 && (cd apps/fabro-web && bun run test) 2>&1 && (cd lib/packages/fabro-api-client && bun run typecheck) 2>&1 && cargo dev build -- -p fabro-cli --release 2>&1\", goal_gate=true, retry_target=\"fixup\"]\n fixup [label=\"Fixup\", prompt=\"The verify step failed. Read the build output from context and fix all format, clippy, Rust test, docs, TypeScript typecheck/test, and build failures.\", model=\"anthropic/claude-fable-5\", provider=\"openrouter\", reasoning_effort=\"xhigh\", max_visits=3]\n\n start -> toolchain\n toolchain -> preflight_compile [condition=\"outcome=succeeded\"]\n toolchain -> exit\n preflight_compile -> preflight_lint [condition=\"outcome=succeeded\"]\n preflight_compile -> exit\n preflight_lint -> implement [condition=\"outcome=succeeded\"]\n preflight_lint -> fix_lints\n fix_lints -> preflight_lint\n implement -> simplify_fable -> simplify_sol -> verify\n verify -> exit [condition=\"outcome=succeeded\"]\n verify -> fixup\n fixup -> verify\n}\n",
|
||
"workflow_slug": "implement-plan",
|
||
"source_directory": "/Users/bhelmkamp/p/fabro-sh/fabro-3",
|
||
"provenance": {
|
||
"server": {
|
||
"version": "0.303.0-nightly.1"
|
||
},
|
||
"client": {
|
||
"user_agent": "fabro-cli/0.302.0-nightly.0",
|
||
"name": "fabro-cli",
|
||
"version": "0.302.0-nightly.0"
|
||
},
|
||
"subject": {
|
||
"kind": "user",
|
||
"identity": {
|
||
"issuer": "https://github.com",
|
||
"subject": "19"
|
||
},
|
||
"login": "brynary",
|
||
"auth_method": "github",
|
||
"avatar_url": "https://avatars.githubusercontent.com/u/19?v=4"
|
||
}
|
||
},
|
||
"manifest_blob": "c2cd720fe18b00d826209b61e7061e0ae15625b51ec2e0af3f5b6ded56c65a75",
|
||
"definition_blob": "3501fc8b5119235fabf49254dfd00c486c8cba321805ce6b9364916ecce1a8ae",
|
||
"git": {
|
||
"origin_url": "https://github.com/fabro-sh/fabro",
|
||
"branch": "main",
|
||
"sha": "1874497056778d15f33de1a71d5cf23b960f1119",
|
||
"dirty": "clean",
|
||
"push_outcome": {
|
||
"type": "not_attempted"
|
||
}
|
||
}
|
||
},
|
||
"web_url": "https://fabro-testing.walleye-rainbow.ts.net/runs/01KY7YH7RYCJ1BDVTTP96ZA4HV",
|
||
"start": null,
|
||
"status": {
|
||
"kind": "starting"
|
||
},
|
||
"status_updated_at": "2026-07-23T16:56:54.887666904Z",
|
||
"last_event_at": "2026-07-23T16:57:07.814814220Z",
|
||
"pending_control": null,
|
||
"checkpoints": [],
|
||
"conclusion": null,
|
||
"sandbox": {
|
||
"kind": "ready",
|
||
"plan": {
|
||
"provider": "daytona"
|
||
},
|
||
"instance": {
|
||
"provider": "daytona",
|
||
"snapshot": "fabro-fdb28dec-1233-892c-b9d7-9f88f8353e7a",
|
||
"runtime": {
|
||
"id": "fabro-01KY7YH7RYCJ1BDVTTP96ZA4HV",
|
||
"working_directory": "/home/daytona/workspace/fabro",
|
||
"repo_cloned": true,
|
||
"clone_origin_url": "https://github.com/fabro-sh/fabro",
|
||
"clone_branch": "main",
|
||
"workspace_root": "/home/daytona/workspace",
|
||
"repos_root": "/home/daytona/repos",
|
||
"primary_repo_path": "/home/daytona/repos/fabro-sh/fabro",
|
||
"primary_repo_link": "/home/daytona/workspace/fabro"
|
||
}
|
||
}
|
||
},
|
||
"pull_request": null,
|
||
"superseded_by": null,
|
||
"pending_interviews": {},
|
||
"stages": {}
|
||
} |