diff --git a/README.md b/README.md index 7392173..cc0c123 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,12 @@ node dist/cli.js emit-spss examples/tam-bundle.json node dist/cli.js csv examples/tam-dataset.json ``` +The `examples/workflow-readiness-*.json` family is a second bundled +demonstration. It uses four factors with 4/3/5/4 items, mixed 1–7 and 1–5 +scales, reverse-keyed items, and a formative factor. Every item is labelled +`demonstration` and is explicitly not a published scale; the files contain no +research citation or provenance claim. + MCP stdio: `node dist/mcp.js` (`agentbiz-quant-mcp`). Tools are executable through `executeTool`, not documentation-only. Agent skill: copy `skills/quant-research/SKILL.md` into the target agent's skill directory, or use the installed package with `AGENTBIZ_QUANT_RESEARCH_ROOT` pointing at a clone. The skill is portable and does not assume the maintainer's filesystem path. diff --git a/examples/reproducibility-manifest.json b/examples/reproducibility-manifest.json index 534f766..c73d2ef 100644 --- a/examples/reproducibility-manifest.json +++ b/examples/reproducibility-manifest.json @@ -32,6 +32,34 @@ { "path": "examples/tam-topic-card.json", "sha256": "sha256:5ee4ca7bfc930c85fb9bbb7d956a5c13cb6b6c054c343d454ffe2f0619bea98a" + }, + { + "path": "examples/workflow-readiness-bundle.json", + "sha256": "sha256:1b6ac30e2a10ce7ed9d8156a33ba2651e5d846717444f4f9c1267594c5ed0f79" + }, + { + "path": "examples/workflow-readiness-dataset.json", + "sha256": "sha256:0b090fe711e3f8db109f466e8cdb54316e53a74b980bdab94d164039e86d9f2f" + }, + { + "path": "examples/workflow-readiness-instrument.json", + "sha256": "sha256:259ac672182600d4e42a68a2484fd433bfcc43d52ace04ab571bb9e575c66bbf" + }, + { + "path": "examples/workflow-readiness-measurement.json", + "sha256": "sha256:f1fd1084c8f4beb68d345576f82921440445953f9227635084ebe65941a065a6" + }, + { + "path": "examples/workflow-readiness-observed.json", + "sha256": "sha256:a627201ca8d31f721b835ac46f4dcd489d283e318f570d8eca02da7522624db1" + }, + { + "path": "examples/workflow-readiness-recode.json", + "sha256": "sha256:c276e99b1552aaddd83d0cda203b258185048dc3af656b2979ce6ffc9fedad91" + }, + { + "path": "examples/workflow-readiness-topic-card.json", + "sha256": "sha256:2d4980adfed94d8dc1aac2ebe59283369687ae168d49f3a188c9d17b90a781e5" } ], "replays": [ diff --git a/examples/workflow-readiness-bundle.json b/examples/workflow-readiness-bundle.json new file mode 100644 index 0000000..b89073b --- /dev/null +++ b/examples/workflow-readiness-bundle.json @@ -0,0 +1,111 @@ +{ + "instrument": { + "schemaVersion": "agentbiz.instrument.v1", + "language": "en", + "constructs": [ + { + "code": "WC", + "name": "Workflow clarity", + "kind": "reflective", + "scale": { + "min": 1, + "max": 7, + "anchors": [ + { "value": 1, "label": "Strongly disagree" }, + { "value": 4, "label": "Neither agree nor disagree" }, + { "value": 7, "label": "Strongly agree" } + ] + }, + "items": [ + { "code": "WC1", "text": "The steps in this workflow are clear to me.", "status": "demonstration", "source": { "note": "Demonstration item only; not a published scale." } }, + { "code": "WC2", "text": "I can tell what should happen next in this workflow.", "status": "demonstration", "source": { "note": "Demonstration item only; not a published scale." } }, + { "code": "WC3", "text": "This workflow often leaves me unsure about the next step.", "reverse": true, "status": "demonstration", "source": { "note": "Demonstration reverse-keyed item only; not a published scale." } }, + { "code": "WC4", "text": "The workflow makes task responsibilities easy to understand.", "status": "demonstration", "source": { "note": "Demonstration item only; not a published scale." } } + ] + }, + { + "code": "DC", + "name": "Data confidence", + "kind": "reflective", + "scale": { + "min": 1, + "max": 5, + "anchors": [ + { "value": 1, "label": "Strongly disagree" }, + { "value": 3, "label": "Neither agree nor disagree" }, + { "value": 5, "label": "Strongly agree" } + ] + }, + "items": [ + { "code": "DC1", "text": "I can find the information needed to complete a task.", "status": "demonstration", "source": { "note": "Demonstration item only; not a published scale." } }, + { "code": "DC2", "text": "I often doubt whether the available information is reliable.", "reverse": true, "status": "demonstration", "source": { "note": "Demonstration reverse-keyed item only; not a published scale." } }, + { "code": "DC3", "text": "The information available to me supports confident decisions.", "status": "demonstration", "source": { "note": "Demonstration item only; not a published scale." } } + ] + }, + { + "code": "SR", + "name": "Support readiness", + "kind": "formative", + "scale": { + "min": 1, + "max": 7, + "anchors": [ + { "value": 1, "label": "Strongly disagree" }, + { "value": 4, "label": "Neither agree nor disagree" }, + { "value": 7, "label": "Strongly agree" } + ] + }, + "items": [ + { "code": "SR1", "text": "Help is available when I encounter a workflow problem.", "status": "demonstration", "source": { "note": "Demonstration item only; not a published scale." } }, + { "code": "SR2", "text": "Training materials cover the tasks I am expected to perform.", "status": "demonstration", "source": { "note": "Demonstration item only; not a published scale." } }, + { "code": "SR3", "text": "Getting support for a workflow issue is difficult.", "reverse": true, "status": "demonstration", "source": { "note": "Demonstration reverse-keyed item only; not a published scale." } }, + { "code": "SR4", "text": "The responsible team communicates changes clearly.", "status": "demonstration", "source": { "note": "Demonstration item only; not a published scale." } }, + { "code": "SR5", "text": "I know where to report a recurring workflow problem.", "status": "demonstration", "source": { "note": "Demonstration item only; not a published scale." } } + ] + }, + { + "code": "CI", + "name": "Continued-use intention", + "kind": "reflective", + "scale": { + "min": 1, + "max": 5, + "anchors": [ + { "value": 1, "label": "Strongly disagree" }, + { "value": 3, "label": "Neither agree nor disagree" }, + { "value": 5, "label": "Strongly agree" } + ] + }, + "items": [ + { "code": "CI1", "text": "I expect to continue using this workflow.", "status": "demonstration", "source": { "note": "Demonstration item only; not a published scale." } }, + { "code": "CI2", "text": "I would choose this workflow for similar tasks.", "status": "demonstration", "source": { "note": "Demonstration item only; not a published scale." } }, + { "code": "CI3", "text": "Using this workflow is worth the effort.", "status": "demonstration", "source": { "note": "Demonstration item only; not a published scale." } }, + { "code": "CI4", "text": "I would avoid using this workflow again when an alternative exists.", "reverse": true, "status": "demonstration", "source": { "note": "Demonstration reverse-keyed item only; not a published scale." } } + ] + } + ] + }, + "topicCard": { + "schemaVersion": "agentbiz.topic-card.v1", + "question": "How are workflow clarity, data confidence, support readiness, and continued-use intention associated in this demonstration instrument?", + "claimClass": "association", + "population": "not specified; demonstration only", + "unit": "workflow user (demonstration record)", + "timeframe": "not specified", + "constructCodes": ["WC", "DC", "SR", "CI"], + "hypotheses": [ + { "id": "H1", "from": "SR", "to": "WC", "sign": "+" }, + { "id": "H2", "from": "DC", "to": "WC", "sign": "+" }, + { "id": "H3", "from": "WC", "to": "CI", "sign": "+" }, + { "id": "H4", "from": "DC", "to": "CI", "sign": "+" }, + { "id": "H5", "from": "SR", "to": "CI", "sign": "+" } + ], + "engine": "smartpls", + "mode": "exploratory" + }, + "measurement": { + "schemaVersion": "agentbiz.measurement.v1", + "mode": "pls-sem", + "engineOptions": { "estimator": "PLS" } + } +} diff --git a/examples/workflow-readiness-dataset.json b/examples/workflow-readiness-dataset.json new file mode 100644 index 0000000..7a121b4 --- /dev/null +++ b/examples/workflow-readiness-dataset.json @@ -0,0 +1,30 @@ +{ + "schemaVersion": "agentbiz.dataset.v1", + "columns": [ + { "name": "id", "role": "id" }, + { "name": "WC1", "role": "indicator", "itemCode": "WC1" }, + { "name": "WC2", "role": "indicator", "itemCode": "WC2" }, + { "name": "WC3", "role": "indicator", "itemCode": "WC3" }, + { "name": "WC4", "role": "indicator", "itemCode": "WC4" }, + { "name": "DC1", "role": "indicator", "itemCode": "DC1" }, + { "name": "DC2", "role": "indicator", "itemCode": "DC2" }, + { "name": "DC3", "role": "indicator", "itemCode": "DC3" }, + { "name": "SR1", "role": "indicator", "itemCode": "SR1" }, + { "name": "SR2", "role": "indicator", "itemCode": "SR2" }, + { "name": "SR3", "role": "indicator", "itemCode": "SR3" }, + { "name": "SR4", "role": "indicator", "itemCode": "SR4" }, + { "name": "SR5", "role": "indicator", "itemCode": "SR5" }, + { "name": "CI1", "role": "indicator", "itemCode": "CI1" }, + { "name": "CI2", "role": "indicator", "itemCode": "CI2" }, + { "name": "CI3", "role": "indicator", "itemCode": "CI3" }, + { "name": "CI4", "role": "indicator", "itemCode": "CI4" }, + { "name": "team", "role": "demographic" } + ], + "rowCount": 4, + "rows": [ + { "id": "R01", "WC1": 4, "WC2": 4, "WC3": 4, "WC4": 4, "DC1": 4, "DC2": 4, "DC3": 4, "SR1": 4, "SR2": 4, "SR3": 4, "SR4": 4, "SR5": 4, "CI1": 4, "CI2": 4, "CI3": 4, "CI4": 4, "team": "A" }, + { "id": "R02", "WC1": 6, "WC2": 5, "WC3": 2, "WC4": 6, "DC1": 5, "DC2": 2, "DC3": 4, "SR1": 5, "SR2": 6, "SR3": 2, "SR4": 5, "SR5": 6, "CI1": 5, "CI2": 4, "CI3": 4, "CI4": 2, "team": "B" }, + { "id": "R03", "WC1": 3, "WC2": 4, "WC3": 5, "WC4": 3, "DC1": 3, "DC2": null, "DC3": 3, "SR1": 3, "SR2": 4, "SR3": 5, "SR4": 3, "SR5": 4, "CI1": 3, "CI2": 3, "CI3": 2, "CI4": 4, "team": "A" }, + { "id": "R04", "WC1": 7, "WC2": 6, "WC3": 1, "WC4": 7, "DC1": 4, "DC2": 1, "DC3": 5, "SR1": 6, "SR2": 5, "SR3": 1, "SR4": 6, "SR5": 5, "CI1": 5, "CI2": 4, "CI3": 5, "CI4": 1, "team": "B" } + ] +} diff --git a/examples/workflow-readiness-instrument.json b/examples/workflow-readiness-instrument.json new file mode 100644 index 0000000..467d16b --- /dev/null +++ b/examples/workflow-readiness-instrument.json @@ -0,0 +1,170 @@ +{ + "schemaVersion": "agentbiz.instrument.v1", + "language": "en", + "constructs": [ + { + "code": "WC", + "name": "Workflow clarity", + "kind": "reflective", + "scale": { + "min": 1, + "max": 7, + "anchors": [ + { "value": 1, "label": "Strongly disagree" }, + { "value": 4, "label": "Neither agree nor disagree" }, + { "value": 7, "label": "Strongly agree" } + ] + }, + "items": [ + { + "code": "WC1", + "text": "The steps in this workflow are clear to me.", + "status": "demonstration", + "source": { "note": "Demonstration item only; not a published scale." } + }, + { + "code": "WC2", + "text": "I can tell what should happen next in this workflow.", + "status": "demonstration", + "source": { "note": "Demonstration item only; not a published scale." } + }, + { + "code": "WC3", + "text": "This workflow often leaves me unsure about the next step.", + "reverse": true, + "status": "demonstration", + "source": { "note": "Demonstration reverse-keyed item only; not a published scale." } + }, + { + "code": "WC4", + "text": "The workflow makes task responsibilities easy to understand.", + "status": "demonstration", + "source": { "note": "Demonstration item only; not a published scale." } + } + ] + }, + { + "code": "DC", + "name": "Data confidence", + "kind": "reflective", + "scale": { + "min": 1, + "max": 5, + "anchors": [ + { "value": 1, "label": "Strongly disagree" }, + { "value": 3, "label": "Neither agree nor disagree" }, + { "value": 5, "label": "Strongly agree" } + ] + }, + "items": [ + { + "code": "DC1", + "text": "I can find the information needed to complete a task.", + "status": "demonstration", + "source": { "note": "Demonstration item only; not a published scale." } + }, + { + "code": "DC2", + "text": "I often doubt whether the available information is reliable.", + "reverse": true, + "status": "demonstration", + "source": { "note": "Demonstration reverse-keyed item only; not a published scale." } + }, + { + "code": "DC3", + "text": "The information available to me supports confident decisions.", + "status": "demonstration", + "source": { "note": "Demonstration item only; not a published scale." } + } + ] + }, + { + "code": "SR", + "name": "Support readiness", + "kind": "formative", + "scale": { + "min": 1, + "max": 7, + "anchors": [ + { "value": 1, "label": "Strongly disagree" }, + { "value": 4, "label": "Neither agree nor disagree" }, + { "value": 7, "label": "Strongly agree" } + ] + }, + "items": [ + { + "code": "SR1", + "text": "Help is available when I encounter a workflow problem.", + "status": "demonstration", + "source": { "note": "Demonstration item only; not a published scale." } + }, + { + "code": "SR2", + "text": "Training materials cover the tasks I am expected to perform.", + "status": "demonstration", + "source": { "note": "Demonstration item only; not a published scale." } + }, + { + "code": "SR3", + "text": "Getting support for a workflow issue is difficult.", + "reverse": true, + "status": "demonstration", + "source": { "note": "Demonstration reverse-keyed item only; not a published scale." } + }, + { + "code": "SR4", + "text": "The responsible team communicates changes clearly.", + "status": "demonstration", + "source": { "note": "Demonstration item only; not a published scale." } + }, + { + "code": "SR5", + "text": "I know where to report a recurring workflow problem.", + "status": "demonstration", + "source": { "note": "Demonstration item only; not a published scale." } + } + ] + }, + { + "code": "CI", + "name": "Continued-use intention", + "kind": "reflective", + "scale": { + "min": 1, + "max": 5, + "anchors": [ + { "value": 1, "label": "Strongly disagree" }, + { "value": 3, "label": "Neither agree nor disagree" }, + { "value": 5, "label": "Strongly agree" } + ] + }, + "items": [ + { + "code": "CI1", + "text": "I expect to continue using this workflow.", + "status": "demonstration", + "source": { "note": "Demonstration item only; not a published scale." } + }, + { + "code": "CI2", + "text": "I would choose this workflow for similar tasks.", + "status": "demonstration", + "source": { "note": "Demonstration item only; not a published scale." } + }, + { + "code": "CI3", + "text": "Using this workflow is worth the effort.", + "status": "demonstration", + "source": { "note": "Demonstration item only; not a published scale." } + }, + { + "code": "CI4", + "text": "I would avoid using this workflow again when an alternative exists.", + "reverse": true, + "status": "demonstration", + "source": { "note": "Demonstration reverse-keyed item only; not a published scale." } + } + ] + } + ] +} diff --git a/examples/workflow-readiness-measurement.json b/examples/workflow-readiness-measurement.json new file mode 100644 index 0000000..c52ac45 --- /dev/null +++ b/examples/workflow-readiness-measurement.json @@ -0,0 +1,5 @@ +{ + "schemaVersion": "agentbiz.measurement.v1", + "mode": "pls-sem", + "engineOptions": { "estimator": "PLS" } +} diff --git a/examples/workflow-readiness-observed.json b/examples/workflow-readiness-observed.json new file mode 100644 index 0000000..b976fc8 --- /dev/null +++ b/examples/workflow-readiness-observed.json @@ -0,0 +1,21 @@ +{ + "schemaVersion": "agentbiz.gap-map.v1", + "observed": [ + { "column": "WC1", "itemCode": "WC1", "constructCode": "WC", "reverse": false, "scale": { "min": 1, "max": 7 } }, + { "column": "WC2", "itemCode": "WC2", "constructCode": "WC", "reverse": false, "scale": { "min": 1, "max": 7 } }, + { "column": "WC3", "itemCode": "WC3", "constructCode": "WC", "reverse": true, "scale": { "min": 1, "max": 7 } }, + { "column": "WC4", "itemCode": "WC4", "constructCode": "WC", "reverse": false, "scale": { "min": 1, "max": 7 } }, + { "column": "DC1", "itemCode": "DC1", "constructCode": "DC", "reverse": false, "scale": { "min": 1, "max": 5 } }, + { "column": "DC2", "itemCode": "DC2", "constructCode": "DC", "reverse": true, "scale": { "min": 1, "max": 5 } }, + { "column": "DC3", "itemCode": "DC3", "constructCode": "DC", "reverse": false, "scale": { "min": 1, "max": 5 } }, + { "column": "SR1", "itemCode": "SR1", "constructCode": "SR", "reverse": false, "scale": { "min": 1, "max": 7 } }, + { "column": "SR2", "itemCode": "SR2", "constructCode": "SR", "reverse": false, "scale": { "min": 1, "max": 7 } }, + { "column": "SR3", "itemCode": "SR3", "constructCode": "SR", "reverse": true, "scale": { "min": 1, "max": 7 } }, + { "column": "SR4", "itemCode": "SR4", "constructCode": "SR", "reverse": false, "scale": { "min": 1, "max": 7 } }, + { "column": "SR5", "itemCode": "SR5", "constructCode": "SR", "reverse": false, "scale": { "min": 1, "max": 7 } }, + { "column": "CI1", "itemCode": "CI1", "constructCode": "CI", "reverse": false, "scale": { "min": 1, "max": 5 } }, + { "column": "CI2", "itemCode": "CI2", "constructCode": "CI", "reverse": false, "scale": { "min": 1, "max": 5 } }, + { "column": "CI3", "itemCode": "CI3", "constructCode": "CI", "reverse": false, "scale": { "min": 1, "max": 5 } }, + { "column": "CI4", "itemCode": "CI4", "constructCode": "CI", "reverse": true, "scale": { "min": 1, "max": 5 } } + ] +} diff --git a/examples/workflow-readiness-recode.json b/examples/workflow-readiness-recode.json new file mode 100644 index 0000000..506a64d --- /dev/null +++ b/examples/workflow-readiness-recode.json @@ -0,0 +1,13 @@ +{ + "schemaVersion": "agentbiz.recode.v1", + "operations": [ + { "kind": "reverse-score", "itemCode": "WC3", "as": "WC3_R" }, + { "kind": "reverse-score", "itemCode": "DC2", "as": "DC2_R" }, + { "kind": "reverse-score", "itemCode": "SR3", "as": "SR3_R" }, + { "kind": "reverse-score", "itemCode": "CI4", "as": "CI4_R" }, + { "kind": "construct-score", "constructCode": "WC", "as": "WC_MEAN" }, + { "kind": "construct-score", "constructCode": "DC", "as": "DC_MEAN" }, + { "kind": "construct-score", "constructCode": "CI", "as": "CI_MEAN" }, + { "kind": "flag-straight-line", "as": "STRAIGHT" } + ] +} diff --git a/examples/workflow-readiness-topic-card.json b/examples/workflow-readiness-topic-card.json new file mode 100644 index 0000000..4b19f5f --- /dev/null +++ b/examples/workflow-readiness-topic-card.json @@ -0,0 +1,18 @@ +{ + "schemaVersion": "agentbiz.topic-card.v1", + "question": "How are workflow clarity, data confidence, support readiness, and continued-use intention associated in this demonstration instrument?", + "claimClass": "association", + "population": "not specified; demonstration only", + "unit": "workflow user (demonstration record)", + "timeframe": "not specified", + "constructCodes": ["WC", "DC", "SR", "CI"], + "hypotheses": [ + { "id": "H1", "from": "SR", "to": "WC", "sign": "+" }, + { "id": "H2", "from": "DC", "to": "WC", "sign": "+" }, + { "id": "H3", "from": "WC", "to": "CI", "sign": "+" }, + { "id": "H4", "from": "DC", "to": "CI", "sign": "+" }, + { "id": "H5", "from": "SR", "to": "CI", "sign": "+" } + ], + "engine": "smartpls", + "mode": "exploratory" +} diff --git a/scripts/check-pack.mjs b/scripts/check-pack.mjs index 4dd8bf6..5c280d3 100644 --- a/scripts/check-pack.mjs +++ b/scripts/check-pack.mjs @@ -50,6 +50,13 @@ const required = [ "schemas/receipt.v1.schema.json", "examples/tam-instrument.json", "examples/tam-bundle.json", + "examples/workflow-readiness-instrument.json", + "examples/workflow-readiness-bundle.json", + "examples/workflow-readiness-topic-card.json", + "examples/workflow-readiness-measurement.json", + "examples/workflow-readiness-recode.json", + "examples/workflow-readiness-dataset.json", + "examples/workflow-readiness-observed.json", "examples/reproducibility-manifest.json", ]; const missing = required.filter((path) => !paths.includes(path)); diff --git a/test/workflow-readiness.test.ts b/test/workflow-readiness.test.ts new file mode 100644 index 0000000..98062ea --- /dev/null +++ b/test/workflow-readiness.test.ts @@ -0,0 +1,79 @@ +import { describe, expect, it } from "vitest"; +import { auditDataset, parseDataset } from "../src/dataset/index.js"; +import { compileGapMap } from "../src/gap-map/index.js"; +import { compileInstrument, parseInstrument } from "../src/instrument/index.js"; +import { compileMeasurement } from "../src/measurement/index.js"; +import { parseQuantBundle } from "../src/bundle.js"; +import { compileRecode } from "../src/recode/index.js"; +import { compileTopicCard } from "../src/topic-card/index.js"; +import { loadExample } from "./helpers.js"; + +describe("workflow-readiness demonstration family", () => { + it("validates the instrument shape and demonstration boundary", () => { + const input = loadExample("workflow-readiness-instrument.json"); + const compiled = compileInstrument(input); + const instrument = compiled.artifact.instrument; + + expect(compiled.receipt.status).toBe("compiled"); + expect(instrument.constructs.map((construct) => construct.code)).toEqual(["WC", "DC", "SR", "CI"]); + expect(instrument.constructs.map((construct) => construct.items.length)).toEqual([4, 3, 5, 4]); + expect(instrument.constructs.map((construct) => `${construct.scale.min}-${construct.scale.max}`)).toEqual([ + "1-7", + "1-5", + "1-7", + "1-5", + ]); + expect(compiled.artifact.dictionary).toHaveLength(16); + expect(compiled.artifact.dictionary.filter((item) => item.reverse).map((item) => item.itemCode)).toEqual([ + "WC3", + "DC2", + "SR3", + "CI4", + ]); + expect( + instrument.constructs.flatMap((construct) => construct.items).every( + (item) => + item.status === "demonstration" && + /demonstration.*not a published scale/i.test(item.source?.note ?? ""), + ), + ).toBe(true); + expect(JSON.stringify(input)).not.toMatch(/citation/i); + }); + + it("runs topic, measurement, gap, dataset, recode, and bundle validation", () => { + const instrument = parseInstrument(loadExample("workflow-readiness-instrument.json")); + const topicCard = compileTopicCard(loadExample("workflow-readiness-topic-card.json"), instrument); + const measurement = compileMeasurement( + loadExample("workflow-readiness-measurement.json"), + instrument, + topicCard.artifact, + ); + const dataset = parseDataset(loadExample("workflow-readiness-dataset.json")); + const audit = auditDataset(loadExample("workflow-readiness-dataset.json"), instrument); + const gap = compileGapMap(loadExample("workflow-readiness-observed.json"), instrument); + const rawRows = JSON.stringify(dataset.rows); + const recode = compileRecode(loadExample("workflow-readiness-recode.json"), dataset, instrument); + const bundle = parseQuantBundle(loadExample("workflow-readiness-bundle.json")); + + expect(topicCard.artifact.constructCodes).toEqual(["WC", "DC", "SR", "CI"]); + expect(topicCard.artifact.hypotheses).toHaveLength(5); + expect(measurement.artifact.mode).toBe("pls-sem"); + expect(measurement.artifact.constructs.map((construct) => construct.itemCount)).toEqual([4, 3, 5, 4]); + expect(measurement.artifact.paths).toHaveLength(5); + expect(gap.artifact.rows.every((row) => row.status === "covered")).toBe(true); + expect(gap.artifact.unexpected).toHaveLength(0); + expect(audit.receipt.status).toBe("audited"); + expect(audit.artifact.dataset.rows).toHaveLength(4); + expect(audit.receipt.counts.straightLineRows).toBe(1); + expect(audit.receipt.counts.missingCells).toBe(1); + expect(recode.artifact.rows[1]?.WC3_R).toBe(6); + expect(recode.artifact.rows[1]?.DC2_R).toBe(4); + expect(recode.artifact.rows[0]?.WC_MEAN).toBeCloseTo(4, 10); + expect(recode.artifact.rows[0]?.CI_MEAN).toBeCloseTo(3.5, 10); + expect(recode.artifact.rows[0]?.STRAIGHT).toBe(1); + expect(JSON.stringify(dataset.rows)).toBe(rawRows); + expect(bundle.instrument.constructs).toHaveLength(4); + expect(bundle.topicCard.hypotheses).toHaveLength(5); + expect(bundle.measurement.mode).toBe("pls-sem"); + }); +});