Metadata-Version: 2.4
Name: scpn-studio-platform
Version: 0.11.3.dev0
Summary: Domain-neutral SDK for the SCPN Studio ecosystem — provenance-first evidence bundles, capability manifests, bounded jobs, and tenant-aware identity.
Author-email: Miroslav Šotek <protoscience@anulum.li>
License-Expression: AGPL-3.0-or-later
Project-URL: Homepage, https://www.anulum.li
Project-URL: Repository, https://github.com/anulum/scpn-studio-platform
Keywords: scpn,studio,provenance,evidence,prov-o,ro-crate,in-toto
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE.md
Requires-Dist: cryptography>=50.0.2
Requires-Dist: jsonschema<5,>=4.26
Provides-Extra: pqc
Requires-Dist: liboqs-python==0.16.0.1; extra == "pqc"
Provides-Extra: dev
Requires-Dist: bandit==1.9.4; extra == "dev"
Requires-Dist: build==1.6.1; extra == "dev"
Requires-Dist: hypothesis==6.168.3; extra == "dev"
Requires-Dist: mypy==2.3.1; extra == "dev"
Requires-Dist: pip-audit==2.10.1; extra == "dev"
Requires-Dist: pre-commit==4.6.2; extra == "dev"
Requires-Dist: pytest==9.1.1; extra == "dev"
Requires-Dist: pytest-benchmark==5.3.0; extra == "dev"
Requires-Dist: pytest-cov==7.1.0; extra == "dev"
Requires-Dist: ruff==0.16.9; extra == "dev"
Requires-Dist: types-jsonschema==4.26.0.20260518; extra == "dev"
Requires-Dist: uv==0.13.6; extra == "dev"
Provides-Extra: docs
Requires-Dist: mkdocs==1.6.1; extra == "docs"
Requires-Dist: mkdocs-material==9.7.7; extra == "docs"
Requires-Dist: pymdown-extensions==12.1; extra == "docs"
Dynamic: license-file

<!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
<!-- Commercial license available -->
<!-- © Concepts 1996–2026 Miroslav Šotek. All rights reserved. -->
<!-- © Code 2020–2026 Miroslav Šotek. All rights reserved. -->
<!-- ORCID: 0009-0009-3560-0851 -->
<!-- Contact: www.anulum.li | protoscience@anulum.li -->
<!-- SCPN Studio Platform — package and evidence contract -->

# SCPN Studio Platform

The domain-neutral SDK at the foundation of the **SCPN Studio** ecosystem: a
federation of standalone scientific studios (neuromorphic, fusion, control,
quantum, magneto-inertial, phase dynamics) that share one platform, one evidence
standard, and one look, composed by a federating Hub shell.

This package is the **open-core foundation**. Each project builds its studio
vertical on it; the managed multi-tenant Hub is the separate paid layer. The
boundary is permanent and documented in
[docs/guides/open_core_boundary.md](docs/guides/open_core_boundary.md): the
claim lattice and every verification path stay open-core forever; the Hub
sells operation, never trust semantics.

## What makes it a category by itself

Provenance-first, as a product surface rather than only an engineering practice.
Every number a studio surfaces is an evidence bundle that:

- is a **PROV-O** graph, packaged as an **RO-Crate** profile (interoperable with
  the scientific data ecosystem, not a proprietary blob);
- carries an empirical evidence level (0–3) **and** an orthogonal `evidence_kind`
  — `measured`, `curated`, or `formally-proven` — so a machine-checked proof is
  never rendered as if it were a measurement;
- is signed as an **in-toto** attestation, with a `subject_digest` so a proof is
  voided the moment its subject drifts;
- declares its **claim boundary** on a nine-state lattice (reference-validated,
  bounded-model, bounded-support, validation-gap, external-dependency-blocked,
  roadmap, toolchain-gated, refuted, voided-by-upstream-retraction) — the Hub
  never upgrades a bounded, roadmap, refuted, or cascade-voided number to
  "validated";
- records how to **reproduce** it (`regenerated_by` + host), not just attest it;
- chains cross-studio derivation by **content digest**, so the provenance graph
  survives coordination-log rotation.

## Package surface

| Subpackage | Responsibility |
|------------|----------------|
| `evidence` | The `studio.*.v1` evidence bundle, attestation, and claim-boundary lattice. |
| `manifest` | Content-addressed, language-agnostic, deterministic capability manifest. |
| `reactor_portfolio` | Strict reactor descriptor, source/map/authority validation, and deterministic producer parity. |
| `verbs`    | Verb taxonomy + per-verb attribute contract (safety tier, fidelity, timing, side-effect, proof). |
| `identity` | Tenant-aware opaque identity + sessions, shared by both transport profiles. |
| `jobs`     | Bounded, fail-closed job/pipeline workers + the real-time timing contract. |

## Functional pipeline contract

Keepers can select their implemented manifest eras through
`load_manifest_envelope(..., supported_eras=("v2",))` and
`aggregate_federation(..., supported_eras=("v2",))`, or the aggregation CLI's
repeatable `--supported-era` option. Omission keeps v1; explicit selection does
not change evidence admission or permit mixed-era execution. See the
[manifest aggregation guide](docs/guides/manifest_aggregation.md).

