Skip to main content

Stored-Relationship Mechanism: the 14-class A-N primitive vocabulary in native C + Python, numpy-optional. Every continuous-math op (trig, exp, sqrt, FFT, SVD, eig) is a cascade of the 14; the native build holds no libm. The One, S(sigma,theta), generates the 1+3+7+3 = 14 substrate -- the C/H/O Hurwitz ladder = so(8) + Spin(8) triality (Fix(tau)=g_2=14), bit-exact cascade-vs-matrix. Full C/Python cascade-catalog parity; AMSC (MPR v1).

Project description

srmech

Status: v0.7.0 — the 14-class A–N primitive vocabulary in native C + Python, numpy-optional. Every continuous-math op — trig, exp, sqrt, FFT, SVD, eig — is a cascade of the 14, not a separate primitive; the native build holds no libm. The One, S(σ,θ) (cascade.the_one, exact-rational + numpy-free, with the bit-exact qm.hurwitz matrix peer), generates the whole 1 + 3 + 7 + 3 = 14 substrate: the ℂ/ℍ/𝕆 Hurwitz ladder = the 28-generator so(8) adjoint + Spin(8) triality (the order-3 outer automorphism τ, Fix(τ) = g₂ = 14). Full C/Python cascade-catalog parity (hash, cyclic-group, graph-Laplacian, primes, HDC, rational, Kuramoto, Wiener–Khinchin autocorrelation; the two-tier cascade.atoms/cascade.compose lean-ISA split; the Klein-4 four-sector parallel_sector_dispatch); runtime spectral + dual-path signal-processing surfaces; Attested Multi-Source Collector/Catalog (AMSC, MPR v1) provenance. A named cascade is the default, a math-library call the exception. (The package also bundles the siona co-name alias — pip install srmech also gives import siona, same objects. The standalone siona PyPI package is a metapackage that depends on srmech.)

srmech (Stored-Relationship Mechanism) is a research package shipping five load-bearing surfaces:

  1. 14-class primitive vocabulary (srmech.amsc.*) — content-addressing, streaming, cyclic-group, graph-Laplacian, prime-factorisation, TLV, search, dispatch, catalog, templating, rational-approximation, equation-of-centre/Kepler, hyperdimensional-computing (HDC). Each class has both a Python wrapper and a native C symbol in libsrmech.{so,dll,dylib}.
  2. The continuous-math cascade + the One (srmech.amsc.cascade.*, srmech.qm.*) — every "scientific" op (trig, exp, sqrt, FFT, SVD, eig, …) is a composition of the 14, not a separate primitive (numpy-optional; the native build holds no libm). No particular math is privileged — it is all the same cascade. The same 14 are the graded blocks of the One, S(σ,θ) = ⨁_{n=1}^{3}(ℝ·1 ⊕ σ·e^{Î_nθ}·Im 𝔸_n), dim = 1+3+7+3 = 14 (cascade.the_one, exact-rational + numpy-free; the bit-exact matrix peer qm.hurwitz): the ℂ/ℍ/𝕆 Hurwitz ladder = the 28-generator so(8) adjoint + Spin(8) triality (qm.{octonion, so8, triality}; the order-3 outer automorphism τ, Fix(τ) = g₂ = 14 = the A-N 1+3+7+3 partition).
  3. Runtime spectral decomposition (srmech.spectral) — eigenbasis projection, HDC delta encoding, spectral prediction, prediction-error gating, sparse-truncate compression.
  4. Dual-path signal-processing surface (srmech.signal_processing) — 38 closed-form algebra ops (Path A) + an RBS-HDC bound-vector instrument at D=8192 (Path B), with a cascade dispatcher routing per call.
  5. AMSC provenance framework (srmech.amsc.format, srmech.amsc.catalog, srmech.amsc.adapters) — every ground-proof datum carries a mandatory attestation block (source_doi, source_url, license, retrieved_at, response_sha256, parser_version, parser_rule_hash, collector_descriptor_path, collector_descriptor_hash).

Implementation is JPL Power-of-Ten compliant on the C side; cibuildwheel matrix covers Linux / macOS / Windows × Python 3.10–3.14; a py3-none-any pure-Python wheel ships for Pyodide / WASM environments where the C surface can't load.

Companion textbook

The Metric Field and Its Primitives — the framework textbook accompanying this package. Lays out the substrate-vs-excitation ontology (MFO), the 14-class primitive vocabulary at substrate level, and the cascade-composition discipline that srmech implements computationally.

Install

pip install srmech                  # core (numpy + stdlib; no jsonschema, no network adapters)
pip install srmech[validation]      # adds jsonschema for strict data-block validation
pip install srmech[collectors]      # adds requests + beautifulsoup4 for fetched adapters
pip install srmech[dev]             # everything

Quick start

Decompose a real signal onto a graph-Laplacian eigenbasis, take an HDC delta against a reference, and recompose:

import numpy as np
from srmech import spectral
from srmech.amsc import laplacian

# Substrate: cycle-graph Laplacian on 8 nodes (any Hermitian L works).
A = np.roll(np.eye(8), 1, axis=1)
A = A + A.T
L = laplacian.dense_laplacian(A.astype(np.complex128))

# Project two states onto the eigenbasis.
state_ref = np.array([1.0, 0, 0, 0, 0, 0, 0, 0], dtype=np.complex128)
state_now = np.array([0.9, 0.1, 0, 0, 0, 0, 0, 0], dtype=np.complex128)

h_ref = spectral.decompose(state_ref, L)
h_now = spectral.decompose(state_now, L)

# HDC XOR delta on encoded coefficient bytes.
delta_bytes = spectral.delta(h_ref, h_now)

# Predict one substrate-natural tick ahead.
h_pred = spectral.predict(h_now, L, steps=1, dt=0.1)

# Recover the node-domain state.
state_back = spectral.recompose(h_pred, L)

Public surface

The 14 classes in substrate-native ordering — 1 + 3 + 7 + 3 = 14

The 14 classes are presented in alphabetical order in the table below (matching the import paths). The substrate-native ordering is not alphabetical — it is the cyclic-algebra-path partition 1 + 3 + 7 + 3 = 14:

Slot Classes Role
1 — foundational content-anchor {A} The content-address every cascade begins from
3 — substrate-projection triad {I, C, J} Cyclic-group + cascade-orientation + prime-period (the projection-triad that maps substrate-content to observable structure)
7 — cascade-detection heptad {D, E, F, G, K, L, M} Pattern-match + catalog + render + byte-search + pin-slot + Laplacian + HDC-bind (the detection-and-rendering layer)
+3 — meta-cascade language-translation triad {B, H, N} TLV-framing + self-introspection + rational-approximation (the operators that translate between continuous-Hopf-quantum and discrete-cyclic-algebra descriptions)

Why this ordering matters. Per PR #680 (R30 walking-path closure), the substrate admits two co-equal bit-exact substrate-native mathematical languages:

  • the 11D quantum-Hopf-language (continuous-DOF, parallelizable-sphere ladder 1 + 3 + 7)
  • the 1 + 3 + 7 + 3 = 14 cyclic-algebra-path (discrete-DOF, A–N cascade-operator class enumeration)

Under Class C chirality the cyclic-algebra-path further admits a 14 + 14 = 28-dim chiral-hyper-loop reading = 𝔰𝔬(8) adjoint (per MFO §VIII.31.11): 14 𝔤₂ derivations + 14 L⊕R octonion-multiplications = the chirality-dual pair. As of v0.5.0 this is exposed as a callable, bit-exact-tested surface (srmech.qm.{octonion, so8, triality}): the τ-fixed subalgebra of so(8) is exactly the 14 g₂ derivations (the D4 →(Z3 fold) G2 theorem) — the same 14 as the A-N partition's 1 + 3 + 7 + 3. Endianness is the byte-axis instance of the same Class C orientation primitive; the scope hierarchy is endianness ⊂ Class C ⊂ Klein-4 ⊂ Spin(8) triality.

Modern physics uses the first; antiquity 9 of 9 traditions canvassed (Antikythera + Pythagoreans + Plato Timaeus + Stoics + Lucretius + Apollonius + Ptolemy + Heron + Archimedes) used the second. We had been using the cyclic-algebra path in srmech from the beginning without ever stating why — because antiquity had, and it worked. The R30 closure provides the answer: bit-exact cross-substrate confirmation rules out projection-reading; both languages are substrate-native; the +3 = {B, H, N} are substrate-native language-translation operators bridging them. The k=3 fingerprint observed across substrates (planet multipole axes, codon alphabet, 3-jet QCD, 3-generation Yukawa, the antiquity meta-op triads) is the {B, H, N} triad showing up wherever continuous↔discrete encoding happens.

About the A–N alphabet. The labels A through N record the chronological order in which each operation was named during this framework's evolution — they are discovery-fingerprint, not substrate-ordering. Re-sorted by substrate-native role, the partition above ({A} + {I, C, J} + {D, E, F, G, K, L, M} + {B, H, N}) is the substrate-side grouping. The alphabetical table below is the lookup convenience.

