@studiolxd/lxd-cli 0.1.0-next.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/LICENSE +36 -0
- package/README.md +123 -0
- package/dist/cli/index.js +2763 -0
- package/dist/core/schema/design-direction.schema.json +84 -0
- package/dist/core/schema/experience.schema.json +75 -0
- package/dist/core/schema/export-config.schema.json +44 -0
- package/dist/core/schema/mechanic-manifest.schema.json +53 -0
- package/dist/core/schema/package-spec.schema.json +126 -0
- package/dist/core/schema/tracking-config.schema.json +63 -0
- package/dist/core/schema/validation-report.schema.json +42 -0
- package/dist/mechanics/manifests/branching-narrative.yml +25 -0
- package/dist/mechanics/manifests/decision-simulation.yml +25 -0
- package/dist/mechanics/manifests/diagnostic-challenge.yml +24 -0
- package/dist/mechanics/manifests/risk-detection.yml +24 -0
- package/docs/agent-agnostic-verification.md +52 -0
- package/docs/commands.md +56 -0
- package/package.json +59 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://studiolxd.dev/lxd-cli/design-direction.schema.json",
|
|
4
|
+
"title": "DesignDirection",
|
|
5
|
+
"description": "First-class, multi-level design model (FR-011/012/013). Package-level, shared by experiences. 'level' gates which inputs are expected.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["level"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"level": { "enum": ["brief", "tokens", "patterns", "design-system", "full-constraints"] },
|
|
11
|
+
"brief": { "type": "string" },
|
|
12
|
+
"tone": { "type": "string" },
|
|
13
|
+
"tokens": {
|
|
14
|
+
"type": "object",
|
|
15
|
+
"additionalProperties": false,
|
|
16
|
+
"properties": {
|
|
17
|
+
"colors": { "type": "object", "additionalProperties": { "type": "string" } },
|
|
18
|
+
"typography": { "type": "object" },
|
|
19
|
+
"spacing": { "type": "object" },
|
|
20
|
+
"density": { "enum": ["compact", "comfortable", "spacious"] }
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"patterns": {
|
|
24
|
+
"type": "object",
|
|
25
|
+
"additionalProperties": false,
|
|
26
|
+
"properties": {
|
|
27
|
+
"ui": { "type": "array", "items": { "type": "string" } },
|
|
28
|
+
"interaction": { "type": "array", "items": { "type": "string" } },
|
|
29
|
+
"componentUsage": { "type": "array", "items": { "type": "string" } }
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"accessibility": {
|
|
33
|
+
"type": "object",
|
|
34
|
+
"additionalProperties": false,
|
|
35
|
+
"properties": {
|
|
36
|
+
"considered": { "type": "boolean" },
|
|
37
|
+
"targets": { "type": "array", "items": { "type": "string" }, "description": "e.g., WCAG level chosen per project" },
|
|
38
|
+
"notes": { "type": "string" }
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"responsive": {
|
|
42
|
+
"type": "object",
|
|
43
|
+
"additionalProperties": false,
|
|
44
|
+
"properties": {
|
|
45
|
+
"approach": { "enum": ["mobile-first", "desktop-first", "fluid"] },
|
|
46
|
+
"breakpoints": { "type": "array", "items": { "type": "string" } }
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"animation": { "type": "string" },
|
|
50
|
+
"designSystemRefs": {
|
|
51
|
+
"type": "array",
|
|
52
|
+
"items": {
|
|
53
|
+
"type": "object",
|
|
54
|
+
"additionalProperties": false,
|
|
55
|
+
"required": ["kind", "ref"],
|
|
56
|
+
"properties": {
|
|
57
|
+
"kind": { "enum": ["url", "file"] },
|
|
58
|
+
"ref": { "type": "string" }
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"constraints": {
|
|
63
|
+
"type": "object",
|
|
64
|
+
"additionalProperties": false,
|
|
65
|
+
"properties": {
|
|
66
|
+
"do": { "type": "array", "items": { "type": "string" } },
|
|
67
|
+
"dont": { "type": "array", "items": { "type": "string" } },
|
|
68
|
+
"implementation": { "type": "array", "items": { "type": "string" } }
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
"output": {
|
|
72
|
+
"type": "array",
|
|
73
|
+
"items": { "type": "string" },
|
|
74
|
+
"description": "e.g., light-mode, dark-mode, mobile-first, corporate, playful, minimal"
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
"allOf": [
|
|
78
|
+
{ "if": { "properties": { "level": { "const": "brief" } }, "required": ["level"] }, "then": { "required": ["brief"] } },
|
|
79
|
+
{ "if": { "properties": { "level": { "const": "tokens" } }, "required": ["level"] }, "then": { "required": ["tokens"] } },
|
|
80
|
+
{ "if": { "properties": { "level": { "const": "patterns" } }, "required": ["level"] }, "then": { "required": ["patterns"] } },
|
|
81
|
+
{ "if": { "properties": { "level": { "const": "design-system" } }, "required": ["level"] }, "then": { "required": ["designSystemRefs"] } },
|
|
82
|
+
{ "if": { "properties": { "level": { "const": "full-constraints" } }, "required": ["level"] }, "then": { "required": ["constraints"] } }
|
|
83
|
+
]
|
|
84
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://studiolxd.dev/lxd-cli/experience.schema.json",
|
|
4
|
+
"title": "Experience",
|
|
5
|
+
"description": "An interactive learning experience inside a package (FR-007). Exactly one mechanic (FR-010).",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["id", "title", "learningPurpose", "scenario", "mechanicRef", "feedback"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"id": { "type": "string", "pattern": "^[a-z0-9][a-z0-9-]*$" },
|
|
11
|
+
"title": { "type": "string", "minLength": 1 },
|
|
12
|
+
"learningPurpose": { "type": "string", "minLength": 1 },
|
|
13
|
+
"scenario": {
|
|
14
|
+
"type": "object",
|
|
15
|
+
"additionalProperties": false,
|
|
16
|
+
"required": ["summary"],
|
|
17
|
+
"properties": {
|
|
18
|
+
"summary": { "type": "string", "minLength": 1 },
|
|
19
|
+
"context": { "type": "string" },
|
|
20
|
+
"roles": { "type": "array", "items": { "type": "string" } }
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"mechanicRef": { "type": "string", "description": "MechanicManifest.id; MUST resolve in the mechanic registry" },
|
|
24
|
+
"mechanicInputs": { "type": "object", "description": "MUST satisfy the mechanic manifest's requiredInputs" },
|
|
25
|
+
"interfaceIntent": { "type": "string" },
|
|
26
|
+
"evaluation": {
|
|
27
|
+
"type": "object",
|
|
28
|
+
"additionalProperties": false,
|
|
29
|
+
"properties": {
|
|
30
|
+
"assessed": { "type": "boolean" },
|
|
31
|
+
"scoreRules": {
|
|
32
|
+
"type": "object",
|
|
33
|
+
"additionalProperties": false,
|
|
34
|
+
"required": ["method"],
|
|
35
|
+
"properties": {
|
|
36
|
+
"method": { "enum": ["percentage", "points", "scaled"] },
|
|
37
|
+
"passThreshold": { "type": "number" },
|
|
38
|
+
"max": { "type": "number" }
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"criteria": { "type": "array", "items": { "type": "string" } }
|
|
42
|
+
},
|
|
43
|
+
"if": { "properties": { "assessed": { "const": true } }, "required": ["assessed"] },
|
|
44
|
+
"then": { "required": ["scoreRules"] }
|
|
45
|
+
},
|
|
46
|
+
"feedback": {
|
|
47
|
+
"type": "object",
|
|
48
|
+
"additionalProperties": false,
|
|
49
|
+
"required": ["model"],
|
|
50
|
+
"properties": {
|
|
51
|
+
"model": { "enum": ["immediate", "delayed", "summary", "adaptive"] },
|
|
52
|
+
"messages": {
|
|
53
|
+
"type": "array",
|
|
54
|
+
"items": {
|
|
55
|
+
"type": "object",
|
|
56
|
+
"additionalProperties": false,
|
|
57
|
+
"required": ["on", "message"],
|
|
58
|
+
"properties": {
|
|
59
|
+
"on": { "type": "string", "description": "meaningful learner action" },
|
|
60
|
+
"message": { "type": "string" }
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
"required": { "type": "boolean", "default": true, "description": "counts toward package completion roll-up" },
|
|
67
|
+
"weight": { "type": "number", "exclusiveMinimum": 0, "default": 1 },
|
|
68
|
+
"signals": {
|
|
69
|
+
"type": "array",
|
|
70
|
+
"description": "signals this experience emits (subset of the canonical signal set)",
|
|
71
|
+
"items": { "enum": ["progress", "score", "completion", "interaction", "feedback", "suspend"] },
|
|
72
|
+
"uniqueItems": true
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://studiolxd.dev/lxd-cli/export-config.schema.json",
|
|
4
|
+
"title": "ExportConfig",
|
|
5
|
+
"description": "Adapter-driven export configuration (FR-022/024). adapterId is an open enum; unknown ids without an adapter must be reported clearly (FR-025).",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["targets"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"targets": {
|
|
11
|
+
"type": "array",
|
|
12
|
+
"minItems": 1,
|
|
13
|
+
"items": {
|
|
14
|
+
"type": "object",
|
|
15
|
+
"additionalProperties": false,
|
|
16
|
+
"required": ["adapterId"],
|
|
17
|
+
"properties": {
|
|
18
|
+
"adapterId": {
|
|
19
|
+
"type": "string",
|
|
20
|
+
"description": "v1 in-tree adapters: web | scorm-1.2 | scorm-2004. Open to future adapters (xapi, cmi5, ...).",
|
|
21
|
+
"examples": ["web", "scorm-1.2", "scorm-2004"]
|
|
22
|
+
},
|
|
23
|
+
"options": {
|
|
24
|
+
"type": "object",
|
|
25
|
+
"description": "Adapter-specific options, validated against the adapter's own option schema",
|
|
26
|
+
"properties": {
|
|
27
|
+
"identifier": { "type": "string", "description": "SCORM manifest identifier" },
|
|
28
|
+
"masteryScore": { "type": "number", "description": "SCORM 1.2 mastery score / 2004 scaled passing score" },
|
|
29
|
+
"title": { "type": "string" }
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"framework": {
|
|
36
|
+
"type": "object",
|
|
37
|
+
"additionalProperties": false,
|
|
38
|
+
"properties": {
|
|
39
|
+
"adapterId": { "type": "string", "examples": ["webcomponents"] },
|
|
40
|
+
"options": { "type": "object" }
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://studiolxd.dev/lxd-cli/mechanic-manifest.schema.json",
|
|
4
|
+
"title": "MechanicManifest",
|
|
5
|
+
"description": "Declarative, REQUIRED contract for an experience mechanic (FR-008a). Official assets authored by Studio LXD in v1. An optional code plugin (FR-008b) may supplement but never replaces this manifest.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["id", "name", "version", "description", "requiredInputs", "trackingContract"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"id": { "type": "string", "pattern": "^[a-z0-9][a-z0-9-]*$" },
|
|
11
|
+
"name": { "type": "string" },
|
|
12
|
+
"version": { "type": "string" },
|
|
13
|
+
"category": { "type": "string" },
|
|
14
|
+
"description": { "type": "string", "minLength": 1 },
|
|
15
|
+
"requiredInputs": {
|
|
16
|
+
"type": "array",
|
|
17
|
+
"items": {
|
|
18
|
+
"type": "object",
|
|
19
|
+
"additionalProperties": false,
|
|
20
|
+
"required": ["key", "type"],
|
|
21
|
+
"properties": {
|
|
22
|
+
"key": { "type": "string" },
|
|
23
|
+
"type": { "enum": ["string", "number", "boolean", "array", "object"] },
|
|
24
|
+
"description": { "type": "string" },
|
|
25
|
+
"required": { "type": "boolean", "default": true }
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"evaluationContract": {
|
|
30
|
+
"type": "object",
|
|
31
|
+
"description": "shape the experience's evaluation must satisfy when this mechanic is assessable",
|
|
32
|
+
"properties": { "assessable": { "type": "boolean" } }
|
|
33
|
+
},
|
|
34
|
+
"feedbackContract": {
|
|
35
|
+
"type": "object",
|
|
36
|
+
"description": "shape of feedback this mechanic expects"
|
|
37
|
+
},
|
|
38
|
+
"trackingContract": {
|
|
39
|
+
"type": "array",
|
|
40
|
+
"description": "signals the mechanic is expected to emit",
|
|
41
|
+
"items": { "enum": ["progress", "score", "completion", "interaction", "feedback", "suspend"] },
|
|
42
|
+
"uniqueItems": true
|
|
43
|
+
},
|
|
44
|
+
"agentGuidance": {
|
|
45
|
+
"type": "string",
|
|
46
|
+
"description": "instructions injected into agent handoff materials for this mechanic"
|
|
47
|
+
},
|
|
48
|
+
"pluginRef": {
|
|
49
|
+
"type": "string",
|
|
50
|
+
"description": "OPTIONAL reference to a code plugin implementing mechanic-plugin.contract.md (FR-008b)"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://studiolxd.dev/lxd-cli/package-spec.schema.json",
|
|
4
|
+
"title": "PackageSpec",
|
|
5
|
+
"description": "Top-level elearning package. The package is the unit of delivery (FR-002); a single experience is never top-level.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": [
|
|
9
|
+
"id",
|
|
10
|
+
"schemaVersion",
|
|
11
|
+
"learningGoal",
|
|
12
|
+
"audience",
|
|
13
|
+
"duration",
|
|
14
|
+
"structure",
|
|
15
|
+
"experienceRefs",
|
|
16
|
+
"designRef",
|
|
17
|
+
"completionRules",
|
|
18
|
+
"trackingRef",
|
|
19
|
+
"exportRef"
|
|
20
|
+
],
|
|
21
|
+
"properties": {
|
|
22
|
+
"id": { "type": "string", "pattern": "^[a-z0-9][a-z0-9-]*$" },
|
|
23
|
+
"schemaVersion": { "type": "string" },
|
|
24
|
+
"learningGoal": { "type": "string", "minLength": 1 },
|
|
25
|
+
"title": { "type": "string" },
|
|
26
|
+
"audience": {
|
|
27
|
+
"type": "object",
|
|
28
|
+
"additionalProperties": false,
|
|
29
|
+
"required": ["description"],
|
|
30
|
+
"properties": {
|
|
31
|
+
"description": { "type": "string", "minLength": 1 },
|
|
32
|
+
"priorKnowledge": { "type": "string" },
|
|
33
|
+
"roles": { "type": "array", "items": { "type": "string" } }
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"duration": {
|
|
37
|
+
"type": "object",
|
|
38
|
+
"additionalProperties": false,
|
|
39
|
+
"required": ["expectedMinutes"],
|
|
40
|
+
"properties": {
|
|
41
|
+
"expectedMinutes": { "type": "number", "exclusiveMinimum": 0 },
|
|
42
|
+
"note": { "type": "string" }
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"context": { "type": "string" },
|
|
46
|
+
"constraints": { "type": "array", "items": { "type": "string" } },
|
|
47
|
+
"tone": { "type": "string" },
|
|
48
|
+
"structure": {
|
|
49
|
+
"type": "object",
|
|
50
|
+
"additionalProperties": false,
|
|
51
|
+
"required": ["navigation", "order"],
|
|
52
|
+
"properties": {
|
|
53
|
+
"navigation": { "enum": ["linear", "free", "guided"] },
|
|
54
|
+
"order": { "type": "array", "items": { "type": "string" }, "minItems": 1 },
|
|
55
|
+
"sections": {
|
|
56
|
+
"type": "array",
|
|
57
|
+
"items": {
|
|
58
|
+
"type": "object",
|
|
59
|
+
"additionalProperties": false,
|
|
60
|
+
"required": ["id", "title", "experienceIds"],
|
|
61
|
+
"properties": {
|
|
62
|
+
"id": { "type": "string" },
|
|
63
|
+
"title": { "type": "string" },
|
|
64
|
+
"experienceIds": { "type": "array", "items": { "type": "string" } }
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
"experienceRefs": {
|
|
71
|
+
"type": "array",
|
|
72
|
+
"minItems": 1,
|
|
73
|
+
"items": { "type": "string", "description": "experience id (file in experiences/)" }
|
|
74
|
+
},
|
|
75
|
+
"designRef": { "type": "string" },
|
|
76
|
+
"evaluationRules": {
|
|
77
|
+
"type": "object",
|
|
78
|
+
"additionalProperties": false,
|
|
79
|
+
"properties": {
|
|
80
|
+
"assessed": { "type": "boolean" },
|
|
81
|
+
"scoreRules": { "$ref": "#/$defs/scoreRules" },
|
|
82
|
+
"criteria": { "type": "array", "items": { "type": "string" } }
|
|
83
|
+
},
|
|
84
|
+
"if": { "properties": { "assessed": { "const": true } }, "required": ["assessed"] },
|
|
85
|
+
"then": { "required": ["scoreRules"] }
|
|
86
|
+
},
|
|
87
|
+
"completionRules": {
|
|
88
|
+
"type": "object",
|
|
89
|
+
"additionalProperties": false,
|
|
90
|
+
"required": ["rule"],
|
|
91
|
+
"properties": {
|
|
92
|
+
"rule": { "enum": ["all-required", "selected-required"] },
|
|
93
|
+
"requiredExperienceIds": { "type": "array", "items": { "type": "string" } }
|
|
94
|
+
},
|
|
95
|
+
"if": { "properties": { "rule": { "const": "selected-required" } } },
|
|
96
|
+
"then": { "required": ["requiredExperienceIds"] }
|
|
97
|
+
},
|
|
98
|
+
"trackingRef": { "type": "string" },
|
|
99
|
+
"exportRef": { "type": "string" },
|
|
100
|
+
"assetRefs": {
|
|
101
|
+
"type": "object",
|
|
102
|
+
"additionalProperties": false,
|
|
103
|
+
"properties": {
|
|
104
|
+
"scormLibraryVersion": { "type": "string" },
|
|
105
|
+
"scormSkillsSnapshot": {
|
|
106
|
+
"type": "object",
|
|
107
|
+
"additionalProperties": false,
|
|
108
|
+
"properties": { "version": { "type": "string" }, "ref": { "type": "string" } }
|
|
109
|
+
},
|
|
110
|
+
"cliVersion": { "type": "string" }
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
"$defs": {
|
|
115
|
+
"scoreRules": {
|
|
116
|
+
"type": "object",
|
|
117
|
+
"additionalProperties": false,
|
|
118
|
+
"required": ["method"],
|
|
119
|
+
"properties": {
|
|
120
|
+
"method": { "enum": ["percentage", "points", "scaled"] },
|
|
121
|
+
"passThreshold": { "type": "number" },
|
|
122
|
+
"max": { "type": "number" }
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://studiolxd.dev/lxd-cli/tracking-config.schema.json",
|
|
4
|
+
"title": "TrackingConfig",
|
|
5
|
+
"description": "Two-level tracking (FR-027): per-experience signals + explicit package roll-up rules (FR-027a). The roll-up produces the single LMS-reported state (FR-027b).",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["experienceSignals", "rollUp"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"experienceSignals": {
|
|
11
|
+
"type": "object",
|
|
12
|
+
"description": "map of experienceId -> declared signals",
|
|
13
|
+
"additionalProperties": {
|
|
14
|
+
"type": "array",
|
|
15
|
+
"items": { "enum": ["progress", "score", "completion", "interaction", "feedback", "suspend"] },
|
|
16
|
+
"uniqueItems": true
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"rollUp": {
|
|
20
|
+
"type": "object",
|
|
21
|
+
"additionalProperties": false,
|
|
22
|
+
"required": ["completion", "score", "reportedFields"],
|
|
23
|
+
"properties": {
|
|
24
|
+
"completion": {
|
|
25
|
+
"type": "object",
|
|
26
|
+
"additionalProperties": false,
|
|
27
|
+
"required": ["rule"],
|
|
28
|
+
"properties": {
|
|
29
|
+
"rule": { "enum": ["all-required-complete", "selected-required-complete"] },
|
|
30
|
+
"requiredExperienceIds": { "type": "array", "items": { "type": "string" } }
|
|
31
|
+
},
|
|
32
|
+
"if": { "properties": { "rule": { "const": "selected-required-complete" } } },
|
|
33
|
+
"then": { "required": ["requiredExperienceIds"] }
|
|
34
|
+
},
|
|
35
|
+
"score": {
|
|
36
|
+
"type": "object",
|
|
37
|
+
"additionalProperties": false,
|
|
38
|
+
"required": ["rule"],
|
|
39
|
+
"properties": {
|
|
40
|
+
"rule": { "enum": ["weighted-average", "final-assessment-only"] },
|
|
41
|
+
"finalAssessmentExperienceId": { "type": "string" }
|
|
42
|
+
},
|
|
43
|
+
"if": { "properties": { "rule": { "const": "final-assessment-only" } } },
|
|
44
|
+
"then": { "required": ["finalAssessmentExperienceId"] }
|
|
45
|
+
},
|
|
46
|
+
"success": {
|
|
47
|
+
"type": "object",
|
|
48
|
+
"additionalProperties": false,
|
|
49
|
+
"properties": {
|
|
50
|
+
"scoreThreshold": { "type": "number" },
|
|
51
|
+
"requireRequiredExperiencesComplete": { "type": "boolean", "default": true }
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
"reportedFields": {
|
|
55
|
+
"type": "array",
|
|
56
|
+
"minItems": 1,
|
|
57
|
+
"items": { "enum": ["completion", "success", "score", "suspend_data", "lesson_location"] },
|
|
58
|
+
"uniqueItems": true
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://studiolxd.dev/lxd-cli/validation-report.schema.json",
|
|
4
|
+
"title": "ValidationReport",
|
|
5
|
+
"description": "Output of the validation subsystem (FR-032/033). Every check is actionable: it identifies what failed and where.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["checks", "summary"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"checks": {
|
|
11
|
+
"type": "array",
|
|
12
|
+
"items": {
|
|
13
|
+
"type": "object",
|
|
14
|
+
"additionalProperties": false,
|
|
15
|
+
"required": ["id", "category", "status", "message"],
|
|
16
|
+
"properties": {
|
|
17
|
+
"id": { "type": "string", "description": "stable check id, e.g., 'learning-goal-present'" },
|
|
18
|
+
"category": {
|
|
19
|
+
"enum": ["instructional", "design", "accessibility", "technical", "tracking", "export", "maintainability", "portability"]
|
|
20
|
+
},
|
|
21
|
+
"status": { "enum": ["pass", "fail", "warn", "skip"] },
|
|
22
|
+
"message": { "type": "string" },
|
|
23
|
+
"location": { "type": "string", "description": "artifact path / field pointer the result refers to" },
|
|
24
|
+
"fix": { "type": "string", "description": "suggested remediation" }
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"summary": {
|
|
29
|
+
"type": "object",
|
|
30
|
+
"additionalProperties": false,
|
|
31
|
+
"required": ["pass", "fail", "warn", "skip", "overall"],
|
|
32
|
+
"properties": {
|
|
33
|
+
"pass": { "type": "integer", "minimum": 0 },
|
|
34
|
+
"fail": { "type": "integer", "minimum": 0 },
|
|
35
|
+
"warn": { "type": "integer", "minimum": 0 },
|
|
36
|
+
"skip": { "type": "integer", "minimum": 0 },
|
|
37
|
+
"overall": { "enum": ["pass", "fail"] }
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"generatedAt": { "type": "string", "format": "date-time" }
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
id: branching-narrative
|
|
2
|
+
name: Branching Narrative
|
|
3
|
+
version: 0.1.0
|
|
4
|
+
category: scenario
|
|
5
|
+
description: >-
|
|
6
|
+
Learner moves through a branching story, making choices that lead to different
|
|
7
|
+
nodes and outcomes. Good for judgement, ethics, and consequence-based learning.
|
|
8
|
+
requiredInputs:
|
|
9
|
+
- key: nodes
|
|
10
|
+
type: array
|
|
11
|
+
description: Story nodes with choices and the node each choice leads to.
|
|
12
|
+
required: true
|
|
13
|
+
- key: start
|
|
14
|
+
type: string
|
|
15
|
+
description: The id of the starting node.
|
|
16
|
+
required: true
|
|
17
|
+
trackingContract:
|
|
18
|
+
- progress
|
|
19
|
+
- completion
|
|
20
|
+
- interaction
|
|
21
|
+
- suspend
|
|
22
|
+
agentGuidance: >-
|
|
23
|
+
Render the narrative as a Web Component; persist the visited path in suspend
|
|
24
|
+
data so the learner can resume; emit completion when a terminal node is reached.
|
|
25
|
+
pluginRef: branching-narrative
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
id: decision-simulation
|
|
2
|
+
name: Decision Simulation
|
|
3
|
+
version: 0.1.0
|
|
4
|
+
category: simulation
|
|
5
|
+
description: >-
|
|
6
|
+
Learner makes a sequence of decisions in a scenario and sees consequences,
|
|
7
|
+
building judgement under realistic constraints.
|
|
8
|
+
requiredInputs:
|
|
9
|
+
- key: scenario
|
|
10
|
+
type: string
|
|
11
|
+
description: The situation the learner is placed in.
|
|
12
|
+
required: true
|
|
13
|
+
- key: decisions
|
|
14
|
+
type: array
|
|
15
|
+
description: Decision points with options and consequences.
|
|
16
|
+
required: true
|
|
17
|
+
trackingContract:
|
|
18
|
+
- progress
|
|
19
|
+
- score
|
|
20
|
+
- completion
|
|
21
|
+
- interaction
|
|
22
|
+
- suspend
|
|
23
|
+
agentGuidance: >-
|
|
24
|
+
Render branching decision points as a Web Component; track the chosen path in
|
|
25
|
+
suspend data; score against the defined consequences.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
id: diagnostic-challenge
|
|
2
|
+
name: Diagnostic Challenge
|
|
3
|
+
version: 0.1.0
|
|
4
|
+
category: assessment
|
|
5
|
+
description: >-
|
|
6
|
+
Learner diagnoses a problem from evidence, selecting causes or next actions.
|
|
7
|
+
Good for troubleshooting and clinical-style reasoning.
|
|
8
|
+
requiredInputs:
|
|
9
|
+
- key: case
|
|
10
|
+
type: object
|
|
11
|
+
description: The presenting evidence/symptoms.
|
|
12
|
+
required: true
|
|
13
|
+
- key: answerKey
|
|
14
|
+
type: object
|
|
15
|
+
description: Correct diagnosis/actions and acceptable alternatives.
|
|
16
|
+
required: true
|
|
17
|
+
trackingContract:
|
|
18
|
+
- progress
|
|
19
|
+
- score
|
|
20
|
+
- completion
|
|
21
|
+
- interaction
|
|
22
|
+
agentGuidance: >-
|
|
23
|
+
Present evidence and a structured response as a Web Component; evaluate the
|
|
24
|
+
learner's diagnosis against the answer key; emit score and completion.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
id: risk-detection
|
|
2
|
+
name: Risk / Error Detection
|
|
3
|
+
version: 0.1.0
|
|
4
|
+
category: assessment
|
|
5
|
+
description: >-
|
|
6
|
+
Learner inspects a scene, interface, or document and identifies hazards,
|
|
7
|
+
errors, or risks. Good for safety, compliance, and review skills.
|
|
8
|
+
requiredInputs:
|
|
9
|
+
- key: items
|
|
10
|
+
type: array
|
|
11
|
+
description: The inspectable items and which are hazards/errors.
|
|
12
|
+
required: true
|
|
13
|
+
- key: prompt
|
|
14
|
+
type: string
|
|
15
|
+
description: What the learner is asked to find.
|
|
16
|
+
required: true
|
|
17
|
+
trackingContract:
|
|
18
|
+
- progress
|
|
19
|
+
- score
|
|
20
|
+
- completion
|
|
21
|
+
- interaction
|
|
22
|
+
agentGuidance: >-
|
|
23
|
+
Render an inspectable scene as a Web Component. Let the learner mark items;
|
|
24
|
+
evaluate against the hazard set; emit score and completion signals.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Agent-agnosticism verification (manual)
|
|
2
|
+
|
|
3
|
+
The product must work with **any** external AI coding agent (FR-017, SC-010). Two layers verify
|
|
4
|
+
this:
|
|
5
|
+
|
|
6
|
+
1. **Automated (CI):** the `checkHandoffAgnostic` check (`src/core/validation/handoff-agnostic.ts`)
|
|
7
|
+
asserts generated handoff materials contain no provider-specific assumptions or credentials. It
|
|
8
|
+
runs in the `handoff` command (warns) and in `tests/contract/handoff-agnostic.test.ts`.
|
|
9
|
+
2. **Manual (this procedure):** confirm the *same* handoff materials can be implemented by **two
|
|
10
|
+
different agents** to a passing package. This is inherently manual (real agents, human judgement)
|
|
11
|
+
and is **not** a CI gate.
|
|
12
|
+
|
|
13
|
+
## Procedure
|
|
14
|
+
|
|
15
|
+
1. **Author one package once.**
|
|
16
|
+
```bash
|
|
17
|
+
lxd init course-x && cd course-x
|
|
18
|
+
# ... goal / audience / structure / experience / design / evaluation / tracking ...
|
|
19
|
+
lxd validate # expect overall: pass
|
|
20
|
+
lxd handoff # produces .agent/** (the shared materials)
|
|
21
|
+
```
|
|
22
|
+
Snapshot `.agent/` (e.g., copy it aside) so both agents get identical inputs.
|
|
23
|
+
|
|
24
|
+
2. **Agent A.** In a clean checkout of the project (same `.agent/`, empty `generated/`), run your
|
|
25
|
+
first agent (e.g., Claude Code) against `.agent/**`. Then:
|
|
26
|
+
```bash
|
|
27
|
+
lxd preview # interactive? ✅/❌
|
|
28
|
+
lxd validate # overall: pass? ✅/❌
|
|
29
|
+
lxd export --target web --target scorm-1.2
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
3. **Agent B.** Repeat step 2 in a *fresh* clean checkout with the **same** `.agent/`, using a
|
|
33
|
+
different agent (e.g., Cursor or Codex).
|
|
34
|
+
|
|
35
|
+
4. **Record results** in the table below. The criterion (SC-010): both agents reach a previewable,
|
|
36
|
+
validated package and conformant exports from the same handoff materials.
|
|
37
|
+
|
|
38
|
+
## Results log
|
|
39
|
+
|
|
40
|
+
| Date | Agent | Preview OK | Validate pass | Export web | Export SCORM | Notes |
|
|
41
|
+
|------|-------|-----------|---------------|------------|--------------|-------|
|
|
42
|
+
| | A: … | | | | | |
|
|
43
|
+
| | B: … | | | | | |
|
|
44
|
+
|
|
45
|
+
## What counts as a failure
|
|
46
|
+
|
|
47
|
+
- Handoff materials assume a specific provider/model, or contain credentials (caught automatically).
|
|
48
|
+
- One agent succeeds and another cannot, due to provider-specific phrasing in the materials.
|
|
49
|
+
- The materials require tools only one agent has.
|
|
50
|
+
|
|
51
|
+
If any occur, generalize the affected prompt/instruction templates in
|
|
52
|
+
`src/agent/handoff/producer.ts` and re-verify.
|