Apply the five findings from the external review: reject archived sources
with 409 (was contradictory); emit RunSupersededBy only on archive success
(was self-contradicting with the ordering rationale); look up working_directory
from the run's RunSpec instead of hand-waving AppState.repo_path; plumb
superseded_by through RunSummary + OpenAPI to honor the 'helps fabro ps' claim;
reconcile test scenarios to the archive-first ordering.
Also add GET /runs/{id}/timeline to Unit 2 so --list display moves server-side
alongside the mutating rewind call (web-UI parity). Normalize all status
codes from 412 to 409 to match fabro-server's CONFLICT convention.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Record the five decisions from the targeted Unit 2 review: 207 Multi-Status
for archive-failure partial success, graceful-degradation mapping for TOCTOU
precondition races, archive-first event ordering, accept-orphan retry posture,
and a new superseded_by projection field. Also add spawn_blocking and
operations-layer composite guidance from the review's autofixes.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Integrates origin's worker-JWT-auth work (commits 8a6f83bb0..c847a828d)
with the config-boundary refactor that landed locally. Conflicts
resolved:
- commands/dump.rs: take origin's removal of the 500-line in-process
test block (replaced by real-server integration coverage).
- commands/run/runner.rs: keep local's dense WorkflowSettings import,
drop dead SettingsLayer import, pull in origin's ActorRef.
- manifest_builder.rs: adopt origin's lifted working_directory
resolution (fixes#159 - manifest git detection in nested repos),
but via local's resolve_working_directory_from_run API that takes
the dense RunNamespace. Update the regression test's
ManifestBuildInput literal to local's run_overrides/cli_overrides
field shape.
- server.rs: keep origin's jwt_auth_mode/jwt_auth_state/
test_user_subject/issue_test_user_jwt/issue_test_worker_token/
create_run_with_bearer/bearer_request test helpers, adapt
jwt_auth_state to local's create_test_app_state_with_session_key
signature (ServerSettings + RunLayer), keep local's dense
canonical_origin_settings that returns ServerSettings via
server_settings_from_toml. Rewrite
build_app_state_requires_session_secret_for_worker_tokens against
the dense AppStateConfig (resolved_settings +
resolved_runtime_settings_for_tests).
Post-merge verification: workspace builds clean, cargo +nightly
fmt --check all clean, cargo +nightly clippy --workspace
--all-targets -- -D warnings clean, cargo nextest run --workspace
4560 tests passed.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Was linking to https://fabro.dev/getting-started/quick-start (wrong
domain, 404). Use relative /getting-started/introduction so it resolves
correctly on docs.fabro.sh.
Fixes#167
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The `fabro store dump` -> `fabro dump` rename left `commands/store/` as a
vestigial directory with a stale one-line `StoreRunExport` alias. Move
`dump.rs` and `rebuild.rs` up to `commands/`, import `RunDump` directly,
rename `dump::dump_command` -> `dump::run`, and clean up stale docs and
a noise test that only asserted clap's default error output.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Implements plan: single origin, drop CLI preflight, gate demo toggle.
Removes loopback client target and CLI auth config preflight endpoint;
adds canonical_origin module on the server; regenerates SPA and TS API
client.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The primary install flow is now to start the server, complete setup in a
browser-based wizard, and restart. fabro install is retained as the
headless CLI-only alternative.
- Auto-open the install URL in the user's browser when fabro server start
enters install mode; print a manual-open fallback when open::that fails
- Rewrite install.md so agents drive the full start → wait → restart loop
- Retarget install.sh Y/n prompt from fabro install to fabro server start
- Update README, quick-start, deploy-server, cli reference, and marketing
captions to point at fabro server start as the next step after download
- Add troubleshooting entries for "wizard didn't open" and "server exited
after wizard"
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
GitHub's App Manifest endpoint rejects `redirect_url` values that carry a
query string with "invalid redirect_uri", leaving the web wizard stuck:
the 10-minute pending-setup guard then blocked every retry for ten
minutes. Move the CSRF state out of `redirect_url` and into a hidden
`state` form field on the auto-submit — GitHub preserves it on the
callback, matching the CLI's working Manifest flow. Drop the retry
conflict so a fresh POST to /install/github/app/manifest always replaces
the pending entry and mints a new state token; stale callbacks are
already rejected by the existing state-match check on the redirect
handler.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces hand-written K/V stores in fabro-store with a shared Record trait
plus Repository<R> typed K/V layer. Adds KeyedMutex for per-key serialization
and transaction() for all-or-nothing WriteBatch commits. Renames
SlateAuthCodeStore/SlateAuthTokenStore to AuthCodeStore/RefreshTokenStore and
adds BlobStore and RunCatalogIndex wrappers on top of Repository. Deletes
catalog.rs in favor of RunCatalogIndex. Database gains blobs() and
catalog_index() accessors; auth_tokens() is renamed refresh_tokens().
Plan: docs/plans/2026-04-20-003-refactor-fabro-store-record-abstractions-plan.md
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Rename the last stale workflow test helpers and assertions that still used
pre-refactor checkpoint/retro file terminology, and update the retro docs
to describe the exported layout that now exists.
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>
Lift shared client DTOs into fabro-types, move auth/target/error/session
logic into fabro-client, and reduce fabro-cli to orchestration around the
builder-based client path.
This also lands the remaining plan cleanup for ApiError, ServerTarget
canonicalization, and the RunEventStream rename at the CLI boundary.
Document that unknown Fabro run events already fall back through
EventBody::Unknown, and that the refactor only needs to preserve
that behavior during the EventEnvelope move.
Capture the technical plan for extracting a new fabro-client crate from
fabro-cli, lifting domain DTOs (RunSummary, EventEnvelope, RunProjection,
ArtifactUpload) to fabro-types, and applying a set of OOP-style naming
cleanups along the way. Ran through ce-plan deepening and document-review
with feedback integrated.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Delete the CliTargetTls settings, ClientTlsSettings struct, rustls-pemfile
dep, and the fabro-http wrapper methods (use_rustls_tls/identity/
add_root_certificate) that only the CLI client-auth path used. The server
no longer terminates TLS in-process and the CliAuthStrategy::Mtls variant
had no construction or match sites.
Also simplify ServerTarget::HttpUrl to a tuple variant (HttpUrl(String))
now that tls is gone, removing the struct-variant ceremony across 22
construction and destructure sites.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>