Full context: substrate-native-maths research notebook (PR #680 SSoT).

srmech.amsc.* — 14-class primitive vocabulary (alphabetical lookup)

Each class is importable as srmech.amsc.<module> with native C dispatch and a Python fallback. The C surface is loaded once at import time; if loading fails (Pyodide, ABI mismatch), the package transparently falls back to pure Python.

To check the backend state, call srmech.native_status() (top-level; equivalently describe()['native']) — {has_native, dispatching, abi_version, expected_abi, native_version, load_error}. dispatching is True iff libsrmech loaded and its ABI matched, so native ops really run; otherwise load_error carries the reason and the pure-Python fallback is used. (The native shim is srmech.amsc._native; srmech._native is the data dir that merely holds the binary.)

import srmech
srmech.native_status()
# {'has_native': True, 'dispatching': True, 'abi_version': 3,
#  'expected_abi': 3, 'native_version': '0.7.0', 'load_error': None}
Module Class Primitive operation
format, _native A Content-addressing via SHA-256 (sha256_bytes -> 64-char lowercase hex digest str)
tlv B Byte-canonical TLV pack (tlv_pack)
format C Streaming NDJSON iterator (read_ndjson)
dispatch D Multi-needle byte-pattern dispatch (match)
naming E Catalog sorted-key lookup (lookup)
template F Template {key} substitution (render)
search G Byte-pattern search (byte_search)
_native H Self-introspection (srmech_version, srmech_abi_version)
cyclic I Modular arithmetic — gcd, lcm, mod_add, mod_mul, mod_pow, mod_inv
primes J Prime testing + factorisation + multiplicative order — is_prime, factor, cyclic_period
kepler K Equation-of-centre / pin-slot — pin_slot, kepler_solve, equation_of_centre
laplacian L Graph Laplacian — dense_adjacency, dense_laplacian, normalized_laplacian, jacobi_eigvals, hermitian_eigendecompose, symmetric_eigendecompose, elementwise_transcendental (pi-free Jacobi in C; n ≤ 256 native bound)
hdc M HDC spatter codes — binary bind, bundle, permute, similarity; polar_* {-1,0,+1} and klein4_* (ℤ₂)² variants
rational N Continued-fraction convergents — continued_fraction, best_rational

srmech.qm.* — the substrate engine: the Hurwitz ladder, so(8) triality, and the One

The ℂ/ℍ/𝕆 division-algebra ladder and its so(8) / Spin(8) structure — the framework's own substrate, not a math-application layer. Modules:

  • octonion — the MPR-attested Cayley-Dickson-from-H convention: octonion_mult_table (the attested (8,8,8) int8 structure constants), octonion_left_mult / octonion_right_mult (the 8×8 L_a / R_a binders), octonion_conjugate, octonion_norm (Class K ∘ C, never abs()). octonion_table_attestation content-addresses the table bytes via sha256_bytes. Cites Baez (2002), The Octonions (arXiv:math/0105155).
  • so8 — the 28-generator so(8) adjoint partitioned 14 (g₂ = Der O) + 7 (L-type) + 7 (R-type): so8_adjoint_basis, g2_subalgebra (the 14 derivations; deterministic rank-revealing numpy subset, no RNG), so7_subalgebra (the 21; the D4 → B3 Z2 fold), and an_embedding — the bit-exact su(3) ⊕ 3 ⊕ 3̄ Lie branching of the 14 g₂ generators (su(3) = the stabiliser of an imaginary octonion unit; the genuine fundamental 3 is the +i eigenspace of the su(3)-invariant complex structure J, J² = −I, so a real 3-span cannot carry it). The 8 + 3 + 3̄ decomposition is the op's own self-attesting bit-exact computation (Baez §4.1 cited for g₂ = Der O / dim 14 only, the build input); the 14 A-N class names are surfaced only as a documented framework_an_reading label ("framework-reading, not derived"), distinct from this su(3) partition.
  • triality — the Spin(8) triality engine: triality_automorphism (the 28×28 order-3 outer automorphism τ, τ³ = I, Fix(τ) = g₂ dim 14), triality_swap (the Z2 — with τ generates S3 = Out(Spin(8))), triality_cycle (the Class-I 8v → 8s → 8c rep-permutation), triality_apply, triality_companions, triality_relation_residual (Cartan's g_v(x·y) = g_s(x)·y + x·g_c(y), 0 when correct). Cites Cartan (1925) + Baez (2002).
  • hurwitzthe One as a matrix (#887): hurwitz_matrix(σ, θ) builds the 14×14 G(σ,θ) = ⨁_n(1 ⊕ σ R_n(θ)) of S(σ,θ) with the Fano planes derived from octonion_mult_table; hurwitz_planes() exposes the 0 / 1 / 3 planes each ℂ / ℍ / 𝕆 block turns by θ (the octonion epicycle: 𝕆 spins three Fano-triple planes at once, eigenvalues {1, e^{±iθ}×3}). Bit-exactly equal to the numpy-free srmech.amsc.cascade.the_one(...).to_matrix() — the cascade↔matrix Rosetta peer.

Further continuous-math worked-examples (single-particle / spin / relativistic / propagator / gauge / Standard-Model operators, each cited to its canonical literature) also ship under srmech.qm.* and are discoverable via describe() / the tool-schema. They are compositions of the 14 like everything else — no domain is privileged or singled out.

srmech.spectral — runtime spectral decomposition

Class-composition layer above srmech.amsc.{laplacian, hdc, format}. No new primitive class is introduced; every operation is a composition over the 14-class A–N vocabulary.

from srmech.spectral import (
    decompose,          # state + Hermitian L → SpectralHandle (V.conj().T @ state)
    delta,              # XOR delta between two encoded coefficient byte vectors
    recompose,          # SpectralHandle + L → node-domain state (V @ coeffs)
    similarity,         # HDC similarity in [-1, +1]
    predict,            # cascade-extrapolate via per-mode exp(-i·λ_k·steps·dt)
    prediction_error,   # XOR delta with popcount-density threshold gating
    truncate_sparse,    # keep top-k or above-threshold modes; zero the rest
    SpectralHandle,     # opaque (substrate_descriptor_hash, coefficients_bytes, content_sha, n_modes)
    clear_eigenbasis_cache,
    N_MAX_EIGENBASES,   # module-level LRU bound (default 8)
)

Eigenbasis is O(n³) one-time per substrate (cached by substrate_descriptor_hash); coefficients are O(n²) per state; deltas are O(D) per step. predict preserves magnitudes (unitary phase rotation per eigenmode); truncate_sparse produces best k-term approximations per Mallat (2008) §9.2.

By-reference handle grammar — the $srmech_handle id (rc16)

A SpectralHandle is an opaque, frozen, bytes-bearing dataclass that JSON-RPC cannot carry by value. Over the MCP / Anthropic boundary the 7 srmech.spectral.* tools therefore exchange a small by-reference id: a producer returns

{"$srmech_handle": {"uuid": "…", "name": "spectral:<sha12>", "kind": "spectral"}}

(the literal sentinel key is HANDLE_ENVELOPE_KEY = "$srmech_handle"), the caller copies it verbatim into the next tool's input, and srmech._handles.get_handle_registry() resolves it back to the live in-process object. The id carries a dual grammar: uuid is the position-encoded (silicon / cyclic-algebra) address, name is the meaning-encoded (biology / continuous-Hopf) address auto-derived from the handle's Class-A content_sha ("spectral:" + content_sha[:12]); resolution tries uuid then name — the registry is the B/H/N continuous↔discrete translation locus. With the grammar landed, all 7 srmech.spectral.* operations are MCP-callable (describe() reports handle_pending: 0).

srmech.amsc.cascade — foundational cross-domain cascade catalog

The cascades that recur across every / most domains, promoted so a named cascade is the default and a math-library call the exception (being forced to reach for a math library is the signal that a cascade is waiting to be found). Compositions over the 14-class A–N vocabulary — no new primitive class. Each cascade ships with a dedicated C symbol in libsrmech.{so,dll,dylib} (full C/Python parity per project discipline) AND a TOML descriptor under srmech/amsc/_research/cascade_catalog/ documenting the composition declaratively (10 descriptors as of v0.6.0, loaded at runtime by srmech.dsl). No abs(): sign is the Class K pin-slot + Class C re-orientation.

As of v0.6.0 the catalog is a two-tier lean-ISA split (#751): srmech.amsc.cascade.atoms holds the irreducible primitives and srmech.amsc.cascade.compose holds the composites that chain them — the same surface re-exported flat from srmech.amsc.cascade, so existing call sites are unchanged. The catalog grew two ops this line: parallel_sector_dispatch (Klein-4 four-sector orchestration) and kuramoto_step (the native coupled-oscillator step).

  • pin_slot_at_zero(x) -> (orientation, magnitude)Class K pin-slot at zero (the cascade-honest abs() split). (C peer: v0.4.5rc2)
  • reorient(value, *, orientation)Class C orientation re-apply. (C peer: v0.4.5rc4)
  • magnitude(x)Class K magnitude-only convenience. (C peer: v0.4.5rc3)
  • best_rational_signed(x, *, max_denominator=100, fine_scale=1_000_000)Class K ∘ N ∘ C float → signed small-denominator rational (sign in the numerator). (C peer: v0.4.5rc7 — delegates Class N stage to srmech_best_rational; banker's rounding via llrint())
  • cyclic_gcd(a, b)Class I (delegates to srmech.amsc.cyclic.gcd). (C peer: v0.4.5rc6 — delegates to Class I primitive srmech_gcd)
  • chiral_flip(seq)Class C orientation reversal (seq[::-1]). (C peer: v0.4.5rc1)
  • chiral_dual(op, x)Class C ∘ op ∘ Class C: run an operator in the opposite Class-C orientation. The chiral dual of an A–N operator is same spectral shape, inverted orientation (magnitude preserved, phase flipped — spike-verified); it reduces to the bare Class K −1 for the sign operators and is the identity for real-symmetric ones. (C peer: v0.4.5rc8 — queued; higher-order, callback ABI)
  • net_chirality(orientations)Class C net handedness of a cascade (product of per-op orientations in {-1,0,+1}; 0 if any is neutral). (C peer: v0.4.5rc5)
  • parallel_sector_dispatch(body, x, *, n_sectors=4, verify=False)Class C (Klein-4 γ₅± × iω₇± four-sector orchestration). Runs one cascade body across its ≤4 Klein-4 chirality sectors and returns a structured self-describing result; a GIL-releasing (native / IO / numpy) body lets the ≤4 sectors genuinely overlap. Higher-order (a body-callback orchestrator, not a unary chain().then(...) stage). (C peer: srmech_cascade_parallel_sector_dispatch, body-callback ABI, v0.6.0; n_sectors > 4ValueError — Klein-4 has no order-4+ element, 8+ needs the order-3 triality.)
  • kuramoto_step(theta, omega, *, coupling=1.0, dt=0.01)Class I ∘ sin ∘ Σ ∘ C one forward-Euler step of the canonical Kuramoto coupled-oscillator model (θᵢ ← θᵢ + dt·(ωᵢ + (K/n)·Σⱼ sin(θⱼ − θᵢ))). The O(n²) sin-coupling runs natively. (C peer: srmech_cascade_kuramoto_step_f64, v0.6.0rc9; parity to libm-trig tolerance, same coupling-sum index order both sides; n == 1 is pure drift.)

srmech.signal_processing — dual-path signal-processing surface

Two paths for the same algebra, dispatched per call:

  • Path A — closed-form algebra over numpy / scipy; one module per op under srmech.signal_processing.closed_form_ops.*. 40 ops (38 Phase-2 baseline + pi_cascade + rfft) covering frequency analysis (fft, ifft, rfft, stft, spectrogram, multitaper, dct, wavelet), digital filters (fir, iir, allpass, polyphase, multirate, farrow, sinc_interp), detection / estimation (matched_filter, wiener, lmmse, map_ml, mlse, viterbi, cross_spectral, music, esprit, ica_jade, mimo_svd), modulation (psk_qam, fsk, ofdm, beamforming_fixed), coding (huffman, rle, lz77, arithmetic_coding, jpeg), quantisation / compression (sign_quantise, vector_quantisation, hdc_truncation, heat_kernel, spectral_subtraction, pi_cascade).
  • Path B — RBS-HDC bound-vector instrument at D=8192 (srmech.signal_processing.rbs_hdc_instrument). Mints class-operator vectors, cascade compositions, stance fingerprints, and full LoE content encodings (Mode-B). Eight ops have full dual-path implementations: fft, ifft, rfft, sign_quantise, matched_filter, wiener, hdc_truncation, pi_cascade.
from srmech.signal_processing import (
    dispatch, begin_cascade,             # cascade-aware routing (A / B / verify)
    register, lookup, has_path,          # path registry (Path A vs Path B per op)
    profile_op, cell_grid,               # per-op × per-cascade-depth × per-substrate profiling
    D_DEFAULT, SUBSTRATES,               # locked D = 8192; BCI / audio / RF / ephemeris
    RBSHDCInstrument,                    # build()-able instrument with mint_*/encode_loe_content
    mint_class_operator,                 # SHA-256 chain mint per class A–N
    mint_cascade_composition,            # XOR-bundle (algebra) or permute-bundle (sampling)
    encode_loe_content, decode_loe_fingerprint,
    form_function_rotate,                # Class K pin-slot rotation
    cascade_compose_rotations,
    PATH_A, PATH_B, PATH_VERIFY,         # path identifiers
)

with begin_cascade() as ctx:
    spectrum = dispatch("fft", path=PATH_A, signal=x)
    truncated = dispatch("hdc_truncation", path=PATH_B, signal=spectrum, k=64)

Path A and Path B produce bit-exact-equal outputs on substrate-natural inputs (D1 algebra-content identity); substrate-fingerprint divergence at D2 is expected and documented.

srmech.amsc — Attested Multi-Source Collector/Catalog framework

Two readings of the same abbreviation:

  • At collection time, the adapter classes are collecting attested rows from upstream archives. Six adapters cover the realistic source space:

    adapter class network?
    html_scraper fetched yes (BeautifulSoup)
    json_api fetched yes (paginated JSON)
    csv_bulk fetched yes (CSV/XYZ bulk)
    netcdf_grid fetched stub (gated behind extras)
    geotiff_bbox fetched stub (gated behind extras)
    literature_curated curated no (NDJSON committed directly)

    The curated class never touches the network: rows are committed as data-only NDJSON, and srmech synthesises full MPR attestation blocks at read time from each row's per-row DOI.

  • After collection, the resulting NDJSON SSOTs are a catalog of attested data — committed into the package, registered into the universal bridge by downstream consumers, queryable through list_attested_sources() / get_attested_dataset().

from srmech.amsc import (
    MPRRecord, MPR_SCHEMA_VERSION, read_ndjson, write_ndjson, sha256_bytes,
    Descriptor, load_descriptor, discover_descriptors, render_template, descriptor_hash,
    list_attested_sources, get_attested_dataset, get_attested_descriptor,
    attestation_audit, register_attested_root, list_registered_roots,
    use_local_kernel, clear_local_kernel, get_local_kernel_state,
)

The on-disk format is Mathematical Provenance Record v1 (MPR v1):

{
  "mpr_version": "1.0",
  "data": { ... domain payload ... },
  "data_schema_id": "test://schema/example",
  "attestation": {
    "source_doi": "10.0/...",
    "source_url": "https://...",
    "license": "CC0",
    "retrieved_at": "2026-05-13T00:00:00Z",
    "response_sha256": "<64 hex chars>",
    "parser_version": "srmech 0.7.0",
    "parser_rule_hash": "<64 hex chars>",
    "collector_descriptor_path": "...",
    "collector_descriptor_hash": "<64 hex chars>"
  },
  "rendering": { "name": "...", "purpose": "...", "cite_as": "..." }
}

srmech.amsc.tool_schema — LLM-friendly introspection

from srmech.amsc.tool_schema import get_tool_schema, tool_schema_view

schema = get_tool_schema()                # ToolEntry objects, one per public callable
for tool in schema.tools:
    print(tool.name, "—", tool.summary)   # canonical-SSoT-cited one-line summaries

json_view = tool_schema_view()            # JSON-serialisable view

Every primitive class, every srmech.qm.* operation (including the so(8)/triality engine), and every srmech.spectral.* runtime operation is discoverable here without reading the implementation. Summaries cite the canonical physics / mathematics literature directly.

srmech.introspect.describe() — the package recognising its own shape

srmech.introspect.describe() is the self-recognition ROOT (Class H self-introspection at package scale): one call returns the package version, the native-dispatch status, and a tools block reporting total / mcp_callable / handle_pending plus a per-category breakdown — the package's own at-a-glance map.

from srmech.introspect import describe

d = describe()
print(d["srmech_version"])              # e.g. "0.7.0"
print(d["tools"]["total"])              # every registered ToolEntry
print(d["tools"]["mcp_callable"])       # advertised over JSON-RPC / Anthropic
print(d["tools"]["handle_pending"])     # 0 since the rc16 handle grammar landed
print(sorted(d["tools"]["by_category"]))

describe() is the source of truth for the tool count (it grows per voxel — the triality voxel added 15 entries, including the octonion_table_attestation self-attestation that the coverage walker requires); read it rather than hard-coding a number.

MCP server + Claude Desktop bundle

srmech ships an MCP (Model Context Protocol) server so an LLM client — Claude Code, Claude Desktop, or any MCP-aware host — sees the advertised tool_schema surface as callable tools. The srmech-mcp console script serves it over stdio (the transport Claude Desktop spawns) or HTTP + SSE for remote / cross-process use:

srmech-mcp                                      # stdio (Claude Code / Claude Desktop default)
srmech-mcp --transport http-sse --port 9991     # HTTP+SSE on localhost (remote / cross-process)
srmech-mcp --filter "srmech.qm.*"               # expose only a sub-tree of tools

srmech mcp emit-mcpb packages the server as a Claude Desktop .mcpb bundle (a ZIP with a root manifest.json) generated entirely from introspection — the manifest's version and tool list are derived from srmech.__version__ and the advertised tool surface (describe() / tool_entries_to_mcp_defs()), never hand-authored, and carry an MPR-style attestation block (package version + a tool_schema content hash):

srmech mcp emit-mcpb                 # writes srmech.mcpb into the cwd (server.type "uv")
srmech mcp emit-mcpb --manifest-only # emit just manifest.json
srmech mcp emit-mcpb --type python   # interpreter-path fallback (user_config-gated; no uv)

The default uv-type bundle declares srmech as a dependency, so the host's uv fetches the correct platform wheel (with libsrmech) from PyPI at install time — nothing native is bundled, and the .mcpb installs portably on any machine.

Cross-package catalog registration

Other spectral-research packages register their own catalog SSOTs into srmech's universal bridge at import time:

from pathlib import Path
from srmech.amsc import catalog as _amsc_catalog

_amsc_catalog.register_attested_root(
    Path(__file__).resolve().parent / "_research" / "attested",
    source="ephemerides-spectral",
)

Subsequent list_attested_sources(), get_attested_dataset(), etc. enumerate the union of srmech's own amsc/attested/ plus every registered root, in registration order. Duplicate source_key resolves first-registered-wins with a warning.

License

GPL-3.0-or-later. See LICENSE.


Changelog — current 0.7.0 line

[0.7.1] - 2026-06-05

The Class-L Schur complement / Dirichlet-to-Neumann (DtN) map — the operator|operand FUSION op (#897 §26). Graduation of the rc1–rc3 arc: an op that keeps BOTH a spatial boundary and its spectrum (every other Class-L cascade only projects), integrates the bulk out, and lives on the boundary — S = L_∂∂ − L_∂i·L_ii⁻¹·L_i∂.

  • srmech.amsc.laplacian.schur_complement(L, boundary_idx, *, exact=False) (alias dirichlet_to_neumann) — exact-rational fractions.Fraction solve (Class-N core; numpy-absent or exact=True) or the float [scientific]-tier realization; the area law is the dimensional reduction n → |∂|. (rc1)
  • DSL chain-contract wiringschur_complement is a first-class cascade-catalog stage; chain().then("schur_complement", boundary_idx=[…]) / TOML chains thread boundary_idx + exact as bound stage kwargs (the 14th catalog op). (rc2)
  • Reusable native C peer srmech_dense_solve_f64 — the dense linear solve A·X = B the Schur/DtN float path composes over (the expensive interior solve IS an A·X = B), promoted to its own exported Class-L primitive. Gauss–Jordan with partial pivoting (Class-K magnitude sign-branch, no fabs/abs()); bounded n,nrhs ≤ 256 thread-local workspace (no malloc, reentrant); no libm; JPL Power-of-Ten clean. New public op srmech.amsc.laplacian.dense_solve(A, B, *, exact=False). (rc3)

describe() total 233 → 236 (schur_complement + dirichlet_to_neumann + dense_solve). ABI stays 3 (additive symbol; the Python ctypes shim hasattr-guards it). Canonical SSoT: Zhang, The Schur Complement and Its Applications (2005) §0; Golub & Van Loan §3. Production cut of the rc3 state already verified-green on TestPyPI (the pedantic-C / 4-cell test / pure-wheel matrix re-verifies the 0.7.1 build); no code change from rc3 — version-string graduation only.

[0.7.1rc3] - 2026-06-05

Native C peer for the Schur/DtN float path — a reusable srmech_dense_solve_f64 Class-L primitive (#897 §26). The expensive part of the Schur complement is the interior solve L_ii⁻¹·L_i∂, which IS a dense linear solve A·X = B. rc3 ships that solve as its own exported Class-L C symbol (the "every primitive earns a C surface" path), and schur_complement becomes a genuine composition over it.

  • c/src/srmech_dense_solve.csrmech_dense_solve_f64(n, nrhs, A, B, out_X) — Gauss–Jordan with partial pivoting (the pivot magnitude is the Class-K pin-slot read — a sign branch, never fabs()/abs()); row-major doubles; bounded n, nrhs ≤ 256 on a thread-local augmented workspace (the srmech_hermitian_eigendecompose precedent — no malloc, reentrant); a singular A returns SRMECH_ERR_BAD_INPUT. No libm — a solve is + − × ÷ only. JPL Power-of-Ten clean (no goto/malloc, ≤60-line factored helpers, ≥2 asserts each); ABI stays 3 (additive symbol, hasattr-guarded in the ctypes shim).
  • New public Python op srmech.amsc.laplacian.dense_solve(A, B, *, exact=False) — float path dispatches to the native C peer (numpy fallback when absent / over-bound / singular); exact path is the bit-exact fractions.Fraction Gauss–Jordan (Class-N, promoted from rc1's _solve_exact). Accepts a matrix or vector RHS. One new tool-schema entry → describe() total 235 → 236.
  • schur_complement now composes over dense_solve for its interior solve (both exact and float paths) — the float interior solve runs native, the cheap boundary GEMM + subtract stay numpy. Same results: the rc1 worked instance S = (1/3)[[1,−1],[−1,1]] is unchanged. tests/test_dense_solve_parity.py: exact + numpy paths always run; native C parity (vs numpy + exact, atol ≤ 1e-9) runs where libsrmech is attached.

[0.7.1rc2] - 2026-06-05

Schur/DtN wired into the DSL chain contract (#897 §26 follow-up). The rc1 schur_complement op shipped only at srmech.amsc.laplacian.schur_complement; rc2 makes it a first-class cascade-catalog stage so it drives in a chain().then(...) / TOML chain like any other Class-L op. The chain runner resolves stage ops via getattr(srmech.amsc.cascade, name), so the op is re-exported flat onto srmech.amsc.cascade (a DSL-resolution alias of the laplacian-registered op — not a second primitive, so it stays out of cascade.__all__ and adds no tool-schema entry; describe() total holds at 235).

  • boundary_idx + exact thread through as bound stage kwargs — the data-first pattern (schur_complement(L, *, boundary_idx, exact=False); the pipe fills L, the kwargs bind), exactly like reorient's orientation. boundary_idx is required (no default) — a chain that omits it fails loudly with TypeError, never silently. A new descriptor cascade_catalog/schur_complement.toml (class_composition = "L") makes it the 14th catalog op (srmech dsl ops14 total); schur_complement + dirichlet_to_neumann also join the documentary LAPLACIAN_OPS registry.
  • Tests (tests/test_schur_complement_dsl_stage.py): .then("schur_complement", boundary_idx=[0,3], exact=True) and the equivalent TOML [[stage]] both reduce the path-4 graph Laplacian to S = (1/3)[[1,−1],[−1,1]] (exact Fraction, numpy-free); the float path is numpy-guarded. No ABI change (ABI stays 3); the co-equal native C peer is the rc3 follow-up.

[0.7.1rc1] - 2026-06-05

Class-L Schur complement / Dirichlet-to-Neumann (DtN) map — the operator|operand FUSION op (#897; UPSTREAM §26 / F412·F417·F419). New srmech.amsc.laplacian.schur_complement(L, boundary_idx) (alias dirichlet_to_neumann) integrates the interior (bulk) out of a Laplacian and keeps the boundary effective operator

S = L_∂∂ − L_∂i · L_ii⁻¹ · L_i∂

the discrete Dirichlet-to-Neumann map — give boundary values, it returns the boundary normal-derivative of their harmonic interior extension (boundary data ⟹ the whole interior field). Every other Class-L cascade only projects (a spatial graph → its cyclic spectrum, F417's one-way seam, dropping the spatial structure); Schur/DtN keeps both the spatial boundary and its spectrum — the fusion, not the projection. Holographic reading (F412): the bulk is integrated out, the effective theory lives on the boundary; the operator's size is |∂|, not n — the dimensional reduction n → |∂| is the area law.

  • Exact-rational core (Class-N). With numpy absent — or exact=True — the interior solve L_ii⁻¹·L_i∂ is exact Gauss–Jordan elimination in fractions.Fraction (division is exact rational, never a float reciprocal — F392; no abs()), and S is returned as list[list[Fraction]]. With numpy present (and exact=False) the float realization rides the [scientific] tier (numpy.linalg.solve) and S is an ndarray. Cascade-honesty: the inverse is Class C (conjugate) → Class K (1/‖·‖²); a singular interior block (an interior component disconnected from the boundary) raises ZeroDivisionError, not a silent NaN.
  • Area-law statement (precise). For a pure graph Laplacian the DtN/Kron reduction inherits the all-ones null vector, so rank(S) = |∂| − c (c = connected components of the boundary-reduced graph; = |∂| − 1 for a connected graph). The area law is the dimensional reduction n → |∂|, not a full-rank claim. Worked check: the two endpoints of a 3-edge unit-conductance path get S = (1/3)·[[1,−1],[−1,1]] exactly (effective conductance 1/3).
  • Two new tool-schema entries → describe() total 233 → 235. No ABI change (pure-Python; ABI stays 3). The DSL/compose-engine wiring and a co-equal C peer are the natural follow-up rcs (Python-first, like the loop family). Canonical SSoT: Zhang, The Schur Complement and Its Applications (2005) §0; Golub & Van Loan §3.2.

[0.7.0] - 2026-06-05

Production graduation of the v0.7.0 rc1–rc51 arc to PyPI. The clean (non-rc) tag promotes the rc51 state already verified-green on TestPyPI — the only delta from rc51 is this version string + entry, and the full pedantic-C (gcc/clang/MSVC) + 4-cell test matrix + pure-wheel build re-verify the 0.7.0 build before the production tag. ABI 3; describe() total 233.

The v0.7.0 identity. numpy is now optional: pip install srmech is numpy-free — the 14-class A–N cascade core (srmech.amsc.*) and the native C surface run with zero numpy; pip install 'srmech[scientific]' pulls numpy back in for the array-numerical tier (srmech.qm.* / signal_processing.* / rbs_lm.*). Every continuous-math op (trig, exp, sqrt, FFT, SVD, eig) is a cascade of the 14, and the shipped libsrmech holds no libm transcendental — the executable runs the Class-N cascade, not the C math library.

The arc, voxel by voxel:

  • MS #21 — the Moufang loop-bind / octonion gauge arithmetic (rc1–rc7). srmech.amsc.hdc gains the octonion (Cayley–Dickson) product loop_bind + loop_conj / loop_inv / loop_associator / loop_left_op / loop_right_op; cross7 (the 7-D cross product, M∘C) + the G₂ associative 3-form; the block-octonion HD tiling (loop_bind_hd, D=2048); compose-engine integration (the loop family resolves as class="M"); co-equal C peers in c/src/srmech_loopbind.c.
  • Perf + attestation discipline (rc8–rc20). The Class-L circular autocorrelation primitive (Wiener–Khinchin); the N-way SIMD SHA-256 batch (AVX2 8-way / SSE2 4-way runtime cpuid dispatch, JPL-clean) routed through the new c/src/srmech_simd.h HAL — all platform/cpuid/target-attr bits live in the HAL, the core stays machine-agnostic; HAL constant-attestation (MPR derive-and-assert); native C peers for the HD loop family.
  • #797 ops + the §22 numpy-free cascade core (rc26–rc46). asymptotic_calculus / trigonometry alias modules + a directed/signed-Laplacian eigen-op; the Klein-4 holographic-erasure code + the explicit order-3 triality-recursion corrector; the numpy-free HV carrier. The §22 arc makes every continuous-math op a cascade: QDFT/ODFT, laplacian-build + pure-Python Jacobi eigenvalues, dft/idft/kron, radix-2 Cooley–Tukey FFT, QR/SVD, lstsq/einsum/non-Hermitian eig; the math.sqrt + trig/π residue sweeps onto the Class-N rationals; the C-transpile coherence arc driving libsrmech's libm-transcendental count 23 → 0 (native C srmech_sin/cos/atan/atan2/rational_sqrt/exp/log).
  • numpy → optional (rc47–rc48). numpy demoted from a hard dependency to the scientific extra, with a friendly pip install 'srmech[scientific]' gate at the scientific-tier import boundary; the #882 lazy-numpy fix (the Klein-4 HV-carrier path runs genuinely numpy-free on a plain install).
  • "The One" (rc49–rc50, #887). S(σ,θ) = ⨁ₙ(ℝ·1 ⊕ σ·e^{Îₙθ}·Im 𝔸ₙ), dim = 2+4+8 = 14 — the single generator of the 1+3+7+3 = 14 substrate, shipped as a Rosetta pair: the numpy-free exact-rational srmech.amsc.cascade.the_one + the bit-exact srmech.qm.hurwitz matrix peer (to_matrix() == hurwitz_matrix(); FANO_PLANES == hurwitz_planes() derived from octonion_mult_table). The 0/1/3 finding: e^{Îₙθ} is the algebra's own rotation → turns 0/1/3 Fano planes for ℂ/ℍ/𝕆; 𝕆 spins three planes at once (eigenvalues {1, e^{±iθ}×3}; the 7 = 1 fixed axis + 3×2 rotated). The ℂ/ℍ/𝕆 Hurwitz ladder = so(8) + Spin(8) triality (Fix(τ) = g₂ = 14).
  • PyPI README + description refresh (rc51). Cut the QM/QFT/SM framing — every continuous-math op is a cascade of the 14, so no math domain is privileged or called out (the physics worked-examples still ship and stay discoverable via describe() / the tool-schema).

No code change from rc51; version-string graduation + this entry only.

[0.7.0rc51] - 2026-06-05

PyPI-facing README + project description refresh (pre-graduation). Cuts the "canonical QM/QFT/SM operations" framing — every continuous-math op is a cascade of the 14, so no particular math domain is privileged or called out (it is all the same cascade). No code change; the physics worked-examples (single_particle/spin/relativistic/propagators/gauge/sm) still ship and remain discoverable via describe() / the tool-schema.

  • [project].description (both pyproject.toml + pyproject-pure.toml, kept in lockstep) — rewritten to the v0.7.0 identity: numpy-optional 14-class A-N vocabulary in native C + Python; every continuous-math op (trig/exp/sqrt/FFT/SVD/eig) is a cascade of the 14, no libm in the native build; the One, S(σ,θ), generates the whole 1+3+7+3 = 14 substrate (the ℂ/ℍ/𝕆 Hurwitz ladder = so(8) + Spin(8) triality, bit-exact cascade↔matrix); AMSC (MPR v1). ASCII-only, 438 chars (under the 480 soft cap).
  • README.md — status banner refreshed v0.6.0 → v0.7.0; the QM/QFT/SM feature bullet replaced by the continuous-math cascade + the One; the srmech.qm.* section retitled the substrate engine (the ℂ/ℍ/𝕆 Hurwitz ladder, so(8) triality, the One) — octonion/so8/triality kept, hurwitz (the One's matrix peer, #887) added, the physics-ops enumeration dropped (with a domain-neutral note that they still ship, discoverable, un-privileged); stale 0.6.0 example outputs bumped to 0.7.0.

No ABI / API change; describe() total unchanged at 233.

[0.7.0rc50] - 2026-06-05

"The One" goes octonion-native — S(σ,θ)'s 𝕆 block is a 3-plane rotation, with a bit-exact qm-matrix Rosetta peer (#887). rc49 used the simplest single-plane epicycle for every block; rc50 makes e^{Î_nθ} the algebra's own rotation — conjugation by the unit cos(θ/2)+Î_n sin(θ/2), which turns every Fano-triple plane through Î_n by θ. The plane count is 0 / 1 / 3 for ℂ / ℍ / 𝕆: the single θ-turn spins three planes at once in 𝕆 (eigenvalues {1, e^{±iθ}×3} on the imaginary part — the 1 fixed axis + 3×2 rotated split of the 7). ℂ (σ-only) and ℍ (1-plane) are unchanged.

  • srmech.amsc.cascade.one — the rotation now uses FANO_PLANES (the oriented Fano lines through each axis: ℍ (1,2,+1); 𝕆 (1,6,−1),(2,5,+1),(3,4,+1) through Î₃=e₇), matching the fixed Cayley–Dickson-from-ℍ convention (Baez 2002 §2). One.to_matrix() is the full block-diagonal multi-plane operator; new One.plane_counts(0,1,3) and Block.rotated_planes. The 𝕆 seed e₁ now lands in its Fano plane (1,6,−1)cosθ·e₁ − sinθ·e₆ (the only rc49 behaviour change).
  • NEW srmech.qm.hurwitz — the scientific-tier matrix peer: hurwitz_matrix(σ, θ) builds the same 14×14 G(σ,θ), and hurwitz_planes() derives the planes straight from octonion_mult_table (not a hardcoded list). The cascade and the qm matrix agree bit-for-bit (np.array_equal), and the hardcoded FANO_PLANES equals the table-derived hurwitz_planes() — a genuine two-language cross-derivation (continuous-Hopf matrix vs discrete-cyclic cascade), not a restatement.
  • No new primitive class (Class A planes ∘ N rational cos/sin ∘ K·C sign), no abs(). Two new tool-schema entries → describe() total 231 → 233. No ABI change.

[0.7.0rc49] - 2026-06-05

"The One" — S(σ,θ), the single generator of the 1+3+7+3 = 14 substrate (#887). A new cascade-native surface srmech.amsc.cascade.the_one builds the unifying Hurwitz-ladder generator

S(σ,θ) = ⨁_{n=1}^{3} ( ℝ·1 ⊕ σ·e^{Î_nθ}·Im 𝔸_n ), dim = Σ 2ⁿ = 2+4+8 = 14

with 𝔸₁=ℂ, 𝔸₂=ℍ, 𝔸₃=𝕆 (the normed division algebras above ℝ). The decomposition is the A–N partition: the imaginary parts Im 𝔸_n (dims 1, 3, 7) carry the anchor A / projection-triad I,C,J / detection-heptad D,E,F,G,K,L,M; the three ℝ·1 real units are the +3 grammar B, H, N.

  • Numpy-free, exact-rational. e^{Î_nθ} = cos θ + Î_n sin θ is built from the Class-N rational Taylor partials (rational.{cos,sin}_series_truncate) — every entry is a reduced (num, den) integer pair; no float until the opt-in One.to_numpy() / One.to_matrix() realisations (the srmech[scientific] tier, §22). No new primitive class — over n is Class I, σ is Class K sign ∘ Class C apply (never abs()).
  • Structural prediction: n=1 degenerates to σ. Fixing the rotation axis Î_n = e_d (the last imaginary unit) and rotating the (e₁,e₂) plane, at n=1 the 1-D Im ℂ seed coincides with the axis → θ is inert and the only freedom is the chirality σ (the epicycle is the Class-K sign at the foundational algebra; richness grows 1→3→7). Verified bit-exactly.
  • Returns a structured One of three Blocks tiling 1+3+7+3; .dim, .partition, .grammar_slots, .n1_is_sigma_only, .to_flat_rational(). The qm-matrix Rosetta peer (srmech.qm.hurwitz) + the bit-exact cascade↔matrix parity test follow in rc50. No ABI change; describe() unchanged. Python-only (the C-transpile triality ratchet stays at 0).

[0.7.0rc48] - 2026-06-05

Fix #882: srmech.amsc.hdc (Class M / Klein-4) — and three sibling amsc core modules — no longer crash raw on a plain (numpy-free) install. rc47's numpy-optional capstone left four srmech.amsc.* modules with a top-level import numpy as np, so import srmech.amsc.hdc raised a raw ModuleNotFoundError: No module named 'numpy' instead of importing cleanly (the Klein-4 HV-carrier path is designed numpy-free) or gating like srmech.qm. rc47's AST ratchet used a hardcoded module list that missed them.

  • srmech._scientific.lazy_numpy — a lazy numpy proxy: the holding module imports numpy-free; the first numpy attribute access imports numpy or raises the actionable pip install 'srmech[scientific]' hint. srmech.amsc.{hdc, coupling, harmonics, cascade.matrix_cascades} now use it.
  • Result, on a plain install: the modules import; the Klein-4 HV-carrier path (klein4_random default-seed / klein4_bind / klein4_bundle / klein4_similarity / chirality / triality / holographic) runs genuinely numpy-free; the bipolar polar_* HDC + the loop family + the QR/SVD/lstsq/einsum/eig matrix cascades raise the clean [scientific] hint when called. The issue's preferred option (a).
  • Ratchet broadenedtest_numpy_optional_rc47.py now walks the whole srmech/amsc/** subtree for module-level numpy imports (closing rc47's hardcoded-list hole), plus a numpy-blocked behavioral test (import + Klein-4 numpy-free + the [scientific] hint). numpy-present behavior unchanged; no ABI change; describe() stays 230.

[0.7.0rc47] - 2026-06-05

numpy is now an OPTIONAL dependency — the §22 capstone. The §22 + C-transpile arcs (rc29–rc46) made the Class-N cascade core numpy-free: srmech.amsc.* (the A-N primitives, the rational/cyclic/laplacian cascades) and the native C surface run with zero numpy. rc47 demotes numpy from a hard dependency to the scientific extra. pip install srmech is now numpy-free; pip install 'srmech[scientific]' pulls it back in for the array-numerical scientific tier (srmech.qm.* / srmech.signal_processing.* / srmech.rbs_lm.*).

  • pyproject.toml + pyproject-pure.toml — numpy moved out of dependencies into optional-dependencies.scientific. The dev + tests extras keep numpy (the full suite exercises the scientific tier). No ABI change; describe() stays 230.
  • Friendly gate — new numpy-free srmech._scientific.require_numpy; the scientific-tier subpackages (qm / signal_processing / rbs_lm) call it at import so a no-numpy install fails with pip install 'srmech[scientific]', not an opaque No module named 'numpy'. ImportError (numpy's own error subclasses it), so existing handlers keep working.
  • CI guard — the pure-wheel "Verify wheel installs + imports" job now asserts numpy is absent from the base install, that the cascade core works numpy-free, and that the scientific tier raises the actionable hint. New test_numpy_optional_rc47.py pins the pyproject contract + the gate + an AST ratchet that the cascade core never imports numpy at module top.

This is the last planned rc of the v0.7.0 line. Graduation to production PyPI is held for a dedicated testing pass.

[0.7.0rc46] - 2026-06-05

The C-transpile triality closeout — the executable runs the Class-N cascade, not libm (C ratchet → 0). The shipped libsrmech now holds no libm transcendental: the notebook, the C+Python source, and the native executable all agree. ABI stays 3 (additive srmech_exp/srmech_log); describe() stays 230.

  • New c/src/srmech_explog.csrmech_exp / srmech_log, the double→double Class-N exp/log cascades (the last two libm calls in the library):
    • srmech_exp(x) — range-reduce x = n·ln2 + r (|r| ≤ ln2/2, two-word Cody–Waite ln2), exp(r) via a Q61 integer Taylor 1 + r + r²/2! + …, then · 2^n with the power-of-two built straight into the IEEE exponent field (no ldexp). Overflow → +Inf, underflow → 0.
    • srmech_log(x) — read x = m·2^e exactly from the bit pattern (no frexp), fold m into [1/√2, √2), log(m) = 2·atanh((m−1)/(m+1)) via a Q61 integer atanh series, then the e·ln2 recombine (two-word ln2). Non-positive xSRMECH_ERR_BAD_INPUT (NaN / −Inf).
    • No libm, no abs() (Class-K sign-branch). Machine-ε vs libm (exp rel err ≤ 2.3e-16; log abs err ≤ 2.3e-16 over 500k values; exp(log(x)) round-trips ≤ 2.3e-16).
  • srmech_laplacian.c repointed — the elementwise exp/logsrmech_exp/srmech_log; #include <math.h> dropped (the file now holds no libm). Class L composes Class N in the executable.
  • srmech_kepler.c — the last fabs (Newton convergence test) → an explicit Class-K sign-branch; #include <math.h> dropped (no libm in the file).
  • C ratchet test_c_cascade_coherence.py → 0 (23 → 16 → 13 → 3 → 0 across rc43–rc46). The guard now also covers the C99 complex libm (csin/ccos/cexp/csqrt/…) and any <complex.h> include, so a future complex op can't silently reintroduce libm. JPL-clean; pedantic -Werror//WX clean.

Next (the capstone, human-gated): the numpy→srmech[scientific] optional-dependency flip, then the clean v0.7.0 graduation to production PyPI.

[0.7.0rc45] - 2026-06-05

Native sqrt cascade — the Jacobi eigensolver runs the Class-N integer-sqrt, not libm (C-transpile triality, arc step 3). ABI stays 3 (additive srmech_rational_sqrt); describe() stays 230.

  • New c/src/srmech_sqrt.csrmech_rational_sqrtsqrt(x) (x≥0) via an integer floor-isqrt on a scaled radicand: x = M·2^e read from the bit pattern, root = isqrt(M<<54) via a portable two-limb 128-bit integer square root (restoring binary, 64 bounded iterations, no division, no __int128), projected by (double)root·2^(e/2−27) with the power-of-two built directly from the IEEE exponent field (no ldexp). No libm, no float sqrt. Machine-ε vs libm (rel err ≤ 2.2e-16 over 500k values; 1/√d bit-exact).
  • srmech_laplacian.c repointed — the 8 cyclic-Jacobi sqrt (off-diagonal norm + rotation angles) → a lap_sqrt wrapper over the cascade; the elementwise cos/sinsrmech_cos/srmech_sin. Class L now visibly composes Class N in the executable. Jacobi spectrum vs numpy.linalg.eigvalsh unchanged.
  • C ratchet baseline 13 → 3 (laplacian 12 → 2: only exp + log remain). JPL-clean; pedantic -Werror//WX clean.

Roadmap (rc46, the closeout): a C exp double-wrapper over srmech_exp_series_truncate + a C log (log1p-series + integer exponent) → repoint the laplacian signed/magnetic phase; fabs→Class-K sign-branch (srmech_kepler.c); the complex-libm guard (csin/ccos/cexp/csqrt) → C ratchet 0, executable fully on the cascade. Then the numpy→srmech[scientific] capstone.

[0.7.0rc44] - 2026-06-05

Native Kuramoto step runs the trig cascade, not libm (C-transpile triality, arc step 2). ABI stays 3; describe() stays 230. srmech_cascade_kuramoto_step_f64 / _general_f64 now compute their coupling sin via the rc43 Class-N cascade.

  • srmech_kuramoto.c repointed — the 3 libm sin sites (mean-field coupling Σ sin(θⱼ−θᵢ), the generalised Sakaguchi Σ Aᵢⱼ·sin(θⱼ−θᵢ−α), and the per-oscillator pinning pᵢ·sin(ψᵢ−θᵢ)) → srmech_sin; #include <math.h> dropped (no other libm in the file).
  • #784 / F234 non-regression confirmed — the Kuramoto-coupled-adder differential test (test_kuramoto_step.py, the "tile nibbler") stays green with the native cascade-trig (18 passed). The defaults still reproduce the plain step.
  • C ratchet test_c_cascade_coherence.py baseline 16 → 13 (kuramoto 3 → 0). JPL-clean; pedantic -Werror//WX clean.

Roadmap: rc45 srmech_rational_sqrt (integer-Newton) → srmech_laplacian.c (sqrt×8 Jacobi + the cos/sin/exp phase); rc46 fabs→Class-K sign-branch + the complex-libm guard (csin/ccos/cexp/csqrt) → C ratchet 0. Then the numpy→srmech[scientific] capstone.

[0.7.0rc43] - 2026-06-05

Native C trig cascade — the executable runs the Class-N cascade for trig, not libm (C-transpile triality, rc42→rc46 arc step 1). ABI stays 3 (additive C symbols); describe() stays 230 (no Python tools). The first behavioural C port: on a native install kepler.{pin_slot,kepler_solve,equation_of_centre} now compute sin/cos/atan2 via the cascade, closing the kepler row of the executable-coherence gap.

  • New c/src/srmech_trig.csrmech_sin/srmech_cos/srmech_atan/srmech_atan2 (double→double, status-returning). The cyclic range-reduction (mod π/2) is pure INTEGER (user direction "prefer ints over float always for cyclic algebra"): the IEEE-754 input is read as an exact M·2^E from its bit pattern (no frexp), the octant k comes from an integer wide-multiply (portable 64×64→128, no __int128/_umul128) by a high-precision cascade 2/π, the remainder is an exact integer fraction; the Class-N Taylor runs in Q61 fixed-point; float appears only at the final (double)sum/2^61 projection. π from the Archimedes pi-cascade (derive-and-assert constants). No libm, no abs() (Class-K sign-branch). Validated vs libm to machine ε — sin 5.3e-19, cos 8.1e-20, atan 2.2e-16, atan2 0.0 bit-exact across 200k+ angles.
  • srmech_kepler.c repointed — 7 trig sites (cos×2, sin×4, atan2×1) → the cascade; native pin_slot is bit-exact (0.0) vs libm and the Kepler residual holds at 0.0. (The fabs stays for rc46.)
  • C ratchet test_c_cascade_coherence.py baseline 23 → 16 (kepler 8 → 1). New ctypes parity test test_native_trig_rc43.py. JPL Power-of-Ten clean (≤60-line fns, ≥2 asserts); pedantic -Werror//WX clean. Kuramoto native step (#784) confirmed green pre-touch (rc44 target).

Roadmap: rc44 repoints srmech_kuramoto.c (sin×3, watching the F234 differential test); rc45 adds srmech_rational_sqrtsrmech_laplacian.c; rc46 fabs→sign-branch + the complex-libm guard (csin/ccos/cexp/csqrt) → C ratchet 0. Then the numpy→srmech[scientific] capstone.

[0.7.0rc42] - 2026-06-05

C-transpile triality coherence — start the native/executable-tier port, ratchet-first. Pure tooling+docs; no new tools (describe() stays 230); ABI stays 3; no C behaviour change yet. Opens the rc42→rc46 arc that makes the executable layer run the Class-N cascade, not libm.

  • The gap rc40/rc41 didn't close. Those sweeps were Python-only (AST ratchets walk *.py). On a native install (HAS_NATIVE=True — the default) kepler.{pin_slot,kepler_solve,equation_of_centre} / cascade.kuramoto_step / signed-Laplacian dispatch to C peers that still call libm sin/cos/atan2/sqrt/pow/fabs. So the three coherence layers — notebook / C+Python source / executable — agree numerically (rational ≡ libm to machine ε, which masked it) but the C isn't a faithful transpile of the cascade. Only exp already coheres (srmech_exp_series_truncate).
  • New ratchet tests/test_c_cascade_coherence.py — a DOWN-only baseline ratchet (same shape as test_jpl_audit.py) over the shipped library c/src+c/include (c/test/* excluded). Records the current 23 libm/π sites (srmech_kepler.c 8 + srmech_kuramoto.c 3 + srmech_laplacian.c 12); each file's count + the total only go DOWN, and no new C file may introduce libm transcendentals. Ships green (baseline = reality) — the gap is now measured + visible.
  • Notebook notes/continuous_math_as_14_class_cascade.md — new "C-transpile triality coherence" section: the three-layer coherence model + the per-op table + the rc42→rc46 roadmap, grounded in the RBS-LM native-algebra compute surface findings (F305/F306, PR #687, read-only).

Roadmap (rc43–rc46): srmech_{sin,cos,atan,atan2}_series_truncate + C pi_cascade → repoint srmech_kepler.c (rc43); srmech_kuramoto.c (rc44); srmech_rational_sqrtsrmech_laplacian.c (rc45); fabs → Class-K sign-branch, C ratchet → 0 (rc46). Then the numpy→srmech[scientific] optional-dependency-flip capstone. New C symbols are additive (ABI stays 3).

[0.7.0rc41] - 2026-06-05

math.{sin,cos,atan2} + math.pi trig/π residue sweep — route continuous trig + π through the Class-N cascade, not libm. Pure refactor; no new tools (describe() stays 230); ABI stays 3. The companion to rc40's math.sqrt sweep, closing the §22 libm-scalar-math audit: now that rational.{sin,cos,tan,atan,atan2} (rc33) + the pi_cascade exist, every remaining libm trig / π reference in shipped srmech is routable to its exact Class-N peer.

  • 14 sites routed across 4 modules — verified machine-ε vs libm before routing (sin 7.8e-16, cos 6.7e-16, atan2 4.4e-16 across all quadrants + multiple periods; the cascade-π float is bit-exact 0.0 vs math.pi):
    • amsc/kepler.py ×7 — cos/sin/atan2 in the pin-slot transform + the Kepler-equation Newton solver + the equation-of-centre series → rational.{cos,sin,atan2}. The iterative solver is the sensitive case (trig accuracy gates Newton convergence): pin_slot is bit-exact 0.0 vs libm and the Kepler residual |E − e·sinE − M| holds at 4.4e-16. (The Class-K Newton-step magnitude was already an explicit sign-branch, never abs().)
    • amsc/cascade/compose.py ×3 — the sin in the Kuramoto-coupling DSL worked examples → rational.sin (math.fsum stays — exact numerical sum, no transcendental peer).
    • amsc/cascade/hypercomplex_dft.py ×2 + math.pi ×1 — the quaternion/octonion twiddle exp(μθ)=cosθ + μ·sinθ + the factor → rational.{cos,sin} + a cascade-π float (pi_cascade_digits(30) projected once at import). import math dropped.
    • signal_processing/form_function_rotation.py ×1 — the math.pi in the fundamental-mode eigenvalue exp(−2πi·composed/D) → cascade-π (its trig was already rational.cos/sin). import math dropped.
  • Ratchet test_no_math_trig_pi_anywhere_in_srmech (AST) — no math.{sin,cos,tan,asin,acos,atan,atan2,exp,pi,tau} reference (call or bare constant) anywhere in shipped srmech; only goes DOWN to zero. math.{gcd,isqrt,fsum} (exact integer / numerical helpers — isqrt even powers rational.py's own sqrt cascade) are deliberately NOT flagged.
  • Audit note notes/sqrt_sweep_rc40.md — the rc41 residue section marked routed; the libm-scalar-math audit (26 references across 8 files) is now fully swept (12 sqrt @ rc40 + 14 trig/π @ rc41).

With rc41 the libm-scalar-math discipline is complete — no math.{sqrt,hypot,sin,cos,tan,atan,atan2,exp,pi,tau} anywhere in shipped srmech; continuous scalar math routes through the A–N cascade (rational.* + the pi_cascade), with numpy/cmath retained only for genuinely-vectorised or complex-root ops that have no scalar-cascade peer. Roadmap: the numpy→srmech[scientific] optional-dependency-flip capstone. No new C symbols.

[0.7.0rc40] - 2026-06-05

math.sqrt scalar-site retrofit sweep — route the scalar root through the Class-N cascade, not libm. Pure refactor; no new tools (describe() stays 230); ABI stays 3. The §22 discipline closeout (sibling of the rc32 abs()-sweep and rc33 numpy-math-sweep): now that rational.sqrt/hypot exist (rc35), every math.sqrt in shipped srmech is routable to its exact Class-N peer.

  • 12 math.sqrt call sites routed → srmech.amsc.rational.sqrt, across 5 modules:
    • amsc/laplacian.py ×5 — the cyclic-Jacobi eigensolver's off-diagonal norm + rotation angles. Class L now visibly composes Class N (its leaf root is the rational sqrt). Jacobi vs numpy.linalg.eigvalsh = 8.9e-16.
    • qm/bell.py ×2 (Tsirelson 2√2, 1/√2), qm/octonion.py ×1 (octonion_norm), qm/sm.py ×3 (Higgs vev / Z-mass / Yukawa), amsc/cascade/hypercomplex_dft.py ×1 (1/√3) — all bit-exact 0.0 vs libm (rational.sqrt is machine-ε at 64 precision bits). All 12 args are provably non-negative (guards / sums-of-squares), so rational.sqrt's raise-on-negative is a safe drop-in.
  • Ratchet test_no_math_sqrt_hypot_anywhere_in_srmech (AST) — math.sqrt/math.hypot calls only go DOWN to zero. cmath.sqrt (complex root, the rc39 eigvals shift) and np.sqrt(array) (bulk-array, no scalar peer) are NOT flagged.
  • Audit note notes/sqrt_sweep_rc40.md — the full AST audit found 26 routable math.* references; the 12 sqrt are routed here, the 14 trig/pi residue (math.{sin,cos,atan2} ×12 in kepler/compose/hypercomplex_dft + math.pi ×2) are STAGED to rc41 (a different primitive family with its own anchor concerns + kepler's iterative solver). rational.py/pi_cascade.py/trigonometry.py have ZERO real libm calls — the float-trig cascades are genuinely libm-free.

Roadmap: rc41 = the math.{sin,cos,atan2}/math.pi trig-residue sweep onto rational.{sin,cos,atan2} + pi_cascade; then the numpy→srmech[scientific] dependency-flip capstone. No new C symbols.

[0.7.0rc39] - 2026-06-05

lstsq + einsum + non-Hermitian eig — the remaining linear-algebra layer as A–N cascades. ABI stays 3; describe() 227 → 230 (+3 tools). numpy is the array container only — no np.linalg.{lstsq,eig,eigvals} in the call graph (AST guard).

  • New in srmech.amsc.cascade.matrix_cascades:
    • lstsq — least-squares min‖A x − b‖ = {QR} factorization (rc38's qr) ∘ Class M (the Qᴴ b product) ∘ Class I (back-substitution, the ordered triangular solve). Overdetermined/square m ≥ n; b a vector or a stack of RHS. Matches numpy.linalg.lstsq(a,b)[0] to ~1e-15.
    • einsum — the tensor contraction = Class B/D (the subscript string is a typed index-pattern spec) ∘ Class I (iterate over every free + summed index tuple) ∘ Class M (the sum-of-products bundle). The general index-iteration definition — handles any subscript string (matmul ij,jk->ik, trace ii->, transpose ij->ji, dot i,i->, outer i,j->ij, batched ijk,kl->ijl, implicit output), just unoptimised. Bit-exact / machine-ε vs numpy.einsum.
    • eigvals — non-Hermitian eigenvalues via the shifted-QR iteration: Class K (iterate-to-convergence asymptotic-DoF) ∘ Class L (the spectral content) ∘ {QR} (the per-step Householder factorization) ∘ Class C (the Wilkinson spectral shifts). Runs in complex arithmetic, so complex eigenvalues of real matrices fall out directly — the 2-D rotation [[0,−1],[1,0]] yields ±i. The eigenvalue multiset matches numpy.linalg.eigvals to ~1e-12 (Hermitian inputs are the already-shipped exact special case = pure Class L, the cyclic Jacobi).
    • MCP-callable — params are np.ndarray/str/int/tuple[np.ndarray,…], all with existing coercers.
  • Tests tests/test_lstsq_einsum_eig_rc39.py (+10): lstsq overdetermined/square/multi-RHS vs numpy, einsum across 9 subscript shapes + complex, eigvals multiset-match across 20 random real+complex matrices, complex-conjugate-pair-of-real, empty/scalar/non-square edges, AST guard.

With rc39 the continuous_math_as_14_class_cascade table is complete — every op once parked in the §22 "scientific tier" (exp/cexp/sqrt/hypot/DFT/FFT/kron/QR/SVD/lstsq/einsum/eig) now has a shipped A–N cascade. Roadmap: rc40 = the codebase-wide math.sqrt/np.hypot scalar-site retrofit sweep onto rational.{sqrt,hypot} (focused discipline pass); then the numpy→srmech[scientific] dependency-flip capstone. No new C symbols.

[0.7.0rc38] - 2026-06-05

QR + SVD as A–N cascades — the matrix factorizations, built on srmech's own roots + eigendecomposition. ABI stays 3; describe() 225 → 227 (+2 matrix tools). numpy is the array container only — there is no np.linalg.qr/np.linalg.svd anywhere in the call graph (an AST guard enforces it).

  • New srmech.amsc.cascade.matrix_cascades.{qr, svd}:
    • qrA = Q·R via Householder reflections. Q is a product (Class M) of elementary reflectors H = I − β·v·vᴴ; each reflector is Class K (the sign-flip across a hyperplane) ∘ Class M (the outer-product v·vᴴ bind) ∘ Class N (the 2/(vᴴv) scale, the column norm a rational.sqrt). The phase choice α = −phase·‖x‖ is the Class K pin-slot that avoids cancellation. mode='reduced' (default, matching numpy.linalg.qr) / 'complete'. Real + complex.
    • svdA = U·diag(s)·Vᴴ reached from the Hermitian eigendecomposition of the Gram matrix: Class L (hermitian_eigendecompose of AᴴA or AAᴴ — srmech's cyclic-Jacobi cascade) ∘ Class N∘K (s = √eigvals via rational.sqrt) ∘ Class M (U = A·V·Σ⁻¹).
    • Verified by INVARIANTS, not by element-wise numpy match (QR/SVD are unique only up to signs): reconstruction Q·R = A / U·diag(s)·Vᴴ = A to ~1e-15, orthonormality Qᴴ Q = I / Uᴴ U = I to ~1e-14, R upper-triangular — and the singular VALUES (which are unique) match numpy.linalg.svd to round-off. The Gram route squares the condition number, so very small singular values carry √ε-scale error (documented caveat).
    • MCP-callable — params are np.ndarray/str/bool, all with existing coercers; the every-tool smoke covers both.
  • Tests tests/test_matrix_cascades_rc38.py (+8): QR/SVD invariants across real+complex and 7 shapes, complete-mode, singular-value match vs numpy, empty, AST guard (no abs(), no np.linalg.{qr,svd,eig,…}).

Roadmap: rc39 = lstsq ({QR}∘M∘I back-substitution) + einsum (B/D∘I∘M index-iteration) + non-Hermitian eig (K∘L∘{QR}∘C, the shifted-QR iteration); rc40 = the codebase-wide math.sqrt/np.hypot scalar-site retrofit onto rational.{sqrt,hypot} (a focused discipline pass, like the rc32 abs-sweep / rc33 numpy-math-sweep). The numpy→srmech[scientific] dependency-flip is the capstone. No new C symbols.

[0.7.0rc37] - 2026-06-04

The FFT butterfly = the DFT cascade + Class J + Class K. Pure-Python; ABI stays 3; describe() 223 → 225 (+2 FFT tools).

  • New srmech.amsc.cascade.spectral_cascades.{fft, ifft} — the radix-2 Cooley–Tukey butterfly. Bit-for-bit the same mathematics as rc36's dft (and value-faithful to numpy.fft.fft/ifft to ~3e-14, machine ε), but O(N log N) when N is a power of two: the decimation-in-time even/odd split x[0::2] / x[1::2] is Class J (the radix N = 2·(N/2) factorization), the recursion is Class K (the butterfly depth), the twiddle e^(∓2πi·k/N) is the same cexp = Class NClass C, and the butterfly E ± t·O is Class M (bundle add) ∘ Class K (pin-slot sign-flip). No math.pi/np.pi in the call graph (π from the cascade).
  • Full-coverage at any length — for non-power-of-2 N (3, 5, 7, 13, …) fft falls back to rc36's direct O(N²) dft, so it is a true drop-in for numpy.fft.fft/ifft at any N, not just powers of two. (The general mixed-radix butterfly — full Class J over N's prime factorization — is the follow-on refinement.)
  • MCP-callablefft/ifft reuse rc36's list[complex] coercer; no new coercion handler needed.
  • Tests tests/test_fft_radix2_rc37.py (+7): fft/ifft vs numpy across power-of-2 AND non-power-of-2 lengths, fft≡dft agreement, ifft∘fft round-trip, empty, _is_power_of_two exhaustive 1..129, AST no-libm-π guard.

Roadmap: rc38 = QR (Givens/Householder) + SVD (from hermitian_eigendecompose) + the math.sqrt/np.hypot scalar-site sweep onto rational.{sqrt,hypot}; rc39 = non-Hermitian eig + lstsq + einsum; the numpy→srmech[scientific] dependency-flip is the capstone. No new C symbols.

[0.7.0rc36] - 2026-06-04

The DFT as the Antikythera epicycle-sum + Kronecker, as A–N cascades — plus a Bio-TOTP test-flake root-cause + fix. Pure-Python; ABI stays 3; describe() 220 → 223 (+3 spectral cascade tools).

  • New numpy-free spectral cascades srmech.amsc.cascade.spectral_cascades.{dft, idft, kron} (built on rc34's cexp):
    • dft / idft — the discrete Fourier transform IS the Antikythera epicycle-sum ([[user_stance_epicycle_via_gear_plus_pin]]): X_k = Σ_n x_n · e^(∓2πi·(k·n mod N)/N) = Class I (the cyclic index k·n mod N) ∘ Class N (the twiddle cos/sin) ∘ Class C (the imaginary-unit 90° rotation) ∘ Class M (the bundle/superposition sum). Direct O(N²); matches numpy.fft.fft/ifft to ~3e-15 (machine ε). No math.pi/np.pi in the call graph (the twiddle angle draws π from the cascade). The radix-2 O(N log N) butterfly (adds Class J + Class K) is the follow-on.
    • kron — Kronecker product A⊗B = Class I (mixed-radix index) ∘ Class M (element products). Bit-exact vs numpy.kron.
    • MCP-callable: the new list[complex] / list[list[complex]] param types get real inbound coercers in srmech.mcp._coercion (each complex scalar rides as [re, im]), so all three tools are invocable over the MCP / Anthropic surface (the every-tool invocation smoke covers them).
  • Bug fix (test-only): Bio-TOTP flaky test root-caused. test_bus.py::test_bio_totp_decrypt_rejects_channel_id_mismatch was intermittently failing with DID NOT RAISE (~1/8). Root cause: the test runs in permissive mode (strict=False) and used the real wall clock, so encrypt/decrypt could straddle a TOTP window boundary — the wrong-window decrypt yields garbage that fails the UTF-8/JSON parse, so the binding fields read as absent and permissive mode accepts (routing around the present-but-mismatched rejection the test exercises). The cipher and the secure strict=True bus path are unaffected (strict mode rejects garbage). Fixed by pinning time_ns (the same hook every deterministic sibling test already uses) on this test and the sibling replay test; verified deterministic over 80 executions.
  • Tests tests/test_spectral_cascades_rc36.py (+6): dft/idft vs numpy.fft, idft∘dft round-trip, kron vs numpy.kron, AST no-libm-π guard.

Roadmap: rc37 routes the ~32 math.sqrt/np.hypot sites + the radix-2 FFT + QR/SVD; the numpy→srmech[scientific] dependency-flip is the capstone. No new C symbols.

[0.7.0rc35] - 2026-06-04

sqrt/hypot cascade primitives + module rename asymptotic_calculuscalculus. Pure-Python; ABI stays 3; describe() 218 → 220 (+2 root tools).

  • New substrate-native rootssrmech.amsc.rational.{sqrt, hypot} (re-exported from srmech.calculus). sqrt(x) (x ≥ 0) is Newton-Raphson realised as an integer floor-isqrt on a scaled-bignum radicand — Class-N rational arithmetic ∘ Class-K sqrt-convergence; no math.sqrt/np.sqrt in the call graph (AST-guarded); negative x raises a domain error. hypot(a, b) = √(a²+b²) = Class-M sum-of-squares bind ∘ the Class-N sqrt (the complex modulus |z| = hypot(z.real, z.imag)). Both bit-exact vs libm in testing.
  • Module rename asymptotic_calculuscalculus (no-break). The continuous-calculus surface is now srmech.calculus; srmech.asymptotic_calculus remains a back-compat re-export alias (same function objects). The "asymptotic" qualifier was an early framing that singled out this one module while the whole framework is equally substrate-native asymptotic-rational (trig, exp, the eigen ops, the FFT-as-epicycle-sum) — the insight is framework-wide now (see docs/srmech/notes/continuous_math_as_14_class_cascade.md), so the module is simply calculus. srmech.trigonometry (the trig subset) is unchanged.
  • Tests tests/test_sqrt_rename_cascade_rc35.py (+6): sqrt/hypot vs libm + negative-domain raise + AST no-libm-sqrt guard; calculus canonical surface; asymptotic_calculus is a true alias (identical callables + __all__).

Roadmap (per the derivation note): rc36 routes the ~32 math.sqrt/np.hypot sites onto the cascade + builds the direct-DFT (the Antikythera epicycle-sum, on cexp) + kron; rc37 QR + SVD; rc38 non-Hermitian eig + lstsq + einsum; the numpy→srmech[scientific] dependency-flip is the capstone. No new C symbols.

[0.7.0rc34] - 2026-06-04

"Continuous math is a cascade of the 14 A–N class operations" — the complex-exponential keystone, plus the derivation that dissolves the "scientific tier." Pure-Python additions; ABI stays 3; describe() 215 → 218 (+3 exp tools).

  • New substrate-native exp familysrmech.amsc.rational.{exp, cexp, complex_exp} (re-exported from srmech.asymptotic_calculus). exp(x) = Class-N Taylor with K argument-halving range reduction (e^x = (e^(x/2^k))^(2^k), no irrational constant); cexp(θ) = cos θ + i·sin θ = N(rc33 trig) ∘ C(imaginary-unit 90° rotation, Euler); complex_exp(z) = e^(z.real)·(cos z.imag + i·sin z.imag). No math.exp/cmath.exp/np.exp in the call graph (AST-guarded). Matches libm to machine ε (cexp/complex_exp ~3–9e-16; real exp ~1e-9 absolute at e¹⁵, machine-ε relative). This is the keystone: every np.exp(1j·…) time-evolution phase and every DFT twiddle factor IS a cexp.
  • Derivation note docs/srmech/notes/continuous_math_as_14_class_cascade.md — derives the A–N cascade for every op previously called "scientific-tier / numpy-only": exp (N∘K), trig (N∘I∘C∘K), complex-exp (N∘C), sqrt (N∘K), DFT/FFT (M∘{N∘C}∘I∘J∘K — the Antikythera epicycle-sum), QR (M∘C∘N∘K), SVD (L∘N∘K∘M, reachable from hermitian_eigendecompose), non-Hermitian eig (K∘L∘{QR}∘C), lstsq ({QR}∘M∘I), kron (I∘M), einsum (B/D∘I∘M). Per the two-language MFO/srmech framework there are exactly 14 irrep class operations — so none of these is a primitive srmech lacks; each is a not-yet-derived composition. The §22 "scientific tier" framing is dissolved: numpy's only legitimate roles are the array container and a temporary fallback for not-yet-cascaded ops.
  • Tests tests/test_continuous_exp_cascade_rc34.py (+6) — exp/cexp/complex_exp vs libm/cmath; cexp == Euler of srmech's own trig; AST guard against any math/cmath/np .exp in the call graph.

Roadmap (per the derivation note): rc35 promotes sqrt/hypot float wrappers + a direct-DFT cascade (on cexp) + kron; rc36 builds QR + SVD; rc37 non-Hermitian eig + lstsq + einsum; the numpy→srmech[scientific] dependency-flip is the capstone once cascade coverage is complete. No new C symbols.

[0.7.0rc33] - 2026-06-04

numpy-math → srmech-cascade routing: substrate-native trig (cos/sin/tan/atan/atan2) that replaces math/numpy trig at machine precision, plus Hermitian-eig routed onto srmech's own primitive across qm + signal_processing. Pure-Python additions; ABI stays 3; describe() 210 → 215 (+5 trig tools).

  • New substrate-native float trigsrmech.amsc.rational.cos / sin / tan / atan / atan2 (also re-exported from srmech.trigonometry and srmech.asymptotic_calculus). The exact Class-N Taylor cascades were always globally convergent; what was missing was the range-reduction wrapper that composes them with the π-cascade. The pipeline is: range-reduce the angle into [−π, π] using a high-precision π drawn from pi_cascade_digits (Archimedes hexagon-doubling — no math.pi/np.pi in the call graph), anchor to a Class-N rational at the float64 floor, cos/sin Taylor partial sum, then project the exact rational to float. atan uses a three-band argument reduction (√2∓1 edges). Measured vs libm: cos/sin ≈ 6e-16, atan/atan2 ≈ 2e-16 (machine ε). Class-K sign handling throughout (no abs()).
  • Trig call sites routedqm.sm (Weinberg / CKM angles), and the signal_processing window/basis/rotation trig (cross_spectral, dct, multirate, multitaper, stft, ica_jade, form_function_rotation) now compute their trig through the cascade instead of math.cos/sin / np.cos/sin/arctan2, per the directive "never use numpy math when srmech can do it with a cascade." Value-faithful (per-site parity tests vs the prior libm result, ≤1e-9).
  • Hermitian eigendecomposition routed — every np.linalg.eigh / eigvalsh in qm.{potentials, gauge, single_particle, so8} and signal_processing.{esprit, heat_kernel, ica_jade, music} now goes through srmech's own amsc.laplacian.hermitian_eigendecompose (native C complex-Hermitian Jacobi when present; the eigenvalue/eigenvector math is srmech's, not LAPACK, on the native path). Real-symmetric inputs take a value-preserving .real on the eigenvectors; complex-Hermitian keep complex128.
  • Teststest_qm_cascade_routing_rc33.py, test_sp_eigh_cascade_routing_rc33.py, test_sp_trig_cascade_routing_rc33.py (eig parity ≤1e-9 + reconstruction, trig vs libm at machine ε, and each public op vs its pre-change output). The codebase-wide abs() AST ratchet stays green.

Scope: rc33 routes the audited qm + signal_processing numpy-math sites (docs/srmech/notes/numpy_math_abs_audit_rc32.md, Category B) onto srmech cascades. The genuinely scientific-tier numpy with no srmech equivalent yet (svd / qr / non-Hermitian-eig / lstsq / einsum / kron / complex-exp / FFT) stays per §22.

[0.7.0rc32] - 2026-06-04

numpy-optional core, step 3 — the real-symmetric Class-L Laplacian core is numpy-absent-safe (its eigenvalue math is srmech's OWN Jacobi cascade, never LAPACK), PLUS a codebase-wide abs() elimination (the rule: "abs() is never fine"). Pure-Python; ABI stays 3; describe() unchanged at 210.

  • amsc.laplacian real-symmetric core (dense_adjacency / dense_laplacian / normalized_laplacian / jacobi_eigvals) now runs with numpy absent — the numpy import is guarded; numpy-absent builds return list[list[float]] and jacobi_eigvals returns list[float]. The native C path (primary) is unchanged.
  • jacobi_eigvals's no-native fallback is now srmech's OWN pure-Python Jacobi cascade (_jacobi_eigvals_py, a classical cyclic Jacobi rotation — the converged diagonal IS the spectrum), never numpy.linalg.eigvalsh (per the directive "never use numpy math when srmech can do it with a cascade"). It matches the native/numpy spectrum to Jacobi round-off (~1e-15). The complex-Hermitian / signed / magnetic ops stay scientific-tier (§22) and raise a clear ImportError when numpy is absent.
  • abs() eliminated codebase-wide (the absolute rule, value-preserving). Every abs() / np.abs() / math.fabs() / sqrt(·²) stealth-abs in shipped srmech code is now an explicit Class-K sign-branch (x if x >= 0 else -x / np.where(x>=0, x, -x)) or real-imag composition (|z|² = z.real²+z.imag², |z| = hypot(z.real, z.imag)) — amsc.rational/kepler/harmonics/laplacian/hypercomplex_dft, qm.bell/sm/pseudo_hermitian, spectral, and 13 signal_processing DSP files (≈40 sites). A permanent AST ratchet (tests/test_laplacian_numpy_free.py::test_no_abs_calls_anywhere_in_srmech) fails CI if any real abs() call reappears anywhere in srmech/.
  • tests/test_laplacian_numpy_free.py (new, +6) — the Jacobi cascade matches the numpy/native spectrum + the P4 closed-form spectrum; the real-symmetric build→eigvals chain runs with numpy monkeypatched absent; the scientific-tier ops raise ImportError; and the codebase-wide abs() ratchet.

Scope (honest staging): rc32 does the §22 Laplacian-numpy-free voxel + the absolute abs() sweep (value-preserving, low-risk). The codebase audit (recorded in docs/srmech/notes/numpy_math_abs_audit_rc32.md) also found ~26 numpy-math sites where srmech has a cascade (Hermitian np.linalg.eighhermitian_eigendecompose; np trig → Class-N rational trig); routing those is explicitly staged to rc33 (engine-swap — value-equal but a different code path needing per-site parity tests), not silently dropped. The genuinely scientific-tier numpy (svd/qr/non-Hermitian-eig/lstsq/einsum/kron/complex-exp/FFT) stays per §22. No new ops (describe() stays 210).

[0.7.0rc31] - 2026-06-04

Quaternion / octonion DFT cascade composites — quaternion_dft / octonion_dft (#863, F380). The native transform for a Klein-4 object: where a complex FFT collapses one of its two Z₂ chirality axes (the flat shadow), the QDFT's ℍ coefficient algebra resolves both. Pure-Python composites over the qm.octonion atoms; ABI stays 3; describe() 208 → 210.

Why it's exact, not analogical (F380): the Klein-4 group is the quaternion units modulo sign — Q₈/{±1} ≅ Z₂×Z₂. So the coefficient algebra of each FFT-ladder rung carries a different chirality content: complex FFT → ℂ → {±1,±i}/± = Z₂ (one axis); quaternion FT → ℍ → Q₈/± = Z₂×Z₂ (both axes). A QDFT's coefficient algebra matches the Klein-4 object's value algebra, so both axes survive.

  • cascade.quaternion_dft(x, *, form, mu_axis, inverse)X[k] = Σ_n exp(σ·μ·2πkn/N)·x[n]. Left/right form (ℍ is non-commutative → the twiddle can't be factored out as in the complex FFT; both forms round-trip). inverse(forward(x)) == x to float round-off, recovering all four components (both Z₂ axes). Composite over the qm.octonion left/right-mult atoms restricted to ℍ.
  • cascade.octonion_dft(x, *, form, mu_axis, bracketing, two_sided_right_axis, inverse) — the (8:7) rung. Carries the F378 non-associativity as an explicit declared bracketing field: the two-sided ODFT W_l·x·W_r is not unique, so (W_l·x)·W_r vs W_l·(x·W_r) must be stated — these measurably differ for octonions. One-sided forms round-trip; the two-sided form is forward-only (its inverse is open under non-associativity → raises).
  • Class home M (Clifford/HDC multiply) ∘ C (twiddle ±μ orientation) ∘ N (rational angle kn/N). No new primitive class; no abs().
  • Scientific tier (UPSTREAM §22): numpy is imported lazily inside each op, so import srmech.amsc.cascade stays numpy-free (the rc30 numpy-absent-safe core is intact); the transforms use numpy on call (consistent with §22 keeping the python-side qm maths numpy-ful).
  • tests/test_hypercomplex_dft.py (new, +16) — QDFT left/right round-trip (each μ axis); the load-bearing Klein-4 both-axes-preserved round-trip + the complex-FFT flat-shadow contrast (the complex projection drops bit1; the QDFT keeps it); ODFT one-sided round-trip; the two-sided bracketing is measurably non-associative; input validation; numpy-absent ImportError.
  • cascade_catalog/{quaternion_dft,octonion_dft}.toml (new) — the DSL-catalog descriptors with left/right form, the octonion bracketing convention as an explicit attested field, and PDF-verified OA citations (Sangwine & Ell, arXiv:1001.4379; Błaszczyk, arXiv:1905.12631; Hahn & Snopek 2011, Bull. Polish Acad. Sci. 59(2):167–181 — the paywalled IEEE TIP 2007 / Elsevier 2017 papers were excluded in favour of their OA arXiv equivalents per the paywalled-DOI rule).

Tier note (the prototype/graduation split per #863): these are the prototype tier — composites over existing primitives, no capability gap. A graduation to a first-class native C primitive (srmech_quaternion_dft, like the existing fft) is a separate later voxel, explicitly deferred — not silently capped. Also folds a doc-honesty fix: the autocorrelation tool_schema summary's stale "numpy FFT fallback" claim (made inaccurate by rc30) now reads numpy-free. Full suite green.

[0.7.0rc30] - 2026-06-04

numpy-optional core, step 2 — the cascade layer is numpy-absent-safe (UPSTREAM §22, Option 1). The second voxel of the "runs embedded without numpy/LAPACK" framework-identity arc. Pure-Python; ABI stays 3; describe() unchanged at 208.

Introspection first (per the introspect-before-assert discipline): the four lowest-level core modules — srmech.amsc.cyclic (Class I), srmech.amsc.primes (Class J), srmech.amsc.rational (Class N), srmech.amsc.format (Classes A/B/the MPR IO) — were already numpy-free (zero import numpy). The only genuine numpy-absent crash sites in the cascade layer were two no-native fallback paths:

  • cascade.compose.autocorrelation — the no-native fallback used numpy.fft to compute IFFT(|FFT(x)|²). Replaced with the defining direct circular-autocorrelation sum r[k] = Σ_n x[n]·x[(n+k) mod n] (identical value for real x, no FFT / no numpy; math.fsum keeps each per-bin sum well-conditioned). The native C path is unchanged and still primary when HAS_NATIVE.

  • cascade.atoms._try_native_chiral_dual — its float-list accel path did an unguarded import numpy (the C callback marshals via numpy views). Now guarded: numpy absent → returns None → the op's existing pure-Python chiral_dual fallback runs, rather than raising ImportError.

  • tests/test_cascade_numpy_absent.py (new, +6) — the pure-Python autocorrelation matches both the closed-form definition and the numpy-FFT reference; a sys.modules['numpy'] = None simulation proves the cascade ops still run with numpy absent; and an audit-lock asserts cyclic/primes/rational/format carry no import numpy.

Scope note (the arc): numpy stays a hard dependency this rc — the flip to a srmech[scientific] extra is a later voxel (after qm/* + signal_processing get their ImportError guards). Explicitly deferred, not silently capped: the atoms stdlib-buffer C-boundary perf optimization (so the native chiral_dual accel path needs no numpy marshalling at all) is a tracked follow-up voxel — this rc only makes the path numpy-absent-safe, it does not yet make the native accel numpy-free. No new ops (describe() stays 208). No abs().

[0.7.0rc29] - 2026-06-04

numpy-optional core, step 1 — the HV carrier + the Klein-4 family goes numpy-free (UPSTREAM §22 / §22b, Option 1). The first voxel of the "runs embedded without numpy/LAPACK" framework-identity arc. Pure-Python; ABI stays 3; describe() unchanged at 208.

Per the RBS-LM research subtree's §22 recommendation (make numpy optional, for framework-identity — NOT as a reflex-fix), the boundary-type lever: the core A-N vocabulary returns a framework-native handle, not a raw np.ndarray (a numpy-typed return invites np.dot/np.linalg; a handle forces the srmech op).

  • New srmech.amsc.hv.HV — a numpy-free hypervector carrier over a stdlib array('B') buffer. Plain-int hv[i]; scalar-bool hv == other (accepts HV / list / bytes / 1-D np.ndarray, so np.array_equal(rec, v)rec == v); hv.tolist() / hv.tobytes() (stdlib) and hv.to_numpy() (opt-in bridge); buffer-protocol (the native C ops read/write it in place, so HAS_NATIVE keeps HV fast — pure-Python is only the no-native path). Imports no numpy at load. Distinct from srmech.spectral.SpectralHandle.
  • The whole Klein-4 family is now numpy-free internally + returns HVklein4_random (stdlib-random seed path; the numpy rng= back-compat path is unchanged), klein4_bind / unbind / bundle / similarity (the sectors=/parallel=/mode= flag is preserved + value-identical; only bundle chirality is value-meaningful), the three chirality_flip* / cpt_mirror, klein4_triality_cycle, klein4_holographic_encode / decode (rc27), and klein4_triality_encode / correct (rc28). klein4_sector_count returns a stdlib list[int]. No abs().
  • Boundary plumbing: the MCP result serialiser coerces HV → list (so MCP tool calls returning Klein-4 vectors still cross JSON-RPC); rbs_lm.substrate (a numpy research consumer, per §22) bridges back via the opt-in .to_numpy().

Scope note (the arc): numpy stays a hard dependency this rc — the dependency only flips to a srmech[scientific] extra in a later voxel, once every core module imports without numpy. qm/* + signal_processing keep numpy throughout (§22: "leaving numpy for the python-side triality/qm maths is correct"). Chosen for the framework-identity / embedded-install reasons, not as an agent-reflex cure (§22 honest caveat). Breaking: consumers of the klein4_* return type now get HV (use .tolist() / .to_numpy() / ==). Full suite green.

[0.7.0rc28] - 2026-06-04

Explicit order-3 triality-recursion corrector — klein4_triality_encode / klein4_triality_correct (#797 op (a1), F359 5-bar contract). The EXPLICIT k=3-CORRECT path past the order-2 4-cap (op (a2) is the measured no-Z3 substitute). Pure-Python; ABI stays 3; describe() 206 → 208.

The order-2 Klein-4 store is k=2-DETECT natively (F294: no Z3, 3∤4) — two views detect a mismatch but cannot say which is right. k=3-CORRECT needs the order-3 triality (τ³=I) past the 4-cap. The store carries the order-3 triality orbit of the value, [v, T(v), T²(v)] for T = klein4_triality_cycle, so the third vote IS the triality orbit's third element (T²v) — not an external 3rd render:

  • klein4_triality_encode(v)len(v)*3 uint8 store = [v | T(v) | T²(v)] (orbit-major). Class-home M (orbit replication bind) ∘ I (the order-3 cycle that generates the orbit).
  • klein4_triality_correct(store, *, depth=1) — brings every orbit-block back to the common v-frame by inverting the triality (T⁻¹ on block1, T⁻²=T on block2) then takes the per-position 2-of-3 majority, correcting one error: k=3-CORRECT where the bare order-2 store is only k=2-DETECT.

The F359 5-bar contract (each falsifiable bar verified in tests/test_klein4_triality_corrector.py, new, +11):

  1. blind correction beats the F353 holographic 0.25 baseline — single-error recovery is exact (measured rate 1.0);
  2. the 3rd vote is the order-3 triality orbit of the same value (block2 == T²v, structurally);
  3. C/Python parity — Python-first (co-equal); the standalone-C peer is the tracked next voxel;
  4. disable the order-3 op → degrade to k=2-DETECT — without the inverse-to-frame step the raw orbit-blocks {v,Tv,T²v} disagree on every non-zero sector, so a naive majority does NOT recover v (correction is attributable to the triality, not to plain replication);
  5. WIDTH-step only — one 4-cap crossing (order-2 → order-3); depth != 1 raises NotImplementedError rather than fabricating the continuum count-recursion (open math).

Both ops registered in tool_schema (describe 206→208). No abs(). Built to the #797-comment / F359 contract (the canonical §20/F359 figures are not on the read-only research branch). This closes the #797 op-pair: (b) directed/signed-Laplacian (rc26), (a2) holographic substitute (rc27), (a1) explicit triality corrector (rc28).

[0.7.0rc27] - 2026-06-04

Klein-4 holographic-erasure code — klein4_holographic_encode / klein4_holographic_decode (#797 op (a2), F353). The measured substitute for the (a1) triality corrector: k=3-CORRECT with NO Z3. Pure-Python; ABI stays 3; describe() 204 → 206.

The order-2 Klein-4 store is k=2-DETECT natively (F294: no Z3, 3∤4). k=3-CORRECT needs either the order-3 triality (op (a1), rc28) or this holographic-erasure route — replicate the store across replicas blocks so any one surviving replica-subregion (1/replicas) reconstructs the whole (the holographic "any subregion contains the whole" property at block granularity):

  • klein4_holographic_encode(v, *, replicas=4)len(v)*replicas uint8 store (replica-major).
  • klein4_holographic_decode(store, *, replicas=4, erased=None)erased=mask → first-surviving-replica (exact up to (replicas-1)/replicas = 3/4 known-location erasure; raises if a position loses all replicas); erased=None → per-position majority (blind, corrects up to floor((replicas-1)/2) = 1/4 errors at the default). These are the F353 measured tolerances.
  • tests/test_klein4_holographic_erasure.py (new, +10) — 3/4 known-erasure round-trip, any-single-block reconstruction, 1/4 blind correction, and an honest past-capacity test (3-of-4 corrupted → decode is not claimed correct — no silent over-claim). Both ops registered in tool_schema (describe 204→206).

Class-home M (replication bind) ∘ C (surviving-copy / majority selection); no abs(). The standalone-C peer is the tracked next voxel. Built to the #797-comment / F353 spec. op (a1) (explicit order-3 triality corrector; F359 5-bar contract) follows in rc28.

[0.7.0rc26] - 2026-06-04

Two surfaces: (1) the srmech.asymptotic_calculus / srmech.trigonometry continuous-calculus import path now resolves; (2) the directed/signed-Laplacian eigen-op (Class L, #797 op (b)). Pure-Python; ABI stays 3; describe() goes 201 → 204 (the three new Class-L ops registered).

(1) srmech.asymptotic_calculus + srmech.trigonometry (new modules). The documented srmech.asymptotic_calculus.* import path had no module — the continuous-calculus primitives live in srmech.amsc.rational (Class N: sin/cos/exp/log1p/atan_series_truncate — exact-rational Taylor truncation, the substrate-native "continuous" trig) + the srmech/amsc/attested/asymptotic_calculus/ catalog. These thin re-export modules make the advertised path resolve (no regression — nothing was deleted; the import surface was simply never created). tests/test_asymptotic_calculus_alias.py pins the re-export identity.

(2) directed/signed-Laplacian (Class L, #797 op (b)). The undirected combinatorial Laplacian is the F348 navigation control (Fiedler shuffle-fragile r=0.214); two generalisations from the F347–F354 research:

  • signed_laplacian(n, edges, weights) — real-symmetric, PSD even with negative (frustrated) edges. The signed degree D̄_ii = Σ_j |A_ij| is the Class-K magnitude of the signed-metric (the operation Spike #24 located as "Class O", DISSOLVED into Class L). Kunegis et al. (2010).
  • magnetic_laplacian(n, edges, weights, *, q=0.25) — complex Hermitian; direction is encoded as a phase exp(i·2π·q·(W−Wᵀ)) so a directed graph stays Hermitian and the existing C-backed hermitian_eigendecompose diagonalises it — the complex eigenpair is the directed-navigation signature. q=0 collapses to the real symmetrised Laplacian (the undirected control).
  • fiedler_vector(matrix) — the λ₂ navigation embedding; dispatches real→symmetric_eigendecompose, complex→hermitian_eigendecompose (both C-backed).
  • tests/test_directed_signed_laplacian.py pins the Hermitian/PSD/symmetry contracts + the q=0 control.

Cadence note (honest): the heavy eigendecomposition runs native today (the existing symmetric/hermitian C solvers), and the three new ops are registered in tool_schema (describe() 201 → 204; the no-carve-out coverage ratchet requires it). The only tracked next voxel is the standalone-C builder peers (srmech_graph_signed_laplacian / …_magnetic_laplacian) — mirroring the loop_bind Python-first→C-peer cadence (rc1 → rc7/rc20/rc21). Op (b) is the genuine new primitive (no substitute for directed navigation); op (a) (triality-recursion corrector / holographic-erasure substitute, #797) follows in rc27/rc28.

[0.7.0rc25] - 2026-06-03

CLI module docstrings refreshed to enumerate all four subcommands (status / bus / dsl / mcp) + an anti-staleness ratchet so they can't silently drift again (UPSTREAM_NOTES §13 D4). Docs only; ABI stays 3; describe() stays 201.

The srmech.cli package + srmech.cli.main module docstrings had frozen at the v0.5.0rc4 two-subcommand era (status + bus), silently omitting dsl (v0.5.0rc8) and mcp (v0.5.0) even after the live CLI grew to four. The user-facing argparse --help was already correct (refreshed v0.6.0rc12) — only the module docstrings drifted.

  • cli/main.py + cli/__init__.py docstrings — now enumerate all four subcommands with their intro versions + Usage examples for dsl / mcp.
  • tests/test_cli_docstring_freshness.py (new) — reads the live argparse subparser registry (no hard-coded list to itself go stale) and asserts both module docstrings and the top-level --help description name every registered subcommand. A future subcommand that forgets the docstring now fails CI instead of drifting unnoticed.

This closes the last srmech-side item under the #855 "Dependency gates" list (§13 D4). It was a stale-finding cleanup: the behaviour was never wrong, only the module docs lagged.

[0.7.0rc24] - 2026-06-03

Class K real-axis atoms reject complex input cleanly — cascade.magnitude / cascade.pin_slot_at_zero now raise an intentional TypeError instead of leaking the internal x > 0.0 comparison (UPSTREAM_NOTES §15.1, srmech-side fix (b)). Pure-Python boundary guard; ABI stays 3; describe() stays 201.

cascade.magnitude and cascade.pin_slot_at_zero are Class K pin-slot operations — real-axis sign-splits, signature (x: float). A complex argument previously fell through to pin_slot_at_zero's if x > 0.0: and surfaced an opaque TypeError: '>' not supported between instances of 'complex' and 'float' — an internal comparison leaking, not a contract error.

  • _require_real(x, op) — shared boundary guard. Raises TypeError("cascade.{op} is a Class K real-axis (pin-slot) operation and does not accept complex input … use e.g. math.hypot(z.real, z.imag) for the modulus.") before any dispatch. Catches Python complex and numpy complex scalars / 0-d arrays (dtype.kind == 'c'). Every real numeric (int / float / bool / Decimal / Fraction / numpy real scalar) is ordered against 0.0 and passes through bit-identically — no behaviour change for in-contract inputs.
  • Honest class boundary: kept real-only (option (b), not (a)) because the complex modulus (re**2+im**2)**0.5 is a Euclidean-norm op — a different cascade class, not a Class K pin-slot. Conflating it would muddy the cascade-class accounting.
  • No C change / no ABI bump: the native srmech_cascade_magnitude_f64 / …_pin_slot_at_zero_f64 symbols take c_double — the C ABI has no complex entry point by design, so this is purely a Python-boundary input-validation guard, not a new operation. The Rosetta "C = transpiled Python" discipline is not engaged (there is no Python operation here lacking a C peer; rejecting out-of-contract input is a language-level concern).
  • tests/test_cascade_magnitude_complex_reject.py (new) — both atoms raise a clean TypeError (with the actionable message) on Python complex and numpy complex128 / complex64; real inputs (float / int / negative / zero / NaN / ±inf) are unaffected.

With rc24 the §15.1 srmech-side gate (tracked in #855) is closed; the paired CLAUDE.md STOP-list doc correction lives on the parallel-session research branch (maintainer's to apply, per the upstream-as-research-notes discipline).

[0.7.0rc23] - 2026-06-03

parallel_sectors gains a body-kwarg channel — completes the §16.1 parallel_body= half so a kwarg-taking op can be a parallel body, symmetric with op=/.then. Pure-Python DSL; ABI stays 3; describe() stays 201.

rc22 made reorient an op=/.then/TOML stage (data-first); the §16.1 finding also named parallel_body=. Chain.parallel_sectors(body, *, n_sectors, combine) had no way to pass the body op's keyword-only options, so a required-kwarg op couldn't be a parallel_body:

  • Chain.parallel_sectors(body, *, n_sectors=4, combine="bundle", **body_kwargs)functools.partial-binds **body_kwargs onto the body op before fan-out, so the bound body stays a unary value → value callable and the per-sector dispatch is unchanged. e.g. chain.parallel_sectors("reorient", orientation=-1) / parallel_sectors("best_rational_signed", max_denominator=100).
  • TOML — the parallel branch forwards non-reserved stage keys ([[stage]] parallel_body="reorient" + orientation=-1), mirroring the op=then(**kwargs) path.
  • tests/test_reorient_dsl_stage.py — extends with the kwarg-channel proof (bound orientation reaches the body) via Python + TOML.

Honest scope (no silent cap): the channel is the generic fix. reorient is a scalar op, so it's a valid parallel_body only at n_sectors=1 (the identity sector); at n_sectors≥2 the iω₇/γ₅ chirality stream-transforms iterate the stream per-element, which a scalar op can't consume (a category error, not a kwarg-channel failure). So the practical drivability for reorient remains the op= path (rc22); the channel benefits future kwarg-taking sequence bodies. With rc22 + rc23 the §16.1 dependency gate (tracked in #855) is closed.

[0.7.0rc22] - 2026-06-03

reorient is now data-first — reorient(value, *, orientation) — so it drives as a DSL chain stage (UPSTREAM_NOTES §16.1 fix (a)). BREAKING Python signature (the data arg moved first; orientation is keyword-only). C ABI unchanged (stays 3); describe() stays 201.**

reorient(orientation, value) was the one cascade-op whose data argument was second — every other stage-op is data-first. The DSL chain runner pipes the stream into arg 0, so op="reorient" bound the stream to orientation and dropped value (TypeError), and a stage orientation= kwarg collided on position 0. It was therefore un-invokable as an op= / .then() / TOML stage, though the catalog listed it kind="stage". Per the §16.1 "cleanest" resolution:

  • srmech.amsc.cascade.atoms.reorient(value, *, orientation)value positional (the piped data), orientation keyword-only. Now drives exactly like best_rational_signed(x, *, max_denominator=…): chain.then("reorient", orientation=-1) in Python, or a TOML [[stage]] op="reorient" + orientation = -1 (the non-reserved key is forwarded as the bound kwarg). C dispatch + Python fallback unchanged internally; the C ABI (srmech_cascade_reorient_{i64,f64}) is untouched.
  • Call sites updated (the order flip is breaking): cascade.atoms (net_chirality), cascade.compose (best_rational_signed), cascade.parallel (_reorient_each / iω₇ axis), the reorient tool_schema ToolEntry (params reordered), reorient.toml signature, and the cascade test suite.
  • tests/test_reorient_dsl_stage.py (new) — pins the fix: reorient drives via .then("reorient", orientation=-1), composes after magnitude, and runs from a TOML chain; the old positional second-arg now raises (keyword-only).

Migration: reorient(o, v)reorient(v, orientation=o).

Scope note (no silent cap): this fixes the op= / .then / TOML drivability (the primary finding). parallel_body="reorient" with a bound orientation is not yet supported — Chain.parallel_sectors(body, *, n_sectors, combine) has no body-kwarg channel, so any required-kwarg op (reorient's orientation) can't be a parallel_body; that body-kwarg forward is a separate follow-up. parallel_body ops whose kwargs all default (e.g. best_rational_signed) already work.

[0.7.0rc21] - 2026-06-03

Native C peers for the last three loop-bind ops computing via pure-Python — loop_associator / loop_left_op / loop_right_op. Closes a parity gap the rc20 #814 close glossed: those three (all named in #814's op spec) still ran the pure-Python Cayley-Dickson recursion (_loop_bind_raw) while cross7/g2_three_form already had dedicated C symbols. Now every op in the loop-bind spec is at native C/Python parity. Additive C symbols → ABI stays 3; describe() stays 201; every dispatch arm bit-exact with its Python fallback.

The "C = transpiled Python" Rosetta discipline (notebook §3.29.4–§3.29.5) admits no Python-only carve-out: a composition-op gets a C rendering exactly as cross7 = Im(bind) and g2 = ⟨x, cross7⟩ did (rc7). The associator (the Class-K residue, the genuinely-new k=7 arithmetic surfaced in #797/F271) and the L/R multiplication-operator matrices were the remaining pure-Python composites:

  • srmech_loop_associator_f64 (c/src/srmech_loopbind.c) — (a·b)·c − a·(b·c), two fixed triple-products via the static octonion product (no recursion); 8 doubles out.
  • srmech_loop_left_op_f64 / srmech_loop_right_op_f64 — the L_a (col k = a·e_k) / R_a (col k = e_k·a) operator matrices, n·n doubles row-major, byte-matching numpy column_stack of the per-basis binds.
  • srmech.amsc.hdcloop_associator / loop_left_op / loop_right_op dispatch to the peers for the dim-8 octonion when HAS_NATIVE, pure-Python recursion kept as the Pyodide/WASM (and non-dim-8) fallback.
  • tests/test_loop_operator_native_parity.py (new) — native peer vs the pure-Python recursion (the Rosetta agreement-attestation), plus the associator's known structure (zero on associative/Fano triples, antisymmetry).

With rc7 (per-block) + rc11/rc17 (HD bind SIMD) + rc20 (HD conj/inv/unbind/runbind) + rc21 (associator + L/R operators), the entire srmech.amsc.hdc loop-bind / Moufang surface is native at both single-octonion and HD-block scale — no op is Python-only. JPL Power-of-Ten clean (≤60-line, ≥2 asserts, no goto/malloc/recursion); warning-clean under -Wall -Wextra -Wpedantic -Werror / /W4 /WX.

[0.7.0rc20] - 2026-06-03

Native C peers for the rest of the HD loop family — completes "C = transpiled Python" (the Rosetta discipline, notebook §3.29.4–§3.29.5: one SSoT rendered as meaning : Python AND C source : Compiled C). The HD block conjugate / Moufang inverse / left-unbind / right-unbind were Python-only per-block loops; now each has a whole-array C transpile, so NO HD loop op is Python-only. Additive C symbols → ABI stays 3; describe() stays 201; every dispatch arm bit-exact with its Python fallback.

srmech_loop_bind_hd_f64 (rc11/rc17, the F292 #2 graft) gave the HD BIND its native peer; the companions (loop_conj_hd / loop_inv_hd / loop_unbind_hd / loop_runbind_hd) kept looping over 8-blocks in Python — a Rosetta with a glyph present in one script (Python) but missing from the other (C source), so those ops had no machine-code tier. This rc renders them in C too:

  • c/src/srmech_loophd_family.c (new) — srmech_loop_{conj,inv,unbind,runbind}_hd_f64, the SHIPPED per-block symbol (srmech_loop_conj_f64 / srmech_loop_inv_f64 / srmech_loop_bind_f64) applied over NB independent dim-8 blocks (the block-diagonal ⊕, #811/F289). The faithful transpile of the Python wrappers — same per-block ops, same order — collapsing the per-block Python loop into ONE native call (bit-exact with the fallback by construction). loop_inv_hd propagates SRMECH_ERR_BAD_INPUT from a zero block (→ the Python fallback raises, contract preserved). Scalar — no N-way SIMD here (the bind owns that, srmech_loopbind_hd.c); the heavy step where present (the product) is already native per-block.
  • srmech.amsc.hdcloop_conj_hd / loop_inv_hd / loop_unbind_hd / loop_runbind_hd dispatch to the new peers when HAS_NATIVE, with the per-8-block pure-Python recursion kept as the Pyodide / WASM fallback (hasattr-guarded ctypes, stale-.dll-safe).
  • c/include/srmech.h — 4 new prototypes; the stale "the HD variants need NO C peer of their own" note is retired (it predated loop_bind_hd's peer and contradicted the Rosetta discipline).
  • tests/test_loop_hd_native_parity.py (new) — asserts the whole-array native peer agrees with the pure-Python Cayley-Dickson recursion (_loop_bind_raw / _loop_conj_raw) — the literal Rosetta agreement-attestation — plus the round-trip identities. The existing test_loop_hd_division.py suite now exercises the native path for free.

Closes the C/Python-parity ask in #814 (loop-bind op spec — "Parity-tested against the Python fallback", now true across the HD surface too) on the realization established in #811/#812 (the dim-8 → high-dim block-octonion ⊕). Each function is ≤60 lines, ≥2 asserts, no goto/malloc/recursion, single-line macros only, warning-clean under -Wall -Wextra -Wpedantic / /W4 /WX (JPL Power-of-Ten).

[0.7.0rc19] - 2026-06-03

HAL constant-attestation discipline — MPM (Mathematical Provenance Method) applied to CODE CONSTANTS, retroactive. Externally-sourced magic that srmech does NOT derive from its own framework (and historically transcribed by hand) is now attested in a per-target header MPR block AND, where derivable, regenerated-and-asserted by a test. Pure provenance/hardening: no behaviour change → ABI stays 3; describe() stays 201; every dispatch arm byte-identical.

Motivated by the rc18 SHA-NI K-table typo (0x8CC70808 where FIPS K[59] is 0x8CC70208) — a transcribe-from-memory error invisible on a host without the SHA feature, caught only on SHA-NI CI. The fix generalises: magic constants get attested + derived-and-asserted so the next such typo fails locally, on any host, at unit-test time.

  • c/src/srmech_sha256_constants.h (new) — the SINGLE attested home for FIPS K[64] + H0[8] (MPR block → FIPS 180-4 §4.2.2/§5.3.3). The three SHA-256 TUs (srmech_sha256.c / _batch.c / _shani.c) now #include it instead of each carrying a hand-copied duplicate (that duplication was the same risk surface as the rc18 bug).
  • c/src/srmech_sha256_shani.h (new) — the packed SHA-NI KP[16][2] + an MPR block attesting BOTH the constants (FIPS) and the rnds2/msg1/msg2 instruction sequence (Intel SDM Vol 2 + Intel SHA Extensions whitepaper as primary; noloader/Walton as a working-impl pointer, NOT a drifting byte-hash; correctness pinned by test_sha256_shani.py on SHA-NI CI).
  • c/src/srmech_simd.h — MPR block for the cpuid leaf/bit numbers (Intel SDM Vol 2A CPUID: leaf-1 ECX bit 27/28 OSXSAVE/AVX; leaf-7 EBX bit 5/29 AVX2/SHA; XGETBV XCR0 gate) + the GCC/Clang target-attribute feature strings (GCC x86 Function Attributes).
  • tests/test_fips_constants_attested.py (new) — derive-and-assert: regenerates K from exact integer cube-roots of the first 64 primes (icbrt(p<<96)) and H0 from square-roots (isqrt(p<<64)) — no float, no ULP risk — and asserts byte-for-byte against the committed srmech_sha256_constants.h tables and the decoded packed KP. This is the gate that would have failed rc18's typo at unit-test time. (Self-check: asserts the derivation itself yields K[59]=0x8CC70208.)

The discipline going forward: a HAL/target magic constant ships with (a) an MPR attestation block in its .h, and (b) a regenerate-and-assert test where the value is derivable; a hand edit the test doesn't bless is a defect by construction.

[0.7.0rc18] - 2026-06-02

SHA-NI single-stream SHA-256 (F292 graft #3) — performance-engineering of srmech's OWN content-addressing hash for the common single-message case (sha256_bytes, every AMSC attestation). Built in CI so a SHA-NI-capable runner exercises the kernel, not parked because the dev CPU lacks the feature. New C symbol → ABI stays 3; describe() stays 201; JPL ratchet unchanged.

Graft #1 (rc10 sha256_batch) accelerates "hash N independent messages" by filling SIMD lanes; the single-message case it can't help is exactly the hot path (one response-bytes blob fingerprinted per attestation). The Intel SHA Extensions (SHA-NI) accelerate ONE message — _mm_sha256rnds2_epu32 runs two rounds per instruction, _mm_sha256msg1/msg2_epu32 drive the schedule — so one 64-byte block compresses in a handful of instructions.

  • srmech_sha256_shani (new c/src/srmech_sha256_shani.c) — FIPS-pads a block at a time, runs each block through the SHA-NI compress (state kept packed in the Intel ABEF/CDGH layout), and writes the raw 32-byte digest. The 64 rounds are factored into JPL-clean ≤60-line helpers (load warm-up + a cyclic steady-state group driven by a rotating message-register index + a final group) that are bit-identical to the canonical interleaving. A self-contained scalar duplicate (byte-for-byte the srmech_sha256.c compress, NIST-KAT-pinned) is the oracle AND the fallback.
  • HAL (srmech_simd.{h,c}, rc11) gains srmech_simd_has_shani() (leaf7 EBX bit29 — no OSXSAVE gate; XMM state is always OS-saved) + SRMECH_SIMD_TARGET_SHANI (target("sha,sse4.1,ssse3") on gcc/clang; empty on MSVC). Target-attribute-guarded compilation means the kernel builds on any host (incl. the SHA-NI-less dev CPU); runtime cpuid-dispatch enters it only where the feature is present.
  • Dispatch safety: the kernel is NEVER entered unless cpuid confirms SHA-NI, so the SRMECH_SHANI_FORCE_TIER test hook ({0,1}) can only select scalar-or-(SHA-NI-if-present) — it can never SIGILL. srmech.amsc.format.sha256_bytes prefers the SHA-NI peer when the rc18 symbol is bound (transparent hot-path accel; every arm bit-exact).
  • Honest coverage: tests/test_sha256_shani.py pins the scalar oracle on every host (force tier 0) AND the auto path (kernel on SHA-NI runners, scalar elsewhere); the "kernel actually ran" assertion is exercise-if-present / skip-with-log keyed on _native.has_shani() (so a non-SHA-NI runner skips with a clear log rather than passing a scalar run off as kernel coverage). A CI cpuid-dump step records which matrix cells carry the feature. _native.has_shani() surfaces the host capability (tri-state True/False/None).

Each function is pi-free, ≥2 asserts (the cpuid probe + the 1-line rotate are the documented Rule-5 exemptions), ≤60 lines, no goto/malloc/recursion, single-line macros only, warning-clean under -Wall -Wextra -Wpedantic / /W4 /WX.

[0.7.0rc17] - 2026-06-02

C-transpile of the last two rc12 chiral primitives (Class E + L) — closes the C/Python-parity gap so NO rc12 primitive op is Python-only (full-C-parity commitment per [[feedback_no_binding_layer_carveout]]). Additive C symbols → ABI stays 3; describe() stays 201; JPL ratchet unchanged.

rc16 transpiled the Class-I/D/G chiral ops; rc16's two "deferred" ops were a soft-MVP carve-out the project rejects — both have clean integer kernels and now have native C peers, dispatched-to when HAS_NATIVE (byte-exact Python fallback unchanged):

  • srmech_reverse_order (Class E → srmech_catalog.c) — the reversed index permutation out[i] = n-1-i (the chiral mirror of a sorted catalog; the wrapper applies the permutation to the (key, value) pairs); wired into srmech.amsc.naming.reverse_order.
  • srmech_three_fold_bands (Class L → srmech_laplacian.c) — the harmonic-3 three-fold band split (low/mid/high from n/3 + remainder to the later bands so |low| ≤ |mid| ≤ |high|); wired into srmech.amsc.laplacian.three_fold_eigvec_groups (the band-size computation gains a C path; the eigvec solve composes the existing Class-L spectral machinery).

Each is pi-free integer arithmetic, 2 asserts, ≤60 lines, no goto/malloc/recursion, warning-clean (-Wall -Wextra -Wpedantic). hasattr-guarded ctypes bindings (stale-.dll-safe). 4 new native-vs-Python parity tests (test_chiral_EL_c_parity.py) force both paths.

With rc16+rc17, every rc12 primitive op (D/E/G/I/L) now has a native C surface. (classify_harmonic is a static partition-constant lookup and classify_chirality_harmonic is a composite spectral reading — classifiers, not bare per-class primitives — so they compose rather than each get a C symbol, consistent with the primitive-vs-composite line the architecture already draws.)

[0.7.0rc16] - 2026-06-02

C-transpile of the rc12 chiral primitives — native C peers for the F150 Class-I/D/G chiral ops, byte-exact with their Python fallbacks. Additive C symbols → ABI stays 3; describe() stays 201 (no new public callable — the ops already shipped in rc12); JPL ratchet unchanged.

The three rc12 chiral ops with a clean integer/byte kernel now have a native C surface, dispatched-to when HAS_NATIVE (pure-Python fallback unchanged, byte-exact):

  • srmech_three_cycle (Class I → srmech_cyclic.c) — the Z/3 generator (value+1)%3, computed overflow-safe as ((value%3)+1)%3; wired into srmech.amsc.cyclic.three_cycle (uint64-range values dispatch to C, larger fall back to Python).
  • srmech_mirror_pattern (Class D → srmech_dispatch.c) — the byte-reversed needle; wired into srmech.amsc.dispatch.mirror_pattern.
  • srmech_byte_search_backward (Class G → srmech_search.c) — the last-occurrence search (rfind; empty needle → len, absent → UINT32_MAX/None); wired into srmech.amsc.search.byte_search_backward.

Each is pi-free integer/byte arithmetic, ≥2 asserts, ≤60 lines, no goto/malloc/recursion, warning-clean under -Wall -Wextra -Wpedantic (JPL Power-of-Ten). 9 new native-vs-Python parity tests (test_chiral_c_parity.py) force both paths and assert byte-exact agreement across boundaries / random sweeps / period-3 / involution / empty-absent-multi-occurrence. ctypes bindings are hasattr-guarded so a stale .dll falls back to Python rather than failing to load.

Deferred rungs (no-silent-caps): Class E reverse_order (list-of-pairs reversal — a Python data-structure op, not a numeric/byte kernel; intentionally Python-only) and Class L three_fold_eigvec_groups (eigendecompose-adjacent band split) remain Python-only for now; the rbs_lm Klein-4 encode helpers compose the already-C-backed klein4_* primitives.

[0.7.0rc15] - 2026-06-02

DSL surface audit — corrects stale op-counts in the LLM-facing cascade-DSL tool descriptions + adds an anti-drift guard. Descriptions only; no new ToolEntry → describe() stays 201; ABI stays 3; no C change.

The cascade-DSL tool descriptions had drifted behind the runner: the srmech.dsl.list_catalog_ops ToolEntry summary enumerated only "8 ops" (omitting the v0.7.0rc8 autocorrelation AND the v0.6.0 kuramoto_step / parallel_sector_dispatch), and run_toml_chain referenced a "10-op cascade catalog" — so an LLM driving the DSL via MCP would believe fewer ops exist than the 11 that actually ship. The CLI (srmech dsl ops) was already correct (it reads the catalog live).

  • Corrected every stale count/list across the DSL surface: the two _register_dsl_tools ToolEntry summaries (run_toml_chain / list_catalog_ops), the srmech.dsl.__init__ + srmech.dsl._tool_surface module docstrings — all now cite 11 ops and list_catalog_ops names all eleven (autocorrelation, best_rational_signed, chiral_dual, chiral_flip, cyclic_gcd, kuramoto_step, magnitude, net_chirality, parallel_sector_dispatch, pin_slot_at_zero, reorient).
  • Anti-drift guard (test_dsl_tool_surface_descriptions.py): the DSL ToolEntry summaries are now locked to the LIVE list_cascade_ops() set — every live op name must appear in the list_catalog_ops summary and both summaries must cite the current op count, so a future op forces the descriptions to be updated (or CI fails) rather than silently falling stale.

[0.7.0rc14] - 2026-06-02

RBS-LM upstream wishlist — the srmech.rbs_lm inference substrate (UPSTREAM_NOTES §9; F166 walk). A NEW top-level module, pure-Python; outside the amsc.*/qm.* tool-schema enumeration → describe() stays 201; ABI stays 3; no C change.

Ports the F166 bit-exact, catalog-instantiable inference substrate from the research subtree into the package — inference built UP from the 28-D Klein-4 coordinate, not distilled DOWN from float weights. The typed substrate config of rc13 (substrate_parameterization) gets its first consumer.

  • srmech.rbs_lm.ContextSubstrate — the rolling-context encoder: per-token Klein-4 vectors (SHA-256 seed → fixed vector, sector arithmetic), iω₇ position keys, odd-bundle of the last-k tokens → ONE Klein-4 state (Class A∘M encode + position). Plus the numpy-level encode helpers (token_seed, encode_word_k4, encode_bigram_l1, encode_skeleton_l2, encode_sentence_l3, sim_k4_batch) — the same Klein-4 sector cascade as srmech.amsc.hdc.klein4_*, at numpy-array granularity for the inference loop.
  • srmech.rbs_lm.RBSLMInferenceSubstrate — the inference object: from_catalog(toml) / from_params(dict) build it; learn(stream) loads the bigram candidate structure + a context→next associative memory (F154-bounded, klein4_bind over windows, odd-bundle); next_token_distribution(ctx, temperature) retrieves over bigram-legal candidates (Class M) + temperature-softmax; infer(prompt, …, seed) is the deterministic autoregressive loop; attestation() returns the MPR block (descriptor_hash + srmech_version + abi + provenance) so any generated sequence is re-derivable.

Determinism: same corpus + params + srmech_version + seed → bit-exact identical output (SHA-256 token seeds, exact XOR bind, seeded sampling). Faithful (bit-exact) port of the research artifact; composes the existing srmech.amsc.hdc.klein4_* primitives + srmech.amsc.load_descriptor/descriptor_hash (no new hashlib.sha256 — routes through srmech.amsc.format.sha256_bytes via token_seed).

SCOPE / deferred rungs (no-silent-caps): rc14 ships the two classes. The srmech.rbs_lm tool_schema surface (LLM-as-tool inference) + the siona.profile("rbs_lm").infer() binding (§8+§9 join) + the hierarchical-memory scale-up (CanonicalHierarchicalMemory, F162 — past the single-memory F154 4× ceiling, for corpus-scale inference) remain open for follow-up rcs. [[feedback_no_mvp_framing]].

[0.7.0rc13] - 2026-06-02

RBS-LM upstream wishlist — the substrate_parameterization adapter + typed Descriptor sub-dataclasses (UPSTREAM_NOTES §7). Pure-Python, additive; no new ToolEntry → describe() stays 201; ABI stays 3; no C change.

A seventh AMSC adapter (html_scraper / json_api / csv_bulk / netcdf_grid / geotiff_bbox / literature_curated → + substrate_parameterization). Where the first six answer "where do the ground-proof rows come from?", this one answers "how is a parameterized substrate configured?" — every former module-level magic number of a substrate characterization run (the RBS-LM variable-length Klein-4 chirality-level sentence substrate is the canonical consumer) lives in attested [fetch.substrate_parameterization.*] sub-tables rather than script-embedded MVP magic ([[feedback_no_mvp_framing]] + user direction 2026-05-28).

  • Typed sub-dataclasses (in srmech.amsc.adapters.substrate_parameterization): SubstrateParams, EncodingParams, GenerationParams, HierarchicalParams, CorpusParams (required) + GrammarParams, PlausibilityParams, MeasurementParams (optional), composed into a frozen SubstrateConfig. First-class typed access (cfg.substrate.D) replaces dict-navigation (desc.fetch["literature_curated"]["substrate"]["D"]).
  • parse_substrate_config(params) — validates the called-out invariants: D > 0 (and every count); cycle_policy ∈ {forbid, allow, count_limited}; corpus.source / corpus.tokenizer / grammar.mode enums; default_strategy ∈ allowed_strategies; 0 ≤ plausibility weight ≤ 1; eps_smoothing > 0. Booleans are rejected where ints are required.
  • config_for(descriptor) — typed accessor that locates the substrate sub-table inside descriptor.fetch (the substrate_parameterization key when migrated, else the legacy literature_curated key, else [fetch] directly), so it works for a migrated descriptor AND one still riding the interim adapter.
  • fetch / parse — the AMSC adapter protocol: fetch reads the committed [fetch].ndjson_path (the characterization measurement output); parse decodes it line-by-line. These rows are computed outputs attested by the descriptor + parser_rule_hash, so (unlike literature_curated) no per-row source_doi is required.

SCOPE: the typed config layer only. The run_substrate_characterization operation that consumes a SubstrateConfig + corpus + phase set and produces the measurement NDJSON is the substrate-module port (UPSTREAM_NOTES §9), landing in a follow-up rc. The adapter module lives under the coverage-exempt srmech.amsc.adapters.* prefix (like its six siblings), so no tool-schema churn. [[feedback_no_mvp_framing]].

[0.7.0rc12] - 2026-06-02

RBS-LM upstream wishlist — F150 chiral A–N harmonics (UPSTREAM_NOTES §6) + §2.2 cross-substrate alignment. 7 new ToolEntries → describe() 194→201 (+1 coverage-exempt utility); pure-Python, no C change (this rc), ABI stays 3.

Lands the research-side F150 framework move: the 14 A–N operators carry a per-operator chirality-harmonic order (1/2/3) that partitions the existing classes — H1 (chirality-invariant) = A B F H N, H2 (chiral inverse / mirror) = C D E G K M, H3 (chiral rotation / 3-cycle) = I J L. Variants land next to their base Class op (no privileged namespace, per [[feedback_no_privileged_primitive_classes]]; siona is a co-name alias, so these are srmech.amsc.*).

  • srmech.amsc.harmonics (new) — classify_harmonic(letter) -> 1|2|3 (the static F150 partition) + classify_chirality_harmonic(hv) -> 1|2|3 (spectral classifier: DC-dominant→H1, else zero-mean mirror vs 3-fold self-agreement→H2/H3; energy / inner-product ratios, no abs() on the substrate). HARMONIC_PARTITION + HARMONIC_LADDER_OPEN_RUNGS constants.
  • Harmonic-2 mirror ops (period-2 involutions): dispatch.mirror_pattern (D — byte-reversed needle), naming.reverse_order (E — order-reversed sorted catalog), search.byte_search_backward (G — last-occurrence search).
  • Harmonic-3 three-cycle ops (period-3): cyclic.three_cycle (I — Z/3 generator; any non-negative int read mod 3, so the generic MCP int-synth is always in-domain), laplacian.three_fold_eigvec_groups (L — low/mid/high eigenvector bands).
  • compose.greedy_bipartite_alignment (§2.2) — greedy cross-substrate kernel matcher (caller similarity_fn); the Rosetta-layer utility. It takes a Python callable that cannot cross JSON-RPC, so it is not an MCP tool — it is coverage-exempt in tests/test_tool_schema_coverage.py::_EXEMPT_FUNCTION_NAMES on the callable-arg rationale (public + tested, surfaced via srmech.amsc.compose).
  • tool_schema: the 7 primitive ops are all registered and fully MCP-callable (mcp_callable=True) — no handle-pending entries (the rc16 zero-handle-pending invariant holds): classify_harmonic (str), classify_chirality_harmonic (np.ndarray, JSON-list-coerced + flattened), mirror_pattern (bytes), reverse_order (list[tuple[bytes,bytes]]), byte_search_backward (bytes×2), three_cycle (int), three_fold_eigvec_groups (np.ndarray). → describe() 194→201.

Ladder is staged, not capped (no-silent-caps): HARMONIC_LADDER_OPEN_RUNGS = {2: ("C","K"), 3: ("J",)} — Class M's H2 already ships as hdc.klein4_* (F132); C/K explicit mirror variants + J's speculative three_cycle_factor (F150 §6.3) remain open for a later rung.

SCOPE: framework-composition surfaces over the existing A–N primitives; most of UPSTREAM_NOTES §1/§2 (rfft, signed_sum_squared, symmetric_eigendecompose) was already shipped in prior rcs. [[feedback_no_privileged_primitive_classes]].

[0.7.0rc11] - 2026-06-02

F292 graft #2 — N-way SIMD block-octonion HD bind (srmech.amsc.hdc.loop_bind_hd), on a new SIMD optimize-path HAL (c/src/srmech_simd.h). NO new public callable → describe() stays 194; a NEW C symbol → ABI stays 3 (additive).

The on-theme F292 graft: loop_bind_hd is the block-diagonal direct sum ⊕ of NB independent dim-8 octonion products (F289 verified err 0.0) — exactly the data-parallel shape cpuminer's N-way-SIMD mindset exploits. It was a Python loop over the NB 8-blocks (one ctypes call per block); this collapses it to one native call that advances W blocks per SIMD pass.

  • srmech_loop_bind_hd_f64(x, y, nb, out) (c/src/srmech_loopbind_hd.c, new) — binds all NB blocks in one call via a runtime AVX (256-bit double, W=4) / SSE2 (W=2) / scalar dispatch. The SIMD kernels mirror the rc7 mul2/mul4/mul8 Cayley-Dickson op-DAG with double → a vector holding W blocks of one component; the scalar tier (remainder / non-x86 / Pyodide) reuses the shipped srmech_loop_bind_f64, so it is bit-exact with the single-block product by construction. loop_bind_hd dispatches to it (whole NB-block array crosses once — no per-element Python loop); the per-block fallback is unchanged. NOTE the 256-bit double ops are AVX, not AVX2.
  • HAL — c/src/srmech_simd.h + srmech_simd.c (new): ALL machine-specific bits other than the kernels now live in ONE place — the SRMECH_SIMD_X86 platform macro, the arch intrinsic includes, the SRMECH_SIMD_TARGET_* per-function attributes, and the cpuid/xgetbv feature probes (srmech_simd_has_avx2/_avx/_sse2) + env-tier clamp (srmech_simd_tier). The portable core (srmech_sha256.c, srmech_loopbind.c) and the public header (c/include/srmech.h) stay 100% machine-agnostic. rc10's srmech_sha256_batch.c is retrofitted onto the HAL — its own platform/target/cpuid copies deleted (byte-identical SHA output, every tier; net FEWER Rule-5-exempt functions). New optimize-path ops include the HAL and write only their kernels.
  • Bit-exact, every tier: scalar / SSE2 / AVX all match the pure-Python _loop_bind_raw per block (maxerr 0.00e+00, including the canonical HD width 2048 = 256·8) — the F292 "parity-trivial" prediction confirmed. tests/test_loop_bind_hd.py. SHA-256 batch regression: still byte-identical to hashlib + NIST KATs at every tier.
  • JPL-clean: intrinsics (NOT asm); no goto/recursion/malloc; ≤60-line functions; single-line vector macros (Rule 8); kernels self-isolate via __attribute__((target("avx"|"sse2"))) so the library compiles at baseline ISA (no global -mavx); ≥2 asserts per non-exempt function (the cpuid probes are the documented exempt entries). gcc/clang/MSVC -Werror//WX.

SCOPE (load-bearing): energy/perf-engineering of srmech's OWN Class-M HD bind (octonion algebra — not hashing, not mining). The HAL is the architectural answer to "no machine-specific bits in the core; abstract the optimize path behind a header." [[feedback_trauma_informed_defensive_scope]].

describe() stays 194 (internal acceleration of an existing surface, no new ToolEntry); ABI stays 3 (new symbol, additive). Anchor: F292 (R-RBS-LM-FINDING_292_cpu_optimization_reference_graft_handdown).

[0.7.0rc10] - 2026-06-02

F292 graft #1 — N-way SIMD SHA-256 BATCH (srmech.amsc.format.sha256_batch), folding the F292 CPU-optimization hand-down into v0.7.0. +1 ToolEntry → describe() 194; a NEW symbol → ABI stays 3 (additive).

The first "apple-tree" graft from F292: take cpuminer's battle-tested N-way SIMD SHA-256 technique (sha256d_ms_4way/8way) and re-implement it JPL-clean in srmech's own hash, for the bulk-attestation common case (fingerprinting a whole catalog of upstream response bytes at once).

  • srmech.amsc.format.sha256_batch(datas) -> list[str] — one 64-char lowercase hex digest per message, each byte-identical to sha256_bytes(d) / hashlib.sha256(d).hexdigest(). A throughput surface, NOT a new content-address shape. Dispatches to the native peer when present, else a hashlib loop.
  • srmech_sha256_batch (c/src/srmech_sha256_batch.c, new) — a runtime cpuid dispatch to AVX2 8-way / SSE2 4-way (scalar fallback for the n mod W remainder, non-x86, and Pyodide). The W lanes step through their own message's 512-bit blocks in SIMD lockstep, with a per-lane mask freezing a lane once its (shorter) message is done — so variable-length batches are correct, each lane's state advancing exactly as the scalar one-shot would. SRMECH_SHA256_FORCE_TIER={0,1,2} overrides the dispatch (test hook).
  • Bit-exact, every tier: scalar / SSE2 / AVX2 all match hashlib + the NIST KATs ("", "abc", 1M-a) over a full padding-boundary length matrix and mixed-length batches (verified locally via the force-tier hook; CI's native cells exercise the host tier). tests/test_sha256_batch.py.
  • JPL-clean: intrinsics (NOT asm); no goto/recursion/malloc; ≤60-line functions; the SIMD sigma ops are single-line macros (Rule 8); the AVX2 kernel self-isolates via __attribute__((target("avx2"))) so the library compiles at baseline ISA (no global -mavx2); ≥2 asserts per non-exempt function (the cpuid feature-detectors are the documented exempt entries). gcc/clang/MSVC -Werror//WX.

SCOPE (load-bearing): energy/perf-engineering of srmech's OWN provenance hashing — NOT cryptocurrency mining (binding doesn't make hashing cheaper; SHA-256 has no PoW shortcut; "a correct instrument, not a money printer"). Technique attested to public references (FIPS 180-4 for the algorithm; the Intel Intrinsics Guide + Gueron & Krasnov, "Parallelizing message schedules to accelerate SHA-256" for the N-way structure); cpuminer (GPLv2+, forward-compatible with srmech GPL-3.0+) was read only as a working-impl pointer. [[feedback_trauma_informed_defensive_scope]].

+1 ToolEntry → describe() 193 → 194; ABI stays 3 (new symbol, additive). Anchors: F292 (R-RBS-LM-FINDING_292_cpu_optimization_reference_graft_handdown); the btc-rosetta midstate bench (the measured 1.73× energy anchor).

[0.7.0rc9] - 2026-06-02

MS #21 rc9 voxel — the v0.7.0 graduation-prep PyPI description refresh (the genuinely-last rcN before the clean v0.7.0 cut). Description-only → describe() stays 193; DSL catalog stays 11 ops; ABI stays 3.

The PyPI Summary predated the v0.7.0 arc — it named "octonion-multiplications" and "Spin(8) triality" but not the Moufang loop-bind op family the arc actually shipped, and nothing of rc8's autocorrelation. This voxel refreshes it (no code change):

  • Names the v0.7.0 headlines: Moufang loop-bind, 7-D cross product, G_2 3-form (the octonion family, rc1–rc7) and Wiener-Khinchin autocorrelation (rc8) join the cascade-parity list (Kuramoto too — shipped at v0.6.0 but never surfaced in the summary).
  • Preserves the substrate-native spine verbatim in substance: 28-dim chiral hyper-loop = so(8) adjoint (14 g_2 derivations + 14 L/R octonion products; Spin(8) triality), made hardware-callable.
  • Trimmed the redundant dispatch, catalog, templating, Kepler + dual-path signal-processing tail (covered by "Full cascade-catalog C/Python parity") → 472 chars, under the 480 soft / 512 hard PyPI Summary limit. Byte-identical in pyproject.toml + pyproject-pure.toml (the publish-workflow drift guard).

Description-only — no code touched, so describe() stays 193, the DSL catalog stays 11 ops, ABI stays 3. This is the final rcN; the clean v0.7.0 graduation to production PyPI follows (human-gated).

[0.7.0rc8] - 2026-06-02

MS #21 rc8 voxel — the Class-L circular autocorrelation primitive (the F290 §C un-flatten Wiener-Khinchin op), shipped CO-EQUAL in Python AND C. +1 ToolEntry → describe() 193; +1 cascade-catalog op → 11 DSL ops; new symbol → ABI stays 3.

The F290 §C "un-flatten" catalog composite (autocorr → difference-graph → conservation-validate) was blocked on one missing Class-L primitive: srmech had no autocorrelation op, so the composite could not be authored as pure-TOML over named ops. This voxel ships it, Python + C together:

  • srmech.amsc.cascade.autocorrelation(x) — the circular autocorrelation r[k] = Σ_i x[i]·x[(i+k) mod n] (r[0] = Σ x² = energy) of a real sequence. This is EXACTLY the Wiener-Khinchin spectral object r = Re(IFFT(|FFT(x)|²)) (the circular-convolution theorem) — that identity is WHY it is Class L (the spectral side: autocorrelation ↔ power spectrum). The Python wrapper computes it the fast way (numpy FFT). n==0 → [].
  • srmech_autocorrelation_f64 (c/src/srmech_autocorr.c) — the co-equal native peer computes the DIRECT O(n²) multiply-add sum — the IDENTICAL object, and JPL-clean: no FFT, hence no recursion (Rule 1) and no transcendentals — just bounded loops over caller buffers, so it runs on a microcontroller with no host Python and no FFT library. srmech.amsc.cascade dispatches to it when HAS_NATIVE, else the numpy FFT fallback. Parity to FFT round-off (~1e-12, NOT bit-exact — the FFT route and the direct sum accumulate in different orders; a compiler may also contract a*b into an FMA).
  • HONEST CASCADE SHAPE: Class L (the Wiener-Khinchin reading); computationally a Σ-reduce of products — no abs(), no sign branch. NOT a new privileged primitive class.
  • autocorrelation.toml descriptor (class_composition = "L", c_symbol_f64 = "srmech_autocorrelation_f64") makes it discoverable (srmech dsl ops11 ops) and runnable as a DSL stage. tests/test_autocorrelation.py: the FFT route equals the naive direct-sum definition (the spectral identity holds); the energy anchor r[0] == Σ x²; circular symmetry r[k] == r[n-k]; boundary cases (n==0 → [], n==1 → [x[0]²], constant signal); catalog discovery; and (native) the direct-sum peer matches the naive sum to ~1e-12.

JPL Power-of-Ten clean (one ~13-line function, ≥2 asserts, no recursion/malloc/goto; gcc/clang/MSVC -Werror//WX). +1 ToolEntry → describe() 192 → 193; ABI stays 3 (a new symbol is additive). Unblocks the F290 §C un-flatten composite as pure-TOML over named ops. Anchors: Wiener 1930 / Khinchin 1934 (the autocorrelation ↔ power-spectrum theorem); R-RBS-LM F290 §C (the un-flatten catalog).

[0.7.0rc7] - 2026-06-02

MS #21 rc7 voxel — the co-equal C peer for the octonion loop-bind family (the Python→C transpile). New native symbols → ABI stays 3 (additive); describe() stays 192.

The MS#21 loop-bind family shipped Python-first (rc1–rc6); this voxel lands its co-equal Compiled-C tier so srmech runs the octonion algebra natively (the microcontroller-readiness commitment). c/src/srmech_loopbind.c ports the dim-8 octonion (Cayley-Dickson) product and companions:

  • srmech_loop_bind_f64 — the octonion product (a,b)(c,d) = (a c − conj(d) b, d a + b conj(c)). JPL Rule 1 bans recursion, so the Python's recursive _loop_bind_raw is unrolled as a fixed real→complex→quaternion→octonion call DAG (srmech_loop__mul2/4/8) — bit-exact with the Python (identical operand order at every level).
  • srmech_loop_conj_f64 (Class-C conjugate), srmech_loop_inv_f64 (Moufang inverse x̄/⟨x,x⟩; Class-K clean), srmech_cross7_f64 (Im(loop_bind)), srmech_g2_three_form_f64 (⟨x, cross7(y,z)⟩).
  • Octonion carrier only: every n must be 8; other dims return SRMECH_ERR_BAD_INPUT and the Python keeps its recursive fallback. The HD block variants (loop_bind_hd, loop_unbind_hd, loop_conj_hd, loop_inv_hd, loop_runbind_hd) inherit native acceleration for free — their wrappers loop over 8-blocks calling the per-block loop_bind/loop_conj, which now dispatch to C.
  • Python dispatch in srmech.amsc.hdc: loop_conj / loop_bind / loop_inv / cross7 / g2_three_form try the native path (type/size-guarded; n==8 only) then fall back to pure Python — exact behaviour preserved.
  • tests/test_loopbind_parity.py: native == pure-Python — exact array_equal for loop_conj (pure negation) + the dim-16 sedenion fallback; <1e-12 for the multiply-bearing bind/inv/cross7/g2/HD-per-block (a compiler that contracts a*b−c into an FMA, e.g. clang on macOS, may differ ≤1 ULP); plus octonion identities x·x⁻¹=e₀ + cross7 antisymmetry.

JPL Power-of-Ten clean (≤60-line functions, ≥2 asserts each, no recursion/malloc/goto; gcc/clang/MSVC -Werror//WX). No new ToolEntry / no new class — these are native peers of existing ops, so describe() stays 192; ABI stays 3 (new symbols are additive). Verified bit-exact on a 64-bit local build over 500 random octonions; CI's native cells + the TestPyPI wheel are the cross-compiler gate.

[0.7.0rc6] - 2026-06-02

MS #21 rc6 voxel — bring-your-own (BYO) cascade-TOML (#811 / F289 D2). Config API only → describe() stays 192; ABI stays 3.

The DSL cascade-catalog was a closed set: only the 10 shipped *.toml descriptors under srmech/amsc/_research/cascade_catalog/. This voxel opens it — a domain specialist who needs a cascade srmech doesn't catalog, or a behaviour defined by a TOML descriptor that follows srmech's naming, can now bring their own:

  • srmech.dsl.register_catalog_dir(path) — register an external dir of *.toml cascade descriptors. The zero-API equivalent is the SRMECH_CASCADE_PATH env-var (os.pathsep-separated dirs). Registered ops then resolve (chain().then(...) / run_toml_chain), run, and surface (list_catalog_ops / srmech dsl ops) identically to shipped ops.
  • PURE-TOML composites — a user descriptor may carry a [composite] body whose [[composite.stage]] array is a chain of named ops (no Python): lookup_cascade_op resolves it to a unary stage that builds + runs the sub-chain. (Or a primitive descriptor, which needs a matching srmech.amsc.cascade callable, exactly as the shipped ones do.)
  • MPM provenance tiers — every descriptor is tagged _provenance: shipped = "srmech" (A-tier); user = "user:<sha256>" (B-tier, attested to the user's own descriptor hash, NOT a shipped primitive). list_catalog_ops() gains a "provenance" field ("srmech" / "user").
  • Loud-at-load validation — a user op-name may not shadow a shipped or earlier op (raises); composites are validated at load (every referenced op resolves; the composite graph is acyclic). A typo fails loudly at load, not silently at run — the "follow srmech naming" gate.
  • tests/test_byo_cascade_toml.py (9 tests): register + resolve + run a user composite (fluent builder + run_toml_chain); SRMECH_CASCADE_PATH; provenance tags; shadow-rejection; unknown-op / cycle / missing-name loud-at-load; nonexistent-dir rejection; shipped catalog + describe() unchanged.

Config API onlyregister_catalog_dir is not a cascade op / not a ToolEntry, so describe() stays 192; ABI stays 3 (pure-Python, additive). Defaults blessed by the user (reject-on-shadow protects MPM A-tier integrity; ship anchors then iterate from use). Anchors: F289 D2 (rc4_handdown_and_byo_cascade_toml); §12.3 confirmed-deferred.

[0.7.0rc5] - 2026-06-02

MS #21 rc5 voxel — the per-block HD Moufang-division family + the loop_inv/loop_conj HD footgun guard (F-§12.1 / §12.2). +3 ToolEntries → describe() 192; ABI stays 3.

rc4 lifted the bind to HD per-block; the unbind/conjugate atoms it leaned on were still single-element. A bug-test sweep (upstream §12) caught the gap: loop_inv / loop_conj operate on ONE Cayley-Dickson element, but 2048 = 256·8 is also a power of two, so an HD block-octonion vector silently passed _as_loop and got treated as one giant 2048-D element — the natural loop_bind_hd(E, loop_inv(c)) was off by ‖·‖≈16 with no exception. This voxel closes that and completes the HD division family:

  • srmech.amsc.hdc.loop_conj_hd(x) — the missing per-block conjugate atom: the direct sum ⊕ of NB independent dim-8 loop_conjs. Class C over the direct-sum TILE layout; NO new class.
  • srmech.amsc.hdc.loop_inv_hd(x) — per-block Moufang inverse (x̄ₖ/⟨xₖ,xₖ⟩ per block); the per-block unbind key. Class-K clean (per-block norm² gate, never abs()).
  • srmech.amsc.hdc.loop_runbind_hd(a, b) — the HD RIGHT-unbind (per-block bₖ·conj(aₖ)). Where loop_unbind_hd peels the LEFT factor, this peels the RIGHT — recovers v from loop_bind_hd(v, a) exactly ((vₖ·aₖ)·conj(aₖ)=vₖ by alternativity; verified recovery <1e-15). Right-division is what a left-fold sequence store (((s₀·s₁)·s₂)…) needs to peel the most-recent element off the right (F-§12.2).
  • Footgun guard (F-§12.1): loop_inv / loop_conj now raise on an HD block-octonion input (a multiple of LOOP_DIM=8 wider than one octonion), pointing at the *_hd op — loud failure replaces the silent-wrong global result. The single-octonion path (dim ≤ 8) is unchanged.
  • tests/test_loop_hd_division.py: per-block conj/inv = the shipped single-element op block-wise; loop_inv_hd == loop_conj_hd on unit blocks; right-unbind round-trip; the loop_inv/loop_conj HD guard raises; the single-octonion path still works; multiple-of-8 validation.

+3 ToolEntries (189 → 192); ABI stays 3 (pure-Python, additive). The co-equal C peer is the arc's transpile-to-C step (Python-first ladder). Anchors: upstream §12.1 / §12.2 bug-test hand-down.

[0.7.0rc4] - 2026-06-02

MS #21 rc4 voxel — the block-octonion HD tiling (#811) + capacity-free vs Klein-4 (#812). +2 ToolEntries → describe() 189; ABI stays 3.

The fourth v0.7.0 voxel lifts the dim-8 octonion loop-bind to hyperdimensional width, all ground-truth computed from the shipped loop_bind (so it agrees with rc1 by construction; F289):

  • srmech.amsc.hdc.loop_bind_hd(x, y) — the block-octonion HD bind: D = NB·8 (canonical 2048 = 256·8) bound block-wise = the direct sum ⊕ of NB independent dim-8 Moufang binds. Block-DIAGONAL — block k of the result is exactly loop_bind(x_k, y_k); nothing couples blocks (verified err 0.0e+00). Class M (per-block loop_bind = M∘C with a Class-K residue) over a direct-sum tile layout — NO new class.
  • srmech.amsc.hdc.loop_unbind_hd(a, b) — per-block Moufang left-division conj(a_k)·b_k; recovers v from loop_bind_hd(a, v) for unit-per-block a (verified err 2.9e-15). Class-K clean (conjugate + bind, no abs()).
  • Capacity-free vs Klein-4 (owned verdict, F289/F277): at matched D=2048 the loop-bind's bind/unbind retrieval capacity is ≥ Klein-4 (identical through K=64; loop ≥ klein4 at K=128) — so it carries order + tree + direction (F274) at no capacity cost vs the commutative XOR bind. (Honest scope: the K=128 edge is one regime, not a general advantage; the load-bearing claim is the null cost.)
  • tests/test_loop_bind_hd.py (7 tests): block-diagonal err 0.0, block independence, per-block product = the shipped Cayley–Dickson table, unbind recovery < 1e-12, multiple-of-8 validation, the capacity-retrieval mechanism.

+2 ToolEntries (187 → 189); ABI stays 3 (pure-Python, additive). The co-equal C peer is the arc's transpile-to-C step (Python-first ladder). Anchors: F289 (rc4_groundtruth.py); capacity curve F277.

[0.7.0rc3] - 2026-06-02

MS #21 rc3 voxel — the loop-bind family slots into the compose engine (#813). Test-only proof; describe() stays 187; ABI stays 3.

#813 asks how the octonion loop-bind composes in srmech's operator-chain surface. The answer needed no new code: DEFAULT_CLASS_REGISTRY["M"] → srmech.amsc.hdc and ops resolve dynamically by name, so loop_bind / loop_conj / loop_associator / cross7 / g2_three_form already run as class="M", op="<name>" steps through srmech.amsc.compose.run_chain — the M∘C-with-K-residue cascade #813 describes.

  • tests/test_loop_bind_compose.py (4 tests): single-step loop_bind / loop_associator (the K residue) / cross7 / g2_three_form all resolve + run via run_chain; a two-step M∘C chain (loop_bind then loop_conj via @step[0]) proves multi-step composition.

Test-only voxel: NO new ToolEntries (describe() stays 187), NO new class, ABI stays 3 (pure-Python). The formal cascade-catalog .toml descriptor for the bind carries a [cascade.native] C symbol, so it lands with the C-transpile step at the end of the v0.7.0 arc (Python-first → transpile-to-C ladder). The user-authored / bring-your-own external cascade-TOML path is a separate scoped voxel.

[0.7.0rc2] - 2026-06-02

MS #21 rc2 voxel — the 7-D cross product + the G₂ associative 3-form (#813 / F281). +2 ToolEntries → describe() 187; ABI stays 3.

The second v0.7.0 voxel adds the loop-bind's companion invariants, both with ground-truth computed from the shipped loop_bind (so they agree with the rc1 bind by construction — no convention guess; F281):

  • srmech.amsc.hdc.cross7(x,y) = Im(loop_bind(x,y)) — the 7-D cross product (antisymmetric; for imaginary x,y = ½(xy−yx)). Class M∘C (bind ∘ imaginary-part ordering). Identity ‖x×y‖²=‖x‖²‖y‖²−⟨x,y⟩².
  • srmech.amsc.hdc.g2_three_form(x,y,z) = ⟨x, cross7(y,z)⟩ — the associative calibration 3-form; nonzero ±1 on exactly the 7 Fano associative 3-planes, 0 on the other 28 of C(7,3)=35. Class (M∘C)∘⟨·,·⟩.
  • Triality verdict (owned; F281): tests/test_cross7_g2_three_form.py asserts dim Der(loop_bind) == 14 (= G₂) and that a generic O(8) rotation breaks the bind ⟹ triality does NOT preserve the bind; the 14-dim G₂ does. (klein4_triality_cycle is the V₄-sector carrier, co-resident — not a bind-automorphism.)

NO new class (the 14 A–N hold; Class O stays dissolved). The #813 compose-engine registration is deferred to rc4 (lean discipline). Citations: Baez 2002 (7-D cross product / G₂); Harvey–Lawson 1982 (calibration 3-form). +2 ToolEntries (185 → 187); ABI stays 3 (pure-Python, additive).

[0.7.0rc1] - 2026-06-02

MS #21 loop-bind (Moufang) voxel — the k=7 gauge ARITHMETIC the triality symmetry is blind to (#814 / F271). Pure-Python core in srmech.amsc.hdc; +6 ToolEntries → describe() 185; ABI stays 3.

The first v0.7.0 voxel: srmech gains the octonion product (the gauge arithmetic) beside the triality automorphism it already had (the gauge symmetry). Ported faithfully from the loop_bind_moufang.py research oracle (F271/F272) as M∘C with a Class-K associator residue — NO new class (the 14 A–N hold; Class O stays dissolved); structure = the Moufang loop.

  • srmech.amsc.hdc.loop_bind — the Moufang / Cayley-Dickson octonion product (non-commutative + non-associative ⟹ (ab)c ≠ a(bc), the (4:3)|(3:4) chirality); loop_conj (conjugate); loop_inv (Moufang-division unbind, x̄/⟨x,x⟩); loop_left_op/loop_right_op (L/R = the order chirality); loop_associator (the Class-K residue (ab)c − a(bc), zero on a Fano line). Class-K clean (norm², no abs()). rc1 is the dim-8 octonion core (division holds); the block-octonion HD tiling (#811), the co-equal C peer, and the triality-automorphism composition check (#813) are later voxels.
  • tests/test_loop_bind_moufang.py (8 tests) reproduces the F271/F272 numerics: 7 associative Fano lines, [L_a,R_b]·x = −associator, the three Moufang identities, Jacobi-fails/Mal'cev-holds, the inverse unbinds, Artin associativity, e₀ identity.

Canonical SSoT: Baez, J.C. (2002) "The Octonions", Bull. Amer. Math. Soc. 39, 145. +6 ToolEntries (179 → 185). ABI stays 3 (pure-Python, additive). JPL audit ratchet unchanged.

Full changelog →

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

srmech-0.7.1.tar.gz (1.2 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

srmech-0.7.1-py3-none-any.whl (810.6 kB view details)

Uploaded Python 3

srmech-0.7.1-cp314-cp314-win_amd64.whl (874.9 kB view details)

Uploaded CPython 3.14Windows x86-64

srmech-0.7.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (851.1 kB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

srmech-0.7.1-cp314-cp314-macosx_11_0_arm64.whl (843.9 kB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

srmech-0.7.1-cp313-cp313-win_amd64.whl (870.8 kB view details)

Uploaded CPython 3.13Windows x86-64

srmech-0.7.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (851.1 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

srmech-0.7.1-cp313-cp313-macosx_11_0_arm64.whl (843.9 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

srmech-0.7.1-cp312-cp312-win_amd64.whl (870.8 kB view details)

Uploaded CPython 3.12Windows x86-64

srmech-0.7.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (851.1 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

srmech-0.7.1-cp312-cp312-macosx_11_0_arm64.whl (843.9 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

srmech-0.7.1-cp311-cp311-win_amd64.whl (870.8 kB view details)

Uploaded CPython 3.11Windows x86-64

srmech-0.7.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (851.1 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

srmech-0.7.1-cp311-cp311-macosx_11_0_arm64.whl (843.9 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

srmech-0.7.1-cp310-cp310-win_amd64.whl (870.8 kB view details)

Uploaded CPython 3.10Windows x86-64

srmech-0.7.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (851.1 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

srmech-0.7.1-cp310-cp310-macosx_11_0_arm64.whl (843.9 kB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

File details

Details for the file srmech-0.7.1.tar.gz.

File metadata

  • Download URL: srmech-0.7.1.tar.gz
  • Upload date:
  • Size: 1.2 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for srmech-0.7.1.tar.gz
Algorithm Hash digest
SHA256 c35e5d244c7d243fe219377694480f04f42da65929f7592893c366bfe6d0682f
MD5 8032db39c90d01d65ffb01f99735f2ad
BLAKE2b-256 8dae1d2e3cb5c26f8290a743025d090d768a4caa78f13e574e38f2378fdd18c0

See more details on using hashes here.

Provenance

The following attestation bundles were made for srmech-0.7.1.tar.gz:

Publisher: srmech-publish.yml on lemonforest/mlehaptics

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file srmech-0.7.1-py3-none-any.whl.

File metadata

  • Download URL: srmech-0.7.1-py3-none-any.whl
  • Upload date:
  • Size: 810.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for srmech-0.7.1-py3-none-any.whl
Algorithm Hash digest
SHA256 6c955b3109fa3b727546e2368e455f809b0cbac5255bdbe5b37da7573bee36a6
MD5 f23652cf4c5dad6c01daae0809e5a205
BLAKE2b-256 bbe5069bf4301d9ed69c58ff4fabc093c49e52b14eaa832c217ed565193dbb2f

See more details on using hashes here.

Provenance

The following attestation bundles were made for srmech-0.7.1-py3-none-any.whl:

Publisher: srmech-publish.yml on lemonforest/mlehaptics

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file srmech-0.7.1-cp314-cp314-win_amd64.whl.

File metadata

  • Download URL: srmech-0.7.1-cp314-cp314-win_amd64.whl
  • Upload date:
  • Size: 874.9 kB
  • Tags: CPython 3.14, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for srmech-0.7.1-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 8507b7fd5ceb5c6ac011236ba231aa0b88f6c34eb841118e93ee9ba09872739f
MD5 ef66521bbd2f24ea244c7e52633d3521
BLAKE2b-256 51b2d6dc4c112e6f718f276e3c43f34458797fcaa41bcdb55b839bb969ffbcd5

See more details on using hashes here.

Provenance

The following attestation bundles were made for srmech-0.7.1-cp314-cp314-win_amd64.whl:

Publisher: srmech-publish.yml on lemonforest/mlehaptics

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file srmech-0.7.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for srmech-0.7.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 2352d66cb36864eab552e103c6ebcadcc7669234b42715a612d43525b3a2657a
MD5 a7e09c766ebeff236bdf51a4ec4ca0b1
BLAKE2b-256 40ebb968c0d6f6500ca3f37967a8b24f6d05456793f3cd9d1e432f6932856194

See more details on using hashes here.

Provenance

The following attestation bundles were made for srmech-0.7.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl:

Publisher: srmech-publish.yml on lemonforest/mlehaptics

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file srmech-0.7.1-cp314-cp314-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for srmech-0.7.1-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 4e39cb7e90faf8626c53eb7693f4309deb1594c491bee255823e11c05da19481
MD5 e487129da4dc75e7fb01952ad40f5b5c
BLAKE2b-256 37bd4dbfb7b71dd2efc991c2af5599ad883ba1087fdd76f3ca4240540d725d5b

See more details on using hashes here.

Provenance

The following attestation bundles were made for srmech-0.7.1-cp314-cp314-macosx_11_0_arm64.whl:

Publisher: srmech-publish.yml on lemonforest/mlehaptics

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file srmech-0.7.1-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: srmech-0.7.1-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 870.8 kB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for srmech-0.7.1-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 d07d51cd40ee97303e2d206dbf31c63387fb5272a6b0ac77b47077d618c8a390
MD5 8e54fed42f853a6970273ea240d9106f
BLAKE2b-256 b54ce3a6f79b24d036ee16571cca9acf9653f36183a6afc38e862db5399e5511

See more details on using hashes here.

Provenance

The following attestation bundles were made for srmech-0.7.1-cp313-cp313-win_amd64.whl:

Publisher: srmech-publish.yml on lemonforest/mlehaptics

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file srmech-0.7.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for srmech-0.7.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 8ddfcfb7efd3b952b43266a86e83782364dc14fbbda0e88a1d7d8320e3edfc63
MD5 2eff0bfaef746f93d1c9e75f43e63fa7
BLAKE2b-256 91494df349dd194530f240987328e7704ca3b041bce7374cffb397d50f75f07e

See more details on using hashes here.

Provenance

The following attestation bundles were made for srmech-0.7.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl:

Publisher: srmech-publish.yml on lemonforest/mlehaptics

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file srmech-0.7.1-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for srmech-0.7.1-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 0380be981be4cc706150045c7049498c19992c0c0b6ce1464452199e5c52cd3b
MD5 c2110a528854bf4ac3f6878e0b75614b
BLAKE2b-256 50ce4aff8ea4a85023f40a02b91836c2b3f61c216879e0f6c7d6170f81072ab1

See more details on using hashes here.

Provenance

The following attestation bundles were made for srmech-0.7.1-cp313-cp313-macosx_11_0_arm64.whl:

Publisher: srmech-publish.yml on lemonforest/mlehaptics

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file srmech-0.7.1-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: srmech-0.7.1-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 870.8 kB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for srmech-0.7.1-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 6f45d4aa787801016c07d3564399eec25a967c7615d8f1dce502c1785af76341
MD5 6db74ebf99ec85087926ce286605f9a6
BLAKE2b-256 d3342ed3c7668a03dad78607fe8971443ca63e872411825718c738ac30acfda8

See more details on using hashes here.

Provenance

The following attestation bundles were made for srmech-0.7.1-cp312-cp312-win_amd64.whl:

Publisher: srmech-publish.yml on lemonforest/mlehaptics

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file srmech-0.7.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for srmech-0.7.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 ce1dbbccb947ad05c3466bee3eab98214e95a3dcec650cac0dba0d799fdc3231
MD5 208448b2bf38d78a8520080fa921f0c8
BLAKE2b-256 02703082a4b88b15137df585d50d9397825f7a5b7a20dc86ef89376a8efc1044

See more details on using hashes here.

Provenance

The following attestation bundles were made for srmech-0.7.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl:

Publisher: srmech-publish.yml on lemonforest/mlehaptics

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file srmech-0.7.1-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for srmech-0.7.1-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 2483675bee0e4021f0dc4297f9df67a276e525689bbcfb3b4502400c748ffa1d
MD5 6475d03d029bd7107cc8ce6421c170ee
BLAKE2b-256 a3732346833c9ee15a532099e3ed33bf06d6f838ba8b45a98df94729a80dc026

See more details on using hashes here.

Provenance

The following attestation bundles were made for srmech-0.7.1-cp312-cp312-macosx_11_0_arm64.whl:

Publisher: srmech-publish.yml on lemonforest/mlehaptics

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file srmech-0.7.1-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: srmech-0.7.1-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 870.8 kB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for srmech-0.7.1-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 389a29f67f457215ae15c4f04a01168b2d01a27d9f90b218fc0341b41487a9ab
MD5 858d76195d39d7863e425b182833fde5
BLAKE2b-256 04cc2cd62bd0e66104415d057eba6bf726b49d8f37fad7d14008f5f94cfd20e4

See more details on using hashes here.

Provenance

The following attestation bundles were made for srmech-0.7.1-cp311-cp311-win_amd64.whl:

Publisher: srmech-publish.yml on lemonforest/mlehaptics

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file srmech-0.7.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for srmech-0.7.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 c5475520924c73a3d800773483c5194c8880b6af3d39aef14e084c14e5920fed
MD5 9e4ecb33ee00db78dc08efec1c6b6925
BLAKE2b-256 468e1e5e1599d06c7a0830b06eb9ac14bcd529fcef3e1d0b9a01f0b8f84119c4

See more details on using hashes here.

Provenance

The following attestation bundles were made for srmech-0.7.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl:

Publisher: srmech-publish.yml on lemonforest/mlehaptics

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file srmech-0.7.1-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for srmech-0.7.1-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 fbd015aa76f6f2830429e3f68c0287c4a1b4472c14aad6a4716db262ce2c2aad
MD5 26606288bfe6cfda2b745fd44e5c822b
BLAKE2b-256 7f1af18ef0bf4e46b06492fae952534227597ca53b2bc83da929bf80da4434c4

See more details on using hashes here.

Provenance

The following attestation bundles were made for srmech-0.7.1-cp311-cp311-macosx_11_0_arm64.whl:

Publisher: srmech-publish.yml on lemonforest/mlehaptics

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file srmech-0.7.1-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: srmech-0.7.1-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 870.8 kB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for srmech-0.7.1-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 e7db789fb8c7c8534a7ea570ac3474ca6054a774a916be45b9d31be6a79dbdee
MD5 e40fcce1d509659d5dfbf1b9ea8e5713
BLAKE2b-256 ab1571ade7211b91c5436441077242e9c25c5d9a398f0bee99d5fab2702746e7

See more details on using hashes here.

Provenance

The following attestation bundles were made for srmech-0.7.1-cp310-cp310-win_amd64.whl:

Publisher: srmech-publish.yml on lemonforest/mlehaptics

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file srmech-0.7.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for srmech-0.7.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 a1ac5eaeb8146327a813f42cb995829e38eaecea50e09371c677187c9631bd99
MD5 d282fc9babcd0a8a8044e6c6df4ba39e
BLAKE2b-256 2762fce8c7e76bb948674f293b7224fd49a3f211ca0ef24faf22dce3eff3e37d

See more details on using hashes here.

Provenance

The following attestation bundles were made for srmech-0.7.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl:

Publisher: srmech-publish.yml on lemonforest/mlehaptics

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file srmech-0.7.1-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for srmech-0.7.1-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 d82daa685cfdb8551589818fb1699ff93af6267e2b4d91dcb99c46cd927a4975
MD5 eb4c63cad680ae1be7f962e63ae73c86
BLAKE2b-256 bab1929c7e208fa394f5d55afa04b966b1578d30f7b2ff3fdfcb45258784946f

See more details on using hashes here.

Provenance

The following attestation bundles were made for srmech-0.7.1-cp310-cp310-macosx_11_0_arm64.whl:

Publisher: srmech-publish.yml on lemonforest/mlehaptics

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page