@qlm/measure
Open measurement SDK for education AI — evidence events, record verification, and dataset clients.
v0.1.0 · Apache-2.0 · Documentation · Manifesto
Limitations (read first)
- This SDK is the public interface layer, not the measurement engine. The estimation service (Bayesian posteriors, IRT ability estimation, calibration) is QLM's hosted engine.
- The verifier checks bookkeeping integrity, not estimation correctness. It can tell you if a record was tampered with. It cannot tell you if the posteriors are accurate. That distinction is the design.
- Evidence event schemas are v0.1 and may change in minor versions. Pin your dependency.
- The ontology client requires the QLM API to be reachable. No offline mode.
- Classifier runners require model weights downloaded separately from Hugging Face.
What it is
- Typed evidence-event vocabulary (
ObservationEvent) — a schema any tool can emit to describe a student interaction, with scaffold level, depth, epistemic mode. - Buffered telemetry emitter (
MeasurementEmitter) — sends events to the measurement service with sendBeacon fallback. - Evidence record format + replay verifier (
verifyRecord,replayToVersion) — audits a record's hash-chain and posterior-chain integrity without containing any estimation mathematics. - Dataset clients (
OntologyClient) — typed wrappers over the public misconception ontology, learning graph, and standards alignment APIs. - Engine client (
EngineClient) — commercial boundary for the hosted measurement service.
What it is NOT
- Not the estimation engine (that runs server-side at QLM)
- Not a standalone learning analytics system
- Not a replacement for the measurement service
- Not a classifier or scorer (those are separate open-weights releases)
Install
npm install @qlm/measure
Quickstart
1. Query the misconception ontology (no auth)
import { OntologyClient } from "@qlm/measure/clients";
const client = new OntologyClient();
const misconceptions = await client.getMisconceptions("math");
console.log(`${misconceptions.length} math misconceptions`);
2. Emit measurement events
import { MeasurementEmitter } from "@qlm/measure/emitter";
const emitter = new MeasurementEmitter({
baseUrl: "https://play.quantumlearningmachines.com",
product: "my-tool",
});
emitter.emit({
eventType: "answer_submitted",
eventCategory: "learning",
domain: "math",
topic: "fractions",
payload: { questionId: "q1", correct: true },
});
3. Verify an evidence record (tamper detection)
import { verifyRecord } from "@qlm/measure/verifier";
const result = verifyRecord(record);
if (!result.valid) {
for (const v of result.violations) {
console.log(`[${v.category}] v${v.version}: ${v.message}`);
}
}
Schema Reference
ObservationEvent (evidence input)
| Field | Type | Required | Description |
|---|---|---|---|
| studentId | string | yes | Pseudonymous ID (no PII) |
| sessionId | string | yes | Session identifier |
| source | string | yes | Source system |
| timestamp | string | yes | ISO 8601 |
| correct | boolean | yes | Was the response correct? |
| responseTimeMs | number | yes | Response time in ms |
| domain | string | yes | Subject domain |
| scaffoldType | ScaffoldType | no | What preceded this response |
| misconceptionId | string | no | Detected misconception ID |
| classifierConfidence | number | no | Classifier confidence (0-1) |
| skillId | string | no | Skill being assessed |
| score | number | no | Response score (0-1) |
| difficulty | number | no | Item difficulty (0-1) |
| epistemicMode | EpistemicMode | no | How student arrived at answer |
| ext | Record | no | Extension namespace |
Enums
ScaffoldType: none, socratic, probing, metacognitive, scaffolding, explain, hint, demonstrate
EpistemicMode: experience, inference, analogy, testimony
DepthLevel: surface, conceptual, transfer, integration
TriageResult: correct, slip, misconception, disengagement, ambiguous
Verifier
The verifier checks:
- Schema validity (required fields, correct types)
- Strictly monotonic version numbers
- Timestamp monotonicity (configurable tolerance)
- Hash-chain integrity (prevHash linkage, entryHash recompute)
- Posterior chain consistency (each prior = previous updated)
- Compaction-boundary integrity
- Enum validity
What it deliberately cannot check:
- Whether posteriors are correctly computed (that requires the engine)
- Whether evidential weights are appropriate (those are calibrated server-side)
- Whether triage classifications are accurate (those use rules not in this package)
This is the design: verify instead of trust.
Privacy
studentIdMUST be a pseudonymous identifier. Never include names, emails, or other PII.- Events are buffered locally and sent via sendBeacon/fetch. No cookies are set.
- The SDK does not store any data persistently.
Versioning
- Semver from 0.1.0.
- Schema changes in minor versions (0.2, 0.3).
- Breaking changes in major versions (1.0).
- Pin your dependency version.
Links
License
Apache-2.0. See LICENSE.
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 qlm_measure-0.1.0.tar.gz.
File metadata
- Download URL: qlm_measure-0.1.0.tar.gz
- Upload date:
- Size: 9.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
304dccee3112fe5649fe35f6ddec011b07b8f4cc17dd7c233e77a8d6bdc9d08e
|
|
| MD5 |
afb19ffa27102ad753e82696625c4615
|
|
| BLAKE2b-256 |
36f401a1adfdd19fb28c12fd979091a60c02b388b2f6ef0a4cc9c86ac94099cc
|
File details
Details for the file qlm_measure-0.1.0-py3-none-any.whl.
File metadata
- Download URL: qlm_measure-0.1.0-py3-none-any.whl
- Upload date:
- Size: 8.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
58a1b066d037f2280dab3dd6e194f4492ea346d5f925f1d00c8f22252292d24c
|
|
| MD5 |
7875f01aaa030f659c3afb6a2ef862b1
|
|
| BLAKE2b-256 |
b6fc4f6f080bc559a336054518fe3f4ede3ba74de2f88b22e14934d0e1521fb4
|