Expand description
Versioned JSON command bridge for embedded (mobile/FFI) consumers.
One entry point, bridge_call, accepts a JSON envelope and returns a JSON
envelope. Request semantics live in the transport-free library services
(starting with crate::solve_v1()); this module contains only the envelope
contract, command dispatch, and panic containment. The C ABI wrapper lives in
crate::bridge::ffi (feature ffi).
§Envelope contract (v1)
Request:
{ "api_version": 1, "command": "solve", "request": { ... } }Success response:
{ "ok": true, "api_version": 1, "engine_version": "0.33.1",
"command": "solve", "result": { ... } }Error response (always in-band; the bridge never signals failure any other way):
{ "ok": false, "api_version": 1, "engine_version": "0.33.1",
"error": { "code": "command_failed", "message": "...", "details": { ... } } }Compatibility policy: the envelope itself rejects unknown fields (a caller that
misspells command should hear about it), while inner request payloads follow
each command’s own schema discipline (e.g. solve uses the solve-json v1
decoder, which also rejects unknown fields with location info). New commands
and new OPTIONAL response fields may appear within api_version 1; anything that
would break an existing well-formed caller bumps BRIDGE_API_VERSION. Callers
feature-detect with meta.capabilities instead of sniffing versions.
§The true.* truing family
true.fit, true.wind, true.tall_target, true.dsf, true.plan, and true.dial_plan
expose the engine’s truing methods. All six are unconditional (no filesystem access, so
all six are present on wasm32), but they are not otherwise uniform:
true.fit(joint MV+BC truing) is backed by the uncertainty solver, so its result always carriesapproximation— a required enum that is eitherAvailablewith intervals for both muzzle velocity and BC, orUnavailablewith a reason, never simply absent. There is deliberately no command that returns a bare truing point estimate.true.wind(effective crosswind from an observed miss) is the one exception to that guarantee:solve_wind_truinghas no uncertainty model, so its result is a bare point value with no interval. Callers must not present it withtrue.fit’s confidence.true.windis also the one command whose wire shape is SI throughout (range_m,miss_right_m,sigma_m) while every other command, including the rest of this family, is imperial; apps convert at the boundary fortrue.windspecifically.true.tall_targetreturns a scope’s tracking correction factor from a tall-target test.true.dsfderives a single Mach-keyed drop-scale-factor point from an observed transonic drop; it never persists into a profile’s DSF table, which is the caller’s job. It established this family’s structured-error.detailsconvention: a machine-readablereason(invalid_input,supersonic,out_of_range,degenerate_drop,forward_model) alongside the message;error.codestayscommand_failedfor all commands, so existing callers are unaffected.true.planrecommends which candidate ranges to shoot for a joint MV/BC truing experiment (crate::truing_plan::plan_truing_experiment_v1, wired directly — no new service function). Its error also carries structurederror.details, under the samereasonkey as every other command in this family (invalid_request,insufficient_reachable_candidates,no_feasible_design) plus therejected_candidatesdiagnostics the typed error itself carries.true.dial_planturns a TRUE angular correction into ranked dial/hold/hybrid execution plans for an INLINE optic (crate::truing_service::dial_plan_v1, wrappingcrate::optic::plan_corrections). Unlike the CLI’sdial-plan --profilemode, there is no profile-loading path here — the optic is supplied inline in the request, since a saved-profile filesystem read must not enter this bridge. Its error also carries structurederror.details: a stablereasonperOpticErrorvariant.
None of this needed a BRIDGE_API_VERSION bump: the six commands are additive within
api_version 1, and meta.capabilities lists all six for feature detection.
Modules§
- ffi
- C ABI for the JSON command bridge — the entire mobile-facing surface.
Enums§
- Bridge
Error Code - Machine-readable bridge error codes. Distinct from any command’s own error
vocabulary: a
command_failedcarries the command’s typed error indetails.
Constants§
- BRIDGE_
API_ VERSION - Bridge envelope version. Bumped only for breaking envelope changes.
- MAX_
A7P_ DECODED_ BYTES - Hard cap on the DECODED
.a7ppayload accepted byprofile.import_a7p. Real files are a few KiB; this exists purely as a resource bound (the request envelope’s ownMAX_REQUEST_BYTESalready caps the base64 text). - MAX_
PDF_ BYTES - Hard cap on the PDF
card.pdfwill hand back, measured on the RAW document (the base64 text in the response is ~4/3 of it, so this bounds a ~5.6 MiB response body). - MAX_
REQUEST_ BYTES - Hard cap on request size, matching the solve-json transport.
Functions§
- bridge_
call - Process one bridge exchange. Never panics; every failure mode is an in-band error envelope. This is the function the C ABI wraps.