Metadata-Version: 2.4
Name: srmech
Version: 0.3.1
Summary: Stored-Relationship Mechanism research package: home of the Attested Multi-Source Collector/Catalog (AMSC) framework — Mathematical Provenance Record v1 on-disk format, descriptor TOML loader, six adapters (html/json/csv/netcdf/geotiff/literature), universal catalog bridge with register_attested_root cross-package overlay, and schema-gap-driven trigger. Native C dispatch (SHA-256 + NDJSON line reader) with pure-Python fallback for Pyodide / WASM.
Keywords: stored-relationship,mechanism,attested,provenance,ndjson,ground-proof,research
Author: Steven Kirkland
License-Expression: GPL-3.0-or-later
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Scientific/Engineering
Classifier: Typing :: Typed
Project-URL: Homepage, https://github.com/lemonforest/mlehaptics/tree/main/docs/srmech/python
Project-URL: Repository, https://github.com/lemonforest/mlehaptics
Project-URL: Issues, https://github.com/lemonforest/mlehaptics/issues
Project-URL: Changelog, https://github.com/lemonforest/mlehaptics/blob/main/docs/srmech/python/CHANGELOG.md
Project-URL: Research notebook, https://github.com/lemonforest/mlehaptics/blob/main/docs/srmech/srmech_research_notebook.md
Requires-Python: >=3.10
Requires-Dist: tomli>=2.0; python_version < "3.11"
Provides-Extra: validation
Requires-Dist: jsonschema>=4.0; extra == "validation"
Provides-Extra: collectors
Requires-Dist: requests>=2.28; extra == "collectors"
Requires-Dist: beautifulsoup4>=4.11; extra == "collectors"
Provides-Extra: tests
Requires-Dist: pytest>=7.0; extra == "tests"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: build; extra == "dev"
Requires-Dist: twine; extra == "dev"
Requires-Dist: scikit-build-core>=0.10; extra == "dev"
Requires-Dist: cmake>=3.23; extra == "dev"
Requires-Dist: hatchling>=1.18; extra == "dev"
Requires-Dist: jsonschema>=4.0; extra == "dev"
Requires-Dist: requests>=2.28; extra == "dev"
Requires-Dist: beautifulsoup4>=4.11; extra == "dev"
Description-Content-Type: text/markdown

# srmech

**Status:** **v0.2.0 on PyPI.** The Task #201 build-out (rc3 → rc9, then v0.2.0rc1 → rc2 on TestPyPI) ships srmech at peer quality with ephemerides-spectral: native C dispatch for SHA-256 + NDJSON line reader, scikit-build-core + CMake build, cibuildwheel matrix (Linux/macOS/Windows × py3.10–3.14), pure-Python fallback for Pyodide / WASM, and JPL Power-of-Ten audit. Cross-package integration with ephemerides-spectral verified during the rc series. The earlier `v0.1.0` shipped the pure-Python AMSC framework via the Task #197 refactor.

`srmech` (Stored-Relationship Mechanism) is a research package. It ships the **Attested Multi-Source Collector/Catalog (AMSC) framework** — the Mathematical Provenance Record (MPR) v1 on-disk format, descriptor TOML loader, six fetch/parse adapters, and a universal catalog bridge surface that downstream packages register their own catalog SSOTs with at import time. **Native C** for the SHA-256 attestation hash + NDJSON streaming reader; pure-Python fallback for Pyodide / WASM environments.

### Why "Collector/Catalog"?

Both readings of **AMSC** are correct and the abbreviation is the same either way:

- At **collection time** (T1 / T3 lifecycle stages — fetch / live-query / re-bake), the adapter classes are *collecting* attested rows from upstream archives. The framework's name describes what it's doing in that moment: **Attested Multi-Source Collector**.
- 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()`. The same framework name describes the post-collection state: **Attested Multi-Source Catalog**.

Both names abbreviate to AMSC. Pick whichever fits the lifecycle stage you're describing — the framework is one thing wearing two hats.

The package was extracted from `ephemerides-spectral`'s `_research/` mirror in Task #197 so that other spectral-research packages can consume the AMSC framework without depending on ephemerides-spectral. The catalog SSOTs themselves do NOT migrate — each downstream package registers its own root via `srmech.amsc.catalog.register_attested_root(path, source=...)`.

## Public API

```python
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,
)
```

## Cross-package catalog registration

The load-bearing API for cross-package use:

```python
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",
)
```

Call this once at package-import time. 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.

## Adapter classes

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.

## Install

```bash
pip install srmech                  # core (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
```

## License

GPL-3.0-or-later. See [LICENSE](LICENSE).
