@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.
@@ -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.