Repository guidance for coding agents and maintainers working in
solverforge-ui.
README.mdis the source of truth for shipped public API and runtime contracts.WIREFRAME.mdcan include shipped and planned UI, but every section must clearly distinguish which is which.js-src/andcss-src/are the editable sources.static/sf/contains the generated bundled assets served to consumers.
- Crate version:
0.7.0. - Versioned asset outputs are emitted as
static/sf/sf.<version>.cssandstatic/sf/sf.<version>.js. solverforge_ui::assetsis available without default features; the Axumroutes()adapter is available behind the defaultaxumfeature.
createJob()results are normalized before any stream is attached. A valid result is a non-empty string id, a finite numeric id including0, or an object with a scalarid,jobId, orjob_idfield. Non-scalar ids are rejected rather than stringified.- Startup streams may begin with either a scored
progressevent or a scoredbest_solutionevent. progressis metadata-only and must not carry the solution payload.best_solutionmust include bothsolutionandsnapshotRevision.- If a backend seeds startup state from a retained snapshot, it must not emit an
identical duplicate startup
best_solutionimmediately after that bootstrap. deleteJob()is mandatory for every backend passed toSF.createSolver().delete()is terminal-only destructive backend cleanup, and local retained state is cleared only after terminal synchronization and backend deletion both succeed.COMPLETEDandTERMINATED_BY_CONFIGretained jobs require successful terminal snapshot synchronization beforedeleteJob()is allowed.- Paused and terminal lifecycle events remain authoritative;
SF.createSolver()synchronizes retained snapshot state before invoking the corresponding callbacks. - HTTP
EventSource.onerrorrepresents transport state. Reconnecting errors are ignored; a closed stream is surfaced throughonErrorand preserves the last authoritative lifecycle, retained job id, score, metadata, and snapshot revision. In-flight states must remain exact:PAUSE_REQUESTED,RESUMING, andCANCELLINGmust not collapse back toSOLVINGorIDLE. Stop remains visible duringCANCELLING; activating it may reattach a closed stream to listen for the terminal event, but it must not send a duplicatecancelJob()call.
SF.rail.createTimeline()is the shipped dense scheduling surface. Keep its README API reference,WIREFRAME.md, tests, demos, and generated assets synchronized whenever timeline config, geometry, scrolling, or layout behavior changes.zoomPresetsdefaults to['1w', '2w', '4w', 'reset'];[]intentionally removes zoom controls for fixed-horizon app surfaces.- Detailed timeline items must preserve exact interval geometry. Adjacent intervals stay visually disjoint on one track; true overlaps are packed onto separate track rows.
- Dense schedules use one scrollable body viewport with synchronized horizontal header/body movement. Do not document the body scrollbar as hidden.
- Timeline layout must resynchronize after detached
createTimeline()orsetModel()calls once the element is mounted.
- Keep public API changes synchronized across code,
README.md, runnable demos, and tests in the same change. - Do not hand-edit
CHANGELOG.mdfor ordinary work; release notes are generated bycommit-and-tag-versionthroughmake release-tag. - Do not document planned or exploratory wireframe ideas as shipped behavior until they are wired into the generated assets and the README API reference.
- Prefer
make lint-frontendfor focused JavaScript linting,make test-frontendormake test-browserfor focused frontend validation, andmake test-quickormake testbefore release work. - When the Rust crate feature surface changes, validate both default features
and
--no-default-features; the latter must keepsolverforge_ui::assetsavailable without depending on Axum.