diff --git a/apps/fabro-web/app/lib/config.server.ts b/apps/fabro-web/app/lib/config.server.ts
index dc22d99c1..f5d75b283 100644
--- a/apps/fabro-web/app/lib/config.server.ts
+++ b/apps/fabro-web/app/lib/config.server.ts
@@ -22,6 +22,7 @@ interface GitConfig {
interface Features {
session_sandboxes: boolean;
+ retros: boolean;
}
interface WebConfig {
@@ -60,6 +61,7 @@ const GIT_DEFAULTS: GitConfig = {
const FEATURES_DEFAULTS: Features = {
session_sandboxes: false,
+ retros: false,
};
export const FABRO_CONFIG_PATH = join(homedir(), ".fabro", "server.toml");
diff --git a/docs/administration/server-configuration.mdx b/docs/administration/server-configuration.mdx
index 80d2d56df..8d58899e6 100644
--- a/docs/administration/server-configuration.mdx
+++ b/docs/administration/server-configuration.mdx
@@ -71,6 +71,9 @@ auto_stop_interval = 60
[sandbox.daytona.labels]
team = "platform"
+[features]
+retros = true
+
[checkpoint]
exclude_globs = ["**/node_modules/**", "**/.cache/**"]
@@ -138,6 +141,17 @@ Configure checkpoint behavior for all runs.
Exclude globs from `server.toml` and run configs are merged (union, deduplicated). See [Run Configuration — Checkpoint](/execution/run-configuration#checkpoint) for per-run configuration.
+### `[features]` section
+
+Toggle experimental or opt-in features. All features default to `false`.
+
+| Key | Description |
+|---|---|
+| `retros` | Enable automatic [retro](/execution/retros) generation after workflow runs (experimental) |
+| `session_sandboxes` | Enable session sandboxes in the web UI |
+
+The same `[features]` section can be set in `fabro.toml` (project-level) to enable features per-project.
+
## Environment variables
Fabro reads environment variables from a `.env` file in the working directory (if present) and from the shell environment. Provider API keys are required for the models you want to use; everything else is optional.
diff --git a/docs/api-reference/fabro-api.yaml b/docs/api-reference/fabro-api.yaml
index a50736272..800d0d69b 100644
--- a/docs/api-reference/fabro-api.yaml
+++ b/docs/api-reference/fabro-api.yaml
@@ -4505,6 +4505,9 @@ components:
session_sandboxes:
type: boolean
description: Enable session sandboxes.
+ retros:
+ type: boolean
+ description: "Experimental: enable automatic retro generation after workflow runs."
# ── Discovery Schemas ────────────────────────────────────────────────
diff --git a/docs/execution/retros.mdx b/docs/execution/retros.mdx
index 2ac396474..5720c9607 100644
--- a/docs/execution/retros.mdx
+++ b/docs/execution/retros.mdx
@@ -3,7 +3,11 @@ title: "Retros"
description: "Automatic retrospectives that analyze every workflow run"
---
-After every workflow run, Fabro generates a **retro** — a structured retrospective that captures what happened, what went well, and what didn't. Retros combine deterministic metrics extracted from the run's checkpoint with a qualitative narrative produced by an LLM agent that analyzes the full event stream.
+
+**Experimental feature.** Retros are disabled by default. Enable them with `[features] retros = true` in your project config or server config.
+
+
+After every workflow run, Fabro can generate a **retro** — a structured retrospective that captures what happened, what went well, and what didn't. Retros combine deterministic metrics extracted from the run's checkpoint with a qualitative narrative produced by an LLM agent that analyzes the full event stream.
The goal is continuous improvement. Retros give you a searchable history of how your workflows perform over time, surface friction patterns that would otherwise go unnoticed, and identify follow-up work before it falls through the cracks.
@@ -116,19 +120,26 @@ Retro: smooth — Successfully implemented the feature
Retro saved to ~/fabro-logs/01JKXYZ.../retro.json
```
-To skip retro generation for a single run, pass `--no-retro`:
+To enable retros for your project, set `retros = true` in the `[features]` section of your `fabro.toml`:
+
+```toml title="fabro.toml"
+version = 1
+
+[features]
+retros = true
+```
+
+To skip retro generation for a single run when retros are enabled, pass `--no-retro`:
```bash
fabro run workflow.fabro --no-retro
```
-To disable retros project-wide, set `retro = false` in your `fabro.toml`:
+Retros can also be enabled server-wide in `server.toml`:
-```toml title="fabro.toml"
-version = 1
-
-[fabro]
-retro = false
+```toml title="server.toml"
+[features]
+retros = true
```
### API
diff --git a/lib/crates/fabro-api/src/demo/mod.rs b/lib/crates/fabro-api/src/demo/mod.rs
index c64b32a9c..d056854ff 100644
--- a/lib/crates/fabro-api/src/demo/mod.rs
+++ b/lib/crates/fabro-api/src/demo/mod.rs
@@ -3284,6 +3284,7 @@ mod settings {
},
features: Features {
session_sandboxes: false,
+ retros: false,
},
log: Default::default(),
run_defaults: fabro_workflows::cli::run_config::RunDefaults {
diff --git a/lib/crates/fabro-api/tests/openapi_conformance.rs b/lib/crates/fabro-api/tests/openapi_conformance.rs
index 2ffb44ac2..b4c144cff 100644
--- a/lib/crates/fabro-api/tests/openapi_conformance.rs
+++ b/lib/crates/fabro-api/tests/openapi_conformance.rs
@@ -272,6 +272,7 @@ fn fully_populated_server_config() -> ServerConfig {
},
features: Features {
session_sandboxes: true,
+ retros: false,
},
log: LogConfig {
level: Some("debug".into()),
diff --git a/lib/crates/fabro-workflows/src/cli/project_config.rs b/lib/crates/fabro-workflows/src/cli/project_config.rs
index 43c66e5f5..a4ccb2367 100644
--- a/lib/crates/fabro-workflows/src/cli/project_config.rs
+++ b/lib/crates/fabro-workflows/src/cli/project_config.rs
@@ -19,6 +19,8 @@ pub struct ProjectConfig {
pub version: u32,
#[serde(default)]
pub fabro: ProjectFabroConfig,
+ #[serde(default)]
+ pub features: ProjectFeatures,
#[serde(alias = "directory")]
pub work_dir: Option,
pub llm: Option,
@@ -60,27 +62,29 @@ impl ProjectConfig {
pub struct ProjectFabroConfig {
#[serde(default = "default_root")]
pub root: String,
- #[serde(default = "default_retro")]
- pub retro: bool,
}
fn default_root() -> String {
".".to_string()
}
-fn default_retro() -> bool {
- true
-}
-
impl Default for ProjectFabroConfig {
fn default() -> Self {
Self {
root: default_root(),
- retro: default_retro(),
}
}
}
+/// Feature flags for the project. All features default to `false` (opt-in).
+#[derive(Debug, Default, Deserialize, PartialEq)]
+#[serde(deny_unknown_fields)]
+pub struct ProjectFeatures {
+ /// Experimental: enable automatic retro generation after workflow runs.
+ #[serde(default)]
+ pub retros: bool,
+}
+
/// Parse a project config from a TOML string.
pub fn parse_project_config(content: &str) -> anyhow::Result {
let config: ProjectConfig =
@@ -342,12 +346,13 @@ fn resolve_workflow_from(
}
/// Check whether retros are enabled in the project config.
-/// Returns `true` (the default) if no config is found or on error.
+/// Returns `false` (the default) if no config is found or on error.
+/// Retros are an experimental feature gated behind `[features] retros = true`.
pub fn is_retro_enabled() -> bool {
let start = std::env::current_dir().unwrap_or_else(|_| PathBuf::from("."));
match discover_project_config(&start) {
- Ok(Some((_path, config))) => config.fabro.retro,
- _ => true,
+ Ok(Some((_path, config))) => config.features.retros,
+ _ => false,
}
}
@@ -375,7 +380,6 @@ mod tests {
version: 1,
fabro: ProjectFabroConfig {
root: ".".to_string(),
- retro: true,
},
..Default::default()
}
@@ -389,9 +393,15 @@ mod tests {
}
#[test]
- fn parse_retro_false() {
- let config = parse_project_config("version = 1\n[fabro]\nretro = false\n").unwrap();
- assert!(!config.fabro.retro);
+ fn parse_retros_default_false() {
+ let config = parse_project_config("version = 1\n").unwrap();
+ assert!(!config.features.retros);
+ }
+
+ #[test]
+ fn parse_retros_enabled() {
+ let config = parse_project_config("version = 1\n[features]\nretros = true\n").unwrap();
+ assert!(config.features.retros);
}
#[test]
diff --git a/lib/packages/fabro-api-client/src/models/features.ts b/lib/packages/fabro-api-client/src/models/features.ts
index 75e01c2cf..ee3916a3e 100644
--- a/lib/packages/fabro-api-client/src/models/features.ts
+++ b/lib/packages/fabro-api-client/src/models/features.ts
@@ -22,5 +22,9 @@ export interface Features {
* Enable session sandboxes.
*/
'session_sandboxes'?: boolean;
+ /**
+ * Experimental: enable automatic retro generation after workflow runs.
+ */
+ 'retros'?: boolean;
}