Visual SNN Design Studio¶
The Studio is a web-based research workbench for designing, simulating, and analysing spiking neurons interactively. It combines 118 built-in neuron models, custom ODE editing, 15 analysis views, and Verilog RTL generation in a single interface.
Installation¶
pip install sc-neurocore[studio]
This installs FastAPI and Uvicorn alongside the core package. A published
wheel also carries the built user interface in
sc_neurocore/studio/frontend_dist/, so no Node.js toolchain is needed to run
the Studio.
An installation from a source checkout carries the interface only if
studio/frontend/dist/ has been built first (see
Development); without it the build still
succeeds, and sc-neurocore studio says that there is no interface and opens
the API documentation at /docs instead. Release builds set
SC_NEUROCORE_STUDIO_UI=required, which makes a build without the interface
fail. Before the wheel can be published, the release workflow installs it into
a clean environment, launches sc-neurocore studio from that installation and
requires the root redirect, every asset the interface names and the whole
model catalogue to be served (tools/studio_installed_acceptance.py).
Quick Start¶
sc-neurocore studio
Opens http://127.0.0.1:8001/studios/sc-neurocore/ in your browser; the
root http://127.0.0.1:8001/ redirects there. The Studio starts in Model
mode with 185 neuron models browsable by category. Switch to ODE mode to
write custom equations.
The first screen opens on an operator workbench rather than a landing page. It
shows the saved-project/session state, selected model or ODE mode, simulation
state, audit/capability evidence health, compile/synthesis readiness, and
evidence-bundle export availability. The export card targets synthesis evidence
first, then compile evidence, then saved-project evidence, and opens the owning
surface when that scoped bundle is already available for artifact download.
Each card links to the production Studio surface that owns the action. The next
left-panel section is a readiness panel derived from
/api/studio/operator/status; it turns route-policy, identity, audit, job
root, runtime-limit, and capability gaps into ready, warning, and
blocked rows before the operator opens Admin or runs release preflight.
To use a different port:
sc-neurocore studio --port 9000
Two Modes¶
Model Mode¶
Browse all sc-neurocore neuron models grouped by category (Conductance, IF, Oscillator, Bursting, Hardware, Network, Statistical, AI). Each model's parameters appear as sliders. Models are auto-classified by firing pattern (tonic, bursting, adapting, irregular, chaotic, silent) with colour-coded badges.
When a model has a canonical bundled schema, the sidebar also exposes its
schema-declared, compiler-supported integrator choices and supported signed
Q-formats. Generate RTL compiles the current selected model, parameter overrides,
timestep, integrator and Q-format through the isolated schema-backed compiler
job. The response includes
studio.compile-traceability.v1 provenance with the exact model/schema and
configuration used, including the canonical schema digest. Models without a
canonical schema fail closed: Studio does not infer a fuzzy schema match or
silently substitute an ODE.
For euler and map configurations, Run RTL co-sim advances the guided
workflow through a real bit-exact parity gate before synthesis. The isolated
job generates the maintained bit-true C reference and the same configured RTL,
compiles them with GCC and Icarus Verilog, executes the RTL with VVP, and
compares spike_out plus every state output as signed integers on every cycle.
The path-free studio.cosim-parity.v1 report records the exact model/schema
configuration, bounded stimulus, signal set, source and trace digests, tool
versions, and the first mismatch when parity fails. Complete sources and traces
remain path-confined job artifacts. exp_euler, rk4, and gauss_seidel are
compile-only until a maintained bit-true reference lowerer exists; Studio
disables the parity action and blocks model-mode guided synthesis rather than
claiming an approximate pass.
Pattern filter: click a pattern badge in the model list to filter.
ODE Mode (custom equations)¶
Write ODEs in Brian2-style syntax in the Monaco editor:
dv/dt = -(v - E_L) / tau_m + I / C
# threshold: v > -50
# reset: v = -65
Five built-in templates: LIF, Izhikevich, AdEx, Hodgkin-Huxley, FitzHugh-Nagumo.
Analysis Views¶
The Studio provides 15 view tabs, each showing a different analysis of the current simulation:
| View | Tab | What it shows |
|---|---|---|
| Trace | Trace | Voltage + current + spike raster with zoom/pan |
| Phase portrait | Phase | v vs w trajectory with nullcline overlay |
| ISI histogram | ISI | Interspike interval distribution |
| f-I curve | f-I | Firing rate vs input current |
| Bifurcation | Bif | Parameter sweep → voltage attractor scatter |
| 2D Heatmap | 2D | Two-parameter sweep → firing rate colour map |
| Sensitivity | Sens | Parameter importance bar chart |
| Spike-triggered average | STA | Average voltage shape around spikes |
| Frequency response | Freq | Bode plot: gain and phase lag of the rate vs the frequency of a modulated drive |
| Characterisation | Char | One-click dashboard: pattern, rheobase, f-I, sensitivity |
| Multi-model overlay | Multi | Compare 2-4 models in one plot |
| A/B Comparison | A/B | Split-view of two configurations |
| E-I Network | E-I | Excitatory-inhibitory network raster + population rates |
| Code generator | Code | Python script + one-liner for notebooks |
| Precision | Q8.8 | Float64 vs bit-true fixed-point kernel run + parameter-quantisation run, error traces |
| Verilog RTL | RTL | Generated Verilog from the selected schema-backed model or custom ODE |
Trace View¶
The main view shows:
- Voltage traces for all state variables (colour-coded)
- Current injection subplot showing the input protocol
- Spike raster with red tick marks
- Zoom/pan: mouse wheel zooms the time axis centred on cursor, drag to pan, double-click to reset
- Crosshair cursor with tooltip showing exact time and voltage values
- Axis labels: mV for voltage, nA for current, ms for time
- Imported data overlay: paste CSV data to compare with simulation
The canvas is pixels, so it names itself with a sentence a screen reader reads: the variables, the run's length and step, its spike count, and each variable's range and final value. Data table (bottom right of the plot) shows the same numbers as a table. Both are read from the display projection the server sends, whose bucket extrema keep every minimum and maximum and whose last sample is the run's last, so they are the run's own values. Other views name themselves by title and point to the CSV and JSON exports for their numbers.
A series with more samples than the plot has pixel columns is stroked as each column's first, lowest, highest and last sample, plus one sample either side of the visible window, so every visible extreme survives while the path the browser draws stays bounded. The result data are not changed; this applies wherever a series is longer than the server's own display projection, such as an imported trace. A series whose horizontal values do not increase (a phase portrait) is drawn in full. Every parameter slider carries its name and unit and states its value for assistive technology.
Characterisation Dashboard¶
Click Characterize to run a one-click analysis that produces:
- Firing pattern classification
- Threshold current (rheobase estimate)
- f-I curve
- Top sensitive parameters
- State variable ranges
E-I Network¶
Simulates a balanced excitatory-inhibitory LIF network. When the Rust engine
is installed, the entire simulation runs in compiled Rust — connectivity
construction, Poisson input generation, Euler integration, spike detection,
and rate binning happen in a single py_simulate_ei_network() call with zero
Python per-timestep overhead. Falls back to NumPy if the engine is unavailable.
Parameters (adjustable via sidebar sliders):
- Neuron counts (N exc, N inh)
- Synaptic weights (E→E, E→I, I→E, I→I)
- Connection probability
- External Poisson drive rate (Hz)
Displays a spike raster (blue = excitatory, red = inhibitory) and population firing rate traces.
Current Injection Protocols¶
Five injection protocols for all simulations:
| Protocol | Description |
|---|---|
| Constant | Steady current for full duration |
| Step | I from 20 % to 80 % of the run, 0 before and after |
| Ramp | Linear increase from 0 to I |
| Pulse train | Five pulses per run at amplitude I, each on for a fifth of its period (at least 10 steps per period, 2 on) |
| Sine | I · sin(2π f t) at frequency_hz; the frequency response adds a bias it oscillates about |
Interactive Features¶
- Auto-simulate: simulation reruns 250ms after any slider change
- Keyboard shortcuts: Space=run, 1-5=switch between the first analysis views, arrow keys/Home/End=move within the view switcher, ?=help overlay
- Session save/load: save named sessions to localStorage
- Shareable URLs: state encoded in URL hash (click Share link)
- 10 preset experiments: threshold exploration, adaptation, bursting, chaos, hardware comparison, and more
- CSV export: download the full-resolution raw traces at their post-step sample times as comma-separated values
- JSON export: download the complete simulation response (raw traces,
snapshots and the display projection) with path-free
studio.simulation-run.v2reproducibility metadata - Evidence labels: trace and analysis plots surface evidence classification, source, input digest, and result digest labels
- PNG export: screenshot the current plot
- Code export: a standalone script built from the resolved experiment. It re-resolves the request, refuses if this installation would resolve a different experiment, and runs it through the public runner — so the time step, drive protocol, initial state, parameters and randomness travel with the export instead of being guessed from the model's constructor
- Replay pack: a sealed
studio.replay-pack.v1document with the re-resolvable request, the specification, its identity digest, the complete expectation (every spike event, a digest per state trace, initial and final state, drive digest) and the environment that sealed it. Replay it withpython -m sc_neurocore.studio.replay_pack <pack.json>; see Replay and code export
One effective experiment per run¶
The resolved Python specification owns immutable snapshots of its inputs. Editing a returned dictionary or a result's experiment metadata cannot change a subsequent execution or its cache identity.
Before anything runs, a simulation request (/api/simulate,
/api/models/simulate, /api/multi-simulate, or the simulate kind of
/api/analysis/jobs) is resolved into one experiment
(studio.experiment-spec.v1) that the response returns and whose digest keys
the result cache:
model— class, module SHA-256, descriptor SHA-256 and contract digest, canonical schema profile and its SHA-256 (orequationswith the equation digest and the declared variables for the playground).numerical— method, family, effectivedtwith its source (override,model_default,model_attribute,studio_default), sub-steps and time unit;steps— the exact step count and effective duration. An oversized synchronous run is refused withexecution_mode = job_requiredand the job route, never shortened.initial_state— typed initial values (descriptor-declared for models, explicit for every playground variable, undeclared ones at 0.0; an initial value for an undeclared variable is rejected).protocol— kind, amplitude, the explicit sinefrequency_hz, the fixed step/ramp/pulse fractions and the SHA-256 of the drive samples.randomness—kind(none,seeded-model,diffusion-noise), the effectiveseedand its source (request,model-default,playground-default,drawn), the requestedtrial(replayorfresh) and the effective one. A seed on a deterministic model or on noise-free equations is rejected; a fresh trial draws a seed, reports it so the trial can be replayed, and is never cached. Playground diffusion noise (xi) is drawn from a per-run generator, not from the process-global stream.backend— the selected backend and the rejected alternatives with their reasons;runtime— package, Python and NumPy versions and the equation builder digest.
Explicit request defaults resolve to the same experiment as omitted ones, so
the GUI, the API and a replay from an exported response share one effective
configuration; cache.hit says whether a replay came from the cache and the
run manifest carries experiment_sha256 and trial.
Complete state and raw-result custody¶
Every simulation response (/api/simulate, /api/models/simulate,
/api/multi-simulate) returns the complete run next to a bounded display
projection:
state_layout— the state the model declares (its committed descriptor[state]table for catalogue models, the equations for the playground), each variable with its role from the canonical schema profile (biological,auxiliaryorunassigned), unit, meaning, declared initial value, observed kind (scalarorvector) and shape. A declared variable the instance does not expose is listed with its reason; attributes that change without being declared are listed underundeclared_mutable.completeistrueonly when every declared variable was recorded at every step and nothing undeclared changed;incomplete_reasonssays why not. Name heuristics are not a state source.observation— the clock: the initial snapshot is at 0 ms, sampleiis the state after stepiat(i + 1) * dt, and drive sampleiapplies over[i * dt, (i + 1) * dt).initial_stateandfinal_state— exact snapshots of every observable declared variable (vectors as lists).raw— full-resolution per-step traces of every recorded scalar state (states), vector states within the element budget (vector_states), the drive, spike step indices and spike times. When the scalar traces alone would exceedelement_budgetthe block says so inreasoninstead of shortening anything; vectors beyond the budget are recorded in the snapshots only and named invector_snapshots_only.time,states,current_trace— the display projection, at most 5,000 points chosen as the per-bucket extrema of every scalar trace and the drive plus the first and the last sample, withdisplay.sample_indexmapping each point to its raw step. Peaks, resets and the final sample survive reduction;spikesare raw step indices and are never decimated. Analyses, exports and the spike-triggered average readraw, not the projection.effective_inputs— the ST-01 receipt;state_recordinglists the recorded and excluded declared variables anddisplay_pointsthe size of the projection.
run_metadata carries the studio.simulation-run.v2 manifest: the digests of
the request, of the returned payload and of the raw block, the layout source,
whether custody is complete, whether raw traces are included and the
observation clock. Evidence bundles accept both v1 (history) and v2 manifests.
The catalogue routes run on the Python custody backend so every declared
variable is observed. The optional Rust batch backend, still used by analysis
sweeps that need rates only, exports the membrane voltage and no initial
snapshot; its result says so in state_layout and is never presented as
complete-state custody.
Analysis validity and metric contracts¶
Every analysis response (/api/fi-curve, /api/bifurcation,
/api/sensitivity, /api/heatmap, /api/freq-response, /api/precision,
/api/nullclines, /api/ir/cosim and the analysis job kinds) carries a
contract block (studio.metric-contract.v1): the kind of metric, its
definition, the units of every reported quantity (model-defined where
the equation system declares none), the applicability conditions, the
limitations of the computation and a domain verdict — complete when
every requested point was evaluated, partial when some points were invalid
and are reported, empty when none could be. The analysis_metadata
manifest repeats the contract kind and the domain so an evidence bundle can
tell a partial result apart without opening it. An invalid point is never a
zero:
- f-I curve, heatmap — the rate is the spike count over the whole simulated duration (transient included); the contract says so, together with the drive protocol.
- Frequency response — measured over the largest whole number of drive
cycles in the run (transient included); a frequency without one whole
cycle is not measured (
null, domainpartial). - Sensitivity — the dimensionless rate elasticity
|rate(p+δ) − rate(p−δ)| / (2δ) · |p| / rate(p)with δ = 10 % ofp. A zero base rate or a zero parameter makes the elasticity undefined; the row reportssensitivity: nullwith areasonand the domain ispartialorempty. - Bifurcation — labelled
numerical-extrema-sweep: the late-run extrema of the analysedvariable(request fieldvariable, first trace by default) under the route's driveprotocol. It is not a bifurcation continuation: no branch is followed and no stability is computed;attractor_kindssays per point whether extrema, a fixed-point mean or an insufficient trace was found. - Nullclines — each component of the drift field is evaluated at every
grid sample with NumPy floating-point errors raised; a sample that raises
or is non-finite is invalid and reported in
validity_0/validity_1(rows followy, columnsx). A contour cell needs four valid corners. The field is evaluated at the request'scurrent(default 0) with every variable outside the two swept ones held atheld(default: its initial value) and the diffusion-noise symbol at zero;domain.statusand the invalid fractions are returned, and the phase view labels a partial domain.
Precision comparison¶
The Python comparison rejects invalid timing and runs exceeding its step limit; it never labels a shortened prefix as a complete comparison.
/api/precision (and /api/ir/cosim) compares three runs of the same
experiment and keeps them apart:
float_result— the float64 explicit-Euler playground run;fixed_result— the bit-true fixed-point run: the generated C kernel of the equation system (sc_neurocore.compiler.intelligence.bit_true_kernel, proven bit-identical to the emitted RTL by the Icarus co-simulation), compiled with the host C compiler and driven with one encoded input word per step. Itswordsblock holds the raw integer state words;arithmeticstates the value encoding, multiply width collapse and rounding, accumulate overflow policy, division/modulo/LUT lowering, threshold/reset sequencing and the kernel and compiler digests.backendisbit-true-kernel.parameter_quantisation_result— float64 with parameters and initial state rounded to the word resolution, so parameter rounding can be told apart from the fixed-point operations (wrap-truncate multiplies, saturation, look-up tables) that only the bit-true run performs. The time-step word the kernel applies is reported underencoding.dt; all three runs receive the same drive samples.
comparison.bit_true and comparison.parameter_quantisation report, for
every state variable, the per-step absolute error (trace, full resolution,
and display aligned with the float result's display samples), its maximum,
mean, RMS and final value and the first step beyond half a word resolution;
the spike trains are compared in order (events); saturation counts the
steps each word spent at the format limits. error and quantized_params
keep the former summary for the first declared variable (bit-true error).
The request names the word (q_format, Q8.8 = 16 bits with 8 fractional,
8 to 32 bits), the accumulate overflow (saturate or wrap) and product
rounding (truncate or nearest), the protocol and frequency_hz. A
parameter, expression constant, initial value, time step or drive sample the
word cannot hold is rejected with its field (HTTP 422 invalid_model_input)
instead of being clamped — a clamped parameter is a different model, not a
precision effect — as are diffusion noise (xi) and integrators the kernel
does not mirror. When the host has no C compiler the route answers HTTP 503
native_tool_unavailable; nothing is estimated in its place.
API Reference¶
The Studio backend exposes a REST API. All POST endpoints accept JSON. Replayable simulations are cached (LRU, 64 slots) by the digest of their resolved experiment; fresh stochastic trials are never cached.
Core Simulation¶
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/simulate |
Run ODE simulation |
| POST | /api/models/simulate |
Run named model simulation |
| POST | /api/compare |
A/B comparison of two configs |
| POST | /api/multi-simulate |
Simulate 2-4 models in parallel |
| POST | /api/network/ei |
E-I balanced network simulation |
Model-run contract (/api/models/simulate, /api/export/svg)¶
A catalogue model run is fail-closed. The request body rejects unknown keys,
non-numeric or non-finite params values and dt, non-positive dt and
duration, and any protocol outside constant, step, ramp, pulse,
sine. The run contract then validates the request against the model class
itself and never substitutes a default:
- every
paramskey must be a numerically overridable constructor field of the model; private state, derived (init=False) fields, factory-initialised fields and non-numeric fields (integrator or profile literals, arrays) are rejected with the reason; - integer fields reject fractional values; integer-drive models reject protocols whose samples are not integral;
- a model with a fixed class-level step (for example
IntegerQIFNeuron, 1.0 ms) accepts only thatdt; a model without any timestep accepts only the Studio default of 0.1 ms per step; - a model whose profile declares a macro step (
HodgkinHuxleyNeuronandConnorStevensNeuron: 1 ms of 100 sub-steps of 0.01 ms;WangBuzsakiNeuron: 0.5 ms of 50) is clocked by that macro step: one sample perstep()call,duration / macro stepcalls, and the responsedtis the macro step. Itsdtis the sub-step, accepted only at the profile's value, because the class chooses its own sub-step count fromdtand nothing declares how long a call lasts at another one. Such a model cannot form a network population, since a network advances every population once perdt; - a model whose
stepneeds inputs the current protocol cannot supply (for exampleDendriticNMDANeuron, which needs glutamate) is rejected before any step runs; - a constructor failure is reported as-is instead of falling back to defaults.
Rejections return HTTP 422 with detail = {"error": "invalid_model_input",
"model", "field", "reason"}; body-schema failures return the usual list of
validation errors, including for NaN or Infinity in the body. A validated
run that raises or produces a non-finite or non-scalar state at some step
returns HTTP 422 with detail = {"error": "model_simulation_failed", "model",
"backend", "step", "time_ms", "diagnostic"} and no partial payload; failed
requests are never cached. A successful run carries an effective_inputs
receipt (studio.model-run-inputs.v1): backend (python or rust), effective
dt and its source, step_ms (the simulated time of one step() call, which
is dt except for a macro-stepping model), every effective parameter, the applied overrides, the
step drive parameter and kind, the protocol, the requested duration, the step
count with a steps_truncated flag, the plot stride, and the recorded and
excluded state variables with the exclusion reason (non-scalar, absent, or not
exported by the Rust batch backend). Non-finite values are never rewritten to
zero.
Analysis¶
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/fi-curve |
Firing rate vs current sweep |
| POST | /api/bifurcation |
Parameter sweep attractor map |
| POST | /api/sensitivity |
Parameter sensitivity analysis |
| POST | /api/heatmap |
Two-parameter firing rate heatmap |
| POST | /api/characterize |
Full model characterisation |
| POST | /api/freq-response |
Frequency response curve |
| POST | /api/precision |
Float64 vs bit-true fixed-point compare (q_format, overflow, rounding, protocol) |
| POST | /api/nullclines |
Nullclines of a 2D section with validity masks (current, held) |
Analysis responses for /api/compare, /api/fi-curve, /api/bifurcation,
/api/sensitivity, /api/heatmap, /api/freq-response, /api/precision,
/api/nullclines, and /api/characterize include analysis_metadata with the
studio.analysis-result.v1 schema. The manifest records the analysis type,
evidence classification, source (ode, model, mixed, or unknown),
input and result SHA-256 digests, the returned result keys, and the metric
contract kind and domain verdict of the payload (contract, domain; null
for a payload without a contract) without exposing host-local paths. The corresponding plot views surface the evidence
class, source, input digest, and result digest next to the rendered analysis.
/api/multi-simulate attaches per-result run_metadata with the
studio.simulation-run.v2 schema so each overlaid trace carries the same
reproducibility provenance as /api/simulate.
The frequency-response endpoint drives the model about an operating point:
I(t) = bias * (1 + depth * sin(2*pi*frequency_hz*t)) (bias is the Studio's
current, depth 0.5 by default and below 1, so the current never changes
sign). From the spike times t_k over the whole drive cycles it reports, per
frequency, the mean rate, the rate's first-harmonic amplitude
2|Σ exp(−2πi f t_k)| / window, the gain (that amplitude per unit of
modulating current, depth * |bias|), the phase by which the rate lags the
drive, and the vector strength. It used to drive a mean-zero sine
amplitude * sin(...) and report the mean rate alone; the default model left
its safety bounds under it. A request that still sends amplitude is refused
with that reason.
Resources¶
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/templates |
List ODE templates |
| GET | /api/templates/{name} |
Get template by name |
| GET | /api/models |
List every catalogue model |
| GET | /api/models/scan |
Classify all models by firing pattern under the synchronous analysis budget and return studio.model-scan.v1 evidence metadata |
| GET | /api/models/{name} |
Get model detail (params, state vars) |
| GET | /api/presets |
List preset experiments |
| GET | /api/presets/{id} |
Get preset detail |
| POST | /api/codegen |
Export a script that reproduces the resolved experiment |
| POST | /api/export/replay-pack |
Export a sealed pack another installation can run and compare |
| POST | /api/export/replay-notebook |
Export a cited Jupyter notebook that carries and replays a sealed pack |
| POST | /api/compile |
Compile ODE to Verilog with source-to-RTL traceability |
| POST | /api/models/compile |
Compile a selected catalogue model with explicit timestep, integrator and Q-format |
| POST | /api/models/cosim |
Run selected-model bit-exact C-reference versus real Icarus RTL parity |
| POST | /api/candidates/validate |
Locate every problem with a candidate model package (Candidate Models) |
| POST | /api/candidates/diff |
Diff a candidate against its parent, mathematically and semantically |
| POST | /api/candidates/simulate |
Run a candidate under its own profile, bounded |
| POST | /api/candidates/review-packet |
Run a candidate's reference tests and return its review packet |
| POST | /api/fits |
Fit a model's parameters to a split cohort, with hold-out error and identifiability (Parameter Fitting) |
| POST | /api/fits/replay |
Run an exported fit again and report whether it reproduced |
| GET | /api/project/{name}/comments |
Review comments, each checked against its revision (Workspaces) |
| POST | /api/project/{name}/revisions/{revision}/comments |
Comment on one immutable revision, or reply |
| GET | /api/cache/stats |
Cache hit/miss statistics |
| GET | /api/health |
Health check |
Network Canvas¶
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/graph/models |
List neuron models available for graph populations |
| POST | /api/graph/population |
Create a population node |
| POST | /api/graph/projection |
Create a projection edge |
| POST | /api/graph/validate |
Validate graph JSON and return structured errors |
| POST | /api/graph/simulate |
Run a graph through the public Network runtime |
| POST | /api/graph/notebook |
Export a tutorial notebook that rebuilds the graph with the public API and checks its spikes |
| POST | /api/graph/export-nir |
Write the validated graph as a NIR (HDF5) file, returned as base64 with notes |
| POST | /api/graph/import-nir |
Read a NIR file or a legacy graph envelope into Studio graph JSON |
A graph runs what it declares. Every population names a catalogue model whose
constructor contract accepts the parameters and the graph timestep; every
projection carries a signed weight that agrees with its source population's
type, an explicit connection rule (random with a probability or
all_to_all), a delay that is a whole number of timesteps and a seed that is
given or derived from the graph seed; populations declare their external
input (none, constant, poisson). The server resolves the graph into
studio.network-graph-spec.v1, lowers it to public Population,
Projection, SpikeMonitor and stimulus objects and runs the reference
Python loop; the result (studio.network-graph-result.v1) reports the
executed specification, the loop's semantics (previous-step propagation,
delay buffering), a topology artefact with CSR digests, every spike event per
population and a metric contract. Validation reports every error of a graph
at once; nothing is clamped, rounded or replaced by a template default, and an
oversized run is refused rather than shortened. See
Network Canvas.
Example: POST /api/simulate¶
{
"equations": ["dv/dt = -(v - E_L) / tau_m + I / C"],
"threshold": "v > -50",
"reset": "v = -65",
"params": {"E_L": -65.0, "tau_m": 20.0, "C": 10.0},
"init": {"v": -65.0},
"dt": 0.1,
"duration": 100.0,
"current": 10.0
}
Response includes time, states, spikes, spike_count, dt, n_steps,
stats (rate_hz, isi_mean_ms, isi_cv, isi_histogram), current_trace, and
pattern (auto-classified firing behaviour), plus the custody fields
(state_layout, observation, initial_state, final_state, raw,
display) described above. Simulation responses also include
run_metadata with the studio.simulation-run.v2 schema, simulation
evidence classification, source (ode or model), input, result and raw
SHA-256 digests, effective dt, executed step count, returned display sample
count, spike count, recorded state variable names, layout source, custody
verdict and observation clock.
Analysis responses include analysis_metadata with path-free result
provenance. The frontend displays the analysis type, source, and shortened
input/result digests beside the active analysis plot so exported JSON can be
matched back to the API result contract.
Development¶
# Terminal 1: backend
sc-neurocore studio --port 8001
# Terminal 2: frontend dev server (hot reload)
cd studio/frontend
npm install
npm run dev
The Vite dev server proxies /api/* to http://127.0.0.1:8001.
Production build:
cd studio/frontend
npm run build # → studio/frontend/dist/
A checkout's sc-neurocore studio serves this build once it exists, and the
package build copies it into the wheel as sc_neurocore/studio/frontend_dist/;
an installation serves its own copy first.
The production build serves two entry surfaces from the same source tree:
- the standalone application at
/studios/sc-neurocore/; - the Module Federation 2.x remote at
/studios/sc-neurocore/remoteEntry.js, with federation identitysc_neurocoreand expose./SnnStudioPanel.
The remote and the SCPN Studio host share react and react-dom as singleton
dependencies pinned to 19.2.7. Keep the object-form share declaration in
vite.config.ts; array shorthand permits an independent React fallback and can
produce invalid hook calls when the host renders the panel. The corresponding
schema-A ui_module contract is:
{
"remote_entry": "/studios/sc-neurocore/remoteEntry.js",
"exposes": ["./SnnStudioPanel"],
"federation": "module-federation-2"
}
npm run build fails unless the emitted remote exports the get/init
container contract, retains the own identity and expose, contains no
demo_studio reference, and resolves its entry imports inside dist/.
Frontend contract tests:
cd studio/frontend
npm test -- src/capabilityShell.test.ts
npm run test:e2e
The frontend capability shell is fail-closed for registered panels. If the backend capability registry omits a panel contract, that panel is disabled instead of assuming the underlying API or external tool is available.
The Playwright e2e suite first exercises the standalone Vite application and
its backend contracts. It then builds the deployable output, serves the real
remoteEntry.js, and loads ./SnnStudioPanel through a separate Module
Federation host with the production singleton-share contract. This second
browser test fails on missing chunks, incorrect public paths, federation-name
drift, expose drift, duplicate-React hook failures, or a panel that cannot
render through the host boundary.
The Admin panel loads path-free audit health at startup and can request the
admin-gated audit export endpoint. Development-preview policy mode can still
use X-Studio-Principal plus the studio.admin role, but production
deployments should set SC_NEUROCORE_STUDIO_ALLOW_HEADER_PRINCIPAL=false and
configure SC_NEUROCORE_STUDIO_IDENTITY_FILE with
sc-neurocore.studio.identity.v1 service accounts. Store only SHA-256 token
hashes in that file, authenticate API calls with Authorization: Bearer
<token>, and give admin export accounts the studio.admin role.
Persistent audit rows are written as canonical JSONL with previous_event_hash
and event_hash fields. The audit status and export endpoints verify the
retained hash chain and report integrity_verified, integrity_error, and the
latest retained event hash without exposing filesystem paths or secret material.
Legacy or unverifiable retained rows are not silently trusted: status and export
payloads include retained_event_count, quarantined_event_count, and
quarantine_reason so operators can separate verified evidence from rows that
must be migrated, quarantined, or reviewed during incident reconstruction.
Administrators can export only the quarantined retained rows through
GET /api/studio/audit/quarantine/export; the payload is path-free, includes
per-row quarantine_reason values, and is intended for incident handoff or
offline archive migration.
Administrators can also persist that quarantine export as confined Studio job
artifacts through POST /api/studio/audit/quarantine/archive; the response
returns a path-free archive manifest, reason counts, job ID, and downloadable
artifact metadata under the existing /api/studio/jobs/{job_id}/artifacts/...
surface.
Before importing or restoring a saved archive, administrators can submit the
archive payload and optional companion manifest to
POST /api/studio/audit/quarantine/archive/validate; Studio recomputes the
reason counts and verifies the manifest linkage without reading arbitrary
server-side paths.
Administrators can review archive retention through
GET /api/studio/audit/quarantine/archive/retention?retain_latest=10; the
path-free response lists valid quarantine archive jobs newest first, marks the
newest archives as retain, and marks older archives as prune_candidate
without deleting job artifacts.
The Admin panel exposes the same archive lifecycle through the Audit archive
section: operators can create a quarantine archive, review the retention plan
with a bounded retain-latest value, paste path-free archive JSON plus an
optional companion manifest for validation, materialize a restore artifact job,
and execute the retention purge without copying host paths or raw audit files
into the browser.
Administrators can materialize a validated quarantine archive into confined
restore artifacts through POST /api/studio/audit/quarantine/archive/restore.
The route validates the archive and optional manifest, then writes
evidence/audit-quarantine/restore.jsonl and
evidence/audit-quarantine/restore-manifest.json as Studio job artifacts. It
does not append restored rows to the active audit chain; operators can inspect,
download, and hand off the restore artifact before any destructive or
chain-mutating action.
After reviewing retention state, administrators can execute the retention purge
through POST /api/studio/audit/quarantine/archive/purge with
{"retain_latest": 10}. The route recomputes the retention plan and removes
only archive jobs marked as prune_candidate; retained archives and non-archive
jobs are left untouched.
When SC_NEUROCORE_STUDIO_AUDIT_ROTATION_BYTES is set, the retained-file count
must be a positive integer so rotation always keeps at least one archived JSONL
segment for incident review and retained-chain verification.
Create the first local service account before enabling the production profile:
sc-neurocore studio-bootstrap-admin \
--identity-file /etc/sc-neurocore/studio-identities.json \
--principal-id svc-studio-admin
The bootstrap command prints the bearer token once and stores only its
SHA-256 digest in the identity file. Capture that token in the deployment
secret manager, set SC_NEUROCORE_STUDIO_IDENTITY_FILE to the written path,
and do not copy the token into repository files or shell history.
Administrators can inspect and update persistent service-account metadata from
the Admin panel Identity section or through
/api/studio/identity/service-accounts. The list and detail endpoints return
principal IDs, role lists, active state, and optional UTC expiry only; they do
not expose bearer-token hashes or filesystem paths. The PATCH endpoint updates
roles, active state, and expiry atomically, preserves the stored token hash,
reloads the backend authenticator after success, and records a dedicated
studio.identity.service_account.update audit event in addition to the normal
route-policy audit decision. Lifecycle updates fail with 409 if the change
would leave the identity file without any active unexpired studio.admin
principal.
Interactive operators can use persistent browser users from the same identity file. Add them offline through the maintained provisioning command:
printf '%s\n' "$STUDIO_OPERATOR_PASSWORD" | sc-neurocore studio-add-browser-user \
--identity-file /etc/sc-neurocore/studio-identities.json \
--username operator \
--principal-id human-operator \
--role studio.viewer \
--password-stdin
The command writes username, principal ID, roles, active state, optional UTC
expiry, and a PBKDF2-HMAC-SHA256 password verifier while preserving existing
service accounts. The browser login form calls POST /api/studio/auth/login;
a successful login stores the returned bearer token in sessionStorage, sends
it as an Authorization header for subsequent API calls, and can revoke it
with POST /api/studio/auth/logout. Studio does not use auth cookies for this
session mode, so cookie CSRF tokens are intentionally not part of the current
contract. Set SC_NEUROCORE_STUDIO_BROWSER_SESSION_TTL_SECONDS to tune the
server-side session expiry; the default is 12 hours.
Repeated invalid browser-login attempts are throttled before another password
check is performed. The default policy permits five invalid attempts within
five minutes and then returns 429 browser_login_throttled with Retry-After
for a 15-minute cooldown. Tune this deployment policy with
SC_NEUROCORE_STUDIO_BROWSER_LOGIN_MAX_FAILURES,
SC_NEUROCORE_STUDIO_BROWSER_LOGIN_FAILURE_WINDOW_SECONDS, and
SC_NEUROCORE_STUDIO_BROWSER_LOGIN_COOLDOWN_SECONDS. A successful login clears
prior invalid-attempt state for that username; disabled or expired users keep
their explicit failure reason and are not converted into throttle events. The
Admin panel Operator section reports the active lockout threshold, failure
window, and cooldown without exposing identity-file paths or secret material.
Administrators can inspect and update browser-user lifecycle metadata from the
Admin panel Identity section or through /api/studio/identity/browser-users.
The Admin panel also creates browser users through the same route. Create,
detail, and PATCH responses return only username, principal ID, roles, active
state, and optional UTC expiry. Creation stores only a PBKDF2-HMAC-SHA256
verifier for the submitted password, reloads backend authentication
immediately, rejects duplicate usernames with 409, and records
studio.identity.browser_user.create without password material. Role,
active-state, and expiry updates preserve the stored password verifier, reload
backend authentication immediately, and record both the route-policy audit
decision and a dedicated studio.identity.browser_user.update audit event.
Browser-user lifecycle updates use the same last-admin guard as
service-account updates.
The Admin panel Audit section derives an identity-lifecycle count and latest
identity-lifecycle action from exported audit rows whose action starts with
studio.identity.. This gives operators a compact confirmation that account
creation, role changes, active-state changes, expiry changes, and password
rotation are present in the audit trail without exposing token hashes,
password verifiers, or local identity-file paths.
Use POST /api/studio/identity/browser-users/{username}/password or the Admin
panel per-user secret field to rotate a browser user's password verifier. The
route preserves public metadata, writes a fresh PBKDF2-HMAC-SHA256 verifier,
reloads backend authentication, clears the login throttle bucket for that
username, revokes active browser sessions for the user's principal, and records
studio.identity.browser_user.password.rotate without password material.
The same Admin surface displays local worker health from
/api/studio/jobs/status. Configure SC_NEUROCORE_STUDIO_JOB_ROOT to keep
per-job working directories on an operator-selected disk, and tune
SC_NEUROCORE_STUDIO_JOB_TIMEOUT_SECONDS for cooperative worker timeouts. Use
SC_NEUROCORE_STUDIO_JOB_MAX_ARTIFACT_BYTES to cap each declared artifact
written by a worker. Use SC_NEUROCORE_STUDIO_EDA_PROCESS_CPU_SECONDS and
SC_NEUROCORE_STUDIO_EDA_PROCESS_MEMORY_BYTES to apply host-supported CPU and
memory ceilings to Yosys and nextpnr child processes. The status payload is
path-free and reports allowed job kinds plus active/completed/failed/timed-out
counts. It also includes one resource_profiles entry per allowed job kind,
recording the default timeout, per-artifact size ceiling, and supported
execution models (thread and process) without exposing the job-root path.
Synchronous analysis routes (/api/simulate, /api/fi-curve,
/api/bifurcation, /api/sensitivity, /api/freq-response, /api/heatmap,
/api/nullclines, /api/precision, /api/characterize, /api/multi-simulate,
/api/compare)
execute in the request worker, so a fail-closed synchronous analysis budget
bounds their cost. The budget projects each request's integration steps
(simulation_count * ceil(duration / dt)) or nullcline grid points and returns HTTP 422 before running
when the request exceeds SC_NEUROCORE_STUDIO_MAX_SYNC_ANALYSIS_STEPS_PER_SIMULATION,
SC_NEUROCORE_STUDIO_MAX_SYNC_ANALYSIS_TOTAL_STEPS, or
SC_NEUROCORE_STUDIO_MAX_SYNC_ANALYSIS_SIMULATIONS. The 422 detail names the
violated limit, the projected cost, and the allowed ceiling without local
paths; a non-positive timestep is rejected the same way. Operator status echoes
the three ceilings in resource_limits.
Training start now submits work through the process-backed local worker manager;
stop, status, and SSE stream routes retain the parent-process control and
observation surface. The training monitor's SSE stream remains the live metric
channel, while the panel surfaces the path-free action-evidence contract for
the active run: evidence classification, action kind, job ID, terminal status,
replay route, terminal artifact names, configuration summary, and latest
epoch. The Admin queue records the bounded training job and its path-free
terminal artifact manifest. Terminal training jobs write
training/status.json and training/evidence.json; the latter uses the
studio.action-evidence.v1 contract to record the action kind, replay route,
job ID, terminal status, evidence classification, status payload SHA-256, and
status artifact metadata without exposing host-local paths or secrets. After
the terminal evidence artifact is available, /api/training/status/{job_id}
returns a studio.training.evidence-summary.v1 operator summary containing the
verified action kind, evidence classification, replay route, evidence artifact
digest, and result artifact metadata.
Training checkpoint controls export studio.training.checkpoint.v1 JSON from
/api/training/checkpoint/{job_id} and import it through
/api/training/checkpoint/import, validating both the config digest and the
full checkpoint digest before restoring the training configuration.
Compile, synthesis, PnR, and full-pipeline routes also submit through the
bounded worker manager. Their HTTP responses remain synchronous for existing UI
flows, and the Admin queue records path-free artifacts at
compiler/result.json, cosim/report.json, cosim/traces.json,
synthesis/result.json,
synthesis/multi-target-result.json, synthesis/pnr-result.json, and
pipeline/result.json. The Network Canvas also surfaces the pipeline
action-evidence contract beside the terminal result, including evidence
classification, action kind, status, target, step, replay route, and the
pipeline/result.json plus pipeline/evidence.json artifact names.
Compile responses include path-free studio.compile-traceability.v1 metadata.
Both /api/compile and /api/ir/emit-sv-direct compile every supplied equation
and preserve init and module_name. The direct route defaults to
sc_ode_neuron; the worker route defaults to sc_neuron. These ODE export
routes use the equation compiler's fixed default timestep of 0.1. They reject
simulation-only fields such as dt, duration, and current with HTTP 422;
they do not silently apply a different simulation configuration. Selected-model
compilation has its own explicit timestep contract.
The manifest records the source equation payload, emitted RTL module metadata,
source and RTL SHA-256 digests, and evidence_classification: "compile"
without exposing host-local paths. The Compiler Inspector displays shortened
source, RTL, and manifest digests beside direct equation-to-Verilog output.
The same strip can export a compile evidence bundle with replay metadata for
/api/ir/emit-sv-direct, using the compile input digest as the replay request
fingerprint and the traceability digest as the operator note. After export, it
lists the compile bundle's path-confined artifacts with size and SHA-256 labels
and downloads each file through the compile-scoped authenticated job-artifact
route.
Synthesis results include path-free studio.synthesis-target-provenance.v1
metadata for the selected target. Multi-target runs include the
studio.synthesis-target-provenance-matrix.v1 matrix with a stable SHA-256
digest across every supported target. These records capture target capacity,
Yosys command, optional nextpnr command/device, tool availability, and tool
version strings when available. The frontend renders the all-target matrix as
device, synthesis-readiness, PnR-readiness, tool, evidence-class, and digest
rows so operators can inspect target support without opening raw JSON.
After a single-target or all-target synthesis run, the FPGA panel can export a
synthesis-scoped evidence bundle anchored on the captured worker job ID. The
bundle includes the worker record plus the validated synthesis/evidence.json
or synthesis/multi-target-evidence.json artifact, and the panel downloads
bundle artefacts through the authenticated job-artifact route.
Each worker-backed compile, model co-simulation, synthesis, PnR, and pipeline
action also writes a
normalized studio.action-evidence.v1 manifest next to the result artifact:
compiler/evidence.json, cosim/evidence.json, synthesis/evidence.json,
synthesis/multi-target-evidence.json, synthesis/pnr-evidence.json, or
pipeline/evidence.json. The manifest records the action kind, replay route,
job ID, evidence classification, result payload SHA-256, and result artifact
metadata without exposing host-local paths or secrets. Evidence bundle export
validates selected job evidence artifacts (evidence.json and
*-evidence.json) against this contract and classifies them as
action_evidence entries in the bundle manifest.
Job artifacts are served through the admin-gated
/api/studio/jobs/{job_id}/artifacts/{artifact_path} endpoint. The endpoint
only serves manifest-declared artifacts, revalidates the recorded size and
SHA-256 digest before returning bytes, and uses generic error details when an
artifact is missing or fails integrity checks.
The Admin panel queue uses /api/studio/jobs and /api/studio/jobs/{job_id}
for path-free job records. Those endpoints are admin-gated and expose status,
owner, request ID, timestamps, result metadata, and artifact manifests without
revealing the configured job-root path.
The Admin Jobs section also displays the resource profiles published by
/api/studio/jobs/status, so operators can see per-kind timeout, artifact, and
execution-model limits before launching long-running work.
Administrators can create reproducible handoff bundles with
POST /api/studio/evidence/bundle. The route runs as a bounded
studio-evidence worker job and can include one saved project payload,
selected simulation responses carrying studio.simulation-run.v1 or .v2 run
metadata,
selected analysis responses carrying studio.analysis-result.v1 analysis
metadata, selected default-flow run and attestation responses, selected job
records, verified copies of selected job artifacts, a bounded audit export,
and command replay metadata such as method, route, and request body digest.
Bundle files are declared job artifacts under evidence/, with simulation
payloads stored under evidence/simulations/, analysis payloads stored under
evidence/analyses/, selected studio.model-scan.v1 model-scan payloads
(classified as analysis evidence) stored under evidence/model-scans/,
selected studio.training.weight-restore.v1 weight-restore payloads (classified
as training evidence) stored under evidence/training-weight-restores/,
selected studio.training.weight-restore-attach.v1 weight-restore attach
payloads (classified as training evidence) stored under
evidence/training-weight-restore-attaches/,
default-flow payloads stored under
evidence/default-flows/, and a studio.evidence-bundle.v1 manifest at
evidence/manifest.json. The Admin evidence form exposes Model Scan JSON,
Weight Restore JSON, and Weight Restore Attach JSON fields alongside the
simulation and analysis inputs. Selected job action-evidence artifacts are copied
under evidence/jobs/{job_id}/artifacts/ and classified as action_evidence
only after studio.action-evidence.v1 validation. The bundle manifest is
path-free and omits bearer tokens, token hashes, password material, and
host-local filesystem paths. The response and manifest also include a
path-free summary with artifact-path count, manifest-entry count, entry-type
counts, action-evidence classification counts, and selected source-job counts
by kind and owner.
The Admin panel exposes the same evidence-bundle workflow. Operators can enter an optional saved project name, simulation-result JSON, analysis-result JSON, default-flow run JSON, default-flow attestation JSON, comma-separated job IDs, audit export settings, and replay metadata. Recent job rows display declared artifact paths plus evidence-manifest counts and can seed the job ID field for bundle export. After export, the panel refreshes the worker queue and shows the bundle ID, evidence job ID, artifact count, and manifest entry count. The panel also surfaces entry-type, evidence-class, and source-job summaries so operators can verify bundle content without opening the raw manifest JSON. It also lists manifest entries with entry type, evidence classification, source, and artifact or replay detail before the downloadable file rows. Bundle artifact rows expose path, size, and SHA-256 labels and download through the authenticated job artifact route, preserving bearer-session access control for browser users.
Studio also exposes a process-backed job-manager path for new backend work
that can be expressed as an importable module:function task with a
JSON-serializable payload and result. Process jobs use the same path-confined
artifact context and public manifest shape as thread-backed jobs, but they run
in a separate Python process so timeout or cancellation can terminate the
worker instead of leaving a long-running Python callable alive in the backend
process. /api/training/start, /api/compile, /api/models/compile,
/api/models/cosim, /api/synth/run,
/api/synth/multi-target, /api/synth/pnr, and /api/pipeline/run use this
process-backed path for training, ODE/model-to-RTL compilation, selected-model
real RTL parity, synthesis, PnR, target comparison, and graph-to-synthesis
execution while preserving their response contracts and evidence artifacts.
Remaining route closures stay on
the thread-backed path until each workflow is migrated to importable process
tasks with explicit payload contracts.
The Admin panel also uses the admin-gated /api/studio/operator/status
aggregate when available. That endpoint reports deployment profile,
route-policy enforcement, route inventory counts, protected-route audit
coverage, identity mode, audit health plus retained-chain integrity, worker
health, resource-limit posture, browser-login lockout limits, and capability
counts without exposing local paths or token material.
The first-screen readiness panel and the Admin Operator section render the same
operator-status posture. Browser readiness is an operator activation aid: it
shows disabled route-policy enforcement, header-principal fallback, memory-only
audit sinks, missing job roots, incomplete runtime ceilings, unhealthy jobs, and
unavailable capabilities early, while sc-neurocore studio-preflight remains
the release promotion gate.
For production deployments, set
SC_NEUROCORE_STUDIO_DEPLOYMENT_PROFILE=production. That profile fails closed
unless route policies are enforced, header principals are disabled, and the
identity file, audit log, and job root are all configured.
Studio ships deployment-profile packages for the three supported operator contexts:
sc-neurocore studio-deployment-profile --studio-profile local
sc-neurocore studio-deployment-profile --studio-profile lab --output studio-lab-profile.json
sc-neurocore studio-deployment-profile --studio-profile server --format env --output studio-server.env
The package schema is studio.deployment-profile.v1. The local package keeps
the runtime profile in development with loopback-only hosts and origins for a
single workstation. The lab and server packages set the runtime profile to
production, require route-policy enforcement, disable header principals, and
include placeholders for the durable identity file, audit log, job root,
saved project workspace, allowed hosts, allowed origins, preflight command,
launch command, and backup items. Package output contains placeholders and safe
defaults only; bearer tokens, password material, token hashes, and host-local
paths must be supplied outside the repository by the operator.
Generate the durable-state backup and restore plan from the same runtime environment:
sc-neurocore studio-backup-plan --output studio-backup-plan.json
The plan schema is studio.backup-plan.v1. By default it is safe for deployment
logs: it lists the identity file, audit log, job root, and saved project
workspace by stable item IDs and source labels without resolved local paths or
secret material. Use --include-local-paths only for an internal host-local
handoff that must name the exact paths to capture and restore.
Saved project writes use the studio.project-save.v1 response schema. The
backend persists the full project JSON for later restore, while the API returns
only the project name, saved timestamp, Studio payload version, project-state
SHA-256, full-project SHA-256, and project_workspace evidence classification.
The response is path-free so deployment logs and UI state do not expose
operator-local workspace roots.
The Projects panel keeps the latest save response in UI state and renders the classification, project name, state digest, project digest, and schema version as the operator-visible confirmation for the persisted workspace. The same strip can export a project evidence bundle through the bounded evidence worker, using the saved project name and project SHA-256 as replay metadata while refreshing the worker queue after export. When the bundle is available, the Projects strip lists the path-confined artifacts with size and SHA-256 labels and downloads each file through the authenticated Studio job-artifact endpoint. The frontend keeps Admin, Projects, Compiler, and Synthesis evidence-bundle state in separate slots so one workflow cannot display or download another workflow's last exported bundle by accident. The operator workbench uses those same scoped slots for its first-screen export action: it routes to synthesis evidence after a synthesis job, compile evidence after compile traceability, and project evidence after a saved project.
Before promoting a Studio deployment, run the release preflight from the same environment that will launch the backend:
sc-neurocore studio-preflight --output studio-preflight.json
The command exits with status 0 when no check fails; non-blocking warnings do
not change the exit status. It checks runtime settings, route-policy
enforcement, disabled development header principals, required admin route
policies, a valid identity store with at least one active unexpired
studio.admin principal, browser-login lockout settings, audit-log readiness,
job-root readiness, and bounded EDA process and job-artifact resource limits.
The required route-policy inventory includes service
account list/detail/update routes and browser-user list/detail/create/update
and password-rotation routes, job list/detail/artifact routes, and the
evidence bundle export route. The resource_limits check reports the configured
EDA CPU and memory ceilings and the per-job artifact byte limit; it returns a
warn status, rather than failing, when the host cannot enforce the ceilings
(non-POSIX) or when they are left unbounded, so operators can still see the gap
in deployment logs. The JSON report uses schema
studio.preflight.v1 and is safe for deployment logs: it reports booleans,
counts, stable check IDs, a top-level warned flag, and path-free remediation
steps without local filesystem paths, bearer tokens, token hashes, passwords, or
password verifiers.
Additional Panels (Blocks 2–6)¶
The Studio includes five additional panels beyond the core research workbench:
- Compiler Inspector — build SC IR, verify, emit SystemVerilog. Details
- Synthesis Dashboard — worker-backed Yosys synthesis for 4 FPGA targets, multi-target comparison, target provenance, resource estimation. Details
- Training Monitor — live SNN training with 6 surrogate gradients, SSE metric streaming. Details
- Network Canvas — drag-and-drop populations and projections with React Flow, NIR export/import. Details
- Integration — worker-backed full pipeline (graph → compile → synthesise), project save/load. Details
Full documentation: Studio Hub