Studio Federation API¶
sc_neurocore.federation is the optional Hub-facing Studio federation surface.
It is separate from the local FastAPI Studio app under sc_neurocore.studio: the
federation package emits schema-A capability manifests, schema-B evidence
bundles, and verifiable-honesty envelopes for SC-NeuroCore result claims.
Install the optional platform contract before importing it:
pip install "sc-neurocore[federation]"
Federation requires Python 3.11 or newer and pins
scpn-studio-platform>=0.11,<0.12; the base library still supports Python 3.10. Environments without that
platform SDK should not import this package; tests use pytest.importorskip so
the base CI lane stays independent of the optional federation dependency.
Capability Manifest¶
Use build_manifest() to produce the schema-A manifest consumed by the Studio
Hub:
from sc_neurocore.federation import build_manifest
manifest = build_manifest()
assert manifest.studio == "sc-neurocore"
The manifest declares contract era v2. A consumer that supports only v1
refuses it; a dependency version alone does not establish era compatibility.
The manifest advertises eight verbs:
| Verb | Purpose | Evidence schema |
|---|---|---|
encode |
Convert float values into stochastic bitstreams. | studio.bitstream-encoding.v1 |
simulate |
Run stochastic-computing inference. | studio.sc-inference.v1 |
analyse |
Extract spike-train analysis results. | studio.spike-analysis.v1 |
benchmark |
Measure backend throughput against the NumPy reference. | studio.backend-benchmark.v1 |
validate |
Compare fixed-point reference and RTL co-simulation. | studio.cosim-parity.v1 |
compile |
Lower a model to synthesisable RTL. | studio.rtl-compilation.v1 |
synthesise |
Record synthesis resource/timing evidence. | studio.fpga-deployment.v1 |
deploy |
Record FPGA deployment evidence. | studio.fpga-deployment.v1 |
The committed manifest artifact lives at docs/_generated/studio_manifest.json
and is generated by:
python tools/emit_studio_manifest.py
python tools/emit_studio_manifest.py --check
The digest covers the declared verbs and evidence schemas, not the current git state, so the manifest is stable across checkouts with the same federation surface.
Evidence Bundles¶
sc_inference_evidence() maps a stochastic inference result into a measured
software evidence bundle. It renders as reference-validated only when the
accelerated backend is bit-identical to the NumPy reference for the fixed seed.
Otherwise the claim is bounded and rejected by the shared platform lattice.
fpga_deployment_evidence() maps a pre-silicon synthesis/co-simulation result
into a measured bundle on the simulator substrate. It renders as
reference-validated only when the RTL co-simulation is bit-exact and re-checked
at source; a mismatch becomes validation-gap. A named FPGA synthesis target
does not establish that a bitstream executed on a physical board.
import hashlib
from datetime import datetime, timezone
import numpy as np
from scpn_studio_platform.evidence import Freshness
from sc_neurocore.accel import pack_bitstream, sc_forward
from sc_neurocore.federation import (
ScInferenceResult,
sc_inference_evidence,
)
started = datetime.now(timezone.utc).isoformat()
length, seed = 257, 173
bits = np.random.default_rng(31).integers(0, 2, size=(2, 3, length), dtype=np.uint8)
weights = np.stack([pack_bitstream(row) for row in bits.reshape(6, length)]).reshape(2, 3, -1)
inputs = np.array([0.125, 0.5, 0.875], dtype=np.float64)
reference = sc_forward(weights, inputs, length=length, seed=seed, backend="numpy")
measured = sc_forward(weights, inputs, length=length, seed=seed, backend="rust")
np.testing.assert_array_equal(measured, reference)
source = weights.astype("<u8").tobytes() + inputs.astype("<f8").tobytes()
source += seed.to_bytes(4, "little") + length.to_bytes(4, "little")
result = ScInferenceResult(
active_backend="rust",
reference_backend="numpy",
max_abs_error=float(np.max(np.abs(measured - reference))),
bitstream_length=length,
input_digest="sha256:" + hashlib.sha256(source).hexdigest(),
result_digest="sha256:" + hashlib.sha256(measured.astype("<f8").tobytes()).hexdigest(),
)
bundle = sc_inference_evidence(
result,
operator="opaque:tenant-1",
studio_version="3.16.0",
started=started,
ended=datetime.now(timezone.utc).isoformat(),
freshness=Freshness.VERIFIED_AT_SOURCE,
)
This example requires the Rust engine as well as the federation extra. It hashes the actual retained input encoding and output bytes after comparing both backends.
Source freshness is explicit. Pass Freshness.VERIFIED_AT_SOURCE only after
recomputing the result or checking the retained source artefacts against their
digests. Bit-exact inference or co-simulation without that re-check is refused.
An unchecked mismatch remains a boundary claim; it never acquires freshness
automatically. Historical signed envelopes remain immutable: changing a digest
or adding freshness requires authentic new producer evidence and a new seal.
Published Platform 0.11.2 and the deployed consumer require separate
verification; installing an SDK does not establish admission by a live Hub.
In 0.11.2 the low-level manifest validator accepts explicit supported_eras,
while its loader and aggregation command retain the default v1 policy. Full v2
consumption requires a consumer that also exposes explicit era negotiation through
those entry points and its deployment wrapper; no fallback changes the manifest.
Verifiable-Honesty Envelopes¶
The attestation helpers wrap platform seals so a rendered claim grade can be verified from signed evidence:
seal_sc_inference()uses recompute mode for SC inference against NumPy.attest_fpga_deployment()signs a pre-silicon result pack in attestation mode. The signature identifies the producer; it is not hardware-rooted attestation.verify_envelope()recomputes the grade by schema and detects stripped, forged, or mismatched rendered claims.
Both seal functions take the same explicit freshness argument as the bundle
mappers. A source-unchecked bit-exact result is refused before signing. Freshness
is part of the signed unit and the regrader checks it; legacy envelopes without
that declaration cannot acquire a validated grade by changing a rendered badge.
Signed numeric scalars use exact decimal strings, preserving signatures across
browser JSON transport. Boolean values cannot stand in for a numeric zero error.
Wire counts must be integers in JavaScript's exact range 0..2^53−1; bitstream
length must also be positive. Larger integers are refused before signing and
cannot earn a validated grade when received as raw wire data.
FpgaArtifact entries require a complete lowercase sha256:<64 hex characters>
address and non-empty role/media type. The caller checks actual artifact bytes
before declaring source freshness. A pre-silicon parity claim earns the validated
grade only when a cosim-transcript artifact backs it. Its result-pack digest binds
the complete signed unit, including report fields, artifact addresses and freshness.
Physical board execution, hardware latency and measured power need their own
device evidence; the current co-simulation mapper does not assert them.
Reference¶
sc_neurocore.federation
¶
SC-NeuroCore's STUDIO federation vertical on the scpn-studio-platform contract.
Hub-facing federation surface (schema-A capability manifest + schema-B evidence
bundles), distinct from the local FastAPI Studio web app under
sc_neurocore.studio. Importing this package requires the federation extra
(pip install sc-neurocore[federation] → scpn-studio-platform>=0.11,<0.12, the
Python 3.11+ SDK with the verifiable-honesty :mod:~scpn_studio_platform.seal module); a
clean ModuleNotFoundError is raised when the platform SDK is absent, which is
why tests guard with pytest.importorskip("scpn_studio_platform").
Example¶
from sc_neurocore.federation import build_manifest, fpga_deployment_evidence manifest = build_manifest() manifest.studio 'sc-neurocore'
PLATFORM_SDK_RANGE = '>=0.11,<0.12'
module-attribute
¶
The platform SDK SemVer range the studio builds on (matches the federation extra).
PROTOCOL_VERSION = '1'
module-attribute
¶
The SYNAPSE wire protocol version the studio pins.
STUDIO_VERSION = _resolve_studio_version()
module-attribute
¶
The SC-NeuroCore studio version this manifest stamps (source package version).
NEUROCORE_VERBS = (ENCODE, SIMULATE, ANALYSE, BENCHMARK, VALIDATE, COMPILE, SYNTHESISE, DEPLOY)
module-attribute
¶
Every verb the SC-NeuroCore studio advertises, in manifest order.
STUDIO_ID = 'sc-neurocore'
module-attribute
¶
The studio identifier this vertical implements (also the federation name).
FpgaArtifact
dataclass
¶
A content-addressed artifact backing a pre-silicon co-simulation claim.
Parameters¶
role
What the artifact is — e.g. "synthesis-timing", "synthesis-utilisation",
"cosim-transcript" (the bit-exactness proof), or "bitstream".
digest
SHA-256 of the artifact ("sha256:<hex>"); the identity that binds the claim
to the real file.
media_type
The artifact's media type (e.g. "text/vivado-timing").
Raises¶
ValueError If a field is blank or the digest is not a lowercase SHA-256 address.
Source code in src/sc_neurocore/federation/attestation.py
| Python | |
|---|---|
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | |
__post_init__()
¶
Reject blank descriptions and malformed content addresses.
Source code in src/sc_neurocore/federation/attestation.py
| Python | |
|---|---|
91 92 93 94 95 96 97 98 | |
to_dict()
¶
Return the JSON-serialisable mapping of the artifact.
Source code in src/sc_neurocore/federation/attestation.py
| Python | |
|---|---|
100 101 102 | |
FpgaDeploymentResult
dataclass
¶
A path-free pre-silicon FPGA synthesis/co-simulation result.
Target device identity and synthesis reports do not attest physical execution.
Parameters¶
device
The target device (e.g. "xc7z020-1clg400").
cosim_bit_exact
Whether the synthesised RTL co-simulation matched the Q8.8 fixed-point
reference bit-for-bit.
lut_used, ff_used
Look-up tables and flip-flops consumed by the synthesised design.
worst_negative_slack_ns
Worst negative slack at the target clock; >= 0 means timing closed.
clock_mhz
The synthesis target clock frequency, in MHz.
result_digest
SHA-256 of the bitstream / synthesis report.
Raises¶
ValueError If a resource count, co-simulation flag, clock, timing or digest is invalid.
Source code in src/sc_neurocore/federation/evidence.py
| Python | |
|---|---|
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | |
__post_init__()
¶
Validate finite report values and their SHA-256 identity.
Source code in src/sc_neurocore/federation/evidence.py
| Python | |
|---|---|
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | |
ScInferenceResult
dataclass
¶
A path-free stochastic-computing inference result.
Parameters¶
active_backend
The accelerated backend that produced the result (e.g. "rust").
reference_backend
The bit-true reference backend (the NumPy floor).
max_abs_error
Maximum absolute difference between the active and reference outputs for
the fixed seed; 0.0 means bit-identical.
bitstream_length
The stochastic bitstream length used.
input_digest
SHA-256 of the weights/inputs/seed.
result_digest
SHA-256 of the output firing rates.
Raises¶
ValueError If a count, error, backend or content address is invalid.
Source code in src/sc_neurocore/federation/evidence.py
| Python | |
|---|---|
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | |
__post_init__()
¶
Validate finite measured inputs and their SHA-256 identities.
Source code in src/sc_neurocore/federation/evidence.py
| Python | |
|---|---|
121 122 123 124 125 126 127 128 129 130 131 132 133 134 | |
attest_fpga_deployment(result, artifacts, *, signer, freshness=None)
¶
Seal pre-silicon co-simulation in attestation mode with a result pack.
The producer signs the complete path-free unit, including source freshness and artifact addresses. Its detached signature vouches for the producer's report; physical device execution and hardware-rooted attestation remain separate.
Parameters¶
result
The path-free synthesis/deployment result.
artifacts
The content-addressed artifacts the claim rests on; at least one is required, and
a cosim-transcript must be present for the claim to grade as validated.
signer
The studio's :class:~scpn_studio_platform.seal.keys.Signer.
freshness
Actual source re-check status; bit-exact reports require
VERIFIED_AT_SOURCE before signing.
Returns¶
HonestyEnvelope
A studio-self-attested measurement on the simulator substrate.
Raises¶
ValueError If artifacts are absent or bit-exact evidence lacks a source re-check.
Source code in src/sc_neurocore/federation/attestation.py
| Python | |
|---|---|
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 | |
regrade_fpga(unit)
¶
Recompute the FPGA grade from the signed unit.
reference-validated requires source-rechecked, measured simulator evidence,
valid report fields and an addressed co-simulation transcript. This grade is
pre-silicon parity; no physical deployment or power claim is established.
Source code in src/sc_neurocore/federation/attestation.py
| Python | |
|---|---|
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 | |
regrade_sc_inference(unit)
¶
Recompute the sc-inference grade from the signed unit.
reference-validated requires a complete measured unit, explicit source
re-check and exact string zero error against NumPy. Missing, legacy or malformed
evidence stays bounded-model. The signed claim_status is not trusted.
Source code in src/sc_neurocore/federation/attestation.py
| Python | |
|---|---|
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | |
seal_sc_inference(result, *, signer, freshness=None)
¶
Seal an sc-inference result in recompute mode (no attestation).
Parameters¶
result
The path-free stochastic-computing inference result.
signer
The studio's :class:~scpn_studio_platform.seal.keys.Signer.
freshness
Actual source re-check status. Bit-identical results require
VERIFIED_AT_SOURCE; the value is part of the signed unit.
Returns¶
HonestyEnvelope A recompute-verifiable envelope: the WASM/NumPy kernel re-derives the result and its digest must match.
Raises¶
ValueError If bit-identical evidence has not been re-checked at source.
Source code in src/sc_neurocore/federation/attestation.py
| Python | |
|---|---|
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | |
verify_envelope(envelope, rendered_grade, *, keyring)
¶
Verify a SC-NeuroCore honesty envelope, dispatching the regrade by schema.
Parameters¶
envelope
The :meth:HonestyEnvelope.to_dict wire form on the page, or None when the
page carries no seal.
rendered_grade
The grade the page displays for the claim, or None.
keyring
The trust anchor mapping key_id → public verifier.
Returns¶
Verdict
:data:~scpn_studio_platform.seal.verdict.Verdict.VERIFIED only when the
signature is valid and the rendered grade equals the grade recomputed from the
signed unit; otherwise STRIPPED / FORGED / UNGRADED.
Source code in src/sc_neurocore/federation/attestation.py
| Python | |
|---|---|
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 | |
fpga_deployment_evidence(result, *, operator, studio_version, started, ended, host=None, freshness=None)
¶
Build the studio.fpga-deployment.v1 pre-silicon measurement bundle.
RTL is co-simulated against the Q8.8 fixed-point reference on the
simulator substrate. The claim is reference-validated only when that
co-simulation is bit-exact and re-checked; a mismatch becomes validation-gap.
Parameters¶
result
The path-free synthesis/deployment result.
operator
Opaque identity of the operator/tenant.
studio_version
Version of the SC-NeuroCore studio that produced the result.
started, ended
ISO-8601 start/end timestamps (passed in; no hidden clock).
host
Optional host descriptor the synthesis ran on.
freshness
Source re-check status supplied by the producer. Bit-exact co-simulation
requires VERIFIED_AT_SOURCE; a retained report alone is not a re-check.
Returns¶
EvidenceBundle
A measured bundle on the simulator substrate, without a board claim.
Raises¶
ValueError If a bit-exact co-simulation lacks a verified-at-source re-check.
Source code in src/sc_neurocore/federation/evidence.py
| Python | |
|---|---|
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 | |
sc_inference_evidence(result, *, operator, studio_version, started, ended, host=None, freshness=None)
¶
Build the studio.sc-inference.v1 bundle (measured software result).
Parameters¶
result
The path-free inference result.
operator
Opaque identity of the operator/tenant.
studio_version
Version of the SC-NeuroCore studio that produced the result.
started, ended
ISO-8601 start/end timestamps (passed in; no hidden clock).
host
Optional host descriptor the run executed on.
freshness
Source re-check status supplied by the producer. A bit-identical result
requires VERIFIED_AT_SOURCE; parity alone never establishes freshness.
Returns¶
EvidenceBundle
A measured bundle that renders as validated only when the accelerated
backend is bit-identical to the NumPy floor.
Raises¶
ValueError If a bit-identical result lacks a verified-at-source re-check.
Source code in src/sc_neurocore/federation/evidence.py
| Python | |
|---|---|
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 | |
build_manifest(*, studio_version=STUDIO_VERSION)
¶
Build the SC-NeuroCore studio's capability manifest.
Parameters¶
studio_version
The studio version to stamp; defaults to :data:STUDIO_VERSION (the
source sc-neurocore version).
Returns¶
CapabilityManifest
The schema-A manifest, with a content digest over :func:declared_surface.
Source code in src/sc_neurocore/federation/manifest.py
| Python | |
|---|---|
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | |
declared_surface()
¶
Return the content-addressable declared surface of the SC-NeuroCore studio.
The surface is the canonical JSON of each advertised verb plus the evidence schema list, keyed by a stable logical path. Hashing surface content (not git state) is what makes the digest reproducible across checkouts.
Returns¶
dict[str, bytes]
Mapping of logical path to canonical-JSON bytes, suitable for
:func:scpn_studio_platform.manifest.content_digest.
Source code in src/sc_neurocore/federation/manifest.py
| Python | |
|---|---|
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | |
core_verbs()
¶
Return the SC-NeuroCore verbs drawn from the shared core spine.
Returns¶
tuple[Verb, ...]
The subset of :data:NEUROCORE_VERBS whose names are in the platform
:data:scpn_studio_platform.verbs.CORE_VERBS.
Source code in src/sc_neurocore/federation/verbs.py
| Python | |
|---|---|
147 148 149 150 151 152 153 154 155 156 | |
domain_verbs()
¶
Return the SC-NeuroCore verbs distinctive to a neuromorphic studio.
Returns¶
tuple[Verb, ...]
The subset of :data:NEUROCORE_VERBS not present in the platform core
spine (encode, deploy).
Source code in src/sc_neurocore/federation/verbs.py
| Python | |
|---|---|
159 160 161 162 163 164 165 166 167 168 | |
evidence_schemas()
¶
Return the distinct evidence schemas every SC-NeuroCore verb emits.
Returns¶
tuple[str, ...]
The sorted, de-duplicated union of each verb's produces schemas.
Source code in src/sc_neurocore/federation/verbs.py
| Python | |
|---|---|
171 172 173 174 175 176 177 178 179 180 | |