This release is a pre-release and may not be stable for production use.
Assay
TL;DR: Assay combines measurements recorded on different scales into one explainable score while preserving every input, transformation, and contribution.
Assay is a small scoring engine for formulas you can write down and replay. Give it measurements, their native scales, and one explicit combining method. It returns the score and the arithmetic behind every row.
Installation status
Status:
assay-engine0.5.0.dev3 and@edgeproc/assay0.5.0-dev.3 are the authorized prerelease pair. Check both registries before installing.
The base registry commands are pip install assay-engine and
npm install @edgeproc/assay. For this prerelease, pin them as
pip install assay-engine==0.5.0.dev3 and npm install @edgeproc/assay@0.5.0-dev.3,
and use them only after both exact versions appear in their registries. The checkout
path below remains runnable before, during, and after publication.
Run the Northstar example
From the checkout root, run:
bash examples/run_composite.sh
The script builds the real Python wheel and npm tarball, installs each in an isolated temporary environment, computes through both public package surfaces, checks every typed field and binary64 value against the committed oracle, and prints one explanation:
Northstar weighted score: 0.92
Method: weighted_mean @ northstar.2026-08-12
Interval: null — all inputs are deterministic
security 19/20 -> 0.950000 × 0.20 = 0.19
privacy 15/15 -> 1.000000 × 0.15 = 0.15
reliability 15/15 -> 1.000000 × 0.15 = 0.15
performance 12/15 -> 0.800000 × 0.15 = 0.12
correctness 15/15 -> 1.000000 × 0.15 = 0.15
clarity 14/15 -> 0.933333 × 0.15 = 0.14
production 2/5 -> 0.400000 × 0.05 = 0.02
Total: 0.92
inputs_hash: sha256:0266b1c59c97bacf85dc945685c55bb4386856b525249c7d5663a8edf020ba06
Parity: Python and TypeScript fields and values match
This is uncapped arithmetic only. Northstar hard caps, evidence grades, release decisions, and other product policies remain outside Assay.
How the score is calculated
The example declares seven components on three native scales. Assay first normalizes each value to 0–1, divides its positive weight by the declared total of 100, then adds the contributions in declaration order:
security: (19 - 0) / (20 - 0) × 20/100 = 0.19
privacy: (15 - 0) / (15 - 0) × 15/100 = 0.15
reliability: (15 - 0) / (15 - 0) × 15/100 = 0.15
performance: (12 - 0) / (15 - 0) × 15/100 = 0.12
correctness: (15 - 0) / (15 - 0) × 15/100 = 0.15
clarity: (14 - 0) / (15 - 0) × 15/100 = 0.14
production: ( 2 - 0) / ( 5 - 0) × 5/100 = 0.02
total: 0.92
Assay's portable typed API supports exactly three composition methods:
weighted_meannormalizes components, converts positive declared weights into coefficients that sum to one, and adds their contributions.additiveapplies each raw term's explicit add or subtract operation and coefficient, then optionally clamps the final total.minimumnormalizes components and selects the first lowest value, making declaration order the tie-breaker.
The method is chosen by the application because it owns the formula. Assay never silently replaces a shipped formula with an average. See Methods for validation, uncertainty, and exact arithmetic rules.
Legacy Python compatibility
The wheel retains a Python-only migration adapter at the deep import assay.composite:
SubScore plus composite(...). It is not exported from the package root, does not
return the typed method or inputs_hash fields, and has no TypeScript equivalent. For
all new code, use package-root parse_request() and compose() with one of the three
portable methods above.
Every result field is explicit:
| Field | Meaning |
|---|---|
schema |
Serialized result contract, currently assay.result/v1. |
method.id |
One of the three portable typed composition methods. |
method.version |
Caller-declared provenance for this formula revision. |
score |
Final finite binary64 result. |
interval |
Propagated uncertainty bounds, or null for deterministic inputs. |
clamp |
Requested boundary policy, or null only for unclamped additive scoring. |
intercept |
Additive starting value; null for the other methods. |
weight_total |
Weighted-mean declared weight total; otherwise null. |
components |
Ordered arithmetic rows retained for replay. |
id |
Stable input identifier for one row. |
raw |
Original finite input value; it may be sensitive. |
normalized |
0–1 transformed value, or null for additive rows. |
declared_weight |
Original weighted-mean weight, otherwise null. |
operation |
add or subtract; normalized methods use add. |
coefficient |
Effective multiplier used for the row. |
contribution |
Pre-operation product: normalized × coefficient or raw × coefficient. For additive rows, operation controls how it changes the running total. |
contribution_interval |
Row uncertainty contribution, or null. |
inputs_hash |
Order-preserving request fingerprint used for replay comparison. |
selected_component_id |
Minimum-method bottleneck ID; otherwise null. |
Python and TypeScript parity covers the three methods, typed field/value structure,
field and component order, IEEE-754 binary64 values, and the exact inputs_hash. It
does not promise byte-identical output from language-native JSON serializers; for
example, one serializer may spell the same number 19.0 and another 19.
What this proves
For a validated request, the result exposes the selected method and version, preserves the scored inputs in declaration order, shows every transformation and contribution, and can be replayed under the same contract. The committed vectors prove the Python and TypeScript composition surfaces agree semantically on all three methods and on the exact request fingerprint.
What this does not prove
Assay does not prove input truth, completeness, fairness, freshness, authenticity,
policy compliance, or decision quality. inputs_hash is a deterministic fingerprint,
not authentication or tamper evidence. A caller-declared method version records
provenance; it does not validate the methodology.
Application-owned bands, thresholds, hard gates, fairness review, abstention policy, release decisions, and other downstream decisions remain application-owned. Results retain raw values, so callers must treat them according to the sensitivity of their inputs.
Architecture
There are exactly two production source-to-artifact mappings:
src/assay/ ──> assay-engine wheel ──> import assay
ts/src/ ──> @edgeproc/assay npm tarball ──> import "@edgeproc/assay"
examples/, docs/, tests/, and testdata/ are repository support files, not
runtime packages. The Python package is the broader surface: composition is in the
base wheel, the command line uses the cli extra, and scientific calculators use the
metrics extra. The npm tarball provides composition plus a smaller set of optional
binary and ranking calculators.
This README is self-contained because the Python source distribution currently ships it, but does not ship the repository's quickstart, docs, or examples. The detailed architecture, operations contract, and quickstart are available in the source checkout.
Use the local candidate directly
Python 3.13 code imports assay from the distribution named assay-engine:
from assay import compose, parse_request
request = parse_request(
{
"method": "minimum",
"method_version": "service-health.v1",
"components": [
{
"id": "availability",
"label": "Availability",
"value": 99.9,
"scale": {"minimum": 99.0, "maximum": 100.0, "direction": "higher_is_better"},
"interval": None,
"weight": None,
},
{
"id": "latency",
"label": "Latency",
"value": 180.0,
"scale": {"minimum": 100.0, "maximum": 500.0, "direction": "lower_is_better"},
"interval": None,
"weight": None,
},
],
"clamp": "reject",
}
)
result = compose(request)
print(result.score, result.selected_component_id)
The command line accepts typed JSON for assay compose, assay measure, and
assay explain. Build and installation commands for the source checkout are in
the quickstart.
Optional calculators
Python's optional scientific surface calculates typed binary-classification, ranking, calibration, agreement, and uncertainty reports. TypeScript exposes a smaller binary and ranking calculator set. Complete optional-metric parity is not claimed, and the calculator resource ceilings do not limit core composition. See Methods and Operations for the exact boundary.
Optional integration
Assay computes scores; Avow seals evidence. They are separate products in separate repositories, and neither imports or requires the other. The already-published avow 0.4.1 and @edgeproc/avow 0.4.1 artifacts remain unchanged.
An application may pass an ordinary Assay result to a separately selected evidence system. That adapter belongs to the application or to its own versioned integration package, never to either core scoring package.
License
MIT © Harish Seshadri
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file assay_engine-0.5.0.dev3.tar.gz.
File metadata
- Download URL: assay_engine-0.5.0.dev3.tar.gz
- Upload date:
- Size: 47.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
303ef50ee174ce3d7de1d2ab0401873eb5bc2d09668f47083a991fe7a3a84f62
|
|
| MD5 |
7300abb370f1c97e746bc45aa646f662
|
|
| BLAKE2b-256 |
2f1ccb5586101dffa8150979dbbfa36257b5258d2a7b575cc0785130ddeb2947
|
Provenance
The following attestation bundles were made for assay_engine-0.5.0.dev3.tar.gz:
Publisher:
publish.yml on hseshadr/assay
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
assay_engine-0.5.0.dev3.tar.gz -
Subject digest:
303ef50ee174ce3d7de1d2ab0401873eb5bc2d09668f47083a991fe7a3a84f62 - Sigstore transparency entry: 2582542474
- Sigstore integration time:
-
Permalink:
hseshadr/assay@d3e005d4dc86369b725ba431c23d6c7bd43cb0a6 -
Branch / Tag:
refs/tags/v0.5.0-dev.3 - Owner: https://github.com/hseshadr
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d3e005d4dc86369b725ba431c23d6c7bd43cb0a6 -
Trigger Event:
push
-
Statement type:
File details
Details for the file assay_engine-0.5.0.dev3-py3-none-any.whl.
File metadata
- Download URL: assay_engine-0.5.0.dev3-py3-none-any.whl
- Upload date:
- Size: 55.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
72beb0a3b33962147e5174c7b71feb629cd76b8b0efbd127f52ed6a43c1f2f43
|
|
| MD5 |
e574d25f260f4ad4aaefef3c6c027ac0
|
|
| BLAKE2b-256 |
450522dad286c09d630661b5558b4ff79809ada6cb42c6360b42310e0ee6fc30
|
Provenance
The following attestation bundles were made for assay_engine-0.5.0.dev3-py3-none-any.whl:
Publisher:
publish.yml on hseshadr/assay
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
assay_engine-0.5.0.dev3-py3-none-any.whl -
Subject digest:
72beb0a3b33962147e5174c7b71feb629cd76b8b0efbd127f52ed6a43c1f2f43 - Sigstore transparency entry: 2582542483
- Sigstore integration time:
-
Permalink:
hseshadr/assay@d3e005d4dc86369b725ba431c23d6c7bd43cb0a6 -
Branch / Tag:
refs/tags/v0.5.0-dev.3 - Owner: https://github.com/hseshadr
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d3e005d4dc86369b725ba431c23d6c7bd43cb0a6 -
Trigger Event:
push
-
Statement type: