Bryan Helmkamp
b9fe1282d3
Attractor spec hunks 9-11: edge selection fallback and default_max_retries rename
...
- Remove any-edge fallback from select_edge() in deterministic mode; random
mode retains it as an enhancement over the base spec
- Restrict preferred_label and suggested_next_ids matching to unconditional
edges only (already applied in prior work, tests added here)
- Rename default_max_retry → default_max_retries across codebase (code, docs,
fixtures, skills) and change default from 3 to 0
- Update transitions.mdx to document edge selection cascade accurately
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 14:20:24 -04:00
Bryan Helmkamp
2172f5987e
Add Node Outcomes docs page and fix status gaps across docs
...
New page (execution/outcomes.mdx) defines the 5 stage statuses, documents
how each handler produces them, and explains allow_partial, auto_status,
the retry loop, goal gate interaction, and outcome in edge conditions.
Existing pages updated: added missing `skipped` status to outcome key
descriptions, improved `goal_gate`/`auto_status` descriptions in the
dot-language reference, added `allow_partial` to the attributes table,
and added cross-links from failures.mdx and transitions.mdx.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 10:05:36 -04:00
brynary-fabro[bot]
f9d0ebaf33
Random Edge Selection ( #12 )
...
This PR introduces a `selection="random"` node attribute that enables
weighted-random tiebreaking when choosing among candidate outgoing
edges. The existing deterministic behavior (highest weight, then lexical
node ID) remains the default. The cascade priority—conditions →
preferred label → suggested next → unconditional → fallback—is
unchanged; randomness only replaces the final pick-one-from-candidates
step within each tier. A new `weighted_random` function handles the
sampling, treating edges with weight ≤ 0 as weight 1, while a
`pick_edge` dispatcher routes to either the random or deterministic
strategy based on the node's `selection()` accessor.
A validation rule (`RandomSelectionNoConditionsRule`) rejects nodes that
combine `selection="random"` with conditional edges, since condition
evaluation order would conflict with random selection. A companion rule
(`SelectionValidRule`) warns on unrecognized selection values. Both are
registered as built-in lint rules with appropriate error/warning
severities and actionable fix suggestions.
Documentation is updated in the transitions guide with a new "Random
selection" section explaining the behavior and constraints, and the DOT
language reference gains a `selection` row in the node attributes table.
All changes were developed following red/green TDD cycles with
comprehensive test coverage for the accessor, weighted random sampling,
edge selection integration, and both validation rules.
### Fabro Details
<details>
<summary>Ran 7 stages in 17m 1s for $4.07</summary>
| Stage | Duration | Cost | Retries |
|---|---|---|---|
| start | 0s | – | 0 |
| toolchain | 0s | – | 0 |
| preflight_compile | 0s | – | 0 |
| preflight_lint | 0s | – | 0 |
| implement | 0s | $2.43 | 0 |
| simplify | 0s | $1.63 | 0 |
| verify | 0s | – | 0 |
| **Total** | **17m 1s** | **$4.07** | **0** |
</details>
<details>
<summary>Ran <code>ImplementAndSimplify.fabro</code> (10 nodes and 13
edges)</summary>
```dot
digraph ImplementAndSimplify {
graph [
goal="Implement and simplify",
model_stylesheet="
* { backend: api; model: claude-opus-4-6;}
"
]
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 2>&1", max_retries=0]
preflight_lint [label="Preflight Lint", shape=parallelogram, script="cargo clippy -- -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."]
simplify [label="Simplify", prompt="@prompts/simplify.md"]
verify [label="Verify", shape=parallelogram, script="cargo clippy -- -D warnings 2>&1 && cargo test 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 and test failures.", max_visits=3]
start -> toolchain
toolchain -> preflight_compile [condition="outcome=success"]
toolchain -> exit
preflight_compile -> preflight_lint [condition="outcome=success"]
preflight_compile -> exit
preflight_lint -> implement [condition="outcome=success"]
preflight_lint -> fix_lints
fix_lints -> preflight_lint
implement -> simplify -> verify
verify -> exit [condition="outcome=success"]
verify -> fixup
fixup -> verify
}
```
</details>
⚒️ Generated with [Fabro](https://fabro.sh )
---------
Co-authored-by: Fabro <noreply@fabro.sh>
2026-03-15 19:54:48 -04:00
Bryan Helmkamp
d4fe6b72e0
docs: rename Arc to Fabro throughout docs
...
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 10:53:44 -04:00
Bryan Helmkamp
4605f821e8
Add custom TextMate grammar for DOT syntax highlighting in docs
...
Revert the graphviz language identifier back to dot (Shiki doesn't
bundle either) and register a custom TextMate grammar via Mintlify's
styling.codeblocks.languages.custom config. The grammar (extracted from
apps/arc-web/app/data/dot-grammar.ts) highlights keywords, shape names,
attributes, strings, comments, and operators.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 21:41:54 -05:00
Bryan Helmkamp
6a98dcc246
Use graphviz language identifier for DOT code blocks, add titles to workflow examples
...
Changes ```dot to ```graphviz across all docs for better syntax highlighting
in Mintlify (Shiki). Full digraph blocks get a title derived from the workflow
name (e.g. title="hello.dot").
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 21:26:45 -05:00
Bryan Helmkamp
dd797cca1a
Fill in core docs: How Arc Works, Models, Workflows, Nodes & Stages, Transitions
...
- How Arc Works: end-to-end architecture with diagram, execution loop, retries,
sandboxes, observability, and resume
- Models: multi-provider rationale, full catalog table, stylesheets, overrides
via CLI and TOML, ensemble SVG
- Workflows: anatomy SVG, key node types, branching/loops SVG, parallel SVG,
model stylesheets, goal gates
- Nodes & Stages: all node types with attributes, fidelity/thread_id tables,
join/error/retry policy tables
- Transitions: edge selection priority, condition expression language, agent
transitions, human gates, weight tiebreaking
- Remove workflows/ingestion page
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 17:29:57 -05:00
Bryan Helmkamp
d450695a20
Scaffold Mintlify docs site with full navigation structure
...
Replace boilerplate Mintlify starter with Arc docs outline:
- Switch to almond theme (sidebar search, card-based layout)
- Top nav: Documentation, Guides, API Reference, Changelog
- Documentation sidebar: Getting Started, Core Concepts, Defining
Workflows, Executing Workflows, Agents, Administration, Deployment,
Reference
- Guides tab with example workflows
- Get Started button in navbar
- 48 MDX stub pages across 9 directories
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-03 10:33:09 -05:00