Implements the plan at
docs/plans/2026-04-20-003-refactor-unify-run-vocabulary-metadata-plan.md.
- Rename RunRecord to RunSpec and RunProjection.run to .spec everywhere
in Rust source, tests, helpers, test names, and error messages.
- Introduce SerializableProjection wrapper that trims bulky node text
fields (prompt, response, diff, stdout, stderr) for run.json snapshots.
- Collapse metadata-branch and CLI export to one RunDump::from_projection
builder emitting run.json + graph.fabro + stages/{stage_id}/... and
drop legacy top-level start/status/checkpoint/sandbox/retro/conclusion
split files.
- Replace MetadataStore::write_checkpoint with write_snapshot returning
the commit SHA; add read_run_projection/read_run_spec; demote
read_checkpoint/read_start_record to projection-field extractors.
- Switch fork, rewind, rebuild_meta, CLI rewind recovery, and retro
upload to read the unified projection layout.
- Add additive query methods on RunSpec and RunProjection.
Serde-level `alias = "spec"` shim dropped; `rename = "run"` retained to
keep the server API wire format stable per the plan's scope boundary.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Keep project config and checked-in workflows under .fabro so they stay out of
normal repo listings. Update config discovery, CLI project commands, fixtures,
docs, and checked-in workflow paths to use .fabro/project.toml and
.fabro/workflows/*.
Add a shared MiniJinja-based template crate and migrate workflow prompts,
imports, hooks, and InterpString env references to the new {{ ... }}
syntax. This also threads typed run inputs through workflow rendering and
updates docs and tests to match the new templating model.
Rewrite every docs/ reference and integration guide example that
previously showed legacy flat TOML (`[llm]`, `[vars]`, `[sandbox]`,
`[setup]`, `[exec]`, `[fabro]`, `[pull_request]`, `[mcp_servers]`,
`[git]`, `[web]`, `[api]`, `[features] retros`, `version = 1`,
top-level `storage_dir`) to use the v2 namespaced schema. Also update
the surrounding prose to describe v2 merge semantics (R22 run.inputs
wholesale replacement, R71 sticky sandbox.env/labels, R30 whole-list
prepare.steps replacement, hook id-based replacement).
Files touched:
- docs/reference/user-configuration.mdx (complete rewrite around
[cli.*] ownership, [run.*] run-scoped defaults, [cli.target] /
[cli.exec] / [cli.output] / [cli.updates] / [cli.logging], and
[run.agent.mcps.<name>] with durations like "10s")
- docs/reference/cli.mdx (settings.toml example uses [cli.exec.*],
[run.model], [cli.target])
- docs/execution/run-configuration.mdx (full run-config example
rewritten to use [workflow].graph, [run].goal/working_dir,
[run.model], [run.prepare.steps], [run.sandbox.daytona.snapshot]
with Size values, [run.inputs], [run.artifacts], [run.agent.mcps],
[run.pull_request], [[run.hooks]] with optional id and duration
timeout; section docs explain the new merge semantics)
- docs/execution/environments.mdx and devcontainers.mdx (sandbox
examples now use [run.sandbox.*])
- docs/execution/retros.mdx (retros moved to [run.execution] retros
= true per R31)
- docs/execution/failures.mdx (fallbacks now a single ordered array
under [run.model].fallbacks)
- docs/workflows/variables.mdx ([vars] → [run.inputs], wholesale
replacement semantics explained)
- docs/administration/server-configuration.mdx (full reference
rewritten around [server.listen]/[server.api]/[server.web]/
[server.auth]/[server.storage]/[server.scheduler]/[server.logging]/
[server.integrations])
- docs/api-reference/overview.mdx (auth strategies now enabled via
[server.auth.api.jwt].enabled and [server.auth.api.mtls].enabled;
listener TLS moved to [server.listen.tls])
- docs/integrations/daytona.mdx, github.mdx (provider config now
nested under [run.sandbox.daytona] / [server.integrations.github])
- docs/human-tools/ssh-access.mdx (sandbox examples to v2)
- docs/agents/mcp.mdx (Playwright sandbox example to [run.agent.mcps])
- docs/core-concepts/models.mdx (model config and fallbacks array to
[run.model])
Canonical fabro-cli overrides and server run_manifest now emit
verbose via [cli.output].verbosity = verbose rather than the prior
run.metadata staging. No code changes beyond those Stage 4 fixes that
were already in flight.
Make ArtifactStore the only artifact read path, stop writing
manifest.json into run scratch, and update the CLI summary to
resolve artifact paths from the durable server API.
Drop scratch-only compatibility paths and legacy test scaffolding now that
SlateDB-backed state is authoritative. This removes scratch file fallbacks,
updates docs and UI labels, and moves tests onto durable store-backed helpers.
Store large context payloads in the global CAS and keep durable
checkpoint state as blob://sha256 refs instead of execution-local file
paths. Resolve and materialize blob refs at execution, output, and export
time so resumed and remote runs can read legacy and new artifacts
consistently.
- centralize FABRO_HOME and storage path resolution in fabro-config
- rename store types, extract ArtifactStore, and simplify run key layout
- switch run scratch to scratch/, remove RuntimeState, and refresh docs/clients
Consolidate CLI and server machine defaults under settings.toml,
including loader renames, writer preservation fixes, same-machine
manifest handling, and docs/test updates for the new config model.
Update the run directory, context, and output docs to describe
large offloaded values as file-backed artifacts while preserving the
existing cache path examples.
Replace the batch AssetsCaptured event with per-file AssetCaptured events
that include content hashes and MIME type. The asset collection manifest
now stores a captured_assets array with full metadata instead of bare
path strings, enabling downstream integrity verification and content
type awareness.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Phase 5: Rename debug artifacts from run.toml/graph.fabro to
workflow.toml/workflow.fabro. Change write_run_config_snapshot to
byte-for-byte copy of the original TOML instead of re-serialization.
Phase 6: Add run_from_record() that builds execution state directly
from a RunRecord, bypassing prepare_workflow(). Refactor run_command
into run_command + run_command_impl to share execution logic. Simplify
run_engine_entrypoint to call run_from_record() instead of
reconstructing RunArgs and re-parsing the workflow.
Step 7k: Write RunRecord in the API server's execute_run() for
observability, enabling fabro ps/inspect for API-initiated runs.
Fix stale manifest.json reference in docs/agents/outputs.mdx.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Roadmap: replace placeholder items with current shipped/building/planned
features. Use real dates for sorting instead of manual sortOrder. Fix
UTC timezone rendering for date display.
Terminology: replace all standalone "DOT" references with "Graphviz" or
"Graphviz DOT" across docs, marketing, README, AGENTS.md, and OpenAPI
spec. Changelogs left unchanged as historical records.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add a blocking cargo-fmt hook to fabro.toml that auto-formats Rust
files after write_file, edit_file, or apply_patch tool calls. Improve
the hooks documentation with a detailed matcher field reference table,
tool name catalog, cross-field matching caveat, and additional examples.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Update 47 MDX doc pages, OpenAPI spec, SVG diagram, language
grammar, frontend demo data, marketing page, skills, and README
to use .fabro extension. Add "fabro" to fileTypes in language
grammars. Document stack.child_workflow alongside stack.child_dotfile.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Per-run data now lives in ~/.arc/runs/ while daily CLI log files
stay in ~/.arc/logs/. Renames: logs_root → run_dir (RunConfig field,
Handler trait param, all handlers), logs_dir → run_dir (CLI arg,
local variables), default_logs_base → default_runs_base (path fn).
Adds DB migration 002 to rename workflow_runs.logs_dir → run_dir.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- docs/agents/mcp.mdx: Remove pre-release warning. Add sandbox transport
docs alongside stdio and HTTP. Restructure configuration section to
cover both cli.toml and run config TOML. Replace filesystem example
with Playwright browser automation example.
- docs/execution/run-configuration.mdx: Add [mcp_servers] section with
field reference for all three transport types. Add to full example.
- docs/reference/cli-configuration.mdx: Add sandbox transport subsection.
Cross-reference workflow-level MCP config.
- docs/integrations/daytona.mdx: Add MCP sandbox transport to feature table.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- hooks.mdx: add pre_tool_use/post_tool_use/post_tool_use_failure events,
tool-specific context fields, matcher support for tool names
- cli.mdx: add --mode and --server-url flags to arc exec
- run-configuration.mdx: add [pull_request] section
- github.mdx: add auto-PR to features table
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Every TOML example now shows which config file it belongs to
(server.toml, cli.toml, or run.toml) via Mintlify's title annotation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The extract_status_fields function recognized "outcome" as a field for
detecting status JSON objects but never read its value — LLM responses
like {"outcome": "fail", "failure_reason": "tests failed"} were silently
ignored and the outcome was always Success.
Now extract_status_fields reads the outcome field to set the node status
and failure_reason to populate the failure detail. Also adds a fallback:
if no routing directives are found in the response text, the handler
reads status.json from the sandbox CWD (written by agents that prefer
file output over inline JSON). Response text always takes priority.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add SVG workflow diagrams for all tutorials and examples
- Fill in NLSpec Convergence and Semantic Port example content
- Add Solitaire example workflow
- Add error handling sections to tools and subagents docs
- Add context compaction and artifact offloading to context docs
- Add credential redaction note to observability docs
- Add workflow diagram Frame references to tutorials
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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>
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>
Add Backends section to agents page explaining the two execution
strategies, expand backend attribute descriptions in dot-language
and stylesheet references, and add API-only notes to tools and
sub-agents pages.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove the "Skill file format" and "Creating skills" sections which
duplicated content from the Agent Skills specification. Link to
agentskills.io for the format spec and introduction instead.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add DaytonaNetwork enum (block/allow_all/allow_list) with custom serde
Deserialize for TOML string-or-table syntax
- Wire network config through run_config defaults merging and base_params
- Document network access in sandboxing, environments, and run-configuration
- Fill in execution docs: checkpoints, environments, failures, interviews,
run configuration, observability, retros
- Rename compounding.mdx → retros.mdx, insights.mdx → observability.mdx
- Use DaytonaConfig::default() in tests to reduce boilerplate
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>