Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .specs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ Proposed deltas to the canonical spec live under `changes/` as single documents
| [changes/2026-06-24-add_atproto_provider.md](changes/2026-06-24-add_atproto_provider.md) | Proposed | service: Tier 3 atproto provider |
| [changes/2026-06-24-complete_telemetry_exporters.md](changes/2026-06-24-complete_telemetry_exporters.md) | Proposed | service: OTLP/X-Ray exporters + OTEL span layer |
| [changes/merged/2026-07-01-complete_config_loading.md](changes/merged/2026-07-01-complete_config_loading.md) | Merged | service: config overlay merge, env overrides, fail-closed `${VAR}` placeholders, startup validation |
| [changes/merged/2026-08-05-resolve_config_placeholders_all_channels.md](changes/merged/2026-08-05-resolve_config_placeholders_all_channels.md) | Merged | service/bindings: one shared config resolve, fail-closed placeholders, FFI parity, and `config check` |
| [changes/merged/2026-07-01-fix_kms_ecdsa_and_jwk_encoding.md](changes/merged/2026-07-01-fix_kms_ecdsa_and_jwk_encoding.md) | Merged | service: KMS ES* DER→raw JWS signatures, RFC 7518 JWK `n`/`e`, ES512 JWK |
| [changes/merged/2026-07-01-valkey_session_store_conformance.md](changes/merged/2026-07-01-valkey_session_store_conformance.md) | Merged | service: Valkey session count, atomic TTL'd writes, expired-index cleanup |
| [changes/merged/2026-07-01-release_gil_in_python_binding.md](changes/merged/2026-07-01-release_gil_in_python_binding.md) | Merged | bindings: release the GIL around the blocking FFI call |
Expand Down Expand Up @@ -78,6 +79,7 @@ board (`backlog/` · `in-progress/` · `blocked/` · `done/`).
| [plans/2026-07-02-webhook_user_sync_conformance/plan.md](plans/2026-07-02-webhook_user_sync_conformance/plan.md) | Done | [changes/merged/2026-07-01-webhook_user_sync_conformance.md](changes/merged/2026-07-01-webhook_user_sync_conformance.md) |
| [plans/2026-07-02-server_error_handling_and_shutdown/plan.md](plans/2026-07-02-server_error_handling_and_shutdown/plan.md) | Done | [changes/merged/2026-07-01-server_error_handling_and_shutdown.md](changes/merged/2026-07-01-server_error_handling_and_shutdown.md) |
| [plans/2026-07-02-implement_lambda_runtime/plan.md](plans/2026-07-02-implement_lambda_runtime/plan.md) | Done | [changes/merged/2026-07-01-implement_lambda_runtime.md](changes/merged/2026-07-01-implement_lambda_runtime.md) |
| [plans/2026-08-05-resolve_config_placeholders_all_channels/plan.md](plans/2026-08-05-resolve_config_placeholders_all_channels/plan.md) | Done | [changes/merged/2026-08-05-resolve_config_placeholders_all_channels.md](changes/merged/2026-08-05-resolve_config_placeholders_all_channels.md) |

## Conventions

Expand Down
15 changes: 12 additions & 3 deletions .specs/bindings/specs/01-ffi-core.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
# FFI Core (`crates/ffi`)

**Status:** Implemented · **Date:** 2026-06-24 · **Owner:** Ant Stanley · **Scope:** crates/ffi
**Status:** Implemented · **Date:** 2026-08-05 · **Owner:** Ant Stanley · **Scope:** crates/ffi

The shared Rust layer the language bindings consume. It wraps the server's axum router behind
a small synchronous interface and owns the tokio runtime so a non-async host can call it.

## Responsibilities

- Build an `AppService` and axum `Router` from a TOML config (re-using
`crates/server`'s bootstrap), and own the tokio `Runtime` that drives them.
- Build an `AppService` and axum `Router` from a TOML config (re-using `crates/server`'s
bootstrap), and own the tokio `Runtime` that drives them. Config supplied through `new`
(inline string) or `from_file` passes the server's shared resolve —
`OIDC_EXCHANGE__{section}__{key}` overrides, fail-closed `${VAR}` placeholder resolution,
then validation ([06-configuration.md](../../service/specs/06-configuration.md) → Loading
order). An unresolvable placeholder or an invalid value is an `FfiError` at construction; a
literal `${…}` never reaches a running router.
- Convert a primitive HTTP request into an axum request, route it, and convert the response
back to primitives.
- Map every error into a stable `FfiError`; never let a panic cross the FFI boundary.
Expand Down Expand Up @@ -63,6 +68,10 @@ Depends on `crates/server` (router construction), `crates/core`, and `tokio`/`ax
is responsible for moving the call off the host's event-loop thread.
- *Errors as `{code, message}`.* **All Rust errors collapse to `FfiError`.** A flat, stable
shape every language can surface without knowing the domain `Error` enum.
- *One resolve, differing sources.* **FFI config passes through the server's resolve; only the
source set differs — the supplied document plus `OIDC_EXCHANGE__…` overrides, with no
`OIDC_EXCHANGE_ENV` file overlay.** A second config pipeline is exactly how the published
Node, Python, and Lambda packages came to load documented secret placeholders as literal text.

### Open questions

Expand Down
Loading