fabro/apps/fabro-web/app/routes
fabro-sh-0530[bot] 94c657b92e
feat: add run.checkpoint.skip_git_hooks to bypass Git commit hooks (#355)
## Summary

Adds an opt-in `skip_git_hooks` boolean to `[run.checkpoint]` that
causes Fabro-managed run-branch checkpoint commits to pass `--no-verify`
to `git commit`, bypassing local hooks such as `pre-commit` and
`commit-msg`. Defaults to `false`. Metadata-branch snapshots and Fabro
`[[run.hooks]]` are unaffected.

```toml
[run.checkpoint]
skip_git_hooks = true
```

### Plan Summary

- `RunCheckpointSettings` (dense, in `fabro-types`) gains
`skip_git_hooks: bool` with `#[serde(default)]`.
- `RunCheckpointLayer` (sparse, in `fabro-config`) gains
`skip_git_hooks: Option<bool>` so layered config can distinguish unset
from explicit `false`.
- `RunCheckpointLayer::combine` is refactored from a wholesale-replace
to field-level merging: `exclude_globs` keeps its existing replace-wins
semantics; `skip_git_hooks` uses `.or()` (highest-priority layer that
sets it wins).
- `resolve_checkpoint` resolves `None → false`.
- `git_checkpoint` / `checked_git_checkpoint` in `sandbox_git.rs` accept
a new `skip_git_hooks: bool` and append `--no-verify` when true.
- `parallel_branch_commit_cmd` (new helper in `handler/parallel.rs`)
replaces the inline format string and accepts the same flag.
- `GitState` carries `checkpoint_skip_git_hooks`;
`RunOptions::checkpoint_skip_git_hooks()` exposes it; `execute.rs` and
`git.rs` thread it through.
- OpenAPI schema, TypeScript API client, and docs are updated.

### Key design decisions

**Field-level merging in `combine`**: the previous
`RunCheckpointLayer::combine` replaced the whole struct when
`self.exclude_globs` was non-empty. The refactor keeps that same replace
rule for `exclude_globs` while adding independent `Option::or` merging
for `skip_git_hooks`, so the two fields don't interfere.

**`--no-verify` only on run-branch commits**: the flag is injected only
in the two Git commit paths Fabro controls for run-branch checkpoints.
Metadata-branch snapshots use `git2` and never fire local hooks
regardless of this setting.


### Fabro Details

<details>
<summary>Ran 9 stages in 48m 3s for $13.91</summary>

| Stage | Duration | Cost | Retries |
|---|---|---|---|
| start | 0s | – | 0 |
| toolchain | 3s | – | 0 |
| preflight_compile | 2m 4s | – | 0 |
| preflight_lint | 2m 15s | – | 0 |
| implement | 24m 13s | $10.38 | 0 |
| simplify_opus | 10m 31s | $1.59 | 0 |
| simplify_gpt | 5m 8s | $1.93 | 0 |
| verify | 3m 4s | – | 0 |
| fmt | 3s | – | 0 |
| **Total** | **48m 3s** | **$13.91** | **0** |

</details>

<details>
<summary>Ran <code>ImplementPlan.fabro</code> (12 nodes and 15
edges)</summary>

```dot
digraph ImplementPlan {
    graph [
        goal="Implement and simplify",
        model_stylesheet="
            * { model: claude-opus-4-7; }
        "
    ]
    rankdir=LR

    start [shape=Mdiamond, label="Start"]
    exit  [shape=Msquare, label="Exit"]

    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]
    preflight_compile [label="Preflight Compile", shape=parallelogram, script="cargo check -q --workspace 2>&1", max_retries=0]
    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]
    fix_lints         [label="Fix Lints", prompt="The preflight lint step failed. Read the build output from context and fix all clippy lint warnings.", max_visits=3]
    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."]
    simplify_opus     [label="Simplify (Opus)", prompt="@prompts/simplify.md"]
    simplify_gpt      [label="Simplify (GPT-55)", prompt="@prompts/simplify.md", model="gpt-55"]
    verify            [label="Verify", shape=parallelogram, script="cargo +nightly-2026-04-14 clippy -q --workspace --all-targets -- -D warnings 2>&1 && cargo nextest run --cargo-quiet --workspace --status-level fail 2>&1 && cargo dev docs refresh 2>&1 && cargo dev docs check 2>&1", goal_gate=true, retry_target="fixup"]
    fixup             [label="Fixup", prompt="The verify step failed. Read the build output from context and fix all clippy lint warnings, test failures, and generated docs errors.", max_visits=3]
    fmt               [label="Format", shape=parallelogram, script="cargo +nightly-2026-04-14 fmt --all 2>&1", max_retries=0]

    start -> toolchain
    toolchain -> preflight_compile [condition="outcome=succeeded"]
    toolchain -> exit
    preflight_compile -> preflight_lint [condition="outcome=succeeded"]
    preflight_compile -> exit
    preflight_lint -> implement [condition="outcome=succeeded"]
    preflight_lint -> fix_lints
    fix_lints -> preflight_lint
    implement -> simplify_opus -> simplify_gpt -> verify
    verify -> fmt   [condition="outcome=succeeded"]
    verify -> fixup
    fixup -> verify
    fmt -> exit
}

```

</details>

⚒️ Generated with [Fabro](https://fabro.sh)

---------

Co-authored-by: Fabro <noreply@fabro.sh>
2026-05-22 17:26:06 -04:00
..
run-files refactor(run-files): rename diff selection picker 2026-05-09 15:33:54 -04:00
run-sandbox refactor(sandbox): unify run sandbox identity 2026-05-10 13:16:57 -04:00
ask-fabro.tsx feat: make the Ask Fabro sidebar resizable 2026-05-22 12:55:41 -04:00
auth-login.tsx refactor(web): move server state to SWR 2026-04-25 07:16:41 -04:00
automation-definition.tsx refactor(web): rename Workflows tab to Automations 2026-05-10 10:47:46 -04:00
automation-detail.tsx feat: add run.checkpoint.skip_git_hooks to bypass Git commit hooks (#355) 2026-05-22 17:26:06 -04:00
automation-diagram.tsx refactor(web): rename Workflows tab to Automations 2026-05-10 10:47:46 -04:00
automation-runs.tsx refactor: remove compatibility shims (#281) 2026-05-16 15:29:25 -04:00
automations.tsx refactor(web): rename Workflows tab to Automations 2026-05-10 10:47:46 -04:00
chats-detail.tsx feat(fabro-web): port /chats/new + /chats/:id from prototype (#289) 2026-05-16 17:10:16 -04:00
chats-layout.tsx feat(fabro-web): port /chats/new + /chats/:id from prototype (#289) 2026-05-16 17:10:16 -04:00
chats-new.tsx feat(fabro-web): port /chats/new + /chats/:id from prototype (#289) 2026-05-16 17:10:16 -04:00
chats-router.test.tsx feat(fabro-web): port /chats/new + /chats/:id from prototype (#289) 2026-05-16 17:10:16 -04:00
insights-editor.tsx refactor(web): simplify run logs view 2026-04-26 17:47:10 -04:00
insights-new.tsx Rename Arc to Fabro in TypeScript/JavaScript 2026-03-12 11:13:18 -04:00
insights.tsx refactor(web): move server state to SWR 2026-04-25 07:16:41 -04:00
profile-overview.tsx feat(web): add profile sub-navigation with Sessions 2026-05-10 12:40:50 -04:00
profile-sessions.test.tsx refactor(web): simplify profile sessions layout 2026-05-10 14:32:19 -04:00
profile-sessions.tsx feat(web): add secrets management settings page (#327) 2026-05-20 17:50:09 -04:00
profile.tsx feat(web): add profile sub-navigation with Sessions 2026-05-10 12:40:50 -04:00
redirect-home.tsx refactor(web): move server state to SWR 2026-04-25 07:16:41 -04:00
run-artifacts.tsx feat(web): migrate to generated API client 2026-05-08 07:44:33 -07:00
run-billing.test.tsx feat: Replace duration/elapsed fields with wall_time_ms and StageTiming (#343) 2026-05-21 21:06:40 -04:00
run-billing.tsx feat: Replace duration/elapsed fields with wall_time_ms and StageTiming (#343) 2026-05-21 21:06:40 -04:00
run-children.tsx fix(web): widen Children tab and hide zero count badge 2026-05-17 12:18:20 -04:00
run-detail.test.ts Collapsible run stage sidebar (#352) 2026-05-22 12:20:29 -04:00
run-detail.tsx feat: make the Ask Fabro sidebar resizable 2026-05-22 12:55:41 -04:00
run-events.tsx Collapsible run stage sidebar (#352) 2026-05-22 12:20:29 -04:00
run-files.render.test.tsx feat(api): unify public run shape 2026-05-10 20:48:55 -04:00
run-files.test.ts refactor(run-files): extract commit picker options 2026-05-09 15:33:19 -04:00
run-files.tsx feat(api): unify public run shape 2026-05-10 20:48:55 -04:00
run-logs.tsx feat(api): unify public run shape 2026-05-10 20:48:55 -04:00
run-overview.test.tsx fix(graph): support dotted Fabro graph attributes (#324) 2026-05-20 09:31:08 -04:00
run-overview.tsx fix(graph): support dotted Fabro graph attributes (#324) 2026-05-20 09:31:08 -04:00
run-sandbox.test.tsx feat(web): group memory sizes with thousands separators 2026-05-21 11:28:39 -04:00
run-sandbox.tsx Collapsible run stage sidebar (#352) 2026-05-22 12:20:29 -04:00
run-settings.tsx refactor: remove compatibility shims (#281) 2026-05-16 15:29:25 -04:00
run-source.tsx refactor(web): replace Graph tab with a Graph Source sidebar page 2026-05-07 16:36:20 -07:00
run-stages.test.ts feat: improve run board, thread, and MCP create flows (#347) 2026-05-22 09:39:20 -04:00
run-stages.tsx Collapsible run stage sidebar (#352) 2026-05-22 12:20:29 -04:00
run-terminal.tsx fix(web): wrap full-screen terminal route in ToastProvider 2026-05-10 10:32:11 -04:00
runs.test.tsx feat: improve run board, thread, and MCP create flows (#347) 2026-05-22 09:39:20 -04:00
runs.tsx feat: improve run board, thread, and MCP create flows (#347) 2026-05-22 09:39:20 -04:00
settings-general.tsx Add system resources settings page (#328) 2026-05-20 17:22:53 -04:00
settings-integrations.tsx feat(web): add Ask Fabro sidebar and settings panels (#346) 2026-05-21 19:36:19 -04:00
settings-live-events.test.tsx refactor(core): simplify reviewed run cleanup 2026-05-10 22:53:20 -04:00
settings-live-events.tsx refactor(core): simplify reviewed run cleanup 2026-05-10 22:53:20 -04:00
settings-models.tsx feat(web): add secrets management settings page (#327) 2026-05-20 17:50:09 -04:00
settings-resources.test.tsx Collapsible run stage sidebar (#352) 2026-05-22 12:20:29 -04:00
settings-resources.tsx feat(web): add Ask Fabro sidebar and settings panels (#346) 2026-05-21 19:36:19 -04:00
settings-secrets-new.tsx feat(web): add secrets management settings page (#327) 2026-05-20 17:50:09 -04:00
settings-secrets.tsx feat(web): add secrets management settings page (#327) 2026-05-20 17:50:09 -04:00
settings-security.tsx feat(web): split settings into General/Integrations/Security/Storage tabs 2026-05-18 16:13:25 -04:00
settings-storage.tsx feat(web): drop the Mount point row from storage settings 2026-05-21 11:28:39 -04:00
settings.tsx feat(web): order Models above Integrations in settings nav 2026-05-21 11:28:39 -04:00
setup.test.ts feat(web): show GitHub App install return state on /setup 2026-04-29 10:41:28 -04:00
setup.tsx feat(web): show GitHub App install return state on /setup 2026-04-29 10:41:28 -04:00
start.tsx Collapsible run stage sidebar (#352) 2026-05-22 12:20:29 -04:00