Each `Verb` can now declare `consumes` symmetrically with `produces`. A `consumes`
entry means a hard runtime dependency on an upstream `studio.*.v1` schema or
interface identifier; soft/demo couplings stay out of this field and remain
ordinary provenance or optional inputs. `manifest.resolve_pipeline()` turns the
visible manifest set into content-addressed pipeline edges, surfaces
`unresolved_upstreams`, and reports incompatible-era matches as hard resolution
conflicts.

## Opaque native projections

`EvidenceBundle(..., native_detail=mapping)` retains the supplied projection in
`to_dict()` and its RO-Crate payload. `None` omits it. This generic SDK does not
decode or qualify native claims, so `renders_as_validated` is false whenever
the producer supplies a projection. The wire gate likewise withholds validated
presentation whenever `native_detail` is present, including an explicit null
from another producer; all common-envelope refusals remain enforced.

The Hub preserves declared outer values and shows the original detail at its
boundary. A supplied native success flag, trusted publication seal or common
admission decision cannot supply native qualification. Unsupported outer wire
versions remain refused.

Only the exact top-level wire key `native_detail` is recognised. Aliases, case
variants and nested fields are ordinary unknown metadata; they do not declare a
supported native projection or confer native qualification. Producers must use
the canonical key.

Producer mappings are snapshotted as finite JSON data with string keys and no
cycles. Later caller mutations and edits to returned JSON cannot rewrite the
bundle. Hashing remains available; opaque detail is excluded from its hash.

## Recovered dynamics provenance

Recovered latent-dynamics claims carry an explicit
`numeric_provenance.recovered_dynamics` envelope. It records the recovery method,
latent and observed dimensions, independent view count, observation-noise model,
identifiability scope, symbolic function basis, optional rollout horizon, and
held-out trajectory/dynamics scores. DYSCO-style claims are therefore bounded as
recoveries within an affine gauge and a declared basis, never as direct access to
the original latent coordinates.

## Cascade retraction contract

`evidence.RetractionRecord` carries the signed `studio.retraction.v1` unit used
when an upstream claim must be withdrawn. The policy is stale-safe by default:
`cascade_retraction()` walks content-addressed `derived_from` evidence edges and
marks every downstream consumer as `voided-by-upstream-retraction`. A
`supersedes_with` digest records a replacement candidate but never auto-heals
existing consumers; downstream studios must re-derive against the replacement and
emit a new evidence bundle.

## Verifiable numeric references

The `seal` package signs WS-1 honesty envelopes and now carries the committed
reference values required by tolerance and stochastic recompute claims. Small
reference series are embedded as canonical little-endian `float64` bytes under
`reference_value.storage = "inline"` with a `sha256:` digest over those bytes.
Large arrays use `reference_value.storage = "artifact"` and sign a side-artifact
descriptor containing `artifact_uri`, media type
`application/vnd.anulum.float64-array.v1`, `dtype = "float64"`,
`byte_order = "little"`, `shape`, `content_length`, and
`canonical_value_digest`.

The SDK validates the signed descriptor. Inline payloads must fit within 16 KiB
and their digest must match the embedded bytes. `reference_artifact_descriptor`,
`seal` and `verify` do not retrieve side-artifact bytes. The caller must retrieve
them and check their length and digest against the signed descriptor before
comparing numeric outputs. A valid seal authenticates the metadata; it does not
establish artifact retrieval or numerical agreement.

## Development

See the [development guide](docs/guides/development.md) for the complete
Python environment, hash locks, Node/pnpm toolchain and local gates.

## Status

Early development. The v1 contract is locked; the platform is being extracted
from the reference SNN Studio implementation and hardened to the contract.

## Licence

Dual-licensed under the GNU AGPL v3 with a commercial option. For commercial
licensing enquiries, contact [protoscience@anulum.li](mailto:protoscience@anulum.li).

## Validity-domain intervals

A numeric validity range is a closed interval: `low` and `high` must be finite
numbers and `low <= high`. Both endpoints are included, and a singleton such as
`[3, 3]` is valid. Booleans, NaN, Infinity, JSON numeric overflow and reversed
bounds are refused. A range names its parameter and may declare its unit.

The SDK checks this when constructing `ValidityRange`. Python and TypeScript
federation gates check supplied domains again on untrusted wire input, including
stored era-v1 evidence; the browser parser refuses malformed intervals before
returning a renderable bundle. The browser also rechecks numeric intervals before
granting validated presentation, so later changes to a parsed range cannot retain
validated tone. Existing proof, refutation, freshness and native-detail boundaries
continue to apply.

A qualitative domain may use a non-empty `note` without numeric ranges. Do not
encode unbounded or unknown scope as Infinity. Well-formed interval metadata is
only a declared applicability boundary; it does not establish scientific validity,
source trust, native qualification or permission to control a device.

## Text and data mining reservation

The rightsholder, Miroslav Šotek (ANULUM), expressly reserves the use of the
works in this repository for text and data mining, including the collection of
this content for, and its use in, training, fine-tuning or evaluating machine
learning and artificial intelligence models, in accordance with Article 4(3) of
Directive (EU) 2019/790 and the national provisions transposing it.

No permission for such use has been granted beyond what the licence in
`LICENSE` grants. This reservation does not change that licence: uses the
licence permits remain permitted on its terms, including its attribution and
share-alike conditions.

Reservation made on 2026-10-19. Requests for permission: contact the
rightsholder through the contact listed in this repository.
