@qlm/learnlog-mcp 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +44 -0
- package/LICENSE +201 -0
- package/NOTICE +43 -0
- package/README.md +121 -2
- package/data/SOURCE_CORRECTION.md +9 -0
- package/data/THIRD_PARTY_DATA.md +148 -0
- package/data/examples/chain-tpc-clinical-v2-tampered.json +97 -0
- package/data/examples/chain-tpc-clinical-v2.json +95 -0
- package/data/examples/evidence-record-clean.json +173 -0
- package/data/examples/evidence-record-tampered.json +173 -0
- package/data/labpath-worlds.json +107 -0
- package/data/preprint/README.md +10 -0
- package/data/preprint/assistments_episodes.json +37 -0
- package/data/preprint/cross_source_episodes.json +63 -0
- package/data/provenance/oatutor.json +84 -0
- package/data/provenance/source-audit.json +69 -0
- package/data/provenance/tutormoments.json +91 -0
- package/data/samples/explicit-assistance-SYNTHETIC.jsonl +5 -0
- package/data/samples/oatutor-real-participants.csv +13 -0
- package/data/samples/sandpiper-SYNTHETIC.csv +9 -0
- package/data/samples/tutormoments-real-transcripts.jsonl +2 -0
- package/dist/bin.js +6 -0
- package/dist/episodes.js +488 -0
- package/dist/files.js +39 -0
- package/dist/package.js +14 -0
- package/dist/py.js +419 -0
- package/dist/respond.js +47 -0
- package/dist/sealed.js +31 -0
- package/dist/server.js +115 -0
- package/dist/stages.js +35 -0
- package/dist/tools/formats.js +35 -0
- package/dist/tools/inventory.js +179 -0
- package/dist/tools/learning-graph.js +111 -0
- package/dist/tools/misconceptions.js +54 -0
- package/dist/tools/preprint.js +241 -0
- package/dist/tools/qlm-datasets.js +56 -0
- package/dist/tools/transform.js +61 -0
- package/dist/tools/validate.js +47 -0
- package/dist/tools/verify-credential.js +155 -0
- package/dist/tools/verify-evidence.js +51 -0
- package/dist/tools/worlds.js +24 -0
- package/dist/transformer.js +92 -0
- package/dist/zip.js +71 -0
- package/package.json +66 -4
- package/skills/learnlog-assistments/SKILL.md +38 -0
- package/skills/learnlog-export-to-action/SKILL.md +31 -0
- package/skills/learnlog-learning-commons/SKILL.md +33 -0
- package/skills/learnlog-nto-sandpiper/SKILL.md +31 -0
- package/vendor/PROVENANCE.json +259 -0
- package/vendor/qlm-measure/checks.d.ts +24 -0
- package/vendor/qlm-measure/checks.js +42 -0
- package/vendor/qlm-measure/cli.d.ts +17 -0
- package/vendor/qlm-measure/cli.js +461 -0
- package/vendor/qlm-measure/rules.d.ts +10 -0
- package/vendor/qlm-measure/rules.js +46 -0
- package/vendor/qlm-measure/schemes/index.d.ts +133 -0
- package/vendor/qlm-measure/schemes/index.js +339 -0
- package/vendor/qlm-measure/schemes/node.d.ts +8 -0
- package/vendor/qlm-measure/schemes/node.js +15 -0
- package/vendor/qlm-measure/schemes/products.d.ts +38 -0
- package/vendor/qlm-measure/schemes/products.js +725 -0
- package/vendor/qlm-measure/verifier/hash.d.ts +27 -0
- package/vendor/qlm-measure/verifier/hash.js +163 -0
- package/vendor/qlm-measure/verifier/verify-record.d.ts +22 -0
- package/vendor/qlm-measure/verifier/verify-record.js +123 -0
- package/vendor/qlm-measure/verifier-v03.d.ts +24 -0
- package/vendor/qlm-measure/verifier-v03.js +205 -0
- package/vendor/transformer/LICENSE.txt +29 -0
- package/vendor/transformer/cross-source-analysis-data.d.mts +3 -0
- package/vendor/transformer/cross-source-analysis-data.mjs +238 -0
- package/vendor/transformer/engine.d.mts +61 -0
- package/vendor/transformer/engine.mjs +445 -0
- package/vendor/transformer/profiles.mjs +309 -0
- package/vendor/transformer/research-semantics.mjs +1453 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: learnlog-assistments
|
|
3
|
+
description: Read an ASSISTments 2012-13 School Data with Affect file (your own copy) with the Learnlog MCP and say, stage by stage, what it records about help and what it can't show. Counts only; rows never leave the file.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# ASSISTments + Learnlog: what a hint log actually records
|
|
7
|
+
|
|
8
|
+
Use this when someone has the ASSISTments 2012-13 School Data with Affect CSV, or a file in the same layout, and asks what it says about help.
|
|
9
|
+
|
|
10
|
+
## What you need
|
|
11
|
+
- The Learnlog MCP (`npx -y @qlm/learnlog-mcp`).
|
|
12
|
+
- The person's own copy of the file. It isn't bundled anywhere: get it from ASSISTments under its terms of use (https://sites.google.com/site/assistmentsdata/datasets/2012-13-school-data-with-affect).
|
|
13
|
+
|
|
14
|
+
## Steps
|
|
15
|
+
1. Call Learnlog `assistance_inventory` with `assistments_csv` set to the file's full path. Nothing else is needed.
|
|
16
|
+
2. Report what the file records, stage by stage, from the tool's `stages.assistments`:
|
|
17
|
+
- requested: the count, split into hints short of the answer, hints to the answer (bottom-out) and asking for steps;
|
|
18
|
+
- offered: candidates only, by rule (steps likely given after a wrong first answer), not established offers;
|
|
19
|
+
- generated, transmitted, accepted: not recorded;
|
|
20
|
+
- displayed: not logged as its own event.
|
|
21
|
+
3. Give the denominators the tool gives: main problems, scaffolding logs, students, and students who ever asked.
|
|
22
|
+
4. If the tool says `is_the_preprint_release: false`, say the numbers are this file's, not the Learnlog preprint's. If it is the pinned release, report the comparison it returns.
|
|
23
|
+
5. Close with what the file can't show, from `cannot_conclude` and `does_not_show`.
|
|
24
|
+
6. For the topic in the last section, use the skills with the most requests from `assistments_requests_by_skill` (counts by the file's own skill labels). Many requests on a skill isn't evidence of a misconception; it's where to look first.
|
|
25
|
+
|
|
26
|
+
## Keep these straight
|
|
27
|
+
- Counts only. Never ask for, quote or reconstruct rows, IDs or answers.
|
|
28
|
+
- "Not recorded" is never "none", and never zero.
|
|
29
|
+
- The four affect values are detector inferences, not observations.
|
|
30
|
+
- Asking for a hint isn't evidence that a hint was read or helped.
|
|
31
|
+
- If the file is synthetic (made only in the same layout for a demo), say so in the first line of the answer.
|
|
32
|
+
|
|
33
|
+
## Then: misconceptions and LabPath worlds
|
|
34
|
+
Always finish here.
|
|
35
|
+
1. **Pick the topic.** Use what the person named, or the data's own labels (an ASSISTments skill, a Sandpiper code about a student error, a standard, an activity id). Say where the topic came from. If you inferred it from the text, say that it's your inference.
|
|
36
|
+
2. **Name the likely beliefs.** Call `qlm_misconceptions` with words from the topic, and a domain when it's clear. For the top two or three matches give the student belief, one way to check for it (its diagnostic question when it has one), and its teacher intervention.
|
|
37
|
+
3. **Suggest LabPath worlds.** Each match lists its `worlds`. Suggest them by name, with each world's link exactly as the tool gives it. Never write a link the tool didn't return. For a science topic, `qlm_learning_graph` on a world says what to do before and after it.
|
|
38
|
+
4. **Say what this is.** These are research-based possibilities to check with the students, not a diagnosis of them.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: learnlog-export-to-action
|
|
3
|
+
description: Take a tutoring or learning export (TutorMoments, OATutor, explicit help events, or a Sandpiper run), convert it to Learnlog on this computer, say what it records about help and what it can't show, then name likely misconceptions and the LabPath worlds that work on them.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# From an export to the next teaching move
|
|
7
|
+
|
|
8
|
+
Use this when someone gives you an export file, or asks what their logs say about help.
|
|
9
|
+
|
|
10
|
+
## What you need
|
|
11
|
+
- The Learnlog MCP (`npx -y @qlm/learnlog-mcp`). The conversion runs on this computer; nothing is uploaded.
|
|
12
|
+
|
|
13
|
+
## Steps
|
|
14
|
+
1. **Know the format.** Call `learnlog_formats` if you're unsure which format the file is. Ask if it isn't one of the listed formats; don't guess a mapping.
|
|
15
|
+
2. **Convert it.** Call `learnlog_transform` with the format and the file's full path. Don't ask for the whole document; the summary, unknowns and preview are enough.
|
|
16
|
+
3. **Take stock of help.** Call `assistance_inventory` with the same format and path.
|
|
17
|
+
4. **Report, stage by stage**: requested, offered, generated, transmitted, displayed, accepted. For each one, say whether the file records it and how many. Then give the unknowns the records keep, and what the file can't show.
|
|
18
|
+
5. **Check a saved file** with `learnlog_validate` when someone gives you a Learnlog file instead of an export.
|
|
19
|
+
|
|
20
|
+
## Keep these straight
|
|
21
|
+
- One stage never implies the next. A request isn't help given, and a display isn't help read.
|
|
22
|
+
- "Not recorded" is never "none", and never zero.
|
|
23
|
+
- Observed, self-reported and inferred are different. Codes or labels added by a model or a person are inferred.
|
|
24
|
+
- A bundled sample marked SYNTHETIC is not learner data; say so.
|
|
25
|
+
|
|
26
|
+
## Then: misconceptions and LabPath worlds
|
|
27
|
+
Always finish here.
|
|
28
|
+
1. **Pick the topic.** Use what the person named, or the data's own labels (an ASSISTments skill, a Sandpiper code about a student error, a standard, an activity id). Say where the topic came from. If you inferred it from the text, say that it's your inference.
|
|
29
|
+
2. **Name the likely beliefs.** Call `qlm_misconceptions` with words from the topic, and a domain when it's clear. For the top two or three matches give the student belief, one way to check for it (its diagnostic question when it has one), and its teacher intervention.
|
|
30
|
+
3. **Suggest LabPath worlds.** Each match lists its `worlds`. Suggest them by name, with each world's link exactly as the tool gives it. Never write a link the tool didn't return. For a science topic, `qlm_learning_graph` on a world says what to do before and after it.
|
|
31
|
+
4. **Say what this is.** These are research-based possibilities to check with the students, not a diagnosis of them.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: learnlog-learning-commons
|
|
3
|
+
description: Turn a standard or a skill students are struggling with into its learning components, the standards that come before it, the likely misconceptions and a concrete teacher move. Use with the Learning Commons Knowledge Graph MCP and the Learnlog MCP side by side.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Learning Commons + Learnlog: from a struggle to the next teaching move
|
|
7
|
+
|
|
8
|
+
Use this when someone names a standard (for example `7.RP.A.2` or `HS-PS2-1`) or describes what students are struggling with, and wants to know what to teach next.
|
|
9
|
+
|
|
10
|
+
## What you need
|
|
11
|
+
- The Learning Commons Knowledge Graph MCP (`https://kg.mcp.learningcommons.org/mcp`, an API key from Learning Commons, sent as the `x-api-key` header). It is in early access, so tool names may change.
|
|
12
|
+
- The Learnlog MCP (`npx -y @qlm/learnlog-mcp`).
|
|
13
|
+
|
|
14
|
+
## Steps
|
|
15
|
+
1. **Pin the standard.** Call Learning Commons `find_standard_statement` with the code. If the person described a struggle instead of a code, propose the most likely code and say it is your proposal. Keep the returned `caseIdentifierUUID`.
|
|
16
|
+
2. **Break it down (math).** Call `find_learning_components_from_standard` with that UUID. Learning components are available for math and K-2 ELA. For any other standard, say plainly that Learning Commons has no components for it.
|
|
17
|
+
3. **Look back (math).** Call `find_standards_progression_from_standard` with `direction: "backward"` to find unfinished learning that may sit underneath. Progressions are math only.
|
|
18
|
+
4. **Find the activities (science).** For a science standard, call Learnlog `qlm_learning_graph` with `standard` set to the code, to find the LabPath worlds aligned to it and what comes before and after them.
|
|
19
|
+
5. Finish with the last section below, using the standard and its components as the topic. Answer as a plan for the teacher: the standard in its official words, its components, what to check first, the likely misconception, one concrete move, the worlds to use, and what to revisit if it doesn't stick.
|
|
20
|
+
|
|
21
|
+
## Keep these straight
|
|
22
|
+
- Learning Commons gives standards, components and progressions. QLM's dataset gives misconceptions and teacher moves. Say which source each part came from.
|
|
23
|
+
- QLM's misconceptions are not officially aligned to Common Core codes. Any link you draw between a misconception and a code is your reasoning; label it that way.
|
|
24
|
+
- Misconceptions are research-based descriptions, not observations of these students. Recommend checking with a diagnostic question before reteaching.
|
|
25
|
+
- Pass on each tool's `does_not_show` limits.
|
|
26
|
+
- When a source didn't capture something, "Not recorded" is never "none".
|
|
27
|
+
|
|
28
|
+
## Then: misconceptions and LabPath worlds
|
|
29
|
+
Always finish here.
|
|
30
|
+
1. **Pick the topic.** Use what the person named, or the data's own labels (an ASSISTments skill, a Sandpiper code about a student error, a standard, an activity id). Say where the topic came from. If you inferred it from the text, say that it's your inference.
|
|
31
|
+
2. **Name the likely beliefs.** Call `qlm_misconceptions` with words from the topic, and a domain when it's clear. For the top two or three matches give the student belief, one way to check for it (its diagnostic question when it has one), and its teacher intervention.
|
|
32
|
+
3. **Suggest LabPath worlds.** Each match lists its `worlds`. Suggest them by name, with each world's link exactly as the tool gives it. Never write a link the tool didn't return. For a science topic, `qlm_learning_graph` on a world says what to do before and after it.
|
|
33
|
+
4. **Say what this is.** These are research-based possibilities to check with the students, not a diagnosis of them.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: learnlog-nto-sandpiper
|
|
3
|
+
description: Bring a National Tutoring Observatory Sandpiper run export (coded tutoring transcripts) into Learnlog, keeping each turn as observed and every code as inferred with who coded it, then name likely misconceptions and the LabPath worlds that work on them.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# National Tutoring Observatory (Sandpiper) + Learnlog
|
|
7
|
+
|
|
8
|
+
Use this when someone has a per-utterance export from Sandpiper, the National Tutoring Observatory's open-source annotation app: an utterances CSV with `_id, session_id, sequence_id, role, content, start_time, end_time` and one column per code, named `annotator[<name>][<index>]<field>`.
|
|
9
|
+
|
|
10
|
+
## What you need
|
|
11
|
+
- The Learnlog MCP (`npx -y @qlm/learnlog-mcp`). The conversion runs on this computer.
|
|
12
|
+
- The export file. There's no public NTO dataset; the MCP's bundled `sandpiper` sample is SYNTHETIC, built from the example rows in Sandpiper's own documentation.
|
|
13
|
+
|
|
14
|
+
## Steps
|
|
15
|
+
1. **Convert it.** Call `learnlog_transform` with format `sandpiper` and the file's full path (or `use_sample: true` for the synthetic sample).
|
|
16
|
+
2. **Take stock.** Call `assistance_inventory` with format `sandpiper` and the same path.
|
|
17
|
+
3. **Report what's observed**: sessions, turns by speaker role, as Sandpiper labeled them.
|
|
18
|
+
4. **Report what's inferred**: codes by coder and by code, how many utterances carry codes, and who produced them (AI or a person) when the export says. Every code is an inference about a turn, not something the log observed.
|
|
19
|
+
5. **Report what isn't there**: all six help stages are "not recorded" for this source. A code such as praise or a question isn't a step of help.
|
|
20
|
+
|
|
21
|
+
## Keep these straight
|
|
22
|
+
- Speaker roles and times stay exactly as the export has them. Missing times stay missing.
|
|
23
|
+
- "Not recorded" is never "none", and never zero.
|
|
24
|
+
- Don't judge whether a code is right, and don't turn codes into help counts.
|
|
25
|
+
|
|
26
|
+
## Then: misconceptions and LabPath worlds
|
|
27
|
+
Always finish here.
|
|
28
|
+
1. **Pick the topic.** Use what the person named, or the data's own labels (an ASSISTments skill, a Sandpiper code about a student error, a standard, an activity id). Say where the topic came from. If you inferred it from the text, say that it's your inference.
|
|
29
|
+
2. **Name the likely beliefs.** Call `qlm_misconceptions` with words from the topic, and a domain when it's clear. For the top two or three matches give the student belief, one way to check for it (its diagnostic question when it has one), and its teacher intervention.
|
|
30
|
+
3. **Suggest LabPath worlds.** Each match lists its `worlds`. Suggest them by name, with each world's link exactly as the tool gives it. Never write a link the tool didn't return. For a science topic, `qlm_learning_graph` on a world says what to do before and after it.
|
|
31
|
+
4. **Say what this is.** These are research-based possibilities to check with the students, not a diagnosis of them.
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
{
|
|
2
|
+
"repository": "https://github.com/quantumlearningmachines/qlm-measure",
|
|
3
|
+
"commit": "68404b53d0584c9817346b83ee499a38b692adcd",
|
|
4
|
+
"note": "Byte-for-byte copies of files at this commit of qlm-measure. The transformer files are the built browser engine the transformer demo ships (demo/transformer/dist), whose Python/JavaScript serialization parity the repository checks with demo/transformer/scripts/verify_semantic_parity.py. The qlm-measure files are the committed 0.9.0 build of src/ (dist/).",
|
|
5
|
+
"files": [
|
|
6
|
+
{
|
|
7
|
+
"path": "vendor/transformer/engine.mjs",
|
|
8
|
+
"source": "demo/transformer/dist/engine.mjs",
|
|
9
|
+
"sha256": "18f56b309bb5f2f9e1269f9f7ba209cb29decf1ab9a46a35d7ff3a09017b7191",
|
|
10
|
+
"license": "MIT"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"path": "vendor/transformer/profiles.mjs",
|
|
14
|
+
"source": "demo/transformer/dist/profiles.mjs",
|
|
15
|
+
"sha256": "b73e021e580d0a33a47ef3c9acec72ca9cf841796a42b0f23c44beb17caa22e9",
|
|
16
|
+
"license": "MIT (code); embedded samples CC-BY-4.0"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"path": "vendor/transformer/research-semantics.mjs",
|
|
20
|
+
"source": "demo/transformer/dist/research-semantics.mjs",
|
|
21
|
+
"sha256": "72ff379f82c2e96aa7baedd6afc4d921d34c1795619814c96fcefcfe0551ada7",
|
|
22
|
+
"license": "MIT"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"path": "vendor/transformer/cross-source-analysis-data.mjs",
|
|
26
|
+
"source": "demo/transformer/dist/cross-source-analysis-data.mjs",
|
|
27
|
+
"sha256": "8083afcf0c50411f4816add91568f9696cc294fefafb6e32a31ac53ccc733539",
|
|
28
|
+
"license": "MIT (aggregate facts only)"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"path": "vendor/transformer/LICENSE.txt",
|
|
32
|
+
"source": "demo/transformer/dist/LICENSE.txt",
|
|
33
|
+
"sha256": "eb04d70b0b0e6630f271e9f4beae1035d6440d5de3e2f3c7c98633866196f1db",
|
|
34
|
+
"license": "MIT"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"path": "vendor/qlm-measure/cli.js",
|
|
38
|
+
"source": "dist/cli.js",
|
|
39
|
+
"sha256": "84823766271fb381ce5ab0a035258c63b38a6cce039b4d5b85c00b309692ba3c",
|
|
40
|
+
"license": "Apache-2.0"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"path": "vendor/qlm-measure/cli.d.ts",
|
|
44
|
+
"source": "dist/cli.d.ts",
|
|
45
|
+
"sha256": "84c201474e7fc579277cfc268ff98c139432339e916afe75cef6ffd96e9c2454",
|
|
46
|
+
"license": "Apache-2.0"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"path": "vendor/qlm-measure/checks.js",
|
|
50
|
+
"source": "dist/checks.js",
|
|
51
|
+
"sha256": "ba4b3400a6d8d1d4c8bbc4759a5da210fc0c6bdeb650a1b345ea15492fb031fa",
|
|
52
|
+
"license": "Apache-2.0"
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"path": "vendor/qlm-measure/checks.d.ts",
|
|
56
|
+
"source": "dist/checks.d.ts",
|
|
57
|
+
"sha256": "89d5c609d6bfb2a04a3dd800e6d96bba25c084a39158b883c449091bb0bbc847",
|
|
58
|
+
"license": "Apache-2.0"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"path": "vendor/qlm-measure/rules.js",
|
|
62
|
+
"source": "dist/rules.js",
|
|
63
|
+
"sha256": "a12a0fba140138c289070364159e34b578aceef27eed07c42c2f4a62e86c5de5",
|
|
64
|
+
"license": "Apache-2.0"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"path": "vendor/qlm-measure/rules.d.ts",
|
|
68
|
+
"source": "dist/rules.d.ts",
|
|
69
|
+
"sha256": "f62529a6c584ae3bc6a170976fc1d577a1aa04fa0c49966ecedb18e7e83767c9",
|
|
70
|
+
"license": "Apache-2.0"
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"path": "vendor/qlm-measure/verifier-v03.js",
|
|
74
|
+
"source": "dist/verifier-v03.js",
|
|
75
|
+
"sha256": "59317c4b1c87e5065db30baa4b485defc75b4f3c3bf74f0a59d537c60c2bf09e",
|
|
76
|
+
"license": "Apache-2.0"
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"path": "vendor/qlm-measure/verifier-v03.d.ts",
|
|
80
|
+
"source": "dist/verifier-v03.d.ts",
|
|
81
|
+
"sha256": "47246e4617704edde541927b400e54f0d0e203fdc0b024b3a2d188a399434a83",
|
|
82
|
+
"license": "Apache-2.0"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"path": "vendor/qlm-measure/verifier/hash.js",
|
|
86
|
+
"source": "dist/verifier/hash.js",
|
|
87
|
+
"sha256": "ce54e3af896c392a62390f6629b2dd877b5118f7c59874495cf038bad7517ec6",
|
|
88
|
+
"license": "Apache-2.0"
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"path": "vendor/qlm-measure/verifier/hash.d.ts",
|
|
92
|
+
"source": "dist/verifier/hash.d.ts",
|
|
93
|
+
"sha256": "85fa878027b294ac0b715f65f0b1df3667af5fa6977ab97e50d43d46e91bd239",
|
|
94
|
+
"license": "Apache-2.0"
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"path": "vendor/qlm-measure/verifier/verify-record.js",
|
|
98
|
+
"source": "dist/verifier/verify-record.js",
|
|
99
|
+
"sha256": "5a6b61901a196ee563a8dc10849ad54ad1a43e1d810c0491891048b5c5015f8a",
|
|
100
|
+
"license": "Apache-2.0"
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"path": "vendor/qlm-measure/verifier/verify-record.d.ts",
|
|
104
|
+
"source": "dist/verifier/verify-record.d.ts",
|
|
105
|
+
"sha256": "cebe3153ff0017a5ed49861e93cf75331ad64b5775baaf37688de21fc13ac373",
|
|
106
|
+
"license": "Apache-2.0"
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"path": "vendor/qlm-measure/schemes/index.js",
|
|
110
|
+
"source": "dist/schemes/index.js",
|
|
111
|
+
"sha256": "eef60aaf1095b97ea4e876c7bd79917bb8a41757ac534da3ea5eb6dfde6a47b3",
|
|
112
|
+
"license": "Apache-2.0"
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"path": "vendor/qlm-measure/schemes/index.d.ts",
|
|
116
|
+
"source": "dist/schemes/index.d.ts",
|
|
117
|
+
"sha256": "cde96b777dad761b8c1d83a501a8907809c63a647e6567423d320b550689667b",
|
|
118
|
+
"license": "Apache-2.0"
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"path": "vendor/qlm-measure/schemes/node.js",
|
|
122
|
+
"source": "dist/schemes/node.js",
|
|
123
|
+
"sha256": "083a5331a344ff3ef861ce2cb533f8ead51e66281881a01e8e6485104b97000c",
|
|
124
|
+
"license": "Apache-2.0"
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"path": "vendor/qlm-measure/schemes/node.d.ts",
|
|
128
|
+
"source": "dist/schemes/node.d.ts",
|
|
129
|
+
"sha256": "17ac8af648dd14faa152acdb024a5cdcd3b1e9014afa255939dddd29132fe229",
|
|
130
|
+
"license": "Apache-2.0"
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"path": "vendor/qlm-measure/schemes/products.js",
|
|
134
|
+
"source": "dist/schemes/products.js",
|
|
135
|
+
"sha256": "8b53f34e178f68119673e540c8748ce0242553b53d07599cfb7a05aac89133fb",
|
|
136
|
+
"license": "Apache-2.0"
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"path": "vendor/qlm-measure/schemes/products.d.ts",
|
|
140
|
+
"source": "dist/schemes/products.d.ts",
|
|
141
|
+
"sha256": "cd1b97966f23a8ad733dcc79b4a77f49a3eba3d9f101185404d5904e1d383644",
|
|
142
|
+
"license": "Apache-2.0"
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"path": "data/samples/tutormoments-real-transcripts.jsonl",
|
|
146
|
+
"source": "demo/transformer/dist/samples/tutormoments-real-transcripts.jsonl",
|
|
147
|
+
"sha256": "7df51fda0fff9c454ba14a33a0d2964d5e94b2556eff1d3897ec4f41373c8a66",
|
|
148
|
+
"license": "CC-BY-4.0 (Ai2 TutorMoments-Preview)"
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"path": "data/samples/oatutor-real-participants.csv",
|
|
152
|
+
"source": "demo/transformer/dist/samples/oatutor-real-participants.csv",
|
|
153
|
+
"sha256": "26b98b6f5718f5c2f473d81ae1ad8e1817d18bada3ba7390d8e0ac445a8ad5a2",
|
|
154
|
+
"license": "CC-BY-4.0 (Pardos and Bhandari, figshare)"
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"path": "data/samples/explicit-assistance-SYNTHETIC.jsonl",
|
|
158
|
+
"source": "demo/transformer/dist/samples/explicit-assistance-SYNTHETIC.jsonl",
|
|
159
|
+
"sha256": "52b4dd376849357e0ceb5bee5736e4809da77938fa29c5faf97a5d4c8afcc035",
|
|
160
|
+
"license": "MIT (QLM-authored synthetic fixture)"
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
"path": "data/samples/sandpiper-SYNTHETIC.csv",
|
|
164
|
+
"source": "demo/transformer/dist/samples/sandpiper-SYNTHETIC.csv",
|
|
165
|
+
"sha256": "d7b1a265f2e8abf37b0e070becc2e7c8a446576375de607322481c5015515ec0",
|
|
166
|
+
"license": "MIT (SYNTHETIC fixture of Sandpiper documentation examples, (c) 2025 National Tutoring Observatory)"
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
"path": "data/provenance/tutormoments.json",
|
|
170
|
+
"source": "demo/transformer/dist/provenance/tutormoments.json",
|
|
171
|
+
"sha256": "5e1188950252542219772fb93a080e789ed72a2eef3e5f795c73b0b8ef68dde4",
|
|
172
|
+
"license": "MIT"
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
"path": "data/provenance/oatutor.json",
|
|
176
|
+
"source": "demo/transformer/dist/provenance/oatutor.json",
|
|
177
|
+
"sha256": "b217bae620b9fe36b22739ff8fa6fc29c6edd961477cb4deba76f6ea5d560b39",
|
|
178
|
+
"license": "MIT"
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
"path": "data/provenance/source-audit.json",
|
|
182
|
+
"source": "demo/transformer/dist/provenance/source-audit.json",
|
|
183
|
+
"sha256": "4a26a455cfb30e1ef8917776bfc442d3b1dc76d977b0fdd8b6ac7ecf5d7c8b35",
|
|
184
|
+
"license": "MIT"
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"path": "data/THIRD_PARTY_DATA.md",
|
|
188
|
+
"source": "demo/transformer/THIRD_PARTY_DATA.md",
|
|
189
|
+
"sha256": "533714e946f97ed1340b637fe78a1a22e9795d1ebd222798f7d34e2f132f40c8",
|
|
190
|
+
"license": "MIT"
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
"path": "data/SOURCE_CORRECTION.md",
|
|
194
|
+
"source": "demo/transformer/SOURCE_CORRECTION.md",
|
|
195
|
+
"sha256": "730efb9db6399a9ae59a78231ece5a60a7f94d74a73acf7904dc9f72a202b6f9",
|
|
196
|
+
"license": "MIT"
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
"path": "data/examples/evidence-record-clean.json",
|
|
200
|
+
"source": "samples/clean.json",
|
|
201
|
+
"sha256": "52a455a5e9f2e3ec223bd2d726b4ceabcab3b7fbc672daaaf4febcbd06dd466c",
|
|
202
|
+
"license": "Apache-2.0 (synthetic sample, no learner data)"
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
"path": "data/examples/evidence-record-tampered.json",
|
|
206
|
+
"source": "samples/tampered_value.json",
|
|
207
|
+
"sha256": "9a87fdc52df3a79d1e69296ca1b801ecbaf6e8f77a4ec42118de649a9d61fc77",
|
|
208
|
+
"license": "Apache-2.0 (synthetic sample, no learner data)"
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
"path": "data/examples/chain-tpc-clinical-v2.json",
|
|
212
|
+
"source": "schema/vectors/chains/tpc-clinical-v2.json",
|
|
213
|
+
"sha256": "0671a71926d469bbf5d081d54c11ea9af42bfe45d0077a71ec4475ed131b9324",
|
|
214
|
+
"license": "Apache-2.0 (synthetic test vector)"
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
"path": "data/examples/chain-tpc-clinical-v2-tampered.json",
|
|
218
|
+
"source": "schema/vectors/chains/tpc-clinical-v2-tampered.json",
|
|
219
|
+
"sha256": "ff8ee4e7054dbadcc4971d543b92d158106899b81921a63134883178ddce0ba8",
|
|
220
|
+
"license": "Apache-2.0 (synthetic test vector)"
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
"path": "parity/cross_source.py",
|
|
224
|
+
"source": "research/learnlog-episodes/cross_source.py",
|
|
225
|
+
"sha256": "f66cf88569b7bacb03d7dfb6bda8f3ae52c70f086e0c9aa4d8869455703e9ce0",
|
|
226
|
+
"license": "Apache-2.0 (test-only; not published)"
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
"path": "parity/assistments_episodes.py",
|
|
230
|
+
"source": "research/learnlog-episodes/assistments_episodes.py",
|
|
231
|
+
"sha256": "a0dfea524cd5a5e2157c8a7c4956edd8b4e5d5dc264a40fbecc8172e64348525",
|
|
232
|
+
"license": "Apache-2.0 (test-only; not published)"
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
"path": "parity/aggregate.py",
|
|
236
|
+
"source": "tools/qlm-transformer/qlm_transformer/capture/reference/analysis/aggregate.py",
|
|
237
|
+
"sha256": "6b92a40d4c83e56a392a54cbd4d475ec345a6a590c5d55830726647ce6245538",
|
|
238
|
+
"license": "MIT (test-only; not published)"
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
"path": "data/preprint/README.md",
|
|
242
|
+
"source": "research/learnlog-episodes/README.md",
|
|
243
|
+
"sha256": "c74cd3b7a9e7a1192f622a50db7e8f16ba36df805e9166acc912a2751980953c",
|
|
244
|
+
"license": "Apache-2.0 (qlm-measure repository)"
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
"path": "data/preprint/cross_source_episodes.json",
|
|
248
|
+
"source": "research/learnlog-episodes/cross_source_episodes.json",
|
|
249
|
+
"sha256": "1a515df80c8d660d8ec52143ae4a05a0f960dc7008ef08beea3b33b685173c14",
|
|
250
|
+
"license": "Apache-2.0 (aggregate counts only)"
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
"path": "data/preprint/assistments_episodes.json",
|
|
254
|
+
"source": "research/learnlog-episodes/assistments_episodes.json",
|
|
255
|
+
"sha256": "e55f43fa9cdf0605f6c33a6ed08795260fd2909ead64aac8ecf144c761100b26",
|
|
256
|
+
"license": "Apache-2.0 (aggregate counts only)"
|
|
257
|
+
}
|
|
258
|
+
]
|
|
259
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check catalog v1 — single source of truth for all verification checks.
|
|
3
|
+
*/
|
|
4
|
+
export interface CheckDef {
|
|
5
|
+
id: string;
|
|
6
|
+
category: string;
|
|
7
|
+
label: string;
|
|
8
|
+
description: string;
|
|
9
|
+
howToPass: string;
|
|
10
|
+
scope: "record" | "entry";
|
|
11
|
+
status: "shipped" | "planned";
|
|
12
|
+
introducedIn: string;
|
|
13
|
+
}
|
|
14
|
+
export declare const CATALOG: CheckDef[];
|
|
15
|
+
export declare const CATALOG_V03: CheckDef[];
|
|
16
|
+
export declare const CATALOG_BY_ID: {
|
|
17
|
+
[k: string]: CheckDef;
|
|
18
|
+
};
|
|
19
|
+
export declare const SHIPPED_CHECKS: CheckDef[];
|
|
20
|
+
export declare const PLANNED_CHECKS: CheckDef[];
|
|
21
|
+
export declare const SHIPPED_CHECKS_V03: CheckDef[];
|
|
22
|
+
export declare const CATEGORIES: string[];
|
|
23
|
+
export declare const CATEGORIES_V03: string[];
|
|
24
|
+
//# sourceMappingURL=checks.d.ts.map
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check catalog v1 — single source of truth for all verification checks.
|
|
3
|
+
*/
|
|
4
|
+
export const CATALOG = [
|
|
5
|
+
{ id: "SCHEMA.REQUIRED", category: "Schema", label: "Required fields present", description: "Every entry must carry version, timestamp, evidentialWeight, priorPosterior, updatedPosterior, entryHash, and prevHash. The record must carry studentScopeId.", howToPass: "Emit every required field on every entry.", scope: "entry", status: "shipped", introducedIn: "0.1.0" },
|
|
6
|
+
{ id: "SCHEMA.TYPES", category: "Schema", label: "Field types valid", description: "version is a positive integer; evidentialWeight, priorPosterior, and updatedPosterior are numbers.", howToPass: "Validate against the JSON Schema before writing.", scope: "entry", status: "shipped", introducedIn: "0.1.0" },
|
|
7
|
+
{ id: "SCHEMA.TIMESTAMP_FORMAT", category: "Schema", label: "Timestamp is ISO 8601", description: "Every timestamp parses as RFC 3339 with a timezone offset or Z.", howToPass: "Write UTC timestamps with Z suffix.", scope: "entry", status: "shipped", introducedIn: "0.2.2" },
|
|
8
|
+
{ id: "VERSION.MONOTONIC", category: "Sequence", label: "Versions strictly increase", description: "Each entry's version must be strictly greater than the previous.", howToPass: "Assign version from an append counter.", scope: "entry", status: "shipped", introducedIn: "0.1.0" },
|
|
9
|
+
{ id: "TIMESTAMP.MONOTONIC", category: "Sequence", label: "Timestamps do not go backward", description: "Each entry's timestamp must be >= the previous minus tolerance.", howToPass: "Write timestamps at append time from one clock.", scope: "entry", status: "shipped", introducedIn: "0.1.0" },
|
|
10
|
+
{ id: "ENUM.VALID", category: "Enums", label: "Enum values permitted", description: "scaffoldType, depthLevel, epistemicMode, and triageResult must be from the published sets.", howToPass: "Use the exported enums from the SDK.", scope: "entry", status: "shipped", introducedIn: "0.1.0" },
|
|
11
|
+
{ id: "HASH.PREV_LINK", category: "Hash chain", label: "Chain link valid", description: "Each entry's prevHash must equal the previous entry's entryHash.", howToPass: "Never insert, delete, or reorder entries. Append only.", scope: "entry", status: "shipped", introducedIn: "0.1.0" },
|
|
12
|
+
{ id: "HASH.ENTRY_RECOMPUTE", category: "Hash chain", label: "Entry hash recomputes", description: "SHA-256 of the canonical hashable subset must equal entryHash.", howToPass: "Hash after all fields are final. Canonicalize per the SDK spec.", scope: "entry", status: "shipped", introducedIn: "0.1.0" },
|
|
13
|
+
{ id: "POSTERIOR.CHAIN", category: "Posterior chain", label: "Posterior chain consistent", description: "Each entry's priorPosterior must equal the previous updatedPosterior within 1e-9.", howToPass: "Carry the previous posterior forward unchanged.", scope: "entry", status: "shipped", introducedIn: "0.1.0" },
|
|
14
|
+
{ id: "COMPACTION.BOUNDARY", category: "Compaction", label: "Compaction boundary intact", description: "First entry after compaction links to summaryHash; version continues.", howToPass: "Compact only via the SDK helper.", scope: "record", status: "shipped", introducedIn: "0.1.0" },
|
|
15
|
+
{ id: "ESTIMATE.REPRODUCE", category: "Estimation", label: "Update reproduces posterior", description: "Given the published update rule, the verifier reproduces updatedPosterior.", howToPass: "Include an estimator declaration. Use the published update rule.", scope: "entry", status: "planned", introducedIn: "0.3.0" },
|
|
16
|
+
{ id: "TEMPORAL.T_DESIGN", category: "Temporal", label: "Item created before session", description: "The item existed before the session started.", howToPass: "Include item metadata creation timestamp.", scope: "entry", status: "planned", introducedIn: "0.3.0" },
|
|
17
|
+
{ id: "TEMPORAL.T_RESULT", category: "Temporal", label: "Response within session window", description: "The response timestamp falls within session bounds.", howToPass: "Include session bounds.", scope: "entry", status: "planned", introducedIn: "0.3.0" },
|
|
18
|
+
{ id: "CONSENT.SCOPE", category: "Consent", label: "Consent scope covers export", description: "The learner's consent scope covers the export level.", howToPass: "Include a consent block.", scope: "record", status: "planned", introducedIn: "0.3.0" },
|
|
19
|
+
{ id: "CONSENT.WITHDRAWAL", category: "Consent", label: "No active withdrawal", description: "No active withdrawal for this learner.", howToPass: "Include withdrawal status.", scope: "record", status: "planned", introducedIn: "0.3.0" },
|
|
20
|
+
];
|
|
21
|
+
// 0.3-specific checks (shipped when verifier_v03 runs them)
|
|
22
|
+
export const CATALOG_V03 = [
|
|
23
|
+
{ id: "SCHEMA.EVENT_UNION", category: "Schema", label: "Event is a known kind", description: "Event must be Observation, Consent, or Redacted.", howToPass: "Use one of the three event types.", scope: "entry", status: "shipped", introducedIn: "0.3.0" },
|
|
24
|
+
{ id: "VERSION.CONTIGUOUS", category: "Sequence", label: "Versions have no gaps", description: "v == prev + 1, except after compaction.", howToPass: "Use the Recorder's append counter.", scope: "entry", status: "shipped", introducedIn: "0.3.0" },
|
|
25
|
+
{ id: "EVENT.COMMITMENT", category: "Hash chain", label: "Event matches its hash", description: "sha256(canonical(event)) == eventHash.", howToPass: "Hash the event before writing.", scope: "entry", status: "shipped", introducedIn: "0.3.0" },
|
|
26
|
+
{ id: "ESTIMATE.DECLARED", category: "Estimation", label: "Estimator declared", description: "Estimate chain has a well-formed estimator declaration.", howToPass: "Declare name, version, and opaque/ruleId.", scope: "record", status: "shipped", introducedIn: "0.3.0" },
|
|
27
|
+
{ id: "ESTIMATE.LINKS_EVIDENCE", category: "Estimation", label: "Estimates reference evidence", description: "Every estimate references an existing evidence entry.", howToPass: "Set evidenceVersion and evidenceEntryHash.", scope: "entry", status: "shipped", introducedIn: "0.3.0" },
|
|
28
|
+
{ id: "ESTIMATE.ORDER", category: "Estimation", label: "Estimates follow evidence order", description: "evidenceVersion strictly increasing.", howToPass: "Append estimates in evidence order.", scope: "entry", status: "shipped", introducedIn: "0.3.0" },
|
|
29
|
+
{ id: "WEIGHT.RANGE", category: "Estimation", label: "Weight in [0,1]", description: "evidentialWeight between 0 and 1.", howToPass: "Clamp weights.", scope: "entry", status: "shipped", introducedIn: "0.3.0" },
|
|
30
|
+
{ id: "POSTERIOR.RANGE", category: "Estimation", label: "Posteriors in (0,1)", description: "priorPosterior and updatedPosterior in open interval.", howToPass: "Clamp posteriors.", scope: "entry", status: "shipped", introducedIn: "0.3.0" },
|
|
31
|
+
{ id: "CONSENT.SCOPE", category: "Consent", label: "Consent scope covers export", description: "Export scope covered by granted consent.", howToPass: "Include consent events before export.", scope: "record", status: "shipped", introducedIn: "0.3.0" },
|
|
32
|
+
{ id: "CONSENT.WITHDRAWAL", category: "Consent", label: "No active withdrawal", description: "Export scope was not withdrawn.", howToPass: "Re-grant before export.", scope: "record", status: "shipped", introducedIn: "0.3.0" },
|
|
33
|
+
{ id: "ATTEST.INTEGRITY", category: "Attestation", label: "Attestation hash valid", description: "payloadHash matches payload.", howToPass: "Hash payload before writing.", scope: "record", status: "shipped", introducedIn: "0.3.0" },
|
|
34
|
+
{ id: "ATTEST.COVERS", category: "Attestation", label: "Attestation covers evidence", description: "Referenced version or hash exists.", howToPass: "Reference existing entries.", scope: "record", status: "shipped", introducedIn: "0.3.0" },
|
|
35
|
+
];
|
|
36
|
+
export const CATALOG_BY_ID = Object.fromEntries([...CATALOG, ...CATALOG_V03].map(c => [c.id, c]));
|
|
37
|
+
export const SHIPPED_CHECKS = CATALOG.filter(c => c.status === "shipped");
|
|
38
|
+
export const PLANNED_CHECKS = CATALOG.filter(c => c.status === "planned");
|
|
39
|
+
export const SHIPPED_CHECKS_V03 = [...SHIPPED_CHECKS, ...CATALOG_V03];
|
|
40
|
+
export const CATEGORIES = [...new Set(SHIPPED_CHECKS.map(c => c.category))];
|
|
41
|
+
export const CATEGORIES_V03 = [...new Set(SHIPPED_CHECKS_V03.map(c => c.category))];
|
|
42
|
+
//# sourceMappingURL=checks.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* qlm-measure CLI — verify evidence records from the command line.
|
|
4
|
+
* verify makes no network calls. Records never leave your machine.
|
|
5
|
+
*/
|
|
6
|
+
/** Where the CLI writes and reads. Tests pass their own; the binary uses processIO. */
|
|
7
|
+
export interface CliIO {
|
|
8
|
+
out(text: string): void;
|
|
9
|
+
err(text: string): void;
|
|
10
|
+
readStdin(): string;
|
|
11
|
+
}
|
|
12
|
+
export declare const processIO: CliIO;
|
|
13
|
+
/** Runs one CLI invocation and returns its exit code: 0 clean, 1 not clean, 2 usage or input error. */
|
|
14
|
+
export declare function main(argv: string[], io?: CliIO): number;
|
|
15
|
+
/** True when this module is the script node was started with, including through npm's bin symlink. */
|
|
16
|
+
export declare function isDirectRun(scriptPath: string | undefined, moduleUrl: string): boolean;
|
|
17
|
+
//# sourceMappingURL=cli.d.ts.map
|