Commit graph

2884 commits

Author SHA1 Message Date
Scott Werner
df5105abc6 Share one supervised process runner between server and CLI Git
The CLI's native Git runner and the server's run_git_plan each hand-rolled
the same mechanics: kill-on-drop, a wall-clock timeout, output capture,
and (only in the CLI) process-group teardown, bounded capture, and
cancellation. Add fabro_proc::SupervisedCommand, which owns stdio, the
process group, the timeout, cooperative cancellation, and bounded
capture, and put both runners on it. The server gains group teardown on
timeout, so helpers a stuck clone or fetch spawned no longer outlive it;
the CLI keeps discarding output on failure and gains nothing but less
code. The hardened -c overrides become one named list in the CLI.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 14:50:10 -06:00
Scott Werner
cd47d53c0a Move the run-driven remote workflow test to cmd/run.rs
remote_workflow_run_starts_once_create_leaves_submitted_and_failures_do_not_refetch
lived in cmd/create.rs but drove fabro run in four of its five
iterations and asserted the start call, which is fabro run's contract.
Split it: cmd/create.rs keeps the single create invocation that must
leave the run submitted without starting it, cmd/run.rs owns the
run-driven success and failure iterations, and the workflow and remote
repository fixtures move to the shared command test support module.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 14:50:10 -06:00
Scott Werner
15413c20f8 Keep Ctrl-C owned for the whole native Git command phase
owned() polled tokio's ctrl_c() only for the duration of one Git
acquisition. On Unix that listener permanently replaces the default
SIGINT disposition, so once acquisition finished nothing handled Ctrl-C
and fabro create, fabro run --detach, and fabro run before attach
silently ignored it while waiting on the server. Introduce an
Interruption handle that the command entry points create from the run
arguments: it installs a listener only when --workflow-git or
--target-git is in play, guards create (and start for fabro run) as one
phase, and tracks owned Git tasks so interruption waits for their
cleanup before returning. attach keeps installing its own listener.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 14:50:10 -06:00
Scott Werner
f2a92b243e Acquire the remote workflow before observing a local Git target
For --workflow-git selections, target resolution ran before the remote
workflow ref was verified to exist. On Docker and Daytona environments a
path target that is a GitHub checkout is observed via
observe_git_run_target, which may silently push the attached branch, so
a typo in --workflow-ref produced a remote side effect with no run
created. Resolve the remote workflow after parent and environment
validation but before target observation, restoring the pre-existing
workflow-then-target order, and cover it with a caller checkout whose
unpushed branch must stay unpublished.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 14:50:10 -06:00
Scott Werner
38c819b5c9 Contain the selected workflow file instead of pre-walking the checkout
Remote acquisition walked the entire depth-1 checkout and failed on any
symlink that dangled or resolved outside the root, even when the link
was nowhere near the selected workflow. Submodule-style dangling links
and links into the host are common in workflow repositories and made
--workflow-git fail where the same commit collected fine locally. The
bundler already root-checks every file it opens; the only unchecked
reads were the selected TOML (or a graph selector's sibling TOML) during
location resolution. Check those in collect_workflow_versions and drop
the O(repo) walk. walkdir stays a dev-dependency for the dump tests.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 14:50:10 -06:00
Scott Werner
67434d1c3a Classify workflow refs once when parsing --workflow-ref
RemoteWorkflowRevision::parse already enforced which ref namespaces a
value may name, but RefCandidates re-derived the branch/tag split from
the string and treated everything under refs/ that was not refs/heads/
as a tag, relying on an invariant checked in another file. Parse now
yields Branch, Tag, or Name variants and resolution matches on them
directly, replacing the Option/Option candidate encoding and its
impossible (None, None) input state.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 14:50:10 -06:00
Scott Werner
7d050ed0f6 Reject unusable remote default branches with a --target-branch hint
Target resolution accepted any remote default HEAD that passed the ref
selector grammar, then failed inside GitRunTarget::validate with a
generic branch-grammar error when the default branch was something like
heads/main or tags/release. Validate the default branch as a working
branch name up front and point the user at --target-branch, since they
passed no branch at all.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 14:50:10 -06:00
Scott Werner
e2d95be8b7 Run native Git metadata lookups from an owned scratch repository
ls-remote ran in the caller's working directory while fetch, cat-file,
checkout, and rev-parse ran inside the temporary checkout, so the lookup
honored repository-local config (url.*.insteadOf, credential.*, http.*,
core.sshCommand) that the fetch never saw, and a broken .git in the
caller's directory failed the lookup outright. Initialize the scratch
repository first and run every command from it, so all steps see the
same configuration. Target resolution uses a short-lived scratch
repository of its own and still creates no checkout.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 14:50:10 -06:00
Scott Werner
cd0127e81f Only kill the Git process group when a command fails
The native Git runner SIGKILLed its child's process group after every
command, including successful ones. Git spawns credential-cache--daemon
into the same group, so each ls-remote or fetch destroyed the cache it
had just warmed and every later command re-ran the full helper chain.
Kill the group only on timeout, cancellation, or failure, and drop the
redundant kill/wait on an already-reaped child.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 14:50:10 -06:00
Scott Werner
3e5b7df998 Disable fsmonitor during native Git workflow checkout
The hardened -c list for CLI-owned Git acquisition disabled hooks, LFS
filters, submodules, and maintenance but omitted core.fsmonitor, so a
user's global fsmonitor hook (or the builtin daemon) still ran during the
temporary checkout. Match the sandbox's hardening and cover it in the
hooks/filters test.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 14:50:10 -06:00
Scott Werner
6e8a6c29df Simplify CLI workflow source and run target selection
Remove validation that ran twice on the same inputs: clap already
enforces the flag co-occurrence rules, and the native Git layer no
longer re-checks selectors, branch names, refs, and commit SHAs that
selection parsing already validated. Remote selector shape rules now
delegate to the shared WorkflowPath validator.

Reuse fabro_proc for the process-group kill and liveness probe instead
of calling nix directly, dropping the extra nix features. Fold the
duplicated branch/tag candidate derivation into one RefCandidates type,
label each Git command explicitly instead of inferring it from argv,
hoist the duplicated workflow resolver call in create_run, and merge the
two directory target arms now that the default is just the caller path.

Share the run-argument parser and workflow/commit fixtures across the
unit tests through a test_support module, drop an integration test that
duplicated one cell of the cross-product test, and make the malformed
slug vectors assert the clap rejection they exercise.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 14:50:10 -06:00
Scott Werner
81bb5bee82 Select CLI workflow sources and run targets independently 2026-09-11 14:50:10 -06:00
Bryan Helmkamp
619cb44e3c
Import lithos-llm types directly instead of through fabro-types
fabro-types no longer re-exports the lithos catalog and request types
(ProviderId, ModelId, ModelHandle, Message, ContentPart, TokenCounts,
Cost, Speed, ReasoningEffort, ReasoningOutput, and the rest). Every
crate that uses them depends on lithos-llm and names them there, and
the fabro-api progenitor replacements point at the lithos paths.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-10 10:03:08 -06:00
Bryan Helmkamp
fa3e485c95
Name built-in providers through lithos catalog::builtin
lithos-llm now ships the built-in provider ids and constructors, so
fabro-types drops its provider_ids module and every caller uses
lithos_llm::catalog::builtin directly. The crates that name a provider
now depend on lithos-llm themselves.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-10 09:48:37 -06:00
Bryan Helmkamp
f8df58966b
Use the lithos closest_supported_effort on ModelCapabilities
The reasoning-effort substitution rule now lives on lithos's
ModelCapabilities, so the workflow fallback planner calls it directly
and fabro-types drops its controls module. ReasoningEffort is re-exported
from lithos alongside the other request types.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-10 09:44:11 -06:00
Bryan Helmkamp
87e1e3a00f
Replace fabro-llm helper modules with lithos-llm equivalents
Delete fabro-llm's attachments, reasoning, and structured modules and
the LlmError newtype and ErrorFacts trait. lithos-llm now provides all
of them: InlineLocalFiles under the local-files feature, ReasoningOutput
with Response::reasoning(), Client::complete_object, and the retry,
auth, cancel, and failover predicates directly on Error and ErrorData.
fabro-llm keeps only failure_signature_hint, which is Fabro's own loop
detection policy.

Store ErrorData directly in the agent and workflow error enums, boxed
where the variant would otherwise dominate the enum size. Repin
lithos-llm to a1e3fd3 for these additions.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-10 09:41:20 -06:00
Bryan Helmkamp
3a998196ff
Answer catalog questions with the lithos catalog queries
fabro-llm's catalog module held some 250 lines of listing and picking
helpers over lithos data: enabled and listed providers, model lookup by
id, alias, or wire id, matches ranked as the resolver ranks, default and
probe models, the small utility model across ready providers, the nearest
model on another provider, and cost by handle. lithos-llm now answers all
of those on `Catalog` and `CatalogProvider` through `Offering`, so the
helpers and the `ModelEntry` wrapper go.

What stays in Fabro's catalog module is its own: building the catalog from
the operator overlay, and reading the agent harness and
`reasoning_by_default` from the shared `metadata.agent` namespace. The
passthrough selection policy in `selection.rs` keeps its rules and calls
lithos for the lookups.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-10 09:26:40 -06:00
Bryan Helmkamp
3510d5081d
Implement the lithos CredentialProvider trait directly
fabro-auth defined its own `CredentialSource` trait beside the lithos
`CredentialProvider`, with a parallel `ResolveError` and an adapter between
them, because lithos had no way to ask which providers a store can serve
right now. It does now: `credentials::readiness`, `ClientBuilder::build_ready`,
and `CredentialError::Unusable`.

- The vault, SQL vault, API-key, and extra-headers stores implement
  `CredentialProvider` directly. Material that is present but unusable (an
  expired token with no refresh, a wrong-typed vault entry, a header secret
  that did not resolve, a store read failure) is `CredentialError::Unusable`
  with the operator-facing reason; its `Display` replaces
  `auth_issue_message`. `is_configured` is the cheap presence check.
- `fabro_llm::build_client` calls `build_ready`; `FabroClient::auth_issues`
  carries `CredentialError`. `fabro_llm::configured_providers` replaces the
  per-store `configured_providers` method.
- `CredentialSource`, `ResolvedCredentials`, `lithos_credentials`,
  `ResolveError`, and `auth_issue_message` are deleted. Twenty files that
  held `Arc<dyn CredentialSource>` hold `Arc<dyn CredentialProvider>`.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-10 09:16:39 -06:00
Bryan Helmkamp
7ef09968f2
Document the catalog overlay without the metadata.fabro namespace
The `[llm]` reference now describes `enabled`, `api_key_url`,
`stands_in_for`, `small_default`, `probe`, `family`, and the cutoffs as
lithos fields, the coding harness under `metadata.agent`, and the secret
names lithos derives for operator-defined providers. Secret-bearing
headers go in `default_headers` as `{{ secrets.NAME }}` tokens. The
integration guides enable a provider with `enabled = true` on its table.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-09 23:26:48 -06:00
Bryan Helmkamp
b82b3dd48e
Use the lithos control enum API instead of local spellings
lithos-llm now exposes `ReasoningEffort::ALL`, `Speed::ALL`, `as_str`,
`Display`, and `FromStr` on its request-control enums. Fabro's
`controls` module kept parallel name tables and parsers for them; only
the nearest-supported-effort rule is Fabro's own, so that is what stays.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-09 23:23:49 -06:00
Bryan Helmkamp
2a2fc41807
Read catalog policy from lithos core fields and metadata.agent
Fabro's policy layer restated the lithos built-ins under `metadata.fabro`:
enabled flags, credentials, display facts, probe and small-default roles,
and agent profiles. lithos-llm now carries every one of those as a core
field or under the shared `metadata.agent` namespace, so the layer and its
typed view go:

- Delete `fabro-policy.toml` and `FABRO_POLICY_TOML`. The catalog is the
  lithos built-ins plus the operator's `[llm]` overlay, nothing between.
- Delete `fabro_types::catalog_policy`. `enabled`, `stands_in_for`,
  `api_key_url`, `family`, the cutoffs, `estimated_output_tps`,
  `small_default`, and `probe` are read from lithos accessors; the agent
  profile and `reasoning_by_default` come from `metadata.agent`, which
  Pebble reads too.
- `catalog::provider`, `enabled_providers`, and `listed_providers` return
  the lithos `CatalogProvider` directly; `ModelEntry` loses its policy
  field and gains `agent_profile()`.
- Test fixtures move `[providers.x.metadata.fabro] enabled = true` onto
  the provider table, drop `credentials` lists in favor of the secret name
  lithos derives from the provider id, and spell `agent_profile` as
  `metadata.agent.profile`.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-09 23:20:12 -06:00
Bryan Helmkamp
6dfc96d3fd
Resolve provider secrets through lithos conventional credentials
lithos-llm now owns which named secrets each provider reads and how they
shape into its auth scheme, including a derived `<PROVIDER>_API_KEY` for
operator-defined providers. Fabro's job shrinks to supplying the store:
`VaultCredentialSource` hands lithos a lookup that reads the process
environment, then the vault, under the same conventional names.

What Fabro still adds on top: the Codex OAuth credential in the vault,
refreshed and persisted when it expires; `{{ secrets.NAME }}` tokens in a
provider's `default_headers`, resolved against the vault and re-sent as
credential headers; and OpenAI organization and project headers from the
environment.

Deleted with the `metadata.fabro.credentials` list: `CredentialRef`,
`CredentialResolver`, `EnvCredentialSource` (now
`VaultCredentialSource::environment_only`), and the `env_var_names` /
`expected_vault_secret_name` helpers, replaced by `secret_names` and
`expected_secret_name` over the lithos table. `openai-codex` joins the
first-party provider id constants.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-09 23:00:08 -06:00
Bryan Helmkamp
0319b24585
Name fabro as the application on the model client
lithos-llm sends the application name as the codex `originator` header,
so the OpenAI Codex deployment can tell which harness a request came from.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-09 22:42:00 -06:00
Bryan Helmkamp
df5c9d2c57
Drop FabroResolver in favor of the lithos resolver
lithos-llm now owns `enabled` and `stands_in_for` as core provider
fields, and its `CatalogResolver` refuses disabled providers and reroutes
a request to the provider standing in for an unavailable one. Fabro's
resolver re-implemented both from `metadata.fabro`, so it goes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-09 22:41:47 -06:00
Bryan Helmkamp
7d5f33ab16
Add the gpt6 agent profile kind
lithos ships `metadata.agent.profile = "gpt6"` on the GPT-6 Astra row.
Fabro runs it on the GPT-5.6 harness: the same Codex core tool set,
memory filenames, question tool, and command timeout. The shared
`uses_codex_core_tools` predicate replaces the `== Gpt56` checks so the
two kinds cannot drift apart.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-09 22:37:28 -06:00
Bryan Helmkamp
6c1dc96af6
Stop Debug-formatting credentials in fabro-auth resolve tests
Three test panics printed the resolved `Credentials` value with `{:?}`.
The lithos credential types redact secrets in their Debug output, but
CodeQL's cleartext-logging rule cannot see that and flagged each site.
The variant name is enough to diagnose a failing test, so drop the value.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-09 19:09:22 -06:00
Bryan Helmkamp
5f49cdf9da
Delete fabro-model and document the lithos catalog overlay
fabro-model's ids and billing rollup now live in fabro-types, and its
pricing, catalog, provider TOMLs, and legacy index are replaced by the
lithos built-in catalog plus the Fabro policy layer.

Regenerate the configuration reference for the `[llm]` overlay and
`metadata.fabro`, and rewrite the SDK, models, and integration docs for
the lithos provider and model shapes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-09 17:26:57 -06:00
Bryan Helmkamp
75e5f34c0d
Expose lithos request and response shapes through the API, server, CLI, and web
The OpenAPI spec adopts the lithos request, response, content part,
tool, usage, and cost schemas. The completions endpoint returns the
lithos `Response` JSON verbatim and SSE carries lithos `StreamEvent`s
verbatim. The models and providers endpoints serve the fabro-types
catalog views, and the install and model-test flows probe providers
through fabro-llm.

The CLI builds its catalog from the operator overlay, drives `fabro exec`
through the server gateway adapter, and parses reasoning effort with the
shared controls. The web app reads content parts as lithos-tagged
objects. The TypeScript client is regenerated.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-09 17:26:57 -06:00
Bryan Helmkamp
82bcafcfca
Port fabro-workflow, hooks, validate, and store to the lithos types
Workflow LLM handlers build lithos requests, bill from lithos usage and
cost, and classify failures from lithos `ErrorKind`. Model resolution and
fallback use the fabro-llm selection and catalog helpers. Validation
rules read the lithos catalog, and store fixtures use the new
`BilledModelUsage` shape.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-09 17:26:57 -06:00
Bryan Helmkamp
e557774b0b
Rebuild fabro-llm on lithos-llm and adopt its stream contract in fabro-agent
fabro-llm is now a thin integration crate: catalog construction from the
lithos built-ins, the Fabro policy layer, and operator overlays; client
construction from catalog plus credentials; a Fabro `ModelResolver` that
enforces `metadata.fabro` policy; model selection; a server gateway
adapter; attachment inlining middleware; reasoning normalization;
one-shot structured output; probe wiring; and catalog API views. The
in-house codecs, transports, providers, tool loop, retry, cost, and
token-count code are deleted along with the wire snapshots that covered
them.

fabro-agent consumes lithos `StreamEvent`s and `Response`s directly.
Retry is split: lithos's retry middleware handles failures before any
visible output, and the agent replays the turn after.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-09 17:26:57 -06:00
Bryan Helmkamp
f37151ed46
Adopt lithos vocabulary in fabro-types, fabro-auth, and fabro-config
fabro-types re-exports the lithos request, response, content, tool, and
stream types and absorbs the identifiers, billing rollup, provider ids,
controls, catalog API views, and Fabro catalog policy (`metadata.fabro`)
that lived in fabro-model. Stored and wire formats use the lithos serde
shapes directly with no compatibility shims.

fabro-auth becomes a lithos `CredentialProvider`: `CredentialSource`
resolves credentials per catalog provider, with env, vault, SQL vault,
extra-headers, and API-key sources.

fabro-config's `[llm]` settings become an opaque TOML overlay layer
(`LlmLayer`) that is applied on top of the lithos built-ins and the Fabro
policy layer.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-09 17:26:57 -06:00
Bryan Helmkamp
580bb85f5b
Depend on lithos-llm and the published twin-openai crate
Add lithos-llm as a pinned git dependency and replace the in-repo
`test/twin/openai` crate with the published `twins` revision that
lithos-llm verifies its codecs against. Move the Fabro policy overlay
(`fabro-policy.toml`) into fabro-llm so Fabro owns its own catalog
policy layer.

Drop the twin-openai nextest overrides and CI package filter now that the
crate is no longer a workspace member.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-09 17:26:57 -06:00
Bryan Helmkamp
b6482910e5
Remove expired startup secret migrations 2026-09-05 14:05:48 -04:00
Bryan Helmkamp
6cf027282f
Update inspect snapshots for projected conclusion stages 2026-09-05 11:53:44 -04:00
Bryan Helmkamp
a7ed03e175
Rebuild conclusion stage summaries from run events 2026-09-05 11:44:23 -04:00
Scott Werner
a712aa4dab Reconcile runnable runs after server restart 2026-09-04 14:15:58 -04:00
Scott Werner
ab7cbeb4ae
Merge pull request #839 from fabro-sh/codex/remove-playground
Remove unsupported workflow playground
2026-09-04 11:18:00 -04:00
Scott Werner
8c0702bfac Remove obsolete playground API route assertion 2026-09-04 10:27:18 -04:00
Scott Werner
a00b95abe0 Report available environments when default is missing
When `fabro run` or `fabro create` omits `--environment` and the server
has no environment named `default`, the CLI previously failed with only
"could not retrieve environment `default`". It now lists the server's
environment catalog in the error so the user can pass an explicit
`--environment <id>` or create the missing `default` entry. Explicit
`--environment` lookups keep their existing not-found message.

Adds `Client::list_environments` to fabro-client for the catalog read.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-03 12:56:47 -04:00
Scott Werner
f52f2a1edb
Merge pull request #838 from fabro-sh/codex/persist-pre-start-worker-failures
Persist pre-start worker failures
2026-09-03 12:48:39 -04:00
Scott Werner
bdb7b29877
Merge pull request #837 from fabro-sh/codex/reject-local-auto-pr-admission
Reject automatic pull requests for Local runs
2026-09-03 12:40:01 -04:00
Scott Werner
f1b569d9e6 Remove unsupported workflow playground 2026-09-03 12:04:35 -04:00
Scott Werner
c437dc012d Simplify pre-start worker failure handling
Move the "which failures can happen before Starting" classification onto
FailureReason as an exhaustive predicate and use it for every
Runnable -> Failed transition, replacing the hand-maintained allowlist.
Give the pending-cancel precedence rule a single owner shared by the
worker launch and worker exit paths.

Test cleanups: share the Notify wait loop, server record fixture, and
post-failure assertions; simplify the pre-start test runtime's hold
flag; and parameterize the slate run.failed payload helper.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-03 11:45:47 -04:00
Scott Werner
c5010c0b33 Simplify the Local pull-request admission check
Use the shared clone-based provider predicate and rely on the settings
resolver dropping disabled pull-request settings instead of re-checking
the enabled flag. List the new intent-lane error code in the OpenAPI
description, trim the acceptance tests to what they actually prove, and
fold the docs note into the existing requirements sentence.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-03 11:43:29 -04:00
Scott Werner
a2002175e1
Merge pull request #835 from fabro-sh/codex/projected-run-cleanup
Move run projection replay into the summary store
2026-09-03 11:40:45 -04:00
Scott Werner
54666632c8 Persist pre-start worker failures 2026-09-02 17:29:41 -04:00
Scott Werner
cd20e453ec Use a compatible environment in pull request settings test 2026-09-02 17:24:22 -04:00
Scott Werner
18cb752b61 Reject automatic pull requests for Local runs 2026-09-02 17:15:52 -04:00
Scott Werner
0f1e5e1c9c Centralize run projection replay on ProjectedRun
Move ProjectedRun next to EventProjectionCache in run_state, since the
summary store both produces and consumes it, and give it a replay
constructor that owns the events-to-head derivation. load_projection now
returns RunNotFound directly instead of erasing it to None and having
callers rebuild it; load_run_projection is the single Option translation
point. install_in_memory_state reuses the existing From impl, and the
commit path passes its Arc through instead of unwrapping and
reallocating it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-02 16:33:14 -04:00
Scott Werner
efcf8a0d93
Merge pull request #831 from fabro-sh/codex/cli-run-intent-producer
Create CLI runs from immutable workflow intents
2026-09-02 15:45:21 -04:00